[asterisk-commits] pcadach: branch pcadach/chan_h323-live r41358 - /team/pcadach/chan_h323-live/...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Wed Aug 30 08:30:41 MST 2006


Author: pcadach
Date: Wed Aug 30 10:30:41 2006
New Revision: 41358

URL: http://svn.digium.com/view/asterisk?rev=41358&view=rev
Log:
Preliminary realtime support for chan_h323

Modified:
    team/pcadach/chan_h323-live/channels/chan_h323.c

Modified: team/pcadach/chan_h323-live/channels/chan_h323.c
URL: http://svn.digium.com/view/asterisk/team/pcadach/chan_h323-live/channels/chan_h323.c?rev=41358&r1=41357&r2=41358&view=diff
==============================================================================
--- team/pcadach/chan_h323-live/channels/chan_h323.c (original)
+++ team/pcadach/chan_h323-live/channels/chan_h323.c Wed Aug 30 10:30:41 2006
@@ -971,979 +971,40 @@
 	}
 }
 
-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 0 /* XXX REALTIME XXX*/
-	if (!u && realtime)
-		u = realtime_user(cd);
-#endif
-
-	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 = NULL;
-
-	if (peer)
-		p = ASTOBJ_CONTAINER_FIND(&peerl, peer);
-	else
-		p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, addr, 0, 0, oh323_addrcmp);
-
-#if 0 /* XXX REALTIME XXX */
-	if (!p && realtime)
-		p = realtime_peer(peer, sin);
-#endif
-
-	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;
+static struct oh323_alias *build_alias(char *name, struct ast_variable *v)
+{
+	struct oh323_alias *alias;
 	int found = 0;
-	char *port;
-	char *hostn;
-	char peer[256] = "";
-
-	strncpy(peer, opeer, sizeof(peer) - 1);
-	port = strchr(peer, ':');
-	if (port) {
-		*port = '\0';
-		port++;
-	}
-	pvt->sa.sin_family = AF_INET;
-	p = find_peer(peer, NULL, 0);
-	if (p) {
+
+	alias = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&aliasl, name, name, 0, 0, strcasecmp);
+
+	if (alias)
 		found++;
-		memcpy(&pvt->options, &p->options, sizeof(pvt->options));
-		pvt->jointcapability = pvt->options.capability;
-		if (pvt->rtp) {
-			ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat);
-			ast_rtp_setnat(pvt->rtp, pvt->options.nat);
-		}
-		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 {
+		if (!(alias = (struct oh323_alias *)calloc(1, sizeof(*alias))))
+			return NULL;
+		ASTOBJ_INIT(alias);
+	}
+	if (!found && name)
+		strncpy(alias->name, name, sizeof(alias->name) - 1);
+	for (; v; v = v->next) {
+		if (!strcasecmp(v->name, "e164")) {
+			strncpy(alias->e164,  v->value, sizeof(alias->e164) - 1);
+		} else if (!strcasecmp(v->name, "prefix")) {
+			strncpy(alias->prefix,  v->value, sizeof(alias->prefix) - 1);
+		} else if (!strcasecmp(v->name, "context")) {
+			strncpy(alias->context,  v->value, sizeof(alias->context) - 1);
+		} else if (!strcasecmp(v->name, "secret")) {
+			strncpy(alias->secret,  v->value, sizeof(alias->secret) - 1);
 		} 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, 0);
