[asterisk-commits] mattf: branch mattf/1.6.0-chan_ccs r262894 - /team/mattf/1.6.0-chan_ccs/chann...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu May 13 10:24:19 CDT 2010


Author: mattf
Date: Thu May 13 10:24:15 2010
New Revision: 262894

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=262894
Log:
Commit includes: 1.) Beginnings of MGCP piggy back message support 2.) Better MGCP handling of wildcard requests that include wildcard endpoints 3.) Enable a bunch of SS7 variables and call metadata setting and getting support for SS7 calls.

Modified:
    team/mattf/1.6.0-chan_ccs/channels/chan_ccs.c
    team/mattf/1.6.0-chan_ccs/channels/chan_mgcp.c

Modified: team/mattf/1.6.0-chan_ccs/channels/chan_ccs.c
URL: http://svnview.digium.com/svn/asterisk/team/mattf/1.6.0-chan_ccs/channels/chan_ccs.c?view=diff&rev=262894&r1=262893&r2=262894
==============================================================================
--- team/mattf/1.6.0-chan_ccs/channels/chan_ccs.c (original)
+++ team/mattf/1.6.0-chan_ccs/channels/chan_ccs.c Thu May 13 10:24:15 2010
@@ -140,6 +140,7 @@
 	char cid_ani[AST_MAX_EXTENSION];
 	int cid_ani2;
 	int cid_ton;					/*!< Type Of Number (TON) */
+	char rdnis[AST_MAX_EXTENSION];
 	char dnid[AST_MAX_EXTENSION];
 
 	char bearer_tech_str[TEL_MAX_REQUEST_SZ];
@@ -614,9 +615,32 @@
 	return 0;
 }
 
