[svn-commits] mattf: trunk r257 - /trunk/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Mar 5 11:53:12 CST 2009


Author: mattf
Date: Thu Mar  5 11:53:06 2009
New Revision: 257

URL: http://svn.digium.com/svn-view/libss7?view=rev&rev=257
Log:
------------------------------------------------------------------------
r220 | mattf | 2008-12-01 12:15:08 -0600 (Mon, 01 Dec 2008) | 1 line

Commit updated version of #13495 patches (with various fixes) so that we can work off of this branch
------------------------------------------------------------------------
r221 | mattf | 2008-12-01 15:09:15 -0600 (Mon, 01 Dec 2008) | 1 line

Fix a couple of coding style issues in ss7.c
------------------------------------------------------------------------
r222 | mattf | 2008-12-01 16:14:54 -0600 (Mon, 01 Dec 2008) | 1 line

Bunch of style related cleanups in mtp3.c
------------------------------------------------------------------------
r223 | mattf | 2008-12-03 10:18:01 -0600 (Wed, 03 Dec 2008) | 1 line

Apply patch from #13495 for moving clearing of GOT_IAM flag into isup.c
------------------------------------------------------------------------
r224 | mattf | 2008-12-03 10:31:12 -0600 (Wed, 03 Dec 2008) | 1 line

Fix a couple of random function definitons
------------------------------------------------------------------------
r225 | mattf | 2008-12-03 10:45:51 -0600 (Wed, 03 Dec 2008) | 1 line

Remove erroneous return statement
------------------------------------------------------------------------
r226 | mattf | 2008-12-03 11:31:02 -0600 (Wed, 03 Dec 2008) | 1 line

Add echo control reporting and setting ability to libss7 (#13495)
------------------------------------------------------------------------
r227 | mattf | 2008-12-03 13:47:08 -0600 (Wed, 03 Dec 2008) | 1 line

ss7linktest builds again
------------------------------------------------------------------------
r228 | mattf | 2008-12-05 15:43:44 -0600 (Fri, 05 Dec 2008) | 1 line

Let's not complain if we can't find the SLC specified
------------------------------------------------------------------------
r229 | mattf | 2008-12-05 15:55:23 -0600 (Fri, 05 Dec 2008) | 1 line

Fix spelling error in the word adjacent
------------------------------------------------------------------------
r230 | mattf | 2008-12-05 16:30:43 -0600 (Fri, 05 Dec 2008) | 1 line

Add support for SLC specification of an mtp2 link
------------------------------------------------------------------------
r231 | mattf | 2008-12-05 16:52:46 -0600 (Fri, 05 Dec 2008) | 1 line

Make sure we set the optparm filed for ANSI GRA and GRS
------------------------------------------------------------------------
r232 | mattf | 2008-12-06 11:03:39 -0600 (Sat, 06 Dec 2008) | 1 line

Add a new point code to string function and fix a bug in finding a link where two links have the same point code
------------------------------------------------------------------------
r233 | mattf | 2008-12-06 11:07:14 -0600 (Sat, 06 Dec 2008) | 1 line

Ooops, make sure we print out the adjpc on all message types, not just FISUs
------------------------------------------------------------------------
r234 | mattf | 2008-12-06 11:40:46 -0600 (Sat, 06 Dec 2008) | 1 line

Add a function that checks a link's DPC when sending MTP3 management messages
------------------------------------------------------------------------
r235 | mattf | 2008-12-06 11:50:02 -0600 (Sat, 06 Dec 2008) | 1 line

Fix the point code output for ANSI networks on ss7 show linkset x
------------------------------------------------------------------------
r236 | mattf | 2008-12-06 12:45:01 -0600 (Sat, 06 Dec 2008) | 1 line

Change ss7_add_link API to include the Adjacent Point Code as well
------------------------------------------------------------------------
r237 | mattf | 2008-12-08 12:04:19 -0600 (Mon, 08 Dec 2008) | 1 line

Fix another mild code style problem in isup_handle_unexpected
------------------------------------------------------------------------
r238 | mattf | 2008-12-08 14:40:30 -0600 (Mon, 08 Dec 2008) | 1 line

Make sure we send GRS twice on ANSI links. Why, oh why, oh why?
------------------------------------------------------------------------
r239 | mattf | 2008-12-11 11:31:07 -0600 (Thu, 11 Dec 2008) | 1 line

Using this as development branch until we get ANSI support tested.  Starting on ISUP masquerade and clustering support, initial check in of this code.
------------------------------------------------------------------------
r240 | mattf | 2008-12-11 11:59:26 -0600 (Thu, 11 Dec 2008) | 1 line

Forgot to add the new isup_masq.c file
------------------------------------------------------------------------
r241 | mattf | 2008-12-11 13:42:57 -0600 (Thu, 11 Dec 2008) | 1 line

Fix some poll flags for TCP
------------------------------------------------------------------------
r242 | mattf | 2008-12-12 11:46:16 -0600 (Fri, 12 Dec 2008) | 1 line

A little more debug would help for short reads
------------------------------------------------------------------------
r243 | mattf | 2008-12-12 15:04:50 -0600 (Fri, 12 Dec 2008) | 1 line

Make sure TCP links default to UP
------------------------------------------------------------------------
r244 | mattf | 2008-12-12 15:06:38 -0600 (Fri, 12 Dec 2008) | 1 line

Give some sense of direction with message debug on TCP links
------------------------------------------------------------------------
r245 | mattf | 2008-12-12 15:33:40 -0600 (Fri, 12 Dec 2008) | 1 line

Take some of this code out for now...
------------------------------------------------------------------------
r246 | mattf | 2008-12-23 11:52:12 -0600 (Tue, 23 Dec 2008) | 1 line

Add support for working client side TCP!  Note: the message format will change, this is only for testing the socket code to make sure we have good read/write socket servicing code.
------------------------------------------------------------------------
r247 | mattf | 2008-12-23 16:10:31 -0600 (Tue, 23 Dec 2008) | 1 line

Add support for the new TCP message format
------------------------------------------------------------------------
r248 | mattf | 2008-12-24 17:20:01 -0600 (Wed, 24 Dec 2008) | 1 line

Milestone reached.  Able to forward messages to the given client properly with ISUP TCP masquerading
------------------------------------------------------------------------
r249 | mattf | 2009-01-06 18:36:40 -0600 (Tue, 06 Jan 2009) | 1 line

Masquerade functionality works in both directions.  Now we have to figure out what to do about TCP link state (losing the socket fd and replacing it with a new one when the link comes up again)
------------------------------------------------------------------------
r252 | mattf | 2009-01-24 15:59:06 -0600 (Sat, 24 Jan 2009) | 1 line

Change API so that we are able to handle IP based links that change file descriptors when they go up and down
------------------------------------------------------------------------
r253 | mattf | 2009-01-24 16:30:31 -0600 (Sat, 24 Jan 2009) | 1 line

Make sure that we pass a link down event up when the TCP link goes down
------------------------------------------------------------------------
r254 | mattf | 2009-02-11 03:50:31 -0600 (Wed, 11 Feb 2009) | 1 line

Add support for ANSI message priority in transmission...
------------------------------------------------------------------------

Added:
    trunk/isup_masq.c
      - copied unchanged from r256, team/mattf/bug13495/isup_masq.c
Modified:
    trunk/Makefile
    trunk/isup.c
    trunk/isup.h
    trunk/libss7.h
    trunk/mtp2.c
    trunk/mtp2.h
    trunk/mtp3.c
    trunk/mtp3.h
    trunk/parser_debug.c
    trunk/ss7.c
    trunk/ss7_internal.h
    trunk/ss7linktest.c
    trunk/ss7test.c

Modified: trunk/Makefile
URL: http://svn.digium.com/svn-view/libss7/trunk/Makefile?view=diff&rev=257&r1=256&r2=257
==============================================================================
--- trunk/Makefile (original)
+++ trunk/Makefile Thu Mar  5 11:53:06 2009
@@ -7,8 +7,8 @@
 INSTALL_PREFIX=$(DESTDIR)
 INSTALL_BASE=/usr
 libdir?=$(INSTALL_BASE)/lib
-STATIC_OBJS=mtp2.o ss7_sched.o ss7.o mtp3.o isup.o version.o
-DYNAMIC_OBJS=mtp2.o ss7_sched.o ss7.o mtp3.o isup.o version.o
+STATIC_OBJS=mtp2.o ss7_sched.o ss7.o mtp3.o isup.o version.o isup_masq.o
+DYNAMIC_OBJS=mtp2.o ss7_sched.o ss7.o mtp3.o isup.o version.o isup_masq.o
 STATIC_LIBRARY=libss7.a
 DYNAMIC_LIBRARY=libss7.so.1.0
 CFLAGS=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -g -fPIC
@@ -16,7 +16,7 @@
 SOFLAGS=-Wl,-hlibss7.so.1
 LDCONFIG=/sbin/ldconfig
 
-UTILITIES=parser_debug
+#UTILITIES=parser_debug
 
 ifneq ($(wildcard /usr/include/dahdi/user.h),)
 UTILITIES+=ss7test ss7linktest

Modified: trunk/isup.c
URL: http://svn.digium.com/svn-view/libss7/trunk/isup.c?view=diff&rev=257&r1=256&r2=257
==============================================================================
--- trunk/isup.c (original)
+++ trunk/isup.c Thu Mar  5 11:53:06 2009
@@ -31,10 +31,12 @@
 
 #include <string.h>
 #include <stdlib.h>
+#include <time.h>
 #include "libss7.h"
 #include "isup.h"
 #include "ss7_internal.h"
 #include "mtp3.h"
+#include "mtp2.h"
 
 #define FUNC_DUMP(name) int ((name))(struct ss7 *ss7, int messagetype, unsigned char *parm, int len)
 /* Length here is paramter length */
@@ -58,13 +60,22 @@
 	FUNC_SEND(*transmit);
 };
 
