[asterisk-commits] russell: branch group/sip-tcptls r90951 - in /team/group/sip-tcptls: ./ apps/...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Dec 4 13:09:32 CST 2007


Author: russell
Date: Tue Dec  4 13:09:31 2007
New Revision: 90951

URL: http://svn.digium.com/view/asterisk?view=rev&rev=90951
Log:
resolve, reset

Added:
    team/group/sip-tcptls/include/asterisk/global_datastores.h
      - copied unchanged from r90949, trunk/include/asterisk/global_datastores.h
    team/group/sip-tcptls/main/global_datastores.c
      - copied unchanged from r90949, trunk/main/global_datastores.c
Modified:
    team/group/sip-tcptls/   (props changed)
    team/group/sip-tcptls/CHANGES
    team/group/sip-tcptls/Makefile
    team/group/sip-tcptls/apps/app_dial.c
    team/group/sip-tcptls/apps/app_queue.c
    team/group/sip-tcptls/apps/app_voicemail.c
    team/group/sip-tcptls/channels/chan_local.c
    team/group/sip-tcptls/channels/chan_zap.c
    team/group/sip-tcptls/configs/zapata.conf.sample
    team/group/sip-tcptls/include/asterisk/callerid.h
    team/group/sip-tcptls/include/asterisk/channel.h
    team/group/sip-tcptls/main/Makefile
    team/group/sip-tcptls/main/callerid.c
    team/group/sip-tcptls/main/channel.c

Propchange: team/group/sip-tcptls/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/group/sip-tcptls/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/group/sip-tcptls/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Dec  4 13:09:31 2007
@@ -1,1 +1,1 @@
-/trunk:1-90861
+/trunk:1-90950

Modified: team/group/sip-tcptls/CHANGES
URL: http://svn.digium.com/view/asterisk/team/group/sip-tcptls/CHANGES?view=diff&rev=90951&r1=90950&r2=90951
==============================================================================
--- team/group/sip-tcptls/CHANGES (original)
+++ team/group/sip-tcptls/CHANGES Tue Dec  4 13:09:31 2007
@@ -277,7 +277,12 @@
   * CID matching information is now shown when doing 'dialplan show'.
   * Added zap show version CLI command to chan_zap.
   * Added setvar support to zapata.conf channel entries.
-
+  * Added two new options: mwimonitor and mwimonitornotify.  These options allow
+     you to enable MWI monitoring on FXO lines.  When the MWI state changes,
+     the script specified in the mwimonitornotify option is executed.  An internal
+	 event indicating the new state of the mailbox is also generated, so that
+	 the normal MWI facilities in Asterisk work as usual.
+ 
 H.323 Changes
 -------------
   * H323 remote hold notification support added (by NOTIFY message

Modified: team/group/sip-tcptls/Makefile
URL: http://svn.digium.com/view/asterisk/team/group/sip-tcptls/Makefile?view=diff&rev=90951&r1=90950&r2=90951
==============================================================================
--- team/group/sip-tcptls/Makefile (original)
+++ team/group/sip-tcptls/Makefile Tue Dec  4 13:09:31 2007
@@ -774,7 +774,8 @@
 	@echo "Generating input for menuselect ..."
 	@build_tools/prep_moduledeps > $@
 
+pdf: asterisk.pdf
 asterisk.pdf:
 	$(MAKE) -C doc/tex asterisk.pdf
 
-.PHONY: menuselect main sounds clean dist-clean distclean all prereqs cleantest uninstall _uninstall uninstall-all dont-optimize $(SUBDIRS_INSTALL) $(SUBDIRS_DIST_CLEAN) $(SUBDIRS_CLEAN) $(SUBDIRS_UNINSTALL) $(SUBDIRS) $(MOD_SUBDIRS_EMBED_LDSCRIPT) $(MOD_SUBDIRS_EMBED_LDFLAGS) $(MOD_SUBDIRS_EMBED_LIBS) menuselect.makeopts
+.PHONY: menuselect main sounds clean dist-clean distclean all prereqs cleantest uninstall _uninstall uninstall-all pdf dont-optimize $(SUBDIRS_INSTALL) $(SUBDIRS_DIST_CLEAN) $(SUBDIRS_CLEAN) $(SUBDIRS_UNINSTALL) $(SUBDIRS) $(MOD_SUBDIRS_EMBED_LDSCRIPT) $(MOD_SUBDIRS_EMBED_LDFLAGS) $(MOD_SUBDIRS_EMBED_LIBS) menuselect.makeopts

Modified: team/group/sip-tcptls/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/group/sip-tcptls/apps/app_dial.c?view=diff&rev=90951&r1=90950&r2=90951
==============================================================================
--- team/group/sip-tcptls/apps/app_dial.c (original)
+++ team/group/sip-tcptls/apps/app_dial.c Tue Dec  4 13:09:31 2007
@@ -54,6 +54,7 @@
 #include "asterisk/manager.h"
 #include "asterisk/privacy.h"
 #include "asterisk/stringfields.h"
+#include "asterisk/global_datastores.h"
 
 static char *app = "Dial";
 
@@ -326,7 +327,6 @@
 	struct chanlist *next;
 	struct ast_channel *chan;
 	uint64_t flags;
-	int forwards;
 };
 
 
