[asterisk-commits] branch oej/sipregister r17407 - in
/team/oej/sipregister: ./ apps/ channels/ ...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Tue Apr 4 12:18:29 MST 2006
Author: oej
Date: Tue Apr 4 14:18:16 2006
New Revision: 17407
URL: http://svn.digium.com/view/asterisk?rev=17407&view=rev
Log:
Update
Modified:
team/oej/sipregister/ (props changed)
team/oej/sipregister/acl.c
team/oej/sipregister/app.c
team/oej/sipregister/apps/app_channelredirect.c
team/oej/sipregister/apps/app_rpt.c
team/oej/sipregister/channels/chan_agent.c
team/oej/sipregister/channels/chan_oss.c
team/oej/sipregister/channels/chan_sip.c
team/oej/sipregister/configs/http.conf.sample
team/oej/sipregister/configs/oss.conf.sample
team/oej/sipregister/configs/sip.conf.sample
team/oej/sipregister/doc/ip-tos.txt
team/oej/sipregister/include/asterisk/module.h
team/oej/sipregister/pbx/pbx_dundi.c
team/oej/sipregister/res/res_smdi.c
team/oej/sipregister/slinfactory.c
Propchange: team/oej/sipregister/
------------------------------------------------------------------------------
automerge = http://edvina.net/training/
Propchange: team/oej/sipregister/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Apr 4 14:18:16 2006
@@ -1,1 +1,1 @@
-/trunk:1-15466
+/trunk:1-15614
Modified: team/oej/sipregister/acl.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipregister/acl.c?rev=17407&r1=17406&r2=17407&view=diff
==============================================================================
--- team/oej/sipregister/acl.c (original)
+++ team/oej/sipregister/acl.c Tue Apr 4 14:18:16 2006
@@ -20,7 +20,7 @@
*
* \brief Various sorts of access control
*
- * \author Mark Spencer <markster at digium.com>
+ * \author Mark Spencer <markster at digium.com>
*/
#include <stdio.h>
@@ -136,7 +136,7 @@
if (prev)
prev->next = link; /* Link previous to this object */
- if (!ret)
+ if (!ret)
ret = link; /* Save starting point */
start = start->next; /* Go to next object */
@@ -153,7 +153,7 @@
struct ast_ha *prev = NULL;
struct ast_ha *ret;
int x, z;
- unsigned int y;
+ unsigned int y;
ret = path;
while (path) {
@@ -313,7 +313,7 @@
else
return -1;
- ast_log(LOG_WARNING, "tos value %s is deprecated. See doc/ip-tos.txt for more information.", value);
+ ast_log(LOG_WARNING, "TOS value %s is deprecated. Please see doc/ip-tos.txt for more information.\n", value);
return 0;
}
@@ -349,7 +349,7 @@
}
/* iface is the interface (e.g. eth0); address is the return value */
-int ast_lookup_iface(char *iface, struct in_addr *address)
+int ast_lookup_iface(char *iface, struct in_addr *address)
{
int mysock, res = 0;
struct my_ifreq ifreq;
@@ -428,4 +428,3 @@
return 0;
return -1;
}
-
Modified: team/oej/sipregister/app.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipregister/app.c?rev=17407&r1=17406&r2=17407&view=diff
==============================================================================
--- team/oej/sipregister/app.c (original)
+++ team/oej/sipregister/app.c Tue Apr 4 14:18:16 2006
@@ -79,7 +79,7 @@
else
ast_log(LOG_NOTICE,"Huh....? no dial for indications?\n");
- for (x = strlen(collect); strlen(collect) < maxlen; ) {
+ for (x = strlen(collect); x < maxlen; ) {
res = ast_waitfordigit(chan, timeout);
if (!ast_ignore_pattern(context, collect))
ast_playtones_stop(chan);
@@ -94,12 +94,8 @@
break;
}
}
- if (res >= 0) {
- if (ast_exists_extension(chan, context, collect, 1, chan->cid.cid_num))
- res = 1;
- else
- res = 0;
- }
+ if (res >= 0)
+ res = ast_exists_extension(chan, context, collect, 1, chan->cid.cid_num) ? 1 : 0;
return res;
}
@@ -1153,9 +1149,10 @@
char *fs;
int res;
int fd;
+ int lp = strlen(path);
time_t start;
- if (!(s = alloca(strlen(path) + 10)) || !(fs = alloca(strlen(path) + 20))) {
+ if (!(s = alloca(lp + 10)) || !(fs = alloca(lp + 20))) {
ast_log(LOG_WARNING, "Out of memory!\n");
return AST_LOCK_FAILURE;
}
@@ -1510,7 +1507,7 @@
if (fd < 0) {
ast_log(LOG_WARNING, "Cannot open file '%s' for reading: %s\n", filename, strerror(errno));
return NULL;
- }
+ }
if ((output = ast_malloc(count))) {
res = read(fd, output, count - 1);
if (res == count - 1) {
@@ -1540,14 +1537,13 @@
s = optstr;
while (*s) {
- curarg = *s++ & 0x7f;
+ curarg = *s++ & 0x7f; /* the array (in app.h) has 128 entries */
ast_set_flag(flags, options[curarg].flag);
argloc = options[curarg].arg_index;
if (*s == '(') {
/* Has argument */
arg = ++s;
- while (*s && (*s != ')'))
- s++;
+ s = strchr(s, ')');
if (*s) {
if (argloc)
args[argloc - 1] = arg;
Modified: team/oej/sipregister/apps/app_channelredirect.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipregister/apps/app_channelredirect.c?rev=17407&r1=17406&r2=17407&view=diff
==============================================================================
--- team/oej/sipregister/apps/app_channelredirect.c (original)
+++ team/oej/sipregister/apps/app_channelredirect.c Tue Apr 4 14:18:16 2006
@@ -47,8 +47,6 @@
static char *descrip =
"ChannelRedirect(channel|[[context|]extension|]priority):\n"
" Sends the specified channel to the specified extension priority\n";
-
-STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
Modified: team/oej/sipregister/apps/app_rpt.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipregister/apps/app_rpt.c?rev=17407&r1=17406&r2=17407&view=diff
==============================================================================
--- team/oej/sipregister/apps/app_rpt.c (original)
+++ team/oej/sipregister/apps/app_rpt.c Tue Apr 4 14:18:16 2006
@@ -260,7 +260,6 @@
struct ast_config *cfg;
-STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
#define MSWAIT 200
Modified: team/oej/sipregister/channels/chan_agent.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipregister/channels/chan_agent.c?rev=17407&r1=17406&r2=17407&view=diff
==============================================================================
--- team/oej/sipregister/channels/chan_agent.c (original)
+++ team/oej/sipregister/channels/chan_agent.c Tue Apr 4 14:18:16 2006
@@ -1552,18 +1552,15 @@
static char *complete_agent_logoff_cmd(const char *line, const char *word, int pos, int state)
{
- struct agent_pvt *p;
- char name[AST_MAX_AGENT];
- int which = 0;
-
if (pos == 2) {
+ struct agent_pvt *p;
+ char name[AST_MAX_AGENT];
+ int which = 0, len = strlen(word);
+
AST_LIST_TRAVERSE(&agents, p, list) {
snprintf(name, sizeof(name), "Agent/%s", p->agent);
- if (!strncasecmp(word, name, strlen(word))) {
- if (++which > state) {
- return ast_strdup(name);
- }
- }
+ if (!strncasecmp(word, name, len) && ++which > state)
+ return ast_strdup(name);
}
} else if (pos == 3 && state == 0) {
return ast_strdup("soft");
Modified: team/oej/sipregister/channels/chan_oss.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipregister/channels/chan_oss.c?rev=17407&r1=17406&r2=17407&view=diff
==============================================================================
--- team/oej/sipregister/channels/chan_oss.c (original)
+++ team/oej/sipregister/channels/chan_oss.c Tue Apr 4 14:18:16 2006
@@ -94,24 +94,51 @@
START_CONFIG
[general]
-; general config options, default values are shown
-; all but debug can go also in the device-specific sections.
-; debug=0x0 ; misc debug flags, default is 0
+ ; General config options, with default values shown.
+ ; You should use one section per device, with [general] being used
+ ; for the first device and also as a template for other devices.
+ ;
+ ; All but 'debug' can go also in the device-specific sections.
+ ;
+ ; debug = 0x0 ; misc debug flags, default is 0
+
+ ; Set the device to use for I/O
+ ; device = /dev/dsp
+
+ ; Optional mixer command to run upon startup (e.g. to set
+ ; volume levels, mutes, etc.
+ ; mixer =
+
+ ; Software mic volume booster (or attenuator), useful for sound
+ ; cards or microphones with poor sensitivity. The volume level
+ ; is in dB, ranging from -20.0 to +20.0
+ ; boost = n ; mic volume boost in dB
+
+ ; Set the callerid for outgoing calls
+ ; callerid = John Doe <555-1234>
+
+ ; autoanswer = no ; no autoanswer on call
+ ; autohangup = yes ; hangup when other party closes
+ ; extension = s ; default extension to call
+ ; context = default ; default context for outgoing calls
+ ; language = "" ; default language
+
+ ; If you set overridecontext to 'yes', then the whole dial string
+ ; will be interpreted as an extension, which is extremely useful
+ ; to dial SIP, IAX and other extensions which use the '@' character.
+ ; The default is 'no' just for backward compatibility, but the
+ ; suggestion is to change it.
+ ; overridecontext = no ; if 'no', the last @ will start the context
+ ; if 'yes' the whole string is an extension.
+
+ ; low level device parameters in case you have problems with the
+ ; device driver on your operating system. You should not touch these
+ ; unless you know what you are doing.
+ ; queuesize = 10 ; frames in device driver
+ ; frags = 8 ; argument to SETFRAGMENT
[card1]
-; autoanswer = no ; no autoanswer on call
-; autohangup = yes ; hangup when other party closes
-; extension=s ; default extension to call
-; context=default ; default context
-; language="" ; default language
-; overridecontext=yes ; the whole dial string is considered an extension.
- ; if no, the last @ will start the context
-
-; device=/dev/dsp ; device to open
-; mixer="-f /dev/mixer0 pcm 80 ; mixer command to run on start
-; queuesize=10 ; frames in device driver
-; frags=8 ; argument to SETFRAGMENT
-; boost = n ; mic volume boost in dB
+ ; device = /dev/dsp1 ; alternate device
END_CONFIG
Modified: team/oej/sipregister/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/sipregister/channels/chan_sip.c?rev=17407&r1=17406&r2=17407&view=diff
==============================================================================
--- team/oej/sipregister/channels/chan_sip.c (original)
+++ team/oej/sipregister/channels/chan_sip.c Tue Apr 4 14:18:16 2006
@@ -188,7 +188,8 @@
XPIDF_XML,
DIALOG_INFO_XML,
CPIM_PIDF_XML,
- PIDF_XML
+ PIDF_XML,
+ MWI_NOTIFICATION
};
static const struct cfsubscription_types {
@@ -202,7 +203,8 @@
{ DIALOG_INFO_XML, "dialog", "application/dialog-info+xml", "dialog-info+xml" },
{ CPIM_PIDF_XML, "presence", "application/cpim-pidf+xml", "cpim-pidf+xml" }, /* RFC 3863 */
{ PIDF_XML, "presence", "application/pidf+xml", "pidf+xml" }, /* RFC 3863 */
- { XPIDF_XML, "presence", "application/xpidf+xml", "xpidf+xml" } /* Pre-RFC 3863 with MS additions */
+ { XPIDF_XML, "presence", "application/xpidf+xml", "xpidf+xml" }, /* Pre-RFC 3863 with MS additions */
+ { MWI_NOTIFICATION, "message-summary", "application/simple-message-summary", "mwi" } /* Mailbox notification */
};
enum sipmethod {
@@ -410,7 +412,7 @@
static int global_regattempts_max; /*!< Registration attempts before giving up */
static int global_allowguest; /*!< allow unauthenticated users/peers to connect? */
static int global_allowsubscribe; /*!< Flag for disabling ALL subscriptions, this is FALSE only if all peers are FALSE
- the global setting is in globals_flag_page2 */
+ the global setting is in globals_flags[1] */
static int global_mwitime; /*!< Time between MWI checks for peers */
static int global_tos_sip; /*!< IP type of service for SIP packets */
static int global_tos_audio; /*!< IP type of service for audio RTP packets */
@@ -618,7 +620,8 @@
#define SIP_PAGE2_VIDEOSUPPORT (1 << 9)
#define SIP_PAGE2_ALLOWSUBSCRIBE (1 << 10) /*!< Allow subscriptions from this peer? */
#define SIP_PAGE2_ALLOWOVERLAP (1 << 11) /*!< Allow overlap dialing ? */
-#define SIP_PAGE2_PEER_REGISTER (1 << 12) /*!< Whether we register or not */
+#define SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 12) /*!< Only issue MWI notification if subscribed to */
+#define SIP_PAGE2_PEER_REGISTER (1 << 13) /*!< Whether we register or not */
#define SIP_PAGE2_FLAGS_TO_COPY \
@@ -735,7 +738,8 @@
struct ast_dsp *vad; /*!< Voice Activation Detection dsp */
- struct sip_peer *peerpoke; /*!< If this dialog is to poke a peer, which one */
+ struct sip_peer *relatedpeer; /*!< If this dialog is related to a peer, which one
+ Used in peerpoke, mwi subscriptions */
struct sip_registry *registry; /*!< If this is a REGISTER dialog, to which registry
If this is an INVITE, to which registry */
struct ast_rtp *rtp; /*!< RTP Session */
@@ -848,6 +852,7 @@
struct ast_ha *ha; /*!< Access control list */
struct ast_variable *chanvars; /*!< Variables to set for channel created by user */
struct sip_registry *registry; /*!< If this peer registers with outside service */
+ struct sip_pvt *mwipvt; /*!< Subscription for MWI */
int lastmsg;
};
@@ -987,6 +992,8 @@
static int find_sip_method(char *msg);
static unsigned int parse_sip_options(struct sip_pvt *pvt, char *supported);
static void sip_destroy(struct sip_pvt *p);
+static void sip_destroy_peer(struct sip_peer *peer);
+static void sip_destroy_user(struct sip_user *user);
static void parse_request(struct sip_request *req);
static char *get_header(struct sip_request *req, const char *name);
static void copy_request(struct sip_request *dst,struct sip_request *src);
@@ -999,6 +1006,8 @@
static void set_peer_defaults(struct sip_peer *peer);
static struct sip_peer *temp_peer(const char *name);
static void sip_registry_destroy(struct sip_registry *reg);
+static int sip_send_mwi_to_peer(struct sip_peer *peer);
+static int sip_scheddestroy(struct sip_pvt *p, int ms);
/*----- RTP interface functions */
@@ -1716,6 +1725,11 @@
/* Delete it, it needs to disappear */
if (peer->call)
sip_destroy(peer->call);
+
+ if (peer->mwipvt) { /* We have an active subscription, delete it */
+ sip_destroy(peer->mwipvt);
+ }
+
if (peer->chanvars) {
ast_variables_destroy(peer->chanvars);
peer->chanvars = NULL;
@@ -2208,6 +2222,10 @@
if (sip_debug_test_pvt(p) || option_debug > 2)
ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
+
+ /* Remove link from peer to subscription of MWI */
+ if (p->relatedpeer && p->relatedpeer->mwipvt)
+ p->relatedpeer->mwipvt = (struct sip_pvt *) NULL;
if (dumphistory)
sip_dump_history(p);
@@ -5321,7 +5339,6 @@
case AST_EXTENSION_REMOVED:
add_header(&req, "Subscription-State", "terminated;reason=noresource");
break;
- break;
default:
if (p->expiry)
add_header(&req, "Subscription-State", "active");
@@ -5402,6 +5419,12 @@
ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", !ast_strlen_zero(vmexten) ? vmexten : default_vmexten, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain);
ast_build_string(&t, &maxbytes, "Voice-Message: %d/%d (0/0)\r\n", newmsgs, oldmsgs);
+ if (p->subscribed) {
+ if (p->expiry)
+ add_header(&req, "Subscription-State", "active");
+ else /* Expired */
+ add_header(&req, "Subscription-State", "terminated;reason=timeout");
+ }
if (t > tmp + sizeof(tmp))
ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n");
@@ -6656,7 +6679,8 @@
update_peer(peer, p->expiry);
/* Say OK and ask subsystem to retransmit msg counter */
transmit_response_with_date(p, "200 OK", req);
- peer->lastmsgssent = -1;
+ if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY))
+ peer->lastmsgssent = -1;
res = 0;
break;
}
@@ -7226,7 +7250,7 @@
\return 0 on success, -1 on failure, and 1 on challenge sent
-2 on authentication error from chedck_auth()
*/
-static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin, int ignore, char *mailbox, int mailboxlen)
+static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin, int ignore, struct sip_peer **authpeer)
{
struct sip_user *user = NULL;
struct sip_peer *peer = NULL;
@@ -7299,7 +7323,7 @@
if (p->registry && p->registry->peer) /* We know this peer from registry */
peer = p->registry->peer;
- if (!mailbox && !peer) /* If it's a mailbox SUBSCRIBE, don't check users */
+ if (!authpeer && !peer) /* If it's a mailbox SUBSCRIBE, don't check users */
user = find_user(of, 1);
/* Find user based on user name in the from header */
@@ -7395,7 +7419,7 @@
ast_verbose("Found user '%s'\n", user->name);
} else {
if (user) {
- if (!mailbox && debug)
+ if (!authpeer && debug)
ast_verbose("Found user '%s', but fails host access\n", user->name);
ASTOBJ_UNREF(user,sip_destroy_user);
}
@@ -7478,8 +7502,10 @@
p->chanvars = tmpvar;
}
}
- if (mailbox)
- snprintf(mailbox, mailboxlen, ",%s,", peer->mailbox);
+ if (authpeer) {
+ (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */
+ }
+
if (!ast_strlen_zero(peer->username)) {
ast_string_field_set(p, username, peer->username);
/* Use the default username for authentication on outbound calls */
@@ -7550,7 +7576,7 @@
*/
static int check_user(struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin, int ignore)
{
- return check_user_full(p, req, sipmethod, uri, reliable, sin, ignore, NULL, 0);
+ return check_user_full(p, req, sipmethod, uri, reliable, sin, ignore, NULL);
}
/*! \brief Get text out of a SIP MESSAGE packet */
@@ -8643,7 +8669,7 @@
static int __sip_show_channels(int fd, int argc, char *argv[], int subscriptions)
{
-#define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s\n"
+#define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n"
#define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n"
#define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s\n"
struct sip_pvt *cur;
@@ -8655,8 +8681,8 @@
cur = iflist;
if (!subscriptions)
ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message");
- else
- ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type");
+ else
+ ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox");
while (cur) {
if (cur->subscribed == NONE && !subscriptions) {
ast_cli(fd, FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr),
@@ -8672,8 +8698,12 @@
if (cur->subscribed != NONE && subscriptions) {
ast_cli(fd, FORMAT3, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr),
ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username,
- cur->callid, cur->exten, ast_extension_state2str(cur->laststate),
- subscription_type2str(cur->subscribed));
+ cur->callid,
+ cur->subscribed == MWI_NOTIFICATION ? "--" : cur->exten,
+ cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate),
+ subscription_type2str(cur->subscribed),
+ cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>"
+);
numchans++;
}
cur = cur->next;
@@ -10053,7 +10083,7 @@
if (resp != 100) {
int statechanged = 0;
int newstate = 0;
- peer = p->peerpoke;
+ peer = p->relatedpeer;
gettimeofday(&tv, NULL);
pingtime = ast_tvdiff_ms(tv, peer->ps);
if (pingtime < 1)
@@ -10133,7 +10163,7 @@
gettag(req, "To", tag, sizeof(tag));
ast_string_field_set(p, theirtag, tag);
}
- if (p->peerpoke) {
+ if (p->relatedpeer && p->method == SIP_OPTIONS) {
/* We don't really care what the response is, just that it replied back.
Well, as long as it's not a 100 response... since we might
need to hang around for something more "definitive" */
@@ -11023,6 +11053,10 @@
int gotdest;
int res = 0;
int firststate = AST_EXTENSION_REMOVED;
+ struct sip_peer *authpeer = NULL;
+ char *event = get_header(req, "Event"); /* Get Event package name */
+ char *accept = get_header(req, "Accept");
+ char *eventparam;
if (p->initreq.headers) {
/* We already have a dialog */
@@ -11033,9 +11067,11 @@
/* Do not destroy session, since we will break the call if we do */
ast_log(LOG_DEBUG, "Got a subscription within the context of another call, can't handle that - %s (Method %s)\n", p->callid, sip_methods[p->initreq.method].text);
return 0;
- } else {
- if (debug)
+ } else if (debug) {
+ if (p->subscribed != NONE)
ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid);
+ else
+ ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid);
}
}
@@ -11048,10 +11084,11 @@
return 0;
}
- if (!ignore && !p->initreq.headers) {
+ if (!ignore && !p->initreq.headers) { /* Set up dialog, new subscription */
/* Use this as the basis */
if (debug)
- ast_verbose("Using latest SUBSCRIBE request as basis request\n");
+ ast_verbose("Creating new subscription\n");
+
/* This call is no longer outgoing if it ever was */
ast_clear_flag(&p->flags[0], SIP_OUTGOING);
copy_request(&p->initreq, req);
@@ -11059,113 +11096,96 @@
} else if (debug && ignore)
ast_verbose("Ignoring this SUBSCRIBE request\n");
- if (!p->lastinvite) {
- char mailboxbuf[256]="";
- char *mailbox = NULL;
- int mailboxsize = 0;
- char *eventparam;
-
- char *event = get_header(req, "Event"); /* Get Event package name */
- char *accept = get_header(req, "Accept");
-
- /* Find parameters to Event: header value and remove them for now */
- eventparam = strchr(event, ';');
- if (eventparam) {
- *eventparam = '\0';
- eventparam++;
- }
-
- if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) {
- mailbox = mailboxbuf;
- mailboxsize = sizeof(mailboxbuf);
- }
- /* Handle authentication if this is our first subscribe */
- res = check_user_full(p, req, SIP_SUBSCRIBE, e, XMIT_UNRELIABLE, sin, ignore, mailbox, mailboxsize);
- if (res) {
- if (res < 0) {
- ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
+
+
+ /* Find parameters to Event: header value and remove them for now */
+ if ((eventparam = strchr(event, ';')))
+ *eventparam++ = '\0';
+
+ /* Handle authentication if this is our first subscribe */
+ res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, ignore, &authpeer);
+ if (res) {
+ if (res < 0) {
+ ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
+ ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
+ }
+ return 0;
+ }
+
+ /* Check if this user/peer is allowed to subscribe at all */
+ if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
+ transmit_response(p, "403 Forbidden (policy)", req);
+ ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
+ return 0;
+ }
+
+ /* Initialize the context if it hasn't been already */
+ if (!ast_strlen_zero(p->subscribecontext))
+ ast_string_field_set(p, context, p->subscribecontext);
+ else if (ast_strlen_zero(p->context))
+ ast_string_field_set(p, context, default_context);
+
+ /* Get destination right away */
+ gotdest = get_destination(p, NULL);
+ build_contact(p);
+ if (gotdest) {
+ transmit_response(p, "404 Not Found", req);
+ ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
+ return 0;
+ } else {
+
+ /* Initialize tag for new subscriptions */
+ if (ast_strlen_zero(p->tag))
+ make_our_tag(p->tag, sizeof(p->tag));
+
+ if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
+
+ /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
+ if (strstr(accept, "application/pidf+xml")) {
+ p->subscribed = PIDF_XML; /* RFC 3863 format */
+ } else if (strstr(accept, "application/dialog-info+xml")) {
+ p->subscribed = DIALOG_INFO_XML;
+ /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
+ } else if (strstr(accept, "application/cpim-pidf+xml")) {
+ p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */
+ } else if (strstr(accept, "application/xpidf+xml")) {
+ p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
+ } else if (strstr(p->useragent, "Polycom")) {
+ p->subscribed = XPIDF_XML; /* Polycoms subscribe for "event: dialog" but don't include an "accept:" header */
+ } else {
+ /* Can't find a format for events that we know about */
+ transmit_response(p, "489 Bad Event", req);
+ ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
+ return 0;
+ }
+ } else if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) {
+ /* Looks like they actually want a mailbox status
+ This version of Asterisk supports mailbox subscriptions
+ The subscribed URI needs to exist in the dial plan
+ In most devices, this is configurable to the voicemailmain extension you use
+ */
+ if (!authpeer || ast_strlen_zero(authpeer->mailbox)) {
+ transmit_response(p, "404 Not found (no mailbox)", req);
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- }
- return 0;
- }
-
- /* Check if this user/peer is allowed to subscribe at all */
- if (! ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
- transmit_response(p, "403 Forbidden (policy)", req);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- return 0;
- }
-
- /* Initialize the context if it hasn't been already */
- if (!ast_strlen_zero(p->subscribecontext))
- ast_string_field_set(p, context, p->subscribecontext);
- else if (ast_strlen_zero(p->context))
- ast_string_field_set(p, context, default_context);
- /* Get destination right away */
- gotdest = get_destination(p, NULL);
- build_contact(p);
- if (gotdest) {
- transmit_response(p, "404 Not Found", req);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- } else {
-
- /* Initialize tag for new subscriptions */
- if (ast_strlen_zero(p->tag))
- make_our_tag(p->tag, sizeof(p->tag));
-
- if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
-
- /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
- if (strstr(accept, "application/pidf+xml")) {
- p->subscribed = PIDF_XML; /* RFC 3863 format */
- } else if (strstr(accept, "application/dialog-info+xml")) {
- p->subscribed = DIALOG_INFO_XML;
- /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
- } else if (strstr(accept, "application/cpim-pidf+xml")) {
- p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */
- } else if (strstr(accept, "application/xpidf+xml")) {
- p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
- } else if (strstr(p->useragent, "Polycom")) {
- p->subscribed = XPIDF_XML; /* Polycoms subscribe for "event: dialog" but don't include an "accept:" header */
- } else {
- /* Can't find a format for events that we know about */
- transmit_response(p, "489 Bad Event", req);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- return 0;
- }
- } else if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) {
- /* Looks like they actually want a mailbox status */
-
- /* At this point, we should check if they subscribe to a mailbox that
- has the same extension as the peer or the mailbox id. If we configure
- the context to be the same as a SIP domain, we could check mailbox
- context as well. To be able to securely accept subscribes on mailbox
- IDs, not extensions, we need to check the digest auth user to make
- sure that the user has access to the mailbox.
-
- Since we do not act on this subscribe anyway, we might as well
- accept any authenticated peer with a mailbox definition in their
- config section.
-
- */
- if (!ast_strlen_zero(mailbox)) {
- transmit_response(p, "200 OK", req);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- } else {
- transmit_response(p, "404 Not found", req);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- }
- return 0;
- } else { /* At this point, Asterisk does not understand the specified event */
- transmit_response(p, "489 Bad Event", req);
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
+ ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name);
return 0;
}
- if (p->subscribed != NONE)
- p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p);
- }
+
+ p->subscribed = MWI_NOTIFICATION;
+ if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */
+ /* We only allow one subscription per peer */
+ sip_destroy(authpeer->mwipvt);
+ authpeer->mwipvt = p; /* Link from peer to pvt */
+ p->relatedpeer = authpeer; /* Link from pvt to peer */
+ } else { /* At this point, Asterisk does not understand the specified event */
+ transmit_response(p, "489 Bad Event", req);
+ if (option_debug > 1)
+ ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event);
+ ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
+ return 0;
+ }
+ if (p->subscribed != MWI_NOTIFICATION)
+ p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p);
}
if (!ignore && p)
@@ -11179,54 +11199,69 @@
if (p->expiry < min_expiry && p->expiry > 0)
p->expiry = min_expiry;
- if (sipdebug || option_debug > 1)
- ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
+ if (sipdebug || option_debug > 1) {
+ if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer)
+ ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox);
+ else
+ ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
+ }
if (p->autokillid > -1)
sip_cancel_destroy(p); /* Remove subscription expiry for renewals */
if (p->expiry > 0)
sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */
- if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
- ast_log(LOG_ERROR, "Got SUBSCRIBE for extensions without hint. Please add hint to %s in context %s\n", p->exten, p->context);
- transmit_response(p, "404 Not found", req);
- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
- return 0;
+ if (p->subscribed == MWI_NOTIFICATION) {
+ transmit_response(p, "200 OK", req);
+ if (p->relatedpeer) { /* Send first notification */
+ ASTOBJ_WRLOCK(p->relatedpeer);
+ sip_send_mwi_to_peer(p->relatedpeer);
+ ASTOBJ_UNLOCK(p->relatedpeer);
+ }
} else {
- struct sip_pvt *p_old;
-
- transmit_response(p, "200 OK", req);
- transmit_state_notify(p, firststate, 1); /* Send first notification */
- append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate));
-
- /* remove any old subscription from this peer for the same exten/context,
- as the peer has obviously forgotten about it and it's wasteful to wait
- for it to expire and send NOTIFY messages to the peer only to have them
- ignored (or generate errors)
- */
- ast_mutex_lock(&iflock);
- for (p_old = iflist; p_old; p_old = p_old->next) {
- if (p_old == p)
- continue;
- if (p_old->initreq.method != SIP_SUBSCRIBE)
- continue;
- if (p_old->subscribed == NONE)
- continue;
- ast_mutex_lock(&p_old->lock);
- if (!strcmp(p_old->username, p->username)) {
- if (!strcmp(p_old->exten, p->exten) &&
- !strcmp(p_old->context, p->context)) {
- ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY);
- ast_mutex_unlock(&p_old->lock);
- break;
+ if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
+ ast_log(LOG_ERROR, "Got SUBSCRIBE for extension without hint. Please add hint to %s in context %s\n", p->exten, p->context);
+ transmit_response(p, "404 Not found", req);
+ ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
+ return 0;
+ } else {
+ struct sip_pvt *p_old;
+
+ transmit_response(p, "200 OK", req);
+ transmit_state_notify(p, firststate, 1); /* Send first notification */
+ append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate));
+
+ /* remove any old subscription from this peer for the same exten/context,
+ as the peer has obviously forgotten about it and it's wasteful to wait
+ for it to expire and send NOTIFY messages to the peer only to have them
+ ignored (or generate errors)
+ */
+ ast_mutex_lock(&iflock);
+ for (p_old = iflist; p_old; p_old = p_old->next) {
+ if (p_old == p)
+ continue;
+ if (p_old->initreq.method != SIP_SUBSCRIBE)
+ continue;
+ if (p_old->subscribed == NONE)
+ continue;
+ ast_mutex_lock(&p_old->lock);
+ if (!strcmp(p_old->username, p->username)) {
+ if (!strcmp(p_old->exten, p->exten) &&
+ !strcmp(p_old->context, p->context)) {
+ ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY);
+ ast_mutex_unlock(&p_old->lock);
+ break;
+ }
}
+ ast_mutex_unlock(&p_old->lock);
}
- ast_mutex_unlock(&p_old->lock);
+ ast_mutex_unlock(&iflock);
}
- ast_mutex_unlock(&iflock);
}
if (!p->expiry)
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
}
+ if (authpeer)
+ ASTOBJ_UNREF(authpeer, sip_destroy_peer);
return 1;
}
@@ -11561,26 +11596,54 @@
return 0;
}
- if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY)))
- return -1;
peer->lastmsgssent = ((newmsgs << 8) | (oldmsgs));
- if (create_addr_from_peer(p, peer)) {
- /* Maybe they're not registered, etc. */
- sip_destroy(p);
- return 0;
- }
- /* Recalculate our side, and recalculate Call ID */
- if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
- memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
- build_via(p);
- build_callid_pvt(p);
+
+ if (peer->mwipvt) {
+ /* Base message on subscription */
+ p = peer->mwipvt;
+ } else {
+ /* Build temporary dialog for this message */
+ if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY)))
+ return -1;
+ if (create_addr_from_peer(p, peer)) {
+ /* Maybe they're not registered, etc. */
+ sip_destroy(p);
+ return 0;
+ }
+ /* Recalculate our side, and recalculate Call ID */
+ if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
+ memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
+ build_via(p);
+ build_callid_pvt(p);
+ /* Destroy this session after 32 secs */
+ sip_scheddestroy(p, 32000);
+ }
/* Send MWI */
ast_set_flag(&p->flags[0], SIP_OUTGOING);
transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
- sip_scheddestroy(p, 15000);
return 0;
}
+
+/*! \brief Check whether peer needs a new MWI notification check */
+static int does_peer_need_mwi(struct sip_peer *peer)
+{
+ time_t t;
+
+ if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
+ !peer->mwipvt) { /* We don't have a subscription */
+ time(&peer->lastmsgcheck); /* Reset timer */
+ return FALSE;
+ }
+
+ time(&t);
+
+ if (!ast_strlen_zero(peer->mailbox) && ((t - peer->lastmsgcheck) > global_mwitime))
+ return TRUE;
+
+ return FALSE;
+}
+
/*! \brief The SIP monitoring thread
\note This thread monitors all the SIP sessions and peers that needs notification of mwi
@@ -11684,7 +11747,7 @@
curpeernum = 0;
peer = NULL;
ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do {
- if ((curpeernum > lastpeernum) && !ast_strlen_zero(iterator->mailbox) && ((t - iterator->lastmsgcheck) > global_mwitime)) {
+ if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) {
fastrestart = TRUE;
lastpeernum = curpeernum;
peer = ASTOBJ_REF(iterator);
@@ -11809,7 +11872,7 @@
if (peer->pokeexpire > -1)
ast_sched_del(sched, peer->pokeexpire);
- p->peerpoke = peer;
+ p->relatedpeer = peer;
ast_set_flag(&p->flags[0], SIP_OUTGOING);
#ifdef VOCAL_DATA_HACK
ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
@@ -12562,6 +12625,8 @@
ast_copy_string(peer->musicclass, v->value, sizeof(peer->musicclass));
} else if (!strcasecmp(v->name, "mailbox")) {
ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
+ } else if (!strcasecmp(v->name, "subscribemwi")) {
+ ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY);
} else if (!strcasecmp(v->name, "vmexten")) {
ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten));
} else if (!strcasecmp(v->name, "callgroup")) {
Modified: team/oej/sipregister/configs/http.conf.sample
URL: http://svn.digium.com/view/asterisk/team/oej/sipregister/configs/http.conf.sample?rev=17407&r1=17406&r2=17407&view=diff
==============================================================================
--- team/oej/sipregister/configs/http.conf.sample (original)
+++ team/oej/sipregister/configs/http.conf.sample Tue Apr 4 14:18:16 2006
@@ -6,7 +6,7 @@
;
; Whether HTTP interface is enabled or not.
;
-enabled=yes
+enabled=no
;
; Address to bind to
;
Modified: team/oej/sipregister/configs/oss.conf.sample
URL: http://svn.digium.com/view/asterisk/team/oej/sipregister/configs/oss.conf.sample?rev=17407&r1=17406&r2=17407&view=diff
==============================================================================
--- team/oej/sipregister/configs/oss.conf.sample (original)
+++ team/oej/sipregister/configs/oss.conf.sample Tue Apr 4 14:18:16 2006
@@ -1,43 +1,51 @@
-;
-; Open Sound System Console Driver Configuration File
-;
+#
+# Automatically generated from ../channels/chan_oss.c
+#
+
[general]
-;
-; Automatically answer incoming calls on the console? Choose yes if
-; for example you want to use this as an intercom.
-;
-autoanswer=yes
-;
-; Default context (is overridden with @context syntax)
-;
-context=local
-;
-; Set overridecontext to yes if you want the context specified above
-; to override what someone places on the command line.
-;
-;overridecontext=yes
-;
-; Default extension to call
-;
-extension=s
-;
-; Default language
-;
-;language=en
-;
-; CallerID for outbound calls
-;
-;callerid=John Doe <1234>
-;
-; Silence supression can be enabled when sound is over a certain threshold.
-; The value for the threshold should probably be between 500 and 2000 or so,
-; but your mileage may vary. Use the echo test to evaluate the best setting.
-;silencesuppression = yes
-;silencethreshold = 1000
-;
-; On half-duplex cards, the driver attempts to switch back and forth between
-; read and write modes. Unfortunately, this fails sometimes on older hardware.
-; To prevent the driver from switching (ie. only play files on your speakers),
-; then set the playbackonly option to yes. Default is no. Note this option has
-; no effect on full-duplex cards.
-;playbackonly=no
+ ; General config options, with default values shown.
+ ; You should use one section per device, with [general] being used
[... 314 lines stripped ...]
More information about the asterisk-commits
mailing list