Lots of changes for APDU handling and debugging. Thanks PCadach (bug #5265)!
git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@286 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
parent
9e03b9b8c7
commit
8fa183a4bc
181
pri_facility.c
181
pri_facility.c
@ -32,6 +32,132 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
static char *asn1id2text(int id)
|
||||
{
|
||||
static char data[32];
|
||||
static char *strings[] = {
|
||||
"none",
|
||||
"Boolean",
|
||||
"Integer",
|
||||
"Bit String",
|
||||
"Octet String",
|
||||
"NULL",
|
||||
"Object Identifier",
|
||||
"Object Descriptor",
|
||||
"External Reference",
|
||||
"Real Number",
|
||||
"Enumerated",
|
||||
"Embedded PDV",
|
||||
"UTF-8 String",
|
||||
"Relative Object ID",
|
||||
"Reserved (0e)",
|
||||
"Reserved (0f)",
|
||||
"Sequence",
|
||||
"Set",
|
||||
"Numeric String",
|
||||
"Printable String",
|
||||
"Tele-Text String",
|
||||
"IA-5 String",
|
||||
"UTC Time",
|
||||
"Generalized Time",
|
||||
};
|
||||
if (id > 0 && id <= 0x18) {
|
||||
return strings[id];
|
||||
} else {
|
||||
sprintf(data, "Unknown (%02x)", id);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
static int asn1_dumprecursive(struct pri *pri, void *comp_ptr, int len, int level)
|
||||
{
|
||||
unsigned char *vdata = (unsigned char *)comp_ptr;
|
||||
struct rose_component *comp;
|
||||
int i = 0;
|
||||
int j, k, l;
|
||||
int clen = 0;
|
||||
|
||||
while (len > 0) {
|
||||
GET_COMPONENT(comp, i, vdata, len);
|
||||
pri_message(pri, "%*s%02X %04X", 2 * level, "", comp->type, comp->len);
|
||||
if ((comp->type == 0) && (comp->len == 0))
|
||||
return clen + 2;
|
||||
if ((comp->type & ASN1_PC_MASK) == ASN1_PRIMITIVE) {
|
||||
for (j = 0; j < comp->len; ++j)
|
||||
pri_message(pri, " %02X", comp->data[j]);
|
||||
}
|
||||
if ((comp->type & ASN1_CLAN_MASK) == ASN1_UNIVERSAL) {
|
||||
switch (comp->type & ASN1_TYPE_MASK) {
|
||||
case 0:
|
||||
pri_message(pri, " (none)");
|
||||
break;
|
||||
case ASN1_BOOLEAN:
|
||||
pri_message(pri, " (BOOLEAN: %d)", comp->data[0]);
|
||||
break;
|
||||
case ASN1_INTEGER:
|
||||
for (k = l = 0; k < comp->len; ++k)
|
||||
l = (l << 8) | comp->data[k];
|
||||
pri_message(pri, " (INTEGER: %d)", l);
|
||||
break;
|
||||
case ASN1_BITSTRING:
|
||||
pri_message(pri, " (BITSTRING:");
|
||||
for (k = 0; k < comp->len; ++k)
|
||||
pri_message(pri, " %02x", comp->data[k]);
|
||||
pri_message(pri, ")");
|
||||
break;
|
||||
case ASN1_OCTETSTRING:
|
||||
pri_message(pri, " (OCTETSTRING:");
|
||||
for (k = 0; k < comp->len; ++k)
|
||||
pri_message(pri, " %02x", comp->data[k]);
|
||||
pri_message(pri, ")");
|
||||
break;
|
||||
case ASN1_NULL:
|
||||
pri_message(pri, " (NULL)");
|
||||
break;
|
||||
case ASN1_OBJECTIDENTIFIER:
|
||||
pri_message(pri, " (OBJECTIDENTIFIER:");
|
||||
for (k = 0; k < comp->len; ++k)
|
||||
pri_message(pri, " %02x", comp->data[k]);
|
||||
pri_message(pri, ")");
|
||||
break;
|
||||
case ASN1_ENUMERATED:
|
||||
for (k = l = 0; k < comp->len; ++k)
|
||||
l = (l << 8) | comp->data[k];
|
||||
pri_message(pri, " (ENUMERATED: %d)", l);
|
||||
break;
|
||||
case ASN1_SEQUENCE:
|
||||
pri_message(pri, " (SEQUENCE)");
|
||||
break;
|
||||
default:
|
||||
pri_message(pri, " (component %02x - %s)", comp->type, asn1id2text(comp->type & ASN1_TYPE_MASK));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((comp->type & ASN1_CLAN_MASK) == ASN1_CONTEXT_SPECIFIC) {
|
||||
pri_message(pri, " (CONTEXT SPECIFIC [%d])", comp->type & ASN1_TYPE_MASK);
|
||||
}
|
||||
else {
|
||||
pri_message(pri, " (component %02x)", comp->type);
|
||||
}
|
||||
pri_message(pri, "\n");
|
||||
if ((comp->type & ASN1_PC_MASK) == ASN1_CONSTRUCTOR)
|
||||
j = asn1_dumprecursive(pri, comp->data, (comp->len ? comp->len : INT_MAX), level+1);
|
||||
else
|
||||
j = comp->len;
|
||||
j += 2;
|
||||
len -= j;
|
||||
vdata += j;
|
||||
clen += j;
|
||||
}
|
||||
return clen;
|
||||
}
|
||||
|
||||
int asn1_dump(struct pri *pri, void *comp, int len)
|
||||
{
|
||||
return asn1_dumprecursive(pri, comp, len, 0);
|
||||
}
|
||||
|
||||
static unsigned char get_invokeid(struct pri *pri)
|
||||
{
|
||||
@ -46,28 +172,44 @@ struct addressingdataelements_presentednumberunscreened {
|
||||
int pres;
|
||||
};
|
||||
|
||||
#define PRI_CHECKOVERFLOW(size) \
|
||||
if (msgptr - message + (size) >= sizeof(message)) { \
|
||||
*msgptr = '\0'; \
|
||||
pri_message(pri, "%s", message); \
|
||||
msgptr = message; \
|
||||
}
|
||||
|
||||
static void dump_apdu(struct pri *pri, unsigned char *c, int len)
|
||||
{
|
||||
#define MAX_APDU_LENGTH 255
|
||||
static char hexs[16] = "0123456789ABCDEF";
|
||||
int i;
|
||||
char message[(2 + MAX_APDU_LENGTH * 3 + 6 + MAX_APDU_LENGTH + 3)] = ""; /* please adjust here, if you make changes below! */
|
||||
char *msgptr;
|
||||
|
||||
if (len > MAX_APDU_LENGTH)
|
||||
return;
|
||||
|
||||
snprintf(message, sizeof(message)-1, " [");
|
||||
for (i=0; i<len; i++)
|
||||
snprintf((char *)(message+strlen(message)), sizeof(message)-strlen(message)-1, " %02x", c[i]);
|
||||
snprintf((char *)(message+strlen(message)), sizeof(message)-strlen(message)-1, " ] - [");
|
||||
msgptr = message;
|
||||
*msgptr++ = ' ';
|
||||
*msgptr++ = '[';
|
||||
for (i=0; i<len; i++) {
|
||||
if (c[i] < 20 || c[i] >= 128)
|
||||
snprintf((char *)(message+strlen(message)), sizeof(message)-strlen(message)-1, "°");
|
||||
else
|
||||
snprintf((char *)(message+strlen(message)), sizeof(message)-strlen(message)-1, "%c", c[i]);
|
||||
PRI_CHECKOVERFLOW(3);
|
||||
*msgptr++ = ' ';
|
||||
*msgptr++ = hexs[(c[i] >> 4) & 0x0f];
|
||||
*msgptr++ = hexs[(c[i]) & 0x0f];
|
||||
}
|
||||
snprintf((char *)(message+strlen(message)), sizeof(message)-strlen(message)-1, "]\n");
|
||||
pri_message(pri, message);
|
||||
PRI_CHECKOVERFLOW(6);
|
||||
strcpy(msgptr, " ] - [");
|
||||
msgptr += strlen(msgptr);
|
||||
for (i=0; i<len; i++) {
|
||||
PRI_CHECKOVERFLOW(1);
|
||||
*msgptr++ = ((c[i] < ' ') || (c[i] > '~')) ? '.' : c[i];
|
||||
}
|
||||
PRI_CHECKOVERFLOW(2);
|
||||
*msgptr++ = ']';
|
||||
*msgptr++ = '\n';
|
||||
*msgptr = '\0';
|
||||
pri_message(pri, "%s", message);
|
||||
}
|
||||
#undef PRI_CHECKOVERFLOW
|
||||
|
||||
int redirectingreason_from_q931(struct pri *pri, int redirectingreason)
|
||||
{
|
||||
@ -564,9 +706,11 @@ static int rose_diverting_leg_information2_encode(struct pri *pri, q931_call *ca
|
||||
unsigned char buffer[256];
|
||||
int len = 253;
|
||||
|
||||
#if 0 /* This is not required by specifications */
|
||||
if (!strlen(call->callername)) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
buffer[i] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_EXTENSIONS);
|
||||
i++;
|
||||
@ -749,7 +893,7 @@ static int add_callername_facility_ies(struct pri *pri, q931_call *c, int cpe)
|
||||
}
|
||||
|
||||
|
||||
/* Now the ADPu that contains the information that needs sent.
|
||||
/* Now the APDU that contains the information that needs sent.
|
||||
* We can reuse the buffer since the queue function doesn't
|
||||
* need it. */
|
||||
|
||||
@ -903,7 +1047,7 @@ extern int eect_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2)
|
||||
|
||||
res = pri_call_apdu_queue(c1, Q931_FACILITY, buffer, i, NULL, NULL);
|
||||
if (res) {
|
||||
pri_message(pri, "Could not queue ADPU in facility message\n");
|
||||
pri_message(pri, "Could not queue APDU in facility message\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1110,7 +1254,7 @@ static int aoc_aoce_charging_unit_encode(struct pri *pri, q931_call *c, long cha
|
||||
/* code below is untested */
|
||||
res = pri_call_apdu_queue(c, Q931_FACILITY, buffer, i, NULL, NULL);
|
||||
if (res) {
|
||||
pri_message(pri, "Could not queue ADPU in facility message\n");
|
||||
pri_message(pri, "Could not queue APDU in facility message\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1305,6 +1449,7 @@ extern int pri_call_add_standard_apdus(struct pri *pri, q931_call *call)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (pri->localtype == PRI_NETWORK) {
|
||||
switch (pri->switchtype) {
|
||||
case PRI_SWITCH_NI2:
|
||||
@ -1324,6 +1469,10 @@ extern int pri_call_add_standard_apdus(struct pri *pri, q931_call *call)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
if (pri->switchtype == PRI_SWITCH_NI2)
|
||||
add_callername_facility_ies(pri, call, (pri->localtype == PRI_CPE));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ struct rose_component {
|
||||
break; \
|
||||
(component) = (struct rose_component*)&((ptr)[idx]); \
|
||||
if ((idx)+(component)->len+2 > (length)) { \
|
||||
if ((component)->len != 128) \
|
||||
if ((component)->len != ASN1_LEN_INDEF) \
|
||||
pri_message(pri, "Length (%d) of 0x%X component is too long\n", (component)->len, (component)->type); \
|
||||
}
|
||||
/*
|
||||
@ -169,6 +169,7 @@ struct rose_component {
|
||||
#define CHECK_COMPONENT(component, comptype, message) \
|
||||
if ((component)->type && ((component)->type & ASN1_TYPE_MASK) != (comptype)) { \
|
||||
pri_message(pri, (message), (component)->type); \
|
||||
asn1_dump(pri, (component), (component)->len+2); \
|
||||
break; \
|
||||
}
|
||||
|
||||
@ -249,7 +250,7 @@ extern int mwi_message_send(struct pri *pri, q931_call *call, struct pri_sr *req
|
||||
/* starts a 2BCT */
|
||||
extern int eect_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
|
||||
|
||||
/* Use this function to queue a facility-IE born ADPU onto a call
|
||||
/* Use this function to queue a facility-IE born APDU onto a call
|
||||
* call is the call to use, messagetype is any one of the Q931 messages,
|
||||
* apdu is the apdu data, apdu_len is the length of the apdu data */
|
||||
extern int pri_call_apdu_queue(q931_call *call, int messagetype, void *apdu, int apdu_len, void (*function)(void *data), void *data);
|
||||
@ -257,7 +258,9 @@ extern int pri_call_apdu_queue(q931_call *call, int messagetype, void *apdu, int
|
||||
/* Used by q931.c to cleanup the apdu queue upon destruction of a call */
|
||||
extern int pri_call_apdu_queue_cleanup(q931_call *call);
|
||||
|
||||
/* Adds the "standard" ADPUs to a call */
|
||||
/* Adds the "standard" APDUs to a call */
|
||||
extern int pri_call_add_standard_apdus(struct pri *pri, q931_call *call);
|
||||
|
||||
int asn1_dump(struct pri *pri, void *comp, int len);
|
||||
|
||||
#endif /* _PRI_FACILITY_H */
|
||||
|
@ -243,6 +243,10 @@ typedef struct q931_ie {
|
||||
/* EuroISDN */
|
||||
#define Q931_SENDING_COMPLETE 0xa1
|
||||
|
||||
|
||||
/* Q.SIG specific */
|
||||
#define QSIG_IE_TRANSIT_COUNT 0x31
|
||||
|
||||
extern int q931_receive(struct pri *pri, q931_h *h, int len);
|
||||
|
||||
extern int q931_alerting(struct pri *pri, q931_call *call, int channel, int info);
|
||||
|
122
q931.c
122
q931.c
@ -1119,22 +1119,21 @@ static FUNC_SEND(transmit_facility)
|
||||
int i = 0;
|
||||
|
||||
for (tmp = call->apdus; tmp; tmp = tmp->next) {
|
||||
if (tmp->message == msgtype)
|
||||
if ((tmp->message == msgtype) && !tmp->sent)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (!tmp) /* No APDU found */
|
||||
return 0;
|
||||
|
||||
if (tmp->apdu_len > 235) { /* TODO: find out how much sapce we can use */
|
||||
pri_message(pri, "Requested ADPU (%d bytes) is too long\n", tmp->apdu_len);
|
||||
|
||||
|
||||
if (tmp->apdu_len > 235) { /* TODO: find out how much space we can use */
|
||||
pri_message(pri, "Requested APDU (%d bytes) is too long\n", tmp->apdu_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(ie->data, tmp->apdu, tmp->apdu_len);
|
||||
memcpy(&ie->data[i], tmp->apdu, tmp->apdu_len);
|
||||
i += tmp->apdu_len;
|
||||
tmp->sent = 1;
|
||||
|
||||
return i + 2;
|
||||
}
|
||||
@ -1434,57 +1433,71 @@ static FUNC_DUMP(dump_display)
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_ie_data(unsigned char *c, int len)
|
||||
#define CHECK_OVERFLOW(limit) \
|
||||
if (tmpptr - tmp + limit >= sizeof(tmp)) { \
|
||||
*tmpptr = '\0'; \
|
||||
pri_message(pri, "%s", tmpptr = tmp); \
|
||||
}
|
||||
|
||||
static void dump_ie_data(struct pri *pri, unsigned char *c, int len)
|
||||
{
|
||||
char tmp[1024] = "";
|
||||
int x=0;
|
||||
static char hexs[16] = "0123456789ABCDEF";
|
||||
char tmp[1024], *tmpptr;
|
||||
int lastascii = 0;
|
||||
while(len) {
|
||||
tmpptr = tmp;
|
||||
for (; len; --len, ++c) {
|
||||
CHECK_OVERFLOW(7);
|
||||
if (isprint(*c)) {
|
||||
if (!lastascii) {
|
||||
if (*tmp) {
|
||||
tmp[x++] = ',';
|
||||
tmp[x++] = ' ';
|
||||
if (tmpptr != tmp) {
|
||||
*tmpptr++ = ',';
|
||||
*tmpptr++ = ' ';
|
||||
}
|
||||
tmp[x++] = '\'';
|
||||
*tmpptr++ = '\'';
|
||||
lastascii = 1;
|
||||
}
|
||||
tmp[x++] = *c;
|
||||
lastascii = 1;
|
||||
*tmpptr++ = *c;
|
||||
} else {
|
||||
if (lastascii) {
|
||||
tmp[x++] = '\'';
|
||||
*tmpptr++ = '\'';
|
||||
lastascii = 0;
|
||||
}
|
||||
if (*tmp) {
|
||||
tmp[x++] = ',';
|
||||
tmp[x++] = ' ';
|
||||
if (tmpptr != tmp) {
|
||||
*tmpptr++ = ',';
|
||||
*tmpptr++ = ' ';
|
||||
}
|
||||
sprintf (tmp + x, "0x%02x", *c);
|
||||
x += 4;
|
||||
lastascii = 0;
|
||||
*tmpptr++ = '0';
|
||||
*tmpptr++ = 'x';
|
||||
*tmpptr++ = hexs[(*c >> 4) & 0x0f];
|
||||
*tmpptr++ = hexs[(*c) & 0x0f];
|
||||
}
|
||||
c++;
|
||||
len--;
|
||||
}
|
||||
if (lastascii)
|
||||
tmp[x++] = '\'';
|
||||
pri_message(NULL, tmp);
|
||||
*tmpptr++ = '\'';
|
||||
*tmpptr = '\0';
|
||||
pri_message(pri, "%s", tmp);
|
||||
}
|
||||
|
||||
static FUNC_DUMP(dump_facility)
|
||||
{
|
||||
pri_message(pri, "%c Facility (len=%2d, codeset=%d) [ ", prefix, len, Q931_IE_CODESET(full_ie));
|
||||
dump_ie_data(ie->data, ie->len);
|
||||
dump_ie_data(pri, ie->data, ie->len);
|
||||
pri_message(NULL, " ]\n");
|
||||
if (ie->len > 1) {
|
||||
pri_message(pri, "PROTOCOL %02X\n", ie->data[0] & ASN1_TYPE_MASK);
|
||||
asn1_dump(pri, &ie->data[1], ie->len - 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static FUNC_DUMP(dump_network_spec_fac)
|
||||
{
|
||||
pri_message(pri, "%c Network-Specific Facilities (len=%2d) [ ", prefix, ie->len);
|
||||
if (ie->data[0] == 0x00) {
|
||||
pri_message(pri, code2str(ie->data[1], facilities, sizeof(facilities) / sizeof(facilities[0])));
|
||||
pri_message(pri, "%s", code2str(ie->data[1], facilities, sizeof(facilities) / sizeof(facilities[0])));
|
||||
}
|
||||
else
|
||||
dump_ie_data(ie->data, ie->len);
|
||||
dump_ie_data(pri, ie->data, ie->len);
|
||||
pri_message(pri, " ]\n");
|
||||
}
|
||||
|
||||
@ -1925,6 +1938,17 @@ static FUNC_DUMP(dump_signal)
|
||||
pri_message(pri, "Signal %s (%d)\n", signal2str(ie->data[0]), ie->data[0]);
|
||||
}
|
||||
|
||||
static FUNC_DUMP(dump_transit_count)
|
||||
{
|
||||
/* Defined in ECMA-225 */
|
||||
pri_message(pri, "%c Transit Count (len=%02d): ", prefix, len);
|
||||
if (len < 3) {
|
||||
pri_message(pri, "Invalid length\n");
|
||||
return;
|
||||
}
|
||||
pri_message(pri, "Count=%d (0x%02x)\n", ie->data[0] & 0x1f, ie->data[0] & 0x1f);
|
||||
}
|
||||
|
||||
|
||||
struct ie ies[] = {
|
||||
/* Codeset 0 - Common */
|
||||
@ -1954,7 +1978,7 @@ struct ie ies[] = {
|
||||
{ 0, Q931_LOW_LAYER_COMPAT, "Low-layer Compatibility" },
|
||||
{ 0, Q931_HIGH_LAYER_COMPAT, "High-layer Compatibility" },
|
||||
{ 1, Q931_PACKET_SIZE, "Packet Size" },
|
||||
{ 1, Q931_IE_FACILITY, "Facility" , dump_facility, receive_facility, transmit_facility },
|
||||
{ 0, Q931_IE_FACILITY, "Facility" , dump_facility, receive_facility, transmit_facility },
|
||||
{ 1, Q931_IE_REDIRECTION_NUMBER, "Redirection Number" },
|
||||
{ 1, Q931_IE_REDIRECTION_SUBADDR, "Redirection Subaddress" },
|
||||
{ 1, Q931_IE_FEATURE_ACTIVATE, "Feature Activation" },
|
||||
@ -1979,6 +2003,8 @@ struct ie ies[] = {
|
||||
{ 1, Q931_IE_USER_USER_FACILITY, "User-User Facility" },
|
||||
{ 1, Q931_IE_UPDATE, "Update" },
|
||||
{ 1, Q931_SENDING_COMPLETE, "Sending Complete", dump_sending_complete, receive_sending_complete, transmit_sending_complete },
|
||||
/* Codeset 4 - Q.SIG specific */
|
||||
{ 1, QSIG_IE_TRANSIT_COUNT | Q931_CODESET(4), "Transit Count", dump_transit_count },
|
||||
/* Codeset 6 - Network specific */
|
||||
{ 1, Q931_IE_ORIGINATING_LINE_INFO, "Originating Line Information", dump_line_information, receive_line_information, transmit_line_information },
|
||||
{ 1, Q931_IE_FACILITY | Q931_CODESET(6), "Facility", dump_facility, receive_facility, transmit_facility },
|
||||
@ -2090,14 +2116,14 @@ static inline void q931_dumpie(struct pri *pri, int codeset, q931_ie *ie, char p
|
||||
int full_ie = Q931_FULL_IE(codeset, ie->ie);
|
||||
int base_ie;
|
||||
|
||||
pri_message(NULL, "%c [", prefix);
|
||||
pri_message(NULL, "%02x", ie->ie);
|
||||
pri_message(pri, "%c [", prefix);
|
||||
pri_message(pri, "%02x", ie->ie);
|
||||
if (!(ie->ie & 0x80)) {
|
||||
pri_message(NULL, " %02x", ielen(ie)-2);
|
||||
pri_message(pri, " %02x", ielen(ie)-2);
|
||||
for (x = 0; x + 2 < ielen(ie); ++x)
|
||||
pri_message(NULL, " %02x", ie->data[x]);
|
||||
pri_message(pri, " %02x", ie->data[x]);
|
||||
}
|
||||
pri_message(NULL, "]\n");
|
||||
pri_message(pri, "]\n");
|
||||
|
||||
/* Special treatment for shifts */
|
||||
if((full_ie & 0xf0) == Q931_LOCKING_SHIFT)
|
||||
@ -2114,7 +2140,7 @@ static inline void q931_dumpie(struct pri *pri, int codeset, q931_ie *ie, char p
|
||||
return;
|
||||
}
|
||||
|
||||
pri_error(pri, "!! %c Unknown IE %d (len = %d)\n", prefix, base_ie, ielen(ie));
|
||||
pri_error(pri, "!! %c Unknown IE %d (cs%d, len = %d)\n", prefix, Q931_IE_IE(base_ie), Q931_IE_CODESET(base_ie), ielen(ie));
|
||||
}
|
||||
|
||||
static q931_call *q931_getcall(struct pri *pri, int cr)
|
||||
@ -2377,7 +2403,6 @@ static int send_message(struct pri *pri, q931_call *c, int msgtype, int ies[])
|
||||
int offset=0;
|
||||
int x;
|
||||
int codeset;
|
||||
struct apdu_event *facevent = c->apdus;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
len = sizeof(buf);
|
||||
@ -2386,24 +2411,7 @@ static int send_message(struct pri *pri, q931_call *c, int msgtype, int ies[])
|
||||
x=0;
|
||||
codeset = 0;
|
||||
while(ies[x] > -1) {
|
||||
if (ies[x] == Q931_IE_FACILITY) {
|
||||
res = 0;
|
||||
while (facevent) {
|
||||
if (!facevent->sent && (facevent->message == msgtype)) {
|
||||
int tmpres;
|
||||
tmpres = add_ie(pri, c, mh->msg, ies[x], (q931_ie *)(mh->data + offset), len, &codeset);
|
||||
if (tmpres < 0) {
|
||||
pri_error(pri, "!! Unable to add IE '%s'\n", ie2str(ies[x]));
|
||||
return -1;
|
||||
}
|
||||
res += tmpres;
|
||||
facevent->sent = 1;
|
||||
}
|
||||
facevent = facevent->next;
|
||||
}
|
||||
} else {
|
||||
res = add_ie(pri, c, mh->msg, ies[x], (q931_ie *)(mh->data + offset), len, &codeset);
|
||||
}
|
||||
res = add_ie(pri, c, mh->msg, ies[x], (q931_ie *)(mh->data + offset), len, &codeset);
|
||||
|
||||
if (res < 0) {
|
||||
pri_error(pri, "!! Unable to add IE '%s'\n", ie2str(ies[x]));
|
||||
|
@ -147,7 +147,7 @@ static void event2(struct pri *pri, pri_event *e)
|
||||
}
|
||||
}
|
||||
|
||||
static void testmsg(char *s)
|
||||
static void testmsg(struct pri *pri, char *s)
|
||||
{
|
||||
char *c;
|
||||
static int keeplast = 0;
|
||||
@ -173,7 +173,7 @@ static void testmsg(char *s)
|
||||
keeplast = 0;
|
||||
}
|
||||
|
||||
static void testerr(char *s)
|
||||
static void testerr(struct pri *pri, char *s)
|
||||
{
|
||||
char *c;
|
||||
static int keeplast = 0;
|
||||
@ -264,6 +264,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
first = pri;
|
||||
pri_set_debug(pri, DEBUG_LEVEL);
|
||||
pri_facility_enable(pri);
|
||||
if (pthread_create(&tmp, NULL, dchan, pri)) {
|
||||
perror("thread(0)");
|
||||
exit(1);
|
||||
@ -273,6 +274,7 @@ int main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
pri_set_debug(pri, DEBUG_LEVEL);
|
||||
pri_facility_enable(pri);
|
||||
if (pthread_create(&tmp, NULL, dchan, pri)) {
|
||||
perror("thread(1)");
|
||||
exit(1);
|
||||
|
Loading…
Reference in New Issue
Block a user