@@ -346,8 +346,6 @@
 		ast_free(oo);
 	}
 }
-
-#define AST_MAX_FORWARDS   8
 
 #define AST_MAX_WATCHERS 256
 
@@ -480,28 +478,22 @@
 		tech = "Local";
 	}
 	/* Before processing channel, go ahead and check for forwarding */
-	o->forwards++;
-	if (o->forwards < AST_MAX_FORWARDS) {
-		ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
-		/* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
-		if (ast_test_flag64(peerflags, OPT_IGNORE_FORWARDING)) {
-			ast_verb(3, "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
-			c = o->chan = NULL;
-			cause = AST_CAUSE_BUSY;
-		} else {
-			/* Setup parameters */
-			c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
-			if (c) {
-				if (single)
-					ast_channel_make_compatible(o->chan, in);
-				ast_channel_inherit_variables(in, o->chan);
-			} else
-				ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
-		}
+	ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
+	/* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
+	if (ast_test_flag64(peerflags, OPT_IGNORE_FORWARDING)) {
+		ast_verb(3, "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
+		c = o->chan = NULL;
+		cause = AST_CAUSE_BUSY;
 	} else {
-		ast_verb(3, "Too many forwards from %s\n", c->name);
-		cause = AST_CAUSE_CONGESTION;
-		c = o->chan = NULL;
+		/* Setup parameters */
+		c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
+		if (c) {
+			if (single)
+				ast_channel_make_compatible(o->chan, in);
+			ast_channel_inherit_variables(in, o->chan);
+			ast_channel_datastore_inherit(in, o->chan);
+		} else
+			ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
 	}
 	if (!c) {
 		ast_clear_flag64(o, DIAL_STILLGOING);	
@@ -1252,6 +1244,8 @@
 	);
 	struct ast_flags64 opts = { 0, };
 	char *opt_args[OPT_ARG_ARRAY_SIZE];
+	struct ast_datastore *datastore = NULL;
+	int fulldial = 0, num_dialed = 0;
 
 	if (ast_strlen_zero(data)) {
 		ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
@@ -1333,7 +1327,13 @@
 		struct ast_channel *tc;	/* channel for this destination */
 		/* Get a technology/[device:]number pair */
 		char *number = cur;
+		char *interface = ast_strdupa(number);
 		char *tech = strsep(&number, "/");
+		/* find if we already dialed this interface */
+		int dialed = 0;
+		struct ast_dialed_interface *di;
+		AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
+		num_dialed++;
 		if (!number) {
 			ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
 			goto out;
@@ -1353,6 +1353,50 @@
 		}
 		ast_copy_string(numsubst, number, sizeof(numsubst));
 		/* Request the peer */
+		if (!(datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL))) {
+			if(!(datastore = ast_channel_datastore_alloc(&dialed_interface_info, NULL))) {
+				ast_log(LOG_WARNING, "Unable to create channel datastore for dialed interfaces. Aborting!\n"); 
+				free(tmp);
+				goto out;
+			}
+			else {
+				datastore->inheritance = DATASTORE_INHERIT_FOREVER;
+				if((dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
+					datastore->data = dialed_interfaces;
+					AST_LIST_HEAD_INIT(dialed_interfaces);
+					ast_channel_datastore_add(chan, datastore);
+				} else {
+					free(tmp);
+					goto out;
+				}
+			}
+		} else 
+			dialed_interfaces = datastore->data;
+		AST_LIST_LOCK(dialed_interfaces);
+		AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
+			/* XXX case sensitive??? */
+			if(!strcasecmp(di->interface, interface)) {
+				dialed = 1;
+				break;
+			}
+		}
+		if(!dialed && strcasecmp(tech, "Local")) {
+			if(!(di = ast_calloc(1, sizeof(*di) + strlen(interface)))) {
+				AST_LIST_UNLOCK(dialed_interfaces);
+				free(tmp);
+				goto out;
+			}
+			strcpy(di->interface, interface);
+			AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
+		} else {
+			AST_LIST_UNLOCK(dialed_interfaces);
+			ast_log(LOG_WARNING, "Skipping dialing interface '%s' again since it has already been dialed\n", di->interface);
+			fulldial++;
+			free(tmp);
+			continue;
+		}
+		AST_LIST_UNLOCK(dialed_interfaces);
+
 		tc = ast_request(tech, chan->nativeformats, numsubst, &cause);
 		if (!tc) {
 			/* If we can't, just go on to the next call */
@@ -1365,50 +1409,6 @@
 			continue;
 		}
 		pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", numsubst);
