[asterisk-commits] rmudgett: branch rmudgett/ss7_27_knk r371051 - in /team/rmudgett/ss7_27_knk: ...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Aug 9 18:02:19 CDT 2012


Author: rmudgett
Date: Thu Aug  9 18:02:15 2012
New Revision: 371051

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=371051
Log:
Reviewboard 1676 diff 11 plus my changes.

Need to run ./bootstrap.sh to create the configure script.

Added:
    team/rmudgett/ss7_27_knk/configs/ss7.timers.sample   (with props)
Modified:
    team/rmudgett/ss7_27_knk/CHANGES
    team/rmudgett/ss7_27_knk/UPGRADE.txt
    team/rmudgett/ss7_27_knk/channels/chan_dahdi.c
    team/rmudgett/ss7_27_knk/channels/sig_ss7.c
    team/rmudgett/ss7_27_knk/channels/sig_ss7.h
    team/rmudgett/ss7_27_knk/configs/chan_dahdi.conf.sample
    team/rmudgett/ss7_27_knk/configure.ac

Modified: team/rmudgett/ss7_27_knk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/ss7_27_knk/CHANGES?view=diff&rev=371051&r1=371050&r2=371051
==============================================================================
--- team/rmudgett/ss7_27_knk/CHANGES (original)
+++ team/rmudgett/ss7_27_knk/CHANGES Thu Aug  9 18:02:15 2012
@@ -249,6 +249,16 @@
 
  * Add options namedcallgroup and namedpickupgroup to support installations
    where a higher number of groups (>64) is required.
+
+ * SS7 support now requires libss7 v2.0 or later.
+
+ * Added SS7 support for connected line and redirecting.
+
+ * Most SS7 CLI commands are reworked as well as new SS7 commands added.
+   See online CLI help.
+
+ * Added several SS7 config option parameters described in
+   chan_dahdi.conf.sample.
 
 
 chan_motif

Modified: team/rmudgett/ss7_27_knk/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/ss7_27_knk/UPGRADE.txt?view=diff&rev=371051&r1=371050&r2=371051
==============================================================================
--- team/rmudgett/ss7_27_knk/UPGRADE.txt (original)
+++ team/rmudgett/ss7_27_knk/UPGRADE.txt Thu Aug  9 18:02:15 2012
@@ -108,6 +108,9 @@
 chan_jingle:
  - chan_jingle has been deprecated in favor of the chan_motif channel driver. It is recommended
    that users switch to using it as it is a core supported module.
+
+chan_dahdi:
+ - SS7 support now requires libss7 v2.0 or later.
 
 SIP
 ===

Modified: team/rmudgett/ss7_27_knk/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/ss7_27_knk/channels/chan_dahdi.c?view=diff&rev=371051&r1=371050&r2=371051
==============================================================================
--- team/rmudgett/ss7_27_knk/channels/chan_dahdi.c (original)
+++ team/rmudgett/ss7_27_knk/channels/chan_dahdi.c Thu Aug  9 18:02:15 2012
@@ -80,7 +80,9 @@
 
 #if defined(HAVE_SS7)
 #include "sig_ss7.h"
-#if defined(LIBSS7_ABI_COMPATIBILITY)
+#if !defined(LIBSS7_ABI_COMPATIBILITY)
+#error "Upgrade your libss7"
+#elif LIBSS7_ABI_COMPATIBILITY != 2
 #error "Your installed libss7 is not compatible"
 #endif
 #endif	/* defined(HAVE_SS7) */
@@ -557,6 +559,7 @@
 static struct dahdi_ss7 linksets[NUM_SPANS];
 
 static int cur_ss7type = -1;
+static int cur_slc = -1;
 static int cur_linkset = -1;
 static int cur_pointcode = -1;
 static int cur_cicbeginswith = -1;
@@ -979,19 +982,27 @@
 	unsigned int mwisendactive:1;
 	/*!
 	 * \brief TRUE if channel is out of reset and ready
-	 * \note Set but not used.
+	 * \note Used by SS7.  Otherwise set but not used.
 	 */
 	unsigned int inservice:1;
 	/*!
-	 * \brief TRUE if the channel is locally blocked.
+	 * \brief Bitmask for the channel being locally blocked.
 	 * \note Applies to SS7 and MFCR2 channels.
+	 * \note For MFCR2 only the first bit is used - TRUE if blocked
+	 * \note For SS7 two bits are used
+	 * \note Bit 0 - TRUE if maintenance blocked
+	 * \note Bit 1 - TRUE if hardware blocked
 	 */
-	unsigned int locallyblocked:1;
+	unsigned int locallyblocked:2;
 	/*!
-	 * \brief TRUE if the channel is remotely blocked.
+	 * \brief Bitmask for the channel being remotely blocked. 1 maintenance, 2 blocked in hardware.
 	 * \note Applies to SS7 and MFCR2 channels.
+	 * \note For MFCR2 only the first bit is used - TRUE if blocked
+	 * \note For SS7 two bits are used
+	 * \note Bit 0 - TRUE if maintenance blocked
+	 * \note Bit 1 - TRUE if hardware blocked
 	 */
-	unsigned int remotelyblocked:1;
+	unsigned int remotelyblocked:2;
 	/*!
 	 * \brief TRUE if the channel alarms will be managed also as Span ones
 	 * \note Applies to all channels
@@ -1331,8 +1342,8 @@
 	MEMBER(dahdi_pvt, mwimonitoractive, AST_DATA_BOOLEAN)			\
 	MEMBER(dahdi_pvt, mwisendactive, AST_DATA_BOOLEAN)			\
 	MEMBER(dahdi_pvt, inservice, AST_DATA_BOOLEAN)				\
-	MEMBER(dahdi_pvt, locallyblocked, AST_DATA_BOOLEAN)			\
-	MEMBER(dahdi_pvt, remotelyblocked, AST_DATA_BOOLEAN)			\
+	MEMBER(dahdi_pvt, locallyblocked, AST_DATA_UNSIGNED_INTEGER)		\
+	MEMBER(dahdi_pvt, remotelyblocked, AST_DATA_UNSIGNED_INTEGER)		\
 	MEMBER(dahdi_pvt, manages_span_alarms, AST_DATA_BOOLEAN)		\
 	MEMBER(dahdi_pvt, use_smdi, AST_DATA_BOOLEAN)				\
 	MEMBER(dahdi_pvt, context, AST_DATA_STRING)				\
@@ -1434,7 +1445,8 @@
 			.internationalprefix = "",
 			.nationalprefix = "",
 			.subscriberprefix = "",
-			.unknownprefix = ""
+			.unknownprefix = "",
+			.networkroutedprefix = ""
 		},
 #endif	/* defined(HAVE_SS7) */
 #ifdef HAVE_OPENR2