-			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->rtp) {
-				ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat);
-				ast_rtp_setnat(pvt->rtp, pvt->options.nat);
-			}
-			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 (!p) {
-		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];
-	
-	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);
-		return NULL;
-	}
-	strncpy(tmp, dest, sizeof(tmp) - 1);	
-	host = strchr(tmp, '@');
-	if (host) {
-		*host = '\0';
-		host++;
-		ext = tmp;
-	} else {
-		host = tmp;
-		ext = NULL;
-	}
-	strtok_r(host, "/", &(h323id));		
-	if (!ast_strlen_zero(h323id)) {
-		h323_set_id(h323id);
-	}
-	if (ext) {
-		strncpy(pvt->exten, ext, sizeof(pvt->exten) - 1);
-	}
-	ast_log(LOG_DEBUG, "Extension: %s Host: %s\n",  pvt->exten, host);
-	if (!usingGk) {
-		if (create_addr(pvt, host)) {
-			oh323_destroy(pvt);
-			return NULL;
-		}
-	}
-	else {
-		memcpy(&pvt->options, &global_options, sizeof(pvt->options));
-		pvt->jointcapability = pvt->options.capability;
-		if (pvt->rtp) {
-			ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat);
-			ast_rtp_setnat(pvt->rtp, pvt->options.nat);
-		}
-		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);
-	}
-	ast_update_use_count();
-	restart_monitor();
-	return tmpc;
-}
-
-/** Find a call by alias */
-static struct oh323_alias *find_alias(const char *source_aliases)
-{
-	struct oh323_alias *a;
-
-	a = ASTOBJ_CONTAINER_FIND(&aliasl, source_aliases);
-
-#if 0 /* XXX REALTIME XXX */
-	if (!a && realtime)
-		a = realtime_alias(source_aliases);
-#endif
-
-	return a;
-}
-
-/**
-  * Callback for sending digits from H.323 up to asterisk
-  *
-  */
-static int send_digit(unsigned call_reference, char digit, const char *token)
-{
-	struct oh323_pvt *pvt;
-	int res;
-
-	if (digit == ' ') /* DTMF tone update -- ignore */
-		return 0;
-	ast_log(LOG_DEBUG, "Received Digit: %c\n", digit);
-	pvt = find_call_locked(call_reference, token); 
-	if (!pvt) {
-		ast_log(LOG_ERROR, "Private structure not found in send_digit.\n");
-		return -1;
-	}
-	if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
-		if (digit == '!')
-			res = ast_queue_control(pvt->owner, AST_CONTROL_FLASH);
-		else {
-			struct ast_frame f = {
-				.frametype = AST_FRAME_DTMF,
-				.subclass = digit,
-				.samples = 800,
-				.src = "SEND_DIGIT",
-			};
-			res = ast_queue_frame(pvt->owner, &f);
-		}
-		ast_channel_unlock(pvt->owner);
-	} else {
-		if (digit == '!')
-			pvt->newcontrol = AST_CONTROL_FLASH;
-		else
-			pvt->newdigit = digit;
-		res = 0;
-	}
-	ast_mutex_unlock(&pvt->lock);
-	return res;
-}
-
-/**
-  * Callback function used to inform the H.323 stack of the local rtp ip/port details
-  *
-  * Returns the local RTP information
-  */
-static struct rtp_info *external_rtp_create(unsigned call_reference, const char * token)
-{	
-	struct oh323_pvt *pvt;
-	struct sockaddr_in us;
-	struct rtp_info *info;
-
-	info = (struct rtp_info *)malloc(sizeof(struct rtp_info));
-	if (!info) {
-		ast_log(LOG_ERROR, "Unable to allocated info structure, this is very bad\n");
-		return NULL;
-	}
-	pvt = find_call_locked(call_reference, token); 
-	if (!pvt) {
-		free(info);
-		ast_log(LOG_ERROR, "Unable to find call %s(%d)\n", token, call_reference);
-		return NULL;
-	}
-	/* figure out our local RTP port and tell the H.323 stack about it */
-	ast_rtp_get_us(pvt->rtp, &us);
-	ast_mutex_unlock(&pvt->lock);
-
-	strncpy(info->addr, ast_inet_ntoa(us.sin_addr), sizeof(info->addr));
-	info->addr[sizeof(info->addr)-1] = '\0';
-	info->port = ntohs(us.sin_port);
-	if (h323debug)
-		ast_log(LOG_DEBUG, "Sending RTP 'US' %s:%d\n", info->addr, info->port);
-	return info;
-}
-
-/**
- * Definition taken from rtp.c for rtpPayloadType because we need it here.
- */
-struct rtpPayloadType {
-	int isAstFormat;        /* whether the following code is an AST_FORMAT */
-	int code;
-};
-
-/**
-  * Call-back function passing remote ip/port information from H.323 to asterisk 
-  *
-  * Returns nothing 
-  */
-static void setup_rtp_connection(unsigned call_reference, const char *remoteIp, int remotePort, const char *token, int pt)
-{
-	struct oh323_pvt *pvt;
-	struct sockaddr_in them;
-	struct rtpPayloadType rtptype;
-
-	if (h323debug)
-		ast_log(LOG_DEBUG, "Setting up RTP connection for %s\n", token);
-
-	/* Find the call or allocate a private structure if call not found */
-	pvt = find_call_locked(call_reference, token); 
-	if (!pvt) {
-		ast_log(LOG_ERROR, "Something is wrong: rtp\n");
-		return;
-	}
-	if (pvt->alreadygone) {
-		ast_mutex_unlock(&pvt->lock);
-		return;
-	}
-	rtptype = ast_rtp_lookup_pt(pvt->rtp, pt);
-	pvt->nativeformats = rtptype.code;
-	if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
-		pvt->owner->nativeformats = pvt->nativeformats;
-		ast_set_read_format(pvt->owner, pvt->owner->readformat);
-		ast_set_write_format(pvt->owner, pvt->owner->writeformat);
-		if (pvt->options.progress_audio)
-			ast_queue_control(pvt->owner, AST_CONTROL_PROGRESS);
-		ast_channel_unlock(pvt->owner);
-	}
-	else {
-		if (pvt->options.progress_audio)
-			pvt->newcontrol = AST_CONTROL_PROGRESS;
-		if (h323debug)
-			ast_log(LOG_DEBUG, "RTP connection preparation for %s is pending...\n", token);
-	}
-
-	them.sin_family = AF_INET;
-	/* only works for IPv4 */
-	them.sin_addr.s_addr = inet_addr(remoteIp); 
-	them.sin_port = htons(remotePort);
-	ast_rtp_set_peer(pvt->rtp, &them);
-
-	ast_mutex_unlock(&pvt->lock);
-
-	if (h323debug)
-		ast_log(LOG_DEBUG, "RTP connection prepared for %s\n", token);
-
-	return;
-}
-
-/**  
-  *	Call-back function to signal asterisk that the channel has been answered 
-  * Returns nothing
-  */
-static void connection_made(unsigned call_reference, const char *token)
-{
-	struct oh323_pvt *pvt;
-
-	if (h323debug)
-		ast_log(LOG_DEBUG, "Call %s answered\n", token);
-
-	pvt = find_call_locked(call_reference, token); 
-	if (!pvt) {
-		ast_log(LOG_ERROR, "Something is wrong: connection\n");
-		return;
-	}
-
-	/* Inform asterisk about remote party connected only on outgoing calls */
-	if (!pvt->outgoing) {
-		ast_mutex_unlock(&pvt->lock);
-		return;
-	}
-	update_state(pvt, AST_STATE_UP, AST_CONTROL_ANSWER);
-	ast_mutex_unlock(&pvt->lock);
-	return;
-}
-
-static int progress(unsigned call_reference, const char *token, int inband)
-{
-	struct oh323_pvt *pvt;
-
-	ast_log(LOG_DEBUG, "Received ALERT/PROGRESS message for %s tones\n", (inband ? "inband" : "self-generated"));
-
-	pvt = find_call_locked(call_reference, token);
-	if (!pvt) {
-		ast_log(LOG_ERROR, "Private structure not found in progress.\n");
-		return -1;
-	}
-	if (!pvt->owner) {
-		ast_mutex_unlock(&pvt->lock);
-		ast_log(LOG_ERROR, "No Asterisk channel associated with private structure.\n");
-		return -1;
-	}
-	update_state(pvt, -1, (inband ? AST_CONTROL_PROGRESS : AST_CONTROL_RINGING));
-	ast_mutex_unlock(&pvt->lock);
-
-	return 0;
-}
-
-/**
- *  Call-back function for incoming calls
- *
- *  Returns 1 on success
- */
-static call_options_t *setup_incoming_call(call_details_t *cd)
-{
-	struct oh323_pvt *pvt;
-	struct oh323_user *user = NULL;
-	struct oh323_alias *alias = NULL;
-
-	if (h323debug)
-		ast_log(LOG_DEBUG, "Setting up incoming call for %s\n", cd->call_token);
-
-	/* allocate the call*/
-	pvt = oh323_alloc(cd->call_reference);
-
-	if (!pvt) {
-		ast_log(LOG_ERROR, "Unable to allocate private structure, this is bad.\n");
-		cleanup_call_details(cd);
-		return NULL;
-	}
-
-	/* Populate the call details in the private structure */
-	memcpy(&pvt->cd, cd, sizeof(pvt->cd));
-	memcpy(&pvt->options, &global_options, sizeof(pvt->options));
-	pvt->jointcapability = pvt->options.capability;
-
-	if (h323debug) {
-		ast_verbose(VERBOSE_PREFIX_3 "Setting up Call\n");
-		ast_verbose(VERBOSE_PREFIX_3 "\tCall token:  [%s]\n", pvt->cd.call_token);
-		ast_verbose(VERBOSE_PREFIX_3 "\tCalling party name:  [%s]\n", pvt->cd.call_source_name);
-		ast_verbose(VERBOSE_PREFIX_3 "\tCalling party number:  [%s]\n", pvt->cd.call_source_e164);
-		ast_verbose(VERBOSE_PREFIX_3 "\tCalled party name:  [%s]\n", pvt->cd.call_dest_alias);
-		ast_verbose(VERBOSE_PREFIX_3 "\tCalled party number:  [%s]\n", pvt->cd.call_dest_e164);
-		ast_verbose(VERBOSE_PREFIX_3 "\tCalling party IP: [%s]\n", pvt->cd.sourceIp);
-	}
-
-	/* Decide if we are allowing Gatekeeper routed calls*/
-	if ((!strcasecmp(cd->sourceIp, gatekeeper)) && (gkroute == -1) && (usingGk)) {
-		if (!ast_strlen_zero(cd->call_dest_e164)) {
-			strncpy(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten) - 1);
-			strncpy(pvt->context, default_context, sizeof(pvt->context) - 1); 
-		} else {
-			alias = find_alias(cd->call_dest_alias);
-			if (!alias) {
-				ast_log(LOG_ERROR, "Call for %s rejected, alias not found\n", cd->call_dest_alias);
-				oh323_destroy(pvt);
-				return NULL;
-			}
-			strncpy(pvt->exten, alias->name, sizeof(pvt->exten) - 1);
-			strncpy(pvt->context, alias->context, sizeof(pvt->context) - 1);
-		}
-	} else {
-		/* Either this call is not from the Gatekeeper 
-		   or we are not allowing gk routed calls */
-		user  = find_user(cd, 0);
-		if (!user) {
-			if (!ast_strlen_zero(pvt->cd.call_dest_e164)) {
-				strncpy(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten) - 1);
-			} else {
-				strncpy(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten) - 1);
-			}
-			if (ast_strlen_zero(default_context)) {
-				ast_log(LOG_ERROR, "Call from '%s' rejected due to no default context\n", pvt->cd.call_source_aliases);
-				oh323_destroy(pvt);
-				return NULL;
-			}
-			strncpy(pvt->context, default_context, sizeof(pvt->context) - 1);
-			ast_log(LOG_DEBUG, "Sending %s to context [%s]\n", cd->call_source_aliases, pvt->context);
-			/* XXX: Is it really required??? */
-#if 0
-			memset(&pvt->options, 0, sizeof(pvt->options));
-#endif
-		} else {
-			if (user->host) {
-				if (strcasecmp(cd->sourceIp, ast_inet_ntoa(user->addr.sin_addr))) {
-					if (ast_strlen_zero(user->context)) {
-						if (ast_strlen_zero(default_context)) {
-							ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s) and no default context\n", user->name, cd->sourceIp);
-							oh323_destroy(pvt);
-							ASTOBJ_UNREF(user, oh323_destroy_user);
-							return NULL;
-						}
-						strncpy(pvt->context, default_context, sizeof(pvt->context) - 1);
-					} else {
-						strncpy(pvt->context, user->context, sizeof(pvt->context) - 1);
-					}
-					pvt->exten[0] = 'i';
-					pvt->exten[1] = '\0';
-					ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s)s\n", user->name, cd->sourceIp);
-					oh323_destroy(pvt);
-					ASTOBJ_UNREF(user, oh323_destroy_user);
-					return NULL;	/* XXX: Hmmm... Why to setup context if we drop connection immediately??? */
-				}
-			}
-			strncpy(pvt->context, user->context, sizeof(pvt->context) - 1);
-			memcpy(&pvt->options, &user->options, sizeof(pvt->options));
-			pvt->jointcapability = pvt->options.capability;
-			if (!ast_strlen_zero(pvt->cd.call_dest_e164)) {
-				strncpy(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten) - 1);
-			} else {
-				strncpy(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten) - 1);
-			}
-			if (!ast_strlen_zero(user->accountcode)) {
-				strncpy(pvt->accountcode, user->accountcode, sizeof(pvt->accountcode) - 1);
-			} 
-			if (user->amaflags) {
-				pvt->amaflags = user->amaflags;
-			}
-			ASTOBJ_UNREF(user, oh323_destroy_user);
-		} 
-	}
-	return &pvt->options;
-}
-
-/**
- * Call-back function to start PBX when OpenH323 ready to serve incoming call
- *
- * Returns 1 on success
- */
-static int answer_call(unsigned call_reference, const char *token)
-{
-	struct oh323_pvt *pvt;
-	struct ast_channel *c = NULL;
-
-	if (h323debug)
-		ast_log(LOG_DEBUG, "Preparing Asterisk to answer for %s\n", token);
-
-	/* Find the call or allocate a private structure if call not found */
-	pvt = find_call_locked(call_reference, token); 
-	if (!pvt) {
-		ast_log(LOG_ERROR, "Something is wrong: answer_call\n");
-		return 0;
-	}
-	/* allocate a channel and tell asterisk about it */
-	c = __oh323_new(pvt, AST_STATE_RINGING, pvt->cd.call_token);
-
-	/* And release when done */
-	ast_mutex_unlock(&pvt->lock);
-	if (!c) {
-		ast_log(LOG_ERROR, "Couldn't create channel. This is bad\n");
-		return 0;
-	}
-	return 1;
-}
-
-/**
- * Call-back function to establish an outgoing H.323 call
- * 
- * Returns 1 on success 
- */
-static int setup_outgoing_call(call_details_t *cd)
-{
-	/* Use argument here or free it immediately */
-	cleanup_call_details(cd);
-
-	return 1;
-}
-
-/**
-  *  Call-back function to signal asterisk that the channel is ringing
-  *  Returns nothing
-  */
-static void chan_ringing(unsigned call_reference, const char *token)
-{
-	struct oh323_pvt *pvt;
-
-	if (h323debug)
-		ast_log(LOG_DEBUG, "Ringing on %s\n", token);
-
-	pvt = find_call_locked(call_reference, token); 
-	if (!pvt) {
-		ast_log(LOG_ERROR, "Something is wrong: ringing\n");
-		return;
-	}
-	if (!pvt->owner) {
-		ast_mutex_unlock(&pvt->lock);
-		ast_log(LOG_ERROR, "Channel has no owner\n");
-		return;
-	}
-	update_state(pvt, AST_STATE_RINGING, AST_CONTROL_RINGING);
-	ast_mutex_unlock(&pvt->lock);
-	return;
-}
-
-/**
-  * Call-back function to cleanup communication
-  * Returns nothing,
-  */
-static void cleanup_connection(unsigned call_reference, const char *call_token)
-{	
-	struct oh323_pvt *pvt;
-
-	ast_log(LOG_DEBUG, "Cleaning connection to %s\n", call_token);
-	
-	while (1) {
-		pvt = find_call_locked(call_reference, call_token); 
-		if (!pvt) {
-			if (h323debug)
-				ast_log(LOG_DEBUG, "No connection for %s\n", call_token);
-			return;
-		}
-		if (!pvt->owner || !ast_channel_trylock(pvt->owner))
-			break;
-#if 1
-#ifdef DEBUG_THREADS
-		ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s, locked at %ld/%d by %s (%s:%d)\n", call_token, pvt->owner->lock.thread[0], pvt->owner->lock.reentrancy, pvt->owner->lock.func[0], pvt->owner->lock.file[0], pvt->owner->lock.lineno[0]);
-#else
-		ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s\n", call_token);
-#endif
-#endif
-		ast_mutex_unlock(&pvt->lock);
-		usleep(1);
-	}
-	if (pvt->rtp) {
-		/* Immediately stop RTP */
-		ast_rtp_destroy(pvt->rtp);
-		pvt->rtp = NULL;
-	}
-	/* Free dsp used for in-band DTMF detection */
-	if (pvt->vad) {
-		ast_dsp_free(pvt->vad);
-		pvt->vad = NULL;
-	}
-	cleanup_call_details(&pvt->cd);
-	pvt->alreadygone = 1;
-	/* Send hangup */	
-	if (pvt->owner) {
-		pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV;
-		ast_queue_hangup(pvt->owner);
-		ast_channel_unlock(pvt->owner);
-	}
-	ast_mutex_unlock(&pvt->lock);
-	if (h323debug)
-		ast_log(LOG_DEBUG, "Connection to %s cleaned\n", call_token);
-	return;	
-}
-
-static void hangup_connection(unsigned int call_reference, const char *token, int cause)
-{
-	struct oh323_pvt *pvt;
-
-	if (h323debug) {
-		ast_log(LOG_DEBUG, "Hanging up connection to %s with cause %d\n", token, cause);
-	}
-	
-	pvt = find_call_locked(call_reference, token); 
-	if (!pvt) {
-		if (h323debug) {
-			ast_log(LOG_DEBUG, "Connection to %s already cleared\n", token);
-		}
-		return;
-	}
-	if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
-		pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV;
-		pvt->owner->hangupcause = pvt->hangupcause = cause;
-		ast_queue_hangup(pvt->owner);
-		ast_channel_unlock(pvt->owner);
-	}
-	else {
-		pvt->needhangup = 1;
-		pvt->hangupcause = cause;
-		ast_log(LOG_DEBUG, "Hangup for %s is pending\n", token);
-	}
-	ast_mutex_unlock(&pvt->lock);
-}
-
-static void set_dtmf_payload(unsigned call_reference, const char *token, int payload)
-{
-	struct oh323_pvt *pvt;
-
-	if (h323debug)
-		ast_log(LOG_DEBUG, "Setting DTMF payload to %d on %s\n", payload, token);
-
-	pvt = find_call_locked(call_reference, token);
-	if (!pvt) {
-		return;
-	}
-	if (pvt->rtp) {
-		ast_rtp_set_rtpmap_type(pvt->rtp, payload, "audio", "telephone-event", 0);
-	}
-	pvt->dtmf_pt = payload;
-	ast_mutex_unlock(&pvt->lock);
-	if (h323debug)
-		ast_log(LOG_DEBUG, "DTMF payload on %s set to %d\n", token, payload);
-}
-
-static void set_peer_capabilities(unsigned call_reference, const char *token, int capabilities)
-{
-	struct oh323_pvt *pvt;
-
-	if (h323debug)
-		ast_log(LOG_DEBUG, "Got remote capabilities from connection %s\n", token);
-
-	pvt = find_call_locked(call_reference, token);
-	if (!pvt)
-		return;
-	pvt->peercapability = capabilities;
-	pvt->jointcapability = pvt->options.capability & capabilities;
-	ast_mutex_unlock(&pvt->lock);
-}
-
-static void set_local_capabilities(unsigned call_reference, const char *token)
-{
-	struct oh323_pvt *pvt;
-	int capability, dtmfmode, pref_codec;
-	struct ast_codec_pref prefs;
-
-	if (h323debug)
-		ast_log(LOG_DEBUG, "Setting capabilities for connection %s\n", token);
-
-	pvt = find_call_locked(call_reference, token);
-	if (!pvt)
-		return;
-	capability = (pvt->jointcapability) ? pvt->jointcapability : pvt->options.capability;
-	dtmfmode = pvt->options.dtmfmode;
-	prefs = pvt->options.prefs;
-	pref_codec = pvt->pref_codec;
-	ast_mutex_unlock(&pvt->lock);
-	h323_set_capabilities(token, capability, dtmfmode, &prefs, pref_codec);
-
-	if (h323debug)
-		ast_log(LOG_DEBUG, "Capabilities for connection %s is set\n", token);
-}
-
-static void *do_monitor(void *data)
-{
-	int res;
-	int reloading;
-	struct oh323_pvt *oh323 = NULL;
-	
-	for(;;) {
-		/* Check for a reload request */
-		ast_mutex_lock(&h323_reload_lock);
-		reloading = h323_reloading;
-		h323_reloading = 0;
-		ast_mutex_unlock(&h323_reload_lock);
-		if (reloading) {
-			if (option_verbose > 0) {
-				ast_verbose(VERBOSE_PREFIX_1 "Reloading H.323\n");
-			}
-			h323_do_reload();
-		}
-		/* Check for interfaces needing to be killed */
-		ast_mutex_lock(&iflock);
-#if 1
-		do {
-			for (oh323 = iflist; oh323; oh323 = oh323->next) {
-				if (oh323->needdestroy) {
-					__oh323_destroy(oh323);
-					break;
-				}
-			}
-		} while (oh323);
-#else
-restartsearch:		
-		oh323 = iflist;
-		while(oh323) {
-			if (oh323->needdestroy) {
-				__oh323_destroy(oh323);
-				goto restartsearch;
-			}
-			oh323 = oh323->next;
-		}
-#endif
-		ast_mutex_unlock(&iflock);
-		pthread_testcancel();
-		/* Wait for sched or io */
-		res = ast_sched_wait(sched);
-		if ((res < 0) || (res > 1000)) {
-			res = 1000;
-		}
-		res = ast_io_wait(io, res);
-		pthread_testcancel();
-		ast_mutex_lock(&monlock);
-		if (res >= 0) {
-			ast_sched_runq(sched);
-		}
-		ast_mutex_unlock(&monlock);
-	}
-	/* Never reached */
-	return NULL;
-}
-
-static int restart_monitor(void)
-{
-	pthread_attr_t attr;
-	/* If we're supposed to be stopped -- stay stopped */
-	if (ast_mutex_lock(&monlock)) {
-		ast_log(LOG_WARNING, "Unable to lock monitor\n");
-		return -1;
-	}
-	if (monitor_thread == AST_PTHREADT_STOP) {
-		ast_mutex_unlock(&monlock);
-		return 0;
-	}
-	if (monitor_thread == pthread_self()) {
-		ast_mutex_unlock(&monlock);
-		ast_log(LOG_WARNING, "Cannot kill myself\n");
-		return -1;
-	}
-	if (monitor_thread && (monitor_thread != AST_PTHREADT_NULL)) {
-		/* Wake up the thread */
-		pthread_kill(monitor_thread, SIGURG);
-	} else {	
-		pthread_attr_init(&attr);
-		pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-		/* Start a new monitor */
-		if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) {
-			monitor_thread = AST_PTHREADT_NULL;
-			ast_mutex_unlock(&monlock);
-			ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
-			return -1;
-		}
-	}
-	ast_mutex_unlock(&monlock);
-	return 0;
-}
-
-static int h323_do_trace(int fd, int argc, char *argv[])
-{
-	if (argc != 3) {
-		return RESULT_SHOWUSAGE;
-	}
-	h323_debug(1, atoi(argv[2]));
-	ast_cli(fd, "H.323 trace set to level %s\n", argv[2]);
-	return RESULT_SUCCESS;
-}
-
-static int h323_no_trace(int fd, int argc, char *argv[])
-{
-	if (argc != 3) {
-		return RESULT_SHOWUSAGE;
-	}
-	h323_debug(0,0);
-	ast_cli(fd, "H.323 trace disabled\n");
-	return RESULT_SUCCESS;
-}
-
-static int h323_do_debug(int fd, int argc, char *argv[])
-{
-	if (argc != 2) {
-		return RESULT_SHOWUSAGE;
-	}
-	h323debug = 1;
-	ast_cli(fd, "H323 debug enabled\n");
-	return RESULT_SUCCESS;
-}
-
-static int h323_no_debug(int fd, int argc, char *argv[])
-{
-	if (argc != 3) {
-		return RESULT_SHOWUSAGE;
-	}
-	h323debug = 0;
-	ast_cli(fd, "H323 Debug disabled\n");
-	return RESULT_SUCCESS;
-}
-
-static int h323_gk_cycle(int fd, int argc, char *argv[])
-{
-#if 0
-	if (argc != 3) {
-		return RESULT_SHOWUSAGE;
-	}	
-	h323_gk_urq();
-	
-	/* Possibly register with a GK */
-	if (!gatekeeper_disable) {
-		if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
-			ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
-		}
-	}
-#endif
-	return RESULT_SUCCESS;
-}
-
-static int h323_ep_hangup(int fd, int argc, char *argv[])
-{
-        if (argc != 3) {
-                return RESULT_SHOWUSAGE;
-	}
-	if (h323_soft_hangup(argv[2])) {
-		ast_verbose(VERBOSE_PREFIX_3 "Hangup succeeded on %s\n", argv[2]);
-	} else { 
-		ast_verbose(VERBOSE_PREFIX_3 "Hangup failed for %s\n", argv[2]);
-	}
-	return RESULT_SUCCESS;
-}
-
-static int h323_tokens_show(int fd, int argc, char *argv[])
-{
-        if (argc != 3) {
-                return RESULT_SHOWUSAGE;
-	}
-	h323_show_tokens();
-	return RESULT_SUCCESS;
-}
-
-static char trace_usage[] = 
-"Usage: h.323 trace <level num>\n"
-"       Enables H.323 stack tracing for debugging purposes\n";
-
-static char no_trace_usage[] = 
-"Usage: h.323 no trace\n"
-"       Disables H.323 stack tracing for debugging purposes\n";
-
-static char debug_usage[] = 
-"Usage: h.323 debug\n"
-"       Enables H.323 debug output\n";
-
-static char no_debug_usage[] = 
-"Usage: h.323 no debug\n"
-"       Disables H.323 debug output\n";
-
-static char show_codec_usage[] = 
-"Usage: h.323 show codec\n"
-"       Shows all enabled codecs\n";
-
-static char show_cycle_usage[] = 
-"Usage: h.323 gk cycle\n"
-"       Manually re-register with the Gatekeper (Currently Disabled)\n";
-
-static char show_hangup_usage[] = 
-"Usage: h.323 hangup <token>\n"
-"       Manually try to hang up call identified by <token>\n";
-
-static char show_tokens_usage[] = 
-"Usage: h.323 show tokens\n"
-"       Print out all active call tokens\n";
-
-static char h323_reload_usage[] =
-"Usage: h323 reload\n"
-"       Reloads H.323 configuration from sip.conf\n";
-
-static struct ast_cli_entry  h323_cli[] = {
-	{ { "h.323", "trace", NULL }, h323_do_trace,
-	  "Enable H.323 Stack Tracing", trace_usage },
-	{ { "h.323", "no", "trace", NULL }, h323_no_trace,
-	  "Disable H.323 Stack Tracing", no_trace_usage },
-	{ { "h.323", "debug", NULL }, h323_do_debug,
-	  "Enable H.323 debug", debug_usage },
-	{ { "h.323", "no", "debug", NULL }, h323_no_debug,
-	  "Disable H.323 debug", no_debug_usage },
-	{ { "h.323", "show", "codecs", NULL }, h323_show_codec,
-	  "Show enabled codecs", show_codec_usage },
-	{ { "h.323", "gk", "cycle", NULL }, h323_gk_cycle,
-	  "Manually re-register with the Gatekeper", show_cycle_usage },
-	{ { "h.323", "hangup", NULL }, h323_ep_hangup,
-	  "Manually try to hang up a call", show_hangup_usage },
-	{ { "h.323", "show", "tokens", NULL }, h323_tokens_show,
-	  "Show all active call tokens", show_tokens_usage },
-};
+			if (strcasecmp(v->value, "h323")) { 	
+				ast_log(LOG_WARNING, "Keyword %s does not make sense in type=h323\n", v->value);
+			}
+		}
+	}
+	ASTOBJ_UNMARK(alias);
+	return alias;
+}
 
 static int update_common_options(struct ast_variable *v, struct call_options *options)
 {
@@ -2000,41 +1061,6 @@
 	return 0;
 }
 