-		if (!ast_strlen_zero(tc->call_forward)) {
-			char tmpchan[256];
-			char *stuff;
-			char *tech;
-			ast_copy_string(tmpchan, tc->call_forward, sizeof(tmpchan));
-			if ((stuff = strchr(tmpchan, '/'))) {
-				*stuff++ = '\0';
-				tech = tmpchan;
-			} else {
-				snprintf(tmpchan, sizeof(tmpchan), "%s@%s", tc->call_forward, tc->context);
-				stuff = tmpchan;
-				tech = "Local";
-			}
-			tmp->forwards++;
-			if (tmp->forwards < AST_MAX_FORWARDS) {
-				ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n",
-					chan->name, tech, stuff, tc->name);
-				ast_hangup(tc);
-				/* If we have been told to ignore forwards, just set this channel to null
-				 * and continue processing extensions normally */
-				if (ast_test_flag64(&opts, OPT_IGNORE_FORWARDING)) {
-					tc = NULL;
-					cause = AST_CAUSE_BUSY;
-					ast_verb(3, "Forwarding %s to '%s/%s' prevented.\n",
-							chan->name, tech, stuff);
-				} else {
-					tc = ast_request(tech, chan->nativeformats, stuff, &cause);
-				}
-				if (!tc)
-					ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
-				else
-					ast_channel_inherit_variables(chan, tc);
-			} else {
-				ast_verb(3, "Too many forwards from %s\n", tc->name);
-				ast_hangup(tc);
-				tc = NULL;
-				cause = AST_CAUSE_CONGESTION;
-			}
-			if (!tc) {
-				handle_cause(cause, &num);
-				ast_free(tmp);
-				continue;
-			}
-		}
 
 		/* Setup outgoing SDP to match incoming one */
 		ast_rtp_make_compatible(tc, chan, !outgoing && !rest);
@@ -1498,6 +1498,10 @@
 
 	if (!outgoing) {
 		strcpy(pa.status, "CHANUNAVAIL");
+		if(fulldial == num_dialed) {
+			res = -1;
+			goto out;
+		}
 	} else {
 		/* Our status will at least be NOANSWER */
 		strcpy(pa.status, "NOANSWER");
@@ -1520,7 +1524,9 @@
 
 	time(&start_time);
 	peer = wait_for_answer(chan, outgoing, &to, peerflags, &pa, &num, &result);
-	
+
+	ast_channel_datastore_remove(chan, datastore);
+	ast_channel_datastore_free(datastore);
 	if (!peer) {
 		if (result) {
 			res = result;

Modified: team/group/sip-tcptls/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/group/sip-tcptls/apps/app_queue.c?view=diff&rev=90951&r1=90950&r2=90951
==============================================================================
--- team/group/sip-tcptls/apps/app_queue.c (original)
+++ team/group/sip-tcptls/apps/app_queue.c Tue Dec  4 13:09:31 2007
@@ -87,6 +87,7 @@
 #include "asterisk/event.h"
 #include "asterisk/astobj2.h"
 #include "asterisk/strings.h"
+#include "asterisk/global_datastores.h"
 
 enum {
 	QUEUE_STRATEGY_RINGALL = 0,
@@ -2295,6 +2296,7 @@
 						numnochan++;
 					} else {
 						ast_channel_inherit_variables(in, o->chan);
+						ast_channel_datastore_inherit(in, o->chan);
 						if (o->chan->cid.cid_num)
 							ast_free(o->chan->cid.cid_num);
 						o->chan->cid.cid_num = ast_strdup(in->cid.cid_num);
@@ -2733,6 +2735,7 @@
 	int forwardsallowed = 1;
 	int callcompletedinsl;
 	struct ao2_iterator memi;
+	struct ast_datastore *datastore = ast_channel_datastore_find(qe->chan, &dialed_interface_info, NULL);
 
 	memset(&bridge_config, 0, sizeof(bridge_config));
 	tmpid[0] = 0;
@@ -2802,7 +2805,9 @@
 	memi = ao2_iterator_init(qe->parent->members, 0);
 	while ((cur = ao2_iterator_next(&memi))) {
 		struct callattempt *tmp = ast_calloc(1, sizeof(*tmp));
-
+		struct ast_dialed_interface *di;
+		int dialed = 0;
+		AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
 		if (!tmp) {
 			ao2_ref(cur, -1);
 			ao2_unlock(qe->parent);
@@ -2810,6 +2815,49 @@
 				ao2_unlock(queues);
 			goto out;
 		}
+		if (!datastore) {
+			if(!(datastore = ast_channel_datastore_alloc(&dialed_interface_info, NULL))) {
+				ao2_ref(cur, -1);
+				ao2_unlock(qe->parent);
+				if(use_weight)
+					ao2_unlock(queues);
+				free(tmp);
+				goto out;
+			}
+			datastore->inheritance = DATASTORE_INHERIT_FOREVER;
+			dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces));
+			datastore->data = dialed_interfaces;
+			AST_LIST_HEAD_INIT(dialed_interfaces);
+			ast_channel_datastore_add(qe->chan, datastore);
+		} else
+			dialed_interfaces = datastore->data;
+		AST_LIST_LOCK(dialed_interfaces);
+		AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
+			/* XXX case sensitive ?? */
+			if(!strcasecmp(cur->interface, di->interface)) {
+				dialed = 1;
+				break;
+			}
+		}
+		if (!dialed && strncasecmp(cur->interface, "Local/", 6)) {
+			if(!(di = ast_calloc(1, sizeof(*di) + strlen(cur->interface)))) {
+				ao2_ref(cur, -1);
+				AST_LIST_UNLOCK(dialed_interfaces);
+				ao2_unlock(qe->parent);
+				if(use_weight)
+					ao2_unlock(queues);
+				free(tmp);
+				goto out;
+			}
+			strcpy(di->interface, cur->interface);
+			AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
+		} else {
+			AST_LIST_UNLOCK(dialed_interfaces);
+			ast_log(LOG_DEBUG, "Skipping dialing interface '%s' since it has already been dialed\n", di->interface);
+			free(tmp);
+			continue;
+		}
+		AST_LIST_UNLOCK(dialed_interfaces);
 		tmp->stillgoing = -1;
 		tmp->member = cur;
 		tmp->oldstatus = cur->status;
@@ -2842,6 +2890,8 @@
 	if (use_weight)
 		ao2_unlock(queues);
 	lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT), forwardsallowed);