+struct isup_timer_param {
+	struct ss7 *ss7;
+	struct isup_call *c;
+	int timer;
+};
+
 static int iam_params[] = {ISUP_PARM_NATURE_OF_CONNECTION_IND, ISUP_PARM_FORWARD_CALL_IND, ISUP_PARM_CALLING_PARTY_CAT,
-	ISUP_PARM_TRANSMISSION_MEDIUM_REQS, ISUP_PARM_CALLED_PARTY_NUM, ISUP_PARM_CALLING_PARTY_NUM, -1};
+	ISUP_PARM_TRANSMISSION_MEDIUM_REQS, ISUP_PARM_CALLED_PARTY_NUM, ISUP_PARM_CALLING_PARTY_NUM, ISUP_PARM_REDIRECTING_NUMBER,
+	ISUP_PARM_REDIRECTION_INFO, ISUP_PARM_REDIRECT_COUNTER, ISUP_PARM_ORIGINAL_CALLED_NUM, ISUP_PARM_OPT_FORWARD_CALL_INDICATOR,
+	ISUP_PARM_CUG_INTERLOCK_CODE, -1};
 
 static int ansi_iam_params[] = {ISUP_PARM_NATURE_OF_CONNECTION_IND, ISUP_PARM_FORWARD_CALL_IND, ISUP_PARM_CALLING_PARTY_CAT,
 	ISUP_PARM_USER_SERVICE_INFO, ISUP_PARM_CALLED_PARTY_NUM, ISUP_PARM_CALLING_PARTY_NUM, ISUP_PARM_CHARGE_NUMBER, 
 	ISUP_PARM_ORIG_LINE_INFO, ISUP_PARM_GENERIC_ADDR, ISUP_PARM_GENERIC_DIGITS, ISUP_PARM_GENERIC_NAME, ISUP_PARM_JIP, 
-	ISUP_PARM_LOCAL_SERVICE_PROVIDER_IDENTIFICATION, -1};
+	ISUP_PARM_LOCAL_SERVICE_PROVIDER_IDENTIFICATION, ISUP_PARM_REDIRECTION_INFO, ISUP_PARM_REDIRECTING_NUMBER, ISUP_PARM_REDIRECT_COUNTER,
+	ISUP_PARM_ORIGINAL_CALLED_NUM, ISUP_PARM_OPT_FORWARD_CALL_INDICATOR, ISUP_PARM_CUG_INTERLOCK_CODE, -1};
 
 
 static int acm_params[] = {ISUP_PARM_BACKWARD_CALL_IND, -1};
@@ -73,9 +84,9 @@
 
 static int far_params[] = {ISUP_PARM_FACILITY_IND, ISUP_PARM_CALL_REF, -1};
 
-static int anm_params[] = { -1};
-
-static int con_params[] = { ISUP_PARM_BACKWARD_CALL_IND, -1};
+static int anm_params[] = { ISUP_CONNECTED_NUMBER, -1};
+
+static int con_params[] = { ISUP_PARM_BACKWARD_CALL_IND, ISUP_CONNECTED_NUMBER, -1};
 
 static int rel_params[] = { ISUP_PARM_CAUSE, -1};
 
@@ -88,6 +99,14 @@
 static int cicgroup_params[] = { ISUP_PARM_CIRCUIT_GROUP_SUPERVISION_IND, ISUP_PARM_RANGE_AND_STATUS, -1};
 
 static int cqr_params[] = { ISUP_PARM_RANGE_AND_STATUS, ISUP_PARM_CIRCUIT_STATE_IND, -1};
