Index: chan_mgcp.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_mgcp.c,v retrieving revision 1.95 diff -u -r1.95 chan_mgcp.c --- chan_mgcp.c 17 Nov 2004 19:11:33 -0000 1.95 +++ chan_mgcp.c 26 Nov 2004 09:53:11 -0000 @@ -72,7 +72,6 @@ #include #include #include -#include #include #include #include @@ -151,8 +150,7 @@ static char language[MAX_LANGUAGE] = ""; static char musicclass[MAX_LANGUAGE] = ""; -static char cid_num[AST_MAX_EXTENSION] = ""; -static char cid_name[AST_MAX_EXTENSION] = ""; +static char callerid[AST_MAX_EXTENSION] = ""; static int dtmfmode = 0; static int nat = 0; @@ -358,8 +356,7 @@ char exten[AST_MAX_EXTENSION]; /* Extention where to start */ char context[AST_MAX_EXTENSION]; char language[MAX_LANGUAGE]; - char cid_num[AST_MAX_EXTENSION]; /* Caller*ID */ - char cid_name[AST_MAX_EXTENSION]; /* Caller*ID */ + char callerid[AST_MAX_EXTENSION]; /* Caller*ID */ char lastcallerid[AST_MAX_EXTENSION]; /* Last Caller*ID */ char call_forward[AST_MAX_EXTENSION]; /* Last Caller*ID */ char mailbox[AST_MAX_EXTENSION]; @@ -448,7 +445,7 @@ static int transmit_response(struct mgcp_subchannel *sub, char *msg, struct mgcp_request *req, char *msgrest); static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone); static int transmit_modify_request(struct mgcp_subchannel *sub); -static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername); +static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callerid); static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp *rtp, int codecs); static int transmit_connection_del(struct mgcp_subchannel *sub); static int transmit_audit_endpoint(struct mgcp_endpoint *p); @@ -461,7 +458,7 @@ static int has_voicemail(struct mgcp_endpoint *p) { - return ast_app_has_voicemail(p->mailbox, NULL); + return ast_app_has_voicemail(p->mailbox); } static int unalloc_sub(struct mgcp_subchannel *sub) @@ -575,6 +572,7 @@ static void mgcp_queue_frame(struct mgcp_subchannel *sub, struct ast_frame *f) { + int i = 0; for(;;) { if (sub->owner) { if (!ast_mutex_trylock(&sub->owner->lock)) { @@ -582,6 +580,7 @@ ast_mutex_unlock(&sub->owner->lock); break; } else { + ast_log(LOG_ERROR, "Unable to aquire lock (n=%d)\n", ++i); ast_mutex_unlock(&sub->lock); usleep(1); ast_mutex_lock(&sub->lock); @@ -593,6 +592,7 @@ static void mgcp_queue_hangup(struct mgcp_subchannel *sub) { + int i = 0; for(;;) { if (sub->owner) { if (!ast_mutex_trylock(&sub->owner->lock)) { @@ -600,6 +600,7 @@ ast_mutex_unlock(&sub->owner->lock); break; } else { + ast_log(LOG_ERROR, "Unable to aquire lock (n=%d)\n", ++i); ast_mutex_unlock(&sub->lock); usleep(1); ast_mutex_lock(&sub->lock); @@ -887,7 +888,7 @@ transmit_modify_request(sub->next); } - transmit_notify_request_with_callerid(sub, tone, ast->cid.cid_num, ast->cid.cid_name); + transmit_notify_request_with_callerid(sub, tone, ast->callerid); ast_setstate(ast, AST_STATE_RINGING); if (sub->next->owner && strlen(sub->next->cxident) && strlen(sub->next->callid)) { @@ -910,60 +911,61 @@ struct mgcp_subchannel *sub = ast->pvt->pvt; struct mgcp_endpoint *p = sub->parent; - if (option_debug) + if (option_debug) { ast_log(LOG_DEBUG, "mgcp_hangup(%s)\n", ast->name); + } if (!ast->pvt->pvt) { ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n"); return 0; } - if (strcmp(sub->magic, MGCP_SUBCHANNEL_MAGIC)) { + ast_mutex_lock(&sub->lock); + if (strcmp(sub->magic, MGCP_SUBCHANNEL_MAGIC)) { ast_log(LOG_DEBUG, "Invalid magic. MGCP subchannel freed up already.\n"); + ast_mutex_unlock(&sub->lock); return 0; - } - if (mgcpdebug) { - ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_hangup(%s) on %s@%s\n", ast->name, p->name, p->parent->name); - } + } + if (mgcpdebug) { + ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_hangup(%s) on %s@%s\n", ast->name, p->name, p->parent->name); + } - if ((p->dtmfmode & MGCP_DTMF_INBAND) && (p->dsp != NULL)){ - /* SC: check whether other channel is active. */ - if (!sub->next->owner) - { - if (mgcpdebug) { - ast_verbose(VERBOSE_PREFIX_2 "MGCP free dsp on %s@%s\n", p->name, p->parent->name); - } - ast_dsp_free(p->dsp); - p->dsp = NULL; - } - } - ast_mutex_lock(&sub->lock); + if ((p->dtmfmode & MGCP_DTMF_INBAND) && p->dsp) { + /* SC: check whether other channel is active. */ + if (!sub->next->owner) { + if (mgcpdebug) { + ast_verbose(VERBOSE_PREFIX_2 "MGCP free dsp on %s@%s\n", p->name, p->parent->name); + } + ast_dsp_free(p->dsp); + p->dsp = NULL; + } + } sub->owner = NULL; if (strlen(sub->cxident)) { transmit_connection_del(sub); - } - sub->cxident[0] = '\0'; - if ((sub == p->sub) && sub->next->owner) { - if (p->hookstate == MGCP_OFFHOOK) { - if (sub->next->owner && ast_bridged_channel(sub->next->owner)) { - transmit_notify_request_with_callerid(p->sub, "L/wt", ast_bridged_channel(sub->next->owner)->cid.cid_num, ast_bridged_channel(sub->next->owner)->cid.cid_name); - } - } else { - /* set our other connection as the primary and swith over to it */ - p->sub = sub->next; - p->sub->cxmode = MGCP_CX_RECVONLY; - transmit_modify_request(p->sub); - if (sub->next->owner && ast_bridged_channel(sub->next->owner)) { - transmit_notify_request_with_callerid(p->sub, "L/rg", ast_bridged_channel(sub->next->owner)->cid.cid_num, ast_bridged_channel(sub->next->owner)->cid.cid_name); - } - } + } + sub->cxident[0] = '\0'; + if ((sub == p->sub) && sub->next->owner) { + if (p->hookstate == MGCP_OFFHOOK) { + if (sub->next->owner && sub->next->owner->bridge) { + transmit_notify_request_with_callerid(p->sub, "L/wt", sub->next->owner->bridge->callerid); + } + } else { + /* set our other connection as the primary and swith over to it */ + p->sub = sub->next; + p->sub->cxmode = MGCP_CX_RECVONLY; + transmit_modify_request(p->sub); + if (sub->next->owner && sub->next->owner->bridge) { + transmit_notify_request_with_callerid(p->sub, "L/rg", sub->next->owner->callerid); + } + } - } else if ((sub == p->sub->next) && p->hookstate == MGCP_OFFHOOK) { - transmit_notify_request(sub, "L/v"); - } else if (p->hookstate == MGCP_OFFHOOK) { - transmit_notify_request(sub, "L/ro"); - } else { - transmit_notify_request(sub, ""); - } + } else if ((sub == p->sub->next) && p->hookstate == MGCP_OFFHOOK) { + transmit_notify_request(sub, "L/v"); + } else if (p->hookstate == MGCP_OFFHOOK) { + transmit_notify_request(sub, "L/ro"); + } else { + transmit_notify_request(sub, ""); + } ast->pvt->pvt = NULL; sub->alreadygone = 0; @@ -978,25 +980,25 @@ } /* SC: Decrement use count */ - ast_mutex_lock(&usecnt_lock); + ast_mutex_lock(&usecnt_lock); usecnt--; ast_mutex_unlock(&usecnt_lock); ast_update_use_count(); - /* SC: Decrement use count */ + /* SC: Decrement use count */ - if ((p->hookstate == MGCP_ONHOOK) && (!sub->next->rtp)) { - if (has_voicemail(p)) { - if (mgcpdebug) { - ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_hangup(%s) on %s@%s set vmwi(+)\n", ast->name, p->name, p->parent->name); - } - transmit_notify_request(sub, "L/vmwi(+)"); - } else { - if (mgcpdebug) { - ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_hangup(%s) on %s@%s set vmwi(-)\n", ast->name, p->name, p->parent->name); - } - transmit_notify_request(sub, "L/vmwi(-)"); - } - } + if ((p->hookstate == MGCP_ONHOOK) && (!sub->next->rtp)) { + if (has_voicemail(p)) { + if (mgcpdebug) { + ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_hangup(%s) on %s@%s set vmwi(+)\n", ast->name, p->name, p->parent->name); + } + transmit_notify_request(sub, "L/vmwi(+)"); + } else { + if (mgcpdebug) { + ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_hangup(%s) on %s@%s set vmwi(-)\n", ast->name, p->name, p->parent->name); + } + transmit_notify_request(sub, "L/vmwi(-)"); + } + } ast_mutex_unlock(&sub->lock); return 0; } @@ -1199,7 +1201,7 @@ { struct mgcp_subchannel *sub = newchan->pvt->pvt; ast_mutex_lock(&sub->lock); - ast_log(LOG_NOTICE, "mgcp_fixup(%s, %s)\n", oldchan->name, newchan->name); + ast_log(LOG_NOTICE, "mgcp_fixup(%s, %s)\n", oldchan->name, newchan->name); if (sub->owner != oldchan) { ast_mutex_unlock(&sub->lock); ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, sub->owner); @@ -1293,9 +1295,9 @@ static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state) { struct ast_channel *tmp; - struct mgcp_endpoint *i = sub->parent; + struct mgcp_endpoint *i = sub->parent; int fmt; - i = sub->parent; + i = sub->parent; tmp = ast_channel_alloc(1); if (tmp) { tmp->nativeformats = i->capability; @@ -1347,10 +1349,8 @@ strncpy(tmp->call_forward, i->call_forward, sizeof(tmp->call_forward) - 1); strncpy(tmp->context, i->context, sizeof(tmp->context)-1); strncpy(tmp->exten, i->exten, sizeof(tmp->exten)-1); - if (!ast_strlen_zero(i->cid_num)) - tmp->cid.cid_num = strdup(i->cid_num); - if (!ast_strlen_zero(i->cid_name)) - tmp->cid.cid_name = strdup(i->cid_name); + if (strlen(i->callerid)) + tmp->callerid = strdup(i->callerid); if (!i->adsi) tmp->adsicpe = AST_ADSI_UNAVAILABLE; tmp->priority = 1; @@ -1371,7 +1371,8 @@ return tmp; } -static char* get_sdp_by_line(char* line, char *name, int nameLen) { +static char* get_sdp_by_line(char* line, char *name, int nameLen) +{ if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') { char* r = line + nameLen + 1; while (*r && (*r < 33)) ++r; @@ -1381,7 +1382,8 @@ return ""; } -static char *get_sdp(struct mgcp_request *req, char *name) { +static char *get_sdp(struct mgcp_request *req, char *name) +{ int x; int len = strlen(name); char *r; @@ -1393,12 +1395,13 @@ return ""; } -static void sdpLineNum_iterator_init(int* iterator) { +static void sdpLineNum_iterator_init(int* iterator) +{ *iterator = 0; } -static char* get_sdp_iterate(int* iterator, - struct mgcp_request *req, char *name) { +static char* get_sdp_iterate(int* iterator, struct mgcp_request *req, char *name) +{ int len = strlen(name); char *r; while (*iterator < req->lines) { @@ -1463,7 +1466,7 @@ char iabuf[INET_ADDRSTRLEN]; char tmp[256] = ""; char *at = NULL, *c; - int found = 0; + int found = 0; if (name) { strncpy(tmp, name, sizeof(tmp) - 1); at = strchr(tmp, '@'); @@ -1687,7 +1690,7 @@ struct ast_hostent ahp; struct hostent *hp; int codec; int iterator; - struct mgcp_endpoint *p = sub->parent; + struct mgcp_endpoint *p = sub->parent; /* Get codec and RTP info from SDP */ m = get_sdp(req, "m"); @@ -1718,7 +1721,7 @@ printf("Peer RTP is at port %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); #endif // Scan through the RTP payload types specified in a "m=" line: - ast_rtp_pt_clear(sub->rtp); + ast_rtp_pt_clear(sub->rtp); codecs = m + len; while(strlen(codecs)) { if (sscanf(codecs, "%d %n", &codec, &len) != 1) { @@ -1755,7 +1758,6 @@ return -1; } return 0; - } static int add_header(struct mgcp_request *req, char *var, char *value) @@ -1771,9 +1773,9 @@ req->header[req->headers] = req->data + req->len; snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s: %s\r\n", var, value); req->len += strlen(req->header[req->headers]); - if (req->headers < MGCP_MAX_HEADERS) + if (req->headers < MGCP_MAX_HEADERS) { req->headers++; - else { + } else { ast_log(LOG_WARNING, "Out of header space\n"); return -1; } @@ -1794,9 +1796,9 @@ req->line[req->lines] = req->data + req->len; snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); req->len += strlen(req->line[req->lines]); - if (req->lines < MGCP_MAX_LINES) + if (req->lines < MGCP_MAX_LINES) { req->lines++; - else { + } else { ast_log(LOG_WARNING, "Out of line space\n"); return -1; } @@ -1844,7 +1846,7 @@ static int respprep(struct mgcp_request *resp, struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest) { - memset(resp, 0, sizeof(*resp)); + memset(resp, 0, sizeof(struct mgcp_request)); init_resp(resp, msg, req, msgrest); return 0; } @@ -1862,7 +1864,7 @@ static int transmit_response(struct mgcp_subchannel *sub, char *msg, struct mgcp_request *req, char *msgrest) { struct mgcp_request resp; - struct mgcp_endpoint *p = sub->parent; + struct mgcp_endpoint *p = sub->parent; struct mgcp_response *mgr; respprep(&resp, p, msg, req, msgrest); mgr = malloc(sizeof(struct mgcp_response) + resp.len + 1); @@ -1897,7 +1899,7 @@ char iabuf[INET_ADDRSTRLEN]; int x; struct sockaddr_in dest; - struct mgcp_endpoint *p = sub->parent; + struct mgcp_endpoint *p = sub->parent; /* XXX We break with the "recommendation" and send our IP, in order that our peer doesn't have to ast_gethostbyname() us XXX */ len = 0; @@ -1921,7 +1923,7 @@ } if (mgcpdebug) { ast_verbose("We're at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->parent->ourip), ntohs(sin.sin_port)); - } + } snprintf(v, sizeof(v), "v=0\r\n"); snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", getpid(), getpid(), ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr)); snprintf(s, sizeof(s), "s=session\r\n"); @@ -1981,7 +1983,7 @@ char tmp[80]; int x; int capability; - struct mgcp_endpoint *p = sub->parent; + struct mgcp_endpoint *p = sub->parent; capability = p->capability; if (codecs) capability = codecs; @@ -2002,15 +2004,15 @@ add_header(&resp, "C", sub->callid); add_header(&resp, "L", local); add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]); - /* SC: X header should not be sent. kept for compatibility */ + /* SC: X header should not be sent. kept for compatibility */ add_header(&resp, "X", sub->txident); add_header(&resp, "I", sub->cxident); /*add_header(&resp, "S", "");*/ ast_rtp_offered_from_local(sub->rtp, 0); add_sdp(&resp, sub, rtp); - /* SC: fill in new fields */ - resp.cmd = MGCP_CMD_MDCX; - resp.trid = oseq; + /* SC: fill in new fields */ + resp.cmd = MGCP_CMD_MDCX; + resp.trid = oseq; return send_request(p, sub, &resp, oseq); /* SC */ } @@ -2020,7 +2022,7 @@ char local[256]; char tmp[80]; int x; - struct mgcp_endpoint *p = sub->parent; + struct mgcp_endpoint *p = sub->parent; snprintf(local, sizeof(local), "p:20"); for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) { @@ -2029,22 +2031,22 @@ strncat(local, tmp, sizeof(local) - strlen(local) - 1); } } - if (mgcpdebug) { - ast_verbose(VERBOSE_PREFIX_3 "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n", - p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid); - } + if (mgcpdebug) { + ast_verbose(VERBOSE_PREFIX_3 "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n", + p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid); + } reqprep(&resp, p, "CRCX"); add_header(&resp, "C", sub->callid); add_header(&resp, "L", local); add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]); - /* SC: X header should not be sent. kept for compatibility */ + /* SC: X header should not be sent. kept for compatibility */ add_header(&resp, "X", sub->txident); /*add_header(&resp, "S", "");*/ ast_rtp_offered_from_local(sub->rtp, 1); add_sdp(&resp, sub, rtp); - /* SC: fill in new fields */ - resp.cmd = MGCP_CMD_CRCX; - resp.trid = oseq; + /* SC: fill in new fields */ + resp.cmd = MGCP_CMD_CRCX; + resp.trid = oseq; return send_request(p, sub, &resp, oseq); /* SC */ } @@ -2077,83 +2079,94 @@ return send_request(p, NULL, &resp, oseq); /* SC */ } -static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername) +static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callerid) { struct mgcp_request resp; + char cid[256]; char tone2[256]; char *l, *n; time_t t; struct tm tm; - struct mgcp_endpoint *p = sub->parent; + struct mgcp_endpoint *p = sub->parent; time(&t); localtime_r(&t,&tm); - n = callername; - l = callernum; + if (callerid) + strncpy(cid, callerid, sizeof(cid) - 1); + else + cid[0] = '\0'; + ast_callerid_parse(cid, &n, &l); + if (l) { + ast_shrink_phone_number(l); + if (!ast_isphonenumber(l)) { + n = l; + l = ""; + } + } if (!n) n = ""; if (!l) l = ""; - /* Keep track of last callerid for blacklist and callreturn */ - strncpy(p->lastcallerid, l, sizeof(p->lastcallerid) - 1); + /* Keep track of last callerid for blacklist and callreturn */ + strncpy(p->lastcallerid, l, sizeof(p->lastcallerid) - 1); snprintf(tone2, sizeof(tone2), "%s,L/ci(%02d/%02d/%02d/%02d,%s,%s)", tone, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, l, n); strncpy(p->curtone, tone, sizeof(p->curtone) - 1); reqprep(&resp, p, "RQNT"); add_header(&resp, "X", p->rqnt_ident); /* SC */ - switch (p->hookstate) { - case MGCP_ONHOOK: - add_header(&resp, "R", "L/hd(N)"); - break; - case MGCP_OFFHOOK: - add_header(&resp, "R", (sub->rtp && (p->dtmfmode & MGCP_DTMF_INBAND)) ? "L/hu(N),L/hf(N)" : "L/hu(N),L/hf(N),D/[0-9#*](N)"); - break; - } - if (strlen(tone2)) { - add_header(&resp, "S", tone2); - } - if (mgcpdebug) { - ast_verbose(VERBOSE_PREFIX_3 "MGCP Asked to indicate tone: %s on %s@%s-%d in cxmode: %s\n", - tone2, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]); - } - /* SC: fill in new fields */ - resp.cmd = MGCP_CMD_RQNT; - resp.trid = oseq; + switch (p->hookstate) { + case MGCP_ONHOOK: + add_header(&resp, "R", "L/hd(N)"); + break; + case MGCP_OFFHOOK: + add_header(&resp, "R", (sub->rtp && (p->dtmfmode & MGCP_DTMF_INBAND)) ? "L/hu(N),L/hf(N)" : "L/hu(N),L/hf(N),D/[0-9#*](N)"); + break; + } + if (strlen(tone2)) { + add_header(&resp, "S", tone2); + } + if (mgcpdebug) { + ast_verbose(VERBOSE_PREFIX_3 "MGCP Asked to indicate tone: %s on %s@%s-%d in cxmode: %s\n", + tone2, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]); + } + /* SC: fill in new fields */ + resp.cmd = MGCP_CMD_RQNT; + resp.trid = oseq; return send_request(p, NULL, &resp, oseq); /* SC */ } static int transmit_modify_request(struct mgcp_subchannel *sub) { struct mgcp_request resp; - struct mgcp_endpoint *p = sub->parent; + struct mgcp_endpoint *p = sub->parent; if (!strlen(sub->cxident)) { /* We don't have a CXident yet, store the destination and wait a bit */ return 0; } - if (mgcpdebug) { - ast_verbose(VERBOSE_PREFIX_3 "Modified %s@%s-%d with new mode: %s on callid: %s\n", - p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid); - } + if (mgcpdebug) { + ast_verbose(VERBOSE_PREFIX_3 "Modified %s@%s-%d with new mode: %s on callid: %s\n", + p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid); + } reqprep(&resp, p, "MDCX"); add_header(&resp, "C", sub->callid); add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]); - /* SC: X header should not be sent. kept for compatibility */ + /* SC: X header should not be sent. kept for compatibility */ add_header(&resp, "X", sub->txident); add_header(&resp, "I", sub->cxident); - switch (sub->parent->hookstate) { + switch (sub->parent->hookstate) { case MGCP_ONHOOK: add_header(&resp, "R", "L/hd(N)"); break; - case MGCP_OFFHOOK: + case MGCP_OFFHOOK: add_header(&resp, "R", (sub->rtp && (p->dtmfmode & MGCP_DTMF_INBAND)) ? "L/hu(N), L/hf(N)" : "L/hu(N),L/hf(N),D/[0-9#*](N)"); break; - } - /* SC: fill in new fields */ - resp.cmd = MGCP_CMD_MDCX; - resp.trid = oseq; + } + /* SC: fill in new fields */ + resp.cmd = MGCP_CMD_MDCX; + resp.trid = oseq; return send_request(p, sub, &resp, oseq); /* SC */ } @@ -2162,55 +2175,55 @@ { struct mgcp_request resp; reqprep(&resp, p, "AUEP"); - /* SC: removed unknown param VS */ + /* SC: removed unknown param VS */ //add_header(&resp, "F", "A,R,D,S,X,N,I,T,O,ES,E,MD,M"); add_header(&resp, "F", "A"); - /* SC: fill in new fields */ - resp.cmd = MGCP_CMD_AUEP; - resp.trid = oseq; + /* SC: fill in new fields */ + resp.cmd = MGCP_CMD_AUEP; + resp.trid = oseq; return send_request(p, NULL, &resp, oseq); /* SC */ } static int transmit_connection_del(struct mgcp_subchannel *sub) { - struct mgcp_endpoint *p = sub->parent; + struct mgcp_endpoint *p = sub->parent; struct mgcp_request resp; - if (mgcpdebug) { - ast_verbose(VERBOSE_PREFIX_3 "Delete connection %s %s@%s-%d with new mode: %s on callid: %s\n", - sub->cxident, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid); - } + if (mgcpdebug) { + ast_verbose(VERBOSE_PREFIX_3 "Delete connection %s %s@%s-%d with new mode: %s on callid: %s\n", + sub->cxident, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid); + } reqprep(&resp, p, "DLCX"); - /* SC: check if call id is avail */ - if (sub->callid[0]) - add_header(&resp, "C", sub->callid); - /* SC: X header should not be sent. kept for compatibility */ + /* SC: check if call id is avail */ + if (sub->callid[0]) + add_header(&resp, "C", sub->callid); + /* SC: X header should not be sent. kept for compatibility */ add_header(&resp, "X", sub->txident); - /* SC: check if cxident is avail */ - if (sub->cxident[0]) - add_header(&resp, "I", sub->cxident); - /* SC: fill in new fields */ - resp.cmd = MGCP_CMD_DLCX; - resp.trid = oseq; + /* SC: check if cxident is avail */ + if (sub->cxident[0]) + add_header(&resp, "I", sub->cxident); + /* SC: fill in new fields */ + resp.cmd = MGCP_CMD_DLCX; + resp.trid = oseq; return send_request(p, sub, &resp, oseq); /* SC */ } static int transmit_connection_del_w_params(struct mgcp_endpoint *p, char *callid, char *cxident) { struct mgcp_request resp; - if (mgcpdebug) { - ast_verbose(VERBOSE_PREFIX_3 "Delete connection %s %s@%s on callid: %s\n", - cxident ? cxident : "", p->name, p->parent->name, callid ? callid : ""); - } + if (mgcpdebug) { + ast_verbose(VERBOSE_PREFIX_3 "Delete connection %s %s@%s on callid: %s\n", + cxident ? cxident : "", p->name, p->parent->name, callid ? callid : ""); + } reqprep(&resp, p, "DLCX"); - /* SC: check if call id is avail */ - if (callid && *callid) - add_header(&resp, "C", callid); - /* SC: check if cxident is avail */ - if (cxident && *cxident) - add_header(&resp, "I", cxident); - /* SC: fill in new fields */ - resp.cmd = MGCP_CMD_DLCX; - resp.trid = oseq; + /* SC: check if call id is avail */ + if (callid && *callid) + add_header(&resp, "C", callid); + /* SC: check if cxident is avail */ + if (cxident && *cxident) + add_header(&resp, "I", cxident); + /* SC: fill in new fields */ + resp.cmd = MGCP_CMD_DLCX; + resp.trid = oseq; return send_request(p, p->sub, &resp, oseq); } @@ -2506,8 +2519,8 @@ /*tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);*/ transmit_notify_request(sub, "L/dl"); } - if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) { - if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { + if (ast_exists_extension(chan, chan->context, exten, 1, p->callerid)) { + if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->callerid)) { if (getforward) { /* Record this as the forwarding extension */ strncpy(p->call_forward, exten, sizeof(p->call_forward) - 1); @@ -2532,20 +2545,16 @@ /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/ ast_indicate(chan, -1); strncpy(chan->exten, exten, sizeof(chan->exten)-1); - if (!ast_strlen_zero(p->cid_num)) { + if (strlen(p->callerid)) { if (!p->hidecallerid) { /* SC: free existing chan->callerid */ - if (chan->cid.cid_num) - free(chan->cid.cid_num); - chan->cid.cid_num = strdup(p->cid_num); - /* SC: free existing chan->callerid */ - if (chan->cid.cid_name) - free(chan->cid.cid_name); - chan->cid.cid_name = strdup(p->cid_name); + if (chan->callerid) + free(chan->callerid); + chan->callerid = strdup(p->callerid); } - if (chan->cid.cid_ani) - free(chan->cid.cid_ani); - chan->cid.cid_ani = strdup(p->cid_num); + if (chan->ani) + free(chan->ani); + chan->ani = strdup(p->callerid); } ast_setstate(chan, AST_STATE_RING); /*zt_enable_ec(p);*/ @@ -2601,12 +2610,9 @@ } /* Disable Caller*ID if enabled */ p->hidecallerid = 1; - if (chan->cid.cid_num) - free(chan->cid.cid_num); - chan->cid.cid_num = NULL; - if (chan->cid.cid_name) - free(chan->cid.cid_name); - chan->cid.cid_name = NULL; + if (chan->callerid) + free(chan->callerid); + chan->callerid = NULL; /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ transmit_notify_request(sub, "L/sl"); len = 0; @@ -2661,10 +2667,10 @@ len = 0; } else if (!strcmp(exten, ast_parking_ext()) && sub->next->owner && - ast_bridged_channel(sub->next->owner)) { + sub->next->owner->bridge) { /* This is a three way call, the main call being a real channel, and we're parking the first call. */ - ast_masq_park_call(ast_bridged_channel(sub->next->owner), chan, 0, NULL); + ast_masq_park_call(sub->next->owner->bridge, chan, 0, NULL); if (option_verbose > 2) { ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name); } @@ -2686,23 +2692,19 @@ } /* Enable Caller*ID if enabled */ p->hidecallerid = 0; - if (chan->cid.cid_num) - free(chan->cid.cid_num); - if (!ast_strlen_zero(p->cid_num)) - chan->cid.cid_num = strdup(p->cid_num); - if (chan->cid.cid_name) - free(chan->cid.cid_name); - if (!ast_strlen_zero(p->cid_name)) - chan->cid.cid_name = strdup(p->cid_name); + if (chan->callerid) + free(chan->callerid); + if (strlen(p->callerid)) + chan->callerid = strdup(p->callerid); /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ transmit_notify_request(sub, "L/sl"); len = 0; memset(exten, 0, sizeof(exten)); timeout = firstdigittimeout; - } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) && + } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->callerid) && ((exten[0] != '*') || (strlen(exten) > 2))) { if (option_debug) - ast_log(LOG_DEBUG, "Can't match %s from '%s' in context %s\n", exten, chan->cid.cid_num ? chan->cid.cid_num : "", chan->context); + ast_log(LOG_DEBUG, "Can't match %s from '%s' in context %s\n", exten, chan->callerid ? chan->callerid : "", chan->context); break; } if (!timeout) @@ -2762,29 +2764,29 @@ /* In order to transfer, we need at least one of the channels to actually be in a call bridge. We can't conference two applications together (but then, why would we want to?) */ - if (ast_bridged_channel(p->sub->owner)) { + if (p->sub->owner->bridge) { /* The three-way person we're about to transfer to could still be in MOH, so stop if now if appropriate */ - if (ast_bridged_channel(p->sub->next->owner)) - ast_moh_stop(ast_bridged_channel(p->sub->next->owner)); + if (p->sub->next->owner->bridge) + ast_moh_stop(p->sub->next->owner->bridge); if (p->sub->owner->_state == AST_STATE_RINGING) { - ast_indicate(ast_bridged_channel(p->sub->next->owner), AST_CONTROL_RINGING); + ast_indicate(p->sub->next->owner->bridge, AST_CONTROL_RINGING); } - if (ast_channel_masquerade(p->sub->next->owner, ast_bridged_channel(p->sub->owner))) { + if (ast_channel_masquerade(p->sub->next->owner, p->sub->owner->bridge)) { ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", - ast_bridged_channel(p->sub->owner)->name, p->sub->next->owner->name); + p->sub->owner->bridge->name, p->sub->next->owner->name); return -1; } /* Orphan the channel */ unalloc_sub(p->sub->next); - } else if (ast_bridged_channel(p->sub->next->owner)) { + } else if (p->sub->next->owner->bridge) { if (p->sub->owner->_state == AST_STATE_RINGING) { - ast_indicate(ast_bridged_channel(p->sub->next->owner), AST_CONTROL_RINGING); + ast_indicate(p->sub->next->owner->bridge, AST_CONTROL_RINGING); } - ast_moh_stop(ast_bridged_channel(p->sub->next->owner)); - if (ast_channel_masquerade(p->sub->owner, ast_bridged_channel(p->sub->next->owner))) { + ast_moh_stop(p->sub->next->owner->bridge); + if (ast_channel_masquerade(p->sub->owner, p->sub->next->owner->bridge)) { ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", - ast_bridged_channel(p->sub->next->owner)->name, p->sub->owner->name); + p->sub->next->owner->bridge->name, p->sub->owner->name); return -1; } /*swap_subs(p, SUB_THREEWAY, SUB_REAL);*/ @@ -2820,8 +2822,8 @@ if (sub->outgoing) { /* Answered */ if (sub->owner) { - if (ast_bridged_channel(sub->owner)) { - ast_moh_stop(ast_bridged_channel(sub->owner)); + if (sub->owner->bridge) { + ast_moh_stop(sub->owner->bridge); } sub->cxmode = MGCP_CX_SENDRECV; if (!sub->rtp) { @@ -2878,8 +2880,8 @@ ast_log(LOG_WARNING, "On hook, but already have owner on %s@%s\n", p->name, p->parent->name); ast_log(LOG_WARNING, "If we're onhook why are we here trying to handle a hd or hf?"); } - if (ast_bridged_channel(sub->owner)) { - ast_moh_stop(ast_bridged_channel(sub->owner)); + if (sub->owner->bridge) { + ast_moh_stop(sub->owner->bridge); } sub->cxmode = MGCP_CX_SENDRECV; if (!sub->rtp) { @@ -2898,13 +2900,13 @@ { char *ev, *s; struct ast_frame f = { 0, }; - struct mgcp_endpoint *p = sub->parent; - struct mgcp_gateway *g = NULL; + struct mgcp_endpoint *p = sub->parent; + struct mgcp_gateway *g = NULL; char iabuf[INET_ADDRSTRLEN]; - int res; + int res; if (mgcpdebug) { ast_verbose("Handling request '%s' on %s@%s\n", req->verb, p->name, p->parent->name); - } + } /* Clear out potential response */ if (!strcasecmp(req->verb, "RSIP")) { /* Test if this RSIP request is just a keepalive */ @@ -2914,10 +2916,10 @@ transmit_response(sub, "200", req, "OK"); } else { dump_queue(p->parent, p); - dump_cmd_queues(p, NULL); + dump_cmd_queues(p, NULL); if (option_verbose > 2 && (strcmp(p->name, p->parent->wcardep) != 0)) { - ast_verbose(VERBOSE_PREFIX_3 "Resetting interface %s@%s\n", p->name, p->parent->name); + ast_verbose(VERBOSE_PREFIX_3 "Resetting interface %s@%s\n", p->name, p->parent->name); } // JS: For RSIP on wildcard we reset all endpoints if (!strcmp(p->name, p->parent->wcardep)) { @@ -2941,7 +2943,7 @@ tmp_sub = tmp_sub->next; if (tmp_sub == first_sub) break; - } + } } tmp_ep = tmp_ep->next; } @@ -2952,7 +2954,7 @@ /* JS: We dont send NTFY or AUEP to wildcard ep */ if (strcmp(p->name, p->parent->wcardep) != 0) { transmit_notify_request(sub, ""); - /* SC: Audit endpoint. + /* SC: Audit endpoint. Idea is to prevent lost lines due to race conditions */ transmit_audit_endpoint(p); @@ -2965,190 +2967,191 @@ ev = get_header(req, "O"); s = strchr(ev, '/'); if (s) ev = s + 1; - if (option_verbose > 2) { - ast_verbose(VERBOSE_PREFIX_3 "Endpoint '%s@%s-%d' observed '%s'\n", p->name, p->parent->name, sub->id, ev); - } + if (option_verbose > 2) { + ast_verbose(VERBOSE_PREFIX_3 "Endpoint '%s@%s-%d' observed '%s'\n", p->name, p->parent->name, sub->id, ev); + } /* Keep looking for events unless this was a hangup */ if (strcasecmp(ev, "hu") && strcasecmp(ev, "hd") && strcasecmp(ev, "ping")) { transmit_notify_request(sub, p->curtone); - } + } if (!strcasecmp(ev, "hd")) { - p->hookstate = MGCP_OFFHOOK; - sub->cxmode = MGCP_CX_SENDRECV; - handle_hd_hf(sub, ev); + p->hookstate = MGCP_OFFHOOK; + sub->cxmode = MGCP_CX_SENDRECV; + handle_hd_hf(sub, ev); } else if (!strcasecmp(ev, "hf")) { - /* We can assume we are offhook if we received a hookflash */ - /* First let's just do call wait and ignore threeway */ - /* We're currently in charge */ - if (p->hookstate != MGCP_OFFHOOK) { - /* Cisco c7940 sends hf even if the phone is onhook */ - /* Thanks to point on IRC for pointing this out */ - return -1; - } - /* do not let * confrnce two down channels */ - if( sub->owner && sub->owner->_state == AST_STATE_DOWN && !sub->next->owner) return -1; - - if (p->callwaiting || p->transfer || p->threewaycalling) { - if (option_verbose > 2) { - ast_verbose(VERBOSE_PREFIX_3 "Swapping %d for %d on %s@%s\n", p->sub->id, p->sub->next->id, p->name, p->parent->name); - } - p->sub = p->sub->next; + /* We can assume we are offhook if we received a hookflash */ + /* First let's just do call wait and ignore threeway */ + /* We're currently in charge */ + if (p->hookstate != MGCP_OFFHOOK) { + /* Cisco c7940 sends hf even if the phone is onhook */ + /* Thanks to point on IRC for pointing this out */ + return -1; + } + /* do not let * confrnce two down channels */ + if( sub->owner && sub->owner->_state == AST_STATE_DOWN && !sub->next->owner) { + return -1; + } - /* transfer control to our next subchannel */ - if (!sub->next->owner) { - /* plave the first call on hold and start up a new call */ - sub->cxmode = MGCP_CX_MUTE; - if (option_verbose > 2) { - ast_verbose(VERBOSE_PREFIX_3 "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name); - } - transmit_modify_request(sub); - if (sub->owner && ast_bridged_channel(sub->owner)) { - ast_moh_start(ast_bridged_channel(sub->owner), NULL); - } - sub->next->cxmode = MGCP_CX_RECVONLY; - handle_hd_hf(sub->next, ev); - } else if (sub->owner && sub->next->owner) { - /* We've got two active calls lets decide whether or not to conference or just flip flop */ - if ((!sub->outgoing) && (!sub->next->outgoing)) { - /* We made both calls lets conferenct */ - if (option_verbose > 2) { - ast_verbose(VERBOSE_PREFIX_3 "MGCP Conferencing %d and %d on %s@%s\n", - sub->id, sub->next->id, p->name, p->parent->name); - } - sub->cxmode = MGCP_CX_CONF; - sub->next->cxmode = MGCP_CX_CONF; - if (ast_bridged_channel(sub->next->owner)) - ast_moh_stop(ast_bridged_channel(sub->next->owner)); - transmit_modify_request(sub); - transmit_modify_request(sub->next); - } else { - /* Let's flipflop between calls */ - /* XXX Need to check for state up ??? */ - /* XXX Need a way to indicate the current call, or maybe the call that's waiting */ - if (option_verbose > 2) { - ast_verbose(VERBOSE_PREFIX_3 "We didn't make one of the calls FLIPFLOP %d and %d on %s@%s\n", - sub->id, sub->next->id, p->name, p->parent->name); - } - sub->cxmode = MGCP_CX_MUTE; - if (option_verbose > 2) { - ast_verbose(VERBOSE_PREFIX_3 "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name); - } - transmit_modify_request(sub); - if (ast_bridged_channel(sub->owner)) - ast_moh_start(ast_bridged_channel(sub->owner), NULL); - - if (ast_bridged_channel(sub->next->owner)) - ast_moh_stop(ast_bridged_channel(sub->next->owner)); - - handle_hd_hf(sub->next, ev); + if (p->callwaiting || p->transfer || p->threewaycalling) { + if (option_verbose > 2) { + ast_verbose(VERBOSE_PREFIX_3 "Swapping %d for %d on %s@%s\n", p->sub->id, p->sub->next->id, p->name, p->parent->name); + } + p->sub = p->sub->next; + + /* transfer control to our next subchannel */ + if (!sub->next->owner) { + /* plave the first call on hold and start up a new call */ + sub->cxmode = MGCP_CX_MUTE; + if (option_verbose > 2) { + ast_verbose(VERBOSE_PREFIX_3 "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name); + } + transmit_modify_request(sub); + if (sub->owner && sub->owner->bridge) { + ast_moh_start(sub->owner->bridge, NULL); + } + sub->next->cxmode = MGCP_CX_RECVONLY; + handle_hd_hf(sub->next, ev); + } else if (sub->owner && sub->next->owner) { + /* We've got two active calls lets decide whether or not to conference or just flip flop */ + if ((!sub->outgoing) && (!sub->next->outgoing)) { + /* We made both calls lets conferenct */ + if (option_verbose > 2) { + ast_verbose(VERBOSE_PREFIX_3 "MGCP Conferencing %d and %d on %s@%s\n", + sub->id, sub->next->id, p->name, p->parent->name); + } + sub->cxmode = MGCP_CX_CONF; + sub->next->cxmode = MGCP_CX_CONF; + if (sub->next->owner->bridge) { + ast_moh_stop(sub->next->owner->bridge); + } + transmit_modify_request(sub); + transmit_modify_request(sub->next); + } else { + /* Let's flipflop between calls */ + /* XXX Need to check for state up ??? */ + /* XXX Need a way to indicate the current call, or maybe the call that's waiting */ + if (option_verbose > 2) { + ast_verbose(VERBOSE_PREFIX_3 "We didn't make one of the calls FLIPFLOP %d and %d on %s@%s\n", + sub->id, sub->next->id, p->name, p->parent->name); + } + sub->cxmode = MGCP_CX_MUTE; + if (option_verbose > 2) { + ast_verbose(VERBOSE_PREFIX_3 "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name); + } + transmit_modify_request(sub); + if (sub->owner->bridge) { + ast_moh_start(sub->owner->bridge, NULL); + } + if (sub->next->owner->bridge) { + ast_moh_stop(sub->next->owner->bridge); + } + handle_hd_hf(sub->next, ev); #if 0 - if (sub->next->owner && (sub->next->owner->_state != AST_STATE_UP)) { - handle_hd_hf(sub->next, ev); - } else { - ast_verbose(VERBOSE_PREFIX_3 "MGCP Unmuting %d on %s@%s\n", sub->next->id, p->name, p->parent->name); - sub->next->cxmode = MGCP_CX_SENDRECV; - transmit_modify_request(sub->next); - } + if (sub->next->owner && (sub->next->owner->_state != AST_STATE_UP)) { + handle_hd_hf(sub->next, ev); + } else { + ast_verbose(VERBOSE_PREFIX_3 "MGCP Unmuting %d on %s@%s\n", sub->next->id, p->name, p->parent->name); + sub->next->cxmode = MGCP_CX_SENDRECV; + transmit_modify_request(sub->next); + } #endif - } - } else { - /* We've most likely lost one of our calls find an active call and bring it up */ - if (sub->owner) { - p->sub = sub; - } else if (sub->next->owner) { - p->sub = sub->next; - } else { - /* We seem to have lost both our calls */ - /* XXX - What do we do now? */ - return -1; - } - if (ast_bridged_channel(p->sub->owner)) { - ast_moh_stop(ast_bridged_channel(p->sub->owner)); - } - p->sub->cxmode = MGCP_CX_SENDRECV; - transmit_modify_request(p->sub); - } - } else { - ast_log(LOG_WARNING, "Callwaiting, call transfer or threeway calling not enabled on endpoint %s@%s\n", - p->name, p->parent->name); - } - /* ast_moh_stop(sub->owner->bridge); */ + } + } else { + /* We've most likely lost one of our calls find an active call and bring it up */ + if (sub->owner) { + p->sub = sub; + } else if (sub->next->owner) { + p->sub = sub->next; + } else { + /* We seem to have lost both our calls */ + /* XXX - What do we do now? */ + return -1; + } + if (p->sub->owner->bridge) { + ast_moh_stop(p->sub->owner->bridge); + } + p->sub->cxmode = MGCP_CX_SENDRECV; + transmit_modify_request(p->sub); + } + } else { + ast_log(LOG_WARNING, "Callwaiting, call transfer or threeway calling not enabled on endpoint %s@%s\n", + p->name, p->parent->name); + } + /* ast_moh_stop(sub->owner->bridge); */ } else if (!strcasecmp(ev, "hu")) { - p->hookstate = MGCP_ONHOOK; - sub->cxmode = MGCP_CX_RECVONLY; - ast_log(LOG_DEBUG, "MGCP %s@%s Went on hook\n", p->name, p->parent->name); - /* JS: Do we need to send MDCX before a DLCX ? - if (sub->rtp) { - transmit_modify_request(sub); - } - */ - if (p->transfer && (sub->owner && sub->next->owner) && ((!sub->outgoing) || (!sub->next->outgoing))) { - /* We're allowed to transfer, we have two avtive calls and */ - /* we made at least one of the calls. Let's try and transfer */ + p->hookstate = MGCP_ONHOOK; + sub->cxmode = MGCP_CX_RECVONLY; + ast_log(LOG_DEBUG, "MGCP %s@%s Went on hook\n", p->name, p->parent->name); + /* JS: Do we need to send MDCX before a DLCX ? + if (sub->rtp) { + transmit_modify_request(sub); + } + */ + if (p->transfer && (sub->owner && sub->next->owner) && ((!sub->outgoing) || (!sub->next->outgoing))) { + /* We're allowed to transfer, we have two avtive calls and */ + /* we made at least one of the calls. Let's try and transfer */ ast_mutex_lock(&p->sub->next->lock); res = attempt_transfer(p); if (res < 0) { - if (p->sub->next->owner) { - sub->next->alreadygone = 1; + if (p->sub->next->owner) { + sub->next->alreadygone = 1; mgcp_queue_hangup(sub->next); - } - } else if (res) { - ast_log(LOG_WARNING, "Transfer attempt failed\n"); + } + } else if (res) { + ast_log(LOG_WARNING, "Transfer attempt failed\n"); ast_mutex_unlock(&p->sub->next->lock); - return -1; - } + return -1; + } ast_mutex_unlock(&p->sub->next->lock); - } else { - /* Hangup the current call */ - /* If there is another active call, mgcp_hangup will ring the phone with the other call */ - if (sub->owner) { - sub->alreadygone = 1; + } else { + /* Hangup the current call */ + /* If there is another active call, mgcp_hangup will ring the phone with the other call */ + if (sub->owner) { + sub->alreadygone = 1; mgcp_queue_hangup(sub); - } else { - /* SC: verbose level check */ - if (option_verbose > 2) { - ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s-%d) ast_channel already destroyed\n", - p->name, p->parent->name, sub->id); - } - } - } - if ((p->hookstate == MGCP_ONHOOK) && (!sub->rtp) && (!sub->next->rtp)) { - if (has_voicemail(p)) { - if (option_verbose > 2) { - ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s) set vmwi(+)\n", p->name, p->parent->name); - } - transmit_notify_request(sub, "L/vmwi(+)"); - } else { - if (option_verbose > 2) { - ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s) set vmwi(-)\n", p->name, p->parent->name); - } - transmit_notify_request(sub, "L/vmwi(-)"); - } - } + } else { + /* SC: verbose level check */ + if (option_verbose > 2) { + ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s-%d) ast_channel already destroyed\n", + p->name, p->parent->name, sub->id); + } + } + } + if ((p->hookstate == MGCP_ONHOOK) && (!sub->rtp) && (!sub->next->rtp)) { + if (has_voicemail(p)) { + if (option_verbose > 2) { + ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s) set vmwi(+)\n", p->name, p->parent->name); + } + transmit_notify_request(sub, "L/vmwi(+)"); + } else { + if (option_verbose > 2) { + ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s) set vmwi(-)\n", p->name, p->parent->name); + } + transmit_notify_request(sub, "L/vmwi(-)"); + } + } } else if ((strlen(ev) == 1) && - (((ev[0] >= '0') && (ev[0] <= '9')) || - ((ev[0] >= 'A') && (ev[0] <= 'D')) || - (ev[0] == '*') || (ev[0] == '#'))) { + (((ev[0] >= '0') && (ev[0] <= '9')) || + ((ev[0] >= 'A') && (ev[0] <= 'D')) || + (ev[0] == '*') || (ev[0] == '#'))) { f.frametype = AST_FRAME_DTMF; f.subclass = ev[0]; f.src = "mgcp"; if (sub->owner) { - /* XXX MUST queue this frame to all subs in threeway call if threeway call is active */ + /* XXX MUST queue this frame to all subs in threeway call if threeway call is active */ mgcp_queue_frame(sub, &f); ast_mutex_lock(&sub->next->lock); - if (sub->next->owner) { + if (sub->next->owner) { mgcp_queue_frame(sub->next, &f); - } + } ast_mutex_unlock(&sub->next->lock); - } - if (strstr(p->curtone, "wt") && (ev[0] == 'A')) { - memset(p->curtone, 0, sizeof(p->curtone)); - } - } - else if (!strcasecmp(ev, "T")) { + } + if (strstr(p->curtone, "wt") && (ev[0] == 'A')) { + memset(p->curtone, 0, sizeof(p->curtone)); + } + } else if (!strcasecmp(ev, "T")) { /* Digit timeout -- unimportant */ - } - else if (!strcasecmp(ev, "ping")) { + } else if (!strcasecmp(ev, "ping")) { /* ping -- unimportant */ } else { ast_log(LOG_NOTICE, "Received unknown event '%s' from %s@%s\n", ev, p->name, p->parent->name); @@ -3203,7 +3206,7 @@ int ident; char iabuf[INET_ADDRSTRLEN]; len = sizeof(sin); - memset(&req, 0, sizeof(req)); + memset(&req, 0, sizeof(struct mgcp_request)); res = recvfrom(mgcpsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); if (res < 0) { if (errno != ECONNREFUSED) @@ -3214,7 +3217,7 @@ req.len = res; if (mgcpdebug) { ast_verbose("MGCP read: \n%s\nfrom %s:%d\n", req.data, ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); - } + } parse(&req); if (req.headers < 1) { /* Must have at least one header */ @@ -3288,8 +3291,8 @@ { int res; int reloading; - /* struct mgcp_gateway *g; */ - /* struct mgcp_endpoint *e; */ + /* struct mgcp_gateway *g; */ + /* struct mgcp_endpoint *e; */ /*time_t thispass = 0, lastpass = 0;*/ /* Add an I/O event to our UDP socket */ @@ -3314,17 +3317,17 @@ mgcpsock_read_id = ast_io_add(io, mgcpsock, mgcpsock_read, AST_IO_IN, NULL); } - /* Check for interfaces needing to be killed */ + /* Check for interfaces needing to be killed */ /* Don't let anybody kill us right away. Nobody should lock the interface list and wait for the monitor list, but the other way around is okay. */ ast_mutex_lock(&monlock); /* Lock the network interface */ ast_mutex_lock(&netlock); +#if 0 /* XXX THIS IS COMPLETELY HOSED */ /* The gateway goes into a state of panic */ /* If the vmwi indicator is sent while it is reseting interfaces */ -#if 0 lastpass = thispass; thispass = time(NULL); g = gateways; @@ -3358,7 +3361,7 @@ pthread_testcancel(); /* Wait for sched or io */ res = ast_sched_wait(sched); - /* SC: copied from chan_sip.c */ + /* SC: copied from chan_sip.c */ if ((res < 0) || (res > 1000)) res = 1000; res = ast_io_wait(io, res); @@ -3405,7 +3408,7 @@ return 0; } -static struct ast_channel *mgcp_request(const char *type, int format, void *data, int *cause) +static struct ast_channel *mgcp_request(char *type, int format, void *data) { int oldformat; struct mgcp_subchannel *sub; @@ -3427,34 +3430,33 @@ sub = find_subchannel_and_lock(tmp, 0, NULL); if (!sub) { ast_log(LOG_WARNING, "Unable to find MGCP endpoint '%s'\n", tmp); - *cause = AST_CAUSE_UNREGISTERED; return NULL; } - if (option_verbose > 2) { - ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_request(%s)\n", tmp); - ast_verbose(VERBOSE_PREFIX_3 "MGCP cw: %d, dnd: %d, so: %d, sno: %d\n", - sub->parent->callwaiting, sub->parent->dnd, sub->owner ? 1 : 0, sub->next->owner ? 1: 0); - } + if (option_verbose > 2) { + ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_request(%s)\n", tmp); + ast_verbose(VERBOSE_PREFIX_3 "MGCP cw: %d, dnd: %d, so: %d, sno: %d\n", + sub->parent->callwaiting, sub->parent->dnd, sub->owner ? 1 : 0, sub->next->owner ? 1: 0); + } /* Must be busy */ if (((sub->parent->callwaiting) && ((sub->owner) && (sub->next->owner))) || - ((!sub->parent->callwaiting) && (sub->owner)) || - (sub->parent->dnd && (!strlen(sub->parent->call_forward)))) { - if (sub->parent->hookstate == MGCP_ONHOOK) { - if (has_voicemail(sub->parent)) { - transmit_notify_request(sub,"L/vmwi(+)"); - } else { - transmit_notify_request(sub,"L/vmwi(-)"); - } - } - *cause = AST_CAUSE_BUSY; - ast_mutex_unlock(&sub->lock); + ((!sub->parent->callwaiting) && (sub->owner)) || + (sub->parent->dnd && (!strlen(sub->parent->call_forward)))) { + if (sub->parent->hookstate == MGCP_ONHOOK) { + if (has_voicemail(sub->parent)) { + transmit_notify_request(sub,"L/vmwi(+)"); + } else { + transmit_notify_request(sub,"L/vmwi(-)"); + } + } + ast_mutex_unlock(&sub->lock); return NULL; - } + } tmpc = mgcp_new(sub->owner ? sub->next : sub, AST_STATE_DOWN); - ast_mutex_unlock(&sub->lock); - if (!tmpc) + ast_mutex_unlock(&sub->lock); + if (!tmpc) { ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp); + } restart_monitor(); return tmpc; } @@ -3464,11 +3466,11 @@ { struct mgcp_gateway *gw; struct mgcp_endpoint *e; - struct mgcp_subchannel *sub; - /*char txident[80];*/ - int i=0, y=0; - int gw_reload = 0; - int ep_reload = 0; + struct mgcp_subchannel *sub; + /*char txident[80];*/ + int i=0, y=0; + int gw_reload = 0; + int ep_reload = 0; canreinvite = CANREINVITE; /* SC: locate existing gateway */ @@ -3549,12 +3551,10 @@ } else if (!strcasecmp(v->name, "nat")) { nat = ast_true(v->value); } else if (!strcasecmp(v->name, "callerid")) { - if (!strcasecmp(v->value, "asreceived")) { - cid_num[0] = '\0'; - cid_name[0] = '\0'; - } else { - ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num)); - } + if (!strcasecmp(v->value, "asreceived")) + callerid[0] = '\0'; + else + strncpy(callerid, v->value, sizeof(callerid) - 1); } else if (!strcasecmp(v->name, "language")) { strncpy(language, v->value, sizeof(language)-1); } else if (!strcasecmp(v->name, "accountcode")) { @@ -3628,8 +3628,7 @@ //strncpy(e->name, "aaln/*", sizeof(e->name) - 1); /* XXX Should we really check for uniqueness?? XXX */ strncpy(e->context, context, sizeof(e->context) - 1); - strncpy(e->cid_num, cid_num, sizeof(e->cid_num) - 1); - strncpy(e->cid_name, cid_name, sizeof(e->cid_name) - 1); + strncpy(e->callerid, callerid, sizeof(e->callerid) - 1); strncpy(e->language, language, sizeof(e->language) - 1); strncpy(e->musicclass, musicclass, sizeof(e->musicclass)-1); strncpy(e->mailbox, mailbox, sizeof(e->mailbox)-1); @@ -3721,8 +3720,7 @@ } /* XXX Should we really check for uniqueness?? XXX */ strncpy(e->context, context, sizeof(e->context) - 1); - strncpy(e->cid_num, cid_num, sizeof(e->cid_num) - 1); - strncpy(e->cid_name, cid_name, sizeof(e->cid_name) - 1); + strncpy(e->callerid, callerid, sizeof(e->callerid) - 1); strncpy(e->language, language, sizeof(e->language) - 1); strncpy(e->musicclass, musicclass, sizeof(e->musicclass)-1); strncpy(e->mailbox, mailbox, sizeof(e->mailbox)-1);