@@ -3583,6 +3595,34 @@
 #if defined(HAVE_SS7)
 /*!
  * \internal
+ * \brief Find the linkset to which SS7 belongs.
+ * \since 11.0
+ *
+ * \param ss7 structure to match on.
+ *
+ * \retval linkset if found.
+ * \retval NULL if not found.
+ */
+static struct sig_ss7_linkset *my_ss7_find_linkset(struct ss7 *ss7)
+{
+	int idx;
+
+	if (!ss7) {
+		return NULL;
+	}
+
+	for (idx = 0; idx < NUM_SPANS; ++idx) {
+		if (linksets[idx].ss7.ss7 == ss7) {
+			return &linksets[idx].ss7;
+		}
+	}
+	return NULL;
+}
+#endif	/* defined(HAVE_SS7) */
+
+#if defined(HAVE_SS7)
+/*!
+ * \internal
  * \brief Create a new asterisk channel structure for SS7.
  * \since 1.8
  *
@@ -3689,6 +3729,7 @@
 	.set_callerid = my_set_callerid,
 	.set_dnid = my_set_dnid,
 	.open_media = my_pri_ss7_open_media,
+	.find_linkset = my_ss7_find_linkset,
 };
 #endif	/* defined(HAVE_SS7) */
 
@@ -5540,7 +5581,7 @@
 		set_actual_gain(p->subs[SUB_REAL].dfd, 0, 0, p->rxdrc, p->txdrc, p->law);
 	} else {
 		set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain, p->txgain, p->rxdrc, p->txdrc, p->law);