+
+static int susres_params[] = { ISUP_PARM_SUSRES_IND, ISUP_PARM_CALL_REF, -1};
+
+static int inr_params[] = { ISUP_PARM_INR_IND, -1};
+
+static int inf_params[] = { ISUP_PARM_INF_IND, ISUP_PARM_CALLING_PARTY_NUM, ISUP_PARM_CALLING_PARTY_CAT, -1};
+
+static int sam_params[] = { ISUP_PARM_SUBSEQUENT_NUMBER, -1};
 
 static int empty_params[] = { -1};
 
@@ -96,40 +115,51 @@
 	int mand_fixed_params;
 	int mand_var_params;
 	int opt_params;
+	int ansi_priority;
 	int *param_list;
 } messages[] = {
-	{ISUP_IAM, 4, 1, 1, iam_params},
-	{ISUP_ACM, 1, 0, 1, acm_params},
-	{ISUP_ANM, 0, 0, 1, anm_params},
-	{ISUP_CON, 1, 0, 1, con_params},
-	{ISUP_REL, 0, 1, 1, rel_params},
-	{ISUP_RLC, 0, 0, 1, empty_params},
-	{ISUP_GRS, 0, 1, 0, greset_params},
-	{ISUP_GRA, 0, 1, 0, greset_params},
-	{ISUP_CGB, 1, 1, 0, cicgroup_params},
-	{ISUP_CGU, 1, 1, 0, cicgroup_params},
-	{ISUP_CGBA, 1, 1, 0, cicgroup_params},
-	{ISUP_CGUA, 1, 1, 0, cicgroup_params},
-	{ISUP_COT, 1, 0, 0, cot_params},
-	{ISUP_CCR, 0, 0, 0, empty_params},
-	{ISUP_BLO, 0, 0, 0, empty_params},
-	{ISUP_LPA, 0, 0, 0, empty_params},
-	{ISUP_UBL, 0, 0, 0, empty_params},
-	{ISUP_BLA, 0, 0, 0, empty_params},
-	{ISUP_UBA, 0, 0, 0, empty_params},
-	{ISUP_RSC, 0, 0, 0, empty_params},
-	{ISUP_CVR, 0, 0, 0, empty_params},
-	{ISUP_CVT, 0, 0, 0, empty_params},
-	{ISUP_CPG, 1, 0, 1, cpg_params},
-	{ISUP_UCIC, 0, 0, 0, empty_params},
-	{ISUP_CQM, 0, 1, 0, greset_params},
-	{ISUP_CQR, 0, 2, 0, cqr_params},
-	{ISUP_FAA, 1, 0, 1, faa_params},
-	{ISUP_FAR, 1, 0, 1, far_params},
-	{ISUP_CFN, 0, 1, 0, rel_params}
+	{ISUP_IAM, 4, 1, 1, 0, iam_params},
+	{ISUP_ACM, 1, 0, 1, 1, acm_params},
+	{ISUP_ANM, 0, 0, 1, 2, anm_params},
+	{ISUP_CON, 1, 0, 1, -1, con_params},
+	{ISUP_REL, 0, 1, 1, 1, rel_params},
+	{ISUP_RLC, 0, 0, 1, 2, empty_params},
+	{ISUP_GRS, 0, 1, 0, 0, greset_params},
+	{ISUP_GRA, 0, 1, 0, 0, greset_params},
+	{ISUP_CGB, 1, 1, 0, 0, cicgroup_params},
+	{ISUP_CGU, 1, 1, 0, 0, cicgroup_params},
+	{ISUP_CGBA, 1, 1, 0, 0, cicgroup_params},
+	{ISUP_CGUA, 1, 1, 0, 0, cicgroup_params},
+	{ISUP_COT, 1, 0, 0, 1, cot_params},
+	{ISUP_CCR, 0, 0, 0, 1, empty_params},
+	{ISUP_BLO, 0, 0, 0, 0, empty_params},
+	{ISUP_LPA, 0, 0, 0, 1, empty_params},
+	{ISUP_UBL, 0, 0, 0, 0, empty_params},
+	{ISUP_BLA, 0, 0, 0, 0, empty_params},
+	{ISUP_UBA, 0, 0, 0, 0, empty_params},
+	{ISUP_RSC, 0, 0, 0, 0, empty_params},
+	{ISUP_CVR, 0, 0, 0, 0, empty_params},
+	{ISUP_CVT, 0, 0, 0, 0, empty_params},
+	{ISUP_CPG, 1, 0, 1, 1, cpg_params},
+	{ISUP_UCIC, 0, 0, 0, 1, empty_params},
+	{ISUP_CQM, 0, 1, 0, 0, greset_params},
+	{ISUP_CQR, 0, 2, 0, 0, cqr_params},
+	{ISUP_FAA, 1, 0, 1, -1, faa_params},
+	{ISUP_FAR, 1, 0, 1, -1, far_params},
+	{ISUP_CFN, 0, 1, 0, 0, rel_params},
+	{ISUP_SUS, 1, 0, 1, 1, susres_params},
+	{ISUP_RES, 1, 0, 1, 1, susres_params},
+	{ISUP_INR, 1, 0, 0, 1, inr_params},
+	{ISUP_INF, 1, 0, 2, 1, inf_params},
+	{ISUP_SAM, 0, 1, 0, -1, sam_params}
 };
 
 static int isup_send_message(struct ss7 *ss7, struct isup_call *c, int messagetype, int parms[]);
+
+static int isup_start_timer(struct ss7 *ss7, struct isup_call *c, int timer);
+static void isup_stop_all_timers(struct ss7 *ss7, struct isup_call *c);
+static int isup_timer2str(int timer, char *res);
+static void isup_stop_timer(struct ss7 *ss7, struct isup_call *c, int timer);
 
 static char * message2str(unsigned char message)
 {
@@ -140,6 +170,8 @@
 			return "ACM";
 		case ISUP_ANM:
 			return "ANM";
+		case ISUP_CON:
+			return "CON";
 		case ISUP_REL:
 			return "REL";
 		case ISUP_RLC:
@@ -188,6 +220,16 @@
 			return "CVR";
 		case ISUP_CFN:
 			return "CFN";
+		case ISUP_SUS:
+			return "SUS";
+		case ISUP_RES:
+			return "RES";
+		case ISUP_INR:
+			return "INR";
+		case ISUP_INF:
+			return "INF";
+		case ISUP_SAM:
+			return "SAM";
 		default:
 			return "Unknown";
 	}
@@ -323,6 +365,9 @@
 	if (c->cot_check_required)
 		parm[0] |= 0x04;
 
+	if (c->local_echocontrol_ind)
+		parm[0] |= 0x10;
+
 	return 1; /* Length plus size of type header */
 }
 
@@ -335,6 +380,11 @@
 	else
 		c->cot_check_required = 0;
 
