[libpri-commits] rmudgett: branch group/issue14068 r741 - /team/group/issue14068/

SVN commits to the libpri project libpri-commits at lists.digium.com
Wed Apr 15 18:36:18 CDT 2009


Author: rmudgett
Date: Wed Apr 15 18:36:15 2009
New Revision: 741

URL: http://svn.digium.com/svn-view/libpri?view=rev&rev=741
Log:
Merged revision 740 from
http://svn.digium.com/svn/libpri/team/rmudgett/facility

..........
r740 | rmudgett | 2009-04-15 16:15:52 -0500 (Wed, 15 Apr 2009) | 5 lines

ROSE ASN.1 facility encode and decode rewrite of existing messages.

Several components are now parsed correctly.  Most notably:
PartyNumber and Q.SIG Name.

Added:
    team/group/issue14068/asn1.h
      - copied unchanged from r740, team/rmudgett/facility/asn1.h
    team/group/issue14068/asn1_primitive.c
      - copied unchanged from r740, team/rmudgett/facility/asn1_primitive.c
    team/group/issue14068/rose.c
      - copied unchanged from r740, team/rmudgett/facility/rose.c
    team/group/issue14068/rose.h
      - copied unchanged from r740, team/rmudgett/facility/rose.h
    team/group/issue14068/rose_address.c
      - copied unchanged from r740, team/rmudgett/facility/rose_address.c
    team/group/issue14068/rose_etsi_aoc.c
      - copied unchanged from r740, team/rmudgett/facility/rose_etsi_aoc.c
    team/group/issue14068/rose_internal.h
      - copied unchanged from r740, team/rmudgett/facility/rose_internal.h
    team/group/issue14068/rose_other.c
      - copied unchanged from r740, team/rmudgett/facility/rose_other.c
    team/group/issue14068/rose_q931.c
      - copied unchanged from r740, team/rmudgett/facility/rose_q931.c
    team/group/issue14068/rose_qsig_ct.c
      - copied unchanged from r740, team/rmudgett/facility/rose_qsig_ct.c
    team/group/issue14068/rose_qsig_diversion.c
      - copied unchanged from r740, team/rmudgett/facility/rose_qsig_diversion.c
    team/group/issue14068/rose_qsig_mwi.c
      - copied unchanged from r740, team/rmudgett/facility/rose_qsig_mwi.c
    team/group/issue14068/rose_qsig_name.c
      - copied unchanged from r740, team/rmudgett/facility/rose_qsig_name.c
    team/group/issue14068/rosetest.c
      - copied unchanged from r740, team/rmudgett/facility/rosetest.c
Modified:
    team/group/issue14068/Makefile
    team/group/issue14068/libpri.h
    team/group/issue14068/pri_facility.c
    team/group/issue14068/pri_facility.h
    team/group/issue14068/pri_internal.h
    team/group/issue14068/q931.c

Modified: team/group/issue14068/Makefile
URL: http://svn.digium.com/svn-view/libpri/team/group/issue14068/Makefile?view=diff&rev=741&r1=740&r2=741
==============================================================================
--- team/group/issue14068/Makefile (original)
+++ team/group/issue14068/Makefile Wed Apr 15 18:36:15 2009
@@ -41,8 +41,42 @@
 
 STATIC_LIBRARY=libpri.a
 DYNAMIC_LIBRARY:=libpri.so.$(SONAME)
-STATIC_OBJS=copy_string.o pri.o q921.o prisched.o q931.o pri_facility.o version.o
-DYNAMIC_OBJS=copy_string.lo pri.lo q921.lo prisched.lo q931.lo pri_facility.lo version.lo
+STATIC_OBJS= \
+	copy_string.o \
+	pri.o \
+	q921.o \
+	prisched.o \
+	q931.o \
+	pri_facility.o \
+	asn1_primitive.o \
+	rose.o \
+	rose_address.o \
+	rose_etsi_aoc.o \
+	rose_other.o \
+	rose_q931.o \
+	rose_qsig_ct.o \
+	rose_qsig_diversion.o \
+	rose_qsig_mwi.o \
+	rose_qsig_name.o \
+	version.o
+DYNAMIC_OBJS= \
+	copy_string.lo \
+	pri.lo \
+	q921.lo \
+	prisched.lo \
+	q931.lo \
+	pri_facility.lo \
+	asn1_primitive.lo \
+	rose.lo \
+	rose_address.lo \
+	rose_etsi_aoc.lo \
+	rose_other.lo \
+	rose_q931.lo \
+	rose_qsig_ct.lo \
+	rose_qsig_diversion.lo \
+	rose_qsig_mwi.lo \
+	rose_qsig_name.lo \
+	version.lo
 CFLAGS=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -g -fPIC $(ALERTING) $(LIBPRI_COUNTERS)
 INSTALL_PREFIX=$(DESTDIR)
 INSTALL_BASE=/usr
@@ -132,6 +166,9 @@
 pridump: pridump.o
 	$(CC) -o pridump pridump.o -L. -lpri $(CFLAGS)
 
+rosetest: rosetest.o
+	$(CC) -o rosetest rosetest.o -L. -lpri $(CFLAGS)
+
 MAKE_DEPS= -MD -MT $@ -MF .$(subst /,_,$@).d -MP
 
 %.o: %.c

Modified: team/group/issue14068/libpri.h
URL: http://svn.digium.com/svn-view/libpri/team/group/issue14068/libpri.h?view=diff&rev=741&r1=740&r2=741
==============================================================================
--- team/group/issue14068/libpri.h (original)
+++ team/group/issue14068/libpri.h Wed Apr 15 18:36:15 2009
@@ -104,13 +104,13 @@
 #define PRI_PROG_CALLER_RETURNED_TO_ISDN					(1 << 9)
 
 /* Numbering plan identifier */
-#define PRI_NPI_UNKNOWN					0x0
-#define PRI_NPI_E163_E164				0x1
-#define PRI_NPI_X121					0x3
-#define PRI_NPI_F69						0x4
-#define PRI_NPI_NATIONAL				0x8
-#define PRI_NPI_PRIVATE					0x9
-#define PRI_NPI_RESERVED				0xF
+#define PRI_NPI_UNKNOWN					0x0 /*!< Unknown numbering plan */
+#define PRI_NPI_E163_E164				0x1 /*!< ISDN/telephony numbering plan (public) */
+#define PRI_NPI_X121					0x3 /*!< Data numbering plan */
+#define PRI_NPI_F69						0x4 /*!< Telex numbering plan */
+#define PRI_NPI_NATIONAL				0x8 /*!< National standard numbering plan */
+#define PRI_NPI_PRIVATE					0x9 /*!< Private numbering plan */
+#define PRI_NPI_RESERVED				0xF /*!< Reserved for extension */
 
 /* Type of number */
 #define PRI_TON_UNKNOWN					0x0