-static struct oh323_alias *build_alias(char *name, struct ast_variable *v)
-{
-	struct oh323_alias *alias;
-	int found = 0;
-
-	alias = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&aliasl, name, name, 0, 0, strcasecmp);
-
-	if (alias)
-		found++;
-	else {
-		if (!(alias = (struct oh323_alias *)calloc(1, sizeof(*alias))))
-			return NULL;
-		ASTOBJ_INIT(alias);
-	}
-	if (!found && name)
-		strncpy(alias->name, name, sizeof(alias->name) - 1);
-	for (; v; v = v->next) {
-		if (!strcasecmp(v->name, "e164")) {
-			strncpy(alias->e164,  v->value, sizeof(alias->e164) - 1);
-		} else if (!strcasecmp(v->name, "prefix")) {
-			strncpy(alias->prefix,  v->value, sizeof(alias->prefix) - 1);
-		} else if (!strcasecmp(v->name, "context")) {
-			strncpy(alias->context,  v->value, sizeof(alias->context) - 1);
-		} else if (!strcasecmp(v->name, "secret")) {
-			strncpy(alias->secret,  v->value, sizeof(alias->secret) - 1);
-		} else {
-			if (strcasecmp(v->value, "h323")) { 	
-				ast_log(LOG_WARNING, "Keyword %s does not make sense in type=h323\n", v->value);
-			}
-		}
-	}
-	ASTOBJ_UNMARK(alias);
-	return alias;
-}
-
 static struct oh323_user *build_user(char *name, struct ast_variable *v, int realtime)
 {
 	struct oh323_user *user;
@@ -2058,6 +1084,14 @@
 	strncpy(user->context, default_context, sizeof(user->context) - 1);
 	if (user && !found)
 		strncpy(user->name, name, sizeof(user->name) - 1);
+
+#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 = v->next) {
 		if (!update_common_options(v, &user->options))
 			continue;
@@ -2097,7 +1131,45 @@
 	return user;
 }
 