+	if (parm[0] & 0x10)
+		c->echocontrol_ind = 1;
+	else
+		c->echocontrol_ind = 0;
+	
 	return 1;
 }
 
@@ -622,6 +672,7 @@
 static FUNC_RECV(backward_call_ind_receive)
 {
 	c->called_party_status_ind = (parm[0] >> 2) & 0x3;
+	c->echocontrol_ind = (parm[1] >> 5) & 0x1;
 	return 2;
 }
 
@@ -629,6 +680,8 @@
 {
 	parm[0] = 0x40;
 	parm[1] = 0x14;
+	if (c->local_echocontrol_ind)
+		parm[1] |= 0x20;
 	return 2;
 }
 
@@ -681,6 +734,50 @@
 	return 1;
 }
 
+static FUNC_DUMP(opt_forward_call_ind_dump)
+{
+	char *desc;
+	
+	switch (parm[0] & 0x03) {
+	case ISUP_CUG_NON:
+		desc = "non-CUG call";
+		break;
+	case ISUP_CUG_OUTGOING_ALLOWED:
+		desc = "closed user group call, outgoing access allowed";
+		break;
+	case ISUP_CUG_OUTGOING_NOT_ALLOWED:
+		desc = "closed user group call, outgoing access not allowed";
+		break;
+	default:
+		desc = "spare";
+	}
+	
+	ss7_message(ss7, "\t\t\tClosed user group call indicator: %s\n", desc);
+	ss7_message(ss7, "\t\t\tSimple segmentation indicator: %s\n", (parm[0] & (1 << 2)) ? 
+			"additional information will be sent in segmentation message" :
+			"no additional message will be sent");
+	ss7_message(ss7, "\t\t\tConnected line identify request indicator %s\n", (parm[0] & (1 << 7)) ?
+			"requested": "not requested");
+	
+	return 1;
+}
+
+static FUNC_SEND(opt_forward_call_ind_transmit)
+{
+	if (c->col_req || c->cug_indicator) {
+		parm[0] = (c->cug_indicator & 0x03) | (c->col_req << 7);
+		return 1;
+	} else
+		return 0;
+}
+
+static FUNC_RECV(opt_forward_call_ind_receive)
+{
+	c->cug_indicator = parm[0] & 0x03;
+	c->col_req = parm[0] >> 7;
+	return 1;
+}
+
 static FUNC_RECV(cause_receive)
 {
 	c->causeloc = parm[0] & 0xf;
@@ -846,15 +943,9 @@
 
 	statuslen = (numcics / 8) + !!(numcics % 8);
 
-	if (messagetype == ISUP_GRA) {
-		for (i = 0; i < statuslen; i++) {
-			parm[1 + i] = 0;
-		}
-	} else {
-		for (i = 0; i < numcics; i++) {
-			if (c->status[i])
-				parm[1 + (i/8)] |= (1 << (i % 8));
-		}
+	for (i = 0; i < numcics; i++) {
+		if (c->status[i])
+			parm[1 + (i/8)] |= (1 << (i % 8));
 	}
 
 	return statuslen + 1;
@@ -896,16 +987,74 @@
 {
 	int oddeven, datalen;
 
-	if (!c->calling_party_num[0])
+	if (!c->calling_party_num[0] && c->presentation_ind != SS7_PRESENTATION_ADDR_NOT_AVAILABLE)
 		return 0;
 
-	isup_put_number(&parm[2], c->calling_party_num, &datalen, &oddeven);
+	if (c->calling_party_num[0] && c->presentation_ind != SS7_PRESENTATION_ADDR_NOT_AVAILABLE)
+		isup_put_number(&parm[2], c->calling_party_num, &datalen, &oddeven);
+	else {
+		datalen = 0;
+		oddeven = 0;
+		c->calling_nai = 0;
+	}
 
 	parm[0] = (oddeven << 7) | c->calling_nai;      /* Nature of Address Indicator */
-	parm[1] = (1 << 4) |                            /* Assume E.164 ISDN numbering plan, calling number complete */
+	 /* Assume E.164 ISDN numbering plan, calling number complete */
+	parm[1] = ((c->presentation_ind == SS7_PRESENTATION_ADDR_NOT_AVAILABLE) ? 0 : (1 << 4)) |
 		((c->presentation_ind & 0x3) << 2) |
 		(c->screening_ind & 0x3);
-
+	
+	return datalen + 2;
+}
+
+static FUNC_DUMP(connected_num_dump)
+{
+	int oddeven = (parm[0] >> 7) & 0x1;
+	char numbuf[64] = "";
+
+	ss7_message(ss7, "\t\t\tNature of address: %x\n", parm[0] & 0x7f);
+	ss7_message(ss7, "\t\t\tNumbering plan: %x\n", (parm[1] >> 4) & 0x7);
+	ss7_message(ss7, "\t\t\tPresentation: %x\n", (parm[1] >> 2) & 0x3);
+	ss7_message(ss7, "\t\t\tScreening: %x\n", parm[1] & 0x3);
+
+	isup_get_number(numbuf, &parm[2], len - 2, oddeven);
+
+	ss7_message(ss7, "\t\t\tAddress signals: %s\n", numbuf);
+
+	return len;
+}
+
+static FUNC_RECV(connected_num_receive)
+{
+	int oddeven = (parm[0] >> 7) & 0x1;
+
+	isup_get_number(c->connected_num, &parm[2], len - 2, oddeven);
+
+	c->connected_nai = parm[0] & 0x7f;                /* Nature of Address Indicator */
+	c->connected_presentation_ind = (parm[1] >> 2) & 0x3;
+	c->connected_screening_ind = parm[1] & 0x3;
+
+	return len;
+
+}
+
+static FUNC_SEND(connected_num_transmit)
+{
+	int oddeven = 0, datalen = 0;
+
+	if (!c->col_req)
+		return 0; /* if they don't ask we won't tell */
+	
+
+	if (!c->connected_num[0])
+		c->connected_presentation_ind = SS7_PRESENTATION_ADDR_NOT_AVAILABLE;
+	else
+		isup_put_number(&parm[2], c->connected_num, &datalen, &oddeven);
+
+	
+	parm[0] = (oddeven << 7) | c->connected_nai;      /* Nature of Address Indicator */
+	 /* Assume E.164 ISDN numbering plan, calling number complete */
+	parm[1] = ((c->connected_presentation_ind & 0x3) << 2) | (c->connected_screening_ind & 0x3);
 	return datalen + 2;
 }
 
@@ -1394,7 +1543,7 @@
 
 	switch ((parm[1] >> 4) & 0xf) {
 		case 0:
-			orig_redir_reas = "Unknown/not available";
+			redir_reas = "Unknown/not available";
 			break;
 		case 1:
 			redir_reas = "User busy";
@@ -1426,11 +1575,21 @@
 
 static FUNC_RECV(redirection_info_receive)
 {
+	c->redirect_info = 1;
+	c->redirect_info_ind = parm[0] & 0x7;
+	c->redirect_info_orig_reas = (parm[0] >> 4) & 0xf;
+	c->redirect_info_counter = parm[1] & 0x7;
+	c->redirect_info_reas = (parm[1] >> 4) & 0xf;
 	return 2;
 }
 
 static FUNC_SEND(redirection_info_transmit)
 {
+	if (!c->redirect_info)
+		return 0;
+
+	parm[0] = (c->redirect_info_ind & 0x7) | ((c->redirect_info_orig_reas << 4) & 0xf0);
+	parm[1] = (c->redirect_info_counter & 0x7) | ((c->redirect_info_reas << 4) & 0xf0); 
 	return 2;
 }
 
@@ -1607,7 +1766,19 @@
 
 static FUNC_SEND(original_called_num_transmit)
 {
-	return len;
+	int oddeven, datalen;
+
+	if (!c->orig_called_num[0])
+		return 0;
+
+	isup_put_number(&parm[2], c->orig_called_num, &datalen, &oddeven);
+
+	parm[0] = (oddeven << 7) | c->orig_called_nai;      /* Nature of Address Indicator */
+	parm[1] = (1 << 4) |                            /* Assume E.164 ISDN numbering plan, calling number complete */
+		((c->orig_called_pres_ind & 0x3) << 2) |
+		(c->orig_called_screening_ind & 0x3);
+
+	return datalen + 2;
 }
 
 static FUNC_DUMP(echo_control_info_dump)
@@ -1813,6 +1984,99 @@
 }
 
 static FUNC_RECV(tns_receive)
+{
+	return len;
+}
+
+static FUNC_DUMP(generic_notofication_ind_dump)
+{
+	int pos = 0;
+	ss7_message(ss7, "\t\t\tNotification indicator: ");
+	
+	while (pos < len && (pos || !(parm[pos - 1] & 0x80))) {
+		switch (parm[pos] & 0x7f) {
+			case 0x00:
+				ss7_message(ss7, "user suspended; ");
+				break;
+			case 0x01:
+				ss7_message(ss7, "user resumed; ");
+				break;
+			case 0x02:
+				ss7_message(ss7, "bearer service change; ");
+				break;
+			case 0x03:
+				ss7_message(ss7, "discriminator for extension to ASN.1; ");
+				break;
+			case 0x04:
+				ss7_message(ss7, "call completion delay; ");
+				break;
+			case 0x42:
+				ss7_message(ss7, "conference established; ");
+				break;
+			case 0x43:
+				ss7_message(ss7, "conference disconnected; ");
+				break;
+			case 0x44:
+				ss7_message(ss7, "other party added; ");
+				break;
+			case 0x45:
+				ss7_message(ss7, "isolated; ");
+				break;
+			case 0x46:
+				ss7_message(ss7, "reattached; ");
+				break;
+			case 0x47:
+				ss7_message(ss7, "other party isolated; ");
+				break;
+			case 0x48:
+				ss7_message(ss7, "other party reattached; ");
+				break;
+			case 0x49:
+				ss7_message(ss7, "other party split; ");
+				break;
+			case 0x4a:
+				ss7_message(ss7, "other party disconnected; ");
+				break;
+			case 0x4b:
+				ss7_message(ss7, "other party floating; ");
+				break;
+			case 0x60:
+				ss7_message(ss7, "call is a waiting call; ");
+				break;
+			case 0x68:
+				ss7_message(ss7, "diversion activated; ");
+				break;
+			case 0x69:
+				ss7_message(ss7, "call transfer, alerting; ");
+				break;
+			case 0x6a:
+				ss7_message(ss7, "call transfer, active; ");
+				break;
+			case 0x79:
+				ss7_message(ss7, "remote hold; ");
+				break;
+			case 0x7a:
+				ss7_message(ss7, "remote retrieval; ");
+				break;
+			case 0x7b:
+				ss7_message(ss7, "remote is diverting; ");
+				break;
+				
+			default:
+				ss7_message(ss7, "reserved; ");
+		}
+		pos++;
+	}
+	ss7_message(ss7, "\n");
+	return len;
+}
+
+static FUNC_SEND(generic_notofication_ind_transmit)
+{
+	return 0;
+}
+
+static FUNC_RECV(generic_notofication_ind_receive)
 {
 	return len;
 }
@@ -1955,8 +2219,110 @@
 
 static FUNC_SEND(redirecting_number_transmit)
 {
-	return 0;	
+	int oddeven, datalen;
+
+	if (!c->redirecting_num[0])
+		return 0;
+
+	isup_put_number(&parm[2], c->redirecting_num, &datalen, &oddeven);
+	parm[0] = (oddeven << 7) | c->redirecting_num_nai;      /* Nature of Address Indicator */
+	parm[1] = (1 << 4) |                            /* Assume E.164 ISDN numbering plan, calling number complete */
+		((c->redirecting_num_presentation_ind & 0x3) << 2) |
+		(c->redirecting_num_screening_ind & 0x3);
+
+	return datalen + 2;
 }	
+
+static FUNC_DUMP(redirect_counter_dump)
+{
+	ss7_message(ss7, "\t\t\tRedirect count: %i\n", parm[0] & 0x1f);
+	return 1;
+}
+
+static FUNC_RECV(redirect_counter_receive)
+{
+	c->redirect_counter = parm[0] & 0x1f;
+	return 1;
+}
+
+static FUNC_SEND(redirect_counter_transmit)
+{
+	if (!c->redirect_counter)
+		return 0;
+
+	parm[0] = c->redirect_counter & 0x1f;
+	return 1;
+}
+
+static FUNC_DUMP(susres_ind_dump)
+{
+	ss7_message(ss7, "\t\t\tSUS/RES indicator: %s (%i)\n", (parm[0] & 1) ? "network initiated" : "ISDN subscriber initiated", parm[0] & 1);
+	return 1;
+}
+
+static FUNC_RECV(susres_ind_receive)
+{
+	c->susres_ind = parm[0] & 1;
+	return 1;
+}
+
+static FUNC_SEND(susres_ind_transmit)
+{
+	parm[0] = c->susres_ind & 1;
+	return 1;
+}
+
+static FUNC_DUMP(inr_ind_dump)
+{
+	ss7_message(ss7, "\t\t\tCalling party address %srequested\n", (parm[0] & 0x1) ? "" : "not ");
+	ss7_message(ss7, "\t\t\tHolding %srequested\n", (parm[0] & 0x2) ? "" : "not ");
+	ss7_message(ss7, "\t\t\tCalling party category %srequested\n", (parm[0] & 0x8) ? "" : "not ");
+	ss7_message(ss7, "\t\t\tCharge information %srequested\n", (parm[0] & 0x10) ? "" : "not ");
+	ss7_message(ss7, "\t\t\tMalicous call identification %srequested\n", (parm[0] & 0x80) ? "" : "not ");
+	return 2;
+}
+
+static FUNC_RECV(inr_ind_receive)
+{
+	c->inr_ind[0] = parm[0];
+	c->inr_ind[1] = parm[1];
+	return 2;
+}
+
+static FUNC_SEND(inr_ind_transmit)
+{
+	parm[0] = c->inr_ind[0];
+	parm[1] = c->inr_ind[1];
+	return 2;
+}
+
+static FUNC_DUMP(inf_ind_dump)
+{
+	ss7_message(ss7, "\t\t\tCalling party address: %s\n",
+		(parm[0] & 0x2) ? ((parm[0] & 0x1) ? "included" : "spare" ) : ((parm[0] & 0x1) ? "not available" : "not included") );
+	ss7_message(ss7, "\t\t\tHold: %sprovided\n", (parm[0] & 0x4) ? "" : "not ");
+	ss7_message(ss7, "\t\t\tCalling party's category %sincluded\n", (parm[0] & 0x20) ? "" : "not ");
+	ss7_message(ss7, "\t\t\tCharge information %sincluded\n", (parm[0] & 0x40) ? "" : "not ");
+	ss7_message(ss7, "\t\t\t%s\n", (parm[0] & 0x80) ? "Unsolicated" : "Solicated");
+
+	return 2;
+}
+
+static FUNC_RECV(inf_ind_receive)
+{
+	c->inf_ind[0] = parm[0];
+	c->inf_ind[1] = parm[1];
+	if ((parm[0] & 0x3) == 0x1)
+		c->presentation_ind = SS7_PRESENTATION_ADDR_NOT_AVAILABLE;
+	return 2;	
+}
+
+static FUNC_SEND(inf_ind_transmit)
+{
+	parm[0] = c->inf_ind[0];
+	parm[1] = c->inf_ind[1];
+	return 2;
+}
 
 static FUNC_DUMP(access_transport_dump)
 {
@@ -1972,6 +2338,79 @@
 	return len;	
 }	
 
+static FUNC_DUMP(subs_num_dump)
+{
+	int oddeven = (parm[0] >> 7) & 0x1;
+	char numbuf[64];
+
+	isup_get_number(numbuf, &parm[1], len - 1, oddeven);
+	ss7_message(ss7, "\t\t\tSubsequent signals: %s\n", numbuf);
+	
+	return len;
+}
+
+static FUNC_RECV(subs_num_receive)
+{
+	int oddeven = (parm[0] >> 7) & 0x1;
+
+	isup_get_number(c->called_party_num, &parm[1], len - 1, oddeven);
+
+	return len;
+}
+
+static FUNC_SEND(subs_num_transmit)
+{
+	int oddeven, datalen;
+
+	isup_put_number(&parm[1], c->called_party_num, &datalen, &oddeven);
+	parm[0] = (oddeven << 7);
+
+	return datalen + 1;
+}
+
+static FUNC_DUMP(cug_interlock_code_dump)
+{
+	char ni[5];
+	unsigned short code;
+	
+	ni[0] = digit2char(parm[0] >> 4);
+	ni[1] = digit2char(parm[0] & 0x0f);
+	ni[2] = digit2char(parm[1] >> 4);
+	ni[3] = digit2char(parm[1] & 0x0f);
+	ni[4] = '\0';
+	
+	code = (parm[2] << 8) | parm [3];
+
+	ss7_message(ss7, "\t\t\tNetwork Identify: %s\n", ni);
+	ss7_message(ss7, "\t\t\tBinary Code: %d\n", code);
+	return 4;
+}
+
+static FUNC_RECV(cug_interlock_code_receive)
+{
+	c->cug_interlock_ni[0] = digit2char(parm[0] >> 4);
+	c->cug_interlock_ni[1] = digit2char(parm[0] & 0x0f);
+	c->cug_interlock_ni[2] = digit2char(parm[1] >> 4);
+	c->cug_interlock_ni[3] = digit2char(parm[1] & 0x0f);
+	c->cug_interlock_ni[4] = '\0';
+	
+	c->cug_interlock_code = (parm[2] << 8) | parm [3];
+	return 4;
+}
+
+static FUNC_SEND(cug_interlock_code_transmit)
+{
+	if (!(c->cug_indicator == ISUP_CUG_OUTGOING_ALLOWED || c->cug_indicator == ISUP_CUG_OUTGOING_NOT_ALLOWED))
+		return 0;
+		
+	parm[0] = (char2digit(c->cug_interlock_ni[0]) << 4) | char2digit(c->cug_interlock_ni[1]);
+	parm[1] = (char2digit(c->cug_interlock_ni[2]) << 4) | char2digit(c->cug_interlock_ni[3]);
+	
+	parm[2] = c->cug_interlock_code >> 8;
+	parm[3] = c->cug_interlock_code & 0xff;
+		
+	return 4;
+}
 
 static struct parm_func parms[] = {
 	{ISUP_PARM_NATURE_OF_CONNECTION_IND, "Nature of Connection Indicator", nature_of_connection_ind_dump, nature_of_connection_ind_receive, nature_of_connection_ind_transmit },
@@ -1991,13 +2430,13 @@
 	{ISUP_PARM_CHARGE_NUMBER, "Charge Number", charge_number_dump, charge_number_receive, charge_number_transmit},
 	{ISUP_PARM_CIRCUIT_ASSIGNMENT_MAP, "Circuit Assignment Map"},
 	{ISUP_PARM_CONNECTION_REQ, "Connection Request"},
-	{ISUP_PARM_CUG_INTERLOCK_CODE, "Interlock Code"},
+	{ISUP_PARM_CUG_INTERLOCK_CODE, "Interlock Code", cug_interlock_code_dump, cug_interlock_code_receive, cug_interlock_code_transmit},
 	{ISUP_PARM_EGRESS_SERV, "Egress Service"},
 	{ISUP_PARM_GENERIC_ADDR, "Generic Address", generic_address_dump, generic_address_receive, generic_address_transmit},
 	{ISUP_PARM_GENERIC_DIGITS, "Generic Digits", generic_digits_dump, generic_digits_receive, generic_digits_transmit},
 	{ISUP_PARM_GENERIC_NAME, "Generic Name", generic_name_dump, generic_name_receive, generic_name_transmit},
 	{ISUP_PARM_TRANSIT_NETWORK_SELECTION, "Transit Network Selection", tns_dump, tns_receive, tns_transmit},
-	{ISUP_PARM_GENERIC_NOTIFICATION_IND, "Generic Notification Indication"},
+	{ISUP_PARM_GENERIC_NOTIFICATION_IND, "Generic Notification Indication", generic_notofication_ind_dump, generic_notofication_ind_receive, generic_notofication_ind_transmit},
 	{ISUP_PARM_PROPAGATION_DELAY, "Propagation Delay Counter", propagation_delay_cntr_dump},
 	{ISUP_PARM_HOP_COUNTER, "Hop Counter", hop_counter_dump, hop_counter_receive, hop_counter_transmit},
 	{ISUP_PARM_BACKWARD_CALL_IND, "Backward Call Indicator", backward_call_ind_dump, backward_call_ind_receive, backward_call_ind_transmit},
@@ -2005,7 +2444,7 @@
 	{ISUP_PARM_CIRCUIT_GROUP_SUPERVISION_IND, "Circuit Group Supervision Indicator", circuit_group_supervision_dump, circuit_group_supervision_receive, circuit_group_supervision_transmit},
 	{ISUP_PARM_RANGE_AND_STATUS, "Range and status", range_and_status_dump, range_and_status_receive, range_and_status_transmit},
 	{ISUP_PARM_EVENT_INFO, "Event Information", event_info_dump, event_info_receive, event_info_transmit},
-	{ISUP_PARM_OPT_FORWARD_CALL_INDICATOR, "Optional forward call indicator"},
+	{ISUP_PARM_OPT_FORWARD_CALL_INDICATOR, "Optional forward call indicator", opt_forward_call_ind_dump, opt_forward_call_ind_receive, opt_forward_call_ind_transmit},
 	{ISUP_PARM_LOCATION_NUMBER, "Location Number"},
 	{ISUP_PARM_ORIG_LINE_INFO, "Originating line information", originating_line_information_dump, originating_line_information_receive, originating_line_information_transmit},
 	{ISUP_PARM_REDIRECTION_INFO, "Redirection Information", redirection_info_dump, redirection_info_receive, redirection_info_transmit},
@@ -2018,6 +2457,12 @@
 	{ISUP_PARM_FACILITY_IND, "Facility Indicator", facility_ind_dump, facility_ind_receive, facility_ind_transmit},
 	{ISUP_PARM_REDIRECTING_NUMBER, "Redirecting Number", redirecting_number_dump, redirecting_number_receive, redirecting_number_transmit},
 	{ISUP_PARM_ACCESS_DELIVERY_INFO, "Access Delivery Information", },
+	{ISUP_PARM_REDIRECT_COUNTER, "Redirect Counter", redirect_counter_dump, redirect_counter_receive, redirect_counter_transmit},
+	{ISUP_PARM_SUSRES_IND, "SUS/RES Indicator", susres_ind_dump, susres_ind_receive, susres_ind_transmit},
+	{ISUP_PARM_INR_IND, "Information Request Indicators", inr_ind_dump, inr_ind_receive, inr_ind_transmit},
+	{ISUP_PARM_INF_IND, "Information Indicators", inf_ind_dump, inf_ind_receive, inf_ind_transmit},
+	{ISUP_PARM_SUBSEQUENT_NUMBER, "Subsequent Number", subs_num_dump, subs_num_receive, subs_num_transmit},
+	{ISUP_CONNECTED_NUMBER, "Connected Number", connected_num_dump, connected_num_receive, connected_num_transmit}
 };
 
 static char * param2str(int parm)
@@ -2033,7 +2478,12 @@
 
 static void init_isup_call(struct isup_call *c)
 {
+	int x;
+	for (x = 0; x < ISUP_MAX_TIMERS; x++)
+		c->timer[x] = -1;
 	c->oli_ani2 = -1;
+	c->range = 0;
+	c->got_sent_msg = 0;
 }
 
 static struct isup_call * __isup_new_call(struct ss7 *ss7, int nolink)
@@ -2079,7 +2529,6 @@
 			snprintf(c->called_party_num, sizeof(c->called_party_num), "%s", called);
 		c->called_nai = called_nai;
 	}
-
 }
 
 void isup_set_oli(struct isup_call *c, int oli_ani2)
