[libpri-commits] rmudgett: branch 1.4 r766 - /branches/1.4/
SVN commits to the libpri project
libpri-commits at lists.digium.com
Tue Apr 21 17:08:49 CDT 2009
Author: rmudgett
Date: Tue Apr 21 17:08:45 2009
New Revision: 766
URL: http://svn.digium.com/svn-view/libpri?view=rev&rev=766
Log:
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:
branches/1.4/asn1.h
- copied unchanged from r765, team/rmudgett/facility/asn1.h
branches/1.4/asn1_primitive.c
- copied unchanged from r765, team/rmudgett/facility/asn1_primitive.c
branches/1.4/rose.c
- copied unchanged from r765, team/rmudgett/facility/rose.c
branches/1.4/rose.h
- copied unchanged from r765, team/rmudgett/facility/rose.h
branches/1.4/rose_address.c
- copied unchanged from r765, team/rmudgett/facility/rose_address.c
branches/1.4/rose_etsi_aoc.c
- copied unchanged from r765, team/rmudgett/facility/rose_etsi_aoc.c
branches/1.4/rose_internal.h
- copied unchanged from r765, team/rmudgett/facility/rose_internal.h
branches/1.4/rose_other.c
- copied unchanged from r765, team/rmudgett/facility/rose_other.c
branches/1.4/rose_q931.c
- copied unchanged from r765, team/rmudgett/facility/rose_q931.c
branches/1.4/rose_qsig_ct.c
- copied unchanged from r765, team/rmudgett/facility/rose_qsig_ct.c
branches/1.4/rose_qsig_diversion.c
- copied unchanged from r765, team/rmudgett/facility/rose_qsig_diversion.c
branches/1.4/rose_qsig_mwi.c
- copied unchanged from r765, team/rmudgett/facility/rose_qsig_mwi.c
branches/1.4/rose_qsig_name.c
- copied unchanged from r765, team/rmudgett/facility/rose_qsig_name.c
branches/1.4/rosetest.c
- copied unchanged from r765, team/rmudgett/facility/rosetest.c
Modified:
branches/1.4/Makefile
branches/1.4/libpri.h
branches/1.4/pri_facility.c
branches/1.4/pri_facility.h
branches/1.4/pri_internal.h
branches/1.4/q931.c
Modified: branches/1.4/Makefile
URL: http://svn.digium.com/svn-view/libpri/branches/1.4/Makefile?view=diff&rev=766&r1=765&r2=766
==============================================================================
--- branches/1.4/Makefile (original)
+++ branches/1.4/Makefile Tue Apr 21 17:08:45 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: branches/1.4/libpri.h
URL: http://svn.digium.com/svn-view/libpri/branches/1.4/libpri.h?view=diff&rev=766&r1=765&r2=766
==============================================================================
--- branches/1.4/libpri.h (original)
+++ branches/1.4/libpri.h Tue Apr 21 17:08:45 2009
@@ -26,7 +26,14 @@
* provided with that copy of Asterisk, instead of the license
* terms granted here.
*/
-
+
+/*
+ * NOTE:
+ * All new global identifiers that are added to this file MUST be
+ * prefixed with PRI_ or pri_ to indicate that they are part of this
+ * library and to reduce potential naming conflicts.
+ */
+
#ifndef _LIBPRI_H
#define _LIBPRI_H
@@ -103,13 +110,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
@@ -137,15 +144,44 @@
#define PRI_UNKNOWN 0x0
/* Presentation */
-#define PRES_ALLOWED_USER_NUMBER_NOT_SCREENED 0x00
-#define PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN 0x01
-#define PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN 0x02
-#define PRES_ALLOWED_NETWORK_NUMBER 0x03
-#define PRES_PROHIB_USER_NUMBER_NOT_SCREENED 0x20
-#define PRES_PROHIB_USER_NUMBER_PASSED_SCREEN 0x21
-#define PRES_PROHIB_USER_NUMBER_FAILED_SCREEN 0x22
-#define PRES_PROHIB_NETWORK_NUMBER 0x23
-#define PRES_NUMBER_NOT_AVAILABLE 0x43
+#define PRI_PRES_NUMBER_TYPE 0x03
+#define PRI_PRES_USER_NUMBER_UNSCREENED 0x00
+#define PRI_PRES_USER_NUMBER_PASSED_SCREEN 0x01
+#define PRI_PRES_USER_NUMBER_FAILED_SCREEN 0x02
+#define PRI_PRES_NETWORK_NUMBER 0x03
+
+#define PRI_PRES_RESTRICTION 0x60
+#define PRI_PRES_ALLOWED 0x00
+#define PRI_PRES_RESTRICTED 0x20
+#define PRI_PRES_UNAVAILABLE 0x40
+#define PRI_PRES_RESERVED 0x60
+
+#define PRES_ALLOWED_USER_NUMBER_NOT_SCREENED \
+ (PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED)
+
+#define PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN \
+ (PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_PASSED_SCREEN)
+
+#define PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN \
+ (PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_FAILED_SCREEN)
+
+#define PRES_ALLOWED_NETWORK_NUMBER \
+ (PRI_PRES_ALLOWED | PRI_PRES_NETWORK_NUMBER)
+
+#define PRES_PROHIB_USER_NUMBER_NOT_SCREENED \
+ (PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED)
+
+#define PRES_PROHIB_USER_NUMBER_PASSED_SCREEN \
+ (PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_PASSED_SCREEN)
+
+#define PRES_PROHIB_USER_NUMBER_FAILED_SCREEN \
+ (PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_FAILED_SCREEN)
+
+#define PRES_PROHIB_NETWORK_NUMBER \
+ (PRI_PRES_RESTRICTED | PRI_PRES_NETWORK_NUMBER)
+
+#define PRES_NUMBER_NOT_AVAILABLE \
+ (PRI_PRES_UNAVAILABLE | PRI_PRES_NETWORK_NUMBER)
/* Causes for disconnection */
#define PRI_CAUSE_UNALLOCATED 1
Modified: branches/1.4/pri_facility.c
URL: http://svn.digium.com/svn-view/libpri/branches/1.4/pri_facility.c?view=diff&rev=766&r1=765&r2=766
==============================================================================
--- branches/1.4/pri_facility.c (original)
+++ branches/1.4/pri_facility.c Tue Apr 21 17:08:45 2009
@@ -33,872 +33,511 @@
#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 partysubaddress[21];
- int npi; /* Numbering Plan Indicator */
- int ton; /* Type Of Number */
- int pres; /* Presentation */
-};
-
-struct addressingdataelements_presentednumberscreened {
- char partyaddress[21];
- char partysubaddress[21];
- int npi; /* Numbering Plan Indicator */
- int ton; /* Type Of Number */
- int pres; /* Presentation */
- int scrind; /* Screening Indicator */
-};
-
-#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
-
-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;
- }
+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:
- 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;
- }
+ value = QSIG_DIVERT_REASON_UNKNOWN;
+ break;
+ }
+ break;
+ default:
+ 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:
- 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:
+ 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:
+ value = PRI_REDIR_UNKNOWN;
+ break;
+ case QSIG_DIVERT_REASON_CFU:
+ value = PRI_REDIR_UNCONDITIONAL;
+ break;
+ case QSIG_DIVERT_REASON_CFB:
+ value = PRI_REDIR_FORWARD_ON_BUSY;
+ break;
+ case QSIG_DIVERT_REASON_CFNR:
+ value = PRI_REDIR_FORWARD_ON_NO_REPLY;
+ break;
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)
-{
+ 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:
+ value = PRI_REDIR_UNKNOWN;
+ break;
+ case Q952_DIVERT_REASON_CFU:
+ value = PRI_REDIR_UNCONDITIONAL;
+ break;
+ case Q952_DIVERT_REASON_CFB:
+ value = PRI_REDIR_FORWARD_ON_BUSY;
+ break;
+ case Q952_DIVERT_REASON_CFNR:
+ value = PRI_REDIR_FORWARD_ON_NO_REPLY;
+ break;
+ case Q952_DIVERT_REASON_CD:
+ value = PRI_REDIR_DEFLECTION;
+ break;
+ case Q952_DIVERT_REASON_IMMEDIATE:
+ pri_message(ctrl,
+ "!! Dont' know how to convert Q.952 diversion reason IMMEDIATE to PRI analog\n");
+ value = PRI_REDIR_UNKNOWN; /* ??? */
+ break;
+ default:
+ 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:
+ 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) {
- 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;
- }
-}
-
-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) {
- /* Truncate */
- datalen = buflen;
- }
- memcpy(namebuf, comp->data, datalen);
- 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_number_digits_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value)
-{
- int i = 0;
- struct rose_component *comp = NULL;
- unsigned char *vdata = data;
- int datalen = 0;
- int res = 0;
-
- do {
- GET_COMPONENT(comp, i, vdata, len);
- CHECK_COMPONENT(comp, ASN1_NUMERICSTRING, "Don't know what to do with PublicPartyNumber ROSE component type 0x%x\n");
- if(comp->len > 20 && comp->len != ASN1_LEN_INDEF) {
- pri_message(pri, "!! Oversized NumberDigits component (%d)\n", comp->len);
- return -1;
- }
- if (comp->len == ASN1_LEN_INDEF) {
- datalen = strlen((char *)comp->data);
- res = datalen + 2;
- } else
- res = datalen = comp->len;
-
- memcpy(value->partyaddress, comp->data, datalen);
- value->partyaddress[datalen] = '\0';
-
- return res + 2;
- }
- while(0);
-
- return -1;
-}
-
-static int rose_public_party_number_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, 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 {
- 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, call, &vdata[i], len-i, value);
- if (res < 0)
- return -1;
- value->ton = ton;
-
- return res + 3;
-
- } while(0);
- return -1;
-}
-
-static int rose_private_party_number_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, 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 {
- 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, call, &vdata[i], len-i, value);
- if (res < 0)
- return -1;
- value->ton = ton;
-
- return res + 3;
-
- } while(0);
- return -1;
-}
-
-static int rose_address_decode(struct pri *pri, q931_call *call, 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);
-
- switch(comp->type) {
- case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0): /* [0] unknownPartyNumber */
- res = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
- if (res < 0)
- return -1;
- value->npi = PRI_NPI_UNKNOWN;
- value->ton = PRI_TON_UNKNOWN;
- break;
- case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0): /* [0] unknownPartyNumber */
- res = asn1_copy_string(value->partyaddress, sizeof(value->partyaddress), comp);
- 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 */
- res = rose_public_party_number_decode(pri, call, comp->data, comp->len, value);
- if (res < 0)
- return -1;
- value->npi = PRI_NPI_E163_E164;
- break;
- case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_2): /* [2] nsapEncodedNumber */
- pri_message(pri, "!! NsapEncodedNumber isn't handled\n");
- return -1;
- case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3): /* [3] dataPartyNumber */
- if(rose_number_digits_decode(pri, call, comp->data, comp->len, value))
- 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_CONSTRUCTOR | ASN1_TAG_4): /* [4] telexPartyNumber */
- res = rose_number_digits_decode(pri, call, comp->data, comp->len, 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] priavePartyNumber */
- res = rose_private_party_number_decode(pri, call, comp->data, comp->len, value);
- if (res < 0)
- return -1;
- value->npi = PRI_NPI_PRIVATE;
- break;
- case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_8): /* [8] nationalStandardPartyNumber */
- res = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
- if (res < 0)
- return -1;
- value->npi = PRI_NPI_NATIONAL;
- value->ton = PRI_TON_NATIONAL;
- break;
- default:
- pri_message(pri, "!! Unknown Party number component received 0x%X\n", comp->type);
- return -1;
- }
- ASN1_FIXUP_LEN(comp, res);
- NEXT_COMPONENT(comp, i);
- 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_presented_number_unscreened_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value)
-{
- int i = 0;
- int size = 0;
- struct rose_component *comp = NULL;
- unsigned char *vdata = data;
-
- /* Fill in default values */
- value->ton = PRI_TON_UNKNOWN;
- value->npi = PRI_NPI_E163_E164;
- value->pres = -1; /* Data is not available */
-
- do {
- GET_COMPONENT(comp, i, vdata, len);
-
- switch(comp->type) {
- case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0): /* [0] presentationAllowedNumber */
- value->pres = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
- size = rose_address_decode(pri, call, comp->data, comp->len, value);
- ASN1_FIXUP_LEN(comp, size);
- return size + 2;
- case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1): /* [1] IMPLICIT presentationRestricted */
- if (comp->len != 0) { /* must be NULL */
- pri_error(pri, "!! Invalid PresentationRestricted component received (len != 0)\n");
- return -1;
- }
- value->pres = PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
- return 2;
- case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2): /* [2] IMPLICIT numberNotAvailableDueToInterworking */
- if (comp->len != 0) { /* must be NULL */
- pri_error(pri, "!! Invalid NumberNotAvailableDueToInterworking component received (len != 0)\n");
- return -1;
- }
- value->pres = PRES_NUMBER_NOT_AVAILABLE;
- return 2;
- case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3): /* [3] presentationRestrictedNumber */
- value->pres = PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
- size = rose_address_decode(pri, call, comp->data, comp->len, value) + 2;
- ASN1_FIXUP_LEN(comp, size);
- return size + 2;
- default:
- pri_message(pri, "Invalid PresentedNumberUnscreened component 0x%X\n", comp->type);
- }
- return -1;
- }
- while (0);
-
- return -1;
-}
-
-static int rose_diverting_leg_information2_decode(struct pri *pri, q931_call *call, struct rose_component *sequence, int len)
-{
- int i = 0;
- int diversion_counter;
- int diversion_reason;
- char origcalledname[50] = "", redirectingname[50] = "";
- struct addressingdataelements_presentednumberunscreened divertingnr;
- struct addressingdataelements_presentednumberunscreened originalcallednr;
- struct rose_component *comp = NULL;
- unsigned char *vdata = sequence->data;
- int res = 0;
- memset(&divertingnr, 0, sizeof(divertingnr));
- memset(&originalcallednr, 0, sizeof(originalcallednr));
-
- /* Data checks */
- if (sequence->type != (ASN1_CONSTRUCTOR | ASN1_SEQUENCE)) { /* Constructed Sequence */
- pri_message(pri, "Invalid DivertingLegInformation2Type argument\n");
- return -1;
- }
-
- if (sequence->len == ASN1_LEN_INDEF) {
- len -= 4; /* For the 2 extra characters at the end
- * and two characters of header */
- } else
- len -= 2;
-
- do {
- /* diversionCounter stuff */
- GET_COMPONENT(comp, i, vdata, len);
- CHECK_COMPONENT(comp, ASN1_INTEGER, "Don't know what to do it diversionCounter is of type 0x%x\n");
- ASN1_GET_INTEGER(comp, diversion_counter);
- NEXT_COMPONENT(comp, i);
-
- /* diversionReason stuff */
- GET_COMPONENT(comp, i, vdata, len);
- CHECK_COMPONENT(comp, ASN1_ENUMERATED, "Invalid diversionReason type 0x%X of ROSE divertingLegInformation2 component received\n");
- ASN1_GET_INTEGER(comp, diversion_reason);
- NEXT_COMPONENT(comp, i);
-
- diversion_reason = redirectingreason_for_q931(pri, diversion_reason);
-
- if(pri->debug & PRI_DEBUG_APDU)
- pri_message(pri, " Redirection reason: %d, total diversions: %d\n", diversion_reason, diversion_counter);
- pri_message(NULL, "Length of message is %d\n", len);
-
- for(; i < len; NEXT_COMPONENT(comp, i)) {
- GET_COMPONENT(comp, i, vdata, len);
- switch(comp->type) {
- case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0):
- call->origredirectingreason = redirectingreason_for_q931(pri, comp->data[0]);
- if (pri->debug & PRI_DEBUG_APDU)
- pri_message(pri, " Received reason for original redirection %d\n", call->origredirectingreason);
- break;
- case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1):
- res = rose_presented_number_unscreened_decode(pri, call, comp->data, comp->len, &divertingnr);
- /* TODO: Fix indefinite length form hacks */
- ASN1_FIXUP_LEN(comp, res);
- comp->len = res;
- if (res < 0)
- return -1;
- if (pri->debug & PRI_DEBUG_APDU) {
- pri_message(pri, " Received divertingNr '%s'\n", divertingnr.partyaddress);
- pri_message(pri, " ton = %d, pres = %d, npi = %d\n", divertingnr.ton, divertingnr.pres, divertingnr.npi);
- }
- break;
- case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_2):
- res = rose_presented_number_unscreened_decode(pri, call, comp->data, comp->len, &originalcallednr);
- if (res < 0)
- return -1;
- ASN1_FIXUP_LEN(comp, res);
- comp->len = res;
- if (pri->debug & PRI_DEBUG_APDU) {
- pri_message(pri, " Received originalcallednr '%s'\n", originalcallednr.partyaddress);
- pri_message(pri, " ton = %d, pres = %d, npi = %d\n", originalcallednr.ton, originalcallednr.pres, originalcallednr.npi);
- }
- break;
- case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3):
- res = asn1_name_decode(comp->data, comp->len, redirectingname, sizeof(redirectingname));
- if (res < 0)
- return -1;
- ASN1_FIXUP_LEN(comp, res);
- comp->len = res;
- if (pri->debug & PRI_DEBUG_APDU)
- pri_message(pri, " Received RedirectingName '%s'\n", redirectingname);
- break;
- case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_4):
- res = asn1_name_decode(comp->data, comp->len, origcalledname, sizeof(origcalledname));
- if (res < 0)
- return -1;
- ASN1_FIXUP_LEN(comp, res);
- comp->len = res;
- if (pri->debug & PRI_DEBUG_APDU)
- pri_message(pri, " Received Originally Called Name '%s'\n", origcalledname);
- break;
- case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_5):
- pri_message(pri, "!! Ignoring DivertingLegInformation2 component 0x%X\n", comp->type);
- break;
- default:
- if (comp->type == 0 && comp->len == 0) {
- break; /* Found termination characters */
- }
- pri_message(pri, "!! Invalid DivertingLegInformation2 component received 0x%X\n", comp->type);
- return -1;
- }
- }
-
- if (divertingnr.pres >= 0) {
- call->redirectingplan = divertingnr.npi;
- call->redirectingpres = divertingnr.pres;
- call->redirectingreason = diversion_reason;
- libpri_copy_string(call->redirectingnum, divertingnr.partyaddress, sizeof(call->redirectingnum));
- pri_message(pri, " Received redirectingnum '%s' (%d)\n", call->redirectingnum, (int)call->redirectingnum[0]);
- }
- if (originalcallednr.pres >= 0) {
- call->origcalledplan = originalcallednr.npi;
- call->origcalledpres = originalcallednr.pres;
- libpri_copy_string(call->origcallednum, originalcallednr.partyaddress, sizeof(call->origcallednum));
- pri_message(pri, " Received origcallednum '%s' (%d)\n", call->origcallednum, (int)call->origcallednum[0]);
- }
- libpri_copy_string(call->redirectingname, redirectingname, sizeof(call->redirectingname));
- libpri_copy_string(call->origcalledname, origcalledname, sizeof(call->origcalledname));
- return 0;
- }
- while (0);
-
- return -1;
-}
-
-static int rose_diverting_leg_information2_encode(struct pri *pri, q931_call *call)
-{
- int i = 0, j, compsp = 0;
- struct rose_component *comp, *compstk[10];
+ default:
+ 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 & PRI_PRES_RESTRICTION) {
+ case PRI_PRES_ALLOWED:
+ value = 0; /* presentationAllowed<Number/Address> */
+ break;
+ default:
+ pri_message(ctrl, "!! Unsupported Q.931 number presentation value (%d)\n",
+ presentation);
+ /* fall through */
+ case PRI_PRES_RESTRICTED:
+ if (number_present) {
+ value = 3; /* presentationRestricted<Number/Address> */
+ } else {
+ value = 1; /* presentationRestricted */
+ }
+ break;
+ case PRI_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 = PRI_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 = PRI_PRES_RESTRICTED;
+ break;
+ case 2: /* numberNotAvailableDueToInterworking */
+ value = PRI_PRES_UNAVAILABLE;
+ break;
+ }
+
+ return value;
+}
+
+/*!
+ * \internal
+ * \brief Encode the Q.SIG DivertingLegInformation2 invoke message.
+ *
+ * \param ctrl D channel controller for diagnostic messages or global options.
+ * \param pos Starting position to encode the facility ie contents.
+ * \param end End of facility ie contents encoding data buffer.
+ * \param call Call leg from which to encode diversion leg 2.
+ *
+ * \retval Start of the next ASN.1 component to encode on success.
+ * \retval NULL on error.
+ */
+static unsigned char *enc_qsig_diverting_leg_information2(struct pri *ctrl,
+ unsigned char *pos, unsigned char *end, q931_call *call)
+{
+ struct fac_extension_header header;
+ struct rose_msg_invoke msg;
+
+ memset(&header, 0, sizeof(header));
+ header.nfe_present = 1;
+ header.nfe.source_entity = 0; /* endPINX */
+ header.nfe.destination_entity = 0; /* endPINX */
+ header.interpretation_present = 1;
+ header.interpretation = 0; /* discardAnyUnrecognisedInvokePdu */
+ pos = facility_encode_header(ctrl, pos, end, &header);
+ if (!pos) {
+ return NULL;
+ }
+
+ memset(&msg, 0, sizeof(msg));
[... 3787 lines stripped ...]
More information about the libpri-commits
mailing list