Провайдер дал поток с сигнализацией ОКС-7 (ss7). Использую chan_ss7
Входящие звонки идут, исходящие идут только для вызовов с 8-кой (очевидно по умолчанию идет NATIONAL). Для местных городских 6-ти значных вызовов есть необходимость устанавливать значение subscriber.
system.conf
Код: Выделить всё
# Span 1: WCT1/0 "Wildcard TE121 Card 0" (MASTER)
span=1,1,0,ccs,hdb3
bchan=1-31
loadzone = ru
defaultzone = ru
Код: Выделить всё
[linkset-rtk]
enabled => yes
enable_st => no
use_connect => yes
hunting_policy => even_mru
context => fromSS7
language => ru
t35 => 15000,timeout
subservice => auto
[link-l1]
linkset => rtk
channels => 1-15,17-31
schannel => 16
firstcic => 1
enabled => yes
[host-my.host.ru]
enabled => yes
default_linkset => rtk
opc => 81
dpc => rtk:16
links => l1:1
В файле ss7.conf в [linkset-rtk] нужно прописать noa => 0x1 для Subscriber, noa => 0x3 для National
После чего нужно перезагружать астериск.
Естественно это не совсем подходит, потому как в зависимости от направления звонка есть потребность устанавливать NOA в то или иное значение.
Поэтому делаем так:
пратчим Name: asterisk1.6.2-chan_ss7, Version: 2.0.0
cat asterisk1.6.2-d00.patch
Код: Выделить всё
--- isup.c.old 2012-01-02 06:54:10.000000000 +0400
+++ isup.c 2012-06-25 14:47:45.026792565 +0400
@@ -487,6 +487,7 @@
case 0x03: // National (significant) number.
break;
case 0x01: // Subscriber local number. Getting this has
+ break;
// got to be wrong, but we've seen it 'in the
// wild' where they looked like international.
@@ -497,10 +498,10 @@
// Intentionally fall-through.
case 0x04: // International -> add '00'.
- num_dig++;
- n->num[i++] = '0';
- num_dig++;
- n->num[i++] = '0';
+// num_dig++;
+// n->num[i++] = '0';
+// num_dig++;
+// n->num[i++] = '0';
break;
default:
ast_log(LOG_NOTICE, "unknown nature of address indicator 0x%0x.\n",
Код: Выделить всё
--- l4isup.c.old 2012-01-02 06:54:10.000000000 +0400
+++ l4isup.c 2012-06-25 12:34:42.483209262 +0400
@@ -1871,7 +1871,7 @@
}
static int isup_phonenum_check(char **number, int *nlen,
- int *is_international) {
+ int *is_international, int *is_mylocal) {
if(*number == NULL) {
ast_log(LOG_DEBUG, "NULL phonenumber, encoding failed.\n");
return -1;
@@ -1891,10 +1891,15 @@
*is_international = 1;
*number += 1;
*nlen -= 1;
+ } else if(strncmp(*number, "L", 1) == 0) {
+ *is_mylocal = 1;
+ *is_international = 0;
+ *number += 1;
+ *nlen -= 1;
} else {
*is_international = 0;
+ *is_mylocal = 0;
}
-
return 0; /* Success */
}
@@ -1940,9 +1945,10 @@
int nlen;
int is_odd;
int is_international;
+ int is_mylocal;
int result_len;
- if(isup_phonenum_check(&number, &nlen, &is_international) == -1) {
+ if(isup_phonenum_check(&number, &nlen, &is_international, &is_mylocal) == -1) {
return -1;
}
@@ -1961,7 +1967,8 @@
if (pvt->link->linkset->noa != -1)
param[0] |= (pvt->link->linkset->noa & 0x7f);
else
- param[0] |= (is_international ? 4 : 3);
+ param[0] |= (is_international ? 4 : (is_mylocal ? 1 : 3));
+ ast_log(LOG_DEBUG, "Parameter is %d Is_int %i Is_local %i Num %s \n", param[0], is_international, is_mylocal, number );
param[1] = 0x10; /* Internal routing allowed, ISDN number plan */
if(isup_phonenum_digits(number, 1, nlen, param) == -1) {
@@ -1977,9 +1984,10 @@
int nlen;
int is_odd;
int is_international;
+ int is_mylocal;
int result_len;
- if(isup_phonenum_check(&number, &nlen, &is_international) == -1) {
+ if(isup_phonenum_check(&number, &nlen, &is_international, &is_mylocal) == -1) {
return -1;
}
@@ -1998,7 +2006,7 @@
if (pvt->link->linkset->noa != -1)
param[0] |= (pvt->link->linkset->noa & 0x7f);
else
- param[0] |= (is_international ? 4 : 3);
+ param[0] |= (is_international ? 4 : (is_mylocal ? 1 : 3));
param[1] = 0x10; /* Internal routing allowed, ISDN number plan */
if(isup_phonenum_digits(number, 0, nlen, param) == -1) {
@@ -2014,9 +2022,10 @@
int nlen;
int is_odd;
int is_international;
+ int is_mylocal;
int result_len;
- if(isup_phonenum_check(&number, &nlen, &is_international) == -1) {
+ if(isup_phonenum_check(&number, &nlen, &is_international, &is_mylocal) == -1) {
return -1;
}
@@ -2029,7 +2038,7 @@
return -1;
}
- param[0] = (is_odd << 7) | (is_international ? 4 : 3);
+ param[0] = (is_odd << 7) | (is_international ? 4 : (is_mylocal ? 1 : 3));
param[1] = 0x10 | si; /* Number complete; ISDN number plan; + screening indicator */
if(pres_restr) {
param[1] |= (0x1 << 2);
1) При входящем звонке не добавляет в номер 00. До этого номер приходил в формате 00495ХХХХХХХ
2) Для исходящих вызовов в диалплане появилась возможность проставлять значение NOA Subscriber или National:
a) Для локальных вызовов NOA=Subscriber=1 , для этого впереди вызываемого номера добавляем L, потом L отрежется и к провайдеру уже без нее полетит.
exten => _11X,1,Set(CALLERID(num)=${IF($[ ${CALLERID(num)} = 209]?495705XXXX:${CALLERID(num)})})
exten => _11X,n,Dial(SS7/rtk/L${EXTEN},300,T)
exten => _11X,n,Hangup()
b) Для междугородних вызовов NOA=National=3, просто передаем номер, ничего спереди добавлять не нужно.
exten => _8X.,1,Set(CALLERID(num)=${IF($[ ${CALLERID(num)} = 209]?495705XXXX:${CALLERID(num)})})
exten => _8X.,n,Dial(SS7/rtk/${EXTEN},300,T)
exten => _8X.,n,Hangup()
c) Для международных вызовов NOA=International=4, добавляем спереди к номеру 00, эти два нуля так же впоследствии отрежутся и к провайдеру без них пойдет.
exten => _810X.,1,Set(CALLERID(num)=${IF($[ ${CALLERID(num)} = 209]?495705XXXX:${CALLERID(num)})})
exten => _810X.,n,Dial(SS7/rtk/00${EXTEN},300,T)
exten => _810X.,n,Hangup()
Надеюсь кому-то эта информация пригодиться.
Так же теперь при звонке стало в лог выводить цифровое значение NOA (выделено жирным). Оно может принимать и большие значение (например 131, 129), просто анализировать надо только младшие три бита числа.
DEBUG[11936]: l4isup.c:1971 isup_called_party_num_encode: Parameter is 1 Is_int 0 Is_local 1 Num 112