Update of /usr/cvsroot/libpri
In directory mongoose.digium.com:/tmp/cvs-serv16702

Modified Files:
        libpri.h pri_facility.c pri_facility.h pri_internal.h q931.c 
Log Message:
BIG libpri-matt merge.  Adding new event information and fixing the
parsing routing for DivertingLegInformation2 so that it can work with
indefinite length-encoded ASN.1 parameters


Index: libpri.h
===================================================================
RCS file: /usr/cvsroot/libpri/libpri.h,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -d -r1.48 -r1.49
--- libpri.h    6 Apr 2005 19:14:39 -0000       1.48
+++ libpri.h    6 Apr 2005 19:42:41 -0000       1.49
@@ -305,6 +305,7 @@
        int ani2;                   /* ANI II */
        char callednum[256];            /* Called number */
        char redirectingnum[256];               /* Redirecting number */
+       char redirectingname[256];              /* Redirecting name */
        int redirectingreason;                  /* Reason for redirect */
        char useruserinfo[256];                 /* User->User info */
        int flexible;                           /* Are we flexible with our 
channel selection? */
@@ -316,6 +317,9 @@
        char callingsubaddr[256];               /* Calling parties subaddress */
        int progress;
        int progressmask;
+       char origcalledname[256];
+       char origcallednum[256];
+       int origredirectingreason;
 } pri_event_ring;
 
 typedef struct pri_event_hangup {

Index: pri_facility.c
===================================================================
RCS file: /usr/cvsroot/libpri/pri_facility.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- pri_facility.c      5 Apr 2005 03:55:58 -0000       1.8
+++ pri_facility.c      6 Apr 2005 19:42:41 -0000       1.9
@@ -181,6 +181,25 @@
        }
 }
 
+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(comp->data);
+               res = datalen + 2;
+       } else
+               datalen = res = comp->len;
+
+       if (datalen > buflen) {
+               /* Truncate */
+               datalen = buflen;
+               memcpy(namebuf, comp->data, datalen);
+       }
+       return res;
+}
+
 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;
@@ -204,18 +223,26 @@
        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) {
+               if(comp->len > 20 && comp->len != ASN1_LEN_INDEF) {
                        pri_message("!! Oversized NumberDigits component 
(%d)\n", comp->len);
                        return -1;
                }
-               memcpy(value->partyaddress, comp->data, comp->len);
-               value->partyaddress[comp->len] = '\0';
+               if (comp->len == ASN1_LEN_INDEF) {
+                       datalen = strlen(comp->data);
+                       res = datalen + 2;
+               } else
+                       res = datalen = comp->len;
+                       
+               memcpy(value->partyaddress, comp->data, datalen);
+               value->partyaddress[datalen] = '\0';
 
-               return 0;
+               return res + 2;
        }
        while(0);
        
@@ -228,6 +255,7 @@
        struct rose_component *comp = NULL;
        unsigned char *vdata = data;
        int ton;
+       int res = 0;
 
        if (len < 2)
                return -1;
@@ -239,11 +267,12 @@
                NEXT_COMPONENT(comp, i);
                ton = typeofnumber_for_q931(pri, ton);
 
-               if(rose_number_digits_decode(pri, call, &vdata[i], len-i, 
value))
+               res = rose_number_digits_decode(pri, call, &vdata[i], len-i, 
value);
+               if (res < 0)
                        return -1;
                value->ton = ton;
 
-               return 0;
+               return res + 2;
 
        } while(0);
        return -1;
@@ -254,19 +283,22 @@
        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 */
-                       if(rose_number_digits_decode(pri, call, comp->data, 
comp->len, value))
+                       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_CONSTRUCTOR | ASN1_TAG_1):   
/* [1] publicPartyNumber */
-                       if(rose_public_party_number_decode(pri, call, 
comp->data, comp->len, value) != 0)
+                       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;
@@ -281,7 +313,8 @@
                        pri_message("!! dataPartyNumber isn't handled\n");
                        return -1;
                case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_4):   