Modified: team/group/issue14068/pri_facility.c
URL: http://svn.digium.com/svn-view/libpri/team/group/issue14068/pri_facility.c?view=diff&rev=741&r1=740&r2=741
==============================================================================
--- team/group/issue14068/pri_facility.c (original)
+++ team/group/issue14068/pri_facility.c Wed Apr 15 18:36:15 2009
@@ -33,445 +33,363 @@
 #include "pri_q921.h"
 #include "pri_q931.h"
 #include "pri_facility.h"
+#include "rose.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
 
-static char *asn1id2text(int id)
-{
-	static char data[32];
-	static char *strings[] = {
-		"none",
-		"Boolean",
-		"Integer",
-		"Bit String",
-		"Octet String",
-		"NULL",
-		"Object Identifier",
-		"Object Descriptor",
-		"External Reference",
-		"Real Number",
-		"Enumerated",
-		"Embedded PDV",
-		"UTF-8 String",
-		"Relative Object ID",
-		"Reserved (0e)",
-		"Reserved (0f)",
-		"Sequence",
-		"Set",
-		"Numeric String",
-		"Printable String",
-		"Tele-Text String",
-		"IA-5 String",
-		"UTC Time",
-		"Generalized Time",
-	};
-	if (id > 0 && id <= 0x18) {
-		return strings[id];
-	} else {
-		sprintf(data, "Unknown (%02x)", id);
-		return data;
-	}
-}
-
-static int asn1_dumprecursive(struct pri *pri, void *comp_ptr, int len, int level)
-{
-	unsigned char *vdata = (unsigned char *)comp_ptr;
-	struct rose_component *comp;
-	int i = 0;
-	int j, k, l;
-	int clen = 0;
-
-	while (len > 0) {
-		GET_COMPONENT(comp, i, vdata, len);
-		pri_message(pri, "%*s%02X %04X", 2 * level, "", comp->type, comp->len);
-		if ((comp->type == 0) && (comp->len == 0))
-			return clen + 2;
-		if ((comp->type & ASN1_PC_MASK) == ASN1_PRIMITIVE) {
-			for (j = 0; j < comp->len; ++j)
-				pri_message(pri, " %02X", comp->data[j]);
-		}
-		if ((comp->type & ASN1_CLAN_MASK) == ASN1_UNIVERSAL) {
-			switch (comp->type & ASN1_TYPE_MASK) {
-			case 0:
-				pri_message(pri, " (none)");
-				break;
-			case ASN1_BOOLEAN:
-				pri_message(pri, " (BOOLEAN: %d)", comp->data[0]);
-				break;
-			case ASN1_INTEGER:
-				for (k = l = 0; k < comp->len; ++k)
-					l = (l << 8) | comp->data[k];
-				pri_message(pri, " (INTEGER: %d)", l);
-				break;
-			case ASN1_BITSTRING:
-				pri_message(pri, " (BITSTRING:");
-				for (k = 0; k < comp->len; ++k)
-				pri_message(pri, " %02x", comp->data[k]);
-				pri_message(pri, ")");
-				break;
-			case ASN1_OCTETSTRING:
-				pri_message(pri, " (OCTETSTRING:");
-				for (k = 0; k < comp->len; ++k)
-					pri_message(pri, " %02x", comp->data[k]);
-				pri_message(pri, ")");
-				break;
-			case ASN1_NULL:
-				pri_message(pri, " (NULL)");
-				break;
-			case ASN1_OBJECTIDENTIFIER:
-				pri_message(pri, " (OBJECTIDENTIFIER:");
-				for (k = 0; k < comp->len; ++k)
-					pri_message(pri, " %02x", comp->data[k]);
-				pri_message(pri, ")");
-				break;
-			case ASN1_ENUMERATED:
-				for (k = l = 0; k < comp->len; ++k)
-					l = (l << 8) | comp->data[k];
-				pri_message(pri, " (ENUMERATED: %d)", l);
-				break;
-			case ASN1_SEQUENCE:
-				pri_message(pri, " (SEQUENCE)");
-				break;
-			default:
-				pri_message(pri, " (component %02x - %s)", comp->type, asn1id2text(comp->type & ASN1_TYPE_MASK));
-				break;
-			}
-		}
-		else if ((comp->type & ASN1_CLAN_MASK) == ASN1_CONTEXT_SPECIFIC) {
-			pri_message(pri, " (CONTEXT SPECIFIC [%d])", comp->type & ASN1_TYPE_MASK);
-		}
-		else {
-			pri_message(pri, " (component %02x)", comp->type);
-		}
-		pri_message(pri, "\n");
-		if ((comp->type & ASN1_PC_MASK) == ASN1_CONSTRUCTOR)
-			j = asn1_dumprecursive(pri, comp->data, (comp->len ? comp->len : INT_MAX), level+1);
-		else
-			j = comp->len;
-		j += 2;
-		len -= j;
-		vdata += j;
-		clen += j;
-	}
-	return clen;
-}
-
-int asn1_dump(struct pri *pri, void *comp, int len)
-{
-	return asn1_dumprecursive(pri, comp, len, 0);
-}
-
-static unsigned char get_invokeid(struct pri *pri)
-{
-	return ++pri->last_invoke;
-}
-
-struct addressingdataelements_presentednumberunscreened {
-	char partyaddress[21];
-	char notused[21];
-	int  npi;       /* Numbering Plan Indicator */
-	int  ton;       /* Type Of Number */
-	int  pres;      /* Presentation */
-};
-
-struct addressingdataelements_presentednumberscreened {
-	char partyaddress[21];
-	char notused[21];
-	int  npi;       /* Numbering Plan Indicator */
-	int  ton;       /* Type Of Number */
-	int  pres;      /* Presentation */
-	int  scrind;    /* Screening Indicator */
-};
-
-struct addressingdataelements_presentedaddressscreened {
-	char partyaddress[21];
-	char partysubaddress[21];
-	int  npi;       /* Numbering Plan Indicator */
-	int  ton;       /* Type Of Number */
-	int  pres;      /* Presentation */
-	int  scrind;    /* Screening Indicator */
-};
-
-struct addressingdataelements_addressscreened {
-	char partyaddress[21];
-	char partysubaddress[21];
-	int  npi;       /* Numbering Plan Indicator */
-	int  ton;       /* Type Of Number */
-	int  notused;
-	int  scrind;    /* Screening Indicator */
-};
-
-struct addressingdataelements_partysubaddress {
-	char notused[21];
-	char partysubaddress[21];
-};
-
-struct nameelements_name {
-	char name[51];
-	int  characterset;
-	int  namepres;
-};
-
-struct nameelements_nameset {
-	char name[51];
-	int  characterset;
-};
-
-struct nameelements_namedata {
-	char name[51];
-};
-
-#define PRI_CHECKOVERFLOW(size) \
-		if (msgptr - message + (size) >= sizeof(message)) { \
-			*msgptr = '\0'; \
-			pri_message(pri, "%s", message); \
-			msgptr = message; \
-		}
-
-static void dump_apdu(struct pri *pri, unsigned char *c, int len) 
-{
-	#define MAX_APDU_LENGTH	255
-	static char hexs[16] = "0123456789ABCDEF";
-	int i;
-	char message[(2 + MAX_APDU_LENGTH * 3 + 6 + MAX_APDU_LENGTH + 3)] = "";	/* please adjust here, if you make changes below! */
-	char *msgptr;
-	
-	msgptr = message;
-	*msgptr++ = ' ';
-	*msgptr++ = '[';
-	for (i=0; i<len; i++) {
-		PRI_CHECKOVERFLOW(3);
-		*msgptr++ = ' ';
-		*msgptr++ = hexs[(c[i] >> 4) & 0x0f];
-		*msgptr++ = hexs[(c[i]) & 0x0f];
-	}
-	PRI_CHECKOVERFLOW(6);
-	strcpy(msgptr, " ] - [");
-	msgptr += strlen(msgptr);
-	for (i=0; i<len; i++) {
-		PRI_CHECKOVERFLOW(1);
-		*msgptr++ = ((c[i] < ' ') || (c[i] > '~')) ? '.' : c[i];
-	}
-	PRI_CHECKOVERFLOW(2);
-	*msgptr++ = ']';
-	*msgptr++ = '\n';
-	*msgptr = '\0';
-	pri_message(pri, "%s", message);
-}
-#undef PRI_CHECKOVERFLOW
-
-static const char *namepres_to_str(int namepres)
-{
-	return (namepres == 0) ? "Restricted" : "Allowed";
-}
-
-static const char *characterset_to_str(int characterset)
-{
-	switch (characterset) {
-	case CHARACTER_SET_UNKNOWN:
-		return "Unknown";
-	case CHARACTER_SET_ISO8859_1:
-		return "ISO8859-1";
-	case CHARACTER_SET_ISO8859_2:
-		return "ISO8859-2";
-	case CHARACTER_SET_ISO8859_3:
-		return "ISO8859-3";
-	case CHARACTER_SET_ISO8859_4:
-		return "ISO8859-4";
-	case CHARACTER_SET_ISO8859_5:
-		return "ISO8859-5";
-	case CHARACTER_SET_ISO8859_7:
-		return "ISO8859-7";
+static short get_invokeid(struct pri *ctrl)
+{
+	return ++ctrl->last_invoke;
+}
+
+static int redirectingreason_from_q931(struct pri *ctrl, int redirectingreason)
+{
+	int value;
+
+	switch (ctrl->switchtype) {
+	case PRI_SWITCH_QSIG:
+		switch (redirectingreason) {
+		case PRI_REDIR_UNKNOWN:
+			value = QSIG_DIVERT_REASON_UNKNOWN;
+			break;
+		case PRI_REDIR_FORWARD_ON_BUSY:
+			value = QSIG_DIVERT_REASON_CFB;
+			break;
+		case PRI_REDIR_FORWARD_ON_NO_REPLY:
+			value = QSIG_DIVERT_REASON_CFNR;
+			break;
+		case PRI_REDIR_UNCONDITIONAL:
+			value = QSIG_DIVERT_REASON_CFU;
+			break;
+		case PRI_REDIR_DEFLECTION:
+		case PRI_REDIR_DTE_OUT_OF_ORDER:
+		case PRI_REDIR_FORWARDED_BY_DTE:
+			pri_message(ctrl,
+				"!! Don't know how to convert Q.931 redirection reason %d to Q.SIG\n",
+				redirectingreason);
+			/* Fall through */
+		default:
+			value = QSIG_DIVERT_REASON_UNKNOWN;
+			break;
+		}
+		break;
 	default:
-		return "illegal value";
-	}
-}
-
-static const char *diversionreason_to_str(struct pri *pri, int diversionreason)
-{
-	if (pri->switchtype == PRI_SWITCH_QSIG) {
-		switch (diversionreason) {
+		switch (redirectingreason) {
+		case PRI_REDIR_UNKNOWN:
+			value = Q952_DIVERT_REASON_UNKNOWN;
+			break;
+		case PRI_REDIR_FORWARD_ON_BUSY:
+			value = Q952_DIVERT_REASON_CFB;
+			break;
+		case PRI_REDIR_FORWARD_ON_NO_REPLY:
+			value = Q952_DIVERT_REASON_CFNR;
+			break;
+		case PRI_REDIR_DEFLECTION:
+			value = Q952_DIVERT_REASON_CD;
+			break;
+		case PRI_REDIR_UNCONDITIONAL:
+			value = Q952_DIVERT_REASON_CFU;
+			break;
+		case PRI_REDIR_DTE_OUT_OF_ORDER:
+		case PRI_REDIR_FORWARDED_BY_DTE:
+			pri_message(ctrl,
+				"!! Don't know how to convert Q.931 redirection reason %d to Q.952\n",
+				redirectingreason);
+			/* Fall through */
+		default:
+			value = Q952_DIVERT_REASON_UNKNOWN;
+			break;
+		}
+		break;
+	}
+
+	return value;
+}
+
+static int redirectingreason_for_q931(struct pri *ctrl, int redirectingreason)
+{
+	int value;
+
+	switch (ctrl->switchtype) {
+	case PRI_SWITCH_QSIG:
+		switch (redirectingreason) {
 		case QSIG_DIVERT_REASON_UNKNOWN:
-			return "Unknown";
+			value = PRI_REDIR_UNKNOWN;
+			break;
 		case QSIG_DIVERT_REASON_CFU:
-			return "Call Forwarding Unconditional";
+			value = PRI_REDIR_UNCONDITIONAL;
+			break;
 		case QSIG_DIVERT_REASON_CFB:
-			return "Call Forwarding Busy";
+			value = PRI_REDIR_FORWARD_ON_BUSY;
+			break;
 		case QSIG_DIVERT_REASON_CFNR:
-			return "Call Forwarding No Reply";
+			value = PRI_REDIR_FORWARD_ON_NO_REPLY;
+			break;
 		default:
-			return "invalid value";
-		}
-	} else {
-		switch(diversionreason) {
+			pri_message(ctrl, "!! Unknown Q.SIG diversion reason %d\n",
+				redirectingreason);
+			value = PRI_REDIR_UNKNOWN;
+			break;
+		}
+		break;
+	default:
+		switch (redirectingreason) {
 		case Q952_DIVERT_REASON_UNKNOWN:
-			return "Unknown";
+			value = PRI_REDIR_UNKNOWN;
+			break;
 		case Q952_DIVERT_REASON_CFU:
-			return "Call Forwarding Unconditional";
+			value = PRI_REDIR_UNCONDITIONAL;
+			break;
 		case Q952_DIVERT_REASON_CFB:
-			return "Call Forwarding Busy";
+			value = PRI_REDIR_FORWARD_ON_BUSY;
+			break;
 		case Q952_DIVERT_REASON_CFNR:
-			return "Call Forwarding No Reply";
+			value = PRI_REDIR_FORWARD_ON_NO_REPLY;
+			break;
 		case Q952_DIVERT_REASON_CD:
-			return "Call Deflection";
+			value = PRI_REDIR_DEFLECTION;
+			break;
 		case Q952_DIVERT_REASON_IMMEDIATE:
-			return "Call Deflection Immediate";
+			pri_message(ctrl,
+				"!! Dont' know how to convert Q.952 diversion reason IMMEDIATE to PRI analog\n");
+			value = PRI_REDIR_UNKNOWN;	/* ??? */
+			break;
 		default:
-			return "invalid value";
-		}
-	}
-}
-
-static const char *callstatus_to_str(int callstatus)
-{
-	switch (callstatus) {
-	case 0:
-		return "answered";
-	case 1:
-		return "alerting";
+			pri_message(ctrl, "!! Unknown Q.952 diversion reason %d\n",
+				redirectingreason);
+			value = PRI_REDIR_UNKNOWN;
+			break;
+		}
+		break;
+	}
+
+	return value;
+}
+
+/*!
+ * \brief Convert the Q.931 type-of-number field to facility.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param ton Q.931 ton/plan octet.
+ *
+ * \return PartyNumber enumeration value.
+ */
+static int typeofnumber_from_q931(struct pri *ctrl, int ton)
+{
+	int value;
+
+	switch ((ton >> 4) & 0x03) {
 	default:
-		return "illegal value";
-	}
-}
-
-static const char *enddesignation_to_str(int enddesignation)
-{
-	switch (enddesignation) {
-	case 0:
-		return "primaryEnd";
-	case 1:
-		return "secondaryEnd";
+		pri_message(ctrl, "!! Unsupported Q.931 TypeOfNumber value (%d)\n", ton);
+		/* fall through */
+	case PRI_TON_UNKNOWN:
+		value = Q932_TON_UNKNOWN;
+		break;
+	case PRI_TON_INTERNATIONAL:
+		value = Q932_TON_INTERNATIONAL;
+		break;
+	case PRI_TON_NATIONAL:
+		value = Q932_TON_NATIONAL;
+		break;
+	case PRI_TON_NET_SPECIFIC:
+		value = Q932_TON_NET_SPECIFIC;
+		break;
+	case PRI_TON_SUBSCRIBER:
+		value = Q932_TON_SUBSCRIBER;
+		break;
+	case PRI_TON_ABBREVIATED:
+		value = Q932_TON_ABBREVIATED;
+		break;
+	}
+
+	return value;
+}
+
+static int typeofnumber_for_q931(struct pri *ctrl, int ton)
+{
+	int value;
+
+	switch (ton) {
 	default:
-		return "illegal value";
-	}
-}
-
-int redirectingreason_from_q931(struct pri *pri, int redirectingreason)
-{
-	switch(pri->switchtype) {
-		case PRI_SWITCH_QSIG:
-			switch(redirectingreason) {
-				case PRI_REDIR_UNKNOWN:
-					return QSIG_DIVERT_REASON_UNKNOWN;
-				case PRI_REDIR_FORWARD_ON_BUSY:
-					return QSIG_DIVERT_REASON_CFB;
-				case PRI_REDIR_FORWARD_ON_NO_REPLY:
-					return QSIG_DIVERT_REASON_CFNR;
-				case PRI_REDIR_UNCONDITIONAL:
-					return QSIG_DIVERT_REASON_CFU;
-				case PRI_REDIR_DEFLECTION:
-				case PRI_REDIR_DTE_OUT_OF_ORDER:
-				case PRI_REDIR_FORWARDED_BY_DTE:
-					pri_message(pri, "!! Don't know how to convert Q.931 redirection reason %d to Q.SIG\n", redirectingreason);
-					/* Fall through */
-				default:
-					return QSIG_DIVERT_REASON_UNKNOWN;
-			}
-		default:
-			switch(redirectingreason) {
-				case PRI_REDIR_UNKNOWN:
-					return Q952_DIVERT_REASON_UNKNOWN;
-				case PRI_REDIR_FORWARD_ON_BUSY:
-					return Q952_DIVERT_REASON_CFB;
-				case PRI_REDIR_FORWARD_ON_NO_REPLY:
-					return Q952_DIVERT_REASON_CFNR;
-				case PRI_REDIR_DEFLECTION:
-					return Q952_DIVERT_REASON_CD;
-				case PRI_REDIR_UNCONDITIONAL:
-					return Q952_DIVERT_REASON_CFU;
-				case PRI_REDIR_DTE_OUT_OF_ORDER:
-				case PRI_REDIR_FORWARDED_BY_DTE:
-					pri_message(pri, "!! Don't know how to convert Q.931 redirection reason %d to Q.952\n", redirectingreason);
-					/* Fall through */
-				default:
-					return Q952_DIVERT_REASON_UNKNOWN;
-			}
-	}
-}
-
-static int redirectingreason_for_q931(struct pri *pri, int redirectingreason)
-{
-	switch(pri->switchtype) {
-		case PRI_SWITCH_QSIG:
-			switch(redirectingreason) {
-				case QSIG_DIVERT_REASON_UNKNOWN:
-					return PRI_REDIR_UNKNOWN;
-				case QSIG_DIVERT_REASON_CFU:
-					return PRI_REDIR_UNCONDITIONAL;
-				case QSIG_DIVERT_REASON_CFB:
-					return PRI_REDIR_FORWARD_ON_BUSY;
-				case QSIG_DIVERT_REASON_CFNR:
-					return PRI_REDIR_FORWARD_ON_NO_REPLY;
-				default:
-					pri_message(pri, "!! Unknown Q.SIG diversion reason %d\n", redirectingreason);
-					return PRI_REDIR_UNKNOWN;
-			}
-		default:
-			switch(redirectingreason) {
-				case Q952_DIVERT_REASON_UNKNOWN:
-					return PRI_REDIR_UNKNOWN;
-				case Q952_DIVERT_REASON_CFU:
-					return PRI_REDIR_UNCONDITIONAL;
-				case Q952_DIVERT_REASON_CFB:
-					return PRI_REDIR_FORWARD_ON_BUSY;
-				case Q952_DIVERT_REASON_CFNR:
-					return PRI_REDIR_FORWARD_ON_NO_REPLY;
-				case Q952_DIVERT_REASON_CD:
-					return PRI_REDIR_DEFLECTION;
-				case Q952_DIVERT_REASON_IMMEDIATE:
-					pri_message(pri, "!! Dont' know how to convert Q.952 diversion reason IMMEDIATE to PRI analog\n");
-					return PRI_REDIR_UNKNOWN;	/* ??? */
-				default:
-					pri_message(pri, "!! Unknown Q.952 diversion reason %d\n", redirectingreason);
-					return PRI_REDIR_UNKNOWN;
-			}
-	}
-}
-
-int typeofnumber_from_q931(struct pri *pri, int ton)
-{
-	switch(ton) {
-		case PRI_TON_INTERNATIONAL:
-			return Q932_TON_INTERNATIONAL;
-		case PRI_TON_NATIONAL:
-			return Q932_TON_NATIONAL;
-		case PRI_TON_NET_SPECIFIC:
-			return Q932_TON_NET_SPECIFIC;
-		case PRI_TON_SUBSCRIBER:
-			return Q932_TON_SUBSCRIBER;
-		case PRI_TON_ABBREVIATED:
-			return Q932_TON_ABBREVIATED;
-		case PRI_TON_RESERVED:
-		default:
-			pri_message(pri, "!! Unsupported Q.931 TypeOfNumber value (%d)\n", ton);
-			/* fall through */
-		case PRI_TON_UNKNOWN:
-			return Q932_TON_UNKNOWN;
-	}
-}
-
-static int typeofnumber_for_q931(struct pri *pri, int ton)
-{
-	switch (ton) {
-		case Q932_TON_UNKNOWN:
-			return PRI_TON_UNKNOWN;
-		case Q932_TON_INTERNATIONAL:
-			return PRI_TON_INTERNATIONAL;
-		case Q932_TON_NATIONAL:
-			return PRI_TON_NATIONAL;
-		case Q932_TON_NET_SPECIFIC:
-			return PRI_TON_NET_SPECIFIC;
-		case Q932_TON_SUBSCRIBER:
-			return PRI_TON_SUBSCRIBER;
-		case Q932_TON_ABBREVIATED:
-			return PRI_TON_ABBREVIATED;
-		default:
-			pri_message(pri, "!! Invalid Q.932 TypeOfNumber %d\n", ton);
-			return PRI_TON_UNKNOWN;
-	}
+		pri_message(ctrl, "!! Invalid TypeOfNumber %d\n", ton);
+		/* fall through */
+	case Q932_TON_UNKNOWN:
+		value = PRI_TON_UNKNOWN;
+		break;
+	case Q932_TON_INTERNATIONAL:
+		value = PRI_TON_INTERNATIONAL;
+		break;
+	case Q932_TON_NATIONAL:
+		value = PRI_TON_NATIONAL;
+		break;
+	case Q932_TON_NET_SPECIFIC:
+		value = PRI_TON_NET_SPECIFIC;
+		break;
+	case Q932_TON_SUBSCRIBER:
+		value = PRI_TON_SUBSCRIBER;
+		break;
+	case Q932_TON_ABBREVIATED:
+		value = PRI_TON_ABBREVIATED;
+		break;
+	}
+
+	return value << 4;
+}
+
+/*!
+ * \internal
+ * \brief Convert the Q.931 numbering plan field to facility.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param plan Q.931 ton/plan octet.
+ *
+ * \return PartyNumber enumeration value.
+ */
+static int numbering_plan_from_q931(struct pri *ctrl, int plan)
+{
+	int value;
+
+	switch (plan & 0x0F) {
+	default:
+		pri_message(ctrl, "!! Unsupported Q.931 numbering plan value (%d)\n", plan);
+		/* fall through */
+	case PRI_NPI_UNKNOWN:
+		value = 0;	/* unknown */
+		break;
+	case PRI_NPI_E163_E164:
+		value = 1;	/* public */
+		break;
+	case PRI_NPI_X121:
+		value = 3;	/* data */
+		break;
+	case PRI_NPI_F69:
+		value = 4;	/* telex */
+		break;
+	case PRI_NPI_NATIONAL:
+		value = 8;	/* nationalStandard */
+		break;
+	case PRI_NPI_PRIVATE:
+		value = 5;	/* private */
+		break;
+	}
+
+	return value;
+}
+
+/*!
+ * \internal
+ * \brief Convert the PartyNumber numbering plan to Q.931 plan field value.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param plan PartyNumber enumeration value.
+ *
+ * \return Q.931 plan field value.
+ */
+static int numbering_plan_for_q931(struct pri *ctrl, int plan)
+{
+	int value;
+
+	switch (plan) {
+	default:
+		pri_message(ctrl,
+			"!! Unsupported PartyNumber to Q.931 numbering plan value (%d)\n", plan);
+		/* fall through */
+	case 0:	/* unknown */
+		value = PRI_NPI_UNKNOWN;
+		break;
+	case 1:	/* public */
+		value = PRI_NPI_E163_E164;
+		break;
+	case 3:	/* data */
+		value = PRI_NPI_X121;
+		break;
+	case 4:	/* telex */
+		value = PRI_NPI_F69;
+		break;
+	case 5:	/* private */
+		value = PRI_NPI_PRIVATE;
+		break;
+	case 8:	/* nationalStandard */
+		value = PRI_NPI_NATIONAL;
+		break;
+	}
+
+	return value;
+}
+
+/*!
+ * \internal
+ * \brief Convert the Q.931 number presentation field to facility.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param presentation Q.931 presentation/screening octet.
+ * \param number_present Non-zero if the number is available.
+ *
+ * \return Presented<Number/Address><Screened/Unscreened> enumeration value.
+ */
+static int presentation_from_q931(struct pri *ctrl, int presentation, int number_present)
+{
+	int value;
+
+	switch (presentation & PRES_RESTRICTION) {
+	case PRES_ALLOWED:
+		value = 0;	/* presentationAllowed<Number/Address> */
+		break;
+	default:
+		pri_message(ctrl, "!! Unsupported Q.931 number presentation value (%d)\n",
+			presentation);
+		/* fall through */
+	case PRES_RESTRICTED:
+		if (number_present) {
+			value = 3;	/* presentationRestricted<Number/Address> */
+		} else {
+			value = 1;	/* presentationRestricted */
+		}
+		break;
+	case PRES_UNAVAILABLE:
+		value = 2;	/* numberNotAvailableDueToInterworking */
+		break;
+	}
+
+	return value;
+}
+
+/*!
+ * \internal
+ * \brief Convert the Presented<Number/Address><Screened/Unscreened> presentation
+ * to Q.931 presentation field value.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param presentation Presented<Number/Address><Screened/Unscreened> value.
+ *
+ * \return Q.931 presentation field value.
+ */
+static int presentation_for_q931(struct pri *ctrl, int presentation)
+{
+	int value;
+
+	switch (presentation) {
+	case 0:	/* presentationAllowed<Number/Address> */
+		value = PRES_ALLOWED;
+		break;
+	default:
+		pri_message(ctrl,
+			"!! Unsupported Presented<Number/Address><Screened/Unscreened> to Q.931 value (%d)\n",
+			presentation);
+		/* fall through */
+	case 1:	/* presentationRestricted */
+	case 3:	/* presentationRestricted<Number/Address> */
+		value = PRES_RESTRICTED;
+		break;
+	case 2:	/* numberNotAvailableDueToInterworking */
+		value = PRES_UNAVAILABLE;
+		break;
+	}
+
+	return value;
 }
 
 static int presentation_to_subscription(struct pri *pri, int presentation)
@@ -483,1605 +401,306 @@
 		return QSIG_NOTIFICATION_WITH_DIVERTED_TO_NR;
 	case PRES_RESTRICTED:
 		return QSIG_NOTIFICATION_WITHOUT_DIVERTED_TO_NR;
-	case PRES_UNAVAILABLE:			/* Number not available due to interworking */
+	case PRES_UNAVAILABLE:	/* Number not available due to interworking */
 		return QSIG_NOTIFICATION_WITHOUT_DIVERTED_TO_NR;	/* ?? QSIG_NO_NOTIFICATION */
 	default:
-		pri_message(pri, "!! Unknown Q.SIG presentationIndicator 0x%02x\n", presentation);
+		pri_message(pri, "!! Unknown Q.SIG presentationIndicator 0x%02x\n",
+			presentation);
 		return QSIG_NOTIFICATION_WITHOUT_DIVERTED_TO_NR;
 	}
 }
 
