Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ace221ca0 | ||
|
|
a7a2245b12 | ||
|
|
c038af7892 | ||
|
|
f8e6096bfe | ||
|
|
d2585d6da2 | ||
|
|
90019b935a |
7
Makefile
7
Makefile
@@ -27,6 +27,8 @@
|
||||
CC=gcc
|
||||
GREP=grep
|
||||
AWK=awk
|
||||
AR=ar
|
||||
RANLIB=ranlib
|
||||
|
||||
OSARCH=$(shell uname -s)
|
||||
PROC?=$(shell uname -m)
|
||||
@@ -67,6 +69,7 @@ STATIC_OBJS= \
|
||||
DYNAMIC_OBJS= \
|
||||
$(STATIC_OBJS)
|
||||
CFLAGS ?= -g
|
||||
CFLAGS += $(CPPFLAGS)
|
||||
CFLAGS += -Wall -Werror -Wstrict-prototypes -Wmissing-prototypes
|
||||
CFLAGS += -fPIC $(ALERTING) $(LIBPRI_OPT) $(COVERAGE_CFLAGS)
|
||||
INSTALL_PREFIX=$(DESTDIR)
|
||||
@@ -192,8 +195,8 @@ MAKE_DEPS= -MD -MT $@ -MF .$(subst /,_,$@).d -MP
|
||||
$(CC) $(CFLAGS) $(MAKE_DEPS) -c -o $@ $<
|
||||
|
||||
$(STATIC_LIBRARY): $(STATIC_OBJS)
|
||||
ar rcs $(STATIC_LIBRARY) $(STATIC_OBJS)
|
||||
ranlib $(STATIC_LIBRARY)
|
||||
$(AR) rcs $(STATIC_LIBRARY) $(STATIC_OBJS)
|
||||
$(RANLIB) $(STATIC_LIBRARY)
|
||||
|
||||
$(DYNAMIC_LIBRARY): $(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)
|
||||
{
|
||||
int i = -1;
|
||||
|
||||
if (len <= 0) {
|
||||
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->length = len;
|
||||
/* 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_subaddress->length = len - i;
|
||||
q931_memget(q931_subaddress->data, sizeof(q931_subaddress->data),
|
||||
ie->data + offset, len);
|
||||
ie->data + offset + i, len - i);
|
||||
|
||||
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)
|
||||
{
|
||||
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)) {
|
||||
/* 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 {
|
||||
/* 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);
|
||||
}
|
||||
|
||||
@@ -2340,6 +2365,7 @@ static int receive_connected_number(int full_ie, struct pri *ctrl, q931_call *ca
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
/* Reference Q.951 Section 5.4.1 for ie */
|
||||
call->connected_number_in_message = 1;
|
||||
call->remote_id.number.valid = 1;
|
||||
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) {
|
||||
case 0:
|
||||
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:
|
||||
/* Keep only the presentation and screening fields */
|
||||
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,
|
||||
ton2str((ie->data[0] >> 4) & 0x07), (ie->data[0] >> 4) & 0x07,
|
||||
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 */
|
||||
pri_message(ctrl, "\n");
|
||||
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;
|
||||
|
||||
/* Reference Q.952 Section 4.1.2 for ie */
|
||||
call->redirecting_number_in_message = 1;
|
||||
call->redirecting.from.number.valid = 1;
|
||||
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;
|
||||
|
||||
/* Reference Q.952 Section 4.1.3 for ie */
|
||||
call->redirection_number.valid = 1;
|
||||
call->redirection_number.presentation =
|
||||
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;
|
||||
struct q931_party_number number;
|
||||
|
||||
/* Reference Q.931 Section 4.5.10 for ie */
|
||||
q931_party_number_init(&number);
|
||||
number.valid = 1;
|
||||
number.presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||
|
||||
Reference in New Issue
Block a user