Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ace221ca0 | ||
|
|
a7a2245b12 | ||
|
|
c038af7892 | ||
|
|
f8e6096bfe | ||
|
|
d2585d6da2 | ||
|
|
90019b935a |
7
Makefile
7
Makefile
@@ -27,6 +27,8 @@
|
|||||||
CC=gcc
|
CC=gcc
|
||||||
GREP=grep
|
GREP=grep
|
||||||
AWK=awk
|
AWK=awk
|
||||||
|
AR=ar
|
||||||
|
RANLIB=ranlib
|
||||||
|
|
||||||
OSARCH=$(shell uname -s)
|
OSARCH=$(shell uname -s)
|
||||||
PROC?=$(shell uname -m)
|
PROC?=$(shell uname -m)
|
||||||
@@ -67,6 +69,7 @@ STATIC_OBJS= \
|
|||||||
DYNAMIC_OBJS= \
|
DYNAMIC_OBJS= \
|
||||||
$(STATIC_OBJS)
|
$(STATIC_OBJS)
|
||||||
CFLAGS ?= -g
|
CFLAGS ?= -g
|
||||||
|
CFLAGS += $(CPPFLAGS)
|
||||||
CFLAGS += -Wall -Werror -Wstrict-prototypes -Wmissing-prototypes
|
CFLAGS += -Wall -Werror -Wstrict-prototypes -Wmissing-prototypes
|
||||||
CFLAGS += -fPIC $(ALERTING) $(LIBPRI_OPT) $(COVERAGE_CFLAGS)
|
CFLAGS += -fPIC $(ALERTING) $(LIBPRI_OPT) $(COVERAGE_CFLAGS)
|
||||||
INSTALL_PREFIX=$(DESTDIR)
|
INSTALL_PREFIX=$(DESTDIR)
|
||||||
@@ -192,8 +195,8 @@ MAKE_DEPS= -MD -MT $@ -MF .$(subst /,_,$@).d -MP
|
|||||||
$(CC) $(CFLAGS) $(MAKE_DEPS) -c -o $@ $<
|
$(CC) $(CFLAGS) $(MAKE_DEPS) -c -o $@ $<
|
||||||
|
|
||||||
$(STATIC_LIBRARY): $(STATIC_OBJS)
|
$(STATIC_LIBRARY): $(STATIC_OBJS)
|
||||||
ar rcs $(STATIC_LIBRARY) $(STATIC_OBJS)
|
$(AR) rcs $(STATIC_LIBRARY) $(STATIC_OBJS)
|
||||||
ranlib $(STATIC_LIBRARY)
|
$(RANLIB) $(STATIC_LIBRARY)
|
||||||
|
|
||||||
$(DYNAMIC_LIBRARY): $(DYNAMIC_OBJS)
|
$(DYNAMIC_LIBRARY): $(DYNAMIC_OBJS)
|
||||||
$(CC) $(SOFLAGS) -o $@ $(DYNAMIC_OBJS)
|
$(CC) $(SOFLAGS) -o $@ $(DYNAMIC_OBJS)
|
||||||
|
|||||||
116
q931.c
116
q931.c
@@ -2196,17 +2196,33 @@ static int transmit_subaddr_helper(int full_ie, struct pri *ctrl, struct q931_pa
|
|||||||
|
|
||||||
static int receive_subaddr_helper(int full_ie, struct pri *ctrl, struct q931_party_subaddress *q931_subaddress, int msgtype, q931_ie *ie, int offset, int len)
|
static int receive_subaddr_helper(int full_ie, struct pri *ctrl, struct q931_party_subaddress *q931_subaddress, int msgtype, q931_ie *ie, int offset, int len)
|
||||||
{
|
{
|
||||||
|
int i = -1;
|
||||||
|
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To follow Q.931 (4.5.1), we must search for start of octet 4 by
|
||||||
|
* walking through all bytes until one with ext bit (8) set to 1
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
++i;
|
||||||
|
switch (i) {
|
||||||
|
case 0: /* Octet 3 */
|
||||||
|
/* type: 0 = NSAP, 2 = User Specified */
|
||||||
|
q931_subaddress->type = ((ie->data[0] & 0x70) >> 4);
|
||||||
|
q931_subaddress->odd_even_indicator = (ie->data[0] & 0x08) ? 1 : 0;
|
||||||
|
break;
|
||||||
|
default: /* Octet 3* extra */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (!(ie->data[i] & 0x80) && len - i);
|
||||||
|
|
||||||
q931_subaddress->valid = 1;
|
q931_subaddress->valid = 1;
|
||||||
q931_subaddress->length = len;
|
q931_subaddress->length = len - i;
|
||||||
/* type: 0 = NSAP, 2 = User Specified */
|
|
||||||
q931_subaddress->type = ((ie->data[0] & 0x70) >> 4);
|
|
||||||
q931_subaddress->odd_even_indicator = (ie->data[0] & 0x08) ? 1 : 0;
|
|
||||||
q931_memget(q931_subaddress->data, sizeof(q931_subaddress->data),
|
q931_memget(q931_subaddress->data, sizeof(q931_subaddress->data),
|
||||||
ie->data + offset, len);
|
ie->data + offset + i, len - i);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2214,13 +2230,22 @@ static int receive_subaddr_helper(int full_ie, struct pri *ctrl, struct q931_par
|
|||||||
static void dump_subaddr_helper(int full_ie, struct pri *ctrl, q931_ie *ie, int offset, int len, int datalen, char prefix)
|
static void dump_subaddr_helper(int full_ie, struct pri *ctrl, q931_ie *ie, int offset, int len, int datalen, char prefix)
|
||||||
{
|
{
|
||||||
unsigned char cnum[256];
|
unsigned char cnum[256];
|
||||||
|
int i = -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To follow Q.931 (4.5.1), we must search for start of octet 4 by
|
||||||
|
* walking through all bytes until one with ext bit (8) set to 1
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
++i;
|
||||||
|
} while (!(ie->data[i] & 0x80) && datalen - i);
|
||||||
|
|
||||||
if (!(ie->data[0] & 0x70)) {
|
if (!(ie->data[0] & 0x70)) {
|
||||||
/* NSAP Get it as a string for dump display purposes only. */
|
/* NSAP Get it as a string for dump display purposes only. */
|
||||||
q931_strget(cnum, sizeof(cnum), ie->data + offset, datalen);
|
q931_strget(cnum, sizeof(cnum), ie->data + offset + i, datalen - i);
|
||||||
} else {
|
} else {
|
||||||
/* User Specified */
|
/* User Specified */
|
||||||
q931_get_subaddr_specific(cnum, sizeof(cnum), ie->data + offset, datalen,
|
q931_get_subaddr_specific(cnum, sizeof(cnum), ie->data + offset + i, datalen - i,
|
||||||
ie->data[0] & 0x08);
|
ie->data[0] & 0x08);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2340,6 +2365,7 @@ static int receive_connected_number(int full_ie, struct pri *ctrl, q931_call *ca
|
|||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
/* Reference Q.951 Section 5.4.1 for ie */
|
||||||
call->connected_number_in_message = 1;
|
call->connected_number_in_message = 1;
|
||||||
call->remote_id.number.valid = 1;
|
call->remote_id.number.valid = 1;
|
||||||
call->remote_id.number.presentation =
|
call->remote_id.number.presentation =
|
||||||
@@ -2350,7 +2376,39 @@ static int receive_connected_number(int full_ie, struct pri *ctrl, q931_call *ca
|
|||||||
switch (i) {
|
switch (i) {
|
||||||
case 0:
|
case 0:
|
||||||
call->remote_id.number.plan = ie->data[i] & 0x7f;
|
call->remote_id.number.plan = ie->data[i] & 0x7f;
|
||||||
break;
|
|
||||||
|
/*
|
||||||
|
* Work around a bug in a Lucent switch implementation that
|
||||||
|
* sets the extension bit in octet 3 even though octet 3a
|
||||||
|
* is present.
|
||||||
|
*
|
||||||
|
* The same issue was seen in a NI2 switch implementation.
|
||||||
|
* It was probably a Lucent switch configured for NI2
|
||||||
|
* operation. To avoid further surprises, I'm going to
|
||||||
|
* enable the work around for all North American switch
|
||||||
|
* types.
|
||||||
|
*/
|
||||||
|
if (ie->data[i] & 0x80) {
|
||||||
|
/* Octet 3 extension bit is set */
|
||||||
|
if (ctrl->switchtype != PRI_SWITCH_LUCENT5E
|
||||||
|
&& ctrl->switchtype != PRI_SWITCH_ATT4ESS
|
||||||
|
&& ctrl->switchtype != PRI_SWITCH_NI1
|
||||||
|
&& ctrl->switchtype != PRI_SWITCH_NI2
|
||||||
|
&& ctrl->switchtype != PRI_SWITCH_DMS100) {
|
||||||
|
/* Not a potentially buggy switch type. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!(ie->data[i + 1] & 0x80)) {
|
||||||
|
/*
|
||||||
|
* The possible octet 3a doesn't have the extension
|
||||||
|
* bit set. It is likely not the erroneous octet 3a.
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Octet 3a is present */
|
||||||
|
++i;
|
||||||
|
/* Fall through */
|
||||||
case 1:
|
case 1:
|
||||||
/* Keep only the presentation and screening fields */
|
/* Keep only the presentation and screening fields */
|
||||||
call->remote_id.number.presentation =
|
call->remote_id.number.presentation =
|
||||||
@@ -2392,7 +2450,44 @@ static void dump_connected_number(int full_ie, struct pri *ctrl, q931_ie *ie, in
|
|||||||
prefix, ie2str(full_ie), len, ie->data[0] >> 7,
|
prefix, ie2str(full_ie), len, ie->data[0] >> 7,
|
||||||
ton2str((ie->data[0] >> 4) & 0x07), (ie->data[0] >> 4) & 0x07,
|
ton2str((ie->data[0] >> 4) & 0x07), (ie->data[0] >> 4) & 0x07,
|
||||||
npi2str(ie->data[0] & 0x0f), ie->data[0] & 0x0f);
|
npi2str(ie->data[0] & 0x0f), ie->data[0] & 0x0f);
|
||||||
break;
|
|
||||||
|
/*
|
||||||
|
* Work around a bug in a Lucent switch implementation that
|
||||||
|
* sets the extension bit in octet 3 even though octet 3a
|
||||||
|
* is present.
|
||||||
|
*
|
||||||
|
* The same issue was seen in a NI2 switch implementation.
|
||||||
|
* It was probably a Lucent switch configured for NI2
|
||||||
|
* operation. To avoid further surprises, I'm going to
|
||||||
|
* enable the work around for all North American switch
|
||||||
|
* types.
|
||||||
|
*/
|
||||||
|
if (ie->data[i] & 0x80) {
|
||||||
|
/* Octet 3 extension bit is set */
|
||||||
|
if (ctrl->switchtype != PRI_SWITCH_LUCENT5E
|
||||||
|
&& ctrl->switchtype != PRI_SWITCH_ATT4ESS
|
||||||
|
&& ctrl->switchtype != PRI_SWITCH_NI1
|
||||||
|
&& ctrl->switchtype != PRI_SWITCH_NI2
|
||||||
|
&& ctrl->switchtype != PRI_SWITCH_DMS100) {
|
||||||
|
/* Not a potentially buggy switch type. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!(ie->data[i + 1] & 0x80)) {
|
||||||
|
/*
|
||||||
|
* The possible octet 3a doesn't have the extension
|
||||||
|
* bit set. It is likely not the erroneous octet 3a.
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pri_message(ctrl, "\n");
|
||||||
|
pri_message(ctrl, "%c Switch bug workaround.\n",
|
||||||
|
prefix);
|
||||||
|
pri_message(ctrl, "%c Assuming octet 3a is present.",
|
||||||
|
prefix);
|
||||||
|
}
|
||||||
|
/* Octet 3a is present */
|
||||||
|
++i;
|
||||||
|
/* Fall through */
|
||||||
case 1: /* Octet 3a */
|
case 1: /* Octet 3a */
|
||||||
pri_message(ctrl, "\n");
|
pri_message(ctrl, "\n");
|
||||||
pri_message(ctrl, "%c Ext: %d Presentation: %s (%d)",
|
pri_message(ctrl, "%c Ext: %d Presentation: %s (%d)",
|
||||||
@@ -2429,6 +2524,7 @@ static int receive_redirecting_number(int full_ie, struct pri *ctrl, q931_call *
|
|||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
/* Reference Q.952 Section 4.1.2 for ie */
|
||||||
call->redirecting_number_in_message = 1;
|
call->redirecting_number_in_message = 1;
|
||||||
call->redirecting.from.number.valid = 1;
|
call->redirecting.from.number.valid = 1;
|
||||||
call->redirecting.from.number.presentation =
|
call->redirecting.from.number.presentation =
|
||||||
@@ -2507,6 +2603,7 @@ static int receive_redirection_number(int full_ie, struct pri *ctrl, q931_call *
|
|||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
/* Reference Q.952 Section 4.1.3 for ie */
|
||||||
call->redirection_number.valid = 1;
|
call->redirection_number.valid = 1;
|
||||||
call->redirection_number.presentation =
|
call->redirection_number.presentation =
|
||||||
PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
|
PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||||
@@ -2650,6 +2747,7 @@ static int receive_calling_party_number(int full_ie, struct pri *ctrl, q931_call
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
struct q931_party_number number;
|
struct q931_party_number number;
|
||||||
|
|
||||||
|
/* Reference Q.931 Section 4.5.10 for ie */
|
||||||
q931_party_number_init(&number);
|
q931_party_number_init(&number);
|
||||||
number.valid = 1;
|
number.valid = 1;
|
||||||
number.presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
|
number.presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||||
|
|||||||
Reference in New Issue
Block a user