+	ast_channel_datastore_remove(qe->chan, datastore);
+	ast_channel_datastore_free(datastore);
 	ao2_lock(qe->parent);
 	if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) {
 		store_next_rr(qe, outgoing);

Modified: team/group/sip-tcptls/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/group/sip-tcptls/apps/app_voicemail.c?view=diff&rev=90951&r1=90950&r2=90951
==============================================================================
--- team/group/sip-tcptls/apps/app_voicemail.c (original)
+++ team/group/sip-tcptls/apps/app_voicemail.c Tue Dec  4 13:09:31 2007
@@ -148,7 +148,7 @@
 static void update_messages_by_imapuser(const char *user, unsigned long number);
 
 static int imap_remove_file (char *dir, int msgnum);
-static int imap_retrieve_file (char *dir, int msgnum, char *mailbox, char *context);
+static int imap_retrieve_file (char *dir, int msgnum, const char *mailbox, char *context);
 static int imap_delete_old_greeting (char *dir, struct vm_state *vms);
 struct vmstate {
 	struct vm_state *vms;

Modified: team/group/sip-tcptls/channels/chan_local.c
URL: http://svn.digium.com/view/asterisk/team/group/sip-tcptls/channels/chan_local.c?view=diff&rev=90951&r1=90950&r2=90951
==============================================================================
--- team/group/sip-tcptls/channels/chan_local.c (original)
+++ team/group/sip-tcptls/channels/chan_local.c Tue Dec  4 13:09:31 2007
@@ -473,6 +473,7 @@
 			AST_LIST_INSERT_TAIL(&p->chan->varshead, new, entries);
 		}
 	}
+	ast_channel_datastore_inherit(p->owner, p->chan);
 
 	/* Start switch on sub channel */
 	if (!(res = ast_pbx_start(p->chan)))

Modified: team/group/sip-tcptls/channels/chan_zap.c
URL: http://svn.digium.com/view/asterisk/team/group/sip-tcptls/channels/chan_zap.c?view=diff&rev=90951&r1=90950&r2=90951
==============================================================================
--- team/group/sip-tcptls/channels/chan_zap.c (original)
+++ team/group/sip-tcptls/channels/chan_zap.c Tue Dec  4 13:09:31 2007
@@ -224,6 +224,9 @@
 
 static char defaultcic[64] = "";
 static char defaultozz[64] = "";
+
+/*! Run this script when the MWI state changes on an FXO line, if mwimonitor is enabled */
+static char mwimonitornotify[PATH_MAX] = "";
 
 static char progzone[10] = "";
 