+static unsigned char cid_pres2ss7pres(int cid_pres)
+{
+	 return (cid_pres >> 5) & 0x03;
+}
+
+static unsigned char cid_pres2ss7screen(int cid_pres)
+{
+	return cid_pres & 0x03;
+}
+
 static int ccs_call(struct ast_channel *ast, char *dest, int timeout)
 {
 	struct ccs_chan *p = ast->tech_pvt;
+	const char *charge_str = NULL;
+	const char *gen_address = NULL;
+	const char *gen_digits = NULL;
+	const char *gen_dig_type = NULL;
+	const char *gen_dig_scheme = NULL;
+	const char *gen_name = NULL;
+	const char *jip_digits = NULL;
+	const char *lspi_ident = NULL;
+	const char *rlt_flag = NULL;
+	const char *call_ref_id = NULL;
+	const char *call_ref_pc = NULL;
+	const char *send_far = NULL;
+	char *l;
 	int res;
 
 	ast_log(LOG_ERROR, "call: chan %s dest %s timeout %d\n", ast->name, dest, timeout);
@@ -641,9 +665,59 @@
 
 	ast_log(LOG_ERROR, "CCS called with %s:%d\n", dest, timeout);
 
+	l = ast->cid.cid_num;
 	p->sig.ss7.call = isup_new_call(p->sig.ss7.ss7->ss7);
  	isup_set_called(p->sig.ss7.call, p->exten, p->sig.ss7.ss7->called_nai, p->sig.ss7.ss7->ss7);
+	isup_set_calling(p->sig.ss7.call, l, p->sig.ss7.ss7->calling_nai,
+			cid_pres2ss7pres(ast->cid.cid_pres),
+			cid_pres2ss7screen(ast->cid.cid_pres));
+
+	isup_set_oli(p->sig.ss7.call, ast->cid.cid_ani2);
 	isup_init_call(p->sig.ss7.ss7->ss7, p->sig.ss7.call, p->sig.ss7.cic, p->sig.ss7.dpc);
+
+	/* Set the charge number if it is set */
+	charge_str = pbx_builtin_getvar_helper(ast, "SS7_CHARGE_NUMBER");
+	if (charge_str)
+		isup_set_charge(p->sig.ss7.call, charge_str, SS7_ANI_CALLING_PARTY_SUB_NUMBER, 0x10);
+	
+	gen_address = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_ADDRESS");
+	if (gen_address)
+		isup_set_gen_address(p->sig.ss7.call, gen_address, p->gen_add_nai,p->gen_add_pres_ind, p->gen_add_num_plan,p->gen_add_type); /* need to add some types here for NAI,PRES,TYPE */
+	
+	gen_digits = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGITS");
+	gen_dig_type = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGTYPE");
+	gen_dig_scheme = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGSCHEME");
+	if (gen_digits)
+		isup_set_gen_digits(p->sig.ss7.call, gen_digits, atoi(gen_dig_type), atoi(gen_dig_scheme)); 
+	
+	gen_name = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_NAME");
+	if (gen_name)
+		isup_set_generic_name(p->sig.ss7.call, gen_name, GEN_NAME_TYPE_CALLING_NAME, GEN_NAME_AVAIL_AVAILABLE, GEN_NAME_PRES_ALLOWED);
+
+	jip_digits = pbx_builtin_getvar_helper(ast, "SS7_JIP");
+	if (jip_digits)
+		isup_set_jip_digits(p->sig.ss7.call, jip_digits);
+	
+	lspi_ident = pbx_builtin_getvar_helper(ast, "SS7_LSPI_IDENT");
+	if (lspi_ident)
+		isup_set_lspi(p->sig.ss7.call, lspi_ident, 0x18, 0x7, 0x00); 
+	
+	rlt_flag = pbx_builtin_getvar_helper(ast, "SS7_RLT_ON");
+	if ((rlt_flag) && ((strncmp("NO", rlt_flag, strlen(rlt_flag))) != 0 )) {
+		isup_set_lspi(p->sig.ss7.call, rlt_flag, 0x18, 0x7, 0x00); /* Setting for Nortel DMS-250/500 */
+	}
+	
+	call_ref_id = pbx_builtin_getvar_helper(ast, "SS7_CALLREF_IDENT");
+	call_ref_pc = pbx_builtin_getvar_helper(ast, "SS7_CALLREF_PC");
+	if (call_ref_id && call_ref_pc) {
+		isup_set_callref(p->sig.ss7.call, atoi(call_ref_id),
+				 call_ref_pc ? atoi(call_ref_pc) : 0);
+	}
+	
+	send_far = pbx_builtin_getvar_helper(ast, "SS7_SEND_FAR");
+	if ((send_far) && ((strncmp("NO", send_far, strlen(send_far))) != 0 ))
+		(isup_far(p->sig.ss7.ss7->ss7, p->sig.ss7.call));
+		
 	isup_iam(p->sig.ss7.ss7->ss7, p->sig.ss7.call);
 
 	CLEANUP(ast, p);
@@ -717,7 +791,7 @@
 	ast_copy_string(c->exten, called_num, sizeof(c->exten));
 
 	/* TODO: Fix exten and context */
-	if (!(c->owner = ast_channel_alloc(1, state, 0, 0, "", c->exten, c->context, 0, "CCS/%s/%d-%d", c->sig.ss7.ss7->name, c->sig.ss7.cic, c->sig.ss7.dpc))) {
+	if (!(c->owner = ast_channel_alloc(1, state, c->cid_num, c->cid_name, "", c->exten, c->context, c->amaflags, "CCS/%s/%d-%d", c->sig.ss7.ss7->name, c->sig.ss7.cic, c->sig.ss7.dpc))) {
 		ast_log(LOG_ERROR, "Could not allocate ast_channel for bearer!\n");
 		return NULL;
 	}
@@ -726,6 +800,27 @@
 
 	ast->tech = &ccs_tech;
 	ast->tech_pvt = c;
+
+	if (!ast_strlen_zero(c->exten))
+		ast_copy_string(ast->exten, c->exten, sizeof(ast->exten));
+	if (!ast_strlen_zero(c->rdnis))
+		ast->cid.cid_rdnis = ast_strdup(c->rdnis);
+	if (!ast_strlen_zero(c->dnid))
+		ast->cid.cid_dnid = ast_strdup(c->dnid);
+
+	/* Don't use ast_set_callerid() here because it will
+	 * generate a needless NewCallerID event */
+#ifdef PRI_ANI
+	if (!ast_strlen_zero(c->cid_ani))
+		ast->cid.cid_ani = ast_strdup(c->cid_ani);
+	else	
+		ast->cid.cid_ani = ast_strdup(c->cid_num);
+#else
+	ast->cid.cid_ani = ast_strdup(c->cid_num);
+#endif
+	ast->cid.cid_pres = c->callingpres;
+	ast->cid.cid_ton = c->cid_ton;
+	ast->cid.cid_ani2 = c->cid_ani2;
 
 	return ast;
 }
@@ -953,6 +1048,7 @@
 {
 	struct ss7 *ss7 = linkset->ss7;
 	struct ast_channel *c;
+	char tmp[256];
 
 #if 0
 	if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &law) == -1)
