--- chan_mgcp.c.v1-0_MERGE 2004-11-18 13:50:28 +0200 +++ chan_mgcp.c.HEAD 2004-11-18 11:35:06 +0200 @@ -72,6 +72,7 @@ #include #include #include +#include #include #include #include @@ -150,7 +151,8 @@ static char language[MAX_LANGUAGE] = ""; static char musicclass[MAX_LANGUAGE] = ""; -static char callerid[AST_MAX_EXTENSION] = ""; +static char cid_num[AST_MAX_EXTENSION] = ""; +static char cid_name[AST_MAX_EXTENSION] = ""; static int dtmfmode = 0; static int nat = 0; @@ -356,7 +358,8 @@ char exten[AST_MAX_EXTENSION]; /* Extention where to start */ char context[AST_MAX_EXTENSION]; char language[MAX_LANGUAGE]; - char callerid[AST_MAX_EXTENSION]; /* Caller*ID */ + char cid_num[AST_MAX_EXTENSION]; /* Caller*ID */ + char cid_name[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]; @@ -445,7 +448,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 *callerid); +static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername); 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); @@ -458,7 +461,7 @@ static int has_voicemail(struct mgcp_endpoint *p) { - return ast_app_has_voicemail(p->mailbox); + return ast_app_has_voicemail(p->mailbox, NULL); } static int unalloc_sub(struct mgcp_subchannel *sub) @@ -884,7 +887,7 @@ transmit_modify_request(sub->next); } - transmit_notify_request_with_callerid(sub, tone, ast->callerid); + transmit_notify_request_with_callerid(sub, tone, ast->cid.cid_num, ast->cid.cid_name); ast_setstate(ast, AST_STATE_RINGING); if (sub->next->owner && strlen(sub->next->cxident) && strlen(sub->next->callid)) { @@ -907,26 +910,24 @@ 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; } - 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 ((p->dtmfmode & MGCP_DTMF_INBAND) && p->dsp) { + if ((p->dtmfmode & MGCP_DTMF_INBAND) && (p->dsp != NULL)){ /* SC: check whether other channel is active. */ - if (!sub->next->owner) { + if (!sub->next->owner) + { if (mgcpdebug) { ast_verbose(VERBOSE_PREFIX_2 "MGCP free dsp on %s@%s\n", p->name, p->parent->name); } @@ -934,6 +935,7 @@ p->dsp = NULL; } } + ast_mutex_lock(&sub->lock); sub->owner = NULL; if (strlen(sub->cxident)) { @@ -942,16 +944,16 @@ 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); + 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 && sub->next->owner->bridge) { - transmit_notify_request_with_callerid(p->sub, "L/rg", sub->next->owner->callerid); + 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); } } @@ -1345,8 +1347,10 @@ 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 (strlen(i->callerid)) - tmp->callerid = strdup(i->callerid); + 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 (!i->adsi) tmp->adsicpe = AST_ADSI_UNAVAILABLE; tmp->priority = 1; @@ -1367,8 +1371,7 @@ 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; @@ -1378,8 +1381,7 @@ 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; @@ -1391,13 +1393,12 @@ 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) { @@ -1754,6 +1755,7 @@ return -1; } return 0; + } static int add_header(struct mgcp_request *req, char *var, char *value) @@ -1769,9 +1771,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; } @@ -1792,9 +1794,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; } @@ -1842,7 +1844,7 @@ static int respprep(struct mgcp_request *resp, struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest) { - memset(resp, 0, sizeof(struct mgcp_request)); + memset(resp, 0, sizeof(*resp)); init_resp(resp, msg, req, msgrest); return 0; } @@ -2075,10 +2077,9 @@ return send_request(p, NULL, &resp, oseq); /* SC */ } -static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callerid) +static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername) { struct mgcp_request resp; - char cid[256]; char tone2[256]; char *l, *n; time_t t; @@ -2087,18 +2088,8 @@ time(&t); localtime_r(&t,&tm); - 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 = ""; - } - } + n = callername; + l = callernum; if (!n) n = ""; if (!l) @@ -2515,8 +2506,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->callerid)) { - if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->callerid)) { + 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 (getforward) { /* Record this as the forwarding extension */ strncpy(p->call_forward, exten, sizeof(p->call_forward) - 1); @@ -2541,16 +2532,20 @@ /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/ ast_indicate(chan, -1); strncpy(chan->exten, exten, sizeof(chan->exten)-1); - if (strlen(p->callerid)) { + if (!ast_strlen_zero(p->cid_num)) { if (!p->hidecallerid) { /* SC: free existing chan->callerid */ - if (chan->callerid) - free(chan->callerid); - chan->callerid = strdup(p->callerid); - } - if (chan->ani) - free(chan->ani); - chan->ani = strdup(p->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->cid.cid_ani) + free(chan->cid.cid_ani); + chan->cid.cid_ani = strdup(p->cid_num); } ast_setstate(chan, AST_STATE_RING); /*zt_enable_ec(p);*/ @@ -2606,9 +2601,12 @@ } /* Disable Caller*ID if enabled */ p->hidecallerid = 1; - if (chan->callerid) - free(chan->callerid); - chan->callerid = NULL; + 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; /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ transmit_notify_request(sub, "L/sl"); len = 0; @@ -2663,10 +2661,10 @@ len = 0; } else if (!strcmp(exten, ast_parking_ext()) && sub->next->owner && - sub->next->owner->bridge) { + ast_bridged_channel(sub->next->owner)) { /* This is a three way call, the main call being a real channel, and we're parking the first call. */ - ast_masq_park_call(sub->next->owner->bridge, chan, 0, NULL); + ast_masq_park_call(ast_bridged_channel(sub->next->owner), chan, 0, NULL); if (option_verbose > 2) { ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name); } @@ -2688,19 +2686,23 @@ } /* Enable Caller*ID if enabled */ p->hidecallerid = 0; - if (chan->callerid) - free(chan->callerid); - if (strlen(p->callerid)) - chan->callerid = strdup(p->callerid); + 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); /*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->callerid) && + } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) && ((exten[0] != '*') || (strlen(exten) > 2))) { if (option_debug) - ast_log(LOG_DEBUG, "Can't match %s from '%s' in context %s\n", exten, chan->callerid ? chan->callerid : "", chan->context); + 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); break; } if (!timeout) @@ -2760,29 +2762,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 (p->sub->owner->bridge) { + if (ast_bridged_channel(p->sub->owner)) { /* The three-way person we're about to transfer to could still be in MOH, so stop if now if appropriate */ - if (p->sub->next->owner->bridge) - ast_moh_stop(p->sub->next->owner->bridge); + if (ast_bridged_channel(p->sub->next->owner)) + ast_moh_stop(ast_bridged_channel(p->sub->next->owner)); if (p->sub->owner->_state == AST_STATE_RINGING) { - ast_indicate(p->sub->next->owner->bridge, AST_CONTROL_RINGING); + ast_indicate(ast_bridged_channel(p->sub->next->owner), AST_CONTROL_RINGING); } - if (ast_channel_masquerade(p->sub->next->owner, p->sub->owner->bridge)) { + if (ast_channel_masquerade(p->sub->next->owner, ast_bridged_channel(p->sub->owner))) { ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", - p->sub->owner->bridge->name, p->sub->next->owner->name); + ast_bridged_channel(p->sub->owner)->name, p->sub->next->owner->name); return -1; } /* Orphan the channel */ unalloc_sub(p->sub->next); - } else if (p->sub->next->owner->bridge) { + } else if (ast_bridged_channel(p->sub->next->owner)) { if (p->sub->owner->_state == AST_STATE_RINGING) { - ast_indicate(p->sub->next->owner->bridge, AST_CONTROL_RINGING); + ast_indicate(ast_bridged_channel(p->sub->next->owner), AST_CONTROL_RINGING); } - ast_moh_stop(p->sub->next->owner->bridge); - if (ast_channel_masquerade(p->sub->owner, p->sub->next->owner->bridge)) { + 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_log(LOG_WARNING, "Unable to masquerade %s as %s\n", - p->sub->next->owner->bridge->name, p->sub->owner->name); + ast_bridged_channel(p->sub->next->owner)->name, p->sub->owner->name); return -1; } /*swap_subs(p, SUB_THREEWAY, SUB_REAL);*/ @@ -2818,8 +2820,8 @@ if (sub->outgoing) { /* Answered */ if (sub->owner) { - if (sub->owner->bridge) { - ast_moh_stop(sub->owner->bridge); + if (ast_bridged_channel(sub->owner)) { + ast_moh_stop(ast_bridged_channel(sub->owner)); } sub->cxmode = MGCP_CX_SENDRECV; if (!sub->rtp) { @@ -2876,8 +2878,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 (sub->owner->bridge) { - ast_moh_stop(sub->owner->bridge); + if (ast_bridged_channel(sub->owner)) { + ast_moh_stop(ast_bridged_channel(sub->owner)); } sub->cxmode = MGCP_CX_SENDRECV; if (!sub->rtp) { @@ -2984,9 +2986,7 @@ return -1; } /* do not let * confrnce two down channels */ - if( sub->owner && sub->owner->_state == AST_STATE_DOWN && !sub->next->owner) { - return -1; - } + 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) { @@ -3002,8 +3002,8 @@ 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); + 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); @@ -3017,9 +3017,8 @@ } sub->cxmode = MGCP_CX_CONF; sub->next->cxmode = MGCP_CX_CONF; - if (sub->next->owner->bridge) { - ast_moh_stop(sub->next->owner->bridge); - } + 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 { @@ -3035,12 +3034,12 @@ 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); - } + 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 0 if (sub->next->owner && (sub->next->owner->_state != AST_STATE_UP)) { @@ -3063,8 +3062,8 @@ /* XXX - What do we do now? */ return -1; } - if (p->sub->owner->bridge) { - ast_moh_stop(p->sub->owner->bridge); + 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); @@ -3145,9 +3144,11 @@ if (strstr(p->curtone, "wt") && (ev[0] == 'A')) { memset(p->curtone, 0, sizeof(p->curtone)); } - } else if (!strcasecmp(ev, "T")) { + } + 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); @@ -3202,7 +3203,7 @@ int ident; char iabuf[INET_ADDRSTRLEN]; len = sizeof(sin); - memset(&req, 0, sizeof(struct mgcp_request)); + memset(&req, 0, sizeof(req)); res = recvfrom(mgcpsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); if (res < 0) { if (errno != ECONNREFUSED) @@ -3320,10 +3321,10 @@ /* 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; @@ -3404,7 +3405,7 @@ return 0; } -static struct ast_channel *mgcp_request(char *type, int format, void *data) +static struct ast_channel *mgcp_request(const char *type, int format, void *data, int *cause) { int oldformat; struct mgcp_subchannel *sub; @@ -3426,6 +3427,7 @@ 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; } @@ -3445,14 +3447,14 @@ transmit_notify_request(sub,"L/vmwi(-)"); } } + *cause = AST_CAUSE_BUSY; 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) { + if (!tmpc) ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp); - } restart_monitor(); return tmpc; } @@ -3547,10 +3549,12 @@ } else if (!strcasecmp(v->name, "nat")) { nat = ast_true(v->value); } else if (!strcasecmp(v->name, "callerid")) { - if (!strcasecmp(v->value, "asreceived")) - callerid[0] = '\0'; - else - strncpy(callerid, v->value, sizeof(callerid) - 1); + 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)); + } } else if (!strcasecmp(v->name, "language")) { strncpy(language, v->value, sizeof(language)-1); } else if (!strcasecmp(v->name, "accountcode")) { @@ -3624,7 +3628,8 @@ //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->callerid, callerid, sizeof(e->callerid) - 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->language, language, sizeof(e->language) - 1); strncpy(e->musicclass, musicclass, sizeof(e->musicclass)-1); strncpy(e->mailbox, mailbox, sizeof(e->mailbox)-1); @@ -3716,7 +3721,8 @@ } /* XXX Should we really check for uniqueness?? XXX */ strncpy(e->context, context, sizeof(e->context) - 1); - strncpy(e->callerid, callerid, sizeof(e->callerid) - 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->language, language, sizeof(e->language) - 1); strncpy(e->musicclass, musicclass, sizeof(e->musicclass)-1); strncpy(e->mailbox, mailbox, sizeof(e->mailbox)-1);