[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