@@ -990,7 +1086,7 @@
 	 * when receiving either and IAM or a COT message.  Since they are only accessed
 	 * from this context, we should be safe to unlock around them */
 
-#if 0
+#if 1
 	if (!ast_strlen_zero(p->charge_number)) {
 		pbx_builtin_setvar_helper(c, "SS7_CHARGE_NUMBER", p->charge_number);
 		/* Clear this after we set it */
@@ -1694,6 +1790,7 @@
 	chan->sig.ss7.ss7 = ss7;
 
 	chan->sigtype = CCS_SIG_SS7;
+	chan->use_callerid = 1;
 
 	ast_mutex_init(&chan->lock);
 

Modified: team/mattf/1.6.0-chan_ccs/channels/chan_mgcp.c
URL: http://svnview.digium.com/svn/asterisk/team/mattf/1.6.0-chan_ccs/channels/chan_mgcp.c?view=diff&rev=262894&r1=262893&r2=262894
==============================================================================
--- team/mattf/1.6.0-chan_ccs/channels/chan_mgcp.c (original)
+++ team/mattf/1.6.0-chan_ccs/channels/chan_mgcp.c Thu May 13 10:24:15 2010
@@ -221,8 +221,8 @@
 /*! The private structures of the  mgcp channels are linked for
   ! selecting outgoing channels */
    
-#define MGCP_MAX_HEADERS	64
-#define MGCP_MAX_LINES		64
+#define MGCP_MAX_HEADERS	128
+#define MGCP_MAX_LINES		128
 
 struct mgcp_request {
 	int len;
@@ -1682,6 +1682,8 @@
 	char tmp[256] = "";
 	char *at = NULL, *c;
 	int found = 0;
+	int wildcard = 0;
+
 	if (name) {
 		ast_copy_string(tmp, name, sizeof(tmp));
 		at = strchr(tmp, '@');
@@ -1735,6 +1737,10 @@
 				continue;
 			}
 			/* SC */
+			if (name && strchr(name, '*')) {
+				ast_debug(1, "Found wildcard on %s@%s, using wildcard endpoint for gateway %s\n", tmp, at, g->name);
+				wildcard = 1;
+			}
 			p = g->endpoints;
 			while(p) {
 				ast_debug(1, "Searching on %s@%s for subchannel\n",
@@ -1762,6 +1768,8 @@
 					found = 1;
 					/* SC */
 					break;
+				} else if (wildcard && !strcasecmp(g->wcardep, p->name)) {
+					sub = p->sub;
 				} else if (name && !strcasecmp(p->name, tmp)) {
 					ast_debug(1, "Coundn't determine subchannel, assuming current master %s@%s-%d\n", 
 						p->name, g->name, p->sub->id);
@@ -1788,6 +1796,42 @@
 		} 
 	}
 	return sub;
+}
+
+static int find_piggyback(struct mgcp_request *req, struct mgcp_request *extra)
+{
+	char *m2, *c;
+	int removecnt = 0;
+
+	m2 = c = strstr("\n.", req->data);
+
+	if (!c)
+		return 0;
+
+	c++;
+	*c = 0;
+
+	req->len = strlen(req->data);
+
+	if (!strncasecmp(c, "\r\n", 2)) {
+		removecnt = 2;
+	} else if (!strncasecmp(c, "\n", 1)) {
+		removecnt = 1;
+	} else {
+		ast_log(LOG_ERROR, "Huh, error parsing out piggyback message!\n");
+		return 0;
+	}
+
+	while (removecnt) {
+		*c = 0;
+		c++;
+	}
+	memset(extra, 0, sizeof(*extra));
+
+	extra->len = strlen(c);
+	memcpy(extra->data, c, extra->len);
+
+	return 1;
 }
 
 static void parse(struct mgcp_request *req)
@@ -3153,6 +3197,23 @@
 			}
 			/* For RSIP on wildcard we reset all endpoints */
 			if (!strcmp(p->name, p->parent->wcardep)) {
+				char *at, *lefthalf;
+				char tmp[256];
+
+				ast_copy_string(tmp, req->endpoint, sizeof(tmp));
+				at = strchr(tmp, '@');
+				if (!at) {
+					ast_log(LOG_NOTICE, "Endpoint '%s' has no at sign!\n", tmp);
+					return -1;
+				}
+				*at++ = '\0';
+
+				at = strchr(tmp, '*');
+				*at = '\0';
+				lefthalf = tmp;
+
+				ast_log(LOG_ERROR, "Found WC ep, left half is now '%s'\n", lefthalf);
+				
 				/* Reset all endpoints */
 				struct mgcp_endpoint *tmp_ep;
 				
@@ -3160,7 +3221,7 @@
 				tmp_ep = g->endpoints;
 				while (tmp_ep) {
 					/*if ((strcmp(tmp_ep->name, "*") != 0) && (strcmp(tmp_ep->name, "aaln/" "*") != 0)) {*/
-					if (strcmp(tmp_ep->name, g->wcardep) != 0) {
+					if (strcmp(tmp_ep->name, g->wcardep) && !strcasecmp(lefthalf, tmp_ep->name)) {
 						struct mgcp_subchannel *tmp_sub, *first_sub;
 						ast_verb(3, "Resetting interface %s@%s\n", tmp_ep->name, p->parent->name);
 						
@@ -3542,47 +3603,26 @@
 	return 0;
 }
 
-static int mgcpsock_read(int *id, int fd, short events, void *ignore)
-{
-	struct mgcp_request req;
-	struct sockaddr_in sin;
+static int mgcp_process_request(struct mgcp_request *req, struct sockaddr_in *sin, int as_gateway)
+{
 	struct mgcp_subchannel *sub;
-	int res;
-	socklen_t len;
 	int result;
 	int ident;
-	int as_gateway = 0;
-	len = sizeof(sin);
-	memset(&req, 0, sizeof(req));
-	res = recvfrom(fd, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
-	if (res < 0) {
-		if (errno != ECONNREFUSED)
-			ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
-		return 1;
-	}
-
-	if (fd == mgcpsock_ca) {
-		ast_log(LOG_ERROR, "Got read from CA sock!\n");
-		as_gateway = 1;
-	}
-	req.data[res] = '\0';
-	req.len = res;
-	if (mgcpdebug) {
-		ast_verbose("MGCP read: \n%s\nfrom %s:%d\n", req.data, ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
-	}
-	parse(&req);
-	if (req.headers < 1) {
+
+	parse(req);
+
+	if (req->headers < 1) {
 		/* Must have at least one header */
 		return 1;
 	}
-	if (ast_strlen_zero(req.identifier)) {
-		ast_log(LOG_NOTICE, "Message from %s missing identifier\n", ast_inet_ntoa(sin.sin_addr));
+	if (ast_strlen_zero(req->identifier)) {
+		ast_log(LOG_NOTICE, "Message from %s missing identifier\n", ast_inet_ntoa(sin->sin_addr));
 		return 1;
 	}
 
-	if (sscanf(req.verb, "%d", &result) && sscanf(req.identifier, "%d", &ident)) {
+	if (sscanf(req->verb, "%d", &result) && sscanf(req->identifier, "%d", &ident)) {
 		/* Try to find who this message is for, if it's important */
-		sub = find_subchannel_and_lock(NULL, ident, &sin, as_gateway);
+		sub = find_subchannel_and_lock(NULL, ident, sin, as_gateway);
 		if (sub) {
 			struct mgcp_gateway *gw = sub->parent->parent;
 			struct mgcp_message *cur, *prev;
@@ -3607,6 +3647,112 @@
 
 			ast_mutex_unlock(&gw->msgs_lock);
 			if (cur) {
+				handle_response(cur->owner_ep, cur->owner_sub, result, ident, req);
+				ast_free(cur);
+				return 1;
+			}
+
+			ast_log(LOG_NOTICE, "Got response back on [%s] for transaction %d we aren't sending?\n", 
+				gw->name, ident);
+		}
+	} else {
+		if (ast_strlen_zero(req->endpoint) || 
+		    	ast_strlen_zero(req->version) || 
+			ast_strlen_zero(req->verb)) {
+			ast_log(LOG_NOTICE, "Message must have a verb, an idenitifier, version, and endpoint\n");
+			return 1;
+		}
+		/* Process request, with iflock held */
+		sub = find_subchannel_and_lock(req->endpoint, 0, sin, as_gateway);
+		if (sub) {
+			/* look first to find a matching response in the queue */
+			if (!find_and_retrans(sub, req))
+				/* pass the request off to the currently mastering subchannel */
+				handle_request(sub, req, sin);
+			ast_mutex_unlock(&sub->lock);
+		}
+	}
+	return 1;
+}
+
+static int mgcpsock_read(int *id, int fd, short events, void *ignore)
+{
+	struct mgcp_request req, piggy;
+	struct sockaddr_in sin;
+	int res;
+	socklen_t len;
+	int as_gateway = 0;
+	int do_two;
+	len = sizeof(sin);
+	memset(&req, 0, sizeof(req));
+	res = recvfrom(fd, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
+	if (res < 0) {
+		if (errno != ECONNREFUSED)
+			ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
+		return 1;
+	}
+
+	if (fd == mgcpsock_ca) {
+		ast_log(LOG_ERROR, "Got read from CA sock!\n");
+		as_gateway = 1;
+	}
+	req.data[res] = '\0';
+	req.len = res;
+	if (mgcpdebug) {
+		ast_verbose("MGCP read: \n%s\nfrom %s:%d\n", req.data, ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
+	}
+
+	do_two = find_piggyback(&req, &piggy);
+
+	if (mgcpdebug && do_two) {
+		ast_verbose("MGCP read first message: \n%s\nfrom %s:%d\n", req.data, ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
+		ast_verbose("MGCP read second message: \n%s\nfrom %s:%d\n", piggy.data, ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
+	}
+
+	mgcp_process_request(&req, &sin, as_gateway);
+
+	if (do_two)
+		mgcp_process_request(&piggy, &sin, as_gateway);
+
+	return 1;
+
+#if 0
+	if (req.headers < 1) {
+		/* Must have at least one header */
+		return 1;
+	}
+	if (ast_strlen_zero(req.identifier)) {
+		ast_log(LOG_NOTICE, "Message from %s missing identifier\n", ast_inet_ntoa(sin.sin_addr));
+		return 1;
+	}
+
+	if (sscanf(req.verb, "%d", &result) && sscanf(req.identifier, "%d", &ident)) {
+		/* Try to find who this message is for, if it's important */
+		sub = find_subchannel_and_lock(NULL, ident, &sin, as_gateway);
+		if (sub) {
+			struct mgcp_gateway *gw = sub->parent->parent;
+			struct mgcp_message *cur, *prev;
+
+			ast_mutex_unlock(&sub->lock);
+			ast_mutex_lock(&gw->msgs_lock);
+			for (prev = NULL, cur = gw->msgs; cur; prev = cur, cur = cur->next) {
+				if (cur->seqno == ident) {
+					ast_debug(1, "Got response back on transaction %d\n", ident);
+					if (prev)
+						prev->next = cur->next;
+					else
+						gw->msgs = cur->next;
+					break;
+				}
+			}
+
+			/* stop retrans timer if the queue is empty */
+			if (!gw->msgs) {
+				AST_SCHED_DEL(sched, gw->retransid);
+			}
+
+			ast_mutex_unlock(&gw->msgs_lock);
+			if (cur) {
 				handle_response(cur->owner_ep, cur->owner_sub, result, ident, &req);
 				ast_free(cur);
 				return 1;
@@ -3633,6 +3779,7 @@
 		}
 	}
 	return 1;
+#endif
 }
 
 static int *mgcpsock_read_id = NULL;




More information about the asterisk-commits mailing list