@@ -552,6 +555,7 @@
 	unsigned int usedistinctiveringdetection:1;
 	unsigned int zaptrcallerid:1;			/*!< should we use the callerid from incoming call on zap transfer or not */
 	unsigned int transfertobusy:1;			/*!< allow flash-transfers to busy channels */
+	unsigned int mwimonitor:1;
 	/* Channel state or unavilability flags */
 	unsigned int inservice:1;
 	unsigned int locallyblocked:1;
@@ -608,6 +612,7 @@
 	int callwaitingrepeat;				/*!< How many samples to wait before repeating call waiting */
 	int cidcwexpire;				/*!< When to expire our muting for CID/CW */
 	unsigned char *cidspill;
+	struct callerid_state *mwi_state;
 	int cidpos;
 	int cidlen;
 	int ringt;
@@ -1842,6 +1847,56 @@
 	}
 	ast_debug(1, "Disabled conferencing\n");
 	return 0;
+}
+
+/*!
+ * \brief Send MWI state change
+ *
+ * \arg mailbox_full This is the mailbox associated with the FXO line that the
+ *      MWI state has changed on.
+ * \arg thereornot This argument should simply be set to 1 or 0, to indicate
+ *      whether there are messages waiting or not.
+ *
+ *  \return nothing
+ *
+ * This function does two things:
+ *
+ * 1) It generates an internal Asterisk event notifying any other module that
+ *    cares about MWI that the state of a mailbox has changed.
+ *
+ * 2) It runs the script specified by the mwimonitornotify option to allow
+ *    some custom handling of the state change.
+ */
+static void notify_message(char *mailbox_full, int thereornot)
+{
+	char s[sizeof(mwimonitornotify) + 80];
+	struct ast_event *event;
+	char *mailbox, *context;
+
+	/* Strip off @default */
+	context = mailbox = ast_strdupa(mailbox_full);
+	strsep(&context, "@");
+	if (ast_strlen_zero(context))
+		context = "default";
+
+	if (!(event = ast_event_new(AST_EVENT_MWI,
+			AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
+			AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
+			AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot,
+			AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot,
+			AST_EVENT_IE_END))) {
+		return;
+	}
+
+	ast_event_queue_and_cache(event,
+		AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR,
+		AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR,
+		AST_EVENT_IE_END);
+
+	if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(mwimonitornotify)) {
+		snprintf(s, sizeof(s), "%s %s %d", mwimonitornotify, mailbox, thereornot);
+		ast_safe_system(s);
+	}
 }
 
 static int restore_conference(struct zt_pvt *p)
@@ -5800,7 +5855,10 @@
 	tmp->cid.cid_pres = i->callingpres;
 	tmp->cid.cid_ton = i->cid_ton;
 	tmp->cid.cid_ani2 = i->cid_ani2;
-#if defined(HAVE_PRI) || defined(HAVE_SS7)
+/* TODO: enable this code for HAVE_SS7 when PRI_TRANS_CAP_DIGITAL gets renamed
+   and doesn't come from libpri.h any longer
+*/
+#if defined(HAVE_PRI)
 	tmp->transfercapability = transfercapability;
 	pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
 	if (transfercapability & PRI_TRANS_CAP_DIGITAL)
@@ -7325,7 +7383,14 @@
 					pfds[count].events = POLLPRI;
 					pfds[count].revents = 0;
 					/* Message waiting or r2 channels also get watched for reading */
-					if (i->cidspill)
+					if (i->mwimonitor && (i->sig & __ZT_SIG_FXS) && !i->mwi_state) {
+						if (!i->mwi_state) {
+							i->mwi_state = callerid_new(i->cid_signalling);
+							bump_gains(i);
+							zt_setlinear(i->subs[SUB_REAL].zfd, 0);
+						}
+					}
+					if (i->cidspill || i->mwi_state)
 						pfds[count].events |= POLLIN;
 					count++;
 				}
@@ -7414,29 +7479,57 @@
 						i = i->next;
 						continue;
 					}
