From f5a82873ae46ca34c99dc00cc21cd4bd571ab7cb Mon Sep 17 00:00:00 2001 From: kpfleming Date: Tue, 16 May 2006 20:05:17 +0000 Subject: don't leak frames when deferring DTMF or dropping duplicate ANSWER frames (issue #7041, slightly different fix, reported/patched by clausf) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@27468 f38db490-d61c-443f-a65b-d21fe96a405b --- channel.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/channel.c b/channel.c index ae4c747e4..77ad5f34e 100644 --- a/channel.c +++ b/channel.c @@ -1950,10 +1950,12 @@ struct ast_frame *ast_read(struct ast_channel *chan) chan->dtmfq[strlen(chan->dtmfq)] = f->subclass; else ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name); + ast_frfree(f); f = &null_frame; } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) { if (prestate == AST_STATE_UP) { ast_log(LOG_DEBUG, "Dropping duplicate answer!\n"); + ast_frfree(f); f = &null_frame; } /* Answer the CDR */ -- cgit v1.2.3 From d17b00c198691131cde8e2415ffe442e7d1350e9 Mon Sep 17 00:00:00 2001 From: file Date: Tue, 16 May 2006 23:31:56 +0000 Subject: Inherit channel variables during call forwards when going through chan_local (issue #7095 reported by raarts) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@27594 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_dial.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/app_dial.c b/apps/app_dial.c index 88f147a7c..3bfa91165 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -471,6 +471,8 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu o->chan = ast_request(tech, in->nativeformats, stuff, &cause); if (!o->chan) ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause); + else + ast_channel_inherit_variables(in, o->chan); } else { if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", o->chan->name); @@ -1060,6 +1062,8 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags tmp->chan = ast_request(tech, chan->nativeformats, stuff, &cause); if (!tmp->chan) ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause); + else + ast_channel_inherit_variables(chan, tmp->chan); } else { if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", tmp->chan->name); -- cgit v1.2.3 From 0d80131e6109d8911dcc32c3865e2056eed78e3f Mon Sep 17 00:00:00 2001 From: tilghman Date: Wed, 17 May 2006 02:19:50 +0000 Subject: Bug 7125 - Fix race condition between resequencing and leaving a message git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@27636 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_voicemail.c | 217 ++++++++++++++++++++++++++------------------------- 1 file changed, 112 insertions(+), 105 deletions(-) diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index 017c75c38..cee3a1eaa 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -2364,17 +2364,17 @@ struct leave_vm_options { static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_options *options) { - char tmptxtfile[256], txtfile[256]; + char txtfile[256], tmptxtfile[256]; char callerid[256]; FILE *txt; - int res = 0; + int res = 0, txtdes; int msgnum; int duration = 0; int ausemacro = 0; int ousemacro = 0; int ouseexten = 0; char date[256]; - char dir[256]; + char dir[256], tmpdir[260]; char fn[256]; char prefile[256]=""; char tempfile[256]=""; @@ -2429,6 +2429,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_ DISPOSE(tempfile, -1); /* It's easier just to try to make it than to check for its existence */ create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); + create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"); /* Check current or macro-calling context for special extensions */ if (ast_test_flag(vmu, VM_OPERATOR)) { @@ -2535,22 +2536,25 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_ if (!ast_strlen_zero(fmt)) { msgnum = 0; - if (vm_lock_path(dir)) { - free_user(vmu); - return ERROR_LOCK_PATH; + if (count_messages(vmu, dir) >= vmu->maxmsg) { + res = ast_streamfile(chan, "vm-mailboxfull", chan->language); + if (!res) + res = ast_waitstream(chan, ""); + ast_log(LOG_WARNING, "No more messages possible\n"); + pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); + goto leave_vm_out; } - /* - * This operation can be very expensive if done say over NFS or if the mailbox has 100+ messages - * in the mailbox. So we should get this first so we don't cut off the first few seconds of the - * message. - */ - do { - make_file(fn, sizeof(fn), dir, msgnum); - if (!EXISTS(dir,msgnum,fn,chan->language)) - break; - msgnum++; - } while (msgnum < vmu->maxmsg); + snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); + txtdes = mkstemp(tmptxtfile); + if (txtdes < 0) { + res = ast_streamfile(chan, "vm-mailboxfull", chan->language); + if (!res) + res = ast_waitstream(chan, ""); + ast_log(LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); + pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); + goto leave_vm_out; + } /* Now play the beep once we have the message number for our next message. */ if (res >= 0) { @@ -2559,101 +2563,104 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_ if (!res) res = ast_waitstream(chan, ""); } - if (msgnum < vmu->maxmsg) { - /* assign a variable with the name of the voicemail file */ - pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); - - /* Store information */ - snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); - snprintf(tmptxtfile, sizeof(tmptxtfile), "%s.txt.tmp", fn); - txt = fopen(tmptxtfile, "w+"); - if (txt) { - get_date(date, sizeof(date)); - fprintf(txt, - ";\n" - "; Message Information file\n" - ";\n" - "[message]\n" - "origmailbox=%s\n" - "context=%s\n" - "macrocontext=%s\n" - "exten=%s\n" - "priority=%d\n" - "callerchan=%s\n" - "callerid=%s\n" - "origdate=%s\n" - "origtime=%ld\n" - "category=%s\n", - ext, - chan->context, - chan->macrocontext, - chan->exten, - chan->priority, - chan->name, - ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"), - date, (long)time(NULL), - category ? category : ""); - } else - ast_log(LOG_WARNING, "Error opening text file for output\n"); - res = play_record_review(chan, NULL, fn, vmmaxmessage, fmt, 1, vmu, &duration, dir, options->record_gain); - if (res == '0') { - if (txt && EXISTS(dir,msgnum,fn,chan->language)) { - fclose(txt); - rename(tmptxtfile, txtfile); - } else if (txt && !EXISTS(dir,msgnum,fn,chan->language)) { - if (option_debug) - ast_log(LOG_DEBUG, "The recorded media file is gone, so we should remove the .txt file too!\n"); - fclose(txt); - unlink(tmptxtfile); - } - goto transfer; - } - if (res > 0) - res = 0; - if (txt) { - fprintf(txt, "duration=%d\n", duration); - fclose(txt); - rename(tmptxtfile, txtfile); - } - + + /* Store information */ + txt = fdopen(txtdes, "w+"); + if (txt) { + get_date(date, sizeof(date)); + fprintf(txt, + ";\n" + "; Message Information file\n" + ";\n" + "[message]\n" + "origmailbox=%s\n" + "context=%s\n" + "macrocontext=%s\n" + "exten=%s\n" + "priority=%d\n" + "callerchan=%s\n" + "callerid=%s\n" + "origdate=%s\n" + "origtime=%ld\n" + "category=%s\n", + ext, + chan->context, + chan->macrocontext, + chan->exten, + chan->priority, + chan->name, + ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"), + date, (long)time(NULL), + category ? category : ""); + } else + ast_log(LOG_WARNING, "Error opening text file for output\n"); + res = play_record_review(chan, NULL, tmptxtfile, vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain); + + if (txt) { if (duration < vmminmessage) { if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminmessage); DELETE(dir,msgnum,fn); - /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ - pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); - goto leave_vm_out; - } - /* Are there to be more recipients of this message? */ - while (tmpptr) { - struct ast_vm_user recipu, *recip; - char *exten, *context; - - exten = strsep(&tmpptr, "&"); - context = strchr(exten, '@'); - if (context) { - *context = '\0'; - context++; - } - if ((recip = find_user(&recipu, context, exten))) { - copy_message(chan, vmu, 0, msgnum, duration, recip, fmt); - free_user(recip); + } else { + fprintf(txt, "duration=%d\n", duration); + fclose(txt); + if (vm_lock_path(dir)) { + ast_log(LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); + /* Delete files */ + ast_filedelete(tmptxtfile, NULL); + unlink(tmptxtfile); + } else { + for (;;) { + make_file(fn, sizeof(fn), dir, msgnum); + if (!EXISTS(dir, msgnum, fn, NULL)) + break; + msgnum++; + } + + /* assign a variable with the name of the voicemail file */ + pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); + + snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); + ast_filerename(tmptxtfile, fn, NULL); + rename(tmptxtfile, txtfile); + + ast_unlock_path(dir); + + /* Are there to be more recipients of this message? */ + while (tmpptr) { + struct ast_vm_user recipu, *recip; + char *exten, *context; + + exten = strsep(&tmpptr, "&"); + context = strchr(exten, '@'); + if (context) { + *context = '\0'; + context++; + } + if ((recip = find_user(&recipu, context, exten))) { + copy_message(chan, vmu, 0, msgnum, duration, recip, fmt); + free_user(recip); + } + } + if (ast_fileexists(fn, NULL, NULL)) { + STORE(dir, vmu->mailbox, vmu->context, msgnum); + notify_new_message(chan, vmu, msgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name); + DISPOSE(dir, msgnum); + } } } - if (ast_fileexists(fn, NULL, NULL)) { - STORE(dir, vmu->mailbox, vmu->context, msgnum); - notify_new_message(chan, vmu, msgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name); - DISPOSE(dir, msgnum); - } - pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); - } else { - ast_unlock_path(dir); - res = ast_streamfile(chan, "vm-mailboxfull", chan->language); - if (!res) - res = ast_waitstream(chan, ""); - ast_log(LOG_WARNING, "No more messages possible\n"); - pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); } + + if (res == '0') { + goto transfer; + } else if (res > 0) + res = 0; + + if (duration < vmminmessage) + /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ + pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); + else + pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); } else ast_log(LOG_WARNING, "No format for saving voicemail?\n"); leave_vm_out: -- cgit v1.2.3 From fa9dd02a2d6f1bbf0622f637d102743b3a4be22f Mon Sep 17 00:00:00 2001 From: oej Date: Wed, 17 May 2006 09:21:45 +0000 Subject: chan_sip did not use the TRANSFER_CONTEXT for transfers, like res_features. Now fixed. git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@27723 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_sip.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index aa651015d..7fbbd7d93 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -6665,6 +6665,7 @@ static int get_refer_info(struct sip_pvt *sip_pvt, struct sip_request *outgoing_ struct sip_request *req = NULL; struct sip_pvt *sip_pvt_ptr = NULL; struct ast_channel *chan = NULL, *peer = NULL; + const char *transfercontext; req = outgoing_req; @@ -6741,8 +6742,12 @@ static int get_refer_info(struct sip_pvt *sip_pvt, struct sip_request *outgoing_ *ptr = '\0'; } + transfercontext = pbx_builtin_getvar_helper(sip_pvt->owner, "TRANSFER_CONTEXT"); + if (ast_strlen_zero(transfercontext)) + transfercontext = sip_pvt->context; + if (sip_debug_test_pvt(sip_pvt)) { - ast_verbose("Transfer to %s in %s\n", refer_to, sip_pvt->context); + ast_verbose("Transfer to %s in %s\n", refer_to, transfercontext); if (referred_by) ast_verbose("Transfer from %s in %s\n", referred_by, sip_pvt->context); } @@ -6767,7 +6772,7 @@ static int get_refer_info(struct sip_pvt *sip_pvt, struct sip_request *outgoing_ INVITE with a replaces header -anthm XXX */ /* The only way to find out is to use the dialplan - oej */ } - } else if (ast_exists_extension(NULL, sip_pvt->context, refer_to, 1, NULL) || !strcmp(refer_to, ast_parking_ext())) { + } else if (ast_exists_extension(NULL, transfercontext, refer_to, 1, NULL) || !strcmp(refer_to, ast_parking_ext())) { /* This is an unsupervised transfer (blind transfer) */ ast_log(LOG_DEBUG,"Unsupervised transfer to (Refer-To): %s\n", refer_to); @@ -6786,7 +6791,7 @@ static int get_refer_info(struct sip_pvt *sip_pvt, struct sip_request *outgoing_ pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", chan->name); } return 0; - } else if (ast_canmatch_extension(NULL, sip_pvt->context, refer_to, 1, NULL)) { + } else if (ast_canmatch_extension(NULL, transfercontext, refer_to, 1, NULL)) { return 1; } -- cgit v1.2.3 From 2479b8ce4048fc4407290997dbb1b6c5b787b279 Mon Sep 17 00:00:00 2001 From: file Date: Wed, 17 May 2006 15:17:04 +0000 Subject: OSPNext does not handle success/failure correctly (issue #7147 reported and fixed by eborgstrom) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@27767 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_osplookup.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/apps/app_osplookup.c b/apps/app_osplookup.c index 2fe2d016a..f436d7cfa 100644 --- a/apps/app_osplookup.c +++ b/apps/app_osplookup.c @@ -216,31 +216,33 @@ static int ospnext_exec(struct ast_channel *chan, void *data) cause = str2cause(args.cause); temp = pbx_builtin_getvar_helper(chan, "OSPHANDLE"); result.handle = -1; - if (!ast_strlen_zero(temp) && (sscanf(temp, "%d", &result.handle) == 1) && (result.handle > -1)) { - temp = pbx_builtin_getvar_helper(chan, "OSPRESULTS"); - if (ast_strlen_zero(temp) || (sscanf(temp, "%d", &result.numresults) != 1)) { - result.numresults = 0; - } - if ((res = ast_osp_next(&result, cause)) > 0) { - char tmp[80]; - snprintf(tmp, sizeof(tmp), "%d", result.handle); - pbx_builtin_setvar_helper(chan, "_OSPHANDLE", tmp); - pbx_builtin_setvar_helper(chan, "_OSPTECH", result.tech); - pbx_builtin_setvar_helper(chan, "_OSPDEST", result.dest); - pbx_builtin_setvar_helper(chan, "_OSPTOKEN", result.token); - snprintf(tmp, sizeof(tmp), "%d", result.numresults); - pbx_builtin_setvar_helper(chan, "_OSPRESULTS", tmp); - pbx_builtin_setvar_helper(chan, "OSPNEXTSTATUS", "SUCCESS"); - } + if (ast_strlen_zero(temp) || (sscanf(temp, "%d", &result.handle) != 1)) { + result.handle = -1; + } + temp = pbx_builtin_getvar_helper(chan, "OSPRESULTS"); + if (ast_strlen_zero(temp) || (sscanf(temp, "%d", &result.numresults) != 1)) { + result.numresults = 0; + } + if ((res = ast_osp_next(&result, cause)) > 0) { + char tmp[80]; + snprintf(tmp, sizeof(tmp), "%d", result.handle); + pbx_builtin_setvar_helper(chan, "_OSPHANDLE", tmp); + pbx_builtin_setvar_helper(chan, "_OSPTECH", result.tech); + pbx_builtin_setvar_helper(chan, "_OSPDEST", result.dest); + pbx_builtin_setvar_helper(chan, "_OSPTOKEN", result.token); + snprintf(tmp, sizeof(tmp), "%d", result.numresults); + pbx_builtin_setvar_helper(chan, "_OSPRESULTS", tmp); + pbx_builtin_setvar_helper(chan, "OSPNEXTSTATUS", "SUCCESS"); } else { if (!res) { if (result.handle < 0) ast_log(LOG_NOTICE, "OSP Lookup Next failed for handle '%d'\n", result.handle); else ast_log(LOG_DEBUG, "No OSP handle specified\n"); - pbx_builtin_setvar_helper(chan, "OSPNEXTSTATUS", "FAILED"); } else ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Next!\n", chan->name); + + pbx_builtin_setvar_helper(chan, "OSPNEXTSTATUS", "FAILED"); } if (!res) { /* Look for a "busy" place */ -- cgit v1.2.3 From 8414901dba0d0e67fd7a4bb62a05056d7882eb99 Mon Sep 17 00:00:00 2001 From: file Date: Wed, 17 May 2006 17:07:52 +0000 Subject: Priority jumping not working on VoiceMail app with new syntax (issue #7164 reported and fixed by alvaro_palma_aste) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@27847 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_voicemail.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index cee3a1eaa..f61f58e86 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -5537,7 +5537,7 @@ static int vm_exec(struct ast_channel *chan, void *data) LOCAL_USER_REMOVE(u); return -1; } - ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING); + ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP); if (ast_test_flag(&flags, OPT_RECORDGAIN)) { int gain; -- cgit v1.2.3 From 243a5c2a23cc73345a4f18bebf80760a4f8b4163 Mon Sep 17 00:00:00 2001 From: oej Date: Wed, 17 May 2006 19:27:15 +0000 Subject: Issue #7176 - Crash in expire_register (We need to find out what's causing peer to be undefined, so this is just a bandaid, not a real fix) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@27927 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_sip.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 7fbbd7d93..6eb47c0c6 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -525,7 +525,7 @@ struct sip_auth { #define SIP_REALTIME (1 << 11) /*!< Flag for realtime users */ #define SIP_USECLIENTCODE (1 << 12) /*!< Trust X-ClientCode info message */ #define SIP_OUTGOING (1 << 13) /*!< Is this an outgoing call? */ -#define SIP_SELFDESTRUCT (1 << 14) +#define SIP_SELFDESTRUCT (1 << 14) /*!< This is an autocreated peer */ #define SIP_DYNAMIC (1 << 15) /*!< Is this a dynamic peer? */ /* --- Choices for DTMF support in SIP channel */ #define SIP_DTMF (3 << 16) /*!< three settings, uses two bits */ @@ -5639,17 +5639,24 @@ static void destroy_association(struct sip_peer *peer) static int expire_register(void *data) { struct sip_peer *peer = data; + + if (!peer) /* Hmmm. We have no peer. Weird. */ + return 0; memset(&peer->addr, 0, sizeof(peer->addr)); destroy_association(peer); manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); - register_peer_exten(peer, 0); + register_peer_exten(peer, 0); /* Remove regexten */ peer->expire = -1; ast_device_state_changed("SIP/%s", peer->name); + + /* Do we need to release this peer from memory? + Only for realtime peers and autocreated peers + */ if (ast_test_flag(peer, SIP_SELFDESTRUCT) || ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTAUTOCLEAR)) { - peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); + peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); /* Remove from peer list */ ASTOBJ_UNREF(peer, sip_destroy_peer); } -- cgit v1.2.3 From c3b984a3201863f7c6596022dce128b803187cf8 Mon Sep 17 00:00:00 2001 From: file Date: Wed, 17 May 2006 22:34:08 +0000 Subject: Fix codec priority stuff during authentication (issue #6194 reported by jkoopmann) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@27973 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_iax2.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index a1ce6907b..a124fb00b 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -464,7 +464,10 @@ struct chan_iax2_pvt { int maxtime; /*! Peer Address */ struct sockaddr_in addr; + /*! Actual used codec preferences */ struct ast_codec_pref prefs; + /*! Requested codec preferences */ + struct ast_codec_pref rprefs; /*! Our call number */ unsigned short callno; /*! Peer callno */ @@ -4755,9 +4758,12 @@ static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies if (ies->version) version = ies->version; - if(ies->codec_prefs) + /* Use provided preferences until told otherwise for actual preferences */ + if(ies->codec_prefs) { + ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); - + } + if (!gotcapability) iaxs[callno]->peercapability = iaxs[callno]->peerformat; if (version > IAX_PROTO_VERSION) { @@ -6299,7 +6305,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata) struct iax_frame *duped_fr; char host_pref_buf[128]; char caller_pref_buf[128]; - struct ast_codec_pref pref,rpref; + struct ast_codec_pref pref; char *using_prefs = "mine"; dblbuf[0] = 0; /* Keep GCC from whining */ @@ -6826,20 +6832,22 @@ retryowner: strcpy(host_pref_buf, "disabled"); } else { using_prefs = "mine"; - if(ies.codec_prefs) { - ast_codec_pref_convert(&rpref, ies.codec_prefs, 32, 0); + /* If the information elements are in here... use them */ + if (ies.codec_prefs) + ast_codec_pref_convert(&iaxs[fr.callno]->rprefs, ies.codec_prefs, 32, 0); + if (ast_codec_pref_index(&iaxs[fr.callno]->rprefs, 0)) { /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) { - pref = rpref; + pref = iaxs[fr.callno]->rprefs; using_prefs = "caller"; } else { pref = iaxs[fr.callno]->prefs; } } else pref = iaxs[fr.callno]->prefs; - + format = ast_codec_choose(&pref, iaxs[fr.callno]->capability & iaxs[fr.callno]->peercapability, 0); - ast_codec_pref_string(&rpref, caller_pref_buf, sizeof(caller_pref_buf) - 1); + ast_codec_pref_string(&iaxs[fr.callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); ast_codec_pref_string(&iaxs[fr.callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); } if (!format) { @@ -6870,12 +6878,12 @@ retryowner: strcpy(host_pref_buf,"disabled"); } else { using_prefs = "mine"; - if(ies.codec_prefs) { + if (ast_codec_pref_index(&iaxs[fr.callno]->rprefs, 0)) { /* Do the opposite of what we tried above. */ if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) { pref = iaxs[fr.callno]->prefs; } else { - pref = rpref; + pref = iaxs[fr.callno]->rprefs; using_prefs = "caller"; } format = ast_codec_choose(&pref, iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability, 1); @@ -7231,11 +7239,11 @@ retryowner2: strcpy(host_pref_buf, "disabled"); } else { using_prefs = "mine"; - if(ies.codec_prefs) { - /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ - ast_codec_pref_convert(&rpref, ies.codec_prefs, 32, 0); + if (ies.codec_prefs) + ast_codec_pref_convert(&iaxs[fr.callno]->rprefs, ies.codec_prefs, 32, 0); + if (ast_codec_pref_index(&iaxs[fr.callno]->rprefs, 0)) { if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) { - ast_codec_pref_convert(&pref, ies.codec_prefs, 32, 0); + pref = iaxs[fr.callno]->rprefs; using_prefs = "caller"; } else { pref = iaxs[fr.callno]->prefs; @@ -7244,7 +7252,7 @@ retryowner2: pref = iaxs[fr.callno]->prefs; format = ast_codec_choose(&pref, iaxs[fr.callno]->capability & iaxs[fr.callno]->peercapability, 0); - ast_codec_pref_string(&rpref, caller_pref_buf, sizeof(caller_pref_buf) - 1); + ast_codec_pref_string(&iaxs[fr.callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); ast_codec_pref_string(&iaxs[fr.callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); } if (!format) { @@ -7278,12 +7286,12 @@ retryowner2: strcpy(host_pref_buf,"disabled"); } else { using_prefs = "mine"; - if(ies.codec_prefs) { + if (ast_codec_pref_index(&iaxs[fr.callno]->rprefs, 0)) { /* Do the opposite of what we tried above. */ if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) { pref = iaxs[fr.callno]->prefs; } else { - pref = rpref; + pref = iaxs[fr.callno]->rprefs; using_prefs = "caller"; } format = ast_codec_choose(&pref, iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability, 1); -- cgit v1.2.3 From 6dd4ef5422e2d2f8f2b27bbd10bb3ed1d4ba2631 Mon Sep 17 00:00:00 2001 From: oej Date: Thu, 18 May 2006 12:13:46 +0000 Subject: Video in meetme? Hmmm. Removed until we do have some code for it. git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@28125 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_meetme.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/app_meetme.c b/apps/app_meetme.c index 891b51554..a8db48d7f 100644 --- a/apps/app_meetme.c +++ b/apps/app_meetme.c @@ -96,7 +96,6 @@ static const char *descrip = " 's' -- Present menu (user or admin) when '*' is received ('send' to menu)\n" " 't' -- set talk only mode. (Talk only, no listening)\n" " 'T' -- set talker detection (sent to manager interface and meetme list)\n" -" 'v' -- video mode\n" " 'w' -- wait until the marked user enters the conference\n" " 'x' -- close the conference when last marked user exits\n" " 'X' -- allow user to exit the conference by entering a valid single\n" @@ -212,7 +211,7 @@ static void *recordthread(void *args); #define CONFFLAG_STARMENU (1 << 4) /* If set asterisk will provide a menu to the user when '*' is pressed */ #define CONFFLAG_TALKER (1 << 5) /* If set the use can only send audio to the conference */ #define CONFFLAG_QUIET (1 << 6) /* If set there will be no enter or leave sounds */ -#define CONFFLAG_VIDEO (1 << 7) /* Set to enable video mode */ +#define CONFFLAG_ANNOUNCEUSERCOUNT (1 << 7) /* If set, when user joins the conference, they will be told the number of users that are already in */ #define CONFFLAG_AGI (1 << 8) /* Set to run AGI Script in Background */ #define CONFFLAG_MOH (1 << 9) /* Set to have music on hold when user is alone in conference */ #define CONFFLAG_MARKEDEXIT (1 << 10) /* If set the MeetMe will return if all marked with this flag left */ @@ -227,7 +226,6 @@ static void *recordthread(void *args); #define CONFFLAG_EMPTY (1 << 19) #define CONFFLAG_EMPTYNOPIN (1 << 20) #define CONFFLAG_ALWAYSPROMPT (1 << 21) -#define CONFFLAG_ANNOUNCEUSERCOUNT (1 << 22) /* If set, when user joins the conference, they will be told the number of users that are already in */ AST_APP_OPTIONS(meetme_opts, { -- cgit v1.2.3 From dbdb7501e3cf718e95adf781ce63463f3cf74a6e Mon Sep 17 00:00:00 2001 From: file Date: Thu, 18 May 2006 14:27:21 +0000 Subject: Fix endless looping message by checking value of res before doing retries stuff. (issue #7140 reported by tanischen) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@28169 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_voicemail.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index f61f58e86..35eedeca6 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -6520,20 +6520,21 @@ static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, s res = ast_play_and_wait(chan, "vm-star-cancel"); if (!res) res = ast_waitfordigit(chan, 6000); - if (!res) + if (!res) { retries++; - if (retries > 3) - res = 't'; - break; - + if (retries > 3) + res = 't'; } - if (res == 't') - res = 0; - else if (res == '*') - res = -1; + break; + } + if (res == 't') + res = 0; + else if (res == '*') + res = -1; } - + } + } else if (option == 1) { /* Reply */ /* Send reply directly to sender */ -- cgit v1.2.3 From d7badb16c77504daaa0faecfa6c9374281a974ca Mon Sep 17 00:00:00 2001 From: file Date: Thu, 18 May 2006 16:31:16 +0000 Subject: Return -1 on error in ODBC messagecount and 0 on success (issue #7133 reported by cfieldmtm) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@28212 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_voicemail.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index 35eedeca6..214c7aff3 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -2006,7 +2006,7 @@ static char *mbox(int id) #ifdef USE_ODBC_STORAGE static int messagecount(const char *mailbox, int *newmsgs, int *oldmsgs) { - int x = 0; + int x = -1; int res; SQLHSTMT stmt; char sql[256]; @@ -2018,6 +2018,7 @@ static int messagecount(const char *mailbox, int *newmsgs, int *oldmsgs) *newmsgs = 0; if (oldmsgs) *oldmsgs = 0; + /* If no mailbox, return immediately */ if (ast_strlen_zero(mailbox)) return 0; @@ -2099,7 +2100,7 @@ static int messagecount(const char *mailbox, int *newmsgs, int *oldmsgs) } SQLFreeHandle (SQL_HANDLE_STMT, stmt); *oldmsgs = atoi(rowdata); - x = 1; + x = 0; } else ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database); -- cgit v1.2.3 From 1d6df62761d2572e0d7fd7336ce2b17b83a623a0 Mon Sep 17 00:00:00 2001 From: tilghman Date: Thu, 18 May 2006 17:27:59 +0000 Subject: Bug 7167 - HasNewVoicemail and VMCOUNT() didn't work when USE_ODBC_STORAGE was defined git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@28257 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_hasnewvoicemail.c | 129 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 114 insertions(+), 15 deletions(-) diff --git a/apps/app_hasnewvoicemail.c b/apps/app_hasnewvoicemail.c index d5e7664f6..dbfea6a65 100644 --- a/apps/app_hasnewvoicemail.c +++ b/apps/app_hasnewvoicemail.c @@ -47,6 +47,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/utils.h" #include "asterisk/app.h" #include "asterisk/options.h" +#ifdef USE_ODBC_STORAGE +#include "asterisk/res_odbc.h" + +static char odbc_database[80]; +static char odbc_table[80]; +#endif static char *tdesc = "Indicator for whether a voice mailbox has messages in a given folder."; static char *app_hasvoicemail = "HasVoicemail"; @@ -77,25 +83,93 @@ STANDARD_LOCAL_USER; LOCAL_USER_DECL; -static int hasvoicemail_internal(char *context, char *box, char *folder) +#ifdef USE_ODBC_STORAGE +static int hasvoicemail_internal(const char *context, const char *mailbox, const char *folder) { - char vmpath[256]; - DIR *vmdir; - struct dirent *vment; - int count=0; - - snprintf(vmpath,sizeof(vmpath), "%s/voicemail/%s/%s/%s", (char *)ast_config_AST_SPOOL_DIR, context, box, folder); - if ((vmdir = opendir(vmpath))) { - /* No matter what the format of VM, there will always be a .txt file for each message. */ - while ((vment = readdir(vmdir))) { - if (!strncmp(vment->d_name + 7, ".txt", 4)) { - count++; - } + int nummsgs = 0; + int res; + SQLHSTMT stmt; + char sql[256]; + char rowdata[20]; + + if (!folder) + folder = "INBOX"; + /* If no mailbox, return immediately */ + if (ast_strlen_zero(mailbox)) + return 0; + if (ast_strlen_zero(context)) + context = "default"; + + odbc_obj *obj; + obj = fetch_odbc_obj(odbc_database, 0); + if (obj) { + res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt); + if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { + ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n"); + goto yuck; + } + snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir = '%s/voicemail/%s/%s/%s'", odbc_table, ast_config_AST_SPOOL_DIR, context, mailbox, folder); + res = SQLPrepare(stmt, sql, SQL_NTS); + if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { + ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql); + SQLFreeHandle(SQL_HANDLE_STMT, stmt); + goto yuck; } - closedir(vmdir); + res = odbc_smart_execute(obj, stmt); + if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { + ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); + SQLFreeHandle(SQL_HANDLE_STMT, stmt); + goto yuck; + } + res = SQLFetch(stmt); + if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { + ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql); + SQLFreeHandle(SQL_HANDLE_STMT, stmt); + goto yuck; + } + res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL); + if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { + ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql); + SQLFreeHandle(SQL_HANDLE_STMT, stmt); + goto yuck; + } + nummsgs = atoi(rowdata); + SQLFreeHandle(SQL_HANDLE_STMT, stmt); + } else + ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database); + +yuck: + return nummsgs; +} + +#else + +static int hasvoicemail_internal(const char *context, const char *mailbox, const char *folder) +{ + DIR *dir; + struct dirent *de; + char fn[256]; + int count = 0; + + if (ast_strlen_zero(folder)) + folder = "INBOX"; + if (ast_strlen_zero(context)) + context = "default"; + /* If no mailbox, return immediately */ + if (ast_strlen_zero(mailbox)) + return 0; + snprintf(fn, sizeof(fn), "%s/voicemail/%s/%s/%s", ast_config_AST_SPOOL_DIR, context, mailbox, folder); + dir = opendir(fn); + if (!dir) + return 0; + while ((de = readdir(dir))) { + if (!strncasecmp(de->d_name, "msg", 3) && !strcasecmp(de->d_name + 8, "txt")) + count++; } + closedir(dir); return count; } +#endif static int hasvoicemail_exec(struct ast_channel *chan, void *data) { @@ -222,6 +296,31 @@ struct ast_custom_function acf_vmcount = { .read = acf_vmcount_exec, }; +static int load_config(void) +{ +#ifdef USE_ODBC_STORAGE + struct ast_config *cfg; + char *tmp; + cfg = ast_config_load("voicemail.conf"); + if (cfg) { + if (! (tmp = ast_variable_retrieve(cfg, "general", "odbcstorage"))) + tmp = "asterisk"; + ast_copy_string(odbc_database, tmp, sizeof(odbc_database)); + + if (! (tmp = ast_variable_retrieve(cfg, "general", "odbctable"))) + tmp = "voicemessages"; + ast_copy_string(odbc_table, tmp, sizeof(odbc_table)); + ast_config_destroy(cfg); + } +#endif + return 0; +} + +int reload(void) +{ + return load_config(); +} + int unload_module(void) { int res; @@ -238,7 +337,7 @@ int unload_module(void) int load_module(void) { int res; - + load_config(); res = ast_custom_function_register(&acf_vmcount); res |= ast_register_application(app_hasvoicemail, hasvoicemail_exec, hasvoicemail_synopsis, hasvoicemail_descrip); res |= ast_register_application(app_hasnewvoicemail, hasvoicemail_exec, hasnewvoicemail_synopsis, hasnewvoicemail_descrip); -- cgit v1.2.3 From d5a76b5b3280880317355244d6815c28e6e4d712 Mon Sep 17 00:00:00 2001 From: kpfleming Date: Thu, 18 May 2006 19:16:40 +0000 Subject: support 'inactive' tag for SDP media streams (simple fix, proper fix will appear in 1.4 release) (issue #7130) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@28335 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_sip.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 6eb47c0c6..bc980b68b 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -3554,12 +3554,12 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req) sdpLineNum_iterator_init(&iterator); while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ - if (!strcasecmp(a, "sendonly")) { - sendonly=1; + if (!strcasecmp(a, "sendonly") || !strcasecmp(a, "inactive")) { + sendonly = 1; continue; } if (!strcasecmp(a, "sendrecv")) { - sendonly=0; + sendonly = 0; } if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue; if (debug) -- cgit v1.2.3 From da196b75b38646d68c1b285c67698af6581890b8 Mon Sep 17 00:00:00 2001 From: kpfleming Date: Thu, 18 May 2006 19:35:55 +0000 Subject: use unsigned counters for handling answer/IE lengths while processing DNS results (issue #7174) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@28337 f38db490-d61c-443f-a65b-d21fe96a405b --- enum.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/enum.c b/enum.c index 194f708ed..0c3e92513 100644 --- a/enum.c +++ b/enum.c @@ -80,27 +80,29 @@ struct naptr { } __attribute__ ((__packed__)); /*--- parse_ie: Parse NAPTR record information elements */ -static int parse_ie(char *data, int maxdatalen, char *src, int srclen) +static unsigned int parse_ie(char *data, unsigned int maxdatalen, char *src, unsigned int srclen) { - int len, olen; + unsigned int len, olen; - len = olen = (int)src[0]; + len = olen = (unsigned int) src[0]; src++; srclen--; - if (len > srclen || len < 0 ) { + + if (len > srclen) { ast_log(LOG_WARNING, "ENUM parsing failed: Wanted %d characters, got %d\n", len, srclen); return -1; } + if (len > maxdatalen) len = maxdatalen; memcpy(data, src, len); + return olen + 1; } /*--- parse_naptr: Parse DNS NAPTR record used in ENUM ---*/ static int parse_naptr(char *dst, int dstsize, char *tech, int techsize, char *answer, int len, char *naptrinput) { - char tech_return[80]; char *oanswer = answer; char flags[512] = ""; @@ -344,7 +346,7 @@ static int txt_callback(void *context, char *answer, int len, char *fullanswer) /*--- enum_callback: Callback from ENUM lookup function */ static int enum_callback(void *context, char *answer, int len, char *fullanswer) { - struct enum_context *c = (struct enum_context *)context; + struct enum_context *c = (struct enum_context *)context; void *p = NULL; int res; -- cgit v1.2.3 From f4f91d667ade903af0b2bcb713ba09cfdd12c921 Mon Sep 17 00:00:00 2001 From: kpfleming Date: Thu, 18 May 2006 20:24:07 +0000 Subject: handle incoming multipart/mixed message bodies in SIP and find the SDP, if presnet (issue #7124 reported and patched by eborgstrom, but very different fix) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@28380 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_sip.c | 124 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 98 insertions(+), 26 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index bc980b68b..da18e06f9 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -454,11 +454,13 @@ struct sip_request { int headers; /*!< # of SIP Headers */ int method; /*!< Method of this request */ char *header[SIP_MAX_HEADERS]; - int lines; /*!< SDP Content */ + int lines; /*!< Body Content */ char *line[SIP_MAX_LINES]; char data[SIP_MAX_PACKET]; int debug; /*!< Debug flag for this packet */ unsigned int flags; /*!< SIP_PKT Flags for this packet */ + unsigned int sdp_start; /*!< the line number where the SDP begins */ + unsigned int sdp_end; /*!< the line number where the SDP ends */ }; struct sip_pkt; @@ -2849,8 +2851,8 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, char *title) return tmp; } -/*! \brief get_sdp_by_line: Reads one line of SIP message body */ -static char* get_sdp_by_line(char* line, char *name, int nameLen) +/*! \brief get_body_by_line: Reads one line of message body */ +static char *get_body_by_line(char *line, char *name, int nameLen) { if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') { return ast_skip_blanks(line + nameLen + 1); @@ -2858,36 +2860,49 @@ static char* get_sdp_by_line(char* line, char *name, int nameLen) return ""; } -/*! \brief get_sdp: Gets all kind of SIP message bodies, including SDP, - but the name wrongly applies _only_ sdp */ +/*! \brief get_sdp: get a specific line from the SDP */ static char *get_sdp(struct sip_request *req, char *name) { int x; int len = strlen(name); char *r; - for (x=0; xlines; x++) { - r = get_sdp_by_line(req->line[x], name, len); + for (x = req->sdp_start; x < req->sdp_end; x++) { + r = get_body_by_line(req->line[x], name, len); if (r[0] != '\0') return r; } return ""; } - -static void sdpLineNum_iterator_init(int* iterator) +static void sdpLineNum_iterator_init(int *iterator, struct sip_request *req) { - *iterator = 0; + *iterator = req->sdp_start; } -static char* get_sdp_iterate(int* iterator, +static char *get_sdp_iterate(int *iterator, struct sip_request *req, char *name) { int len = strlen(name); char *r; - while (*iterator < req->lines) { - r = get_sdp_by_line(req->line[(*iterator)++], name, len); + while (*iterator < req->sdp_end) { + r = get_body_by_line(req->line[(*iterator)++], name, len); + if (r[0] != '\0') + return r; + } + return ""; +} + +/*! \brief get_body: get a specific line from the message body */ +static char *get_body(struct sip_request *req, char *name) +{ + int x; + int len = strlen(name); + char *r; + + for (x = 0; x < req->lines; x++) { + r = get_body_by_line(req->line[x], name, len); if (r[0] != '\0') return r; } @@ -3390,6 +3405,68 @@ static void parse_request(struct sip_request *req) determine_firstline_parts(req); } +/*! + \brief Determine whether a SIP message contains an SDP in its body + \param req the SIP request to process + \return 1 if SDP found, 0 if not found + + Also updates req->sdp_start and req->sdp_end to indicate where the SDP + lives in the message body. +*/ +static int find_sdp(struct sip_request *req) +{ + char *content_type; + char *search; + char *boundary; + unsigned int x; + + content_type = get_header(req, "Content-Type"); + + /* if the body contains only SDP, this is easy */ + if (!strcasecmp(content_type, "application/sdp")) { + req->sdp_start = 0; + req->sdp_end = req->lines; + return 1; + } + + /* if it's not multipart/mixed, there cannot be an SDP */ + if (strncasecmp(content_type, "multipart/mixed", 15)) + return 0; + + /* if there is no boundary marker, it's invalid */ + if (!(search = strcasestr(content_type, ";boundary="))) + return 0; + + search += 10; + + if (ast_strlen_zero(search)) + return 0; + + /* make a duplicate of the string, with two extra characters + at the beginning */ + boundary = ast_strdupa(search - 2); + boundary[0] = boundary[1] = '-'; + + /* search for the boundary marker, but stop when there are not enough + lines left for it, the Content-Type header and at least one line of + body */ + for (x = 0; x < (req->lines - 2); x++) { + if (!strncasecmp(req->line[x], boundary, strlen(boundary)) && + !strcasecmp(req->line[x + 1], "Content-Type: application/sdp")) { + req->sdp_start = x + 2; + /* search for the end of the body part */ + for ( ; x < req->lines; x++) { + if (!strncasecmp(req->line[x], boundary, strlen(boundary))) + break; + } + req->sdp_end = x; + return 1; + } + } + + return 0; +} + /*! \brief process_sdp: Process SIP SDP and activate RTP channels---*/ static int process_sdp(struct sip_pvt *p, struct sip_request *req) { @@ -3424,13 +3501,8 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req) time(&p->lastrtprx); time(&p->lastrtptx); - /* Get codec and RTP info from SDP */ - if (strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { - ast_log(LOG_NOTICE, "Content is '%s', not 'application/sdp'\n", get_header(req, "Content-Type")); - return -1; - } m = get_sdp(req, "m"); - sdpLineNum_iterator_init(&destiterator); + sdpLineNum_iterator_init(&destiterator, req); c = get_sdp_iterate(&destiterator, req, "c"); if (ast_strlen_zero(m) || ast_strlen_zero(c)) { ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); @@ -3446,7 +3518,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req) ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); return -1; } - sdpLineNum_iterator_init(&iterator); + sdpLineNum_iterator_init(&iterator, req); ast_set_flag(p, SIP_NOVIDEO); while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { int found = 0; @@ -3551,7 +3623,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req) /* Next, scan through each "a=rtpmap:" line, noting each * specified RTP payload type (with corresponding MIME subtype): */ - sdpLineNum_iterator_init(&iterator); + sdpLineNum_iterator_init(&iterator, req); while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ if (!strcasecmp(a, "sendonly") || !strcasecmp(a, "inactive")) { @@ -8632,7 +8704,7 @@ static void handle_request_info(struct sip_pvt *p, struct sip_request *req) !strcasecmp(get_header(req, "Content-Type"), "application/vnd.nortelnetworks.digits")) { /* Try getting the "signal=" part */ - if (ast_strlen_zero(c = get_sdp(req, "Signal")) && ast_strlen_zero(c = get_sdp(req, "d"))) { + if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); transmit_response(p, "200 OK", req); /* Should return error */ return; @@ -9494,7 +9566,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru if (p->owner->_state != AST_STATE_UP) ast_setstate(p->owner, AST_STATE_RINGING); } - if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { + if (find_sdp(req)) { process_sdp(p, req); if (!ignore && p->owner) { /* Queue a progress frame only if we have SDP in 180 */ @@ -9505,7 +9577,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru case 183: /* Session progress */ sip_cancel_destroy(p); /* Ignore 183 Session progress without SDP */ - if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { + if (find_sdp(req)) { process_sdp(p, req); if (!ignore && p->owner) { /* Queue a progress frame */ @@ -9516,7 +9588,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru case 200: /* 200 OK on invite - someone's answering our call */ sip_cancel_destroy(p); p->authtries = 0; - if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { + if (find_sdp(req)) { process_sdp(p, req); } @@ -10323,7 +10395,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int check_via(p, req); if (p->owner) { /* Handle SDP here if we already have an owner */ - if (!strcasecmp(get_header(req, "Content-Type"), "application/sdp")) { + if (find_sdp(req)) { if (process_sdp(p, req)) { transmit_response(p, "488 Not acceptable here", req); if (!p->lastinvite) -- cgit v1.2.3 From 6e053a7aa604c833128d72efbcbf9901592ffeb0 Mon Sep 17 00:00:00 2001 From: kpfleming Date: Thu, 18 May 2006 20:43:42 +0000 Subject: fix up a few more places to find the SDP properly (fallout from fix for #7124) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@28384 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_sip.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index da18e06f9..6c4091c16 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -10045,7 +10045,7 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_ } else if ((resp >= 100) && (resp < 200)) { if (sipmethod == SIP_INVITE) { sip_cancel_destroy(p); - if (!ast_strlen_zero(get_header(req, "Content-Type"))) + if (find_sdp(req)) process_sdp(p, req); if (p->owner) { /* Queue a progress frame */ @@ -10425,7 +10425,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int return 0; } /* Process the SDP portion */ - if (!ast_strlen_zero(get_header(req, "Content-Type"))) { + if (find_sdp(req)) { if (process_sdp(p, req)) { transmit_response(p, "488 Not acceptable here", req); ast_set_flag(p, SIP_NEEDDESTROY); @@ -11162,7 +11162,7 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc if (seqno == p->pendinginvite) { p->pendinginvite = 0; __sip_ack(p, seqno, FLAG_RESPONSE, 0); - if (!ast_strlen_zero(get_header(req, "Content-Type"))) { + if (find_sdp(req)) { if (process_sdp(p, req)) return -1; } -- cgit v1.2.3 From a182b3d0a1b46debb36b630d90f150ee663388b1 Mon Sep 17 00:00:00 2001 From: file Date: Fri, 19 May 2006 15:38:59 +0000 Subject: Treat paused queue members as unreachable (issue #7127 reported by peterh) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@28627 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_queue.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/app_queue.c b/apps/app_queue.c index a35a3ee19..61cf45617 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -431,6 +431,8 @@ static enum queue_member_status get_member_status(const struct ast_call_queue *q enum queue_member_status result = QUEUE_NO_MEMBERS; for (member = q->members; member; member = member->next) { + if (member->paused) continue; + switch (member->status) { case AST_DEVICE_INVALID: /* nothing to do */ -- cgit v1.2.3 From 84406ee9d6610d44efc7a12d6043a114c346a57d Mon Sep 17 00:00:00 2001 From: file Date: Fri, 19 May 2006 15:52:09 +0000 Subject: Backport of fix for issue #6654 that was fixed in trunk but not here git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@28630 f38db490-d61c-443f-a65b-d21fe96a405b --- enum.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/enum.c b/enum.c index 0c3e92513..9daef1ef7 100644 --- a/enum.c +++ b/enum.c @@ -80,7 +80,7 @@ struct naptr { } __attribute__ ((__packed__)); /*--- parse_ie: Parse NAPTR record information elements */ -static unsigned int parse_ie(char *data, unsigned int maxdatalen, char *src, unsigned int srclen) +static unsigned int parse_ie(unsigned char *data, unsigned int maxdatalen, unsigned char *src, unsigned int srclen) { unsigned int len, olen; @@ -101,7 +101,7 @@ static unsigned int parse_ie(char *data, unsigned int maxdatalen, char *src, uns } /*--- parse_naptr: Parse DNS NAPTR record used in ENUM ---*/ -static int parse_naptr(char *dst, int dstsize, char *tech, int techsize, char *answer, int len, char *naptrinput) +static int parse_naptr(unsigned char *dst, int dstsize, char *tech, int techsize, unsigned char *answer, int len, unsigned char *naptrinput) { char tech_return[80]; char *oanswer = answer; -- cgit v1.2.3 From b79c30c466a5b42618ff8c3487e02b8ac232c3e3 Mon Sep 17 00:00:00 2001 From: file Date: Fri, 19 May 2006 16:03:33 +0000 Subject: When forwarding messages use the context that the active voicemail user was found in. (issue #7010) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@28651 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_voicemail.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index 214c7aff3..b595944f2 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -5310,7 +5310,7 @@ static int vm_execmain(struct ast_channel *chan, void *data) case '5': /* Leave VoiceMail */ if (ast_test_flag(vmu, VM_SVMAIL)) { - cmd = forward_message(chan, context, vms.curdir, vms.curmsg, vmu, vmfmts, 1, record_gain); + cmd = forward_message(chan, vmu->context, vms.curdir, vms.curmsg, vmu, vmfmts, 1, record_gain); if (cmd == ERROR_LOCK_PATH) { res = cmd; goto out; @@ -5391,7 +5391,7 @@ static int vm_execmain(struct ast_channel *chan, void *data) case '8': if (vms.lastmsg > -1) { - cmd = forward_message(chan, context, vms.curdir, vms.curmsg, vmu, vmfmts, 0, record_gain); + cmd = forward_message(chan, vmu->context, vms.curdir, vms.curmsg, vmu, vmfmts, 0, record_gain); if (cmd == ERROR_LOCK_PATH) { res = cmd; goto out; -- cgit v1.2.3 From 1e7f09ff59a5e6a34b3cfde4af49856847775115 Mon Sep 17 00:00:00 2001 From: file Date: Fri, 19 May 2006 17:04:02 +0000 Subject: Make the minidle option actually exist as documented (issue #7159 reported by imran) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@28698 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_zap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/channels/chan_zap.c b/channels/chan_zap.c index 6dae296bc..847063a5b 100644 --- a/channels/chan_zap.c +++ b/channels/chan_zap.c @@ -10718,6 +10718,8 @@ static int setup_zap(int reload) v->value, v->lineno); } else if (!strcasecmp(v->name, "minunused")) { minunused = atoi(v->value); + } else if (!strcasecmp(v->name, "minidle")) { + minidle = atoi(v->value); } else if (!strcasecmp(v->name, "idleext")) { ast_copy_string(idleext, v->value, sizeof(idleext)); } else if (!strcasecmp(v->name, "idledial")) { -- cgit v1.2.3 From 257ff7d1da5c474fe4c8f541f8f4130c201dffaf Mon Sep 17 00:00:00 2001 From: russell Date: Fri, 19 May 2006 19:01:17 +0000 Subject: This explicit poll is only needed on mac. In fact, it breaks some systems such as some versions of Fedora, causing 'asterisk -rx' to never exit. This has been tested on systems showing the asterisk -rx problem, as well as other unaffected versions of linux, mac osx 10.4, and FreeBSD 6. (issue #7071) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@28754 f38db490-d61c-443f-a65b-d21fe96a405b --- asterisk.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/asterisk.c b/asterisk.c index 334d322df..c0605f036 100644 --- a/asterisk.c +++ b/asterisk.c @@ -1803,13 +1803,17 @@ static void ast_remotecontrol(char * data) if (option_exec && data) { /* hack to print output then exit if asterisk -rx is used */ char tempchar; +#ifdef __Darwin__ struct pollfd fds[0]; fds[0].fd = ast_consock; fds[0].events = POLLIN; fds[0].revents = 0; - while(poll(fds, 1, 100) > 0) { + while (poll(fds, 1, 100) > 0) { ast_el_read_char(el, &tempchar); } +#else + while (!ast_el_read_char(el, &tempchar)); +#endif return; } for(;;) { -- cgit v1.2.3 From f9b9945c97801e3a17bad721a62cf1768a83b541 Mon Sep 17 00:00:00 2001 From: russell Date: Fri, 19 May 2006 19:18:41 +0000 Subject: fix the build of smsq with -Werror. I learned something new about format strings from this patch! (issue #7141, Mithraen) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@28790 f38db490-d61c-443f-a65b-d21fe96a405b --- utils/smsq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/smsq.c b/utils/smsq.c index 361fc2679..429ca0004 100644 --- a/utils/smsq.c +++ b/utils/smsq.c @@ -142,7 +142,7 @@ static char txqcheck (char *dir, char *queue, char subaddress, char *channel, ch p = channel; p = strchr (p, 'X'); if (p) - fprintf (f, "%.*s%c%s\n", p - channel, channel, subaddress, p + 1); + fprintf (f, "%.*s%c%s\n", (int)(p - channel), channel, subaddress, p + 1); else fprintf (f, "%s\n", channel); } @@ -153,7 +153,7 @@ static char txqcheck (char *dir, char *queue, char subaddress, char *channel, ch { p = strchr (callerid, 'X'); if (p) - fprintf (f, "%.*s%c%s", p - callerid, callerid, subaddress, p + 1); + fprintf (f, "%.*s%c%s", (int)(p - callerid), callerid, subaddress, p + 1); else fprintf (f, "%s", callerid); } -- cgit v1.2.3 From 71d9fcf1247cfdcdc87de15212ef3d39750fae75 Mon Sep 17 00:00:00 2001 From: kpfleming Date: Fri, 19 May 2006 19:39:55 +0000 Subject: use the specified 'subscribecontext' for a peer rather than the context found via the target domain (domain contexts are for calls, not for subscriptions) (issue #7122, reported by raarts) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@28794 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_sip.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 6c4091c16..f3d93f52a 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -10823,13 +10823,17 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, } return 0; } - /* Initialize the context if it hasn't been already */ + gotdest = get_destination(p, NULL); + /* Initialize the context if it hasn't been already; + note this is done _after_ handling any domain lookups, + because the context specified there is for calls, not + subscriptions + */ if (!ast_strlen_zero(p->subscribecontext)) ast_copy_string(p->context, p->subscribecontext, sizeof(p->context)); else if (ast_strlen_zero(p->context)) strcpy(p->context, default_context); /* Get destination right away */ - gotdest = get_destination(p, NULL); build_contact(p); if (gotdest) { if (gotdest < 0) -- cgit v1.2.3 From 782c18e18ad29d7f6bb6db53b622f79397e9cccd Mon Sep 17 00:00:00 2001 From: kpfleming Date: Sat, 20 May 2006 00:55:31 +0000 Subject: don't try to predict where the compiler will place things on the stack... put them in the right place explicitly (issues #7029 and #7100, maybe others) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@28896 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_iax2.c | 856 +++++++++++++++++++++++++-------------------------- 1 file changed, 428 insertions(+), 428 deletions(-) diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index a124fb00b..d186da94a 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -6285,8 +6285,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata) struct ast_iax2_meta_trunk_hdr *mth; struct ast_iax2_meta_trunk_entry *mte; struct ast_iax2_meta_trunk_mini *mtm; - char dblbuf[4096]; /* Declaration of dblbuf must immediately *preceed* fr on the stack */ - struct iax_frame fr; + struct iax_frame *fr; struct iax_frame *cur; char iabuf[INET_ADDRSTRLEN]; struct ast_frame f; @@ -6308,8 +6307,9 @@ static int socket_read(int *id, int fd, short events, void *cbdata) struct ast_codec_pref pref; char *using_prefs = "mine"; - dblbuf[0] = 0; /* Keep GCC from whining */ - fr.callno = 0; + /* allocate an iax_frame with 4096 bytes of data buffer */ + fr = alloca(sizeof(*fr) + 4096); + fr->callno = 0; res = recvfrom(fd, buf, sizeof(buf), 0,(struct sockaddr *) &sin, &len); if (res < 0) { @@ -6329,7 +6329,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata) } if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { /* This is a video frame, get call number */ - fr.callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1, fd); + fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1, fd); minivid = 1; } else if (meta->zeros == 0) { unsigned char metatype; @@ -6380,16 +6380,16 @@ static int socket_read(int *id, int fd, short events, void *cbdata) /* Stop if we don't have enough data */ if (len > res) break; - fr.callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd); - if (fr.callno) { - ast_mutex_lock(&iaxsl[fr.callno]); + fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd); + if (fr->callno) { + ast_mutex_lock(&iaxsl[fr->callno]); /* If it's a valid call, deliver the contents. If not, we drop it, since we don't have a scallno to use for an INVAL */ /* Process as a mini frame */ f.frametype = AST_FRAME_VOICE; - if (iaxs[fr.callno]) { - if (iaxs[fr.callno]->voiceformat > 0) { - f.subclass = iaxs[fr.callno]->voiceformat; + if (iaxs[fr->callno]) { + if (iaxs[fr->callno]->voiceformat > 0) { + f.subclass = iaxs[fr->callno]->voiceformat; f.datalen = len; if (f.datalen >= 0) { if (f.datalen) @@ -6397,11 +6397,11 @@ static int socket_read(int *id, int fd, short events, void *cbdata) else f.data = NULL; if(trunked_ts) { - fr.ts = (iaxs[fr.callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); + fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); } else - fr.ts = fix_peerts(&rxtrunktime, fr.callno, ts); + fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); /* Don't pass any packets until we're started */ - if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED)) { + if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { /* Common things */ f.src = "IAX2"; f.mallocd = 0; @@ -6410,28 +6410,28 @@ static int socket_read(int *id, int fd, short events, void *cbdata) f.samples = ast_codec_get_samples(&f); else f.samples = 0; - fr.outoforder = 0; - iax_frame_wrap(&fr, &f); + fr->outoforder = 0; + iax_frame_wrap(fr, &f); #ifdef BRIDGE_OPTIMIZATION - if (iaxs[fr.callno]->bridgecallno) { + if (iaxs[fr->callno]->bridgecallno) { forward_delivery(&fr); } else { duped_fr = iaxfrdup2(&fr); if (duped_fr) { - schedule_delivery(duped_fr, updatehistory, 1, &fr.ts); + schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); } } #else - duped_fr = iaxfrdup2(&fr); + duped_fr = iaxfrdup2(fr); if (duped_fr) { - schedule_delivery(duped_fr, updatehistory, 1, &fr.ts); + schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); } #endif - if (iaxs[fr.callno]->last < fr.ts) { - iaxs[fr.callno]->last = fr.ts; + if (iaxs[fr->callno]->last < fr->ts) { + iaxs[fr->callno]->last = fr->ts; #if 1 if (option_debug) - ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr.callno, fr.ts); + ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); #endif } } @@ -6440,10 +6440,10 @@ static int socket_read(int *id, int fd, short events, void *cbdata) } } else { ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n "); - iax2_vnak(fr.callno); + iax2_vnak(fr->callno); } } - ast_mutex_unlock(&iaxsl[fr.callno]); + ast_mutex_unlock(&iaxsl[fr->callno]); } ptr += len; res -= len; @@ -6476,13 +6476,13 @@ static int socket_read(int *id, int fd, short events, void *cbdata) f.subclass = 0; } - if (!fr.callno) - fr.callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, 1, fd); + if (!fr->callno) + fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, 1, fd); - if (fr.callno > 0) - ast_mutex_lock(&iaxsl[fr.callno]); + if (fr->callno > 0) + ast_mutex_lock(&iaxsl[fr->callno]); - if (!fr.callno || !iaxs[fr.callno]) { + if (!fr->callno || !iaxs[fr->callno]) { /* A call arrived for a nonexistent destination. Unless it's an "inval" frame, reply with an inval */ if (ntohs(mh->callno) & IAX_FLAG_FULL) { @@ -6495,14 +6495,14 @@ static int socket_read(int *id, int fd, short events, void *cbdata) raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, fd); } - if (fr.callno > 0) - ast_mutex_unlock(&iaxsl[fr.callno]); + if (fr->callno > 0) + ast_mutex_unlock(&iaxsl[fr->callno]); return 1; } - if (ast_test_flag(iaxs[fr.callno], IAX_ENCRYPTED)) { - if (decrypt_frame(fr.callno, fh, &f, &res)) { + if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { + if (decrypt_frame(fr->callno, fh, &f, &res)) { ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); - ast_mutex_unlock(&iaxsl[fr.callno]); + ast_mutex_unlock(&iaxsl[fr->callno]); return 1; } #ifdef DEBUG_SUPPORT @@ -6512,24 +6512,24 @@ static int socket_read(int *id, int fd, short events, void *cbdata) } /* count this frame */ - iaxs[fr.callno]->frames_received++; + iaxs[fr->callno]->frames_received++; - if (!inaddrcmp(&sin, &iaxs[fr.callno]->addr) && !minivid && + if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ f.subclass != IAX_COMMAND_TXACC) /* for attended transfer */ - iaxs[fr.callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL); + iaxs[fr->callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL); if (ntohs(mh->callno) & IAX_FLAG_FULL) { if (option_debug && iaxdebug) ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); /* Check if it's out of order (and not an ACK or INVAL) */ - fr.oseqno = fh->oseqno; - fr.iseqno = fh->iseqno; - fr.ts = ntohl(fh->ts); + fr->oseqno = fh->oseqno; + fr->iseqno = fh->iseqno; + fr->ts = ntohl(fh->ts); #ifdef IAXTESTS if (test_resync) { if (option_debug) - ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr.ts, fr.ts + test_resync); - fr.ts += test_resync; + ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); + fr->ts += test_resync; } #endif /* IAXTESTS */ #if 0 @@ -6542,8 +6542,8 @@ static int socket_read(int *id, int fd, short events, void *cbdata) #endif if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) updatehistory = 0; - if ((iaxs[fr.callno]->iseqno != fr.oseqno) && - (iaxs[fr.callno]->iseqno || + if ((iaxs[fr->callno]->iseqno != fr->oseqno) && + (iaxs[fr->callno]->iseqno || ((f.subclass != IAX_COMMAND_TXCNT) && (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ @@ -6563,8 +6563,8 @@ static int socket_read(int *id, int fd, short events, void *cbdata) /* If it's not an ACK packet, it's out of order. */ if (option_debug) ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", - iaxs[fr.callno]->iseqno, fr.oseqno, f.frametype, f.subclass); - if (iaxs[fr.callno]->iseqno > fr.oseqno) { + iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); + if (iaxs[fr->callno]->iseqno > fr->oseqno) { /* If we've already seen it, ack it XXX There's a border condition here XXX */ if ((f.frametype != AST_FRAME_IAX) || ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { @@ -6572,13 +6572,13 @@ static int socket_read(int *id, int fd, short events, void *cbdata) ast_log(LOG_DEBUG, "Acking anyway\n"); /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if we have anything to send, we'll retransmit and get an ACK back anyway XXX */ - send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); + send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); } } else { /* Send a VNAK requesting retransmission */ - iax2_vnak(fr.callno); + iax2_vnak(fr->callno); } - ast_mutex_unlock(&iaxsl[fr.callno]); + ast_mutex_unlock(&iaxsl[fr->callno]); return 1; } } else { @@ -6589,67 +6589,67 @@ static int socket_read(int *id, int fd, short events, void *cbdata) (f.subclass != IAX_COMMAND_TXACC) && (f.subclass != IAX_COMMAND_VNAK)) || (f.frametype != AST_FRAME_IAX)) - iaxs[fr.callno]->iseqno++; + iaxs[fr->callno]->iseqno++; } /* A full frame */ if (res < sizeof(struct ast_iax2_full_hdr)) { ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int)sizeof(struct ast_iax2_full_hdr)); - ast_mutex_unlock(&iaxsl[fr.callno]); + ast_mutex_unlock(&iaxsl[fr->callno]); return 1; } f.datalen = res - sizeof(struct ast_iax2_full_hdr); /* Handle implicit ACKing unless this is an INVAL, and only if this is from the real peer, not the transfer peer */ - if (!inaddrcmp(&sin, &iaxs[fr.callno]->addr) && + if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && ((f.subclass != IAX_COMMAND_INVAL) || (f.frametype != AST_FRAME_IAX))) { unsigned char x; /* XXX This code is not very efficient. Surely there is a better way which still properly handles boundary conditions? XXX */ /* First we have to qualify that the ACKed value is within our window */ - for (x=iaxs[fr.callno]->rseqno; x != iaxs[fr.callno]->oseqno; x++) - if (fr.iseqno == x) + for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) + if (fr->iseqno == x) break; - if ((x != iaxs[fr.callno]->oseqno) || (iaxs[fr.callno]->oseqno == fr.iseqno)) { + if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { /* The acknowledgement is within our window. Time to acknowledge everything that it says to */ - for (x=iaxs[fr.callno]->rseqno; x != fr.iseqno; x++) { + for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { /* Ack the packet with the given timestamp */ if (option_debug && iaxdebug) ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); ast_mutex_lock(&iaxq.lock); for (cur = iaxq.head; cur ; cur = cur->next) { /* If it's our call, and our timestamp, mark -1 retries */ - if ((fr.callno == cur->callno) && (x == cur->oseqno)) { + if ((fr->callno == cur->callno) && (x == cur->oseqno)) { cur->retries = -1; /* Destroy call if this is the end */ if (cur->final) { if (iaxdebug && option_debug) - ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", fr.callno); - iax2_destroy_nolock(fr.callno); + ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", fr->callno); + iax2_destroy_nolock(fr->callno); } } } ast_mutex_unlock(&iaxq.lock); } /* Note how much we've received acknowledgement for */ - if (iaxs[fr.callno]) - iaxs[fr.callno]->rseqno = fr.iseqno; + if (iaxs[fr->callno]) + iaxs[fr->callno]->rseqno = fr->iseqno; else { /* Stop processing now */ - ast_mutex_unlock(&iaxsl[fr.callno]); + ast_mutex_unlock(&iaxsl[fr->callno]); return 1; } } else - ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr.iseqno, iaxs[fr.callno]->rseqno, iaxs[fr.callno]->oseqno); + ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); } - if (inaddrcmp(&sin, &iaxs[fr.callno]->addr) && + if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && ((f.frametype != AST_FRAME_IAX) || ((f.subclass != IAX_COMMAND_TXACC) && (f.subclass != IAX_COMMAND_TXCNT)))) { /* Only messages we accept from a transfer host are TXACC and TXCNT */ - ast_mutex_unlock(&iaxsl[fr.callno]); + ast_mutex_unlock(&iaxsl[fr->callno]); return 1; } @@ -6657,7 +6657,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata) if (f.frametype == AST_FRAME_IAX) { if (iax_parse_ies(&ies, buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) { ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); - ast_mutex_unlock(&iaxsl[fr.callno]); + ast_mutex_unlock(&iaxsl[fr->callno]); return 1; } f.data = NULL; @@ -6671,59 +6671,59 @@ static int socket_read(int *id, int fd, short events, void *cbdata) memset(&ies, 0, sizeof(ies)); } if (f.frametype == AST_FRAME_VOICE) { - if (f.subclass != iaxs[fr.callno]->voiceformat) { - iaxs[fr.callno]->voiceformat = f.subclass; + if (f.subclass != iaxs[fr->callno]->voiceformat) { + iaxs[fr->callno]->voiceformat = f.subclass; ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); - if (iaxs[fr.callno]->owner) { + if (iaxs[fr->callno]->owner) { int orignative; retryowner: - if (ast_mutex_trylock(&iaxs[fr.callno]->owner->lock)) { - ast_mutex_unlock(&iaxsl[fr.callno]); + if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { + ast_mutex_unlock(&iaxsl[fr->callno]); usleep(1); - ast_mutex_lock(&iaxsl[fr.callno]); - if (iaxs[fr.callno] && iaxs[fr.callno]->owner) goto retryowner; + ast_mutex_lock(&iaxsl[fr->callno]); + if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; } - if (iaxs[fr.callno]) { - if (iaxs[fr.callno]->owner) { - orignative = iaxs[fr.callno]->owner->nativeformats; - iaxs[fr.callno]->owner->nativeformats = f.subclass; - if (iaxs[fr.callno]->owner->readformat) - ast_set_read_format(iaxs[fr.callno]->owner, iaxs[fr.callno]->owner->readformat); - iaxs[fr.callno]->owner->nativeformats = orignative; - ast_mutex_unlock(&iaxs[fr.callno]->owner->lock); + if (iaxs[fr->callno]) { + if (iaxs[fr->callno]->owner) { + orignative = iaxs[fr->callno]->owner->nativeformats; + iaxs[fr->callno]->owner->nativeformats = f.subclass; + if (iaxs[fr->callno]->owner->readformat) + ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); + iaxs[fr->callno]->owner->nativeformats = orignative; + ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); } } else { ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); - ast_mutex_unlock(&iaxsl[fr.callno]); + ast_mutex_unlock(&iaxsl[fr->callno]); return 1; } } } } if (f.frametype == AST_FRAME_VIDEO) { - if (f.subclass != iaxs[fr.callno]->videoformat) { + if (f.subclass != iaxs[fr->callno]->videoformat) { ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); - iaxs[fr.callno]->videoformat = f.subclass & ~0x1; + iaxs[fr->callno]->videoformat = f.subclass & ~0x1; } } if (f.frametype == AST_FRAME_IAX) { - if (iaxs[fr.callno]->initid > -1) { + if (iaxs[fr->callno]->initid > -1) { /* Don't auto congest anymore since we've gotten something usefulb ack */ - ast_sched_del(sched, iaxs[fr.callno]->initid); - iaxs[fr.callno]->initid = -1; + ast_sched_del(sched, iaxs[fr->callno]->initid); + iaxs[fr->callno]->initid = -1; } /* Handle the IAX pseudo frame itself */ if (option_debug && iaxdebug) ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); /* Update last ts unless the frame's timestamp originated with us. */ - if (iaxs[fr.callno]->last < fr.ts && + if (iaxs[fr->callno]->last < fr->ts && f.subclass != IAX_COMMAND_ACK && f.subclass != IAX_COMMAND_PONG && f.subclass != IAX_COMMAND_LAGRP) { - iaxs[fr.callno]->last = fr.ts; + iaxs[fr->callno]->last = fr->ts; if (option_debug && iaxdebug) - ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr.callno, fr.ts); + ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); } switch(f.subclass) { @@ -6731,102 +6731,102 @@ retryowner: /* Do nothing */ break; case IAX_COMMAND_QUELCH: - if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED)) { + if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { /* Generate Manager Hold event, if necessary*/ - if (iaxs[fr.callno]->owner) { + if (iaxs[fr->callno]->owner) { manager_event(EVENT_FLAG_CALL, "Hold", "Channel: %s\r\n" "Uniqueid: %s\r\n", - iaxs[fr.callno]->owner->name, - iaxs[fr.callno]->owner->uniqueid); + iaxs[fr->callno]->owner->name, + iaxs[fr->callno]->owner->uniqueid); } - ast_set_flag(iaxs[fr.callno], IAX_QUELCH); + ast_set_flag(iaxs[fr->callno], IAX_QUELCH); if (ies.musiconhold) { - if (iaxs[fr.callno]->owner && - ast_bridged_channel(iaxs[fr.callno]->owner)) - ast_moh_start(ast_bridged_channel(iaxs[fr.callno]->owner), NULL); + if (iaxs[fr->callno]->owner && + ast_bridged_channel(iaxs[fr->callno]->owner)) + ast_moh_start(ast_bridged_channel(iaxs[fr->callno]->owner), NULL); } } break; case IAX_COMMAND_UNQUELCH: - if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED)) { + if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { /* Generate Manager Unhold event, if necessary*/ - if (iaxs[fr.callno]->owner && ast_test_flag(iaxs[fr.callno], IAX_QUELCH)) { + if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { manager_event(EVENT_FLAG_CALL, "Unhold", "Channel: %s\r\n" "Uniqueid: %s\r\n", - iaxs[fr.callno]->owner->name, - iaxs[fr.callno]->owner->uniqueid); + iaxs[fr->callno]->owner->name, + iaxs[fr->callno]->owner->uniqueid); } - ast_clear_flag(iaxs[fr.callno], IAX_QUELCH); - if (iaxs[fr.callno]->owner && - ast_bridged_channel(iaxs[fr.callno]->owner)) - ast_moh_stop(ast_bridged_channel(iaxs[fr.callno]->owner)); + ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); + if (iaxs[fr->callno]->owner && + ast_bridged_channel(iaxs[fr->callno]->owner)) + ast_moh_stop(ast_bridged_channel(iaxs[fr->callno]->owner)); } break; case IAX_COMMAND_TXACC: - if (iaxs[fr.callno]->transferring == TRANSFER_BEGIN) { + if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { /* Ack the packet with the given timestamp */ ast_mutex_lock(&iaxq.lock); for (cur = iaxq.head; cur ; cur = cur->next) { /* Cancel any outstanding txcnt's */ - if ((fr.callno == cur->callno) && (cur->transfer)) + if ((fr->callno == cur->callno) && (cur->transfer)) cur->retries = -1; } ast_mutex_unlock(&iaxq.lock); memset(&ied1, 0, sizeof(ied1)); - iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr.callno]->callno); - send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); - iaxs[fr.callno]->transferring = TRANSFER_READY; + iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); + send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); + iaxs[fr->callno]->transferring = TRANSFER_READY; } break; case IAX_COMMAND_NEW: /* Ignore if it's already up */ - if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) + if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) break; if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) check_provisioning(&sin, fd, ies.serviceident, ies.provver); /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ - if (ast_test_flag(iaxs[fr.callno], IAX_TRUNK)) { - fr.callno = make_trunk(fr.callno, 1); + if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { + fr->callno = make_trunk(fr->callno, 1); } /* For security, always ack immediately */ if (delayreject) - send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); - if (check_access(fr.callno, &sin, &ies)) { + send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); + if (check_access(fr->callno, &sin, &ies)) { /* They're not allowed on */ - auth_fail(fr.callno, IAX_COMMAND_REJECT); + auth_fail(fr->callno, IAX_COMMAND_REJECT); if (authdebug) - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context); + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); break; } /* This might re-enter the IAX code and need the lock */ - if (strcasecmp(iaxs[fr.callno]->exten, "TBD")) { - ast_mutex_unlock(&iaxsl[fr.callno]); - exists = ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->cid_num); - ast_mutex_lock(&iaxsl[fr.callno]); + if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { + ast_mutex_unlock(&iaxsl[fr->callno]); + exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); + ast_mutex_lock(&iaxsl[fr->callno]); } else exists = 0; - if (ast_strlen_zero(iaxs[fr.callno]->secret) && ast_strlen_zero(iaxs[fr.callno]->inkeys)) { - if (strcmp(iaxs[fr.callno]->exten, "TBD") && !exists) { + if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { + if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { memset(&ied0, 0, sizeof(ied0)); iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); - send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); + send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); if (authdebug) - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context); + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); } else { /* Select an appropriate format */ - if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOPREFS)) { - if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) { + if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { + if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { using_prefs = "reqonly"; } else { using_prefs = "disabled"; } - format = iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability; + format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; memset(&pref, 0, sizeof(pref)); strcpy(caller_pref_buf, "disabled"); strcpy(host_pref_buf, "disabled"); @@ -6834,62 +6834,62 @@ retryowner: using_prefs = "mine"; /* If the information elements are in here... use them */ if (ies.codec_prefs) - ast_codec_pref_convert(&iaxs[fr.callno]->rprefs, ies.codec_prefs, 32, 0); - if (ast_codec_pref_index(&iaxs[fr.callno]->rprefs, 0)) { + ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); + if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ - if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) { - pref = iaxs[fr.callno]->rprefs; + if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { + pref = iaxs[fr->callno]->rprefs; using_prefs = "caller"; } else { - pref = iaxs[fr.callno]->prefs; + pref = iaxs[fr->callno]->prefs; } } else - pref = iaxs[fr.callno]->prefs; + pref = iaxs[fr->callno]->prefs; - format = ast_codec_choose(&pref, iaxs[fr.callno]->capability & iaxs[fr.callno]->peercapability, 0); - ast_codec_pref_string(&iaxs[fr.callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); - ast_codec_pref_string(&iaxs[fr.callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); + format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); + ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); + ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); } if (!format) { - if(!ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) - format = iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability; + if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) + format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; if (!format) { memset(&ied0, 0, sizeof(ied0)); iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); - send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); + send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); if (authdebug) { - if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->capability); + if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); else - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iaxs[fr.callno]->capability); + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); } } else { /* Pick one... */ - if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) { - if(!(iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability)) + if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { + if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) format = 0; } else { - if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOPREFS)) { - using_prefs = ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; + if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { + using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; memset(&pref, 0, sizeof(pref)); - format = ast_best_codec(iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); + format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); strcpy(caller_pref_buf,"disabled"); strcpy(host_pref_buf,"disabled"); } else { using_prefs = "mine"; - if (ast_codec_pref_index(&iaxs[fr.callno]->rprefs, 0)) { + if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { /* Do the opposite of what we tried above. */ - if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) { - pref = iaxs[fr.callno]->prefs; + if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { + pref = iaxs[fr->callno]->prefs; } else { - pref = iaxs[fr.callno]->rprefs; + pref = iaxs[fr->callno]->rprefs; using_prefs = "caller"; } - format = ast_codec_choose(&pref, iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability, 1); + format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); } else /* if no codec_prefs IE do it the old way */ - format = ast_best_codec(iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); + format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); } } @@ -6897,11 +6897,11 @@ retryowner: memset(&ied0, 0, sizeof(ied0)); iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); - ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); - send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); + ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); + send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); if (authdebug) - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iaxs[fr.callno]->capability); - ast_set_flag(iaxs[fr.callno], IAX_ALREADYGONE); + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); + ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); break; } } @@ -6910,9 +6910,9 @@ retryowner: /* No authentication required, let them in */ memset(&ied1, 0, sizeof(ied1)); iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); - send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); - if (strcmp(iaxs[fr.callno]->exten, "TBD")) { - ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED); + send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); + if (strcmp(iaxs[fr->callno]->exten, "TBD")) { + ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" "%srequested format = %s,\n" @@ -6922,7 +6922,7 @@ retryowner: "%spriority = %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), VERBOSE_PREFIX_4, - ast_getformatname(iaxs[fr.callno]->peerformat), + ast_getformatname(iaxs[fr->callno]->peerformat), VERBOSE_PREFIX_4, caller_pref_buf, VERBOSE_PREFIX_4, @@ -6932,10 +6932,10 @@ retryowner: VERBOSE_PREFIX_4, using_prefs); - if(!(c = ast_iax2_new(fr.callno, AST_STATE_RING, format))) - iax2_destroy_nolock(fr.callno); + if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) + iax2_destroy_nolock(fr->callno); } else { - ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD); + ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); /* If this is a TBD call, we're ready but now what... */ if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); @@ -6944,35 +6944,35 @@ retryowner: } break; } - if (iaxs[fr.callno]->authmethods & IAX_AUTH_MD5) - merge_encryption(iaxs[fr.callno],ies.encmethods); + if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) + merge_encryption(iaxs[fr->callno],ies.encmethods); else - iaxs[fr.callno]->encmethods = 0; - authenticate_request(iaxs[fr.callno]); - ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_AUTHENTICATED); + iaxs[fr->callno]->encmethods = 0; + authenticate_request(iaxs[fr->callno]); + ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); break; case IAX_COMMAND_DPREQ: /* Request status in the dialplan */ - if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD) && - !ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED) && ies.called_number) { + if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && + !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { if (iaxcompat) { /* Spawn a thread for the lookup */ - spawn_dp_lookup(fr.callno, iaxs[fr.callno]->context, ies.called_number, iaxs[fr.callno]->cid_num); + spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); } else { /* Just look it up */ - dp_lookup(fr.callno, iaxs[fr.callno]->context, ies.called_number, iaxs[fr.callno]->cid_num, 1); + dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); } } break; case IAX_COMMAND_HANGUP: - ast_set_flag(iaxs[fr.callno], IAX_ALREADYGONE); - ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr.callno); + ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); + ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); /* Set hangup cause according to remote */ - if (ies.causecode && iaxs[fr.callno]->owner) - iaxs[fr.callno]->owner->hangupcause = ies.causecode; + if (ies.causecode && iaxs[fr->callno]->owner) + iaxs[fr->callno]->owner->hangupcause = ies.causecode; /* Send ack immediately, before we destroy */ - send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); - iax2_destroy_nolock(fr.callno); + send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); + iax2_destroy_nolock(fr->callno); break; case IAX_COMMAND_REJECT: memset(&f, 0, sizeof(f)); @@ -6980,101 +6980,101 @@ retryowner: f.subclass = AST_CONTROL_CONGESTION; /* Set hangup cause according to remote */ - if (ies.causecode && iaxs[fr.callno]->owner) - iaxs[fr.callno]->owner->hangupcause = ies.causecode; + if (ies.causecode && iaxs[fr->callno]->owner) + iaxs[fr->callno]->owner->hangupcause = ies.causecode; - iax2_queue_frame(fr.callno, &f); - if (ast_test_flag(iaxs[fr.callno], IAX_PROVISION)) { + iax2_queue_frame(fr->callno, &f); + if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { /* Send ack immediately, before we destroy */ - send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); - iax2_destroy_nolock(fr.callno); + send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); + iax2_destroy_nolock(fr->callno); break; } - if (iaxs[fr.callno]->owner) { + if (iaxs[fr->callno]->owner) { if (authdebug) - ast_log(LOG_WARNING, "Call rejected by %s: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr), ies.cause ? ies.cause : ""); + ast_log(LOG_WARNING, "Call rejected by %s: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr), ies.cause ? ies.cause : ""); } - ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", fr.callno); + ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", fr->callno); /* Send ack immediately, before we destroy */ - send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); - iaxs[fr.callno]->error = EPERM; - iax2_destroy_nolock(fr.callno); + send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); + iaxs[fr->callno]->error = EPERM; + iax2_destroy_nolock(fr->callno); break; case IAX_COMMAND_TRANSFER: - if (iaxs[fr.callno]->owner && ast_bridged_channel(iaxs[fr.callno]->owner) && ies.called_number) { + if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && ies.called_number) { if (!strcmp(ies.called_number, ast_parking_ext())) { - if (iax_park(ast_bridged_channel(iaxs[fr.callno]->owner), iaxs[fr.callno]->owner)) { - ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr.callno]->owner)->name); + if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) { + ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); } else - ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr.callno]->owner)->name); + ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); } else { - if (ast_async_goto(ast_bridged_channel(iaxs[fr.callno]->owner), iaxs[fr.callno]->context, ies.called_number, 1)) - ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr.callno]->owner)->name, - ies.called_number, iaxs[fr.callno]->context); + if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1)) + ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, + ies.called_number, iaxs[fr->callno]->context); else - ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr.callno]->owner)->name, - ies.called_number, iaxs[fr.callno]->context); + ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, + ies.called_number, iaxs[fr->callno]->context); } } else - ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr.callno); + ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); break; case IAX_COMMAND_ACCEPT: /* Ignore if call is already up or needs authentication or is a TBD */ - if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) + if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) break; - if (ast_test_flag(iaxs[fr.callno], IAX_PROVISION)) { + if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { /* Send ack immediately, before we destroy */ - send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); - iax2_destroy_nolock(fr.callno); + send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); + iax2_destroy_nolock(fr->callno); break; } if (ies.format) { - iaxs[fr.callno]->peerformat = ies.format; + iaxs[fr->callno]->peerformat = ies.format; } else { - if (iaxs[fr.callno]->owner) - iaxs[fr.callno]->peerformat = iaxs[fr.callno]->owner->nativeformats; + if (iaxs[fr->callno]->owner) + iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; else - iaxs[fr.callno]->peerformat = iaxs[fr.callno]->capability; + iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; } if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s (format %s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr), ast_getformatname(iaxs[fr.callno]->peerformat)); - if (!(iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability)) { + ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s (format %s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat)); + if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { memset(&ied0, 0, sizeof(ied0)); iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); - send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); + send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); if (authdebug) - ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->capability); + ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); } else { - ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED); - if (iaxs[fr.callno]->owner) { + ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); + if (iaxs[fr->callno]->owner) { /* Switch us to use a compatible format */ - iaxs[fr.callno]->owner->nativeformats = iaxs[fr.callno]->peerformat; + iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr.callno]->owner->nativeformats)); + ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); retryowner2: - if (ast_mutex_trylock(&iaxs[fr.callno]->owner->lock)) { - ast_mutex_unlock(&iaxsl[fr.callno]); + if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { + ast_mutex_unlock(&iaxsl[fr->callno]); usleep(1); - ast_mutex_lock(&iaxsl[fr.callno]); - if (iaxs[fr.callno] && iaxs[fr.callno]->owner) goto retryowner2; + ast_mutex_lock(&iaxsl[fr->callno]); + if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; } - if (iaxs[fr.callno] && iaxs[fr.callno]->owner) { + if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { /* Setup read/write formats properly. */ - if (iaxs[fr.callno]->owner->writeformat) - ast_set_write_format(iaxs[fr.callno]->owner, iaxs[fr.callno]->owner->writeformat); - if (iaxs[fr.callno]->owner->readformat) - ast_set_read_format(iaxs[fr.callno]->owner, iaxs[fr.callno]->owner->readformat); - ast_mutex_unlock(&iaxs[fr.callno]->owner->lock); + if (iaxs[fr->callno]->owner->writeformat) + ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); + if (iaxs[fr->callno]->owner->readformat) + ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); + ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); } } } ast_mutex_lock(&dpcache_lock); - dp = iaxs[fr.callno]->dpentries; + dp = iaxs[fr->callno]->dpentries; while(dp) { if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { - iax2_dprequest(dp, fr.callno); + iax2_dprequest(dp, fr->callno); } dp = dp->peer; } @@ -7082,71 +7082,71 @@ retryowner2: break; case IAX_COMMAND_POKE: /* Send back a pong packet with the original timestamp */ - send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr.ts, NULL, 0, -1); + send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); break; case IAX_COMMAND_PING: #ifdef BRIDGE_OPTIMIZATION - if (iaxs[fr.callno]->bridgecallno) { + if (iaxs[fr->callno]->bridgecallno) { /* If we're in a bridged call, just forward this */ - forward_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PING, fr.ts, NULL, 0, -1); + forward_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PING, fr->ts, NULL, 0, -1); } else { struct iax_ie_data pingied; - construct_rr(iaxs[fr.callno], &pingied); + construct_rr(iaxs[fr->callno], &pingied); /* Send back a pong packet with the original timestamp */ - send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr.ts, pingied.buf, pingied.pos, -1); + send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); } #else { struct iax_ie_data pingied; - construct_rr(iaxs[fr.callno], &pingied); + construct_rr(iaxs[fr->callno], &pingied); /* Send back a pong packet with the original timestamp */ - send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr.ts, pingied.buf, pingied.pos, -1); + send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); } #endif break; case IAX_COMMAND_PONG: #ifdef BRIDGE_OPTIMIZATION - if (iaxs[fr.callno]->bridgecallno) { + if (iaxs[fr->callno]->bridgecallno) { /* Forward to the other side of the bridge */ - forward_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr.ts, NULL, 0, -1); + forward_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); } else { /* Calculate ping time */ - iaxs[fr.callno]->pingtime = calc_timestamp(iaxs[fr.callno], 0, &f) - fr.ts; + iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; } #else /* Calculate ping time */ - iaxs[fr.callno]->pingtime = calc_timestamp(iaxs[fr.callno], 0, &f) - fr.ts; + iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; #endif /* save RR info */ - save_rr(&fr, &ies); + save_rr(fr, &ies); - if (iaxs[fr.callno]->peerpoke) { - peer = iaxs[fr.callno]->peerpoke; + if (iaxs[fr->callno]->peerpoke) { + peer = iaxs[fr->callno]->peerpoke; if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { - if (iaxs[fr.callno]->pingtime <= peer->maxms) { - ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr.callno]->pingtime); - manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr.callno]->pingtime); + if (iaxs[fr->callno]->pingtime <= peer->maxms) { + ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); + manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ } } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { - if (iaxs[fr.callno]->pingtime > peer->maxms) { - ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr.callno]->pingtime); - manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr.callno]->pingtime); + if (iaxs[fr->callno]->pingtime > peer->maxms) { + ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); + manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ } } - peer->lastms = iaxs[fr.callno]->pingtime; + peer->lastms = iaxs[fr->callno]->pingtime; if (peer->smoothing && (peer->lastms > -1)) - peer->historicms = (iaxs[fr.callno]->pingtime + peer->historicms) / 2; + peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; else if (peer->smoothing && peer->lastms < 0) peer->historicms = (0 + peer->historicms) / 2; else - peer->historicms = iaxs[fr.callno]->pingtime; + peer->historicms = iaxs[fr->callno]->pingtime; if (peer->pokeexpire > -1) ast_sched_del(sched, peer->pokeexpire); - send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); - iax2_destroy_nolock(fr.callno); + send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); + iax2_destroy_nolock(fr->callno); peer->callno = 0; /* Try again eventually */ ast_log(LOG_DEBUG, "Peer lastms %d, historicms %d, maxms %d\n", peer->lastms, peer->historicms, peer->maxms); @@ -7159,158 +7159,158 @@ retryowner2: case IAX_COMMAND_LAGRQ: case IAX_COMMAND_LAGRP: #ifdef BRIDGE_OPTIMIZATION - if (iaxs[fr.callno]->bridgecallno) { - forward_command(iaxs[fr.callno], AST_FRAME_IAX, f.subclass, fr.ts, NULL, 0, -1); + if (iaxs[fr->callno]->bridgecallno) { + forward_command(iaxs[fr->callno], AST_FRAME_IAX, f.subclass, fr->ts, NULL, 0, -1); } else { #endif f.src = "LAGRQ"; f.mallocd = 0; f.offset = 0; f.samples = 0; - iax_frame_wrap(&fr, &f); + iax_frame_wrap(fr, &f); if(f.subclass == IAX_COMMAND_LAGRQ) { /* Received a LAGRQ - echo back a LAGRP */ - fr.af.subclass = IAX_COMMAND_LAGRP; - iax2_send(iaxs[fr.callno], &fr.af, fr.ts, -1, 0, 0, 0); + fr->af.subclass = IAX_COMMAND_LAGRP; + iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); } else { /* Received LAGRP in response to our LAGRQ */ unsigned int ts; /* This is a reply we've been given, actually measure the difference */ - ts = calc_timestamp(iaxs[fr.callno], 0, &fr.af); - iaxs[fr.callno]->lag = ts - fr.ts; + ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); + iaxs[fr->callno]->lag = ts - fr->ts; if (option_debug && iaxdebug) ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", - ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr), iaxs[fr.callno]->lag); + ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); } #ifdef BRIDGE_OPTIMIZATION } #endif break; case IAX_COMMAND_AUTHREQ: - if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { - ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr.callno]->owner ? iaxs[fr.callno]->owner->name : ""); + if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { + ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : ""); break; } - if (authenticate_reply(iaxs[fr.callno], &iaxs[fr.callno]->addr, &ies, iaxs[fr.callno]->secret, iaxs[fr.callno]->outkey)) { + if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { ast_log(LOG_WARNING, "I don't know how to authenticate %s to %s\n", - ies.username ? ies.username : "", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr)); + ies.username ? ies.username : "", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr)); } break; case IAX_COMMAND_AUTHREP: /* For security, always ack immediately */ if (delayreject) - send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); + send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); /* Ignore once we've started */ - if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { - ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr.callno]->owner ? iaxs[fr.callno]->owner->name : ""); + if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { + ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : ""); break; } - if (authenticate_verify(iaxs[fr.callno], &ies)) { + if (authenticate_verify(iaxs[fr->callno], &ies)) { if (authdebug) - ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr), iaxs[fr.callno]->username); + ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->username); memset(&ied0, 0, sizeof(ied0)); - auth_fail(fr.callno, IAX_COMMAND_REJECT); + auth_fail(fr->callno, IAX_COMMAND_REJECT); break; } - if (strcasecmp(iaxs[fr.callno]->exten, "TBD")) { + if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { /* This might re-enter the IAX code and need the lock */ - exists = ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->cid_num); + exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); } else exists = 0; - if (strcmp(iaxs[fr.callno]->exten, "TBD") && !exists) { + if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { if (authdebug) - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context); + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); memset(&ied0, 0, sizeof(ied0)); iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); - send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); + send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); } else { /* Select an appropriate format */ - if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOPREFS)) { - if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) { + if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { + if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { using_prefs = "reqonly"; } else { using_prefs = "disabled"; } - format = iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability; + format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; memset(&pref, 0, sizeof(pref)); strcpy(caller_pref_buf, "disabled"); strcpy(host_pref_buf, "disabled"); } else { using_prefs = "mine"; if (ies.codec_prefs) - ast_codec_pref_convert(&iaxs[fr.callno]->rprefs, ies.codec_prefs, 32, 0); - if (ast_codec_pref_index(&iaxs[fr.callno]->rprefs, 0)) { - if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) { - pref = iaxs[fr.callno]->rprefs; + ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); + if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { + if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { + pref = iaxs[fr->callno]->rprefs; using_prefs = "caller"; } else { - pref = iaxs[fr.callno]->prefs; + pref = iaxs[fr->callno]->prefs; } } else /* if no codec_prefs IE do it the old way */ - pref = iaxs[fr.callno]->prefs; + pref = iaxs[fr->callno]->prefs; - format = ast_codec_choose(&pref, iaxs[fr.callno]->capability & iaxs[fr.callno]->peercapability, 0); - ast_codec_pref_string(&iaxs[fr.callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); - ast_codec_pref_string(&iaxs[fr.callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); + format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); + ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); + ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); } if (!format) { - if(!ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) { - ast_log(LOG_DEBUG, "We don't do requested format %s, falling back to peer capability %d\n", ast_getformatname(iaxs[fr.callno]->peerformat), iaxs[fr.callno]->peercapability); - format = iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability; + if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { + ast_log(LOG_DEBUG, "We don't do requested format %s, falling back to peer capability %d\n", ast_getformatname(iaxs[fr->callno]->peerformat), iaxs[fr->callno]->peercapability); + format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; } if (!format) { if (authdebug) { - if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->capability); + if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); else - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iaxs[fr.callno]->capability); + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); } memset(&ied0, 0, sizeof(ied0)); iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); - send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); + send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); } else { /* Pick one... */ - if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) { - if(!(iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability)) + if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { + if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) format = 0; } else { - if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOPREFS)) { - using_prefs = ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; + if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { + using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; memset(&pref, 0, sizeof(pref)); - format = ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP) ? - iaxs[fr.callno]->peerformat : ast_best_codec(iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); + format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? + iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); strcpy(caller_pref_buf,"disabled"); strcpy(host_pref_buf,"disabled"); } else { using_prefs = "mine"; - if (ast_codec_pref_index(&iaxs[fr.callno]->rprefs, 0)) { + if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { /* Do the opposite of what we tried above. */ - if (ast_test_flag(iaxs[fr.callno], IAX_CODEC_USER_FIRST)) { - pref = iaxs[fr.callno]->prefs; + if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { + pref = iaxs[fr->callno]->prefs; } else { - pref = iaxs[fr.callno]->rprefs; + pref = iaxs[fr->callno]->rprefs; using_prefs = "caller"; } - format = ast_codec_choose(&pref, iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability, 1); + format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); } else /* if no codec_prefs IE do it the old way */ - format = ast_best_codec(iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); + format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); } } if (!format) { - ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); + ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); if (authdebug) { - if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->capability); + if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); else - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iaxs[fr.callno]->capability); + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); } memset(&ied0, 0, sizeof(ied0)); iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); - send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); + send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); } } } @@ -7318,9 +7318,9 @@ retryowner2: /* Authentication received */ memset(&ied1, 0, sizeof(ied1)); iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); - send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); - if (strcmp(iaxs[fr.callno]->exten, "TBD")) { - ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED); + send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); + if (strcmp(iaxs[fr->callno]->exten, "TBD")) { + ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" "%srequested format = %s,\n" @@ -7330,7 +7330,7 @@ retryowner2: "%spriority = %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), VERBOSE_PREFIX_4, - ast_getformatname(iaxs[fr.callno]->peerformat), + ast_getformatname(iaxs[fr->callno]->peerformat), VERBOSE_PREFIX_4, caller_pref_buf, VERBOSE_PREFIX_4, @@ -7340,11 +7340,11 @@ retryowner2: VERBOSE_PREFIX_4, using_prefs); - ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED); - if(!(c = ast_iax2_new(fr.callno, AST_STATE_RING, format))) - iax2_destroy_nolock(fr.callno); + ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); + if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) + iax2_destroy_nolock(fr->callno); } else { - ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD); + ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); /* If this is a TBD call, we're ready but now what... */ if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); @@ -7353,147 +7353,147 @@ retryowner2: } break; case IAX_COMMAND_DIAL: - if (ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD)) { - ast_clear_flag(&iaxs[fr.callno]->state, IAX_STATE_TBD); - ast_copy_string(iaxs[fr.callno]->exten, ies.called_number ? ies.called_number : "s", sizeof(iaxs[fr.callno]->exten)); - if (!ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->cid_num)) { + if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { + ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); + ast_copy_string(iaxs[fr->callno]->exten, ies.called_number ? ies.called_number : "s", sizeof(iaxs[fr->callno]->exten)); + if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { if (authdebug) - ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context); + ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); memset(&ied0, 0, sizeof(ied0)); iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); - send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); + send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); } else { - ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED); + ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat); - ast_set_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED); - send_command(iaxs[fr.callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); - if(!(c = ast_iax2_new(fr.callno, AST_STATE_RING, iaxs[fr.callno]->peerformat))) - iax2_destroy_nolock(fr.callno); + ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat); + ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); + send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); + if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) + iax2_destroy_nolock(fr->callno); } } break; case IAX_COMMAND_INVAL: - iaxs[fr.callno]->error = ENOTCONN; - ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr.callno); - iax2_destroy_nolock(fr.callno); + iaxs[fr->callno]->error = ENOTCONN; + ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); + iax2_destroy_nolock(fr->callno); if (option_debug) - ast_log(LOG_DEBUG, "Destroying call %d\n", fr.callno); + ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); break; case IAX_COMMAND_VNAK: ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); /* Force retransmission */ - vnak_retransmit(fr.callno, fr.iseqno); + vnak_retransmit(fr->callno, fr->iseqno); break; case IAX_COMMAND_REGREQ: case IAX_COMMAND_REGREL: /* For security, always ack immediately */ if (delayreject) - send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); - if (register_verify(fr.callno, &sin, &ies)) { + send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); + if (register_verify(fr->callno, &sin, &ies)) { /* Send delayed failure */ - auth_fail(fr.callno, IAX_COMMAND_REGREJ); + auth_fail(fr->callno, IAX_COMMAND_REGREJ); break; } - if ((ast_strlen_zero(iaxs[fr.callno]->secret) && ast_strlen_zero(iaxs[fr.callno]->inkeys)) || ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_AUTHENTICATED)) { + if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { if (f.subclass == IAX_COMMAND_REGREL) memset(&sin, 0, sizeof(sin)); - if (update_registry(iaxs[fr.callno]->peer, &sin, fr.callno, ies.devicetype, fd, ies.refresh)) + if (update_registry(iaxs[fr->callno]->peer, &sin, fr->callno, ies.devicetype, fd, ies.refresh)) ast_log(LOG_WARNING, "Registry error\n"); if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) check_provisioning(&sin, fd, ies.serviceident, ies.provver); break; } - registry_authrequest(iaxs[fr.callno]->peer, fr.callno); + registry_authrequest(iaxs[fr->callno]->peer, fr->callno); break; case IAX_COMMAND_REGACK: - if (iax2_ack_registry(&ies, &sin, fr.callno)) + if (iax2_ack_registry(&ies, &sin, fr->callno)) ast_log(LOG_WARNING, "Registration failure\n"); /* Send ack immediately, before we destroy */ - send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); - iax2_destroy_nolock(fr.callno); + send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); + iax2_destroy_nolock(fr->callno); break; case IAX_COMMAND_REGREJ: - if (iaxs[fr.callno]->reg) { + if (iaxs[fr->callno]->reg) { if (authdebug) { - ast_log(LOG_NOTICE, "Registration of '%s' rejected: '%s' from: '%s'\n", iaxs[fr.callno]->reg->username, ies.cause ? ies.cause : "", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); - manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr.callno]->reg->username, ies.cause ? ies.cause : ""); + ast_log(LOG_NOTICE, "Registration of '%s' rejected: '%s' from: '%s'\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); + manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : ""); } - iaxs[fr.callno]->reg->regstate = REG_STATE_REJECTED; + iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; } /* Send ack immediately, before we destroy */ - send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); - iax2_destroy_nolock(fr.callno); + send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); + iax2_destroy_nolock(fr->callno); break; case IAX_COMMAND_REGAUTH: /* Authentication request */ - if (registry_rerequest(&ies, fr.callno, &sin)) { + if (registry_rerequest(&ies, fr->callno, &sin)) { memset(&ied0, 0, sizeof(ied0)); iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); - send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); + send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); } break; case IAX_COMMAND_TXREJ: - iaxs[fr.callno]->transferring = 0; + iaxs[fr->callno]->transferring = 0; if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr.callno]->owner ? iaxs[fr.callno]->owner->name : ""); - memset(&iaxs[fr.callno]->transfer, 0, sizeof(iaxs[fr.callno]->transfer)); - if (iaxs[fr.callno]->bridgecallno) { - if (iaxs[iaxs[fr.callno]->bridgecallno]->transferring) { - iaxs[iaxs[fr.callno]->bridgecallno]->transferring = 0; - send_command(iaxs[iaxs[fr.callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); + ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : ""); + memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); + if (iaxs[fr->callno]->bridgecallno) { + if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { + iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; + send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); } } break; case IAX_COMMAND_TXREADY: - if (iaxs[fr.callno]->transferring == TRANSFER_BEGIN) { - iaxs[fr.callno]->transferring = TRANSFER_READY; + if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { + iaxs[fr->callno]->transferring = TRANSFER_READY; if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr.callno]->owner ? iaxs[fr.callno]->owner->name : ""); - if (iaxs[fr.callno]->bridgecallno) { - if (iaxs[iaxs[fr.callno]->bridgecallno]->transferring == TRANSFER_READY) { + ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : ""); + if (iaxs[fr->callno]->bridgecallno) { + if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) { if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr.callno]->owner ? iaxs[fr.callno]->owner->name : "", - iaxs[iaxs[fr.callno]->bridgecallno]->owner ? iaxs[iaxs[fr.callno]->bridgecallno]->owner->name : ""); + ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "", + iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : ""); /* They're both ready, now release them. */ - iaxs[iaxs[fr.callno]->bridgecallno]->transferring = TRANSFER_RELEASED; - iaxs[fr.callno]->transferring = TRANSFER_RELEASED; - ast_set_flag(iaxs[iaxs[fr.callno]->bridgecallno], IAX_ALREADYGONE); - ast_set_flag(iaxs[fr.callno], IAX_ALREADYGONE); + iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; + iaxs[fr->callno]->transferring = TRANSFER_RELEASED; + ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); + ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); /* Stop doing lag & ping requests */ - stop_stuff(fr.callno); - stop_stuff(iaxs[fr.callno]->bridgecallno); + stop_stuff(fr->callno); + stop_stuff(iaxs[fr->callno]->bridgecallno); memset(&ied0, 0, sizeof(ied0)); memset(&ied1, 0, sizeof(ied1)); - iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr.callno]->bridgecallno]->peercallno); - iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr.callno]->peercallno); - send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); - send_command(iaxs[iaxs[fr.callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); + iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); + iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); + send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); + send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); } } } break; case IAX_COMMAND_TXREQ: - try_transfer(iaxs[fr.callno], &ies); + try_transfer(iaxs[fr->callno], &ies); break; case IAX_COMMAND_TXCNT: - if (iaxs[fr.callno]->transferring) - send_command_transfer(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); + if (iaxs[fr->callno]->transferring) + send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); break; case IAX_COMMAND_TXREL: /* Send ack immediately, rather than waiting until we've changed addresses */ - send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); - complete_transfer(fr.callno, &ies); - stop_stuff(fr.callno); /* for attended transfer to work with libiax */ + send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); + complete_transfer(fr->callno, &ies); + stop_stuff(fr->callno); /* for attended transfer to work with libiax */ break; case IAX_COMMAND_DPREP: - complete_dpreply(iaxs[fr.callno], &ies); + complete_dpreply(iaxs[fr->callno], &ies); break; case IAX_COMMAND_UNSUPPORT: ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); @@ -7503,17 +7503,17 @@ retryowner2: memset(&ied0, 0, sizeof(ied0)); res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); if (res < 0) - send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); + send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); else if (res > 0) - send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); + send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); else - send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); + send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); break; default: - ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr.callno, iaxs[fr.callno]->peercallno); + ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); memset(&ied0, 0, sizeof(ied0)); iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); - send_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); + send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); } /* Don't actually pass these frames along */ if ((f.subclass != IAX_COMMAND_ACK) && @@ -7521,23 +7521,23 @@ retryowner2: (f.subclass != IAX_COMMAND_TXACC) && (f.subclass != IAX_COMMAND_INVAL) && (f.subclass != IAX_COMMAND_VNAK)) { - if (iaxs[fr.callno] && iaxs[fr.callno]->aseqno != iaxs[fr.callno]->iseqno) - send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); + if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) + send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); } - ast_mutex_unlock(&iaxsl[fr.callno]); + ast_mutex_unlock(&iaxsl[fr->callno]); return 1; } /* Unless this is an ACK or INVAL frame, ack it */ - if (iaxs[fr.callno]->aseqno != iaxs[fr.callno]->iseqno) - send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); + if (iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) + send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); } else if (minivid) { f.frametype = AST_FRAME_VIDEO; - if (iaxs[fr.callno]->videoformat > 0) - f.subclass = iaxs[fr.callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); + if (iaxs[fr->callno]->videoformat > 0) + f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); else { ast_log(LOG_WARNING, "Received mini frame before first full video frame\n "); - iax2_vnak(fr.callno); - ast_mutex_unlock(&iaxsl[fr.callno]); + iax2_vnak(fr->callno); + ast_mutex_unlock(&iaxsl[fr->callno]); return 1; } f.datalen = res - sizeof(struct ast_iax2_video_hdr); @@ -7547,25 +7547,25 @@ retryowner2: f.data = NULL; #ifdef IAXTESTS if (test_resync) { - fr.ts = (iaxs[fr.callno]->last & 0xFFFF8000L) | ((ntohs(mh->ts) + test_resync) & 0x7fff); + fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(mh->ts) + test_resync) & 0x7fff); } else #endif /* IAXTESTS */ - fr.ts = (iaxs[fr.callno]->last & 0xFFFF8000L) | (ntohs(mh->ts) & 0x7fff); + fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(mh->ts) & 0x7fff); } else { /* A mini frame */ f.frametype = AST_FRAME_VOICE; - if (iaxs[fr.callno]->voiceformat > 0) - f.subclass = iaxs[fr.callno]->voiceformat; + if (iaxs[fr->callno]->voiceformat > 0) + f.subclass = iaxs[fr->callno]->voiceformat; else { ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n "); - iax2_vnak(fr.callno); - ast_mutex_unlock(&iaxsl[fr.callno]); + iax2_vnak(fr->callno); + ast_mutex_unlock(&iaxsl[fr->callno]); return 1; } f.datalen = res - sizeof(struct ast_iax2_mini_hdr); if (f.datalen < 0) { ast_log(LOG_WARNING, "Datalen < 0?\n"); - ast_mutex_unlock(&iaxsl[fr.callno]); + ast_mutex_unlock(&iaxsl[fr->callno]); return 1; } if (f.datalen) @@ -7574,15 +7574,15 @@ retryowner2: f.data = NULL; #ifdef IAXTESTS if (test_resync) { - fr.ts = (iaxs[fr.callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); + fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); } else #endif /* IAXTESTS */ - fr.ts = (iaxs[fr.callno]->last & 0xFFFF0000L) | ntohs(mh->ts); + fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ } /* Don't pass any packets until we're started */ - if (!ast_test_flag(&iaxs[fr.callno]->state, IAX_STATE_STARTED)) { - ast_mutex_unlock(&iaxsl[fr.callno]); + if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { + ast_mutex_unlock(&iaxsl[fr->callno]); return 1; } /* Common things */ @@ -7596,43 +7596,43 @@ retryowner2: ast_frame_byteswap_be(&f); } else f.samples = 0; - iax_frame_wrap(&fr, &f); + iax_frame_wrap(fr, &f); /* If this is our most recent packet, use it as our basis for timestamping */ - if (iaxs[fr.callno]->last < fr.ts) { - /*iaxs[fr.callno]->last = fr.ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ - fr.outoforder = 0; + if (iaxs[fr->callno]->last < fr->ts) { + /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ + fr->outoforder = 0; } else { if (option_debug && iaxdebug) - ast_log(LOG_DEBUG, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass, fr.ts, iaxs[fr.callno]->last); - fr.outoforder = -1; + ast_log(LOG_DEBUG, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass, fr->ts, iaxs[fr->callno]->last); + fr->outoforder = -1; } #ifdef BRIDGE_OPTIMIZATION - if (iaxs[fr.callno]->bridgecallno) { + if (iaxs[fr->callno]->bridgecallno) { forward_delivery(&fr); } else { duped_fr = iaxfrdup2(&fr); if (duped_fr) { - schedule_delivery(duped_fr, updatehistory, 0, &fr.ts); + schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); } } #else - duped_fr = iaxfrdup2(&fr); + duped_fr = iaxfrdup2(fr); if (duped_fr) { - schedule_delivery(duped_fr, updatehistory, 0, &fr.ts); + schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); } #endif - if (iaxs[fr.callno]->last < fr.ts) { - iaxs[fr.callno]->last = fr.ts; + if (iaxs[fr->callno]->last < fr->ts) { + iaxs[fr->callno]->last = fr->ts; #if 1 if (option_debug && iaxdebug) - ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr.callno, fr.ts); + ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); #endif } /* Always run again */ - ast_mutex_unlock(&iaxsl[fr.callno]); + ast_mutex_unlock(&iaxsl[fr->callno]); return 1; } -- cgit v1.2.3 From dbe06afe0a5791dafe565da85bb20098ff3a83bf Mon Sep 17 00:00:00 2001 From: russell Date: Sat, 20 May 2006 02:31:30 +0000 Subject: fix a case where code made assumptions about how memory for variables is allocatted on the stack - this patch is slightly different than the one that went in for the trunk git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@28966 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_sms.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/apps/app_sms.c b/apps/app_sms.c index 4c15cc185..beaf4e2a1 100644 --- a/apps/app_sms.c +++ b/apps/app_sms.c @@ -1178,25 +1178,24 @@ static void sms_messagetx(sms_t * h) static int sms_generate (struct ast_channel *chan, void *data, int len, int samples) { struct ast_frame f = { 0 }; - unsigned char waste[AST_FRIENDLY_OFFSET]; +#define MAXSAMPLES 800 #ifdef OUTALAW - unsigned char buf[800]; + unsigned char *buf; #else - signed short buf[800]; + short *buf; #endif +#define SAMPLE2LEN sizeof(*buf) sms_t *h = data; int i; - if (len > sizeof (buf)) { - ast_log (LOG_WARNING, "Only doing %d bytes (%d bytes requested)\n", (int)(sizeof (buf) / sizeof (signed short)), len); - len = sizeof (buf); -#ifdef OUTALAW - samples = len; -#else - samples = len / 2; -#endif + if (samples > MAXSAMPLES) { + ast_log (LOG_WARNING, "Only doing %d samples (%d requested)\n", + MAXSAMPLES, samples); + samples = MAXSAMPLES; } - waste[0] = 0; /* make compiler happy */ + len = samples * SAMPLE2LEN + AST_FRIENDLY_OFFSET; + buf = alloca(len); + f.frametype = AST_FRAME_VOICE; #ifdef OUTALAW f.subclass = AST_FORMAT_ALAW; @@ -1206,8 +1205,7 @@ static int sms_generate (struct ast_channel *chan, void *data, int len, int samp f.datalen = samples * 2; #endif f.offset = AST_FRIENDLY_OFFSET; - f.mallocd = 0; - f.data = buf; + f.data = buf + AST_FRIENDLY_OFFSET; f.samples = samples; f.src = "app_sms"; /* create a buffer containing the digital sms pattern */ -- cgit v1.2.3 From 6f39f98a0e1784c8eb4ad967a3feb9f3cfdd224e Mon Sep 17 00:00:00 2001 From: kpfleming Date: Sat, 20 May 2006 02:35:53 +0000 Subject: don't allow queue member devices to ring longer than the total queue timeout (issue #6423, reported and patched by bcnit) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@28968 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_queue.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/app_queue.c b/apps/app_queue.c index 61cf45617..4fd6b5364 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -2125,10 +2125,10 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce cur = cur->next; } - if (qe->parent->timeout) - to = qe->parent->timeout * 1000; - else - to = -1; + if (qe->expire && (!qe->parent->timeout || (qe->expire - now) <= qe->parent->timeout)) + to = (qe->expire - now) * 1000; + else + to = (qe->parent->timeout) ? qe->parent->timeout * 1000 : -1; ring_one(qe, outgoing, &numbusies); ast_mutex_unlock(&qe->parent->lock); if (use_weight) -- cgit v1.2.3 From 1a43795f60755de8d0c24a1cf9df5ceb83a214a7 Mon Sep 17 00:00:00 2001 From: russell Date: Sat, 20 May 2006 19:50:41 +0000 Subject: fix the possibility of writing one byte past the end of a buffer. (issue #7189, Mithraen) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@29052 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_sip.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index f3d93f52a..8719be134 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -11215,8 +11215,9 @@ static int sipsock_read(int *id, int fd, short events, void *ignore) } if (res == sizeof(req.data)) { ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); - } - req.data[res] = '\0'; + req.data[sizeof(req.data) - 1] = '\0'; + } else + req.data[res] = '\0'; req.len = res; if(sip_debug_test_addr(&sin)) ast_set_flag(&req, SIP_PKT_DEBUG); -- cgit v1.2.3 From b701e656fd2b06a4f54e74f62485b42ba5d6e7de Mon Sep 17 00:00:00 2001 From: bweschke Date: Sun, 21 May 2006 15:16:59 +0000 Subject: When an application that is executed via applicationmap and exits non-zero, make sure that we pass through the correct return value from the application to make sure a segfault doesn't occur by a bridge trying to continue when it should not. Also, when executing applications via applicationmap, make sure that the application is executed against the channel whose DTMF caused it to be fired off in the first place. (part 1/2 of #7090 - this is the only fix that will be applied to both 1.2 and /trunk) acunningham and blitzrage on testing... git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@29196 f38db490-d61c-443f-a65b-d21fe96a405b --- res/res_features.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/res/res_features.c b/res/res_features.c index f83cadecc..eaae5816d 100644 --- a/res/res_features.c +++ b/res/res_features.c @@ -944,8 +944,12 @@ static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer, if (ast_test_flag(feature, AST_FEATURE_FLAG_CALLEE)) work = peer; res = pbx_exec(work, app, feature->app_args, 1); - if (res < 0) - return res; + if (res == AST_PBX_KEEPALIVE) + return FEATURE_RETURN_PBX_KEEPALIVE; + else if (res == AST_PBX_NO_HANGUP_PEER) + return FEATURE_RETURN_NO_HANGUP_PEER; + else if (res) + return FEATURE_RETURN_SUCCESSBREAK; } else { ast_log(LOG_WARNING, "Could not find application (%s)\n", feature->app); return -2; @@ -1021,7 +1025,10 @@ static int ast_feature_interpret(struct ast_channel *chan, struct ast_channel *p if (!strcmp(feature->exten, code)) { if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 " Feature Found: %s exten: %s\n",feature->sname, tok); - res = feature->operation(chan, peer, config, code, sense); + if (sense == FEATURE_SENSE_CHAN) + res = feature->operation(chan, peer, config, code, sense); + else + res = feature->operation(peer, chan, config, code, sense); break; } else if (!strncmp(feature->exten, code, strlen(code))) { res = FEATURE_RETURN_STOREDIGITS; -- cgit v1.2.3 From b92e7eaf9af155026d270bc5fdce7de3a90f36c9 Mon Sep 17 00:00:00 2001 From: tilghman Date: Mon, 22 May 2006 14:34:34 +0000 Subject: Bug 7196 - month range did not work git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@29394 f38db490-d61c-443f-a65b-d21fe96a405b --- pbx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pbx.c b/pbx.c index 7cd94e6d2..3e0c41724 100644 --- a/pbx.c +++ b/pbx.c @@ -4064,7 +4064,7 @@ static unsigned int get_month(char *mon) } if (c) { e = 0; - while((e < 12) && strcasecmp(mon, months[e])) e++; + while((e < 12) && strcasecmp(c, months[e])) e++; if (e >= 12) { ast_log(LOG_WARNING, "Invalid month '%s', assuming none\n", c); return 0; -- cgit v1.2.3 From 81cdcbf774522ea49b3ccd22f43adce746275fb0 Mon Sep 17 00:00:00 2001 From: tilghman Date: Mon, 22 May 2006 14:59:59 +0000 Subject: Bug 7194 - spelling fix git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@29398 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_meetme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/app_meetme.c b/apps/app_meetme.c index a8db48d7f..129a57157 100644 --- a/apps/app_meetme.c +++ b/apps/app_meetme.c @@ -627,7 +627,7 @@ static int conf_cmd(int fd, int argc, char **argv) { user->chan->name, user->userflags & CONFFLAG_ADMIN ? "(Admin)" : "", user->userflags & CONFFLAG_MONITOR ? "(Listen only)" : "", - user->adminflags & ADMINFLAG_MUTED ? "(Admn Muted)" : "", + user->adminflags & ADMINFLAG_MUTED ? "(Admin Muted)" : "", istalking(user->talking)); ast_cli(fd,"%d users in that conference.\n",cnf->users); -- cgit v1.2.3 From b8f170954080e7f60db9c83e139f137ef637062e Mon Sep 17 00:00:00 2001 From: file Date: Mon, 22 May 2006 16:33:03 +0000 Subject: Preserve presentation bit when going through chan_local (issue #7002 reported by acunningham) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@29464 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_local.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/channels/chan_local.c b/channels/chan_local.c index f843fd95d..14ef083f6 100644 --- a/channels/chan_local.c +++ b/channels/chan_local.c @@ -344,6 +344,8 @@ static int local_call(struct ast_channel *ast, char *dest, int timeout) else p->chan->cid.cid_ani = NULL; + p->chan->cid.cid_pres = p->owner->cid.cid_pres; + strncpy(p->chan->language, p->owner->language, sizeof(p->chan->language) - 1); strncpy(p->chan->accountcode, p->owner->accountcode, sizeof(p->chan->accountcode) - 1); p->chan->cdrflags = p->owner->cdrflags; -- cgit v1.2.3 From 17db6392cb9e01670428793600ebf4fab88c433c Mon Sep 17 00:00:00 2001 From: file Date: Mon, 22 May 2006 20:15:04 +0000 Subject: Use the correct language when playing the transfer sound (issue #7109 reported by casper) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@29512 f38db490-d61c-443f-a65b-d21fe96a405b --- res/res_features.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/res_features.c b/res/res_features.c index eaae5816d..30c00db27 100644 --- a/res/res_features.c +++ b/res/res_features.c @@ -641,7 +641,7 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p ast_verbose(VERBOSE_PREFIX_3 "Unable to find extension '%s' in context '%s'\n", newext, transferer_real_context); } if (!ast_strlen_zero(xferfailsound)) - res = ast_streamfile(transferer, xferfailsound, transferee->language); + res = ast_streamfile(transferer, xferfailsound, transferer->language); else res = 0; if (res) { -- cgit v1.2.3 From f9781942fb3fa0b44ff91f3a57e2b7556bf3ed54 Mon Sep 17 00:00:00 2001 From: file Date: Mon, 22 May 2006 21:27:12 +0000 Subject: Increase the silence threshold to 128 to "fix" it, so I'm told. (issue #6595 reported by davetroy fixed by casper) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@29555 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_waitforsilence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/app_waitforsilence.c b/apps/app_waitforsilence.c index 615eddbce..64839f352 100644 --- a/apps/app_waitforsilence.c +++ b/apps/app_waitforsilence.c @@ -69,7 +69,7 @@ static int do_waiting(struct ast_channel *chan, int maxsilence) { int totalsilence = 0; int dspsilence = 0; int gotsilence = 0; - static int silencethreshold = 64; + static int silencethreshold = 128; int rfmt = 0; int res = 0; struct ast_dsp *sildet; /* silence detector dsp */ -- cgit v1.2.3 From 398097da5064c5b7fe408eb4ff4b5896df83d9f4 Mon Sep 17 00:00:00 2001 From: bweschke Date: Tue, 23 May 2006 15:58:24 +0000 Subject: Fix a potential leak and correct (hopefully) a segfault under certain conditions. #6784 (vovan and perry testing) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@29696 f38db490-d61c-443f-a65b-d21fe96a405b --- res/res_features.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/res/res_features.c b/res/res_features.c index 30c00db27..885f4a7d7 100644 --- a/res/res_features.c +++ b/res/res_features.c @@ -1433,6 +1433,9 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast featurecode = peer_featurecode; } featurecode[strlen(featurecode)] = f->subclass; + /* Get rid of the frame before we start doing "stuff" with the channels */ + ast_frfree(f); + f = NULL; config->feature_timer = backup_config.feature_timer; res = ast_feature_interpret(chan, peer, config, featurecode, sense); switch(res) { @@ -1445,10 +1448,8 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast } if (res >= FEATURE_RETURN_PASSDIGITS) { res = 0; - } else { - ast_frfree(f); + } else break; - } hasfeatures = !ast_strlen_zero(chan_featurecode) || !ast_strlen_zero(peer_featurecode); if (hadfeatures && !hasfeatures) { /* Restore backup */ -- cgit v1.2.3 From 62a7522f316acf205715a3585b9e4ce260062823 Mon Sep 17 00:00:00 2001 From: kpfleming Date: Tue, 23 May 2006 17:15:23 +0000 Subject: backport some mutex initialization and linked list handling fixes from trunk git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@29732 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_sql_postgres.c | 7 +----- dnsmgr.c | 3 +-- include/asterisk/linkedlists.h | 50 ++++++++++++++++++++++++++++++++++-------- include/asterisk/lock.h | 21 +++++++++++++----- pbx.c | 1 + res/res_features.c | 3 +-- 6 files changed, 60 insertions(+), 25 deletions(-) diff --git a/apps/app_sql_postgres.c b/apps/app_sql_postgres.c index d9ba1bfb7..6f554a677 100644 --- a/apps/app_sql_postgres.c +++ b/apps/app_sql_postgres.c @@ -132,7 +132,7 @@ struct ast_PGSQL_id { AST_LIST_ENTRY(ast_PGSQL_id) entries; } *ast_PGSQL_id; -AST_LIST_HEAD(PGSQLidshead,ast_PGSQL_id) PGSQLidshead; +static AST_LIST_HEAD_STATIC(PGSQLidshead,ast_PGSQL_id); static void *find_identifier(int identifier,int identifier_type) { struct PGSQLidshead *headp; @@ -551,11 +551,6 @@ int unload_module(void) int load_module(void) { - struct PGSQLidshead *headp; - - headp=&PGSQLidshead; - - AST_LIST_HEAD_INIT(headp); return ast_register_application(app, PGSQL_exec, synopsis, descrip); } diff --git a/dnsmgr.c b/dnsmgr.c index f1a9dbe59..de8324741 100644 --- a/dnsmgr.c +++ b/dnsmgr.c @@ -57,7 +57,7 @@ struct ast_dnsmgr_entry { char name[1]; }; -static AST_LIST_HEAD(entry_list, ast_dnsmgr_entry) entry_list; +static AST_LIST_HEAD_STATIC(entry_list, ast_dnsmgr_entry); AST_MUTEX_DEFINE_STATIC(refresh_lock); @@ -289,7 +289,6 @@ int dnsmgr_init(void) ast_log(LOG_ERROR, "Unable to create schedule context.\n"); return -1; } - AST_LIST_HEAD_INIT(&entry_list); ast_cli_register(&cli_reload); ast_cli_register(&cli_status); return do_reload(1); diff --git a/include/asterisk/linkedlists.h b/include/asterisk/linkedlists.h index 5f8a57b16..fec406f6e 100644 --- a/include/asterisk/linkedlists.h +++ b/include/asterisk/linkedlists.h @@ -100,6 +100,23 @@ struct name { \ struct type *last; \ } +/*! + \brief Defines initial values for a declaration of AST_LIST_HEAD +*/ +#define AST_LIST_HEAD_INIT_VALUE { \ + .first = NULL, \ + .last = NULL, \ + .lock = AST_MUTEX_INIT_VALUE, \ + } + +/*! + \brief Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK +*/ +#define AST_LIST_HEAD_NOLOCK_INIT_VALUE { \ + .first = NULL, \ + .last = NULL, \ + } + /*! \brief Defines a structure to be used to hold a list of specified type, statically initialized. \param name This will be the name of the defined structure. @@ -122,11 +139,18 @@ struct name { \ struct type *first; \ struct type *last; \ ast_mutex_t lock; \ -} name = { \ - .first = NULL, \ - .last = NULL, \ - .lock = AST_MUTEX_INIT_VALUE, \ -}; +} name = AST_LIST_HEAD_INIT_VALUE + +/*! + \brief Defines a structure to be used to hold a list of specified type, statically initialized. + + This is the same as AST_LIST_HEAD_STATIC, except without the lock included. +*/ +#define AST_LIST_HEAD_NOLOCK_STATIC(name, type) \ +struct name { \ + struct type *first; \ + struct type *last; \ +} name = AST_LIST_HEAD_NOLOCK_INIT_VALUE /*! \brief Initializes a list head structure with a specified first entry. @@ -183,6 +207,12 @@ struct { \ */ #define AST_LIST_FIRST(head) ((head)->first) +/*! + \brief Returns the last entry contained in a list. + \param head This is a pointer to the list tail structure + */ +#define AST_LIST_LAST(head) ((head)->last) + /*! \brief Returns the next entry in the list after the given entry. \param elm This is a pointer to the current entry. @@ -433,11 +463,13 @@ struct { \ (head)->last = NULL; \ } else { \ typeof(elm) curelm = (head)->first; \ - while (curelm->field.next != (elm)) \ + while (curelm && (curelm->field.next != (elm))) \ curelm = curelm->field.next; \ - curelm->field.next = (elm)->field.next; \ - if ((head)->last == (elm)) \ - (head)->last = curelm; \ + if (curelm) { \ + curelm->field.next = (elm)->field.next; \ + if ((head)->last == (elm)) \ + (head)->last = curelm; \ + } \ } \ (elm)->field.next = NULL; \ } while (0) diff --git a/include/asterisk/lock.h b/include/asterisk/lock.h index 38c4e64ac..cf9549751 100644 --- a/include/asterisk/lock.h +++ b/include/asterisk/lock.h @@ -97,6 +97,13 @@ typedef struct ast_mutex_info ast_mutex_t; typedef pthread_cond_t ast_cond_t; +static pthread_mutex_t empty_mutex; + +static void __attribute__((constructor)) init_empty_mutex(void) +{ + memset(&empty_mutex, 0, sizeof(empty_mutex)); +} + static inline int __ast_pthread_mutex_init_attr(const char *filename, int lineno, const char *func, const char *mutex_name, ast_mutex_t *t, pthread_mutexattr_t *attr) @@ -105,14 +112,16 @@ static inline int __ast_pthread_mutex_init_attr(const char *filename, int lineno int canlog = strcmp(filename, "logger.c"); if ((t->mutex) != ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) { - __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is already initialized.\n", - filename, lineno, func, mutex_name); - __ast_mutex_logger("%s line %d (%s): Error: previously initialization of mutex '%s'.\n", - t->file, t->lineno, t->func, mutex_name); + if ((t->mutex) != (empty_mutex)) { + __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is already initialized.\n", + filename, lineno, func, mutex_name); + __ast_mutex_logger("%s line %d (%s): Error: previously initialization of mutex '%s'.\n", + t->file, t->lineno, t->func, mutex_name); #ifdef THREAD_CRASH - DO_THREAD_CRASH; + DO_THREAD_CRASH; #endif - return 0; + return 0; + } } #endif diff --git a/pbx.c b/pbx.c index 3e0c41724..ee00f3a47 100644 --- a/pbx.c +++ b/pbx.c @@ -3706,6 +3706,7 @@ void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char int length; struct ast_state_cb *thiscb, *prevcb; + memset(&store, 0, sizeof(store)); AST_LIST_HEAD_INIT(&store); /* it is very important that this function hold the hintlock _and_ the conlock diff --git a/res/res_features.c b/res/res_features.c index 885f4a7d7..a122abf5f 100644 --- a/res/res_features.c +++ b/res/res_features.c @@ -866,7 +866,7 @@ struct ast_call_feature builtin_features[] = }; -static AST_LIST_HEAD(feature_list,ast_call_feature) feature_list; +static AST_LIST_HEAD_STATIC(feature_list,ast_call_feature); /* register new feature into feature_list*/ void ast_register_feature(struct ast_call_feature *feature) @@ -2145,7 +2145,6 @@ int load_module(void) { int res; - AST_LIST_HEAD_INIT(&feature_list); memset(parking_ext, 0, sizeof(parking_ext)); memset(parking_con, 0, sizeof(parking_con)); -- cgit v1.2.3 From 788bbeb7b3bbe1d961e71d1b016215d2b200f28c Mon Sep 17 00:00:00 2001 From: bweschke Date: Tue, 23 May 2006 17:17:02 +0000 Subject: Sanity check code for an extended failure in trying to obtain a channel lock that may have been obtained elsewhere. Prevents the monitor thread of the SIP module from going into an infinite loop, effectively, breaking SIP until you restart Asterisk or the mutex is unlocked, whichever comes first. git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@29733 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_sip.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 8719be134..72d95e2f5 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -11199,6 +11199,7 @@ static int sipsock_read(int *id, int fd, short events, void *ignore) int nounlock; int recount = 0; char iabuf[INET_ADDRSTRLEN]; + int lockretrycount = 0; len = sizeof(sin); memset(&req, 0, sizeof(req)); @@ -11253,7 +11254,15 @@ retrylock: ast_mutex_unlock(&netlock); /* Sleep infintismly short amount of time */ usleep(1); - goto retrylock; + lockretrycount++; + if (lockretrycount < 100) + goto retrylock; + } + if (lockretrycount > 100) { + ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", p->owner->name); + ast_log(LOG_ERROR, "SIP MESSAGE JUST IGNORED: %s \n", req.data); + ast_log(LOG_ERROR, "BAD! BAD! BAD!\n"); + return 1; } memcpy(&p->recv, &sin, sizeof(p->recv)); if (recordhistory) { -- cgit v1.2.3 From 2815b08f6bf3ba391411e5d0c1f97b307c84cd71 Mon Sep 17 00:00:00 2001 From: kpfleming Date: Tue, 23 May 2006 18:16:40 +0000 Subject: simplify/fix lock retry, and fix comment git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@29764 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_sip.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 72d95e2f5..61c55fa76 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -11199,7 +11199,7 @@ static int sipsock_read(int *id, int fd, short events, void *ignore) int nounlock; int recount = 0; char iabuf[INET_ADDRSTRLEN]; - int lockretrycount = 0; + unsigned int lockretry = 100; len = sizeof(sin); memset(&req, 0, sizeof(req)); @@ -11252,13 +11252,12 @@ retrylock: ast_log(LOG_DEBUG, "Failed to grab lock, trying again...\n"); ast_mutex_unlock(&p->lock); ast_mutex_unlock(&netlock); - /* Sleep infintismly short amount of time */ + /* Sleep for a very short amount of time */ usleep(1); - lockretrycount++; - if (lockretrycount < 100) + if (--lockretry) goto retrylock; } - if (lockretrycount > 100) { + if (!lockretry) { ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", p->owner->name); ast_log(LOG_ERROR, "SIP MESSAGE JUST IGNORED: %s \n", req.data); ast_log(LOG_ERROR, "BAD! BAD! BAD!\n"); -- cgit v1.2.3 From 79d3054e6f57cbc08e29cf2c931e20a12ddc8c20 Mon Sep 17 00:00:00 2001 From: russell Date: Tue, 23 May 2006 21:44:52 +0000 Subject: fix the sourceaddress option (issue #7213, alphaque) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@29849 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_iax2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index d186da94a..d113a89ac 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -8089,6 +8089,7 @@ static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr) int res; sin.sin_port = 0; + sin.sin_family = AF_INET; res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); if (res == 0) { /* ip address valid. */ -- cgit v1.2.3 From a63521ee667619be60885a7ae5cd1494229f6a02 Mon Sep 17 00:00:00 2001 From: kpfleming Date: Wed, 24 May 2006 03:32:02 +0000 Subject: add an option to allow the admin to 'hide' SIP user/peer names from systems trying to 'fish' names git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@29904 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_sip.c | 56 ++++++++++++++++++++++++++++++++++++++----------- configs/sip.conf.sample | 4 ++++ 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 61c55fa76..e768e2644 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -349,6 +349,8 @@ static char default_notifymime[AST_MAX_EXTENSION] = DEFAULT_NOTIFYMIME; static int global_notifyringing = 1; /*!< Send notifications on ringing */ +static int global_alwaysauthreject = 0; /*!< Send 401 Unauthorized for all failing requests */ + static int default_qualify = 0; /*!< Default Qualify= setting */ static struct ast_flags global_flags = {0}; /*!< global SIP_ flags */ @@ -6428,6 +6430,15 @@ static int cb_extensionstate(char *context, char* exten, int state, void *data) return 0; } +/*! \brief Send a fake 401 Unauthorized response when the administrator + wants to hide the names of local users/peers from fishers +*/ +static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, char *randdata, int randlen, int reliable) +{ + snprintf(randdata, randlen, "%08x", thread_safe_rand()); + transmit_response_with_auth(p, "401 Unauthorized", req, randdata, reliable, "WWW-Authenticate", 0); +} + /*! \brief register_verify: Verify registration of user */ static int register_verify(struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri, int ignore) { @@ -6559,8 +6570,12 @@ static int register_verify(struct sip_pvt *p, struct sockaddr_in *sin, struct si transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); break; case -3: - /* URI not found */ - transmit_response(p, "404 Not found", &p->initreq); + if (global_alwaysauthreject) { + transmit_fake_auth_response(p, &p->initreq, p->randdata, sizeof(p->randdata), 1); + } else { + /* URI not found */ + transmit_response(p, "404 Not found", &p->initreq); + } /* Set res back to -2 because we don't want to return an invalid domain message. That check already happened up above. */ res = -2; break; @@ -7289,10 +7304,13 @@ static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipme ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port)); /* do we allow guests? */ - if (!global_allowguest) - res = -1; /* we don't want any guests, authentication will fail */ + if (!global_allowguest) { + if (global_alwaysauthreject) + res = -4; /* reject with fake authorization request */ + else + res = -1; /* we don't want any guests, authentication will fail */ #ifdef OSP_SUPPORT - else if (global_allowguest == 2) { + } else if (global_allowguest == 2) { ast_copy_flags(p, &global_flags, SIP_OSPAUTH); res = check_auth(p, req, p->randdata, sizeof(p->randdata), "", "", "", sipmethod, uri, reliable, ignore); } @@ -8265,6 +8283,7 @@ static int sip_show_settings(int fd, int argc, char *argv[]) ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags, SIP_USEREQPHONE) ? "Yes" : "No"); ast_cli(fd, " Our auth realm %s\n", global_realm); ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); + ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); ast_cli(fd, " User Agent: %s\n", default_useragent); ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); ast_cli(fd, " Reg. context: %s\n", ast_strlen_zero(regcontext) ? "(not set)" : regcontext); @@ -10412,16 +10431,19 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int 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); - if (res) { - if (res < 0) { + if (res < 0) { + if (res == -4) { + ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); + transmit_fake_auth_response(p, req, p->randdata, sizeof(p->randdata), 1); + } else { ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); if (ignore) transmit_response(p, "403 Forbidden", req); else transmit_response_reliable(p, "403 Forbidden", req, 1); - ast_set_flag(p, SIP_NEEDDESTROY); - p->theirtag[0] = '\0'; /* Forget their to-tag, we'll get a new one */ } + ast_set_flag(p, SIP_NEEDDESTROY); + p->theirtag[0] = '\0'; /* Forget their to-tag, we'll get a new one */ return 0; } /* Process the SDP portion */ @@ -10816,11 +10838,18 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, } /* Handle authentication if this is our first subscribe */ res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, ignore, mailbox, mailboxsize); - if (res) { - if (res < 0) { + if (res < 0) { + if (res == -4) { + ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); + transmit_fake_auth_response(p, req, p->randdata, sizeof(p->randdata), 1); + } else { ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); - ast_set_flag(p, SIP_NEEDDESTROY); + if (ignore) + transmit_response(p, "403 Forbidden", req); + else + transmit_response_reliable(p, "403 Forbidden", req, 1); } + ast_set_flag(p, SIP_NEEDDESTROY); return 0; } gotdest = get_destination(p, NULL); @@ -12444,6 +12473,7 @@ static int reload_config(void) ast_copy_string(default_useragent, DEFAULT_USERAGENT, sizeof(default_useragent)); ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); global_notifyringing = 1; + global_alwaysauthreject = 0; ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); ast_copy_string(global_musicclass, "default", sizeof(global_musicclass)); ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); @@ -12543,6 +12573,8 @@ static int reload_config(void) ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); } else if (!strcasecmp(v->name, "notifyringing")) { global_notifyringing = ast_true(v->value); + } else if (!strcasecmp(v->name, "alwaysauthreject")) { + global_alwaysauthreject = ast_true(v->value); } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { ast_copy_string(global_musicclass, v->value, sizeof(global_musicclass)); } else if (!strcasecmp(v->name, "language")) { diff --git a/configs/sip.conf.sample b/configs/sip.conf.sample index 400fbcb7e..ecaef3c89 100644 --- a/configs/sip.conf.sample +++ b/configs/sip.conf.sample @@ -107,6 +107,10 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls ; Useful to limit subscriptions to local extensions ; Settable per peer/user also ;notifyringing = yes ; Notify subscriptions on RINGING state +;alwaysauthreject = yes ; When an incoming INVITE or REGISTER is to be rejected, + ; for any reason, always reject with '401 Unauthorized' + ; instead of letting the requester know whether there was + ; a matching user or peer for their request ; ; If regcontext is specified, Asterisk will dynamically create and destroy a -- cgit v1.2.3 From 4ffc2ae9570837cd7df9a42bec29eb9600091cb7 Mon Sep 17 00:00:00 2001 From: kpfleming Date: Wed, 24 May 2006 12:31:45 +0000 Subject: fix for non-OSP builds (issue #7217) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@29959 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_sip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index e768e2644..18929876a 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -7313,8 +7313,8 @@ static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipme } else if (global_allowguest == 2) { ast_copy_flags(p, &global_flags, SIP_OSPAUTH); res = check_auth(p, req, p->randdata, sizeof(p->randdata), "", "", "", sipmethod, uri, reliable, ignore); - } #endif + } } } -- cgit v1.2.3 From e770d2a13344fa0b805616f19ee32c58d65e9d3d Mon Sep 17 00:00:00 2001 From: kpfleming Date: Wed, 24 May 2006 16:17:26 +0000 Subject: respect 'usecallingpres' in zapata.conf even if CLID has not been set for the channel (issue #7123) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@29969 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_zap.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/channels/chan_zap.c b/channels/chan_zap.c index 847063a5b..c167db2ba 100644 --- a/channels/chan_zap.c +++ b/channels/chan_zap.c @@ -2119,9 +2119,8 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout) prilocaldialplan = PRI_LOCAL_ISDN; } } - pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan, - l ? (p->use_callingpres ? ast->cid.cid_pres : PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN) : - PRES_NUMBER_NOT_AVAILABLE); + pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan, + p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE)); pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, PRI_REDIR_UNCONDITIONAL); #ifdef SUPPORT_USERUSER -- cgit v1.2.3 From 20942c8a97de6f595b7f9cdda67924f99a7f5c6a Mon Sep 17 00:00:00 2001 From: kpfleming Date: Wed, 24 May 2006 16:52:08 +0000 Subject: fix various bugs related to exiting from queue via keypress and moh handling (issue #6776, different fix) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@29971 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_queue.c | 50 ++++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/apps/app_queue.c b/apps/app_queue.c index 4fd6b5364..704573de5 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -1181,13 +1181,16 @@ static int say_position(struct queue_ent *qe) ast_verbose(VERBOSE_PREFIX_3 "Told %s in %s their queue position (which was %d)\n", qe->chan->name, qe->parent->name, qe->pos); res = play_file(qe->chan, qe->parent->sound_thanks); + if (res && !valid_exit(qe, res)) + res = 0; playout: /* Set our last_pos indicators */ qe->last_pos = now; qe->last_pos_said = qe->pos; + /* Don't restart music on hold if we're about to exit the caller from the queue */ - if (res) + if (!res) ast_moh_start(qe->chan, qe->moh); return res; @@ -1556,7 +1559,7 @@ static int background_file(struct queue_ent *qe, struct ast_channel *chan, char if (!res) { /* Wait for a keypress */ res = ast_waitstream(chan, AST_DIGIT_ANY); - if (res <= 0 || !valid_exit(qe, res)) + if (res < 0 || !valid_exit(qe, res)) res = 0; /* Stop playback */ @@ -1594,8 +1597,9 @@ static int say_periodic_announcement(struct queue_ent *qe) /* play the announcement */ res = background_file(qe, qe->chan, qe->parent->sound_periodicannounce); - /* Resume Music on Hold */ - ast_moh_start(qe->chan, qe->moh); + /* Resume Music on Hold if the caller is going to stay in the queue */ + if (!res) + ast_moh_start(qe->chan, qe->moh); /* update last_periodic_announce_time */ qe->last_periodic_announce_time = now; @@ -1920,18 +1924,17 @@ static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *r } /* Make a position announcement, if enabled */ - if (qe->parent->announcefrequency && !ringing) - res = say_position(qe); - if (res) + if (qe->parent->announcefrequency && !ringing && + (res = say_position(qe))) break; /* Make a periodic announcement, if enabled */ - if (qe->parent->periodicannouncefrequency && !ringing) - res = say_periodic_announcement(qe); + if (qe->parent->periodicannouncefrequency && !ringing && + (res = say_periodic_announcement(qe))) + break; /* Wait a second before checking again */ - if (!res) res = ast_waitfordigit(qe->chan, RECHECK * 1000); - if (res) + if ((res = ast_waitfordigit(qe->chan, RECHECK * 1000))) break; } return res; @@ -2230,7 +2233,7 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce if (res < 0) { ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "SYSCOMPAT", "%s", ""); ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", qe->chan->name, peer->name); - record_abandoned(qe); + record_abandoned(qe); ast_hangup(peer); return -1; } @@ -2307,13 +2310,10 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce (long)(time(NULL) - callstart)); } - if(bridge != AST_PBX_NO_HANGUP_PEER) + if (bridge != AST_PBX_NO_HANGUP_PEER) ast_hangup(peer); update_queue(qe->parent, member); - if (bridge == 0) - res = 1; /* JDG: bridge successfull, leave app_queue */ - else - res = bridge; /* bridge error, stay in the queue */ + res = bridge ? 0 : -1; } out: hangupcalls(outgoing, NULL); @@ -2991,9 +2991,8 @@ check_turns: if (makeannouncement) { /* Make a position announcement, if enabled */ - if (qe.parent->announcefrequency && !ringing) - res = say_position(&qe); - if (res) { + if (qe.parent->announcefrequency && !ringing && + (res = say_position(&qe))) { ast_queue_log(queuename, chan->uniqueid, "NONE", "EXITWITHKEY", "%s|%d", qe.digits, qe.pos); break; } @@ -3002,10 +3001,8 @@ check_turns: makeannouncement = 1; /* Make a periodic announcement, if enabled */ - if (qe.parent->periodicannouncefrequency && !ringing) - res = say_periodic_announcement(&qe); - - if (res && valid_exit(&qe, res)) { + if (qe.parent->periodicannouncefrequency && !ringing && + (res = say_periodic_announcement(&qe))) { ast_queue_log(queuename, chan->uniqueid, "NONE", "EXITWITHKEY", "%c|%d", res, qe.pos); break; } @@ -3018,8 +3015,9 @@ check_turns: record_abandoned(&qe); ast_queue_log(queuename, chan->uniqueid, "NONE", "ABANDON", "%d|%d|%ld", qe.pos, qe.opos, (long)time(NULL) - qe.start); } - } else if (res > 0) + } else if (valid_exit(&qe, res)) { ast_queue_log(queuename, chan->uniqueid, "NONE", "EXITWITHKEY", "%s|%d", qe.digits, qe.pos); + } break; } @@ -3082,7 +3080,7 @@ check_turns: if (!is_our_turn(&qe)) { if (option_debug) ast_log(LOG_DEBUG, "Darn priorities, going back in queue (%s)!\n", - qe.chan->name); + qe.chan->name); goto check_turns; } } -- cgit v1.2.3 From 709401939a46e3a9e7b5fdabedd3bab169f71947 Mon Sep 17 00:00:00 2001 From: kpfleming Date: Wed, 24 May 2006 16:59:20 +0000 Subject: support video recording via AGI 'RECORD FILE' command (issue #7068) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@29973 f38db490-d61c-443f-a65b-d21fe96a405b --- res/res_agi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/res/res_agi.c b/res/res_agi.c index 8f9654443..14713fcc2 100644 --- a/res/res_agi.c +++ b/res/res_agi.c @@ -941,6 +941,9 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, char return RESULT_FAILURE; } + /* Request a video update */ + ast_indicate(chan, AST_CONTROL_VIDUPDATE); + chan->stream = fs; ast_applystream(chan,fs); /* really should have checks */ @@ -1004,6 +1007,9 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, char } } break; + case AST_FRAME_VIDEO: + ast_writestream(fs, f); + break; } ast_frfree(f); if (gotsilence) -- cgit v1.2.3 From 28f103ab4627c9fab8f834136aa9269f8b4e08f9 Mon Sep 17 00:00:00 2001 From: file Date: Wed, 24 May 2006 19:14:01 +0000 Subject: Fix deadlock caused by a race condition in the logger when reloading (issue #7195 reported and fixed by softins) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@30033 f38db490-d61c-443f-a65b-d21fe96a405b --- logger.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/logger.c b/logger.c index 0a397ff46..0cb0f06d0 100644 --- a/logger.c +++ b/logger.c @@ -384,6 +384,7 @@ int reload_logger(int rotate) FILE *myf; int x, res = 0; + ast_mutex_lock(&msglist_lock); /* to avoid deadlock */ ast_mutex_lock(&loglock); if (eventlog) fclose(eventlog); @@ -490,6 +491,7 @@ int reload_logger(int rotate) } } ast_mutex_unlock(&loglock); + ast_mutex_unlock(&msglist_lock); return res; } -- cgit v1.2.3 From 4a32b8e28ddd975fa839cd9dcae7645997567e81 Mon Sep 17 00:00:00 2001 From: file Date: Wed, 24 May 2006 19:44:26 +0000 Subject: Merge branch for bug 6264 (Privacy option 2 returns dial-status ANSWER / option_priority_jumping not respected) (reported by jkoopmann and branch by murf git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@30035 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_dial.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/app_dial.c b/apps/app_dial.c index 3bfa91165..4481910fb 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -939,20 +939,26 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags } if( privdb_val == AST_PRIVACY_DENY ) { + strcpy(status, "NOANSWER"); ast_verbose( VERBOSE_PREFIX_3 "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n"); res=0; goto out; } else if( privdb_val == AST_PRIVACY_KILL ) { - ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 201); + strcpy(status, "DONTCALL"); + if (option_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) { + ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 201); + } res = 0; goto out; /* Is this right? */ } else if( privdb_val == AST_PRIVACY_TORTURE ) { - ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 301); + strcpy(status, "TORTURE"); + if (option_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) { + ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 301); + } res = 0; goto out; /* is this right??? */ - } else if( privdb_val == AST_PRIVACY_UNKNOWN ) { /* Get the user's intro, store it in priv-callerintros/$CID, @@ -1310,6 +1316,7 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags opt_args[OPT_ARG_PRIVACY], privcid); ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_DENY); } + strcpy(status,"NOANSWER"); if (ast_test_flag(&opts, OPT_MUSICBACK)) { ast_moh_stop(chan); } else if (ast_test_flag(&opts, OPT_RINGBACK)) { -- cgit v1.2.3 From 0306fcce5b10ed9f68cb7d0b1bf3840cd8350b5c Mon Sep 17 00:00:00 2001 From: mogorman Date: Wed, 24 May 2006 19:55:21 +0000 Subject: app_meemte used the ast_max_exten instead of path_max solves bug 6822 git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@30037 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_meetme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/app_meetme.c b/apps/app_meetme.c index 129a57157..a4d82eb38 100644 --- a/apps/app_meetme.c +++ b/apps/app_meetme.c @@ -165,7 +165,7 @@ struct ast_conf_user { int talking; /* Is user talking */ int zapchannel; /* Is a Zaptel channel */ char usrvalue[50]; /* Custom User Value */ - char namerecloc[AST_MAX_EXTENSION]; /* Name Recorded file Location */ + char namerecloc[PATH_MAX]; /* Name Recorded file Location */ time_t jointime; /* Time the user joined the conference */ struct volume talk; struct volume listen; -- cgit v1.2.3 From f7d22e8dcf6a9daf1b0fbd9e35ec94476a7a6f77 Mon Sep 17 00:00:00 2001 From: kpfleming Date: Wed, 24 May 2006 20:09:24 +0000 Subject: don't send CANCEL on a pending INVITE if we haven't received a provisional response yet... mark it pending until the first response is received (issue #7079) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@30069 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_sip.c | 74 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 18929876a..ed1b8f5b9 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -530,7 +530,7 @@ struct sip_auth { #define SIP_USECLIENTCODE (1 << 12) /*!< Trust X-ClientCode info message */ #define SIP_OUTGOING (1 << 13) /*!< Is this an outgoing call? */ #define SIP_SELFDESTRUCT (1 << 14) /*!< This is an autocreated peer */ -#define SIP_DYNAMIC (1 << 15) /*!< Is this a dynamic peer? */ +#define SIP_CAN_BYE (1 << 15) /*!< Can we send BYE for this dialog? */ /* --- Choices for DTMF support in SIP channel */ #define SIP_DTMF (3 << 16) /*!< three settings, uses two bits */ #define SIP_DTMF_RFC2833 (0 << 16) /*!< RTP DTMF */ @@ -580,6 +580,7 @@ struct sip_auth { #define SIP_PAGE2_RTAUTOCLEAR (1 << 2) #define SIP_PAGE2_IGNOREREGEXPIRE (1 << 3) #define SIP_PAGE2_RT_FROMCONTACT (1 << 4) +#define SIP_PAGE2_DYNAMIC (1 << 5) /*!< Is this a dynamic peer? */ /* SIP packet flags */ #define SIP_PKT_DEBUG (1 << 0) /*!< Debug this packet */ @@ -2456,12 +2457,18 @@ static int sip_hangup(struct ast_channel *ast) /* stop retransmitting an INVITE that has not received a response */ __sip_pretend_ack(p); - /* Send a new request: CANCEL */ - transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0); - /* Actually don't destroy us yet, wait for the 487 on our original - INVITE, but do set an autodestruct just in case we never get it. */ - ast_clear_flag(&locflags, SIP_NEEDDESTROY); - sip_scheddestroy(p, 32000); + /* are we allowed to send CANCEL yet? if not, mark + it pending */ + if (!ast_test_flag(p, SIP_CAN_BYE)) { + ast_set_flag(p, SIP_PENDINGBYE); + } else { + /* Send a new request: CANCEL */ + transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0); + /* Actually don't destroy us yet, wait for the 487 on our original + INVITE, but do set an autodestruct just in case we never get it. */ + ast_clear_flag(&locflags, SIP_NEEDDESTROY); + sip_scheddestroy(p, 32000); + } if ( p->initid != -1 ) { /* channel still up - reverse dec of inUse counter only if the channel is not auto-congested */ @@ -6495,7 +6502,7 @@ static int register_verify(struct sip_pvt *p, struct sockaddr_in *sin, struct si ASTOBJ_UNREF(peer,sip_destroy_peer); } if (peer) { - if (!ast_test_flag(peer, SIP_DYNAMIC)) { + if (!ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)) { ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); } else { ast_copy_flags(p, peer, SIP_NAT); @@ -7644,7 +7651,7 @@ static int _sip_show_peers(int fd, int *total, struct mansession *s, struct mess snprintf(srch, sizeof(srch), FORMAT, name, iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", - ast_test_flag(iterator, SIP_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ + ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ iterator->ha ? " A " : " ", /* permit/deny */ ntohs(iterator->addr.sin_port), status); @@ -7652,7 +7659,7 @@ static int _sip_show_peers(int fd, int *total, struct mansession *s, struct mess if (!s) {/* Normal CLI list */ ast_cli(fd, FORMAT, name, iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", - ast_test_flag(iterator, SIP_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ + ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ iterator->ha ? " A " : " ", /* permit/deny */ @@ -7674,7 +7681,7 @@ static int _sip_show_peers(int fd, int *total, struct mansession *s, struct mess iterator->name, iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "-none-", ntohs(iterator->addr.sin_port), - ast_test_flag(iterator, SIP_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ + ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ iterator->ha ? "yes" : "no", /* permit/deny */ status); @@ -8047,7 +8054,7 @@ static int _sip_show_peer(int type, int fd, struct mansession *s, struct message ast_cli(fd, " VM Extension : %s\n", peer->vmexten); ast_cli(fd, " LastMsgsSent : %d\n", peer->lastmsgssent); ast_cli(fd, " Call limit : %d\n", peer->call_limit); - ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(peer, SIP_DYNAMIC)?"Yes":"No")); + ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)?"Yes":"No")); ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); ast_cli(fd, " Expire : %d\n", peer->expire); ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE))); @@ -8119,7 +8126,7 @@ static int _sip_show_peer(int type, int fd, struct mansession *s, struct message ast_cli(fd, "VoiceMailbox: %s\r\n", peer->mailbox); ast_cli(fd, "LastMsgsSent: %d\r\n", peer->lastmsgssent); ast_cli(fd, "Call limit: %d\r\n", peer->call_limit); - ast_cli(fd, "Dynamic: %s\r\n", (ast_test_flag(peer, SIP_DYNAMIC)?"Y":"N")); + ast_cli(fd, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)?"Y":"N")); ast_cli(fd, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); ast_cli(fd, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); ast_cli(fd, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE))); @@ -9383,7 +9390,7 @@ static char *function_sippeer(struct ast_channel *chan, char *cmd, char *data, c } else if (!strcasecmp(colname, "expire")) { snprintf(buf, len, "%d", peer->expire); } else if (!strcasecmp(colname, "dynamic")) { - ast_copy_string(buf, (ast_test_flag(peer, SIP_DYNAMIC) ? "yes" : "no"), len); + ast_copy_string(buf, (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); } else if (!strcasecmp(colname, "callerid_name")) { ast_copy_string(buf, peer->cid_name, len); } else if (!strcasecmp(colname, "callerid_num")) { @@ -9543,11 +9550,18 @@ static void parse_moved_contact(struct sip_pvt *p, struct sip_request *req) /*! \brief check_pendings: Check pending actions on SIP call ---*/ static void check_pendings(struct sip_pvt *p) { - /* Go ahead and send bye at this point */ if (ast_test_flag(p, SIP_PENDINGBYE)) { - transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); - ast_set_flag(p, SIP_NEEDDESTROY); - ast_clear_flag(p, SIP_NEEDREINVITE); + /* if we can't BYE, then this is really a pending CANCEL */ + if (!ast_test_flag(p, SIP_CAN_BYE)) { + transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0); + /* Actually don't destroy us yet, wait for the 487 on our original + INVITE, but do set an autodestruct just in case we never get it. */ + sip_scheddestroy(p, 32000); + } else { + transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); + ast_set_flag(p, SIP_NEEDDESTROY); + ast_clear_flag(p, SIP_NEEDREINVITE); + } } else if (ast_test_flag(p, SIP_NEEDREINVITE)) { ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); /* Didn't get to reinvite yet, so do it now */ @@ -9577,6 +9591,10 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru switch (resp) { case 100: /* Trying */ sip_cancel_destroy(p); + /* must call check_pendings before setting CAN_BYE, so that + if PENDINGBYE is set it will know to send CANCEL instead */ + check_pendings(p); + ast_set_flag(p, SIP_CAN_BYE); break; case 180: /* 180 Ringing */ sip_cancel_destroy(p); @@ -9592,6 +9610,10 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru ast_queue_control(p->owner, AST_CONTROL_PROGRESS); } } + /* must call check_pendings before setting CAN_BYE, so that + if PENDINGBYE is set it will know to send CANCEL instead */ + check_pendings(p); + ast_set_flag(p, SIP_CAN_BYE); break; case 183: /* Session progress */ sip_cancel_destroy(p); @@ -9603,6 +9625,10 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru ast_queue_control(p->owner, AST_CONTROL_PROGRESS); } } + /* must call check_pendings before setting CAN_BYE, so that + if PENDINGBYE is set it will know to send CANCEL instead */ + check_pendings(p); + ast_set_flag(p, SIP_CAN_BYE); break; case 200: /* 200 OK on invite - someone's answering our call */ sip_cancel_destroy(p); @@ -12151,7 +12177,7 @@ static struct sip_peer *temp_peer(const char *name) peer->rtpholdtimeout = global_rtpholdtimeout; peer->rtpkeepalive = global_rtpkeepalive; ast_set_flag(peer, SIP_SELFDESTRUCT); - ast_set_flag(peer, SIP_DYNAMIC); + ast_set_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC); peer->prefs = prefs; reg_source_db(peer); @@ -12282,7 +12308,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); } else { /* They'll register with us */ - ast_set_flag(peer, SIP_DYNAMIC); + ast_set_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC); if (!found) { /* Initialize stuff iff we're not found, otherwise we keep going with what we had */ @@ -12299,7 +12325,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int if (peer->expire > -1) ast_sched_del(sched, peer->expire); peer->expire = -1; - ast_clear_flag(peer, SIP_DYNAMIC); + ast_clear_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC); if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { if (ast_get_ip_or_srv(&peer->addr, v->value, "_sip._udp")) { ASTOBJ_UNREF(peer, sip_destroy_peer); @@ -12322,7 +12348,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { peer->ha = ast_append_ha(v->name, v->value, peer->ha); } else if (!strcasecmp(v->name, "port")) { - if (!realtime && ast_test_flag(peer, SIP_DYNAMIC)) + if (!realtime && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)) peer->defaddr.sin_port = htons(atoi(v->value)); else peer->addr.sin_port = htons(atoi(v->value)); @@ -12404,7 +12430,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int */ v=v->next; } - if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(peer, SIP_DYNAMIC) && realtime) { + if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) && realtime) { time_t nowtime; time(&nowtime); @@ -12416,7 +12442,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int } } ast_copy_flags(peer, &peerflags, mask.flags); - if (!found && ast_test_flag(peer, SIP_DYNAMIC) && !ast_test_flag(peer, SIP_REALTIME)) + if (!found && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) && !ast_test_flag(peer, SIP_REALTIME)) reg_source_db(peer); ASTOBJ_UNMARK(peer); ast_free_ha(oldha); -- cgit v1.2.3 From 01f38da4ebc4a92fb1d046e72246f7a5257a6ce3 Mon Sep 17 00:00:00 2001 From: kpfleming Date: Wed, 24 May 2006 21:24:45 +0000 Subject: oops... make sure to stop processing a request once we have sent an authentication challenge (issue #7220) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@30098 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_sip.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index ed1b8f5b9..4b72af406 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -10457,6 +10457,9 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int 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); + /* if an authentication challenge was sent, we are done here */ + if (res > 0) + return 0; if (res < 0) { if (res == -4) { ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); @@ -10864,6 +10867,9 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, } /* Handle authentication if this is our first subscribe */ res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, ignore, mailbox, mailboxsize); + /* if an authentication challenge was sent, we are done here */ + if (res > 0) + return 0; if (res < 0) { if (res == -4) { ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); -- cgit v1.2.3 From 7e4782480604737ecc98f14104d62f441c964c53 Mon Sep 17 00:00:00 2001 From: file Date: Thu, 25 May 2006 15:27:44 +0000 Subject: Get rid of an incorrect SIP dial string in the sample extensions.conf - I even tried variations... no go (issue #7222 reported by arkadia) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@30239 f38db490-d61c-443f-a65b-d21fe96a405b --- configs/extensions.conf.sample | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/configs/extensions.conf.sample b/configs/extensions.conf.sample index 7d46f08ab..5c55ef501 100644 --- a/configs/extensions.conf.sample +++ b/configs/extensions.conf.sample @@ -442,12 +442,10 @@ exten => 8500,n,Goto(s,6) include => demo ; -; Extensions like the two below can be used for FWD, Nikotel, sipgate etc. -; Note that you must have a [sipprovider] section in sip.conf whereas -; the otherprovider.net example does not require such a peer definition +; An extension like the one below can be used for FWD, Nikotel, sipgate etc. +; Note that you must have a [sipprovider] section in sip.conf ; ;exten => _41X.,1,Dial(SIP/${EXTEN:2}@sipprovider,,r) -;exten => _42X.,1,Dial(SIP/user:passwd@${EXTEN:2}@otherprovider.net,30,rT) ; Real extensions would go here. Generally you want real extensions to be ; 4 or 5 digits long (although there is no such requirement) and start with a -- cgit v1.2.3 From 06e12c0a81733d23bd920a5893d958dcdb4b7e2b Mon Sep 17 00:00:00 2001 From: kpfleming Date: Thu, 25 May 2006 17:18:01 +0000 Subject: allow SIPCHANINFO(peername) to work for calls from users as well (issue #7215) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@30293 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_sip.c | 1 + 1 file changed, 1 insertion(+) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 4b72af406..cf7e8892c 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -7177,6 +7177,7 @@ static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipme } if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num)) ast_copy_string(p->cid_name, user->cid_name, sizeof(p->cid_name)); + ast_copy_string(p->peername, user->name, sizeof(p->peername)); ast_copy_string(p->username, user->name, sizeof(p->username)); ast_copy_string(p->peersecret, user->secret, sizeof(p->peersecret)); ast_copy_string(p->subscribecontext, user->subscribecontext, sizeof(p->subscribecontext)); -- cgit v1.2.3 From 313ad4a73ed2bdb9130118879cbfa9cade55ab61 Mon Sep 17 00:00:00 2001 From: kpfleming Date: Thu, 25 May 2006 17:39:33 +0000 Subject: don't try to use -march=s390 when building on S/390 systems (reported via asterisk-users mailing list) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@30296 f38db490-d61c-443f-a65b-d21fe96a405b --- codecs/gsm/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/codecs/gsm/Makefile b/codecs/gsm/Makefile index 5da9cd465..f35361ca3 100644 --- a/codecs/gsm/Makefile +++ b/codecs/gsm/Makefile @@ -50,6 +50,7 @@ ifneq (${PROC},sparc64) ifneq (${PROC},arm) ifneq (${PROC},ppc) ifneq (${PROC},ppc64) +ifneq (${PROC},s390) OPTIMIZE+=-march=$(PROC) endif endif -- cgit v1.2.3 From 229b8e4408761367642aa1144da784980c0a535f Mon Sep 17 00:00:00 2001 From: russell Date: Thu, 25 May 2006 18:40:42 +0000 Subject: add a missing endif from the recent Makefile change and use indentation to hopefully prevent us from breaking this Makefile once again (This nesting is no longer used in the trunk version of this Makefile) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@30329 f38db490-d61c-443f-a65b-d21fe96a405b --- codecs/gsm/Makefile | 51 ++++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/codecs/gsm/Makefile b/codecs/gsm/Makefile index f35361ca3..965aea187 100644 --- a/codecs/gsm/Makefile +++ b/codecs/gsm/Makefile @@ -38,32 +38,33 @@ WAV49 = -DWAV49 ######### probably require gcc. ifneq (${OSARCH},Darwin) -ifneq (${OSARCH},SunOS) -ifneq (${PROC},x86_64) -ifneq (${PROC},amd64) -ifneq (${PROC},ultrasparc) -ifneq ($(shell uname -m),ppc) -ifneq ($(shell uname -m),ppc64) -ifneq ($(shell uname -m),alpha) -ifneq ($(shell uname -m),armv4l) -ifneq (${PROC},sparc64) -ifneq (${PROC},arm) -ifneq (${PROC},ppc) -ifneq (${PROC},ppc64) -ifneq (${PROC},s390) + ifneq (${OSARCH},SunOS) + ifneq (${PROC},x86_64) + ifneq (${PROC},amd64) + ifneq (${PROC},ultrasparc) + ifneq ($(shell uname -m),ppc) + ifneq ($(shell uname -m),ppc64) + ifneq ($(shell uname -m),alpha) + ifneq ($(shell uname -m),armv4l) + ifneq (${PROC},sparc64) + ifneq (${PROC},arm) + ifneq (${PROC},ppc) + ifneq (${PROC},ppc64) + ifneq (${PROC},s390) OPTIMIZE+=-march=$(PROC) -endif -endif -endif -endif -endif -endif -endif -endif -endif -endif -endif -endif + endif + endif + endif + endif + endif + endif + endif + endif + endif + endif + endif + endif + endif endif #The problem with sparc is the best stuff is in newer versions of gcc (post 3.0) only. -- cgit v1.2.3 From 4eb8ce8704c777825ae9febc5ea60e6d860d31f1 Mon Sep 17 00:00:00 2001 From: file Date: Thu, 25 May 2006 20:03:11 +0000 Subject: Don't play the enter sound twice when a person joins a conference after the leader has joined it. (issue #6138 reported by shanermn) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@30373 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_meetme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/app_meetme.c b/apps/app_meetme.c index a4d82eb38..69996c8f7 100644 --- a/apps/app_meetme.c +++ b/apps/app_meetme.c @@ -1069,7 +1069,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c if (!firstpass && !(confflags & CONFFLAG_MONITOR) && !(confflags & CONFFLAG_ADMIN)) { firstpass = 1; if (!(confflags & CONFFLAG_QUIET)) - if (!(confflags & CONFFLAG_WAITMARKED) || (conf->markedusers >= 1)) + if (!(confflags & CONFFLAG_WAITMARKED) || ((confflags & CONFFLAG_MARKEDUSER) && (conf->markedusers >= 1))) conf_play(chan, conf, ENTER); } -- cgit v1.2.3 From 280d46f7c6b72b8f2a91a2f1d6c1072e58acbe11 Mon Sep 17 00:00:00 2001 From: bweschke Date: Thu, 25 May 2006 21:22:16 +0000 Subject: Oops. git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@30424 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/app_queue.c b/apps/app_queue.c index 704573de5..58a85813c 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -2313,7 +2313,7 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce if (bridge != AST_PBX_NO_HANGUP_PEER) ast_hangup(peer); update_queue(qe->parent, member); - res = bridge ? 0 : -1; + res = bridge ? -1 : 0; } out: hangupcalls(outgoing, NULL); -- cgit v1.2.3 From 9edd593f9dc3d21576ec29a100ab65705c0182a2 Mon Sep 17 00:00:00 2001 From: bweschke Date: Fri, 26 May 2006 17:09:51 +0000 Subject: A new way to try and deal with deadlocks that occur in app_queue at present. Using this approach, we only manipulate the main queue mutexes when we get a dev state change on a device that is actually a member of a queue. Backported from /trunk for the "bug fix". git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@30546 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_queue.c | 175 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 146 insertions(+), 29 deletions(-) diff --git a/apps/app_queue.c b/apps/app_queue.c index 58a85813c..5e41b990d 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -303,6 +303,13 @@ struct member { struct member *next; /*!< Next member */ }; +struct ast_member_interfaces { + char interface[80]; + AST_LIST_ENTRY(ast_member_interfaces) list; /*!< Next call queue */ +}; + +static AST_LIST_HEAD_STATIC(interfaces, ast_member_interfaces); + /* values used in multi-bit flags in ast_call_queue */ #define QUEUE_EMPTY_NORMAL 1 #define QUEUE_EMPTY_STRICT 2 @@ -458,6 +465,7 @@ static void *changethread(void *data) struct ast_call_queue *q; struct statechange *sc = data; struct member *cur; + struct ast_member_interfaces *curint; char *loc; char *technology; @@ -470,36 +478,50 @@ static void *changethread(void *data) free(sc); return NULL; } - if (option_debug) - ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state)); - ast_mutex_lock(&qlock); - for (q = queues; q; q = q->next) { - ast_mutex_lock(&q->lock); - cur = q->members; - while(cur) { - if (!strcasecmp(sc->dev, cur->interface)) { - if (cur->status != sc->state) { - cur->status = sc->state; - if (!q->maskmemberstatus) { - manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus", - "Queue: %s\r\n" - "Location: %s\r\n" - "Membership: %s\r\n" - "Penalty: %d\r\n" - "CallsTaken: %d\r\n" - "LastCall: %d\r\n" - "Status: %d\r\n" - "Paused: %d\r\n", - q->name, cur->interface, cur->dynamic ? "dynamic" : "static", - cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused); + + AST_LIST_LOCK(&interfaces); + AST_LIST_TRAVERSE(&interfaces, curint, list) { + if (!strcasecmp(curint->interface, sc->dev)) + break; + } + AST_LIST_UNLOCK(&interfaces); + + if (curint) { + + if (option_debug) + ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state)); + ast_mutex_lock(&qlock); + for (q = queues; q; q = q->next) { + ast_mutex_lock(&q->lock); + cur = q->members; + while(cur) { + if (!strcasecmp(sc->dev, cur->interface)) { + if (cur->status != sc->state) { + cur->status = sc->state; + if (!q->maskmemberstatus) { + manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus", + "Queue: %s\r\n" + "Location: %s\r\n" + "Membership: %s\r\n" + "Penalty: %d\r\n" + "CallsTaken: %d\r\n" + "LastCall: %d\r\n" + "Status: %d\r\n" + "Paused: %d\r\n", + q->name, cur->interface, cur->dynamic ? "dynamic" : "static", + cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused); + } } } + cur = cur->next; } - cur = cur->next; + ast_mutex_unlock(&q->lock); } - ast_mutex_unlock(&q->lock); - } - ast_mutex_unlock(&qlock); + ast_mutex_unlock(&qlock); + } else { + if (option_debug) + ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d' (%s) but we don't care because they're not a member of any queue.\n", technology, loc, sc->state, devstate2str(sc->state)); + } free(sc); return NULL; } @@ -596,6 +618,89 @@ static void clear_queue(struct ast_call_queue *q) q->wrapuptime = 0; } +static int add_to_interfaces(char *interface) +{ + struct ast_member_interfaces *curint, *newint; + + AST_LIST_LOCK(&interfaces); + AST_LIST_TRAVERSE(&interfaces, curint, list) { + if (!strcasecmp(curint->interface, interface)) + break; + } + + if (!curint) { + if (option_debug) + ast_log(LOG_DEBUG, "Adding %s to the list of interfaces that make up all of our queue members.\n", interface); + + if ((newint = malloc(sizeof(*newint)))) { + memset(newint, 0, sizeof(*newint)); + ast_copy_string(newint->interface, interface, sizeof(newint->interface)); + AST_LIST_INSERT_HEAD(&interfaces, newint, list); + } + } + AST_LIST_UNLOCK(&interfaces); + + return 0; +} + +static int interface_exists_global(char *interface) +{ + struct ast_call_queue *q; + struct member *mem; + int ret = 0; + + ast_mutex_lock(&qlock); + for (q = queues; q && !ret; q = q->next) { + ast_mutex_lock(&q->lock); + mem = q->members; + while(mem) { + if (!strcasecmp(interface, mem->interface)) { + ret = 1; + break; + } + } + ast_mutex_unlock(&q->lock); + } + ast_mutex_unlock(&qlock); + + return ret; +} + + +static int remove_from_interfaces(char *interface) +{ + struct ast_member_interfaces *curint; + + AST_LIST_LOCK(&interfaces); + AST_LIST_TRAVERSE_SAFE_BEGIN(&interfaces, curint, list) { + if (!strcasecmp(curint->interface, interface) && !interface_exists_global(interface)) { + if (option_debug) + ast_log(LOG_DEBUG, "Removing %s from the list of interfaces that make up all of our queue members.\n", interface); + AST_LIST_REMOVE_CURRENT(&interfaces, list); + free(curint); + } + } + AST_LIST_TRAVERSE_SAFE_END; + AST_LIST_UNLOCK(&interfaces); + + return 0; +} + +static void clear_and_free_interfaces(void) +{ + struct ast_member_interfaces *curint; + + AST_LIST_LOCK(&interfaces); + AST_LIST_TRAVERSE_SAFE_BEGIN(&interfaces, curint, list) { + AST_LIST_REMOVE_CURRENT(&interfaces, list); + free(curint); + } + AST_LIST_TRAVERSE_SAFE_END; + AST_LIST_UNLOCK(&interfaces); + + return; +} + /*! \brief Configure a queue parameter. \par For error reporting, line number is passed for .conf static configuration. @@ -746,6 +851,7 @@ static void rt_handle_member_record(struct ast_call_queue *q, char *interface, c m = create_queue_member(interface, penalty, 0); if (m) { m->dead = 0; + add_to_interfaces(interface); if (prev_m) { prev_m->next = m; } else { @@ -770,6 +876,7 @@ static void free_members(struct ast_call_queue *q, int all) prev->next = next; else q->members = next; + remove_from_interfaces(curm->interface); free(curm); } else prev = curm; @@ -917,6 +1024,7 @@ static struct ast_call_queue *find_queue_by_name_rt(const char *queuename, struc } else { q->members = next_m; } + remove_from_interfaces(m->interface); free(m); } else { prev_m = m; @@ -1033,9 +1141,9 @@ static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result * qe->chan->cid.cid_num ? qe->chan->cid.cid_num : "unknown", qe->chan->cid.cid_name ? qe->chan->cid.cid_name : "unknown", q->name, qe->pos, q->count ); -#if 0 -ast_log(LOG_NOTICE, "Queue '%s' Join, Channel '%s', Position '%d'\n", q->name, qe->chan->name, qe->pos ); -#endif + + if (option_debug) + ast_log(LOG_DEBUG, "Queue '%s' Join, Channel '%s', Position '%d'\n", q->name, qe->chan->name, qe->pos ); } ast_mutex_unlock(&q->lock); ast_mutex_unlock(&qlock); @@ -2421,6 +2529,8 @@ static int remove_from_queue(char *queuename, char *interface) } ast_mutex_unlock(&q->lock); } + if (res == RES_OKAY) + remove_from_interfaces(interface); ast_mutex_unlock(&qlock); return res; } @@ -2440,6 +2550,9 @@ static int add_to_queue(char *queuename, char *interface, int penalty, int pause if (q) { ast_mutex_lock(&q->lock); if (interface_exists(q, interface) == NULL) { + + add_to_interfaces(interface); + new_member = create_queue_member(interface, penalty, paused); if (new_member != NULL) { @@ -3251,6 +3364,8 @@ static void reload_queues(void) } free(cur); } else { + /* Add them to the master int list if necessary */ + add_to_interfaces(interface); newm->next = q->members; q->members = newm; } @@ -3275,6 +3390,7 @@ static void reload_queues(void) q->members = cur->next; newm = cur; } + remove_from_interfaces(cur->interface); } } if (!new) @@ -3827,6 +3943,7 @@ int unload_module(void) { int res; + clear_and_free_interfaces(); res = ast_cli_unregister(&cli_show_queue); res |= ast_cli_unregister(&cli_show_queues); res |= ast_cli_unregister(&cli_add_queue_member); -- cgit v1.2.3 From 8b5cb4a3d6e2ff8448d9ad2a68f160d1a46261bb Mon Sep 17 00:00:00 2001 From: bweschke Date: Tue, 30 May 2006 14:55:16 +0000 Subject: Fix infinite loop scenario and add some sanity checking to prevent segfault on a NULL parameter coming in (which probably shouldn't happen, but just to be safe...) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@30770 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_queue.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/apps/app_queue.c b/apps/app_queue.c index 5e41b990d..53929b309 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -622,6 +622,9 @@ static int add_to_interfaces(char *interface) { struct ast_member_interfaces *curint, *newint; + if (!interface) + return 0; + AST_LIST_LOCK(&interfaces); AST_LIST_TRAVERSE(&interfaces, curint, list) { if (!strcasecmp(curint->interface, interface)) @@ -649,6 +652,9 @@ static int interface_exists_global(char *interface) struct member *mem; int ret = 0; + if (!interface) + return ret; + ast_mutex_lock(&qlock); for (q = queues; q && !ret; q = q->next) { ast_mutex_lock(&q->lock); @@ -658,6 +664,7 @@ static int interface_exists_global(char *interface) ret = 1; break; } + mem = mem->next; } ast_mutex_unlock(&q->lock); } @@ -671,6 +678,9 @@ static int remove_from_interfaces(char *interface) { struct ast_member_interfaces *curint; + if (!interface) + return 0; + AST_LIST_LOCK(&interfaces); AST_LIST_TRAVERSE_SAFE_BEGIN(&interfaces, curint, list) { if (!strcasecmp(curint->interface, interface) && !interface_exists_global(interface)) { -- cgit v1.2.3 From d21afd47df4b62c484302a965fb19487c5ea76a5 Mon Sep 17 00:00:00 2001 From: kpfleming Date: Tue, 30 May 2006 16:07:16 +0000 Subject: another S/390 build fix git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@30802 f38db490-d61c-443f-a65b-d21fe96a405b --- codecs/gsm/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/codecs/gsm/Makefile b/codecs/gsm/Makefile index 965aea187..8bc53e88d 100644 --- a/codecs/gsm/Makefile +++ b/codecs/gsm/Makefile @@ -242,6 +242,7 @@ ifneq ($(shell uname -m),armv4l) ifneq ($(shell uname -m),sparc64) ifneq (${PROC},arm) ifneq ($(shell uname -m), parisc) +ifneq ($(shell uname -m), s390) GSM_SOURCES+= $(SRC)/k6opt.s endif endif @@ -253,6 +254,7 @@ endif endif endif endif +endif TOAST_SOURCES = $(SRC)/toast.c \ $(SRC)/toast_lin.c \ -- cgit v1.2.3 From db1a2718186b0a4483b24f202a96794e2c2e00e2 Mon Sep 17 00:00:00 2001 From: kpfleming Date: Tue, 30 May 2006 19:18:30 +0000 Subject: check the proper variable... git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@30874 f38db490-d61c-443f-a65b-d21fe96a405b --- codecs/gsm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codecs/gsm/Makefile b/codecs/gsm/Makefile index 8bc53e88d..9058f1293 100644 --- a/codecs/gsm/Makefile +++ b/codecs/gsm/Makefile @@ -242,7 +242,7 @@ ifneq ($(shell uname -m),armv4l) ifneq ($(shell uname -m),sparc64) ifneq (${PROC},arm) ifneq ($(shell uname -m), parisc) -ifneq ($(shell uname -m), s390) +ifneq (${PROC}, s390) GSM_SOURCES+= $(SRC)/k6opt.s endif endif -- cgit v1.2.3