-	}	
+	}
 
 #ifdef HAVE_PRI
 	if (dahdi_sig_pri_lib_handles(p->sig)) {
@@ -11532,9 +11573,10 @@
 			break;
 		case MWI_SEND_SPILL:
 			/* We read some number of bytes.  Write an equal amount of data */
-			if(0 < num_read) {
-				if (num_read > pvt->cidlen - pvt->cidpos)
+			if (0 < num_read) {
+				if (num_read > pvt->cidlen - pvt->cidpos) {
 					num_read = pvt->cidlen - pvt->cidpos;
+				}
 				res = write(pvt->subs[SUB_REAL].dfd, pvt->cidspill + pvt->cidpos, num_read);
 				if (res > 0) {
 					pvt->cidpos += res;
@@ -11585,7 +11627,7 @@
 	if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current) {
 		switch (event) {
 		case DAHDI_EVENT_RINGEROFF:
-			if(pvt->mwisend_data.mwisend_current == MWI_SEND_SA_WAIT) {
+			if (pvt->mwisend_data.mwisend_current == MWI_SEND_SA_WAIT) {
 				handled = 1;
 
 				if (dahdi_set_hook(pvt->subs[SUB_REAL].dfd, DAHDI_RINGOFF) ) {
@@ -13297,6 +13339,9 @@
 #if defined(HAVE_SS7)
 			case SIG_SS7:
 				tmp->inservice = 0;
+				if (tmp->ss7->flags & LINKSET_FLAG_INITIALHWBLO) {
+					tmp->remotelyblocked |= SS7_BLOCKED_HARDWARE;
+				}
 				break;
 #endif	/* defined(HAVE_SS7) */
 			default:
@@ -13331,6 +13376,7 @@
 		case SIG_SS7:
 			if (ss7_chan) {
 				ss7_chan->inalarm = tmp->inalarm;
+				ss7_chan->inservice = tmp->inservice;
 
 				ss7_chan->stripmsd = tmp->stripmsd;
 				ss7_chan->hidecallerid = tmp->hidecallerid;
@@ -15436,6 +15482,9 @@
 	}
 	ss7_set_error(dahdi_ss7_error);
 	ss7_set_message(dahdi_ss7_message);
+	ss7_set_hangup(sig_ss7_cb_hangup);
+	ss7_set_notinservice(sig_ss7_cb_notinservice);
+	ss7_set_call_null(sig_ss7_cb_call_null);
 #endif	/* defined(HAVE_SS7) */
 
 	if (setup_dahdi(2) != 0) {
@@ -15488,9 +15537,8 @@
 	int targetnum = 0;
 	int filtertype = 0;
 	struct dahdi_pvt *tmp = NULL;
-	char tmps[20] = "";
-	char statestr[20] = "";
-	char blockstr[20] = "";
+	char tmps[20];
+	char blockstr[20];
 
 	switch (cmd) {
 	case CLI_INIT:
@@ -15506,14 +15554,16 @@
 
 	/* syntax: dahdi show channels [ group <group> | context <context> ] */
 
-	if (!((a->argc == 3) || (a->argc == 5)))
+	if (!((a->argc == 3) || (a->argc == 5))) {
 		return CLI_SHOWUSAGE;
+	}
 
 	if (a->argc == 5) {
 		if (!strcasecmp(a->argv[3], "group")) {
 			targetnum = atoi(a->argv[4]);
-			if ((targetnum < 0) || (targetnum > 63))
+			if ((targetnum < 0) || (targetnum > 63)) {
 				return CLI_SHOWUSAGE;
+			}
 			targetnum = 1 << targetnum;
 			filtertype = 1;
 		} else if (!strcasecmp(a->argv[3], "context")) {
@@ -15521,7 +15571,7 @@
 		}
 	}
 
-	ast_cli(a->fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret", "Blocked", "State", "Description");
+	ast_cli(a->fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret", "Blocked", "In Service", "Description");
 	ast_mutex_lock(&iflock);
 	for (tmp = iflist; tmp; tmp = tmp->next) {
 		if (filtertype) {
@@ -15542,24 +15592,15 @@
 		}
 		if (tmp->channel > 0) {
 			snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
-		} else
+		} else {
 			ast_copy_string(tmps, "pseudo", sizeof(tmps));
-
-		if (tmp->locallyblocked)
-			blockstr[0] = 'L';
-		else
-			blockstr[0] = ' ';
-
-		if (tmp->remotelyblocked)
-			blockstr[1] = 'R';
-		else
-			blockstr[1] = ' ';
-
+		}
+
+		blockstr[0] = tmp->locallyblocked ? 'L' : ' ';
+		blockstr[1] = tmp->remotelyblocked ? 'R' : ' ';
 		blockstr[2] = '\0';
 
-		snprintf(statestr, sizeof(statestr), "%s", "In Service");
-
-		ast_cli(a->fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret, blockstr, statestr, tmp->description);
+		ast_cli(a->fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret, blockstr, tmp->inservice ? "Yes" : "No", tmp->description);
 	}
 	ast_mutex_unlock(&iflock);
 	return CLI_SUCCESS;
@@ -16536,7 +16577,7 @@
 		(params.sigtype == DAHDI_SIG_MTP2)
 			? SS7_TRANSPORT_DAHDIMTP2
 			: SS7_TRANSPORT_DAHDIDCHAN,
-		si.alarms, cur_networkindicator, cur_pointcode, cur_adjpointcode);
+		si.alarms, cur_networkindicator, cur_pointcode, cur_adjpointcode, cur_slc);
 	if (res) {
 		dahdi_close_ss7_fd(link, curfd);
 		return -1;
@@ -16562,8 +16603,11 @@
 	case CLI_GENERATE:
 		return NULL;
 	}
-	if (a->argc < 6)
+
+	if (a->argc < 6) {
 		return CLI_SHOWUSAGE;
+	}
+
 	span = atoi(a->argv[5]);
 	if ((span < 1) || (span > NUM_SPANS)) {
 		ast_cli(a->fd, "Invalid linkset %s.  Should be a number from %d to %d\n", a->argv[5], 1, NUM_SPANS);
@@ -16588,24 +16632,35 @@
 #endif	/* defined(HAVE_SS7) */
 
 #if defined(HAVE_SS7)
-static char *handle_ss7_block_cic(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+static char *handle_ss7_cic_blocking(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	int linkset, cic;
-	int blocked = -1, i;
+	int blocked, i;
+	int do_block = 0;
+	unsigned int dpc;
+
 	switch (cmd) {
 	case CLI_INIT:
-		e->command = "ss7 block cic";
+		e->command = "ss7 {block|unblock} cic";
 		e->usage =
-			"Usage: ss7 block cic <linkset> <CIC>\n"
-			"       Sends a remote blocking request for the given CIC on the specified linkset\n";
+			"Usage: ss7 {block|unblock} cic <linkset> <dpc> <CIC>\n"
+			"       Sends a remote {blocking|unblocking} request for the given CIC on the specified linkset\n";
 		return NULL;
 	case CLI_GENERATE:
 		return NULL;
 	}
-	if (a->argc == 5)
+
+	if (a->argc == 6) {
 		linkset = atoi(a->argv[3]);
-	else
+	} else {
 		return CLI_SHOWUSAGE;
+	}
+
+	if (!strcasecmp(a->argv[1], "block")) {
+		do_block = 1;
+	} else if (strcasecmp(a->argv[1], "unblock")) {
+		return CLI_SHOWUSAGE;
+	}
 
 	if ((linkset < 1) || (linkset > NUM_SPANS)) {
 		ast_cli(a->fd, "Invalid linkset %s.  Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS);
@@ -16617,60 +16672,69 @@
 		return CLI_SUCCESS;
 	}
 
-	cic = atoi(a->argv[4]);
-
+	cic = atoi(a->argv[5]);
 	if (cic < 1) {
 		ast_cli(a->fd, "Invalid CIC specified!\n");
 		return CLI_SUCCESS;
 	}
 
+	dpc = atoi(a->argv[4]);
+	if (dpc < 1) {
+		ast_cli(a->fd, "Invalid DPC specified!\n");
+		return CLI_SUCCESS;
+	}
+
 	for (i = 0; i < linksets[linkset-1].ss7.numchans; i++) {
-		if (linksets[linkset-1].ss7.pvts[i]->cic == cic) {
+		if (linksets[linkset-1].ss7.pvts[i] && linksets[linkset-1].ss7.pvts[i]->cic == cic && linksets[linkset-1].ss7.pvts[i]->dpc == dpc) {
 			blocked = linksets[linkset-1].ss7.pvts[i]->locallyblocked;
-			if (!blocked) {
-				ast_mutex_lock(&linksets[linkset-1].ss7.lock);
-				isup_blo(linksets[linkset-1].ss7.ss7, cic, linksets[linkset-1].ss7.pvts[i]->dpc);
-				ast_mutex_unlock(&linksets[linkset-1].ss7.lock);
-			}
-		}
-	}
-
-	if (blocked < 0) {
-		ast_cli(a->fd, "Invalid CIC specified!\n");
-		return CLI_SUCCESS;
-	}
-
-	if (!blocked)
-		ast_cli(a->fd, "Sent blocking request for linkset %d on CIC %d\n", linkset, cic);
-	else
-		ast_cli(a->fd, "CIC %d already locally blocked\n", cic);
-
-	/* Break poll on the linkset so it sends our messages */
-	pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
-
+			if (!do_block ^ !(blocked & SS7_BLOCKED_MAINTENANCE)) {
+				if (sig_ss7_cic_blocking(&linksets[linkset-1].ss7, do_block, i) < 0) {
+					ast_cli(a->fd, "Unable to allocate new ss7call\n");
+				} else {
+					ast_cli(a->fd, "Sent %sblocking request for linkset %d on CIC %d DPC %d\n", (do_block) ? "" : "un", linkset, cic, dpc);
+				}
+			} else if (!do_block && blocked) {
+				ast_cli(a->fd, "CIC %d is hardware locally blocked!\n", cic);
+			} else {
+				ast_cli(a->fd, "CIC %d %s locally blocked\n", cic, do_block ? "already" : "is not");
+			}
+			return CLI_SUCCESS;
+		}
+	}
+
+	ast_cli(a->fd, "Invalid CIC specified!\n");
 	return CLI_SUCCESS;
 }
 #endif	/* defined(HAVE_SS7) */
 
 #if defined(HAVE_SS7)
-static char *handle_ss7_block_linkset(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-	int linkset;
-	int i;
+static char *handle_ss7_linkset_blocking(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	int linkset, i;
+	int do_block = 0;
+
 	switch (cmd) {
 	case CLI_INIT:
-		e->command = "ss7 block linkset";
+		e->command = "ss7 {block|unblock} linkset";
 		e->usage =
-			"Usage: ss7 block linkset <linkset number>\n"
-			"       Sends a remote blocking request for all CICs on the given linkset\n";
+			"Usage: ss7 {block|unblock} linkset <linkset number>\n"
+			"       Sends a remote {blocking|unblocking} request for all CICs on the given linkset\n";
 		return NULL;
 	case CLI_GENERATE:
 		return NULL;
 	}
-	if (a->argc == 4)
+
+	if (a->argc == 4) {
 		linkset = atoi(a->argv[3]);
-	else
+	} else {
 		return CLI_SHOWUSAGE;
+	}
+
+	if (!strcasecmp(a->argv[1], "block")) {
+		do_block = 1;
+	} else if (strcasecmp(a->argv[1], "unblock")) {
+		return CLI_SHOWUSAGE;
+	}
 
 	if ((linkset < 1) || (linkset > NUM_SPANS)) {
 		ast_cli(a->fd, "Invalid linkset %s.  Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS);
@@ -16683,39 +16747,210 @@
 	}
 
 	for (i = 0; i < linksets[linkset-1].ss7.numchans; i++) {
-		ast_cli(a->fd, "Sending remote blocking request on CIC %d\n", linksets[linkset-1].ss7.pvts[i]->cic);
-		ast_mutex_lock(&linksets[linkset-1].ss7.lock);
-		isup_blo(linksets[linkset-1].ss7.ss7, linksets[linkset-1].ss7.pvts[i]->cic, linksets[linkset-1].ss7.pvts[i]->dpc);
-		ast_mutex_unlock(&linksets[linkset-1].ss7.lock);
-	}
-
-	/* Break poll on the linkset so it sends our messages */
-	pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
+		/* XXX Should be done with GRS instead - see ss7_reset_linkset() */
+		if (linksets[linkset-1].ss7.pvts[i] && !sig_ss7_cic_blocking(&linksets[linkset-1].ss7, do_block, i)) {
+			ast_cli(a->fd, "Sent remote %sblocking request on CIC %d\n", do_block ? "" : "un", linksets[linkset-1].ss7.pvts[i]->cic);
+		}
+	}
 
 	return CLI_SUCCESS;
 }
 #endif	/* defined(HAVE_SS7) */
 
 #if defined(HAVE_SS7)
-static char *handle_ss7_unblock_cic(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-	int linkset, cic;
-	int i, blocked = -1;
+static char *handle_ss7_group_blocking(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	int linkset, cic, range, chanpos;
+	int i, dpc, orient = 0;
+	int do_block = 0;
+	unsigned char state[255];
+
 	switch (cmd) {
 	case CLI_INIT:
-		e->command = "ss7 unblock cic";
+		e->command = "ss7 {block|unblock} group";
 		e->usage =
-			"Usage: ss7 unblock cic <linkset> <CIC>\n"
-			"       Sends a remote unblocking request for the given CIC on the specified linkset\n";
+			"Usage: ss7 {block|unblock} group <linkset> <dpc> <1st. CIC> <range> [H]\n"
+			"       Sends a remote {blocking|unblocking} request for CIC range on the specified linkset\n";
 		return NULL;
 	case CLI_GENERATE:
 		return NULL;
 	}
 
-	if (a->argc == 5)
+	if (a->argc == 7 || a->argc == 8) {
 		linkset = atoi(a->argv[3]);
-	else
+	} else {
 		return CLI_SHOWUSAGE;
+	}
+
+	if (!strcasecmp(a->argv[1], "block")) {
+		do_block = 1;
+	} else if (strcasecmp(a->argv[1], "unblock")) {
+		return CLI_SHOWUSAGE;
+	}
+
+	if (a->argc == 8) {
+		if (!strcasecmp(a->argv[7], "H")) {
+			orient = 1;
+		} else {
+			return CLI_SHOWUSAGE;
+		}
+	}
+
+	if ((linkset < 1) || (linkset > NUM_SPANS)) {
+		ast_cli(a->fd, "Invalid linkset %s.  Should be a number %d to %d\n", a->argv[4], 1, NUM_SPANS);
+		return CLI_SUCCESS;
+	}
+
+	if (!linksets[linkset-1].ss7.ss7) {
+		ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
+		return CLI_SUCCESS;
+	}
+
+	cic = atoi(a->argv[5]);
+	if (cic < 1) {
+		ast_cli(a->fd, "Invalid CIC specified!\n");
+		return CLI_SUCCESS;
+	}
+
+	range = atoi(a->argv[6]);
+	if (range < 1 || range > 31) {	/* ITU-T Q.763 3.43 - range 0 is reserved, which makes a range of 2 CICs a minimum group */
+		ast_cli(a->fd, "Invalid range specified!\n");
+		return CLI_SUCCESS;
+	}
+
+	dpc = atoi(a->argv[4]);
+	if (dpc < 1) {
+		ast_cli(a->fd, "Invalid DPC specified!\n");
+		return CLI_SUCCESS;
+	}
+
+	ast_mutex_lock(&linksets[linkset-1].ss7.lock);
+	if (!sig_ss7_find_cic_range(&linksets[linkset-1].ss7, cic, cic + range, dpc)) {
+		ast_mutex_unlock(&linksets[linkset-1].ss7.lock);
+		ast_cli(a->fd, "Invalid CIC/RANGE\n");
+		return CLI_SHOWUSAGE;
+	}
+
+	memset(state, 0, sizeof(state));
+	for (i = 0; i <= range; ++i) {
+		state[i] = 1;
+	}
+
+	/* We are guaranteed to find chanpos because of sig_ss7_find_cic_range() includes it. */
+	chanpos = sig_ss7_find_cic(&linksets[linkset-1].ss7, cic, dpc);
+	if (sig_ss7_group_blocking(&linksets[linkset-1].ss7, do_block, chanpos, cic + range - 1, state, orient)) {
+		ast_cli(a->fd, "Unable allocate new ss7call\n");
+	} else {
+		ast_cli(a->fd, "Sending remote%s %sblocking request linkset %d on CIC %d range %d\n",
+			orient ? " hardware" : "", do_block ? "" : "un", linkset, cic, range);
+	}
+
+	ast_mutex_unlock(&linksets[linkset-1].ss7.lock);
+
+	/* Break poll on the linkset so it sends our messages */
+	if (linksets[linkset-1].ss7.master != AST_PTHREADT_NULL) {
+		pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
+	}
+	return CLI_SUCCESS;
+}
+#endif	/* defined(HAVE_SS7) */
+
+#if defined(HAVE_SS7)
+static char *handle_ss7_group_reset(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	int linkset, cic, range;
+	unsigned int dpc;
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "ss7 reset group";
+		e->usage =
+			"Usage: ss7 reset group <linkset> <dpc> <1st CIC> <range>\n"
+			"       Send a GRS for the given CIC range on the specified linkset\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc == 7) {
+		linkset = atoi(a->argv[3]);
+	} else {
+		return CLI_SHOWUSAGE;
+	}
+
+	if ((linkset < 1) || (linkset > NUM_SPANS)) {
+		ast_cli(a->fd, "Invalid linkset %s.  Should be a number %d to %d\n", a->argv[4], 1, NUM_SPANS);
+		return CLI_SUCCESS;
+	}
+
+	if (!linksets[linkset-1].ss7.ss7) {
+		ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
+		return CLI_SUCCESS;
+	}
+
+	cic = atoi(a->argv[5]);
+
+	if (cic < 1) {
+		ast_cli(a->fd, "Invalid CIC specified!\n");
+		return CLI_SUCCESS;
+	}
+
+	range = atoi(a->argv[6]);
+	if (range < 1 || range > 31) {
+		ast_cli(a->fd, "Invalid range specified!\n");
+		return CLI_SUCCESS;
+	}
+
+	dpc = atoi(a->argv[4]);
+	if (dpc < 1) {
+		ast_cli(a->fd, "Invalid DPC specified!\n");
+		return CLI_SUCCESS;
+	}
+
+	ast_mutex_lock(&linksets[linkset-1].ss7.lock);
+	if (!sig_ss7_find_cic_range(&linksets[linkset-1].ss7, cic, cic + range, dpc)) {
+		ast_mutex_unlock(&linksets[linkset-1].ss7.lock);
+		ast_cli(a->fd, "Invalid CIC/RANGE\n");
+		return CLI_SHOWUSAGE;
+	}
+
+	if (sig_ss7_reset_group(&linksets[linkset-1].ss7, cic, dpc, range)) {
+		ast_cli(a->fd, "Unable to allocate new ss7call\n");
+	} else {
+		ast_cli(a->fd, "GRS sent ... \n");
+	}
+
+	ast_mutex_unlock(&linksets[linkset-1].ss7.lock);
+
+	/* Break poll on the linkset so it sends our messages */
+	if (linksets[linkset-1].ss7.master != AST_PTHREADT_NULL) {
+		pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
+	}
+	return CLI_SUCCESS;
+}
+#endif	/* defined(HAVE_SS7) */
+
+#if defined(HAVE_SS7)
+static char *handle_ss7_show_calls(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	int linkset;
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "ss7 show calls";
+		e->usage =
+			"Usage: ss7 show calls <linkset>\n"
+			"       Show SS7 calls on the specified linkset\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc == 4) {
+		linkset = atoi(a->argv[3]);
+	} else {
+		return CLI_SHOWUSAGE;
+	}
 
 	if ((linkset < 1) || (linkset > NUM_SPANS)) {
 		ast_cli(a->fd, "Invalid linkset %s.  Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS);
@@ -16727,74 +16962,164 @@
 		return CLI_SUCCESS;
 	}
 
-	cic = atoi(a->argv[4]);
+	ast_mutex_lock(&linksets[linkset-1].ss7.lock);
+	isup_show_calls(linksets[linkset-1].ss7.ss7, &ast_cli, a->fd);
+	ast_mutex_unlock(&linksets[linkset-1].ss7.lock);
+
+	return CLI_SUCCESS;
+}
+#endif	/* defined(HAVE_SS7) */
+
+#if defined(HAVE_SS7)
+static char *handle_ss7_reset_cic(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	int linkset, cic, res;
+	unsigned int dpc;
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "ss7 reset cic";
+		e->usage =
+			"Usage: ss7 reset cic <linkset> <dpc> <CIC>\n"
+			"       Send a RSC for the given CIC on the specified linkset\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc == 6) {
+		linkset = atoi(a->argv[3]);
+	} else {
+		return CLI_SHOWUSAGE;
+	}
+
+	if ((linkset < 1) || (linkset > NUM_SPANS)) {
+		ast_cli(a->fd, "Invalid linkset %s.  Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS);
+		return CLI_SUCCESS;
+	}
+
+	if (!linksets[linkset-1].ss7.ss7) {
+		ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
+		return CLI_SUCCESS;
+	}
+
+	cic = atoi(a->argv[5]);
 
 	if (cic < 1) {
 		ast_cli(a->fd, "Invalid CIC specified!\n");
 		return CLI_SUCCESS;
 	}
 
-	for (i = 0; i < linksets[linkset-1].ss7.numchans; i++) {
-		if (linksets[linkset-1].ss7.pvts[i]->cic == cic) {
-			blocked = linksets[linkset-1].ss7.pvts[i]->locallyblocked;
-			if (blocked) {
-				ast_mutex_lock(&linksets[linkset-1].ss7.lock);
-				isup_ubl(linksets[linkset-1].ss7.ss7, cic, linksets[linkset-1].ss7.pvts[i]->dpc);
-				ast_mutex_unlock(&linksets[linkset-1].ss7.lock);
-			}
-		}
-	}
-
-	if (blocked > 0)
-		ast_cli(a->fd, "Sent unblocking request for linkset %d on CIC %d\n", linkset, cic);
-
-	/* Break poll on the linkset so it sends our messages */
-	pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
+	dpc = atoi(a->argv[4]);
+	if (dpc < 1) {
+		ast_cli(a->fd, "Invalid DPC specified!\n");
+		return CLI_SUCCESS;
+	}
+
+	res = sig_ss7_reset_cic(&linksets[linkset-1].ss7, cic, dpc);
+
+	ast_cli(a->fd, "%s RSC for linkset %d on CIC %d DPC %d\n", res ? "Sent" : "Failed", linkset, cic, dpc);
 
 	return CLI_SUCCESS;
 }
 #endif	/* defined(HAVE_SS7) */
 
 #if defined(HAVE_SS7)
-static char *handle_ss7_unblock_linkset(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+static char *handle_ss7_net_mng(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	int linkset;
-	int i;
+	unsigned int slc;
+	unsigned int arg = 0;
+	const char *res;
+
 	switch (cmd) {
 	case CLI_INIT:
-		e->command = "ss7 unblock linkset";
+		e->command = "ss7 mtp3";
 		e->usage =
-			"Usage: ss7 unblock linkset <linkset number>\n"
-			"       Sends a remote unblocking request for all CICs on the specified linkset\n";
+			"Usage: ss7 mtp3 <linkset> <slc> coo|coa|cbd|cba|eco|eca|tfp|tfa|lin|lun|lia|lua|lid|lfu <arg>\n"
+			"       Send a NET MNG message\n"
+			"       WARNING!!! WARNING!!! We are not a STP, just for testing/development purposes\n";
 		return NULL;
 	case CLI_GENERATE:
 		return NULL;
 	}
 
-	if (a->argc == 4)
-		linkset = atoi(a->argv[3]);
-	else
+	if (a->argc < 5) {
 		return CLI_SHOWUSAGE;
-
+	}
+
+	linkset = atoi(a->argv[2]);
 	if ((linkset < 1) || (linkset > NUM_SPANS)) {
-		ast_cli(a->fd, "Invalid linkset %s.  Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS);
+		ast_cli(a->fd, "Invalid linkset %s.  Should be a number %d to %d\n", a->argv[2], 1, NUM_SPANS);
 		return CLI_SUCCESS;
 	}
-
 	if (!linksets[linkset-1].ss7.ss7) {
 		ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
 		return CLI_SUCCESS;
 	}
 
-	for (i = 0; i < linksets[linkset-1].ss7.numchans; i++) {
-		ast_cli(a->fd, "Sending remote unblock request on CIC %d\n", linksets[linkset-1].ss7.pvts[i]->cic);
-		ast_mutex_lock(&linksets[linkset-1].ss7.lock);
-		isup_ubl(linksets[linkset-1].ss7.ss7, linksets[linkset-1].ss7.pvts[i]->cic, linksets[linkset-1].ss7.pvts[i]->dpc);
-		ast_mutex_unlock(&linksets[linkset-1].ss7.lock);
-	}
+	slc = atoi(a->argv[3]);
+
+	if (a->argc == 6) {
+		arg = atoi(a->argv[5]);
+	}
+
+	ast_mutex_lock(&linksets[linkset-1].ss7.lock);
+	res = mtp3_net_mng(linksets[linkset-1].ss7.ss7, slc, a->argv[4], arg);
+	ast_mutex_unlock(&linksets[linkset-1].ss7.lock);
 
 	/* Break poll on the linkset so it sends our messages */
-	pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
+	if (linksets[linkset-1].ss7.master != AST_PTHREADT_NULL) {
+		pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
+	}
+
+	ast_cli(a->fd, "%s", res);
+
+	return CLI_SUCCESS;
+}
+#endif	/* defined(HAVE_SS7) */
+
+#if defined(HAVE_SS7)
+static char *handle_ss7_mtp3_restart(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	int linkset;
+	unsigned int slc = 0;
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "ss7 restart mtp3";
+		e->usage =
+			"Usage: ss7 restart mtp3 <linkset> <slc>\n"
+			"       Restart link\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc < 5) {
+		return CLI_SHOWUSAGE;
+	}
+
+	linkset = atoi(a->argv[3]);
+	if ((linkset < 1) || (linkset > NUM_SPANS)) {
+		ast_cli(a->fd, "Invalid linkset %s.  Should be a number %d to %d\n", a->argv[2], 1, NUM_SPANS);
+		return CLI_SUCCESS;
+	}
+	if (!linksets[linkset-1].ss7.ss7) {
+		ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
+		return CLI_SUCCESS;
+	}
+
+	slc = atoi(a->argv[4]);
+
+	ast_mutex_lock(&linksets[linkset-1].ss7.lock);
+	mtp3_init_restart(linksets[linkset-1].ss7.ss7, slc);
+	ast_mutex_unlock(&linksets[linkset-1].ss7.lock);
+
+	/* Break poll on the linkset so it sends our messages */
+	if (linksets[linkset-1].ss7.master != AST_PTHREADT_NULL) {
+		pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
+	}
 
 	return CLI_SUCCESS;
 }
@@ -16816,8 +17141,10 @@
 		return NULL;
 	}
 
-	if (a->argc < 4)
+	if (a->argc < 4) {
 		return CLI_SHOWUSAGE;
+	}
+
 	linkset = atoi(a->argv[3]);
 	if ((linkset < 1) || (linkset > NUM_SPANS)) {
 		ast_cli(a->fd, "Invalid linkset %s.  Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS);
@@ -16829,7 +17156,16 @@
 		return CLI_SUCCESS;
 	}
 
+	ast_cli(a->fd, "SS7 flags: 0x%x\n", ss7->flags);
 	ast_cli(a->fd, "SS7 linkset %d status: %s\n", linkset, (ss7->state == LINKSET_STATE_UP) ? "Up" : "Down");
+	ast_cli(a->fd, "SS7 calling nai: %i\n", ss7->calling_nai);
+	ast_cli(a->fd, "SS7 called nai: %i\n", ss7->called_nai);
+	ast_cli(a->fd, "SS7 nationalprefix: %s\n", ss7->nationalprefix);
+	ast_cli(a->fd, "SS7 internationalprefix: %s\n", ss7->internationalprefix);
+	ast_cli(a->fd, "SS7 unknownprefix: %s\n", ss7->unknownprefix);
+	ast_cli(a->fd, "SS7 networkroutedprefix: %s\n", ss7->networkroutedprefix);
+	ast_cli(a->fd, "SS7 subscriberprefix: %s\n", ss7->subscriberprefix);
+	ss7_show_linkset(ss7->ss7, &ast_cli, a->fd);
 
 	return CLI_SUCCESS;
 }
@@ -16851,8 +17187,9 @@
 		return NULL;
 	}
 
-	if (a->argc != 3)
+	if (a->argc != 3) {
 		return CLI_SHOWUSAGE;
+	}
 
 	sig_ss7_cli_show_channels_header(a->fd);
 	for (linkset = 0; linkset < NUM_SPANS; ++linkset) {
@@ -16861,6 +17198,110 @@
 		}
 	}
 	return CLI_SUCCESS;
+}
+#endif	/* defined(HAVE_SS7) */
+
+#if defined(HAVE_SS7)
+static char *handle_ss7_show_cics(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+#define FORMAT "%5s %5s %6s %12s   %-12s\n"
+#define FORMAT2 "%5i %5i %6i %12s   %-12s\n"
+	int i, linkset, dpc = 0;
+	struct sig_ss7_linkset *ss7;
+	char *state;
+	char blocking[12];
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "ss7 show cics";
+		e->usage =
+			"Usage: ss7 show cics <linkset> [dpc]\n"
+			"       Shows the cics of an SS7 linkset.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc < 4 || a->argc > 5) {
+		return CLI_SHOWUSAGE;
+	}
+
+	linkset = atoi(a->argv[3]);
+
+	if ((linkset < 1) || (linkset > NUM_SPANS)) {
+		ast_cli(a->fd, "Invalid linkset %s.  Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS);
+		return CLI_SUCCESS;
+	}
+
+	if (!linksets[linkset-1].ss7.ss7) {
+		ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
+		return CLI_SUCCESS;
+	}
+	ss7 = &linksets[linkset-1].ss7;
+
+	if (a->argc == 5) {
+		dpc = atoi(a->argv[4]);
+		if (dpc < 1) {
+			ast_cli(a->fd, "Invalid DPC specified!\n");
+			return CLI_SUCCESS;
+		}
+	}
+
+	ast_cli(a->fd, FORMAT, "CIC", "DPC", "DAHDI", "STATE", "BLOCKING");
+
+	for (i = 0; i < ss7->numchans; i++) {
+		if (!dpc || (ss7->pvts[i] && ss7->pvts[i]->dpc == dpc)) {
+			struct dahdi_pvt *p = ss7->pvts[i]->chan_pvt;
+
+			if (ss7->pvts[i]->owner) {
+				state = "Used";
+			} else if (ss7->pvts[i]->ss7call) {
+				state = "Pending";
+			} else if (!p->inservice) {
+				state = "NotInServ";
+			} else {
+				state = "Idle";
+			}
+
+			if (p->locallyblocked) {
+				strcpy(blocking, "L:");
+				if (p->locallyblocked & SS7_BLOCKED_MAINTENANCE) {
+					strcat(blocking, "M");
+				} else {
+					strcat(blocking, " ");
+				}
+
+				if (p->locallyblocked & SS7_BLOCKED_HARDWARE) {
+					strcat(blocking, "H");
+				} else {
+					strcat(blocking, " ");
+				}
+			} else {
+				strcpy(blocking, "    ");
+			}
+
+			if (p->remotelyblocked) {
+				strcat(blocking, " R:");
+				if (p->remotelyblocked & SS7_BLOCKED_MAINTENANCE) {
+					strcat(blocking, "M");
+				} else {
+					strcat(blocking, " ");
+				}
+
+				if (p->remotelyblocked & SS7_BLOCKED_HARDWARE) {
+					strcat(blocking, "H");
+				} else {
+					strcat(blocking, " ");
+				}
+			}
+
+			ast_cli(a->fd, FORMAT2, ss7->pvts[i]->cic, ss7->pvts[i]->dpc, ss7->pvts[i]->channel, state, blocking);
+		}
+	}
+
+	return CLI_SUCCESS;
+#undef FORMAT
+#undef FORMAT2
 }
 #endif	/* defined(HAVE_SS7) */
 
@@ -16887,12 +17328,17 @@
 #if defined(HAVE_SS7)
 static struct ast_cli_entry dahdi_ss7_cli[] = {
 	AST_CLI_DEFINE(handle_ss7_debug, "Enables SS7 debugging on a linkset"),
-	AST_CLI_DEFINE(handle_ss7_block_cic, "Blocks the given CIC"),
-	AST_CLI_DEFINE(handle_ss7_unblock_cic, "Unblocks the given CIC"),
-	AST_CLI_DEFINE(handle_ss7_block_linkset, "Blocks all CICs on a linkset"),
-	AST_CLI_DEFINE(handle_ss7_unblock_linkset, "Unblocks all CICs on a linkset"),
+	AST_CLI_DEFINE(handle_ss7_cic_blocking, "Blocks/Unblocks the given CIC"),
+	AST_CLI_DEFINE(handle_ss7_linkset_blocking, "Blocks/Unblocks all CICs on a linkset"),
+	AST_CLI_DEFINE(handle_ss7_group_blocking, "Blocks/Unblocks the given CIC range"),
+	AST_CLI_DEFINE(handle_ss7_reset_cic, "Resets the given CIC"),
+	AST_CLI_DEFINE(handle_ss7_group_reset, "Resets the given CIC range"),
+	AST_CLI_DEFINE(handle_ss7_mtp3_restart, "Restart a link"),
+	AST_CLI_DEFINE(handle_ss7_net_mng, "Send an NET MNG message"),
 	AST_CLI_DEFINE(handle_ss7_show_linkset, "Shows the status of a linkset"),
 	AST_CLI_DEFINE(handle_ss7_show_channels, "Displays SS7 channel information"),
+	AST_CLI_DEFINE(handle_ss7_show_calls, "Show ss7 calls"),
+	AST_CLI_DEFINE(handle_ss7_show_cics, "Show cics on a linkset"),
 	AST_CLI_DEFINE(handle_ss7_version, "Displays libss7 version"),
 };
 #endif	/* defined(HAVE_SS7) */
@@ -17083,10 +17529,15 @@
 
 #if defined(HAVE_SS7)
 	for (i = 0; i < NUM_SPANS; i++) {
-		if (linksets[i].ss7.master && (linksets[i].ss7.master != AST_PTHREADT_NULL))
+		if (linksets[i].ss7.master && (linksets[i].ss7.master != AST_PTHREADT_NULL)) {
 			pthread_join(linksets[i].ss7.master, NULL);
+		}
 		for (j = 0; j < SIG_SS7_NUM_DCHANS; j++) {
 			dahdi_close_ss7_fd(&(linksets[i]), j);
+		}
+		if (linksets[i].ss7.ss7) {
+			ss7_destroy(linksets[i].ss7.ss7);
+			linksets[i].ss7.ss7 = NULL;
 		}
 	}
 #endif	/* defined(HAVE_SS7) */
@@ -17353,13 +17804,13 @@
 
 	for (; ;) {
 		/* Scans the string for the next value in the pattern. If none, it checks to see if any have been entered so far. */
-		if(!sscanf(v->value, "%30d", &norval) && count_pattern == 0) { 
+		if (!sscanf(v->value, "%30d", &norval) && count_pattern == 0) {
 			ast_log(LOG_ERROR, "busypattern= expects either busypattern=tonelength,quietlength or busypattern=t1length, q1length, t2length, q2length at line %d.\n", v->lineno);
 			break;
 		}
 
-		busy_cadence->pattern[count_pattern] = norval; 
-		
+		busy_cadence->pattern[count_pattern] = norval;
+
 		count_pattern++;
 		if (count_pattern == 4) {
 			break;
@@ -17691,23 +18142,23 @@
 #else
 			/* Default is fsk, to turn it off you must specify nofsk */
 			memset(&confp->chan.mwisend_setting, 0, sizeof(confp->chan.mwisend_setting));
-			if (strcasestr(v->value, "nofsk")) { 		/* NoFSK */
+			if (strcasestr(v->value, "nofsk")) {		/* NoFSK */
 				confp->chan.mwisend_fsk = 0;
 			} else {					/* Default FSK */
 				confp->chan.mwisend_fsk = 1;
 			}
-			if (strcasestr(v->value, "rpas")) { 		/* Ring Pulse Alert Signal, normally followed by FSK */
+			if (strcasestr(v->value, "rpas")) {		/* Ring Pulse Alert Signal, normally followed by FSK */
 				confp->chan.mwisend_rpas = 1;
 			} else {
 				confp->chan.mwisend_rpas = 0;
 			}
-			if (strcasestr(v->value, "lrev")) { 		/* Line Reversal */
+			if (strcasestr(v->value, "lrev")) {		/* Line Reversal */
 				confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_LREV;
 			}
-			if (strcasestr(v->value, "hvdc")) { 		/* HV 90VDC */
+			if (strcasestr(v->value, "hvdc")) {		/* HV 90VDC */
 				confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVDC;
 			}
-			if ( (strcasestr(v->value, "neon")) || (strcasestr(v->value, "hvac")) ){ 	/* 90V DC pulses */
+			if ( (strcasestr(v->value, "neon")) || (strcasestr(v->value, "hvac")) ) {	/* 90V DC pulses */
 				confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVAC;
 			}
 #endif
@@ -18210,8 +18661,11 @@
 					cur_ss7type = SS7_ITU;
 				} else if (!strcasecmp(v->value, "ansi")) {
 					cur_ss7type = SS7_ANSI;
-				} else
+				} else {
 					ast_log(LOG_WARNING, "'%s' is an unknown ss7 switch type at line %d.!\n", v->value, v->lineno);
+				}
+			} else if (!strcasecmp(v->name, "slc")) {
+				cur_slc = atoi(v->value);
 			} else if (!strcasecmp(v->name, "linkset")) {
 				cur_linkset = atoi(v->value);
 			} else if (!strcasecmp(v->name, "pointcode")) {
@@ -18223,16 +18677,17 @@
 			} else if (!strcasecmp(v->name, "cicbeginswith")) {
 				cur_cicbeginswith = atoi(v->value);
 			} else if (!strcasecmp(v->name, "networkindicator")) {
-				if (!strcasecmp(v->value, "national"))
+				if (!strcasecmp(v->value, "national")) {
 					cur_networkindicator = SS7_NI_NAT;
-				else if (!strcasecmp(v->value, "national_spare"))
+				} else if (!strcasecmp(v->value, "national_spare")) {
 					cur_networkindicator = SS7_NI_NAT_SPARE;
-				else if (!strcasecmp(v->value, "international"))
+				} else if (!strcasecmp(v->value, "international")) {
 					cur_networkindicator = SS7_NI_INT;
-				else if (!strcasecmp(v->value, "international_spare"))
+				} else if (!strcasecmp(v->value, "international_spare")) {
 					cur_networkindicator = SS7_NI_INT_SPARE;
-				else
+				} else {
 					cur_networkindicator = -1;
+				}
 			} else if (!strcasecmp(v->name, "ss7_internationalprefix")) {
 				ast_copy_string(confp->ss7.ss7.internationalprefix, v->value, sizeof(confp->ss7.ss7.internationalprefix));
 			} else if (!strcasecmp(v->name, "ss7_nationalprefix")) {
@@ -18241,6 +18696,8 @@
 				ast_copy_string(confp->ss7.ss7.subscriberprefix, v->value, sizeof(confp->ss7.ss7.subscriberprefix));
 			} else if (!strcasecmp(v->name, "ss7_unknownprefix")) {
 				ast_copy_string(confp->ss7.ss7.unknownprefix, v->value, sizeof(confp->ss7.ss7.unknownprefix));
+			} else if (!strcasecmp(v->name, "ss7_networkroutedprefix")) {
+				ast_copy_string(confp->ss7.ss7.networkroutedprefix, v->value, sizeof(confp->ss7.ss7.networkroutedprefix));
 			} else if (!strcasecmp(v->name, "ss7_called_nai")) {
 				if (!strcasecmp(v->value, "national")) {
 					confp->ss7.ss7.called_nai = SS7_NAI_NATIONAL;
@@ -18273,9 +18730,9 @@
 				int sigchan, res;
 				sigchan = atoi(v->value);
 				res = linkset_addsigchan(sigchan);
-				if (res < 0)
+				if (res < 0) {
 					return -1;
-
+				}
 			} else if (!strcasecmp(v->name, "ss7_explicitacm")) {
 				struct dahdi_ss7 *link;
 				link = ss7_resolve_linkset(cur_linkset);
@@ -18283,8 +18740,148 @@
 					ast_log(LOG_ERROR, "Invalid linkset number.  Must be between 1 and %d\n", NUM_SPANS + 1);
 					return -1;
 				}
-				if (ast_true(v->value))
+				if (ast_true(v->value)) {
 					link->ss7.flags |= LINKSET_FLAG_EXPLICITACM;
+				} else {
+					link->ss7.flags &= ~LINKSET_FLAG_EXPLICITACM;
+				}
+			} else if (!strcasecmp(v->name, "ss7_autoacm")) {
+				struct dahdi_ss7 *link;
+				link = ss7_resolve_linkset(cur_linkset);
+				if (!link) {
+					ast_log(LOG_ERROR, "Invalid linkset number.  Must be between 1 and %d\n", NUM_SPANS + 1);
+					return -1;
+				}
+				if (ast_true(v->value)) {
+					link->ss7.flags |= LINKSET_FLAG_AUTOACM;
+				} else {
+					link->ss7.flags &= ~LINKSET_FLAG_AUTOACM;
+				}
+			} else if (!strcasecmp(v->name, "ss7_initialhwblo")) {
+				struct dahdi_ss7 *link;
+				link = ss7_resolve_linkset(cur_linkset);
+				if (!link) {
+					ast_log(LOG_ERROR, "Invalid linkset number.  Must be between 1 and %d\n", NUM_SPANS + 1);
+					return -1;
+				}
+				if (ast_true(v->value)) {
+					link->ss7.flags |= LINKSET_FLAG_INITIALHWBLO;
+				} else {
+					link->ss7.flags &= ~LINKSET_FLAG_INITIALHWBLO;
+				}
+			} else if (!strcasecmp(v->name, "ss7_use_echocontrol")) {
+				struct dahdi_ss7 *link;
+				link = ss7_resolve_linkset(cur_linkset);
+				if (!link) {
+					ast_log(LOG_ERROR, "Invalid linkset number.  Must be between 1 and %d\n", NUM_SPANS + 1);
+					return -1;
+				}
+				if (ast_true(v->value)) {
+					link->ss7.flags |= LINKSET_FLAG_USEECHOCONTROL;
+				} else {
+					link->ss7.flags &= ~LINKSET_FLAG_USEECHOCONTROL;
+				}
+			} else if (!strcasecmp(v->name, "ss7_default_echocontrol")) {
+				struct dahdi_ss7 *link;
+				link = ss7_resolve_linkset(cur_linkset);
+				if (!link) {
+					ast_log(LOG_ERROR, "Invalid linkset number.  Must be between 1 and %d\n", NUM_SPANS + 1);
+					return -1;
+				}
+				if (ast_true(v->value)) {
+					link->ss7.flags |= LINKSET_FLAG_DEFAULTECHOCONTROL;
+				} else {
+					link->ss7.flags &= ~LINKSET_FLAG_DEFAULTECHOCONTROL;
+				}
+			} else if (!strncasecmp(v->name, "isup_timer.", 11)) {
+				struct dahdi_ss7 *link;
+				link = ss7_resolve_linkset(cur_linkset);
+				if (!link) {

[... 3139 lines stripped ...]



More information about the asterisk-commits mailing list