[asterisk-ss7] chan_ss7 decoding isup phone num

Gregory Massel greg at csurf.co.za
Wed Jun 23 05:25:26 CDT 2010


I wrote the following patch to deal with subscriber numbers and special 
characters that we see with subscriber numbers:

--- l4isup.c.old        2009-12-06 11:34:42.000000000 +0200
+++ l4isup.c    2010-05-27 11:43:45.000000000 +0200
@@ -1689,7 +1689,7 @@ static void check_obci(struct ss7_chan*
 }

 static int isup_phonenum_check(char **number, int *nlen,
-                               int *is_international) {
+                               int *is_international, int 
*is_subscribernumber) {
   if(*number == NULL) {
     ast_log(LOG_DEBUG, "NULL phonenumber, encoding failed.\n");
     return -1;
@@ -1703,14 +1703,22 @@ static int isup_phonenum_check(char **nu
   /* Handle both '00' and '+' as international prefix. */
   if(strncmp(*number, "00", 2) == 0) {
     *is_international = 1;
+    *is_subscribernumber = 0;
     *number += 2;
     *nlen -= 2;
   } else if(strncmp(*number, "+", 1) == 0) {
     *is_international = 1;
+    *is_subscribernumber = 0;
     *number += 1;
     *nlen -= 1;
-  } else {
+  } else if(strncmp(*number, "0", 1) == 0) {   /* Handle '0' as national 
prefix. */
+    *is_international = 0;
+    *is_subscribernumber = 0;
+    *number += 1;
+    *nlen -= 1;
+  } else {     /* Must be a subscriber number */
     *is_international = 0;
+    *is_subscribernumber = 1;
   }

   return 0;                     /* Success */
@@ -1730,10 +1738,14 @@ static int isup_phonenum_digits(char *nu
     } else {
       if ((number[i] >= '0') && (number[i] <= '9'))
        d = number[i] - '0';
+      else if ((number[i] == 'a') || (number[i] == 'A'))
+       d = 0x0a;
       else if ((number[i] == 'b') || (number[i] == 'B'))
        d = 0x0b;
       else if ((number[i] == 'c') || (number[i] == 'C'))
        d = 0x0c;
+      else if ((number[i] == 'd') || (number[i] == 'D'))
+       d = 0x0d;
       else if ((number[i] == 'e') || (number[i] == 'E'))
        d = 0x0e;
       else {
@@ -1758,9 +1770,10 @@ int isup_called_party_num_encode(struct
   int nlen;
   int is_odd;
   int is_international;
+  int is_subscribernumber;
   int result_len;

-  if(isup_phonenum_check(&number, &nlen, &is_international) == -1) {
+  if(isup_phonenum_check(&number, &nlen, &is_international, 
&is_subscribernumber) == -1) {
     return -1;
   }

@@ -1779,7 +1792,7 @@ int isup_called_party_num_encode(struct
   if (pvt->link->linkset->noa != -1)
     param[0] |= (pvt->link->linkset->noa & 0x7f);
   else
-    param[0] |= (is_international ? 4 : 3);
+    param[0] |= (is_subscribernumber ? 1 : (is_international ? 4 : 3));
   param[1] = 0x10; /* Internal routing allowed, ISDN number plan */

   if(isup_phonenum_digits(number, 1, nlen, param) == -1) {
@@ -1795,9 +1808,10 @@ int isup_called_party_num_encode_no_st(s
   int nlen;
   int is_odd;
   int is_international;
+  int is_subscribernumber;
   int result_len;

-  if(isup_phonenum_check(&number, &nlen, &is_international) == -1) {
+  if(isup_phonenum_check(&number, &nlen, &is_international, 
&is_subscribernumber) == -1) {
     return -1;
   }

@@ -1816,7 +1830,7 @@ int isup_called_party_num_encode_no_st(s
   if (pvt->link->linkset->noa != -1)
     param[0] |= (pvt->link->linkset->noa & 0x7f);
   else
-    param[0] |= (is_international ? 4 : 3);
+    param[0] |= (is_subscribernumber ? 1 : (is_international ? 4 : 3));
   param[1] = 0x10; /* Internal routing allowed, ISDN number plan */

   if(isup_phonenum_digits(number, 0, nlen, param) == -1) {
@@ -1832,9 +1846,10 @@ int isup_calling_party_num_encode(char *
   int nlen;
   int is_odd;
   int is_international;
+  int is_subscribernumber;
   int result_len;

-  if(isup_phonenum_check(&number, &nlen, &is_international) == -1) {
+  if(isup_phonenum_check(&number, &nlen, &is_international, 
&is_subscribernumber) == -1) {
     return -1;
   }

@@ -1847,7 +1862,7 @@ int isup_calling_party_num_encode(char *
     return -1;
   }

-  param[0] = (is_odd << 7) | (is_international ? 4 : 3);
+  param[0] = (is_odd << 7) | (is_subscribernumber ? 1 : (is_international ? 
4 : 3));
   param[1] = 0x10 | si; /* Number complete; ISDN number plan; + screening 
indicator */
   if(pres_restr) {
     param[1] |= (0x1 << 2);


One should probably also patch the "decode_isup_phonenum" function in isup.c 
as well so that it doesn't log a warning message and doesn't prepend '00' in 
respect of subscriber numbers. I didn't bother as the warning doesn't bother 
me and I'm just stripping the 00 off within the dialplan.

Out of interest, in what circumstances do you receive NAI of subscriber 
number?

We receive it on calls to all numbers that have been ported into our network 
and have a port-code prepended to the number by the number block operator.

We send it on all calls to numbers that are short-coded operator numbers, 
e.g. three and four-digit numbers for services like directory enquiries. We 
also send it on all calls to numbers ported out of our network for which 
we've pre-pended the recipient operator's port code. Our port codes start 
with 'D' hence the patch to match the missing hex character digits.

--Greg

----- Original Message ----- 
From: "Kristian Nielsen" <knielsen at knielsen-hq.org>
To: <elcaio at gmail.com>
Cc: <asterisk-ss7 at lists.digium.com>
Sent: Wednesday, June 23, 2010 12:04 PM
Subject: Re: [asterisk-ss7] chan_ss7 decoding isup phone num


> Claudio Furrer <elcaio at gmail.com> writes:
>
>> Does anybody know why chan_ss7 fall-through to international phone 
>> number, no
>> matters if the number is national or subscriber local one? (I mean in 
>> incoming
>> calls, from pstn).
>
> It's my fault :) Here is the story ...
>
> Back in 2005 when I wrote the original chan_ss7, our systems were running
> inside the central switching point for a Danish mobile operator. In this
> context, subscriber local makes little sense (we were running centrally, 
> not
> on a local end-subscriber switch, and Denmark have no subscriber-local 
> numbers
> anyway, much less for mobile numbers).
>
> At some point (I think even pre-chan_ss7), we had seen some rare occasions
> where an incoming call would arrive from some exotic country with a 
> calling
> number that was obviously international (had a national prefix etc.), yet 
> was
> marked as "subscriber local", which is obviously wrong. "Subscriber local"
> makes little sense when crossing national borders ...
>
> So a quick hack was made to convert these to "international", and it seems
> that hack carried over into chan_ss7.
>
> So that's the "why" :) Obviously, with chan_ss7 now having reached a much 
> much
> broader usage, this needs to be fixed. Someone should decide how to expose
> the "subscriber local" and similar flags to the dialplan, and once that is
> decided it shouldn't be hard to fix the code...
>
> - Kristian.
>
> -- 
> _____________________________________________________________________
> -- Bandwidth and Colocation Provided by http://www.api-digital.com --
>
> asterisk-ss7 mailing list
> To UNSUBSCRIBE or update options visit:
>   http://lists.digium.com/mailman/listinfo/asterisk-ss7
> 




More information about the asterisk-ss7 mailing list