-					if (!i->cidspill) {
+					if (!i->cidspill && !i->mwi_state) {
 						ast_log(LOG_WARNING, "Whoa....  I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd);
 						i = i->next;
 						continue;
 					}
 					res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf));
 					if (res > 0) {
-						/* We read some number of bytes.  Write an equal amount of data */
-						if (res > i->cidlen - i->cidpos) 
-							res = i->cidlen - i->cidpos;
-						res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res);
-						if (res2 > 0) {
-							i->cidpos += res2;
-							if (i->cidpos >= i->cidlen) {
-								ast_free(i->cidspill);
-								i->cidspill = 0;
-								i->cidpos = 0;
-								i->cidlen = 0;
-							}
-						} else {
-							ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno));
-							i->msgstate = -1;
-						}
+ 						if (i->mwi_state) {
+ 							if (i->cid_signalling == CID_SIG_V23_JP) {
+ 								res = callerid_feed_jp(i->mwi_state, (unsigned char *)buf, res, AST_LAW(i));
+ 							} else {
+ 								res = callerid_feed(i->mwi_state, (unsigned char *)buf, res, AST_LAW(i));
+ 							}
+ 							if (res < 0) {
+ 								ast_log(LOG_WARNING, "MWI CallerID feed failed: %s!\n", strerror(errno));
+ 								callerid_free(i->mwi_state);
+ 								i->mwi_state = NULL;
+ 							} else if (res) {
+ 								char *name, *number;
+ 								int flags;
+ 								callerid_get(i->mwi_state, &number, &name, &flags);
+ 								if (flags & CID_MSGWAITING) {
+ 									ast_log(LOG_NOTICE, "MWI: Channel %d message waiting!\n",i->channel);
+ 									notify_message(i->mailbox, 1);
+ 								} else if (flags & CID_NOMSGWAITING) {
+ 									ast_log(LOG_NOTICE, "MWI: Channel %d no message waiting!\n",i->channel);
+ 									notify_message(i->mailbox, 0);
+ 								} else 
+ 									ast_log(LOG_NOTICE, "MWI: Channel %d status unknown\n", i->channel);
+ 								callerid_free(i->mwi_state);
+ 								i->mwi_state = NULL;
+ 							}
+ 						} else if (i->cidspill) {
+ 							/* We read some number of bytes.  Write an equal amount of data */
+ 							if (res > i->cidlen - i->cidpos) 
+ 								res = i->cidlen - i->cidpos;
+ 							res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res);
+ 							if (res2 > 0) {
+ 								i->cidpos += res2;
+ 								if (i->cidpos >= i->cidlen) {
+ 									free(i->cidspill);
+ 									i->cidspill = 0;
+ 									i->cidpos = 0;
+ 									i->cidlen = 0;
+ 								}
+ 							} else {
+ 								ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno));
+ 								i->msgstate = -1;
+ 							}
+  						}
+
 					} else {
 						ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
 					}
@@ -7454,6 +7547,12 @@
 							ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd);
 						i = i->next;
 						continue;
+					}
+					if (i->mwi_state) {
+						callerid_free(i->mwi_state);
+						i->mwi_state = NULL;
+						zt_setlinear(i->subs[SUB_REAL].zfd, i->subs[SUB_REAL].linear);
+						restore_gains(i);
 					}
 					res = zt_get_event(i->subs[SUB_REAL].zfd);
 					ast_debug(1, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
@@ -7970,6 +8069,7 @@
 #endif
 		tmp->immediate = conf.chan.immediate;
 		tmp->transfertobusy = conf.chan.transfertobusy;
+		tmp->mwimonitor = conf.chan.mwimonitor;
 		tmp->sig = conf.chan.sig;
 		tmp->outsigmod = conf.chan.outsigmod;
 		tmp->radio = conf.chan.radio;
@@ -8560,8 +8660,14 @@
 	return tmp;
 }
 
+#if defined(HAVE_PRI) || defined(HAVE_SS7)
+static int zt_setlaw(int zfd, int law)
+{
+	return ioctl(zfd, ZT_SETLAW, &law);
+}
+#endif
+
 #ifdef HAVE_SS7
-static int zt_setlaw(int zfd, int law);
 
 static int ss7_find_cic(struct zt_ss7 *linkset, int cic)
 {
@@ -9578,14 +9684,6 @@
 	}
 }
 