@@ -2089,12 +2538,75 @@
 
 void isup_set_calling(struct isup_call *c, const char *calling, unsigned char calling_nai, unsigned char presentation_ind, unsigned char screening_ind)
 {
-	if (calling && calling[0]) {
-		strncpy(c->calling_party_num, calling, sizeof(c->calling_party_num));
+	if ((calling && calling[0]) || presentation_ind == SS7_PRESENTATION_ADDR_NOT_AVAILABLE) {
+		if (calling)
+			strncpy(c->calling_party_num, calling, sizeof(c->calling_party_num));
 		c->calling_nai = calling_nai;
 		c->presentation_ind = presentation_ind;
 		c->screening_ind = screening_ind;
 	}
+}
+
+void isup_set_connected(struct isup_call *c, const char *connected, unsigned char connected_nai, unsigned char connected_presentation_ind, unsigned char connected_screening_ind) {
+	if ((connected && connected[0]) || connected_presentation_ind == SS7_PRESENTATION_ADDR_NOT_AVAILABLE) {
+		if (connected)
+			strncpy(c->connected_num, connected, sizeof(c->connected_num));
+		c->connected_nai = connected_nai;
+		c->connected_presentation_ind = connected_presentation_ind;
+		c->connected_screening_ind = connected_screening_ind;
+	}
+}
+
+void isup_set_redirecting_number(struct isup_call *c, const char *redirecting_number, unsigned char redirecting_num_nai, unsigned char redirecting_num_presentation_ind, unsigned char redirecting_num_screening_ind)
+{
+	if (redirecting_number && redirecting_number[0]) {
+		strncpy(c->redirecting_num, redirecting_number, sizeof(c->redirecting_num));
+		c->redirecting_num_nai = redirecting_num_nai;
+		c->redirecting_num_presentation_ind = redirecting_num_presentation_ind;
+		c->redirecting_num_screening_ind = redirecting_num_screening_ind;
+	}
+}
+
+void isup_set_redirectiong_info(struct isup_call *c, unsigned char redirect_info_ind, unsigned char redirect_info_orig_reas,
+	unsigned char redirect_info_counter, unsigned char redirect_info_reas)
+{
+	c->redirect_info = 1;
+	c->redirect_info_ind = redirect_info_ind;
+	c->redirect_info_orig_reas = redirect_info_orig_reas;
+	c->redirect_info_counter = redirect_info_counter;
+	c->redirect_info_reas = redirect_info_reas;
+}
+
+void isup_set_redirect_counter(struct isup_call *c, unsigned char redirect_counter)
+{
+	c->redirect_counter = redirect_counter;
+}
+
+void isup_set_orig_called_num(struct isup_call *c, const char *orig_called_num, unsigned char orig_called_nai, unsigned char orig_called_pres_ind, unsigned char orig_called_screening_ind)
+{
+	if (orig_called_num && orig_called_num[0]) {
+		strncpy(c->orig_called_num, orig_called_num, sizeof(c->orig_called_num));
+		c->orig_called_nai = orig_called_nai;
+		c->orig_called_pres_ind = orig_called_pres_ind;
+		c->orig_called_screening_ind = orig_called_screening_ind;
+	}
+}
+
+void isup_set_col_req(struct isup_call *c)
+{
+	c->col_req = 1;
+}
+
+void isup_set_cug(struct isup_call *c, unsigned char cug_indicator, const char *cug_interlock_ni, unsigned short cug_interlock_code)
+{
+	c->cug_indicator = cug_indicator;
+	strncpy(c->cug_interlock_ni, cug_interlock_ni, sizeof(c->cug_interlock_ni));
+	c->cug_interlock_code = cug_interlock_code;
+}
+
+void isup_set_echocontrol(struct isup_call *c, unsigned char ec)
+{
+	c->local_echocontrol_ind = ec;
 }
 
 void isup_set_charge(struct isup_call *c, const char *charge, unsigned char charge_nai, unsigned char charge_num_plan)
@@ -2194,9 +2706,12 @@
 	return winner;
 }
 