/* [4] telexPartyNumber */
-                       if (rose_number_digits_decode(pri, call, comp->data, 
comp->len, value))
+                       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 /* ??? */;
@@ -292,7 +325,8 @@
                        value->npi = PRI_NPI_PRIVATE;
                        return -1;
                case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_8):   
/* [8] nationalStandardPartyNumber */
-                       if (rose_number_digits_decode(pri, call, comp->data, 
comp->len, value))
+                       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;
@@ -304,7 +338,7 @@
                NEXT_COMPONENT(comp, i);
                if(i < len)
                        pri_message("!! not all information is handled from 
Address component\n");
-               return 0;
+               return res;
        }
        while (0);
 
@@ -328,24 +362,24 @@
                switch(comp->type) {
                case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0):   
        /* [0] presentationAllowedNumber */
                        value->pres = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
-                       return rose_address_decode(pri, call, comp->data, 
comp->len, value);
+                       return rose_address_decode(pri, call, comp->data, 
comp->len, value) + 2;
                case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1):              /* [1] 
IMPLICIT presentationRestricted */
                        if (comp->len != 0) { /* must be NULL */
                                pri_error("!! Invalid PresentationRestricted 
component received (len != 0)\n");
                                return -1;
                        }
                        value->pres = PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
-                       return 0;
+                       return 2;
                case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2):              /* [2] 
IMPLICIT numberNotAvailableDueToInterworking */
                        if (comp->len != 0) { /* must be NULL */
                                pri_error("!! Invalid 
NumberNotAvailableDueToInterworking component received (len != 0)\n");
                                return -1;
                        }
                        value->pres = PRES_NUMBER_NOT_AVAILABLE;
-                       return 0;
+                       return 2;
                case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3):   
        /* [3] presentationRestrictedNumber */
                        value->pres = PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
-                       return rose_address_decode(pri, call, comp->data, 
comp->len, value);
+                       return rose_address_decode(pri, call, comp->data, 
comp->len, value) + 2;
                default:
                        pri_message("Invalid PresentedNumberUnscreened 
component 0x%X\n", comp->type);
                }
@@ -361,10 +395,12 @@
        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 = data;
