⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chan_h323.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 5 页
字号:
	struct ast_ha *oldha;	int found = 0;	int format;	user = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&userl, name, name, 0, 0, strcmp);	if (user)		found++;	else {		if (!(user = (struct oh323_user *)calloc(1, sizeof(*user))))			return NULL;		ASTOBJ_INIT(user);	}	oldha = user->ha;	user->ha = (struct ast_ha *)NULL;	memcpy(&user->options, &global_options, sizeof(user->options));	/* Set default context */	ast_copy_string(user->context, default_context, sizeof(user->context));	if (user && !found)		ast_copy_string(user->name, name, sizeof(user->name));#if 0 /* XXX Port channel variables functionality from chan_sip XXX */	if (user->chanvars) {		ast_variables_destroy(user->chanvars);		user->chanvars = NULL;	}#endif	for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {		if (!update_common_options(v, &user->options))			continue;		if (!strcasecmp(v->name, "context")) {			ast_copy_string(user->context, v->value, sizeof(user->context));		} else if (!strcasecmp(v->name, "secret")) {			ast_copy_string(user->secret, v->value, sizeof(user->secret));		} else if (!strcasecmp(v->name, "accountcode")) {			ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));		} else if (!strcasecmp(v->name, "host")) {			if (!strcasecmp(v->value, "dynamic")) {				ast_log(LOG_ERROR, "A dynamic host on a type=user does not make any sense\n");				ASTOBJ_UNREF(user, oh323_destroy_user);				return NULL;			} else if (ast_get_ip(&user->addr, v->value)) {				ASTOBJ_UNREF(user, oh323_destroy_user);				return NULL;			}			/* Let us know we need to use ip authentication */			user->host = 1;		} else if (!strcasecmp(v->name, "amaflags")) {			format = ast_cdr_amaflags2int(v->value);			if (format < 0) {				ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);			} else {				user->amaflags = format;			}		} else if (!strcasecmp(v->name, "permit") ||					!strcasecmp(v->name, "deny")) {			user->ha = ast_append_ha(v->name, v->value, user->ha);		}	}	ASTOBJ_UNMARK(user);	ast_free_ha(oldha);	return user;}static struct oh323_user *realtime_user(const call_details_t *cd){	struct ast_variable *var, *tmp;	struct oh323_user *user;	char *username;	if (userbyalias)		var = ast_load_realtime("h323", "name", username = cd->call_source_aliases, NULL);	else {		username = (char *)NULL;		var = ast_load_realtime("h323", "host", cd->sourceIp, NULL);	}	if (!var)		return NULL;	for (tmp = var; tmp; tmp = tmp->next) {		if (!strcasecmp(tmp->name, "type") &&		!(!strcasecmp(tmp->value, "user") || !strcasecmp(tmp->value, "friend"))) {			ast_variables_destroy(var);			return NULL;		} else if (!username && !strcasecmp(tmp->name, "name"))			username = tmp->value;	}	if (!username) {		ast_log(LOG_WARNING, "Cannot determine user name for IP address %s\n", cd->sourceIp);		ast_variables_destroy(var);		return NULL;	}	user = build_user(username, var, NULL, 1);	ast_variables_destroy(var);	return user;}static struct oh323_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime){	struct oh323_peer *peer;	struct ast_ha *oldha;	int found = 0;	peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp);	if (peer)		found++;	else {		if (!(peer = (struct oh323_peer*)calloc(1, sizeof(*peer))))			return NULL;		ASTOBJ_INIT(peer);	}	oldha = peer->ha;	peer->ha = NULL;	memcpy(&peer->options, &global_options, sizeof(peer->options));	peer->addr.sin_port = htons(h323_signalling_port);	peer->addr.sin_family = AF_INET;	if (!found && name)		ast_copy_string(peer->name, name, sizeof(peer->name));#if 0 /* XXX Port channel variables functionality from chan_sip XXX */	if (peer->chanvars) {		ast_variables_destroy(peer->chanvars);		peer->chanvars = NULL;	}#endif	/* Default settings for mailbox */	peer->mailbox[0] = '\0';	for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {		if (!update_common_options(v, &peer->options))			continue;		if (!strcasecmp(v->name, "host")) {			if (!strcasecmp(v->value, "dynamic")) {				ast_log(LOG_ERROR, "Dynamic host configuration not implemented.\n");				ASTOBJ_UNREF(peer, oh323_destroy_peer);				return NULL;			}			if (ast_get_ip(&peer->addr, v->value)) {				ast_log(LOG_ERROR, "Could not determine IP for %s\n", v->value);				ASTOBJ_UNREF(peer, oh323_destroy_peer);				return NULL;			}		} else if (!strcasecmp(v->name, "port")) {			peer->addr.sin_port = htons(atoi(v->value));		} else if (!strcasecmp(v->name, "permit") ||					!strcasecmp(v->name, "deny")) {			peer->ha = ast_append_ha(v->name, v->value, peer->ha);		} else if (!strcasecmp(v->name, "mailbox")) {			ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));		} else if (!strcasecmp(v->name, "hasvoicemail")) {			if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {				ast_copy_string(peer->mailbox, name, sizeof(peer->mailbox));			}		}	}	ASTOBJ_UNMARK(peer);	ast_free_ha(oldha);	return peer;}static struct oh323_peer *realtime_peer(const char *peername, struct sockaddr_in *sin){	struct oh323_peer *peer;	struct ast_variable *var;	struct ast_variable *tmp;	const char *addr;	/* First check on peer name */	if (peername)		var = ast_load_realtime("h323", "name", peername, addr = NULL);	else if (sin) /* Then check on IP address for dynamic peers */		var = ast_load_realtime("h323", "host", addr = ast_inet_ntoa(sin->sin_addr), NULL);	else		return NULL;	if (!var)		return NULL;	for (tmp = var; tmp; tmp = tmp->next) {		/* If this is type=user, then skip this object. */		if (!strcasecmp(tmp->name, "type") &&				!(!strcasecmp(tmp->value, "peer") || !strcasecmp(tmp->value, "friend"))) {			ast_variables_destroy(var);			return NULL;		} else if (!peername && !strcasecmp(tmp->name, "name")) {			peername = tmp->value;		}	}	if (!peername) {	/* Did not find peer in realtime */		ast_log(LOG_WARNING, "Cannot determine peer name for IP address %s\n", addr);		ast_variables_destroy(var);		return NULL;	}	/* Peer found in realtime, now build it in memory */	peer = build_peer(peername, var, NULL, 1);	ast_variables_destroy(var);	return peer;}static int oh323_addrcmp_str(struct in_addr inaddr, char *addr){	return strcmp(ast_inet_ntoa(inaddr), addr);}static struct oh323_user *find_user(const call_details_t *cd, int realtime){	struct oh323_user *u;	if (userbyalias)		u = ASTOBJ_CONTAINER_FIND(&userl, cd->call_source_aliases);	else		u = ASTOBJ_CONTAINER_FIND_FULL(&userl, cd->sourceIp, addr.sin_addr, 0, 0, oh323_addrcmp_str);	if (!u && realtime)		u = realtime_user(cd);	if (!u && h323debug)		ast_log(LOG_DEBUG, "Could not find user by name %s or address %s\n", cd->call_source_aliases, cd->sourceIp);	return u;}static int oh323_addrcmp(struct sockaddr_in addr, struct sockaddr_in *sin){	int res;	if (!sin)		res = -1;	else		res = inaddrcmp(&addr , sin);	return res;}static struct oh323_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime){	struct oh323_peer *p;	if (peer)		p = ASTOBJ_CONTAINER_FIND(&peerl, peer);	else		p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, addr, 0, 0, oh323_addrcmp);	if (!p && realtime)		p = realtime_peer(peer, sin);	if (!p && h323debug)		ast_log(LOG_DEBUG, "Could not find peer by name %s or address %s\n", (peer ? peer : "<NONE>"), (sin ? ast_inet_ntoa(sin->sin_addr) : "<NONE>"));	return p;}static int create_addr(struct oh323_pvt *pvt, char *opeer){	struct hostent *hp;	struct ast_hostent ahp;	struct oh323_peer *p;	int portno;	int found = 0;	char *port;	char *hostn;	char peer[256] = "";	ast_copy_string(peer, opeer, sizeof(peer));	port = strchr(peer, ':');	if (port) {		*port = '\0';		port++;	}	pvt->sa.sin_family = AF_INET;	p = find_peer(peer, NULL, 1);	if (p) {		found++;		memcpy(&pvt->options, &p->options, sizeof(pvt->options));		pvt->jointcapability = pvt->options.capability;		if (pvt->options.dtmfmode) {			if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {				pvt->nonCodecCapability |= AST_RTP_DTMF;			} else {				pvt->nonCodecCapability &= ~AST_RTP_DTMF;			}		}		if (p->addr.sin_addr.s_addr) {			pvt->sa.sin_addr = p->addr.sin_addr;			pvt->sa.sin_port = p->addr.sin_port;		}		ASTOBJ_UNREF(p, oh323_destroy_peer);	}	if (!p && !found) {		hostn = peer;		if (port) {			portno = atoi(port);		} else {			portno = h323_signalling_port;		}		hp = ast_gethostbyname(hostn, &ahp);		if (hp) {			memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr));			pvt->sa.sin_port = htons(portno);			/* Look peer by address */			p = find_peer(NULL, &pvt->sa, 1);			memcpy(&pvt->options, (p ? &p->options : &global_options), sizeof(pvt->options));			pvt->jointcapability = pvt->options.capability;			if (p) {				ASTOBJ_UNREF(p, oh323_destroy_peer);			}			if (pvt->options.dtmfmode) {				if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {					pvt->nonCodecCapability |= AST_RTP_DTMF;				} else {					pvt->nonCodecCapability &= ~AST_RTP_DTMF;				}			}			return 0;		} else {			ast_log(LOG_WARNING, "No such host: %s\n", peer);			return -1;		}	} else if (!found) {		return -1;	} else {		return 0;	}}static struct ast_channel *oh323_request(const char *type, int format, void *data, int *cause){	int oldformat;	struct oh323_pvt *pvt;	struct ast_channel *tmpc = NULL;	char *dest = (char *)data;	char *ext, *host;	char *h323id = NULL;	char tmp[256], tmp1[256];	if (h323debug)		ast_log(LOG_DEBUG, "type=%s, format=%d, data=%s.\n", type, format, (char *)data);	pvt = oh323_alloc(0);	if (!pvt) {		ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char *)data);		return NULL;	}	oldformat = format;	format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1);	if (!format) {		ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format);		oh323_destroy(pvt);		if (cause)			*cause = AST_CAUSE_INCOMPATIBLE_DESTINATION;		return NULL;	}	ast_copy_string(tmp, dest, sizeof(tmp));	host = strchr(tmp, '@');	if (host) {		*host = '\0';		host++;		ext = tmp;	} else {		ext = strrchr(tmp, '/');		if (ext)			*ext++ = '\0';		host = tmp;	}	strtok_r(host, "/", &(h323id));	if (!ast_strlen_zero(h323id)) {		h323_set_id(h323id);	}	if (ext) {		ast_copy_string(pvt->exten, ext, sizeof(pvt->exten));	}	if (h323debug)		ast_log(LOG_DEBUG, "Extension: %s Host: %s\n", pvt->exten, host);	if (gatekeeper_disable) {		if (create_addr(pvt, host)) {			oh323_destroy(pvt);			if (cause)				*cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;			return NULL;		}	}	else {		memcpy(&pvt->options, &global_options, sizeof(pvt->options));		pvt->jointcapability = pvt->options.capability;		if (pvt->options.dtmfmode) {			if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {				pvt->nonCodecCapability |= AST_RTP_DTMF;			} else {				pvt->nonCodecCapability &= ~AST_RTP_DTMF;			}		}	}	ast_mutex_lock(&caplock);	/* Generate unique channel identifier */	snprintf(tmp1, sizeof(tmp1)-1, "%s-%u", host, ++unique);	tmp1[sizeof(tmp1)-1] = '\0';	ast_mutex_unlock(&caplock);	ast_mutex_lock(&pvt->lock);	tmpc = __oh323_new(pvt, AST_STATE_DOWN, tmp1);	ast_mutex_unlock(&pvt->lock);	if (!tmpc) {		oh323_destroy(pvt);		if (cause)			*cause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;	}	ast_update_use_count();	restart_monitor();	return tmpc;}/** Find a call by alias */static struct oh323_alias *find_alias(const char *source_aliases, int realtime){	struct oh323_alias *a;	a = ASTOBJ_CONTAINER_FIND(&aliasl, source_aliases);	if (!a && realtime)		a = realtime_alias(source_aliases);	return a;}/**  * Callback for sending digits from H.323 up to asterisk  *  */static int receive_digit(unsigned call_reference, char digit, const char *token, int duration){	struct oh323_pvt *pvt;	int res;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -