Commit path for ROSE-12 and ROSE-13 support (#9076)

git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@413 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
Matthew Fredrickson
2007-05-25 17:36:28 +00:00
parent ec3b7c156e
commit 0a62b72633
4 changed files with 551 additions and 12 deletions

View File

@@ -291,6 +291,8 @@ typedef struct pri_event_answer {
typedef struct pri_event_facname {
int e;
int callingpres; /* Presentation of Calling CallerID */
int callingplan; /* Dialing plan of Calling entity */
char callingname[256];
char callingnum[256];
int channel;

View File

@@ -167,9 +167,18 @@ static unsigned char get_invokeid(struct pri *pri)
struct addressingdataelements_presentednumberunscreened {
char partyaddress[21];
char partysubaddress[21];
int npi;
int ton;
int pres;
int npi; /* Numbering Plan Indicator */
int ton; /* Type Of Number */
int pres; /* Presentation */
};
struct addressingdataelements_presentednumberscreened {
char partyaddress[21];
char partysubaddress[21];
int npi; /* Numbering Plan Indicator */
int ton; /* Type Of Number */
int pres; /* Presentation */
int scrind; /* Screening Indicator */
};
#define PRI_CHECKOVERFLOW(size) \
@@ -453,6 +462,35 @@ static int rose_public_party_number_decode(struct pri *pri, q931_call *call, uns
return -1;
}
static int rose_private_party_number_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value)
{
int i = 0;
struct rose_component *comp = NULL;
unsigned char *vdata = data;
int ton;
int res = 0;
if (len < 2)
return -1;
do {
GET_COMPONENT(comp, i, vdata, len);
CHECK_COMPONENT(comp, ASN1_ENUMERATED, "Don't know what to do with PrivatePartyNumber ROSE component type 0x%x\n");
ASN1_GET_INTEGER(comp, ton);
NEXT_COMPONENT(comp, i);
ton = typeofnumber_for_q931(pri, ton);
res = rose_number_digits_decode(pri, call, &vdata[i], len-i, value);
if (res < 0)
return -1;
value->ton = ton;
return res + 3;
} while(0);
return -1;
}
static int rose_address_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value)
{
int i = 0;
@@ -503,9 +541,11 @@ static int rose_address_decode(struct pri *pri, q931_call *call, unsigned char *
pri_message(pri, "!! telexPartyNumber isn't handled\n");
return -1;
case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_5): /* [5] priavePartyNumber */
pri_message(pri, "!! privatePartyNumber isn't handled\n");
value->npi = PRI_NPI_PRIVATE;
res = rose_private_party_number_decode(pri, call, comp->data, comp->len, value);
if (res < 0)
return -1;
value->npi = PRI_NPI_PRIVATE;
break;
case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_8): /* [8] nationalStandardPartyNumber */
res = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
if (res < 0)
@@ -589,6 +629,8 @@ static int rose_diverting_leg_information2_decode(struct pri *pri, q931_call *ca
struct rose_component *comp = NULL;
unsigned char *vdata = sequence->data;
int res = 0;
memset(&divertingnr, 0, sizeof(divertingnr));
memset(&originalcallednr, 0, sizeof(originalcallednr));
/* Data checks */
if (sequence->type != (ASN1_CONSTRUCTOR | ASN1_SEQUENCE)) { /* Constructed Sequence */
@@ -670,6 +712,9 @@ static int rose_diverting_leg_information2_decode(struct pri *pri, q931_call *ca
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " Received Originally Called Name '%s'\n", origcalledname);
break;
case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_5):
pri_message(pri, "!! Ignoring DivertingLegInformation2 component 0x%X\n", comp->type);
break;
default:
if (comp->type == 0 && comp->len == 0) {
break; /* Found termination characters */
@@ -684,11 +729,13 @@ static int rose_diverting_leg_information2_decode(struct pri *pri, q931_call *ca
call->redirectingpres = divertingnr.pres;
call->redirectingreason = diversion_reason;
libpri_copy_string(call->redirectingnum, divertingnr.partyaddress, sizeof(call->redirectingnum));
pri_message(pri, " Received redirectingnum '%s' (%d)\n", call->redirectingnum, (int)call->redirectingnum[0]);
}
if (originalcallednr.pres >= 0) {
call->origcalledplan = originalcallednr.npi;
call->origcalledpres = originalcallednr.pres;
libpri_copy_string(call->origcallednum, originalcallednr.partyaddress, sizeof(call->origcallednum));
pri_message(pri, " Received origcallednum '%s' (%d)\n", call->origcallednum, (int)call->origcallednum[0]);
}
libpri_copy_string(call->redirectingname, redirectingname, sizeof(call->redirectingname));
libpri_copy_string(call->origcalledname, origcalledname, sizeof(call->origcalledname));
@@ -1348,6 +1395,432 @@ static int aoc_aoce_charging_unit_encode(struct pri *pri, q931_call *c, long cha
}
/* End AOC */
/* ===== Call Transfer Supplementary Service (ECMA-178) ===== */
static int rose_party_number_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value)
{
int i = 0;
int size = 0;
struct rose_component *comp = NULL;
unsigned char *vdata = data;
do {
GET_COMPONENT(comp, i, vdata, len);
switch(comp->type) {
case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0): /* [0] IMPLICIT NumberDigits -- default: unknownPartyNumber */
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " PartyNumber: UnknownPartyNumber len=%d\n", len);
size = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
if (size < 0)
return -1;
value->npi = PRI_NPI_UNKNOWN;
value->ton = PRI_TON_UNKNOWN;
break;
case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1): /* [1] IMPLICIT PublicPartyNumber */
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " PartyNumber: PublicPartyNumber len=%d\n", len);
size = rose_public_party_number_decode(pri, call, comp->data, comp->len, value);
if (size < 0)
return -1;
value->npi = PRI_NPI_E163_E164;
break;
case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3): /* [3] IMPLICIT NumberDigits -- not used: dataPartyNumber */
pri_message(pri, "!! PartyNumber: dataPartyNumber is reserved!\n");
size = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
if (size < 0)
return -1;
value->npi = PRI_NPI_X121 /* ??? */;
value->ton = PRI_TON_UNKNOWN /* ??? */;
break;
case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_4): /* [4] IMPLICIT NumberDigits -- not used: telexPartyNumber */
pri_message(pri, "!! PartyNumber: telexPartyNumber is reserved!\n");
size = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
if (size < 0)
return -1;
value->npi = PRI_NPI_F69 /* ??? */;
value->ton = PRI_TON_UNKNOWN /* ??? */;
break;
case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_5): /* [5] IMPLICIT PrivatePartyNumber */
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " PartyNumber: PrivatePartyNumber len=%d\n", len);
size = rose_private_party_number_decode(pri, call, comp->data, comp->len, value);
if (size < 0)
return -1;
value->npi = PRI_NPI_PRIVATE;
break;
case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_8): /* [8] IMPLICIT NumberDigits -- not used: nationalStandatdPartyNumber */
pri_message(pri, "!! PartyNumber: nationalStandardPartyNumber is reserved!\n");
size = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
if (size < 0)
return -1;
value->npi = PRI_NPI_NATIONAL;
value->ton = PRI_TON_NATIONAL;
break;
default:
pri_message(pri, "Invalid PartyNumber component 0x%X\n", comp->type);
return -1;
}
ASN1_FIXUP_LEN(comp, size);
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " PartyNumber: '%s' size=%d len=%d\n", value->partyaddress, size, len);
return size;
}
while (0);
return -1;
}
static int rose_number_screened_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberscreened *value)
{
int i = 0;
int size = 0;
struct rose_component *comp = NULL;
unsigned char *vdata = data;
int scrind = -1;
do {
/* Party Number */
GET_COMPONENT(comp, i, vdata, len);
size = rose_party_number_decode(pri, call, (u_int8_t *)comp, comp->len + 2, (struct addressingdataelements_presentednumberunscreened*) value);
if (size < 0)
return -1;
comp->len = size;
NEXT_COMPONENT(comp, i);
/* Screening Indicator */
GET_COMPONENT(comp, i, vdata, len);
CHECK_COMPONENT(comp, ASN1_ENUMERATED, "Don't know what to do with NumberScreened ROSE component type 0x%x\n");
ASN1_GET_INTEGER(comp, scrind);
// Todo: scrind = screeningindicator_for_q931(pri, scrind);
NEXT_COMPONENT(comp, i);
value->scrind = scrind;
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " NumberScreened: '%s' ScreeningIndicator=%d i=%d len=%d\n", value->partyaddress, scrind, i, len);
return i-2; // We do not have a sequence header here.
}
while (0);
return -1;
}
static int rose_presented_number_screened_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberscreened *value)
{
int i = 0;
int size = 0;
struct rose_component *comp = NULL;
unsigned char *vdata = data;
/* Fill in default values */
value->ton = PRI_TON_UNKNOWN;
value->npi = PRI_NPI_UNKNOWN;
value->pres = -1; /* Data is not available */
do {
GET_COMPONENT(comp, i, vdata, len);
switch(comp->type) {
case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0): /* [0] IMPLICIT presentationAllowedNumber */
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " PresentedNumberScreened: presentationAllowedNumber comp->len=%d\n", comp->len);
value->pres = PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
size = rose_number_screened_decode(pri, call, comp->data, comp->len, value);
if (size < 0)
return -1;
ASN1_FIXUP_LEN(comp, size);
return size + 2;
case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1): /* [1] IMPLICIT presentationRestricted */
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " PresentedNumberScreened: presentationRestricted comp->len=%d\n", comp->len);
if (comp->len != 0) { /* must be NULL */
pri_error(pri, "!! Invalid PresentationRestricted component received (len != 0)\n");
return -1;
}
value->pres = PRES_PROHIB_USER_NUMBER_PASSED_SCREEN;
return 2;
case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2): /* [2] IMPLICIT numberNotAvailableDueToInterworking */
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " PresentedNumberScreened: NumberNotAvailableDueToInterworking comp->len=%d\n", comp->len);
if (comp->len != 0) { /* must be NULL */
pri_error(pri, "!! Invalid NumberNotAvailableDueToInterworking component received (len != 0)\n");
return -1;
}
value->pres = PRES_NUMBER_NOT_AVAILABLE;
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " PresentedNumberScreened: numberNotAvailableDueToInterworking Type=0x%X i=%d len=%d size=%d\n", comp->type, i, len);
return 2;
case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3): /* [3] IMPLICIT presentationRestrictedNumber */
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " PresentedNumberScreened: presentationRestrictedNumber comp->len=%d\n", comp->len);
value->pres = PRES_PROHIB_USER_NUMBER_PASSED_SCREEN;
size = rose_number_screened_decode(pri, call, comp->data, comp->len, value);
if (size < 0)
return -1;
ASN1_FIXUP_LEN(comp, size);
return size + 2;
default:
pri_message(pri, "Invalid PresentedNumberScreened component 0x%X\n", comp->type);
}
return -1;
}
while (0);
return -1;
}
static int rose_call_transfer_complete_decode(struct pri *pri, q931_call *call, struct rose_component *sequence, int len)
{
int i = 0;
struct rose_component *comp = NULL;
unsigned char *vdata = sequence->data;
int res = 0;
int end_designation = 0;
struct addressingdataelements_presentednumberscreened redirection_number;
char redirection_name[50] = "";
int call_status = 0;
redirection_number.partyaddress[0] = 0;
redirection_number.partysubaddress[0] = 0;
call->callername[0] = 0;
call->callernum[0] = 0;
/* Data checks */
if (sequence->type != (ASN1_CONSTRUCTOR | ASN1_SEQUENCE)) { /* Constructed Sequence */
pri_message(pri, "Invalid callTransferComplete argument. (Not a sequence)\n");
return -1;
}
if (sequence->len == ASN1_LEN_INDEF) {
len -= 4; /* For the 2 extra characters at the end
* and two characters of header */
} else
len -= 2;
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " CT-Complete: len=%d\n", len);
do {
/* End Designation */
GET_COMPONENT(comp, i, vdata, len);
CHECK_COMPONENT(comp, ASN1_ENUMERATED, "Invalid endDesignation type 0x%X of ROSE callTransferComplete component received\n");
ASN1_GET_INTEGER(comp, end_designation);
NEXT_COMPONENT(comp, i);
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " CT-Complete: Received endDesignation=%d\n", end_designation);
/* Redirection Number */
GET_COMPONENT(comp, i, vdata, len);
res = rose_presented_number_screened_decode(pri, call, (u_int8_t *)comp, comp->len + 2, &redirection_number);
if (res < 0)
return -1;
comp->len = res;
if (res > 2) {
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " CT-Complete: Received redirectionNumber=%s\n", redirection_number.partyaddress);
strncpy(call->callernum, redirection_number.partyaddress, 20);
call->callernum[20] = 0;
}
NEXT_COMPONENT(comp, i);
#if 0 /* This one is optional. How do we check if it is there? */
/* Basic Call Info Elements */
GET_COMPONENT(comp, i, vdata, len);
NEXT_COMPONENT(comp, i);
#endif
/* Redirection Name */
GET_COMPONENT(comp, i, vdata, len);
res = asn1_name_decode((u_int8_t *)comp, comp->len + 2, redirection_name, sizeof(redirection_name));
if (res < 0)
return -1;
memcpy(call->callername, comp->data, comp->len);
call->callername[comp->len] = 0;
ASN1_FIXUP_LEN(comp, res);
comp->len = res;
NEXT_COMPONENT(comp, i);
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " CT-Complete: Received redirectionName '%s'\n", redirection_name);
/* Call Status */
GET_COMPONENT(comp, i, vdata, len);
CHECK_COMPONENT(comp, ASN1_ENUMERATED, "Invalid callStatus type 0x%X of ROSE callTransferComplete component received\n");
ASN1_GET_INTEGER(comp, call_status);
NEXT_COMPONENT(comp, i);
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " CT-Complete: Received callStatus=%d\n", call_status);
/* Argument Extension */
#if 0 /* Not supported */
GET_COMPONENT(comp, i, vdata, len);
switch (comp->type) {
case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_9): /* [9] IMPLICIT Extension */
res = rose_extension_decode(pri, call, comp->data, comp->len, &redirection_number);
if (res < 0)
return -1;
ASN1_FIXUP_LEN(comp, res);
comp->len = res;
case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_10): /* [10] IMPLICIT SEQUENCE OF Extension */
res = rose_sequence_of_extension_decode(pri, call, comp->data, comp->len, &redirection_number);
if (res < 0)
return -1;
ASN1_FIXUP_LEN(comp, res);
comp->len = res;
default:
pri_message(pri, " CT-Complete: !! Unknown argumentExtension received 0x%X\n", comp->type);
return -1;
}
#else
GET_COMPONENT(comp, i, vdata, len);
ASN1_FIXUP_LEN(comp, res);
NEXT_COMPONENT(comp, i);
#endif
if(i < len)
pri_message(pri, " CT-Complete: !! not all information is handled !! i=%d / len=%d\n", i, len);
return 0;
}
while (0);
return -1;
}
static int rose_call_transfer_update_decode(struct pri *pri, q931_call *call, struct rose_component *sequence, int len)
{
int i = 0;
struct rose_component *comp = NULL;
unsigned char *vdata = sequence->data;
int res = 0;
struct addressingdataelements_presentednumberscreened redirection_number;
redirection_number.partyaddress[0] = 0;
redirection_number.partysubaddress[0] = 0;
char redirection_name[50] = "";
call->callername[0] = 0;
call->callernum[0] = 0;
/* Data checks */
if (sequence->type != (ASN1_CONSTRUCTOR | ASN1_SEQUENCE)) { /* Constructed Sequence */
pri_message(pri, "Invalid callTransferComplete argument. (Not a sequence)\n");
return -1;
}
if (sequence->len == ASN1_LEN_INDEF) {
len -= 4; /* For the 2 extra characters at the end
* and two characters of header */
} else
len -= 2;
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " CT-Complete: len=%d\n", len);
do {
/* Redirection Number */
GET_COMPONENT(comp, i, vdata, len);
res = rose_presented_number_screened_decode(pri, call, (u_int8_t *)comp, comp->len + 2, &redirection_number);
if (res < 0)
return -1;
comp->len = res;
if (res > 2) {
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " CT-Complete: Received redirectionNumber=%s\n", redirection_number.partyaddress);
strncpy(call->callernum, redirection_number.partyaddress, 20);
call->callernum[20] = 0;
}
NEXT_COMPONENT(comp, i);
/* Redirection Name */
GET_COMPONENT(comp, i, vdata, len);
res = asn1_name_decode((u_int8_t *)comp, comp->len + 2, redirection_name, sizeof(redirection_name));
if (res < 0)
return -1;
memcpy(call->callername, comp->data, comp->len);
call->callername[comp->len] = 0;
ASN1_FIXUP_LEN(comp, res);
comp->len = res;
NEXT_COMPONENT(comp, i);
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " CT-Complete: Received redirectionName '%s'\n", redirection_name);
#if 0 /* This one is optional. How do we check if it is there? */
/* Basic Call Info Elements */
GET_COMPONENT(comp, i, vdata, len);
NEXT_COMPONENT(comp, i);
#endif
/* Argument Extension */
#if 0 /* Not supported */
GET_COMPONENT(comp, i, vdata, len);
switch (comp->type) {
case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_9): /* [9] IMPLICIT Extension */
res = rose_extension_decode(pri, call, comp->data, comp->len, &redirection_number);
if (res < 0)
return -1;
ASN1_FIXUP_LEN(comp, res);
comp->len = res;
case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_10): /* [10] IMPLICIT SEQUENCE OF Extension */
res = rose_sequence_of_extension_decode(pri, call, comp->data, comp->len, &redirection_number);
if (res < 0)
return -1;
ASN1_FIXUP_LEN(comp, res);
comp->len = res;
default:
pri_message(pri, " CT-Complete: !! Unknown argumentExtension received 0x%X\n", comp->type);
return -1;
}
#else
GET_COMPONENT(comp, i, vdata, len);
ASN1_FIXUP_LEN(comp, res);
NEXT_COMPONENT(comp, i);
#endif
if(i < len)
pri_message(pri, " CT-Complete: !! not all information is handled !! i=%d / len=%d\n", i, len);
return 0;
}
while (0);
return -1;
}
/* ===== End Call Transfer Supplementary Service (ECMA-178) ===== */
int rose_reject_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
{
int i = 0;
@@ -1595,6 +2068,50 @@ int rose_invoke_decode(struct pri *pri, q931_call *call, unsigned char *data, in
return -1;
}
break;
case ROSE_CALL_TRANSFER_IDENTIFY:
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, "ROSE %i: CallTransferIdentify - not handled!\n", operation_tag);
dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
return -1;
case ROSE_CALL_TRANSFER_ABANDON:
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, "ROSE %i: CallTransferAbandon - not handled!\n", operation_tag);
dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
return -1;
case ROSE_CALL_TRANSFER_INITIATE:
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, "ROSE %i: CallTransferInitiate - not handled!\n", operation_tag);
dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
return -1;
case ROSE_CALL_TRANSFER_SETUP:
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, "ROSE %i: CallTransferSetup - not handled!\n", operation_tag);
dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
return -1;
case ROSE_CALL_TRANSFER_ACTIVE:
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, "ROSE %i: CallTransferActive - not handled!\n", operation_tag);
dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
return -1;
case ROSE_CALL_TRANSFER_COMPLETE:
if (pri->debug & PRI_DEBUG_APDU)
{
pri_message(pri, "ROSE %i: Handle CallTransferComplete\n", operation_tag);
dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
}
return rose_call_transfer_complete_decode(pri, call, comp, len-i);
case ROSE_CALL_TRANSFER_UPDATE:
if (pri->debug & PRI_DEBUG_APDU)
{
pri_message(pri, "ROSE %i: Handle CallTransferUpdate\n", operation_tag);
dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
}
return rose_call_transfer_update_decode(pri, call, comp, len-i);
case ROSE_SUBADDRESS_TRANSFER:
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, "ROSE %i: SubaddressTransfer - not handled!\n", operation_tag);
dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
return -1;
case ROSE_DIVERTING_LEG_INFORMATION2:
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " Handle DivertingLegInformation2\n");