-static void isup_free_call(struct ss7 *ss7, struct isup_call *c)
+void isup_free_call(struct ss7 *ss7, struct isup_call *c)
 {
 	struct isup_call *cur, *prev = NULL, *winner = NULL;
+	
+	if (!ss7 || !c)
+		return;
 
 	cur = ss7->calls;
 	while (cur) {
@@ -2213,9 +2728,12 @@
 			ss7->calls = winner->next;
 		else
 			prev->next = winner->next;
-	}
-
-	free(c);
+
+		isup_stop_all_timers(ss7, c);
+		free(c);
+	} else
+		ss7_error(ss7, "Requested free an unlinked call!!!\n");
+
 
 	return;
 }
@@ -2338,6 +2856,7 @@
 	int offset = 0;
 	int x = 0;
 	int i = 0;
+	int priority = -1;
 
 	/* Do init stuff */
 	msg = ss7_msg_new();
@@ -2381,6 +2900,7 @@
 	fixedparams = messages[ourmessage].mand_fixed_params;
 	varparams = messages[ourmessage].mand_var_params;
 	optparams = messages[ourmessage].opt_params;
+	priority = messages[ourmessage].ansi_priority;
 
 	/* Again, the ANSI exception */
 	if (ss7->switchtype == SS7_ANSI) {
@@ -2389,6 +2909,10 @@
 			varparams = 2;
 		} else if (messages[ourmessage].messagetype == ISUP_RLC) {
 			optparams = 0;
+		} else if (messages[ourmessage].messagetype == ISUP_GRS) {
+			optparams = 1;
+		} else if (messages[ourmessage].messagetype == ISUP_GRA) {
+			optparams = 1;
 		}
 	}
 
