[asterisk-commits] branch oej/test-this-branch r19732 - in
/team/oej/test-this-branch: ./ apps/ ...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Thu Apr 13 04:45:02 MST 2006
Author: oej
Date: Thu Apr 13 06:44:38 2006
New Revision: 19732
URL: http://svn.digium.com/view/asterisk?rev=19732&view=rev
Log:
Reset, resolve go
Added:
team/oej/test-this-branch/apps/app_speech_utils.c
- copied unchanged from r19128, trunk/apps/app_speech_utils.c
team/oej/test-this-branch/doc/datastores.txt
- copied unchanged from r19128, trunk/doc/datastores.txt
team/oej/test-this-branch/doc/speechrec.txt
- copied unchanged from r19128, trunk/doc/speechrec.txt
team/oej/test-this-branch/include/asterisk/speech.h
- copied unchanged from r19128, trunk/include/asterisk/speech.h
team/oej/test-this-branch/res/res_speech.c
- copied unchanged from r19128, trunk/res/res_speech.c
Modified:
team/oej/test-this-branch/ (props changed)
team/oej/test-this-branch/.cleancount
team/oej/test-this-branch/UPGRADE.txt
team/oej/test-this-branch/app.c
team/oej/test-this-branch/apps/app_dial.c
team/oej/test-this-branch/apps/app_parkandannounce.c
team/oej/test-this-branch/apps/app_queue.c
team/oej/test-this-branch/apps/app_rpt.c
team/oej/test-this-branch/apps/app_voicemail.c
team/oej/test-this-branch/channel.c
team/oej/test-this-branch/channels/chan_misdn.c
team/oej/test-this-branch/channels/chan_sip.c
team/oej/test-this-branch/channels/misdn/isdn_lib.c
team/oej/test-this-branch/doc/00README.1st
team/oej/test-this-branch/doc/CODING-GUIDELINES
team/oej/test-this-branch/formats/format_g723.c
team/oej/test-this-branch/formats/format_g726.c
team/oej/test-this-branch/formats/format_g729.c
team/oej/test-this-branch/formats/format_gsm.c
team/oej/test-this-branch/formats/format_h263.c
team/oej/test-this-branch/formats/format_h264.c
team/oej/test-this-branch/formats/format_ilbc.c
team/oej/test-this-branch/formats/format_ogg_vorbis.c
team/oej/test-this-branch/formats/format_pcm.c
team/oej/test-this-branch/formats/format_sln.c
team/oej/test-this-branch/formats/format_vox.c
team/oej/test-this-branch/formats/format_wav.c
team/oej/test-this-branch/formats/format_wav_gsm.c
team/oej/test-this-branch/funcs/func_odbc.c
team/oej/test-this-branch/include/asterisk/channel.h
team/oej/test-this-branch/include/asterisk/compat.h
team/oej/test-this-branch/include/asterisk/doxyref.h
team/oej/test-this-branch/include/asterisk/frame.h
team/oej/test-this-branch/pbx.c
team/oej/test-this-branch/res/res_config_pgsql.c
team/oej/test-this-branch/utils.c
Propchange: team/oej/test-this-branch/
------------------------------------------------------------------------------
automerge = http://edvina.net/training/
Propchange: team/oej/test-this-branch/
------------------------------------------------------------------------------
Binary property 'branch-1.2-merged' - no diff available.
Propchange: team/oej/test-this-branch/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Thu Apr 13 06:44:38 2006
@@ -1,1 +1,1 @@
-/trunk:1-18604
+/trunk:1-19128
Modified: team/oej/test-this-branch/.cleancount
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/.cleancount?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/.cleancount (original)
+++ team/oej/test-this-branch/.cleancount Thu Apr 13 06:44:38 2006
@@ -1,1 +1,1 @@
-13
+15
Modified: team/oej/test-this-branch/UPGRADE.txt
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/UPGRADE.txt?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/UPGRADE.txt (original)
+++ team/oej/test-this-branch/UPGRADE.txt Thu Apr 13 06:44:38 2006
@@ -1,5 +1,10 @@
Information for Upgrading From Previous Asterisk Releases
=========================================================
+
+PBX Core:
+
+* The (very old and undocumented) ability to use BYEXTENSION for dialing
+ instead of ${EXTEN} has been removed.
Command Line Interface:
Modified: team/oej/test-this-branch/app.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/app.c?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/app.c (original)
+++ team/oej/test-this-branch/app.c Thu Apr 13 06:44:38 2006
@@ -552,7 +552,6 @@
struct ast_dsp *sildet=NULL; /* silence detector dsp */
int totalsilence = 0;
int dspsilence = 0;
- int gotsilence = 0; /* did we timeout for silence? */
int rfmt=0;
struct ast_silence_generator *silgen = NULL;
@@ -675,7 +674,7 @@
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000);
ast_frfree(f);
- gotsilence = 1;
+ res = 'S';
outmsg=2;
break;
}
@@ -779,7 +778,6 @@
struct ast_dsp *sildet; /* silence detector dsp */
int totalsilence = 0;
int dspsilence = 0;
- int gotsilence = 0; /* did we timeout for silence? */
int rfmt=0;
char prependfile[80];
@@ -898,7 +896,7 @@
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "Recording automatically stopped after a silence of %d seconds\n", totalsilence/1000);
ast_frfree(f);
- gotsilence = 1;
+ res = 'S';
outmsg=2;
break;
}
Modified: team/oej/test-this-branch/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/apps/app_dial.c?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/apps/app_dial.c (original)
+++ team/oej/test-this-branch/apps/app_dial.c Thu Apr 13 06:44:38 2006
@@ -1,7 +1,7 @@
/*
* Asterisk -- An open source telephony toolkit.
*
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999 - 2006, Digium, Inc.
*
* Mark Spencer <markster at digium.com>
*
@@ -747,10 +747,8 @@
int numnochan = 0;
int cause;
char numsubst[AST_MAX_EXTENSION];
- char restofit[AST_MAX_EXTENSION];
char cidname[AST_MAX_EXTENSION];
char toast[80];
- char *newnum;
char *l;
int privdb_val=0;
unsigned int calldurationlimit=0;
@@ -1007,14 +1005,6 @@
ast_set2_flag(tmp, args.url, DIAL_NOFORWARDHTML);
}
ast_copy_string(numsubst, number, sizeof(numsubst));
- /* If we're dialing by extension, look at the extension to know what to dial */
- if ((newnum = strstr(numsubst, "BYEXTENSION"))) {
- /* strlen("BYEXTENSION") == 11 */
- ast_copy_string(restofit, newnum + 11, sizeof(restofit));
- snprintf(newnum, sizeof(numsubst) - (newnum - numsubst), "%s%s", chan->exten,restofit);
- if (option_debug)
- ast_log(LOG_DEBUG, "Dialing by extension %s\n", numsubst);
- }
/* Request the peer */
tmp->chan = ast_request(tech, chan->nativeformats, numsubst, &cause);
if (!tmp->chan) {
Modified: team/oej/test-this-branch/apps/app_parkandannounce.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/apps/app_parkandannounce.c?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/apps/app_parkandannounce.c (original)
+++ team/oej/test-this-branch/apps/app_parkandannounce.c Thu Apr 13 06:44:38 2006
@@ -1,7 +1,7 @@
/*
* Asterisk -- An open source telephony toolkit.
*
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999 - 2006, Digium, Inc.
*
* Mark Spencer <markster at digium.com>
*
@@ -164,9 +164,9 @@
}
/* At this point we have a priority and maybe an extension and a context */
chan->priority = atoi(priority);
- if(exten && strcasecmp(exten, "BYEXTENSION"))
+ if (exten)
strncpy(chan->exten, exten, sizeof(chan->exten)-1);
- if(context)
+ if (context)
strncpy(chan->context, context, sizeof(chan->context)-1);
} else { /* increment the priority by default*/
chan->priority++;
Modified: team/oej/test-this-branch/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/apps/app_queue.c?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/apps/app_queue.c (original)
+++ team/oej/test-this-branch/apps/app_queue.c Thu Apr 13 06:44:38 2006
@@ -2018,11 +2018,9 @@
struct member *cur;
struct callattempt *outgoing=NULL; /* the queue we are building */
int to;
- char restofit[AST_MAX_EXTENSION];
char oldexten[AST_MAX_EXTENSION]="";
char oldcontext[AST_MAX_CONTEXT]="";
char queuename[256]="";
- char *newnum;
struct ast_channel *peer;
struct ast_channel *which;
struct callattempt *lpeer;
@@ -2103,14 +2101,6 @@
tmp->oldstatus = cur->status;
tmp->lastcall = cur->lastcall;
ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface));
- /* If we're dialing by extension, look at the extension to know what to dial */
- if ((newnum = strstr(tmp->interface, "/BYEXTENSION"))) {
- newnum++;
- strncpy(restofit, newnum + strlen("BYEXTENSION"), sizeof(restofit) - 1);
- snprintf(newnum, sizeof(tmp->interface) - (newnum - tmp->interface), "%s%s", qe->chan->exten, restofit);
- if (option_debug)
- ast_log(LOG_DEBUG, "Dialing by extension %s\n", tmp->interface);
- }
/* Special case: If we ring everyone, go ahead and ring them, otherwise
just calculate their metric for the appropriate strategy */
if (!calc_metric(qe->parent, cur, x++, qe, tmp)) {
Modified: team/oej/test-this-branch/apps/app_rpt.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/apps/app_rpt.c?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/apps/app_rpt.c (original)
+++ team/oej/test-this-branch/apps/app_rpt.c Thu Apr 13 06:44:38 2006
@@ -6452,9 +6452,9 @@
}
/* At this point we have a priority and maybe an extension and a context */
chan->priority = atoi(priority);
- if(exten && strcasecmp(exten, "BYEXTENSION"))
+ if (exten)
strncpy(chan->exten, exten, sizeof(chan->exten)-1);
- if(context)
+ if (context)
strncpy(chan->context, context, sizeof(chan->context)-1);
} else { /* increment the priority by default*/
chan->priority++;
Modified: team/oej/test-this-branch/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/apps/app_voicemail.c?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/apps/app_voicemail.c (original)
+++ team/oej/test-this-branch/apps/app_voicemail.c Thu Apr 13 06:44:38 2006
@@ -3311,7 +3311,7 @@
cmd = 't';
}
}
- if (cmd == 't')
+ if (cmd == 't' || cmd == 'S')
cmd = 0;
return cmd;
}
Modified: team/oej/test-this-branch/channel.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/channel.c?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/channel.c (original)
+++ team/oej/test-this-branch/channel.c Thu Apr 13 06:44:38 2006
@@ -655,6 +655,7 @@
headp = &tmp->varshead;
ast_mutex_init(&tmp->lock);
AST_LIST_HEAD_INIT_NOLOCK(headp);
+ AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores);
strcpy(tmp->context, "default");
ast_string_field_set(tmp, language, defaultlanguage);
strcpy(tmp->exten, "s");
@@ -930,6 +931,7 @@
struct ast_var_t *vardata;
struct ast_frame *f, *fp;
struct varshead *headp;
+ struct ast_datastore *datastore = NULL;
char name[AST_CHANNEL_NAME];
headp=&chan->varshead;
@@ -983,6 +985,12 @@
ast_frfree(fp);
}
+ /* Get rid of each of the data stores on the channel */
+ while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry)))
+ /* Free the data store */
+ ast_channel_datastore_free(datastore);
+ AST_LIST_HEAD_INIT_NOLOCK(&chan->datastores);
+
/* loop over the variables list, freeing all data and deleting list items */
/* no need to lock the list, as the channel is already locked */
@@ -999,6 +1007,105 @@
AST_LIST_UNLOCK(&channels);
ast_device_state_changed_literal(name);
+}
+
+struct ast_datastore *ast_channel_datastore_alloc(const struct ast_datastore_info *info, char *uid)
+{
+ struct ast_datastore *datastore = NULL;
+
+ /* Make sure we at least have type so we can identify this */
+ if (info == NULL) {
+ return NULL;
+ }
+
+ /* Allocate memory for datastore and clear it */
+ datastore = ast_calloc(1, sizeof(*datastore));
+ if (datastore == NULL) {
+ return NULL;
+ }
+
+ datastore->info = info;
+
+ if (uid != NULL) {
+ datastore->uid = ast_strdup(uid);
+ }
+
+ return datastore;
+}
+
+int ast_channel_datastore_free(struct ast_datastore *datastore)
+{
+ int res = 0;
+
+ /* Using the destroy function (if present) destroy the data */
+ if (datastore->info->destroy != NULL && datastore->data != NULL) {
+ datastore->info->destroy(datastore->data);
+ datastore->data = NULL;
+ }
+
+ /* Free allocated UID memory */
+ if (datastore->uid != NULL) {
+ free(datastore->uid);
+ datastore->uid = NULL;
+ }
+
+ /* Finally free memory used by ourselves */
+ free(datastore);
+ datastore = NULL;
+
+ return res;
+}
+
+int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
+{
+ int res = 0;
+
+ AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry);
+
+ return res;
+}
+
+int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
+{
+ struct ast_datastore *datastore2 = NULL;
+ int res = -1;
+
+ /* Find our position and remove ourselves */
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore2, entry) {
+ if (datastore2 == datastore) {
+ AST_LIST_REMOVE_CURRENT(&chan->datastores, entry);
+ res = 0;
+ break;
+ }
+ }
+ AST_LIST_TRAVERSE_SAFE_END
+
+ return res;
+}
+
+struct ast_datastore *ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, char *uid)
+{
+ struct ast_datastore *datastore = NULL;
+
+ if (info == NULL)
+ return NULL;
+
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) {
+ if (datastore->info == info) {
+ if (uid != NULL && datastore->uid != NULL) {
+ if (!strcasecmp(uid, datastore->uid)) {
+ /* Matched by type AND uid */
+ break;
+ }
+ } else {
+ /* Matched by type at least */
+ break;
+ }
+ }
+ }
+ AST_LIST_TRAVERSE_SAFE_END
+
+ return datastore;
}
int ast_channel_spy_add(struct ast_channel *chan, struct ast_channel_spy *spy)
@@ -3061,6 +3168,11 @@
if (x != AST_GENERATOR_FD)
original->fds[x] = clone->fds[x];
}
+ /* Move data stores over */
+ if (AST_LIST_FIRST(&clone->datastores))
+ AST_LIST_INSERT_TAIL(&original->datastores, AST_LIST_FIRST(&clone->datastores), entry);
+ AST_LIST_HEAD_INIT_NOLOCK(&clone->datastores);
+
clone_variables(original, clone);
AST_LIST_HEAD_INIT_NOLOCK(&clone->varshead);
/* Presense of ADSI capable CPE follows clone */
Modified: team/oej/test-this-branch/channels/chan_misdn.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/channels/chan_misdn.c?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/channels/chan_misdn.c (original)
+++ team/oej/test-this-branch/channels/chan_misdn.c Thu Apr 13 06:44:38 2006
@@ -2067,7 +2067,6 @@
if (!len) {
chan_misdn_log(4,tmp->bc->port,"misdn_read: ZERO READ\n");
-
tmp->frame.frametype = AST_FRAME_NULL;
tmp->frame.subclass = 0;
return &tmp->frame;
@@ -2885,7 +2884,7 @@
close(ch->pipe[0]);
close(ch->pipe[1]);
- if (ast && MISDN_ASTERISK_PVT(ast)) {
+ if (ast && MISDN_ASTERISK_TECH_PVT(ast)) {
chan_misdn_log(1, bc->port, "* RELEASING CHANNEL pid:%d ctx:%s dad:%s oad:%s state: %s\n",bc?bc->pid:-1, ast->context, ast->exten,AST_CID_P(ast),misdn_get_ch_state(ch));
chan_misdn_log(3, bc->port, " --> * State Down\n");
/* copy cause */
@@ -3556,7 +3555,7 @@
send_cause2ast(ch->ast,bc);
- if (misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) {
+ if ( ch->orginator==ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) {
/* If there's inband information available (e.g. a
recorded message saying what was wrong with the
dialled number, or perhaps even giving an
@@ -3588,7 +3587,6 @@
*/
misdn_lib_send_event(bc,EVENT_RELEASE);
-
}
break;
Modified: team/oej/test-this-branch/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/channels/chan_sip.c?rev=19732&r1=19731&r2=19732&view=diff
==============================================================================
--- team/oej/test-this-branch/channels/chan_sip.c (original)
+++ team/oej/test-this-branch/channels/chan_sip.c Thu Apr 13 06:44:38 2006
@@ -107,7 +107,6 @@
#define TRUE 1
#endif
-
#define VIDEO_CODEC_MASK 0x1fc0000 /*!< Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO */
#ifndef IPTOS_MINCOST
#define IPTOS_MINCOST 0x02
@@ -159,6 +158,7 @@
#define SIP_MAX_LINES 64 /*!< Max amount of lines in SIP attachment (like SDP) */
#define SIP_MAX_PACKET 4096 /*!< Also from RFC 3261 (2543), should sub headers tho */
+#define INITIAL_CSEQ 101 /*!< our initial sip sequence number */
#ifdef AST_JB
#include "asterisk/abstract_jb.h"
@@ -288,31 +288,6 @@
{ SIP_PUBLISH, NO_RTP, "PUBLISH" }
};
-/*! \brief Structure for conversion between compressed SIP and "normal" SIP */
-static const struct cfalias {
- char * const fullname;
- char * const shortname;
-} aliases[] = {
- { "Content-Type", "c" },
- { "Content-Encoding", "e" },
- { "From", "f" },
- { "Call-ID", "i" },
- { "Contact", "m" },
- { "Content-Length", "l" },
- { "Subject", "s" },
- { "To", "t" },
- { "Supported", "k" },
- { "Refer-To", "r" },
- { "Referred-By", "b" },
- { "Allow-Events", "u" },
- { "Event", "o" },
- { "Via", "v" },
- { "Accept-Contact", "a" },
- { "Reject-Contact", "j" },
- { "Request-Disposition", "d" },
- { "Session-Expires", "x" },
-};
-
/*! Define SIP option tags, used in Require: and Supported: headers
We need to be aware of these properties in the phones to use
the replace: header. We should not do that without knowing
@@ -347,7 +322,7 @@
int id; /*!< Bitmap ID */
int supported; /*!< Supported by Asterisk ? */
char * const text; /*!< Text id, as in standard */
-} sip_options[] = {
+} sip_options[] = { /* XXX used in 3 places */
/* Replaces: header for transfer */
{ SIP_OPT_REPLACES, SUPPORTED, "replaces" },
/* RFC3262: PRACK 100% reliability */
@@ -535,13 +510,31 @@
int len; /*!< Length */
int headers; /*!< # of SIP Headers */
int method; /*!< Method of this request */
+ int lines; /*!< SDP Content */
+ unsigned int flags; /*!< SIP_PKT Flags for this packet */
char *header[SIP_MAX_HEADERS];
- int lines; /*!< SDP 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 */
};
+
+/*
+ * A sip packet is stored into the data[] buffer, with the header followed
+ * by an empty line and the body of the message.
+ * On outgoing packets, data is accumulated in data[] with len reflecting
+ * the next available byte, headers and lines count the number of lines
+ * in both parts. There are no '\0' in data[0..len-1].
+ *
+ * On received packet, the input read from the socket is copied into data[],
+ * len is set and the string is NUL-terminated. Then a parser fills up
+ * the other fields -header[] and line[] to point to the lines of the
+ * message, rlPart1 and rlPart2 parse the first lnie as below:
+ *
+ * Requests have in the first line METHOD URI SIP/2.0
+ * rlPart1 = method; rlPart2 = uri;
+ * Responses have in the first line SIP/2.0 code description
+ * rlPart1 = SIP/2.0; rlPart2 = code + description;
+ *
+ */
/*! \brief structure used in transfers */
struct sip_dual {
@@ -702,6 +695,9 @@
/* SIP packet flags */
#define SIP_PKT_DEBUG (1 << 0) /*!< Debug this packet */
#define SIP_PKT_WITH_TOTAG (1 << 1) /*!< This packet has a to-tag */
+#define SIP_PKT_IGNORE (1 << 2) /*!< This is a re-transmit, ignore it */
+#define SIP_PKT_IGNORE_RESP (1 << 3) /*!< Resp ignore - ??? */
+#define SIP_PKT_IGNORE_REQ (1 << 4) /*!< Req ignore - ??? */
#define sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG)
#define sipdebug_config ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG)
@@ -845,6 +841,7 @@
};
/*! \brief Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) */
+/* XXX field 'name' must be first otherwise sip_addrcmp() will fail */
struct sip_peer {
ASTOBJ_COMPONENTS(struct sip_peer); /*!< name, refcount, objflags, object pointers */
enum objecttype type; /*!< SIP_PEER and/or SIP_USER */
@@ -982,7 +979,7 @@
/*---------------------------- Forward declarations of functions in chan_sip.c */
static int transmit_response(struct sip_pvt *p, char *msg, struct sip_request *req);
static int transmit_response_with_sdp(struct sip_pvt *p, char *msg, struct sip_request *req, enum xmittype reliable);
-static int transmit_response_with_unsupported(struct sip_pvt *p, char *msg, struct sip_request *req, char *unsupported);
+static int transmit_response_with_unsupported(struct sip_pvt *p, const char *msg, struct sip_request *req, const char *unsupported);
static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, struct sip_request *req, const char *rand, enum xmittype reliable, const char *header, int stale);
static int transmit_request(struct sip_pvt *p, int sipmethod, int inc, enum xmittype reliable, int newbranch);
static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, int inc, enum xmittype reliable, int newbranch);
@@ -1027,15 +1024,15 @@
static void sip_dump_history(struct sip_pvt *dialog); /* Dump history to LOG_DEBUG at end of dialog, before destroying data */
static const struct cfsubscription_types *find_subscription_type(enum subscriptiontype subtype);
static int transmit_state_notify(struct sip_pvt *p, int state, int full);
-static char *gettag(struct sip_request *req, char *header, char *tagbuf, int tagbufsize);
-static int find_sip_method(char *msg);
-static unsigned int parse_sip_options(struct sip_pvt *pvt, char *supported);
+static const char *gettag(const struct sip_request *req, char *header, char *tagbuf, int tagbufsize);
+static int find_sip_method(const char *msg);
+static unsigned int parse_sip_options(struct sip_pvt *pvt, const char *supported);
static void sip_destroy(struct sip_pvt *p);
static void sip_destroy_device(struct sip_peer *device);
static void parse_request(struct sip_request *req);
-static char *get_header(struct sip_request *req, const char *name);
+static const char *get_header(const struct sip_request *req, const char *name);
static void copy_request(struct sip_request *dst,struct sip_request *src);
-static int transmit_response_reliable(struct sip_pvt *p, char *msg, struct sip_request *req);
+static int transmit_response_reliable(struct sip_pvt *p, const char *msg, struct sip_request *req);
static int transmit_register(struct sip_registry *r, int sipmethod, char *auth, char *authheader);
static int sip_poke_peer(struct sip_peer *peer);
static int __sip_do_register(struct sip_registry *r);
@@ -1057,6 +1054,17 @@
static int transmit_reinvite_with_t38_sdp(struct sip_pvt *p);
static struct ast_udptl *sip_get_udptl_peer(struct ast_channel *chan);
static int sip_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl);
+
+/*------Request handling functions */
+static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, char *e);
+static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock);
+static int handle_request_bye(struct sip_pvt *p, struct sip_request *req);
+static int handle_request_register(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, char *e);
+static int handle_request_cancel(struct sip_pvt *p, struct sip_request *req);
+static int handle_request_message(struct sip_pvt *p, struct sip_request *req);
+static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e);
+static void handle_request_info(struct sip_pvt *p, struct sip_request *req);
+static int handle_request_options(struct sip_pvt *p, struct sip_request *req);
/*----- RTP interface functions */
static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active);
@@ -1110,25 +1118,37 @@
set_udptl_peer: sip_set_udptl_peer,
};
-/*! \brief Find SIP method from header
- * Strictly speaking, SIP methods are case SENSITIVE, but we don't check
- * following Jon Postel's rule: Be gentle in what you accept, strict with what you send */
-static int find_sip_method(char *msg)
+/*! \brief returns true if 'name' (with optional trailing whitespace)
+ * matches the sip method 'id'.
+ * Strictly speaking, SIP methods are case SENSITIVE, but we do
+ * a case-insensitive comparison to be more tolerant.
+ * following Jon Postel's rule: Be gentle in what you accept, strict with what you send
+ */
+static int method_match(enum sipmethod id, const char *name)
+{
+ int len = strlen(sip_methods[id].text);
+ int l_name = name ? strlen(name) : 0;
+ /* true if the string is long enough, and ends with whitespace, and matches */
+ return (l_name >= len && name[len] < 33 &&
+ !strncasecmp(sip_methods[id].text, name, len));
+}
+
+/*! \brief find_sip_method: Find SIP method from header */
+static int find_sip_method(const char *msg)
{
int i, res = 0;
if (ast_strlen_zero(msg))
return 0;
-
for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) {
- if (!strcasecmp(sip_methods[i].text, msg))
+ if (method_match(i, msg))
res = sip_methods[i].id;
}
return res;
}
/*! \brief Parse supported header in incoming packet */
-static unsigned int parse_sip_options(struct sip_pvt *pvt, char *supported)
+static unsigned int parse_sip_options(struct sip_pvt *pvt, const char *supported)
{
char *next, *sep;
char *temp = ast_strdupa(supported);
@@ -1179,29 +1199,35 @@
return 1;
}
+/* The real destination address for a write */
+static const struct sockaddr_in *sip_real_dst(const struct sip_pvt *p)
+{
+ return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa;
+}
+
+static const char *sip_nat_mode(const struct sip_pvt *p)
+{
+ return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT";
+}
+
/*! \brief Test PVT for debugging output */
static inline int sip_debug_test_pvt(struct sip_pvt *p)
{
if (!sipdebug)
return 0;
- return sip_debug_test_addr(ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ? &p->recv : &p->sa);
-}
-
+ return sip_debug_test_addr(sip_real_dst(p));
+}
/*! \brief Transmit SIP message */
static int __sip_xmit(struct sip_pvt *p, char *data, int len)
{
int res;
char iabuf[INET_ADDRSTRLEN];
-
- if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE))
- res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->recv, sizeof(struct sockaddr_in));
- else
- res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct sockaddr_in));
-
- if (res != len) {
- ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s:%d returned %d: %s\n", data, len, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), res, strerror(errno));
- }
+ const struct sockaddr_in *dst = sip_real_dst(p);
+ res=sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in));
+
+ if (res != len)
+ ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s:%d returned %d: %s\n", data, len, ast_inet_ntoa(iabuf, sizeof(iabuf), dst->sin_addr), ntohs(dst->sin_port), res, strerror(errno));
return res;
}
@@ -1232,7 +1258,7 @@
if (localaddr && externip.sin_addr.s_addr &&
ast_apply_ha(localaddr, &theirs)) {
- if (externexpire && (time(NULL) >= externexpire)) {
+ if (externexpire && time(NULL) >= externexpire) {
struct ast_hostent ahp;
struct hostent *hp;
@@ -1415,7 +1441,6 @@
pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */
if (fatal)
ast_set_flag(pkt, FLAG_FATAL);
-
if (pkt->timer_t1)
siptimer_a = pkt->timer_t1 * 2;
@@ -1482,10 +1507,11 @@
/*! \brief Cancel destruction of SIP dialog */
static int sip_cancel_destroy(struct sip_pvt *p)
{
- if (p->autokillid > -1)
+ if (p->autokillid > -1) {
ast_sched_del(sched, p->autokillid);
- append_history(p, "CancelDestroy", "");
- p->autokillid = -1;
+ append_history(p, "CancelDestroy", "");
+ p->autokillid = -1;
+ }
return 0;
}
@@ -1534,9 +1560,9 @@
/*! \brief Pretend to ack all packets */
static int __sip_pretend_ack(struct sip_pvt *p)
{
- struct sip_pkt *cur=NULL;
-
- while(p->packets) {
+ struct sip_pkt *cur = NULL;
+
+ while (p->packets) {
if (cur == p->packets) {
ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
return -1;
@@ -1562,16 +1588,14 @@
{
struct sip_pkt *cur;
int res = -1;
- char *msg = sip_methods[sipmethod].text;
-
- for (cur = p->packets; cur ; cur = cur->next) {
- if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) &&
- ((ast_test_flag(cur, FLAG_RESPONSE)) ||
- (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) {
+
+ for (cur = p->packets; cur; cur = cur->next) {
+ if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp &&
+ (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) {
/* this is our baby */
if (cur->retransid > -1) {
if (option_debug > 3 && sipdebug)
- ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, msg);
+ ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text);
ast_sched_del(sched, cur->retransid);
}
cur->retransid = -1;
@@ -1712,6 +1736,7 @@
char ipaddr[20];
char regseconds[20];
time_t nowtime;
+ const char *fc = fullcontact ? "fullcontact" : NULL;
time(&nowtime);
nowtime += expirey;
@@ -1719,10 +1744,9 @@
ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr);
snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
- if (fullcontact)
- ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, "fullcontact", fullcontact, NULL);
- else
- ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, NULL);
+ ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
+ "port", port, "regseconds", regseconds,
+ "username", username, fc, fullcontact, NULL); /* note fc _can_ be NULL */
}
/*! \brief Automatically add peer extension to dial plan */
@@ -1843,14 +1867,14 @@
if (!newpeername) { /* Did not find peer in realtime */
ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf);
ast_variables_destroy(var);
- return (struct sip_peer *) NULL;
+ return NULL;
}
/* Peer found in realtime, now build it in memory */
peer = build_peer(newpeername, var, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS));
if (!peer) {
ast_variables_destroy(var);
- return (struct sip_peer *) NULL;
+ return NULL;
}
if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
@@ -1947,18 +1971,16 @@
* realtime storage (defined in extconfig.conf) */
static struct sip_peer *find_user(const char *name, int realtime)
{
- struct sip_peer *u = NULL;
- u = ASTOBJ_CONTAINER_FIND(&userl,name);
- if (!u && realtime) {
+ struct sip_peer *u = ASTOBJ_CONTAINER_FIND(&userl,name);
+ if (!u && realtime)
u = realtime_user(name);
- }
return u;
}
/*! \brief Create address structure from peer reference */
static int create_addr_from_peer(struct sip_pvt *r, struct sip_peer *peer)
{
- int usenatroute;
+ int natflags;
if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) &&
(!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) {
@@ -1976,6 +1998,7 @@
r->vrtp = NULL;
}
r->prefs = peer->prefs;
+
if (ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)) {
ast_copy_flags(&r->t38.t38support, &peer->flags[1], SIP_PAGE2_T38SUPPORT);
r->t38.capability = global_t38_capability;
@@ -1996,21 +2019,21 @@
if (r->udptl)
ast_udptl_destroy(r->udptl);
}
- usenatroute = ast_test_flag(&r->flags[0], SIP_NAT) & SIP_NAT_ROUTE;
+ natflags = ast_test_flag(&r->flags[0], SIP_NAT) & SIP_NAT_ROUTE;
if (r->rtp) {
if (option_debug)
- ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", usenatroute);
- ast_rtp_setnat(r->rtp, usenatroute);
+ ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", natflags);
+ ast_rtp_setnat(r->rtp, natflags);
}
if (r->vrtp) {
if (option_debug)
- ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", usenatroute);
- ast_rtp_setnat(r->vrtp, usenatroute);
+ ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", natflags);
+ ast_rtp_setnat(r->vrtp, natflags);
}
if (r->udptl) {
if (option_debug)
- ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %d\n", usenatroute);
- ast_udptl_setnat(r->udptl, usenatroute);
+ ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %d\n", natflags);
+ ast_udptl_setnat(r->udptl, natflags);
}
ast_string_field_set(r, peername, peer->username);
ast_string_field_set(r, authname, peer->username);
@@ -2034,8 +2057,7 @@
if (ast_strlen_zero(r->tohost)) {
char iabuf[INET_ADDRSTRLEN];
- ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr.s_addr ? peer->addr.sin_addr : peer->defaddr.sin_addr);
-
+ ast_inet_ntoa(iabuf, sizeof(iabuf), r->sa.sin_addr);
ast_string_field_set(r, tohost, iabuf);
}
if (!ast_strlen_zero(peer->fromdomain))
@@ -2083,10 +2105,8 @@
ast_copy_string(peer, opeer, sizeof(peer));
port = strchr(peer, ':');
- if (port) {
- *port = '\0';
- port++;
- }
+ if (port)
+ *port++ = '\0';
dialog->sa.sin_family = AF_INET;
dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */
p = find_peer(peer, NULL, 1);
@@ -2101,10 +2121,7 @@
return -1;
hostn = peer;
- if (port)
- portno = atoi(port);
- else
- portno = DEFAULT_SIP_PORT;
+ portno = port ? atoi(port) : DEFAULT_SIP_PORT;
if (srvlookup) {
char service[MAXHOSTNAMELEN];
int tportno;
@@ -2141,6 +2158,7 @@
ast_mutex_lock(&p->lock);
p->initid = -1;
if (p->owner) {
+ /* XXX fails on possible deadlock */
if (!ast_mutex_trylock(&p->owner->lock)) {
ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name);
ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
@@ -2250,7 +2268,7 @@
/* Remove link from peer to subscription of MWI */
if (p->relatedpeer && p->relatedpeer->mwipvt)
- p->relatedpeer->mwipvt = (struct sip_pvt *) NULL;
+ p->relatedpeer->mwipvt = NULL;
if (dumphistory)
sip_dump_history(p);
@@ -2320,9 +2338,8 @@
/* remove all current packets in this dialog */
while((cp = p->packets)) {
p->packets = p->packets->next;
- if (cp->retransid > -1) {
+ if (cp->retransid > -1)
ast_sched_del(sched, cp->retransid);
- }
free(cp);
}
if (p->chanvars) {
@@ -2536,10 +2553,9 @@
31 normal unspecified 480 Temporarily unavailable
\endverbatim
*/
-static char *hangup_cause2sip(int cause)
-{
- switch(cause)
- {
+static const char *hangup_cause2sip(int cause)
+{
+ switch (cause) {
case AST_CAUSE_UNALLOCATED: /* 1 */
case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */
case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */
@@ -2648,10 +2664,10 @@
update_call_counter(p, INC_CALL_LIMIT);
}
} else { /* Incoming call, not up */
- char *res;
- if (ast->hangupcause && ((res = hangup_cause2sip(ast->hangupcause)))) {
+ const char *res;
+ if (ast->hangupcause && (res = hangup_cause2sip(ast->hangupcause)))
transmit_response_reliable(p, res, &p->initreq);
- } else
+ else
transmit_response_reliable(p, "603 Declined", &p->initreq);
}
} else { /* Call is in UP state, send BYE */
@@ -2795,16 +2811,25 @@
Basically update any ->owner links */
static int sip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
{
- struct sip_pvt *p = newchan->tech_pvt;
+ int ret = -1;
+ struct sip_pvt *p;
+
+ if (!newchan || !newchan->tech_pvt) {
+ ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name);
+ return -1;
+ }
+ p = newchan->tech_pvt;
+
ast_mutex_lock(&p->lock);
- if (p->owner != oldchan) {
+ if (p->owner != oldchan)
ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
- ast_mutex_unlock(&p->lock);
- return -1;
- }
- p->owner = newchan;
+ else {
+ p->owner = newchan;
+ append_history(p, "Masq", "Old channel: %s\n", oldchan->name);
+ ret = 0;
+ }
ast_mutex_unlock(&p->lock);
- return 0;
+ return ret;
}
/*! \brief Send DTMF character on SIP channel
@@ -3059,26 +3084,20 @@
if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))
tmp->cid.cid_dnid = ast_strdup(i->exten);
tmp->priority = 1;
- if (!ast_strlen_zero(i->uri)) {
+ if (!ast_strlen_zero(i->uri))
pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri);
- }
- if (!ast_strlen_zero(i->domain)) {
+ if (!ast_strlen_zero(i->domain))
pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain);
- }
- if (!ast_strlen_zero(i->useragent)) {
+ if (!ast_strlen_zero(i->useragent))
pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent);
- }
- if (!ast_strlen_zero(i->callid)) {
+ if (!ast_strlen_zero(i->callid))
pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid);
- }
ast_setstate(tmp, state);
- if (state != AST_STATE_DOWN) {
- if (ast_pbx_start(tmp)) {
- ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
- tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
- ast_hangup(tmp);
- tmp = NULL;
- }
+ if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {
+ ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
+ tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
+ ast_hangup(tmp);
+ tmp = NULL;
}
/* Set channel variables for this call from configuration */
for (v = i->chanvars ; v ; v = v->next)
@@ -3098,52 +3117,64 @@
}
/*! \brief Reads one line of SIP message body */
-static char* get_sdp_by_line(char* line, char *name, int nameLen)
-{
- if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') {
+static const char* get_sdp_by_line(const char* line, const char *name, int nameLen)
+{
+ if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=')
return ast_skip_blanks(line + nameLen + 1);
- }
return "";
}
-/*! \brief Gets all kind of SIP message bodies, including SDP,
- but the name wrongly applies _only_ sdp */
-static char *get_sdp(struct sip_request *req, char *name)
-{
- int x;
+/*! \brief get_sdp_iterate: lookup 'name' in the request starting
+ * at the 'start' line. Returns the matching line, and 'start'
+ * is updated with the next line number.
+ */
+static const char* get_sdp_iterate(int* start,
+ struct sip_request *req, const char *name)
+{
int len = strlen(name);
- char *r;
-
- for (x = 0; x < req->lines; x++) {
- r = get_sdp_by_line(req->line[x], name, len);
+
+ while (*start < req->lines) {
+ const char *r = get_sdp_by_line(req->line[(*start)++], name, len);
[... 3567 lines stripped ...]
More information about the asterisk-commits
mailing list