-static struct oh323_peer *build_peer(char *name, struct ast_variable *v, int realtime)
+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, 1);
+	
+	ast_variables_destroy(var);
+
+	return user;
+}
+
+static struct oh323_peer *build_peer(const char *name, struct ast_variable *v, int realtime)
 {
 	struct oh323_peer *peer;
 	struct ast_ha *oldha;
@@ -2119,6 +1191,7 @@
 	peer->addr.sin_family = AF_INET;
 	if (!found && name)
 		strncpy(peer->name, name, sizeof(peer->name) - 1);
+
 #if 0 /* XXX Port channel variables functionality from chan_sip XXX */
 	if (peer->chanvars) {
 		ast_variables_destroy(peer->chanvars);
@@ -2151,6 +1224,1019 @@
 	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, 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, 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] = "";
+
+	strncpy(peer, opeer, sizeof(peer) - 1);
+	port = strchr(peer, ':');
+	if (port) {
+		*port = '\0';
+		port++;
+	}
+	pvt->sa.sin_family = AF_INET;
+	p = find_peer(peer, NULL, 0);
+	if (p) {
+		found++;
+		memcpy(&pvt->options, &p->options, sizeof(pvt->options));
+		pvt->jointcapability = pvt->options.capability;
+		if (pvt->rtp) {
+			ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat);
+			ast_rtp_setnat(pvt->rtp, pvt->options.nat);
+		}
+		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, 0);
+			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->rtp) {
+				ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat);
+				ast_rtp_setnat(pvt->rtp, pvt->options.nat);
+			}
+			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 (!p) {
+		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];
+	
+	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);
+		return NULL;
+	}
+	strncpy(tmp, dest, sizeof(tmp) - 1);	
+	host = strchr(tmp, '@');
+	if (host) {
+		*host = '\0';
+		host++;
+		ext = tmp;
+	} else {
+		host = tmp;
+		ext = NULL;
+	}
+	strtok_r(host, "/", &(h323id));		
+	if (!ast_strlen_zero(h323id)) {
+		h323_set_id(h323id);
+	}
+	if (ext) {
+		strncpy(pvt->exten, ext, sizeof(pvt->exten) - 1);
+	}
+	ast_log(LOG_DEBUG, "Extension: %s Host: %s\n",  pvt->exten, host);
+	if (!usingGk) {
+		if (create_addr(pvt, host)) {
+			oh323_destroy(pvt);
+			return NULL;
+		}
+	}
+	else {
+		memcpy(&pvt->options, &global_options, sizeof(pvt->options));
+		pvt->jointcapability = pvt->options.capability;
+		if (pvt->rtp) {
+			ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat);
+			ast_rtp_setnat(pvt->rtp, pvt->options.nat);
+		}
+		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);
+	}
+	ast_update_use_count();
+	restart_monitor();
+	return tmpc;
+}
+
+/** Find a call by alias */
+static struct oh323_alias *find_alias(const char *source_aliases)
+{
+	struct oh323_alias *a;
+
+	a = ASTOBJ_CONTAINER_FIND(&aliasl, source_aliases);
+
+#if 0 /* XXX REALTIME XXX */
+	if (!a && realtime)
+		a = realtime_alias(source_aliases);
+#endif
+
+	return a;
+}
+
+/**
+  * Callback for sending digits from H.323 up to asterisk
+  *
+  */
+static int send_digit(unsigned call_reference, char digit, const char *token)
+{
+	struct oh323_pvt *pvt;
+	int res;
+
+	if (digit == ' ') /* DTMF tone update -- ignore */
+		return 0;
+	ast_log(LOG_DEBUG, "Received Digit: %c\n", digit);

[... 733 lines stripped ...]


More information about the asterisk-commits mailing list