-static int zt_setlaw(int zfd, int law)
-{
-	int res;
-	res = ioctl(zfd, ZT_SETLAW, &law);
-	if (res)
-		return res;
-	return 0;
-}
 
 static void *pri_dchannel(void *vpri)
 {
@@ -11338,6 +11436,7 @@
 			ast_cli(a->fd, "Caller ID: %s\n", tmp->cid_num);
 			ast_cli(a->fd, "Calling TON: %d\n", tmp->cid_ton);
 			ast_cli(a->fd, "Caller ID name: %s\n", tmp->cid_name);
+			ast_cli(a->fd, "Mailbox: %s\n", S_OR(tmp->mailbox, "none"));
 			if (tmp->vars) {
 				struct ast_variable *v;
 				ast_cli(a->fd, "Variables:\n");
@@ -11778,9 +11877,11 @@
 {
 	int x;
 	struct zt_pvt *p, *pl;
-
-#ifdef HAVE_PRI
+#if defined(HAVE_PRI) || defined(HAVE_SS7)
 	int i;
+#endif
+
+#if defined(HAVE_PRI)
 	for (i = 0; i < NUM_SPANS; i++) {
 		if (pris[i].master != AST_PTHREADT_NULL) 
 			pthread_cancel(pris[i].master);
@@ -11788,6 +11889,7 @@
 	ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
 	ast_unregister_application(zap_send_keypad_facility_app);
 #endif
+
 	ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
 	ast_manager_unregister( "ZapDialOffhook" );
 	ast_manager_unregister( "ZapHangup" );
@@ -11836,20 +11938,23 @@
 	iflist = NULL;
 	ifcount = 0;
 	ast_mutex_unlock(&iflock);
-#ifdef HAVE_PRI		
+
+#if defined(HAVE_PRI)
 	for (i = 0; i < NUM_SPANS; i++) {
 		if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL))
 			pthread_join(pris[i].master, NULL);
 		zt_close(pris[i].fds[i]);
 	}
-#endif
-#ifdef HAVE_SS7
+#endif /* HAVE_PRI */
+
+#if defined(HAVE_SS7)
 	for (i = 0; i < NUM_SPANS; i++) {
 		if (linksets[i].master && (linksets[i].master != AST_PTHREADT_NULL))
 			pthread_join(linksets[i].master, NULL);
 		zt_close(linksets[i].fds[i]);
 	}
 #endif /* HAVE_SS7 */
+
 	return 0;
 }
 
@@ -12505,6 +12610,8 @@
 			confp->chan.immediate = ast_true(v->value);
 		} else if (!strcasecmp(v->name, "transfertobusy")) {
 			confp->chan.transfertobusy = ast_true(v->value);
+		} else if (!strcasecmp(v->name, "mwimonitor")) {
+			confp->chan.mwimonitor = ast_true(v->value) ? 1 : 0;
 		} else if (!strcasecmp(v->name, "cid_rxgain")) {
 			if (sscanf(v->value, "%f", &confp->chan.cid_rxgain) != 1) {
 				ast_log(LOG_WARNING, "Invalid cid_rxgain: %s\n", v->value);
@@ -13067,7 +13174,9 @@
 				ast_copy_string(defaultcic, v->value, sizeof(defaultcic));
 			} else if (!strcasecmp(v->name, "defaultozz")) {
 				ast_copy_string(defaultozz, v->value, sizeof(defaultozz));
-			} 
+			} else if (!strcasecmp(v->name, "mwimonitornotify")) {
+				ast_copy_string(mwimonitornotify, v->value, sizeof(mwimonitornotify));
+			}
 		} else if (!skipchannels)
 			ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
 	}

Modified: team/group/sip-tcptls/configs/zapata.conf.sample
URL: http://svn.digium.com/view/asterisk/team/group/sip-tcptls/configs/zapata.conf.sample?view=diff&rev=90951&r1=90950&r2=90951
==============================================================================
--- team/group/sip-tcptls/configs/zapata.conf.sample (original)
+++ team/group/sip-tcptls/configs/zapata.conf.sample Tue Dec  4 13:09:31 2007
@@ -337,6 +337,19 @@
 ;
 ;hidecallerid=yes
 ;
+; The following option enables receiving MWI on FXO lines.  The default
+; value is no.  When this is enabled, and MWI notification indicates on or off,
+; the script specified by the mwimonitornotify option is executed.
+;
+;mwimonitor=no
+;
+; This option is used in conjunction with mwimonitor.  This will get executed
+; when incoming MWI state changes.  The script is passed 2 arguments.  The
+; first is the corresponding mailbox, and the second is 1 or 0, indicating if
+; there are messages waiting or not.
+;
+;mwimonitornotify=/usr/local/bin/zapnotify.sh
+;
 ; Whether or not to enable call waiting on internal extensions
 ; With this set to 'yes', busy extensions will hear the call-waiting
 ; tone, and can use hook-flash to switch between callers. The Dial()

Modified: team/group/sip-tcptls/include/asterisk/callerid.h
URL: http://svn.digium.com/view/asterisk/team/group/sip-tcptls/include/asterisk/callerid.h?view=diff&rev=90951&r1=90950&r2=90951
==============================================================================
--- team/group/sip-tcptls/include/asterisk/callerid.h (original)
+++ team/group/sip-tcptls/include/asterisk/callerid.h Tue Dec  4 13:09:31 2007
@@ -49,6 +49,8 @@
 #define CID_PRIVATE_NUMBER		(1 << 1)
 #define CID_UNKNOWN_NAME		(1 << 2)
 #define CID_UNKNOWN_NUMBER		(1 << 3)
+#define CID_MSGWAITING			(1 << 4)
+#define CID_NOMSGWAITING		(1 << 5)
 
 #define CID_SIG_BELL	1
 #define CID_SIG_V23	2