View File

@@ -32,6 +32,15 @@
#define COMP_TYPE_NFE 0xAA
/* Operation ID values */
/* Q.952.7 (ECMA-178) ROSE operations (Transfer) */
#define ROSE_CALL_TRANSFER_IDENTIFY 7
#define ROSE_CALL_TRANSFER_ABANDON 8
#define ROSE_CALL_TRANSFER_INITIATE 9
#define ROSE_CALL_TRANSFER_SETUP 10
#define ROSE_CALL_TRANSFER_ACTIVE 11
#define ROSE_CALL_TRANSFER_COMPLETE 12
#define ROSE_CALL_TRANSFER_UPDATE 13
#define ROSE_SUBADDRESS_TRANSFER 14
/* Q.952 ROSE operations (Diverting) */
#define ROSE_DIVERTING_LEG_INFORMATION1 18
#define ROSE_DIVERTING_LEG_INFORMATION2 0x15
@@ -146,7 +155,8 @@ struct rose_component {
u_int8_t data[0];
};
#define GET_COMPONENT(component, idx, ptr, length) \
#if 1
#define GET_COMPONENT(component, idx, ptr, length) \
if ((idx)+2 > (length)) \
break; \
(component) = (struct rose_component*)&((ptr)[idx]); \
@@ -154,16 +164,24 @@ struct rose_component {
if ((component)->len != ASN1_LEN_INDEF) \
pri_message(pri, "Length (%d) of 0x%X component is too long\n", (component)->len, (component)->type); \
}
/*
pri_message("XX Got component %d (0x%02X), length %d\n", (component)->type, (component)->type, (component)->len); \
#else /* Debugging */
#define GET_COMPONENT(component, idx, ptr, length) \
if ((idx)+2 > (length)) \
break; \
(component) = (struct rose_component*)&((ptr)[idx]); \
if ((idx)+(component)->len+2 > (length)) { \
if ((component)->len != 128) \
pri_message(pri, "Length (%d) of 0x%X component is too long\n", (component)->len, (component)->type); \
} \
pri_message(pri, "XX %s:%d Got component %d (0x%02X), length %d\n", __FUNCTION__, __LINE__, (component)->type, (component)->type, (component)->len); \
if ((component)->len > 0) { \
int zzz; \
pri_message("XX Data:"); \
pri_message(pri, "XX Data:"); \
for (zzz = 0; zzz < (component)->len; ++zzz) \
pri_message(" %02X", (component)->data[zzz]); \
pri_message("\n"); \
pri_message(pri, " %02X", (component)->data[zzz]); \
pri_message(pri, "\n"); \
}
*/
#endif
#define NEXT_COMPONENT(component, idx) \
(idx) += (component)->len + 2

2
q931.c
View File

@@ -3383,6 +3383,8 @@ int q931_receive(struct pri *pri, q931_h *h, int len)
libpri_copy_string(pri->ev.facname.callingname, c->callername, sizeof(pri->ev.facname.callingname));
libpri_copy_string(pri->ev.facname.callingnum, c->callernum, sizeof(pri->ev.facname.callingnum));
pri->ev.facname.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
pri->ev.facname.callingpres = c->callerpres;
pri->ev.facname.callingplan = c->callerplan;
pri->ev.facname.cref = c->cr;
pri->ev.facname.call = c;
#if 0