+       int res = 0;
 
        do {
                /* diversionCounter stuff */
@@ -386,23 +422,43 @@
 
                for(; i < len; NEXT_COMPONENT(comp, i)) {
                        GET_COMPONENT(comp, i, vdata, len);
-                       switch(comp->type) {
-                       case 0xA1:              /* divertingnr: 
presentednumberunscreened */
-                               if(rose_presented_number_unscreened_decode(pri, 
call, comp->data, comp->len, &divertingnr) != 0)
+                       switch(comp->type & ASN1_TYPE_MASK) {
+                       case ASN1_TAG_0:
+                               call->origredirectingreason = 
redirectingreason_for_q931(pri, comp->data[0]);
+                               if (pri->debug & PRI_DEBUG_APDU)
+                                       pri_message("    Received reason for 
original redirection %d\n", call->origredirectingreason);
+                               break;
+                       case ASN1_TAG_1:                /* divertingnr: 
presentednumberunscreened */
+                               res = 
rose_presented_number_unscreened_decode(pri, call, comp->data, comp->len, 
&divertingnr);
+                               /* TODO: Fix indefinite length form hacks */
+                               comp->len = res;
+                               if (res < 0)
                                        return -1;
                                if (pri->debug & PRI_DEBUG_APDU) {
                                        pri_message("    Received divertingNr 
'%s'\n", divertingnr.partyaddress);
                                        pri_message("      ton = %d, pres = %d, 
npi = %d\n", divertingnr.ton, divertingnr.pres, divertingnr.npi);
                                }
                                break;
-                       case 0xA2:              /* originalCalledNr: 
PresentedNumberUnscreened */
-                               if(rose_presented_number_unscreened_decode(pri, 
call, comp->data, comp->len, &originalcallednr) != 0)
+                       case ASN1_TAG_2:                /* originalCalledNr: 
PresentedNumberUnscreened */
+                               res = 
rose_presented_number_unscreened_decode(pri, call, comp->data, comp->len, 
&originalcallednr);
+                               if (res < 0)
                                        return -1;
+                               comp->len = res;
                                if (pri->debug & PRI_DEBUG_APDU) {
                                        pri_message("    Received 
originalcallednr '%s'\n", originalcallednr.partyaddress);
                                        pri_message("      ton = %d, pres = %d, 
npi = %d\n", originalcallednr.ton, originalcallednr.pres, originalcallednr.npi);
                                }
                                break;
+                       case ASN1_TAG_3:
+                               comp->len = asn1_name_decode(comp->data, 
comp->len, redirectingname, sizeof(redirectingname));
+                               if (pri->debug & PRI_DEBUG_APDU)
+                                       pri_message("    Received 
RedirectingName '%s'\n", redirectingname);
+                               break;
+                       case ASN1_TAG_4:
+                               comp->len = asn1_name_decode(comp->data, 
comp->len, origcalledname, sizeof(origcalledname));
+                               if (pri->debug & PRI_DEBUG_APDU)
+                                       pri_message("    Received Originally 
Called Name '%s'\n", origcalledname);
+                               break;
                        default:
                                pri_message("!! Invalid 
DivertingLegInformation2 component received 0x%X\n", comp->type);
                                return -1;
@@ -418,12 +474,19 @@
                        strncpy(call->redirectingnum, divertingnr.partyaddress, 
sizeof(call->redirectingnum)-1);
                        call->redirectingnum[sizeof(call->redirectingnum)-1] = 
'\0';
                }
-               else if (originalcallednr.pres >= 0) {
-                       call->redirectingplan = originalcallednr.npi;
-                       call->redirectingpres = originalcallednr.pres;
-                       call->redirectingreason = diversion_reason;
-                       strncpy(call->redirectingnum, 
originalcallednr.partyaddress, sizeof(call->redirectingnum)-1);
-                       call->redirectingnum[sizeof(call->redirectingnum)-1] = 
'\0';
+               if (originalcallednr.pres >= 0) {
+                       call->origcalledplan = originalcallednr.npi;
+                       call->origcalledpres = originalcallednr.pres;
+                       strncpy(call->origcallednum, 
originalcallednr.partyaddress, sizeof(call->origcallednum)-1);
+                       call->origcallednum[sizeof(call->origcallednum)-1] = 
'\0';
+               }
+               if (strlen(redirectingname) > 0) {
+                       strncpy(call->redirectingname, redirectingname, 
sizeof(call->redirectingname));
+                       call->redirectingname[sizeof(call->redirectingname)-1] 
= '\0';
+               }
+               if (strlen(origcalledname) > 0) {
+                       strncpy(call->origcalledname, origcalledname, 
sizeof(call->origcalledname));
+                       call->origcalledname[sizeof(call->origcalledname)-1] = 
'\0';
                }
                return 0;
        }

Index: pri_facility.h
===================================================================
RCS file: /usr/cvsroot/libpri/pri_facility.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- pri_facility.h      5 Apr 2005 03:55:58 -0000       1.4
+++ pri_facility.h      6 Apr 2005 19:42:41 -0000       1.5
@@ -107,6 +107,9 @@
 #define ASN1_CONTEXT_SPECIFIC  0x80
 #define ASN1_PRIVATE                   0xc0
 
+/* ASN.1 Length masks */
+#define ASN1_LEN_INDEF                 0x80
+
 
 #define INVOKE_OPERATION_INT   __USE_ASN1_INTEGER
 #define INVOKE_OBJECT_ID               __USE_ASN1_OBJECTIDENTIFIER
@@ -225,6 +228,9 @@
 
 extern int asn1_string_encode(unsigned char asn1_type, void *data, int len, 
int max_len, void *src, int src_len);
 
+/* Get Name types from ASN.1 */
+extern int asn1_name_decode(void * data, int len, char *namebuf, int buflen);
+
 extern int typeofnumber_from_q931(struct pri *pri, int ton);
 
 extern int redirectingreason_from_q931(struct pri *pri, int redirectingreason);

Index: pri_internal.h
===================================================================
RCS file: /usr/cvsroot/libpri/pri_internal.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- pri_internal.h      5 Apr 2005 03:55:58 -0000       1.19
+++ pri_internal.h      6 Apr 2005 19:42:41 -0000       1.20
@@ -211,10 +211,19 @@
 
        int retranstimer;               /* Timer for retransmitting DISC */
        int t308_timedout;              /* Whether t308 timed out once */
+
        int redirectingplan;
        int redirectingpres;
        int redirectingreason;        
-       char redirectingnum[256];
+       char redirectingnum[256];       /* Number of redirecting party */
+       char redirectingname[256];      /* Name of redirecting party */
+
+       /* Filled in cases of multiple diversions */
+       int origcalledplan;
+       int origcalledpres;
+       int origredirectingreason;      /* Original reason for redirect (in 
cases of multiple redirects) */
+       char origcalledname[256];       /* Original name of person being called 
*/
+       char origcallednum[256];                /* Orignal number of person 
being called */
 
         int useruserprotocoldisc;
        char useruserinfo[256];

Index: q931.c
===================================================================
RCS file: /usr/cvsroot/libpri/q931.c,v
retrieving revision 1.123
retrieving revision 1.124
diff -u -d -r1.123 -r1.124
--- q931.c      5 Apr 2005 21:54:15 -0000       1.123
+++ q931.c      6 Apr 2005 19:42:41 -0000       1.124
@@ -3151,7 +3151,13 @@
                 c->redirectingplan = -1;
                 c->redirectingpres = -1;
                 c->redirectingreason = -1;
+                c->origcalledplan = -1;
+                c->origcalledpres = -1;
+                c->origredirectingreason = -1;
                strcpy(c->redirectingnum, "");
+               strcpy(c->origcallednum, "");
+               strcpy(c->redirectingname, "");
+               strcpy(c->origcalledname, "");
                 c->useruserprotocoldisc = -1; 
                strcpy(c->useruserinfo, "");
                c->complete = 0;
@@ -3357,8 +3363,13 @@
                pri->ev.ring.calledplan = c->calledplan;
                strncpy(pri->ev.ring.callingsubaddr, c->callingsubaddr, 
sizeof(pri->ev.ring.callingsubaddr) - 1);
                strncpy(pri->ev.ring.callednum, c->callednum, 
sizeof(pri->ev.ring.callednum) - 1);
+               strncpy(pri->ev.ring.origcalledname, c->origcalledname, 
sizeof(pri->ev.ring.origcalledname) - 1);
+               strncpy(pri->ev.ring.origcallednum, c->origcallednum, 
sizeof(pri->ev.ring.origcallednum) - 1);
                 strncpy(pri->ev.ring.redirectingnum, c->redirectingnum, 
sizeof(pri->ev.ring.redirectingnum) - 1);
+                strncpy(pri->ev.ring.redirectingname, c->redirectingname, 
sizeof(pri->ev.ring.redirectingname) - 1);
                 strncpy(pri->ev.ring.useruserinfo, c->useruserinfo, 
sizeof(pri->ev.ring.useruserinfo) - 1);
+               pri->ev.ring.redirectingreason = c->redirectingreason;
+               pri->ev.ring.origredirectingreason = c->origredirectingreason;
                pri->ev.ring.flexible = ! (c->chanflags & FLAG_EXCLUSIVE);
                pri->ev.ring.cref = c->cr;
                pri->ev.ring.call = c;

_______________________________________________
Asterisk-Cvs mailing list
[email protected]
http://lists.digium.com/mailman/listinfo/asterisk-cvs

Reply via email to