Index: channels/chan_sip.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v retrieving revision 1.711 diff -u -u -r1.711 chan_sip.c --- channels/chan_sip.c 29 Apr 2005 20:42:48 -0000 1.711 +++ channels/chan_sip.c 1 May 2005 03:27:31 -0000 @@ -71,6 +71,7 @@ /* #define VOCAL_DATA_HACK */ +#define SIP_RETVAL_IGNORE 42 /* shrug */ #define SIPDUMPER #define DEFAULT_DEFAULT_EXPIRY 120 #define DEFAULT_MAX_EXPIRY 3600 @@ -667,6 +668,7 @@ static struct sip_user *build_user(const char *name, struct ast_variable *v, int realtime); static int sip_do_reload(void); static int expire_register(void *data); +static int sip_addheader(struct ast_channel *chan, void *data); static int callevents = 0; static struct ast_channel *sip_request(const char *type, int format, void *data, int *cause); @@ -1247,7 +1249,7 @@ /* Delete it, it needs to disappear */ if (peer->call) sip_destroy(peer->call); - if(peer->chanvars) { + if (peer->chanvars) { ast_variables_destroy(peer->chanvars); peer->chanvars = NULL; } @@ -1312,7 +1314,7 @@ !strcasecmp(tmp->value, "user")) { ast_variables_destroy(var); return NULL; - } else if(!newpeername && !strcasecmp(tmp->name, "name")) { + } else if (!newpeername && !strcasecmp(tmp->name, "name")) { newpeername = tmp->value; } tmp = tmp->next; @@ -1322,9 +1324,9 @@ peer = build_peer(newpeername, var, ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS) ? 0 : 1); if (peer) { - if(ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { + if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { ast_copy_flags((&peer->flags_page2),(&global_flags_page2), SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); - if(ast_test_flag((&global_flags_page2), SIP_PAGE2_RTAUTOCLEAR)) { + if (ast_test_flag((&global_flags_page2), SIP_PAGE2_RTAUTOCLEAR)) { if (peer->expire > -1) { ast_sched_del(sched, peer->expire); } @@ -1374,7 +1376,7 @@ static void sip_destroy_user(struct sip_user *user) { ast_free_ha(user->ha); - if(user->chanvars) { + if (user->chanvars) { ast_variables_destroy(user->chanvars); user->chanvars = NULL; } @@ -1526,6 +1528,8 @@ } } if (!p && !found) { + char *ptr, *hostp; + hostn = peer; if (port) portno = atoi(port); @@ -1542,7 +1546,15 @@ portno = tportno; } } - hp = ast_gethostbyname(hostn, &ahp); + if ((hostp = ast_strdupa(hostn))) { + if ((ptr = strchr(hostp, '?'))) { + *ptr = '\0'; + } + } else { + hostp = peer; + } + + hp = ast_gethostbyname(hostp, &ahp); if (hp) { strncpy(r->tohost, peer, sizeof(r->tohost) - 1); memcpy(&r->sa.sin_addr, hp->h_addr, sizeof(r->sa.sin_addr)); @@ -1742,7 +1754,7 @@ free(cp); } ast_mutex_destroy(&p->lock); - if(p->chanvars) { + if (p->chanvars) { ast_variables_destroy(p->chanvars); p->chanvars = NULL; } @@ -2531,7 +2543,7 @@ if (!p->rtp) { ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno)); ast_mutex_destroy(&p->lock); - if(p->chanvars) { + if (p->chanvars) { ast_variables_destroy(p->chanvars); p->chanvars = NULL; } @@ -3097,7 +3109,7 @@ if (!strcasecmp(aliases[x].fullname, var)) shortname = aliases[x].shortname; } - if(!ast_strlen_zero(shortname)) { + if (!ast_strlen_zero(shortname)) { snprintf(req->header[req->headers], sizeof(req->data) - req->len - 4, "%s: %s\r\n", shortname, value); } else { snprintf(req->header[req->headers], sizeof(req->data) - req->len - 4, "%s: %s\r\n", var, value); @@ -3714,7 +3726,7 @@ } /* Start by sending our preferred codecs */ for (x = 0 ; x < 32 ; x++) { - if(!(pref_codec = ast_codec_pref_index(&p->prefs,x))) + if (!(pref_codec = ast_codec_pref_index(&p->prefs,x))) break; if ((capability & pref_codec) && !(alreadysent & pref_codec)) { if (debug) @@ -3861,7 +3873,7 @@ while( *e && ( *e < 33 ) ) { e++; } - if( !*e ) { + if ( !*e ) { return -1; } @@ -3869,7 +3881,7 @@ /* We have a response */ req->rlPart2 = e; len = strlen( req->rlPart2 ); - if( len < 2 ) { + if ( len < 2 ) { return -1; } e+= len - 1; @@ -3879,18 +3891,18 @@ *(++e)= '\0'; } else { /* We have a request */ - if( *e == '<' ) { + if ( *e == '<' ) { e++; - if( !*e ) { + if ( !*e ) { return -1; } } req->rlPart2 = e; /* URI */ - if( ( e= strrchr( req->rlPart2, 'S' ) ) == NULL ) { + if ( ( e= strrchr( req->rlPart2, 'S' ) ) == NULL ) { return -1; } while( isspace( *(--e) ) ) {} - if( *e == '>' ) { + if ( *e == '>' ) { *e = '\0'; } else { *(++e)= '\0'; @@ -4995,7 +5007,7 @@ /* Save User agent */ useragent = get_header(req, "User-Agent"); - if(useragent && strcasecmp(useragent, p->useragent)) { + if (useragent && strcasecmp(useragent, p->useragent)) { strncpy(p->useragent, useragent, sizeof(p->useragent) - 1); if (option_verbose > 3) { ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n",p->useragent,p->name); @@ -5223,12 +5235,12 @@ c+= strlen("response="); if ((*c == '\"')) { response=++c; - if((c = strchr(c,'\"'))) + if ((c = strchr(c,'\"'))) *c = '\0'; } else { response=c; - if((c = strchr(c,','))) + if ((c = strchr(c,','))) *c = '\0'; } @@ -5236,11 +5248,11 @@ c+= strlen("uri="); if ((*c == '\"')) { resp_uri=++c; - if((c = strchr(c,'\"'))) + if ((c = strchr(c,'\"'))) *c = '\0'; } else { resp_uri=c; - if((c = strchr(c,','))) + if ((c = strchr(c,','))) *c = '\0'; } @@ -5250,7 +5262,7 @@ c++; } snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); - if(!ast_strlen_zero(resp_uri)) + if (!ast_strlen_zero(resp_uri)) snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, resp_uri); else snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, uri); @@ -5484,8 +5496,23 @@ return 0; } +static int sip_extract_tag(char **in) +{ + char *tag; + + if ((tag = ast_strcasestr(*in, "tag="))) { + char *ptr; + tag += 4; + if ((ptr = strchr(tag, ';'))) { + *ptr = '\0'; + } + return 0; + } + return -1; +} + /*--- get_sip_pvt_byid_locked: Lock interface lock and find matching pvt lock ---*/ -static struct sip_pvt *get_sip_pvt_byid_locked(char *callid) +static struct sip_pvt *get_sip_pvt_byid_locked(char *callid, struct sip_request *req, char *totag, char *fromtag) { struct sip_pvt *sip_pvt_ptr = NULL; @@ -5494,8 +5521,38 @@ sip_pvt_ptr = iflist; while(sip_pvt_ptr) { if (!strcmp(sip_pvt_ptr->callid, callid)) { + char *real_totag = NULL, *real_fromtag = NULL; + int match = 1; + /* Go ahead and lock it (and its owner) before returning */ ast_mutex_lock(&sip_pvt_ptr->lock); + + if (req && pedanticsipchecking) { + if (totag) { + real_totag = ast_strdupa(get_header(req, "To")); + if (sip_extract_tag(&real_totag)) { + real_totag = NULL; + } + if (strcmp(real_totag, totag)) { + match = 0; + } + } + if (match && fromtag) { + real_fromtag = ast_strdupa(get_header(req, "From")); + if (sip_extract_tag(&real_fromtag)) { + real_fromtag = NULL; + } + if (strcmp(real_fromtag, fromtag)) { + match = 0; + } + } + } + + if (!match) { + ast_mutex_unlock(&sip_pvt_ptr->lock); + break; + } + if (sip_pvt_ptr->owner) { while(ast_mutex_trylock(&sip_pvt_ptr->owner->lock)) { ast_mutex_unlock(&sip_pvt_ptr->lock); @@ -5532,14 +5589,12 @@ return replaced; } - - /*--- get_refer_info: Call transfer support (new standard) ---*/ static int get_refer_info(struct sip_pvt *sip_pvt, struct sip_request *outgoing_req) { char *p_refer_to = NULL, *p_referred_by = NULL, *h_refer_to = NULL, *h_referred_by = NULL, *h_contact = NULL; - char *replace_callid = "", *refer_to = NULL, *referred_by = NULL, *ptr = NULL; + char *replace_callid = "", *refer_to = NULL, *referred_by = NULL, *ptr = NULL, *replaces_header=NULL, *refer_uri; struct sip_request *req = NULL; struct sip_pvt *sip_pvt_ptr = NULL; struct ast_channel *chan = NULL, *peer = NULL; @@ -5550,14 +5605,14 @@ req = &sip_pvt->initreq; } - if(!( (p_refer_to = get_header(req, "Refer-To")) && (h_refer_to = ast_strdupa(p_refer_to)) )) { + if (!( (p_refer_to = get_header(req, "Refer-To")) && (h_refer_to = ast_strdupa(p_refer_to)) )) { ast_log(LOG_WARNING, "No Refer-To Header That's illegal\n"); return -1; } refer_to = ditch_braces(h_refer_to); - if(!( (p_referred_by = get_header(req, "Referred-By")) && (h_referred_by = ast_strdupa(p_referred_by)) )) { + if (!( (p_referred_by = get_header(req, "Referred-By")) && (h_referred_by = ast_strdupa(p_referred_by)) )) { ast_log(LOG_WARNING, "No Refer-To Header That's illegal\n"); return -1; } @@ -5570,9 +5625,11 @@ ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", referred_by); return -1; } + + refer_to += 4; referred_by += 4; - + refer_uri = ast_strdupa(refer_to); if ((ptr = strchr(refer_to, '?'))) { /* Search for arguemnts */ @@ -5580,10 +5637,7 @@ ptr++; if (!strncasecmp(ptr, "REPLACES=", 9)) { replace_callid = ast_strdupa(ptr + 9); - /* someday soon to support invite/replaces properly! - replaces_header = ast_strdupa(replace_callid); - -anthm - */ + replaces_header = ast_strdupa(replace_callid); sip_unescape_uri(replace_callid); if ((ptr = strchr(replace_callid, '%'))) *ptr = '\0'; @@ -5617,19 +5671,50 @@ strncpy(sip_pvt->referred_by, "", sizeof(sip_pvt->referred_by) - 1); strncpy(sip_pvt->refer_contact, "", sizeof(sip_pvt->refer_contact) - 1); sip_pvt->refer_call = NULL; - if ((sip_pvt_ptr = get_sip_pvt_byid_locked(replace_callid))) { + if ((sip_pvt_ptr = get_sip_pvt_byid_locked(replace_callid, req, NULL, NULL))) { sip_pvt->refer_call = sip_pvt_ptr; if (sip_pvt->refer_call == sip_pvt) { ast_log(LOG_NOTICE, "Supervised transfer attempted to transfer into same call id (%s == %s)!\n", replace_callid, sip_pvt->callid); sip_pvt->refer_call = NULL; - } else - return 0; + } + return 0; } else { - ast_log(LOG_NOTICE, "Supervised transfer requested, but unable to find callid '%s'. Both legs must reside on Asterisk box to transfer at this time.\n", replace_callid); - /* XXX The refer_to could contain a call on an entirely different machine, requiring an - INVITE with a replaces header -anthm XXX */ + /* Don't ask me =0 ?, SIP made do it! */ + int cause = 0, res = -1; + struct ast_channel *ichan = NULL; - + transmit_notify_with_sipfrag(sip_pvt, sip_pvt->ocseq); + if ((ptr = strchr(refer_uri, ';'))) { + *ptr = '\0'; + } + + if ((ichan = sip_request("SIP", sip_pvt->owner ? sip_pvt->owner->readformat : AST_FORMAT_ULAW, refer_uri, &cause))) { + struct ast_frame *f; + char *rbuf; + ast_log(LOG_DEBUG, "Going hunting for a remote INVITE/Replaces at [%s] Wish me luck!\n", refer_uri); + if ((rbuf = alloca(strlen(replaces_header) + 10))) { + sprintf(rbuf, "Replaces: %s", replaces_header); + sip_addheader(ichan, rbuf); + sip_call(ichan, refer_uri, 20000); + ast_channel_masquerade(sip_pvt->owner, ichan); + if ((f = ast_read(ichan))) { + ast_log(LOG_DEBUG, "WooHoo! The INVITE/Replaces Worked!\n"); + ast_frfree(f); + transmit_response(sip_pvt, "202 Accepted", req); + res = SIP_RETVAL_IGNORE; /* means do nothing more */ + } else { + res = -1; + } + } else { + ast_log(LOG_ERROR,"Memory Error!\n"); + res = -1; + } + + ast_hangup(ichan); + } else { + res = -1; + } + return res; } } else if (ast_exists_extension(NULL, sip_pvt->context, refer_to, 1, NULL) || !strcmp(refer_to, ast_parking_ext())) { /* This is an unsupervised transfer */ @@ -5643,7 +5728,7 @@ strncpy(sip_pvt->refer_contact, h_contact, sizeof(sip_pvt->refer_contact) - 1); } sip_pvt->refer_call = NULL; - if((chan = sip_pvt->owner) && (peer = ast_bridged_channel(sip_pvt->owner))) { + if ((chan = sip_pvt->owner) && (peer = ast_bridged_channel(sip_pvt->owner))) { pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", peer->name); pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", chan->name); } @@ -5818,7 +5903,7 @@ *end = '\0'; else output[0] = '\0'; - if(strstr(input,"privacy=full") || strstr(input,"privacy=uri")) + if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; return 0; @@ -5851,7 +5936,7 @@ rpid = get_header(req, "Remote-Party-ID"); memset(rpid_num,0,sizeof(rpid_num)); - if(!ast_strlen_zero(rpid)) + if (!ast_strlen_zero(rpid)) p->callingpres = get_rpid_num(rpid,rpid_num, sizeof(rpid_num)); of = ditch_braces(from); @@ -5887,14 +5972,14 @@ ast_copy_flags(p, user, SIP_TRUSTRPID | SIP_USECLIENTCODE | SIP_NAT | SIP_PROG_INBAND | SIP_OSPAUTH); /* copy channel vars */ for (v = user->chanvars ; v ; v = v->next) { - if((tmpvar = ast_variable_new(v->name, v->value))) { + if ((tmpvar = ast_variable_new(v->name, v->value))) { tmpvar->next = p->chanvars; p->chanvars = tmpvar; } } p->prefs = user->prefs; /* replace callerid if rpid found, and not restricted */ - if(!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) { + if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) { if (*calleridname) strncpy(p->cid_name, calleridname, sizeof(p->cid_name) - 1); strncpy(p->cid_num, rpid_num, sizeof(p->cid_num) - 1); @@ -5966,7 +6051,7 @@ /* Take the peer */ ast_copy_flags(p, peer, SIP_TRUSTRPID | SIP_USECLIENTCODE | SIP_NAT | SIP_PROG_INBAND | SIP_OSPAUTH); /* replace callerid if rpid found, and not restricted */ - if(!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) { + if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) { if (*calleridname) strncpy(p->cid_name, calleridname, sizeof(p->cid_name) - 1); strncpy(p->cid_num, rpid_num, sizeof(p->cid_num) - 1); @@ -5999,7 +6084,7 @@ strncpy(p->authname, peer->name, sizeof(p->authname) - 1); /* copy channel vars */ for (v = peer->chanvars ; v ; v = v->next) { - if((tmpvar = ast_variable_new(v->name, v->value))) { + if ((tmpvar = ast_variable_new(v->name, v->value))) { tmpvar->next = p->chanvars; p->chanvars = tmpvar; } @@ -6737,10 +6822,10 @@ pref = &peer->prefs; for(x = 0; x < 32 ; x++) { codec = ast_codec_pref_index(pref,x); - if(!codec) + if (!codec) break; ast_cli(fd, "%s", ast_getformatname(codec)); - if(x < 31 && ast_codec_pref_index(pref,x+1)) + if (x < 31 && ast_codec_pref_index(pref,x+1)) ast_cli(fd, "|"); } @@ -6820,10 +6905,10 @@ pref = &peer->prefs; for(x = 0; x < 32 ; x++) { codec = ast_codec_pref_index(pref,x); - if(!codec) + if (!codec) break; ast_cli(fd, "%s", ast_getformatname(codec)); - if(x < 31 && ast_codec_pref_index(pref,x+1)) + if (x < 31 && ast_codec_pref_index(pref,x+1)) ast_cli(fd, ","); } @@ -6896,10 +6981,10 @@ pref = &user->prefs; for(x = 0; x < 32 ; x++) { codec = ast_codec_pref_index(pref,x); - if(!codec) + if (!codec) break; ast_cli(fd, "%s", ast_getformatname(codec)); - if(x < 31 && ast_codec_pref_index(pref,x+1)) + if (x < 31 && ast_codec_pref_index(pref,x+1)) ast_cli(fd, "|"); } @@ -7976,12 +8061,12 @@ } switch(resp) { case 100: /* 100 Trying */ - if(sipmethod == SIP_INVITE) { + if (sipmethod == SIP_INVITE) { sip_cancel_destroy(p); } break; case 183: /* 183 Session Progress */ - if(sipmethod == SIP_INVITE) { + if (sipmethod == SIP_INVITE) { sip_cancel_destroy(p); if (!ast_strlen_zero(get_header(req, "Content-Type"))) process_sdp(p, req); @@ -7992,7 +8077,7 @@ } break; case 180: /* 180 Ringing */ - if(sipmethod == SIP_INVITE) { + if (sipmethod == SIP_INVITE) { sip_cancel_destroy(p); if (p->owner) { ast_queue_control(p->owner, AST_CONTROL_RINGING); @@ -8071,8 +8156,8 @@ for(;;) { contact = __get_header(req, "Contact", &start); /* this loop ensures we get a contact header about our register request */ - if(!ast_strlen_zero(contact)) { - if( (tmptmp=strstr(contact, p->our_contact))) { + if (!ast_strlen_zero(contact)) { + if ( (tmptmp=strstr(contact, p->our_contact))) { contact=tmptmp; break; } @@ -8146,7 +8231,7 @@ transmit_request(p, SIP_ACK, seqno, 0, 0); /* Then we AUTH */ /* But only if the packet wasn't marked as ignore in handle_request */ - if(!ignore){ + if (!ignore){ p->theirtag[0]='\0'; /* forget their old tag, so we don't match tags when getting response */ if ((p->authtries > 1) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", SIP_INVITE, 1)) { ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); @@ -8419,18 +8504,19 @@ if (peera->cdr && peerb->cdr) { peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); - } else if(peera->cdr) { + } else if (peera->cdr) { peerb->cdr = peera->cdr; } peera->cdr = NULL; if (peerb->cdr && peerc->cdr) { peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); - } else if(peerc->cdr) { + } else if (peerc->cdr) { peerb->cdr = peerc->cdr; } peerc->cdr = NULL; + ast_log(LOG_DEBUG, "XXXX Trying to masquerade %s and %s\n", peerb->name, peerc->name); if (ast_channel_masquerade(peerb, peerc)) { ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); res = -1; @@ -8478,7 +8564,24 @@ struct ast_channel *c=NULL; int gotdest; struct ast_frame af = { AST_FRAME_NULL, }; + char *p_replaces, *replace_id = NULL; + if ((p_replaces = get_header(req, "Replaces"))) { + if (ast_strlen_zero(p_replaces)) { + p_replaces = NULL; + } else { + char *ptr; + ast_log(LOG_DEBUG, "I SEE a Replaces [%s]\n", p_replaces); + replace_id = ast_strdupa(p_replaces); + if (strchr(replace_id, '%')) { + sip_unescape_uri(replace_id); + } + if ((ptr = strchr(replace_id, ';'))) { + *ptr = '\0'; + } + } + } + if (ast_test_flag(p, SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { /* This is a call to ourself. Send ourselves an error code and stop processing immediately, as SIP really has no good mechanism for @@ -8487,6 +8590,7 @@ /* We do NOT destroy p here, so that our response will be accepted */ return 0; } + if (!ignore) { /* Use this as the basis */ if (debug) @@ -8511,8 +8615,10 @@ ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); } } - } else if (debug) + } else if (debug) { ast_verbose("Ignoring this request\n"); + } + if (!p->lastinvite && !ignore && !p->owner) { /* Handle authentication if this is our first invite */ res = check_user(p, req, SIP_INVITE, e, 1, sin, ignore); @@ -8563,22 +8669,22 @@ get_rdnis(p, NULL); extract_uri(p, req); build_contact(p); - - if (gotdest) { + + if (!replace_id && gotdest) { if (gotdest < 0) { if (ignore) transmit_response(p, "404 Not Found", req); else transmit_response_reliable(p, "404 Not Found", req, 1); update_user_counter(p,DEC_IN_USE); - } else { - if (ignore) - transmit_response(p, "484 Address Incomplete", req); - else - transmit_response_reliable(p, "484 Address Incomplete", req, 1); - update_user_counter(p,DEC_IN_USE); - } - ast_set_flag(p, SIP_NEEDDESTROY); + } else { + if (ignore) + transmit_response(p, "484 Address Incomplete", req); + else + transmit_response_reliable(p, "484 Address Incomplete", req, 1); + update_user_counter(p,DEC_IN_USE); + } + ast_set_flag(p, SIP_NEEDDESTROY); } else { /* If no extension was specified, use the s one */ if (ast_strlen_zero(p->exten)) @@ -8591,16 +8697,41 @@ /* Save Record-Route for any later requests we make on this dialogue */ build_route(p, req, 0); if (c) { + if (replace_id) { + struct sip_pvt *refer_pvt; + struct ast_frame *f; + + if ((refer_pvt = get_sip_pvt_byid_locked(replace_id, req, NULL, p->theirtag))) { + ast_log(LOG_DEBUG, "XXXXXXXX I PARSED a Replaces [%s]\n", p_replaces); + transmit_response(p, "100 Trying", req); + ast_mutex_unlock(&refer_pvt->owner->lock); + ast_mutex_unlock(&refer_pvt->lock); + ast_channel_masquerade(refer_pvt->owner, c ); + ast_hangup(c); + c = refer_pvt->owner; + if ((f = ast_read(c))) { + ast_log(LOG_DEBUG, "XXXXXXXX I DID a Replaces [%s]\n", p_replaces); + ast_frfree(f); + ast_setstate(c, AST_STATE_UP); + } + } else { + transmit_response_with_allow(p, "481 Call/Transaction Does Not Exist", req, 0); + return 0; + } + } /* Pre-lock the call */ ast_mutex_lock(&c->lock); } } - - } else + } else { c = p->owner; - if (!ignore && p) + } + + if (!ignore && p) { p->lastinvite = seqno; + } if (c) { + switch(c->_state) { case AST_STATE_DOWN: transmit_response(p, "100 Trying", req); @@ -8688,11 +8819,13 @@ if (ast_strlen_zero(p->context)) strncpy(p->context, default_context, sizeof(p->context) - 1); res = get_refer_info(p, req); - if (res < 0) + if (res == SIP_RETVAL_IGNORE) { + ignore = 1; + } else if (res < 0) { transmit_response_with_allow(p, "404 Not Found", req, 1); - else if (res > 0) + } else if (res > 0) { transmit_response_with_allow(p, "484 Address Incomplete", req, 1); - else { + } else { int nobye = 0; if (!ignore) { if (p->refer_call) { @@ -9016,7 +9149,7 @@ cseq += len; /* Determine the request URI for sip, sips or tel URIs */ - if( determine_firstline_parts( req ) < 0 ) { + if ( determine_firstline_parts( req ) < 0 ) { return -1; } cmd = req->rlPart1; @@ -9723,7 +9856,7 @@ ast_set_flag(flags, SIP_PROG_INBAND_YES); } else if (!strcasecmp(v->name, "allowguest")) { #ifdef OSP_SUPPORT - if(!strcasecmp(v->value, "osp")) + if (!strcasecmp(v->value, "osp")) global_allowguest = 2; else #endif @@ -9893,7 +10026,7 @@ if (varname && (varval = strchr(varname,'='))) { *varval = '\0'; varval++; - if((tmpvar = ast_variable_new(varname, varval))) { + if ((tmpvar = ast_variable_new(varname, varval))) { tmpvar->next = user->chanvars; user->chanvars = tmpvar; } @@ -10037,7 +10170,7 @@ peer->expiry = expiry; } /* If we have channel variables, remove them (reload) */ - if(peer->chanvars) { + if (peer->chanvars) { ast_variables_destroy(peer->chanvars); peer->chanvars = NULL; } @@ -10210,7 +10343,7 @@ if (varname && (varval = strchr(varname,'='))) { *varval = '\0'; varval++; - if((tmpvar = ast_variable_new(varname, varval))) { + if ((tmpvar = ast_variable_new(varname, varval))) { tmpvar->next = peer->chanvars; peer->chanvars = tmpvar; } @@ -10347,7 +10480,7 @@ ast_set2_flag((&global_flags_page2), ast_true(v->value), SIP_PAGE2_RTNOUPDATE); } else if (!strcasecmp(v->name, "rtautoclear")) { int i = atoi(v->value); - if(i > 0) + if (i > 0) global_rtautoclear = i; else i = 0; @@ -11124,7 +11257,7 @@ p = p->next; /* Free associated memory */ ast_mutex_destroy(&pl->lock); - if(pl->chanvars) { + if (pl->chanvars) { ast_variables_destroy(pl->chanvars); pl->chanvars = NULL; }