Modified: team/group/sip-tcptls/include/asterisk/channel.h
URL: http://svn.digium.com/view/asterisk/team/group/sip-tcptls/include/asterisk/channel.h?view=diff&rev=90951&r1=90950&r2=90951
==============================================================================
--- team/group/sip-tcptls/include/asterisk/channel.h (original)
+++ team/group/sip-tcptls/include/asterisk/channel.h Tue Dec  4 13:09:31 2007
@@ -649,6 +649,7 @@
  * \retval 0 success
  * \retval non-zero failure
  */
+
 int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore);
 
 /*! 

Modified: team/group/sip-tcptls/main/Makefile
URL: http://svn.digium.com/view/asterisk/team/group/sip-tcptls/main/Makefile?view=diff&rev=90951&r1=90950&r2=90951
==============================================================================
--- team/group/sip-tcptls/main/Makefile (original)
+++ team/group/sip-tcptls/main/Makefile Tue Dec  4 13:09:31 2007
@@ -27,7 +27,7 @@
 	netsock.o slinfactory.o ast_expr2.o ast_expr2f.o \
 	cryptostub.o sha1.o http.o fixedjitterbuf.o abstract_jb.o \
 	strcompat.o threadstorage.o dial.o event.o adsistub.o audiohook.o \
-	astobj2.o hashtab.o server.o
+	astobj2.o hashtab.o server.o global_datastores.o
 
 # we need to link in the objects statically, not as a library, because
 # otherwise modules will not have them available if none of the static

Modified: team/group/sip-tcptls/main/callerid.c
URL: http://svn.digium.com/view/asterisk/team/group/sip-tcptls/main/callerid.c?view=diff&rev=90951&r1=90950&r2=90951
==============================================================================
--- team/group/sip-tcptls/main/callerid.c (original)
+++ team/group/sip-tcptls/main/callerid.c Tue Dec  4 13:09:31 2007
@@ -555,7 +555,7 @@
 					cid->sawflag = 2;
 				break;
 			case 2: /* Get lead-in */
-				if ((b == 0x04) || (b == 0x80)) {
+				if ((b == 0x04) || (b == 0x80) || (b == 0x06) || (b == 0x82)) {
 					cid->type = b;
 					cid->sawflag = 3;
 					cid->cksum = b;
@@ -591,8 +591,10 @@
 		
 				cid->number[0] = '\0';
 				cid->name[0] = '\0';
+				/* Update flags */
+				cid->flags = 0;
 				/* If we get this far we're fine.  */
-				if (cid->type == 0x80) {
+				if ((cid->type == 0x80) || (cid->type == 0x82)) {
 					/* MDMF */
 					/* Go through each element and process */
 					for (x = 0; x < cid->pos;) {
@@ -626,6 +628,13 @@
 							memcpy(cid->name, cid->rawdata + x + 1, res);
 							cid->name[res] = '\0';
 							break;
+						case 11: /* Message Waiting */
+							res = cid->rawdata[x + 1];
+							if (res)
+								cid->flags |= CID_MSGWAITING;
+							else
+								cid->flags |= CID_NOMSGWAITING;
+							break;
 						case 17: /* UK: Call type, 1=Voice Call, 2=Ringback when free, 129=Message waiting  */
 						case 19: /* UK: Network message system status (Number of messages waiting) */
 						case 22: /* Something French */
@@ -643,12 +652,17 @@
 						x += cid->rawdata[x];
 						x++;
 					}
+				} else if (cid->type == 0x6) {
+					/* VMWI SDMF */
+					if (cid->rawdata[2] == 0x42) {
+						cid->flags |= CID_MSGWAITING;
+					} else if (cid->rawdata[2] == 0x6f) {
+						cid->flags |= CID_NOMSGWAITING;
+					}
 				} else {
 					/* SDMF */
 					ast_copy_string(cid->number, cid->rawdata + 8, sizeof(cid->number));
 				}
-				/* Update flags */
-				cid->flags = 0;
 				if (!strcmp(cid->number, "P")) {
 					strcpy(cid->number, "");
 					cid->flags |= CID_PRIVATE_NUMBER;

Modified: team/group/sip-tcptls/main/channel.c
URL: http://svn.digium.com/view/asterisk/team/group/sip-tcptls/main/channel.c?view=diff&rev=90951&r1=90950&r2=90951
==============================================================================
--- team/group/sip-tcptls/main/channel.c (original)
+++ team/group/sip-tcptls/main/channel.c Tue Dec  4 13:09:31 2007
@@ -673,6 +673,10 @@
 	if (needqueue) {
 		if (pipe(tmp->alertpipe)) {
 			ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n");
+#ifdef HAVE_ZAPTEL
+			if (tmp->timingfd > -1)
+				close(tmp->timingfd);
+#endif
 			sched_context_destroy(tmp->sched);
 			ast_string_field_free_memory(tmp);
 			ast_free(tmp);




More information about the asterisk-commits mailing list