-int asn1_name_decode(void *data, int len, char *namebuf, int buflen)
-{
-	struct rose_component *comp = (struct rose_component*)data;
-	int datalen = 0, res = 0;
-
-	if (comp->len == ASN1_LEN_INDEF) {
-		datalen = strlen((char *)comp->data);
-		res = datalen + 2;
-	} else
-		datalen = res = comp->len;
-
-	if (datalen > buflen - 1) {
-		/* Truncate */
-		datalen = buflen;
-	}
-	memcpy(namebuf, comp->data, datalen);
-	namebuf[datalen] = '\0';
-
-	return res + 2;
-}
-
-int asn1_string_encode(unsigned char asn1_type, void *data, int len, int max_len, void *src, int src_len)
-{
-	struct rose_component *comp = NULL;
-	
-	if (len < 2 + src_len)
-		return -1;
-
-	if (max_len && (src_len > max_len))
-		src_len = max_len;
-
-	comp = (struct rose_component *)data;
-	comp->type = asn1_type;
-	comp->len = src_len;
-	memcpy(comp->data, src, src_len);
-	
-	return 2 + src_len;
-}
-
-int asn1_copy_string(char * buf, int buflen, struct rose_component *comp)
-{
-	int res;
-	int datalen;
-
-	if ((comp->len > buflen) && (comp->len != ASN1_LEN_INDEF))
-		return -1;
-
-	if (comp->len == ASN1_LEN_INDEF) {
-		datalen = strlen((char*)comp->data);
-		res = datalen + 2;
-	} else
-		res = datalen = comp->len;
-
-	memcpy(buf, comp->data, datalen);
-	buf[datalen] = 0;
-
-	return res;
-}
-
-static int rose_namedata_decode(struct pri *pri, unsigned char *data, int len, int implicit, struct nameelements_namedata *value)
-{
-	int i = 0;
-	struct rose_component *comp = NULL;
-	unsigned char *vdata = data;
-	int res;
-
-	do {
-		/* NameData */
-		if (!implicit) {
-			GET_COMPONENT(comp, i, vdata, len);
-			CHECK_COMPONENT(comp, ASN1_OCTETSTRING, "Don't know what to do if NameData is of type 0x%x\n");
-
-			data = comp->data;
-			if (comp->len == ASN1_LEN_INDEF) {
-				len = strlen((char *)comp->data);
-				res = len + 2 + 2;
-			} else {
-				len = comp->len;
-				res = len + 2;
-			}
-		} else
-			res = len;
-
-		if (len > sizeof(value->name)-1) {
-			pri_message(pri, "!! Oversized NameData component (%d)\n", len);
-			return -1;
-		}
-
-		memcpy(value->name, data, len);
-		value->name[len] = '\0';
-
-		return res;
-	}
-	while(0);
-
-	return -1;
-}
-
-static int rose_namedata_encode(struct pri *pri, unsigned char *dst, int implicit, char *name)
-{
-	int size = 0;
-	struct rose_component *comp;
-	int namesize;
-
-	namesize = strlen(name);
-	if (namesize > 50 ) {
-		pri_message(pri, "!! Encoding of oversized NameData component failed (%d)\n", namesize);
-		return -1;
-	} else if (namesize == 0){
-		pri_message(pri, "!! Encoding of undersized NameData component failed (%d)\n", namesize);
-		return -1;
-	}
-
-	if (!implicit) {
-		/* constructor component  (0x04,len) */
-		comp = (struct rose_component *)dst;
-		comp->type = ASN1_OCTETSTRING;
-		comp->len = 2 + namesize;
-		size += 2;
-		dst += 2;
-	}
-
-	memcpy(dst, name, namesize);
-	size += namesize;
-
-	return size;
-}
-
-static int rose_nameset_decode(struct pri *pri, unsigned char *data, int len, int implicit, struct nameelements_nameset *value)
-{
-	int size;
-	int i = 0;
-	struct rose_component *comp = NULL;
-	unsigned char *vdata = data;
- 	int characterset;
-
-	value->characterset = CHARACTER_SET_ISO8859_1;
-
-	do {
-		/* NameSet */
-		if (!implicit) {
-			GET_COMPONENT(comp, i, vdata, len);
-			CHECK_COMPONENT(comp, ASN1_SEQUENCE, "Don't know what to do if NameSet is of type 0x%x\n");
-			SUB_COMPONENT(comp, i);
-		}
-
-		/* nameData NameData */
-		GET_COMPONENT(comp, i, vdata, len);
-		size = rose_namedata_decode(pri, (u_int8_t *)comp, len, 0, (struct nameelements_namedata *)value);
-		if (size < 0)
-			return -1;
-		i += size;
-
-		if (i < len) {
-			/* characterSet CharacterSet OPTIONAL */
-			GET_COMPONENT(comp, i, vdata, len);
-			CHECK_COMPONENT(comp, ASN1_INTEGER, "Don't know what to do if CharacterSet is of type 0x%x\n");
-			ASN1_GET_INTEGER(comp, characterset);
-			NEXT_COMPONENT(comp, i);
-			if (pri->debug & PRI_DEBUG_APDU)
-				pri_message(pri, "     NameSet: Received characterSet=%s(%d)\n", characterset_to_str(characterset), characterset);
-			value->characterset = characterset;
-		}
-
-		if (pri->debug & PRI_DEBUG_APDU)
-			pri_message(pri, "     NameSet: '%s', characterSet=%s(%d) i=%d len=%d\n", value->name, characterset_to_str(value->characterset), value->characterset, i, len);
-
-		return i;
-	}
-	while(0);
-	
-	return -1;
-}
-
-static int rose_name_decode(struct pri *pri, unsigned char *data, int len, struct nameelements_name *value)
-{
-	int i = 0;
-	int size = 0;
-	struct rose_component *comp = NULL;
-	unsigned char *vdata = data;
-
-	value->name[0] = '\0';
-	value->characterset = CHARACTER_SET_UNKNOWN;
-	value->namepres = -1;
-
-	do {
-		GET_COMPONENT(comp, i, vdata, len);
-
-		switch(comp->type) {
-		case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0):			/* [0] namePresentationAllowedSimple */
-			size = rose_namedata_decode(pri, comp->data, comp->len, 1, (struct nameelements_namedata *)value);
-			if (size < 0)
-				return -1;
-			i += (size + 2);
-			value->characterset = CHARACTER_SET_ISO8859_1;
-			value->namepres = 1;
-			break;
-		case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1):	/* [1] namePresentationAllowedExtended */
-			size = rose_nameset_decode(pri, comp->data, comp->len, 1, (struct nameelements_nameset *)value);
-			if (size < 0)
-				return -1;
-			i += (size + 2);
-			value->namepres = 1;
-			break;
-		case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2):			/* [2] namePresentationRestrictedSimple */
-			size = rose_namedata_decode(pri, comp->data, comp->len, 1, (struct nameelements_namedata *)value);
-			if (size < 0)
-				return -1;
-			i += (size + 2);
-			value->characterset = CHARACTER_SET_ISO8859_1;
-			value->namepres = 0;
-			break;
-		case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3):	/* [3] namePresentationRestrictedExtended */
-			size = rose_nameset_decode(pri, comp->data, comp->len, 1, (struct nameelements_nameset *)value);
-			if (size < 0)
-				return -1;
-			i += (size + 2);
-			value->namepres = 0;
-			break;
-		case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_4):			/* [4] nameNotAvailable */
-		case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_7):			/* [7] namePresentationRestrictedNull */
-			i += (comp->len + 2);
-			value->name[0] = '\0';
-			value->characterset = CHARACTER_SET_UNKNOWN;
-			value->namepres = 0;
-			break;
-		default:
-			pri_message(pri, "!! Unknown Name component received 0x%x\n", comp->type);
-			return -1;
-		}
-
-		if (pri->debug & PRI_DEBUG_APDU)
-			pri_message(pri, "     Name: '%s' i=%d len=%d\n", value->name, i, len);
-		return i;
-	}
-	while (0);
-
-	return -1;
-}
-
-static int rose_number_digits_decode(struct pri *pri, unsigned char *data, int len, int implicit, struct addressingdataelements_presentednumberunscreened *value)
-{
-	int i = 0;
-	struct rose_component *comp = NULL;
-	unsigned char *vdata = data;
-	int res = 0;
-
-	do {
-		if (!implicit) {
-			GET_COMPONENT(comp, i, vdata, len);
-			CHECK_COMPONENT(comp, ASN1_NUMERICSTRING, "Don't know what to do with NumberDigits ROSE component type 0x%x\n");
-
-			data = comp->data;
-			if (comp->len == ASN1_LEN_INDEF) {
-				len = strlen((char *)comp->data);
-				res = len + 2 + 2;
-			} else {
-				len = comp->len;
-				res = len + 2;
-			}
-		} else
-			res = len;
-
-		if (len > sizeof(value->partyaddress)-1) {
-			pri_message(pri, "!! Oversized NumberDigits component (%d)\n", len);
-			return -1;
-		}
-
-		memcpy(value->partyaddress, data, len);
-		value->partyaddress[len] = '\0';
-
-		return res;
-	}
-	while(0);
-
-	return -1;
-}
-
-static int rose_public_party_number_decode(struct pri *pri, unsigned char *data, int len, int implicit, struct addressingdataelements_presentednumberunscreened *value)
-{
-	int i = 0;
-	struct rose_component *comp = NULL;
-	unsigned char *vdata = data;
-	int ton;
-	int res = 0;
-
-	if (len < 2)
-		return -1;
-
-	do {
-		if (!implicit) {
-			GET_COMPONENT(comp, i, vdata, len);
-			CHECK_COMPONENT(comp, ASN1_SEQUENCE, "Don't know what to do if PublicPartyNumber is of type 0x%x\n");
-			SUB_COMPONENT(comp, i);
-		}
-
-		GET_COMPONENT(comp, i, vdata, len);
-		CHECK_COMPONENT(comp, ASN1_ENUMERATED, "Don't know what to do with PublicPartyNumber ROSE component type 0x%x\n");
-		ASN1_GET_INTEGER(comp, ton);
-		NEXT_COMPONENT(comp, i);
-		ton = typeofnumber_for_q931(pri, ton);
-
-		res = rose_number_digits_decode(pri, &vdata[i], len-i, 0, value);
-		if (res < 0)
-			return -1;
-		value->ton = ton;
-
-		return res + 3;
-
-	} while(0);
-	return -1;
-}
-
-static int rose_public_party_number_encode(struct pri *pri, unsigned char *dst, int implicit, unsigned char ton, char *num)
-{
-	int i = 0, compsp = 0;
-	struct rose_component *comp, *compstk[10];
-	int numsize;
-
-	numsize = strlen(num);
-	if (numsize > 20 ) {
-		pri_message(pri, "!! Encoding of oversized PublicPartyNumber component failed (%d)\n", numsize);
-		return -1;
-	}
-
-	if (!implicit) {
-		/* constructor component  (0x30,len) */
-		ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), dst, i);
-		ASN1_PUSH(compstk, compsp, comp);
-	} else
-		comp = (struct rose_component *)dst;
-
-	/* publicTypeOfNumber   (0x0a,0x01,ton)*/
-	ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, dst, i, ton);
-
-	/* publicNumberDigits */
-
-	/* tag component NumericString  (0x12,len) */
-	ASN1_ADD_SIMPLE(comp, ASN1_NUMERICSTRING, dst, i);
-	ASN1_PUSH(compstk, compsp, comp);
-
-	/* NumericString */
-	memcpy(comp->data, num, numsize);
-	i += numsize;
-
-	ASN1_FIXUP(compstk, compsp, dst, i);
-
-	if (!implicit)
-		ASN1_FIXUP(compstk, compsp, dst, i);
-
-	return i;
-}
-
-static int rose_private_party_number_decode(struct pri *pri, unsigned char *data, int len, int implicit, struct addressingdataelements_presentednumberunscreened *value)
-{
-	int i = 0;
-	struct rose_component *comp = NULL;
-	unsigned char *vdata = data;
-	int ton;
-	int res = 0;
-
-	if (len < 2)
-		return -1;
-
-	do {
-		if (!implicit) {
-			GET_COMPONENT(comp, i, vdata, len);
-			CHECK_COMPONENT(comp, ASN1_SEQUENCE, "Don't know what to do if PrivatePartyNumber is of type 0x%x\n");
-			SUB_COMPONENT(comp, i);
-		}
-
-		GET_COMPONENT(comp, i, vdata, len);
-		CHECK_COMPONENT(comp, ASN1_ENUMERATED, "Don't know what to do with PrivatePartyNumber ROSE component type 0x%x\n");
-		ASN1_GET_INTEGER(comp, ton);
-		NEXT_COMPONENT(comp, i);
-		ton = typeofnumber_for_q931(pri, ton);
-
-		res = rose_number_digits_decode(pri, &vdata[i], len-i, 0, value);
-		if (res < 0)
-			return -1;
-		value->ton = ton;
-
-		return res + 3;
-
-	} while(0);
-	return -1;
-}
-
-static int rose_address_decode(struct pri *pri, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value)
-{
-	int i = 0;
-	struct rose_component *comp = NULL;
-	unsigned char *vdata = data;
-	int res = 0;
-
-	do {
-		GET_COMPONENT(comp, i, vdata, len);
-
-		/* PartyNumber */
-		switch(comp->type) {
-		case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0):	/* [0] unknownPartyNumber, IMPLICIT NumberDigits */
-			res = rose_number_digits_decode(pri, comp->data, comp->len, 1, value);
-			if (res < 0)
-				return -1;
-			value->npi = PRI_NPI_UNKNOWN;
-			value->ton = PRI_TON_UNKNOWN;
-			break;
-		case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1):	/* [1] publicPartyNumber, IMPLICIT PublicPartyNumber */
-			res = rose_public_party_number_decode(pri, comp->data, comp->len, 1, value);
-			if (res < 0)
-				return -1;
-			value->npi = PRI_NPI_E163_E164;
-			break;
-		case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_3):	/* [3] dataPartyNumber, IMPLICIT NumberDigits */
-			res = rose_number_digits_decode(pri, comp->data, comp->len, 1, value);
-			if (res < 0)
-				return -1;
-			value->npi = PRI_NPI_X121 /* ??? */;
-			value->ton = PRI_TON_UNKNOWN /* ??? */;
-			pri_message(pri, "!! dataPartyNumber isn't handled\n");
-			return -1;
-		case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_4):	/* [4] telexPartyNumber, IMPLICIT NumberDigits */
-			res = rose_number_digits_decode(pri, comp->data, comp->len, 1, value);
-			if (res < 0)
-				return -1;
-			value->npi = PRI_NPI_F69 /* ??? */;
-			value->ton = PRI_TON_UNKNOWN /* ??? */;
-			pri_message(pri, "!! telexPartyNumber isn't handled\n");
-			return -1;
-		case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_5):	/* [5] privatePartyNumber, IMPLICIT PrivatePartyNumber */
-			res = rose_private_party_number_decode(pri, comp->data, comp->len, 1, value);
-			if (res < 0)
-				return -1;
-			value->npi = PRI_NPI_PRIVATE;
-			break;
-		case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_8):	/* [8] nationalStandardPartyNumber, IMPLICIT NumberDigits */
-			res = rose_number_digits_decode(pri, comp->data, comp->len, 1, value);
-			if (res < 0)
-				return -1;
-			value->npi = PRI_NPI_NATIONAL;
-			value->ton = PRI_TON_NATIONAL;
-			break;
-		default:
-			pri_message(pri, "!! Unknown PartyNumber component received 0x%X\n", comp->type);
-			return -1;
-		}
-		ASN1_FIXUP_LEN(comp, res);
-		NEXT_COMPONENT(comp, i);
-
-		/* PartySubaddress OPTIONAL */
-		if (i < len)
-			pri_message(pri, "!! not all information is handled from Address component\n");
-		return res + 2;
-	}
-	while (0);
-
-	return -1;
-}
-
-static int rose_party_number_encode(struct pri *pri, unsigned char *dst, unsigned char ton, char *num)
-{
-	int i = 0, compsp = 0;
-	struct rose_component *comp, *compstk[10];
-	int numsize, size;
-
-	numsize = strlen(num);
-	if (numsize > 20 ) {
-		pri_message(pri, "!! Encoding of oversized PartyNumber component failed (%d)\n", numsize);
-		return -1;
-	}
-
-#if 0
-	/* tag component unknownPartyNumber  (0x80,len) */
-	ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0), dst, i);
-	ASN1_PUSH(compstk, compsp, comp);
-
-	/* unknownPartyNumber, implicid NumberDigits */
-	memcpy(comp->data, num, numsize);
-	i += numsize;
-
-	ASN1_FIXUP(compstk, compsp, dst, i);
-#endif
-
-	/* tag component publicPartyNumber  (0xa1,len) */

[... 5532 lines stripped ...]



More information about the libpri-commits mailing list