@@ -2461,7 +2985,7 @@
 
 	ss7_msg_userpart_len(msg, offset + rlsize + CIC_SIZE + 1);   /* Message type length is 1 */
 
-	return mtp3_transmit(ss7, SIG_ISUP, rl.sls, msg);
+	return mtp3_transmit(ss7, SIG_ISUP, rl, priority, msg);
 }
 
 int isup_dump(struct ss7 *ss7, struct mtp2 *link, unsigned char *buf, int len)
@@ -2473,10 +2997,12 @@
 	int offset = 0;
 	int fixedparams = 0, varparams = 0, optparams = 0;
 	int res, x;
-	unsigned char *opt_ptr = NULL;
+	unsigned char *param_pointer = NULL;
 
 	mh = (struct isup_h*) buf;
 
+	len -= 3; /* ISUP msg header size !*/
+	
 	if (ss7->switchtype == SS7_ITU) {
 		cic = mh->cic[0] | ((mh->cic[1] & 0x0f) << 8);
 	} else {
@@ -2531,33 +3057,44 @@
 		offset += res;
 	}
 
+	if (len < 1)
+		return 0;
+
+	if (varparams || optparams) {
+		param_pointer = &mh->data[offset];
+	} else
+		return 0;
+
+	x = 0;
 	if (varparams) {
-		offset += varparams; /* add one for the optionals */
-		len -= varparams;
-	}
+		ss7_message(ss7, "\t\t--VARIABLE LENGTH PARMS[%d]--\n", varparams); 
+		
+		for (; x < varparams && len > 0; x++) {
+			if (!param_pointer[0])
+				return 0;
+			res = dump_parm(ss7, mh->type, parms[fixedparams + x], 
+					(void *)(param_pointer + param_pointer[0]), len, PARM_TYPE_VARIABLE);
+		
+			if (res < 0) {
+				ss7_error(ss7, "!! Unable to parse mandatory variable parameter '%s'\n", param2str(parms[fixedparams + x]));
+				return -1;
+			}
+			len -= (res + 1); /* 1byte for pointer */
+			param_pointer++;
+			offset++;
+		}
+	}
+	
+	if (len < 1 || !param_pointer[0])
+		return 0;
+
+	/* Optional paramter parsing code */
 	if (optparams) {
-		opt_ptr = &mh->data[offset++];
-		len++;
-	}
-
-	if (varparams)
-		ss7_message(ss7, "\t\t--VARIABLE LENGTH PARMS[%d]--\n", varparams);
-	for (; (x - fixedparams) < varparams; x++) {
-		res = dump_parm(ss7, mh->type, parms[x], (void *)(mh->data + offset), len, PARM_TYPE_VARIABLE);
-
-		if (res < 0) {
-			ss7_error(ss7, "!! Unable to parse mandatory variable parameter '%s'\n", param2str(parms[x]));
-			return -1;
-		}
-
-		len -= res;
-		offset += res;
-	}
-
-	/* Optional paramter parsing code */
-	if (optparams && *opt_ptr) {
-		if (len > 0)
-			ss7_message(ss7, "\t\t--OPTIONAL PARMS--\n");
+			
+		ss7_message(ss7, "\t\t--OPTIONAL PARMS--\n");
+		offset += param_pointer[0];
+		len-- ; /* optional parameter pointer */
+		
 		while ((len > 0) && (mh->data[offset] != 0)) {
 			struct isup_parm_opt *optparm = (struct isup_parm_opt *)(mh->data + offset);
 
@@ -2577,6 +3114,36 @@
 	}
 
 	return 0;
+}
+
+/* Checking we whether got more 1 bits back in the status */
+static int isup_check_status(unsigned char *sent_status, unsigned char *got_status, int range)
+{
+	int i;
+	for (i = 0; i <= range; i++)
+		if (got_status[i] > sent_status[i])
+			return 1;
+
+	return 0;
+}
+

[... 6135 lines stripped ...]



More information about the svn-commits mailing list