[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