Add support for calling and called subaddress. Partial support for COLP subaddress.

The Telecom Specs in NZ suggests that SUB ADDRESS is always on, so doing
"desk to desk" between offices each with an asterisk box over the ISDN
should then be possible, without a whole load of DDI numbers required.

(closes issue #15604)
Reported by: alecdavis
Patches:
      libpri_subaddr_trunk.diff11.txt uploaded by alecdavis (license 585)
      Some minor modificatons were made.
Tested by: alecdavis, rmudgett

Review:	https://reviewboard.asterisk.org/r/406/


git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@1230 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
Richard Mudgett 2009-10-22 16:16:50 +00:00
parent 6cb01561eb
commit a78ee730c9
5 changed files with 348 additions and 41 deletions

View File

@ -428,7 +428,7 @@ struct pri_party_subaddress {
* \note The null terminator is a convenience only since the data could be
* BCD/binary and thus have a null byte as part of the contents.
*/
char data[32];
unsigned char data[32];
};
/*! \brief Information needed to identify an endpoint in a call. */
@ -598,7 +598,7 @@ typedef struct pri_event_ring {
int layer1; /* User layer 1 */
int complete; /* Have we seen "Complete" i.e. no more number? */
q931_call *call; /* Opaque call pointer */
char callingsubaddr[256]; /* Calling parties subaddress */
char callingsubaddr[256]; /* Calling parties subaddress, backwards compatibility */
int progress;
int progressmask;
char origcalledname[256];
@ -607,6 +607,8 @@ typedef struct pri_event_ring {
int origredirectingreason;
int reversecharge;
struct pri_subcommands *subcmds;
struct pri_party_id calling; /* Calling Party's info, initially subaddress' */
struct pri_party_subaddress called_subaddress; /* Called party's subaddress */
} pri_event_ring;
typedef struct pri_event_hangup {
@ -832,8 +834,8 @@ extern pri_event *pri_schedule_run(struct pri *pri);
extern pri_event *pri_schedule_run_tv(struct pri *pri, const struct timeval *now);
int pri_call(struct pri *pri, q931_call *c, int transmode, int channel,
int exclusive, int nonisdn, char *caller, int callerplan, char *callername, int callerpres,
char *called,int calledplan, int ulayer1);
int exclusive, int nonisdn, char *caller, int callerplan, char *callername, int callerpres,
char *called, int calledplan, int ulayer1);
struct pri_sr *pri_sr_new(void);
void pri_sr_free(struct pri_sr *sr);
@ -854,6 +856,26 @@ void pri_sr_set_caller_party(struct pri_sr *sr, const struct pri_party_id *calle
/*! \note Use pri_sr_set_caller_party() instead to pass more precise caller information. */
int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres);
/*!
* \brief Set the calling subaddress information in the call SETUP record.
*
* \param sr New call SETUP record.
* \param subaddress information to set.
*
* \return Nothing
*/
void pri_sr_set_caller_subaddress(struct pri_sr *sr, const struct pri_party_subaddress *subaddress);
/*!
* \brief Set the called subaddress information in the call SETUP record.
*
* \param sr New call SETUP record.
* \param subaddress information to set.
*
* \return Nothing
*/
void pri_sr_set_called_subaddress(struct pri_sr *sr, const struct pri_party_subaddress *subaddress);
/*!
* \brief Set the redirecting information in the call SETUP record.
*

47
pri.c
View File

@ -616,6 +616,40 @@ static void pri_copy_party_number_to_q931(struct q931_party_number *q931_number,
}
}
/*!
* \internal
* \brief Copy the PRI party subaddress to the Q.931 party subaddress structure.
*
* \param q931_subaddress Q.931 party subaddress structure
* \param pri_subaddress PRI party subaddress structure
*
* \return Nothing
*/
static void pri_copy_party_subaddress_to_q931(struct q931_party_subaddress *q931_subaddress, const struct pri_party_subaddress *pri_subaddress)
{
int length;
int maxlen = sizeof(q931_subaddress->data) - 1;
q931_party_subaddress_init(q931_subaddress);
if (!pri_subaddress->valid) {
return;
}
q931_subaddress->valid = 1;
q931_subaddress->type = pri_subaddress->type;
length = pri_subaddress->length;
if (length > maxlen){
length = maxlen;
} else {
q931_subaddress->odd_even_indicator = pri_subaddress->odd_even_indicator;
}
q931_subaddress->length = length;
memcpy(q931_subaddress->data, pri_subaddress->data, length);
q931_subaddress->data[length] = '\0';
}
/*!
* \internal
* \brief Copy the PRI party id to the Q.931 party id structure.
@ -629,6 +663,7 @@ static void pri_copy_party_id_to_q931(struct q931_party_id *q931_id, const struc
{
pri_copy_party_name_to_q931(&q931_id->name, &pri_id->name);
pri_copy_party_number_to_q931(&q931_id->number, &pri_id->number);
pri_copy_party_subaddress_to_q931(&q931_id->subaddress, &pri_id->subaddress);
}
int pri_connected_line_update(struct pri *ctrl, q931_call *call, const struct pri_party_connected_line *connected)
@ -974,7 +1009,7 @@ int pri_setup(struct pri *pri, q931_call *c, struct pri_sr *req)
int pri_call(struct pri *pri, q931_call *c, int transmode, int channel, int exclusive,
int nonisdn, char *caller, int callerplan, char *callername, int callerpres, char *called,
int calledplan,int ulayer1)
int calledplan, int ulayer1)
{
struct pri_sr req;
if (!pri || !c)
@ -1206,6 +1241,11 @@ int pri_sr_set_called(struct pri_sr *sr, char *called, int calledplan, int numco
return 0;
}
void pri_sr_set_called_subaddress(struct pri_sr *sr, const struct pri_party_subaddress *subaddress)
{
pri_copy_party_subaddress_to_q931(&sr->called.subaddress, subaddress);
}
int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres)
{
q931_party_id_init(&sr->caller);
@ -1226,6 +1266,11 @@ int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int cal
return 0;
}
void pri_sr_set_caller_subaddress(struct pri_sr *sr, const struct pri_party_subaddress *subaddress)
{
pri_copy_party_subaddress_to_q931(&sr->caller.subaddress, subaddress);
}
void pri_sr_set_caller_party(struct pri_sr *sr, const struct pri_party_id *caller)
{
pri_copy_party_id_to_q931(&sr->caller, caller);

View File

@ -181,7 +181,6 @@ struct q931_party_number {
/*! \brief Maximum subaddress length plus null terminator */
#define PRI_MAX_SUBADDRESS_LEN (20 + 1)
#if defined(POSSIBLE_FUTURE_SUBADDRESS_SUPPORT)
struct q931_party_subaddress {
/*! \brief TRUE if the subaddress information is valid/present */
unsigned char valid;
@ -205,17 +204,14 @@ struct q931_party_subaddress {
* \note The null terminator is a convenience only since the data could be
* BCD/binary and thus have a null byte as part of the contents.
*/
char data[PRI_MAX_SUBADDRESS_LEN];
unsigned char data[PRI_MAX_SUBADDRESS_LEN];
};
#endif /* defined(POSSIBLE_FUTURE_SUBADDRESS_SUPPORT) */
struct q931_party_address {
/*! \brief Subscriber phone number */
struct q931_party_number number;
#if defined(POSSIBLE_FUTURE_SUBADDRESS_SUPPORT)
/*! \brief Subscriber subaddress */
struct q931_party_subaddress subaddress;
#endif /* defined(POSSIBLE_FUTURE_SUBADDRESS_SUPPORT) */
};
/*! \brief Information needed to identify an endpoint in a call. */
@ -224,10 +220,8 @@ struct q931_party_id {
struct q931_party_name name;
/*! \brief Subscriber phone number */
struct q931_party_number number;
#if defined(POSSIBLE_FUTURE_SUBADDRESS_SUPPORT)
/*! \brief Subscriber subaddress */
struct q931_party_subaddress subaddress;
#endif /* defined(POSSIBLE_FUTURE_SUBADDRESS_SUPPORT) */
};
enum Q931_REDIRECTING_STATE {
@ -489,16 +483,19 @@ void __pri_free_tei(struct pri *p);
void q931_party_name_init(struct q931_party_name *name);
void q931_party_number_init(struct q931_party_number *number);
void q931_party_subaddress_init(struct q931_party_subaddress *subaddr);
void q931_party_address_init(struct q931_party_address *address);
void q931_party_id_init(struct q931_party_id *id);
void q931_party_redirecting_init(struct q931_party_redirecting *redirecting);
int q931_party_name_cmp(const struct q931_party_name *left, const struct q931_party_name *right);
int q931_party_number_cmp(const struct q931_party_number *left, const struct q931_party_number *right);
int q931_party_subaddress_cmp(const struct q931_party_subaddress *left, const struct q931_party_subaddress *right);
int q931_party_id_cmp(const struct q931_party_id *left, const struct q931_party_id *right);
void q931_party_name_copy_to_pri(struct pri_party_name *pri_name, const struct q931_party_name *q931_name);
void q931_party_number_copy_to_pri(struct pri_party_number *pri_number, const struct q931_party_number *q931_number);
void q931_party_subaddress_copy_to_pri(struct pri_party_subaddress *pri_subaddress, const struct q931_party_subaddress *q931_subaddress);
void q931_party_id_copy_to_pri(struct pri_party_id *pri_id, const struct q931_party_id *q931_id);
void q931_party_redirecting_copy_to_pri(struct pri_party_redirecting *pri_redirecting, const struct q931_party_redirecting *q931_redirecting);

View File

@ -174,8 +174,9 @@ typedef struct q931_ie {
#define Q931_IE_SEGMENTED_MSG 0x00
#define Q931_IE_CHANGE_STATUS 0x01
#define Q931_IE_ORIGINATING_LINE_INFO (0x01 | Q931_CODESET(6))
#define Q931_IE_CONNECTED_ADDR 0x0C
#define Q931_IE_CONNECTED_NUM 0x4C
#define Q931_IE_CONNECTED_ADDR 0x0c
#define Q931_IE_CONNECTED_NUM 0x4c
#define Q931_IE_CONNECTED_SUBADDR 0x4d
#define Q931_IE_CALL_IDENTITY 0x10
#define Q931_IE_FACILITY 0x1c
#define Q931_IE_ENDPOINT_ID 0x26

296
q931.c
View File

@ -319,6 +319,22 @@ void q931_party_number_init(struct q931_party_number *number)
number->str[0] = '\0';
}
/*!
* \brief Initialize the given struct q931_party_subaddress
*
* \param subaddress Structure to initialize
*
* \return Nothing
*/
void q931_party_subaddress_init(struct q931_party_subaddress *subaddress)
{
subaddress->valid = 0;
subaddress->type = 0;
subaddress->odd_even_indicator = 0;
subaddress->length = 0;
subaddress->data[0] = '\0';
}
/*!
* \brief Initialize the given struct q931_party_address
*
@ -329,6 +345,7 @@ void q931_party_number_init(struct q931_party_number *number)
void q931_party_address_init(struct q931_party_address *address)
{
q931_party_number_init(&address->number);
q931_party_subaddress_init(&address->subaddress);
}
/*!
@ -342,6 +359,7 @@ void q931_party_id_init(struct q931_party_id *id)
{
q931_party_name_init(&id->name);
q931_party_number_init(&id->number);
q931_party_subaddress_init(&id->subaddress);
}
/*!
@ -430,6 +448,45 @@ int q931_party_number_cmp(const struct q931_party_number *left, const struct q93
return cmp;
}
/*!
* \brief Compare the left and right party subaddress.
*
* \param left Left parameter party subaddress.
* \param right Right parameter party subaddress.
*
* \retval < 0 when left < right.
* \retval == 0 when left == right.
* \retval > 0 when left > right.
*/
int q931_party_subaddress_cmp(const struct q931_party_subaddress *left, const struct q931_party_subaddress *right)
{
int cmp;
if (!left->valid) {
if (!right->valid) {
return 0;
}
return -1;
} else if (!right->valid) {
return 1;
}
cmp = left->type - right->type;
if (cmp) {
return cmp;
}
cmp = memcmp(left->data, right->data,
(left->length < right->length) ? left->length : right->length);
if (cmp) {
return cmp;
}
cmp = left->length - right->length;
if (cmp) {
return cmp;
}
cmp = left->odd_even_indicator - right->odd_even_indicator;
return cmp;
}
/*!
* \brief Compare the left and right party id.
*
@ -448,6 +505,10 @@ int q931_party_id_cmp(const struct q931_party_id *left, const struct q931_party_
if (cmp) {
return cmp;
}
cmp = q931_party_subaddress_cmp(&left->subaddress, &right->subaddress);
if (cmp) {
return cmp;
}
cmp = q931_party_name_cmp(&left->name, &right->name);
return cmp;
}
@ -498,6 +559,42 @@ void q931_party_number_copy_to_pri(struct pri_party_number *pri_number, const st
}
}
/*!
* \brief Copy the Q.931 party subaddress to the PRI party subaddress structure.
*
* \param pri_subaddress PRI party subaddress structure
* \param q931_subaddress Q.931 party subaddress structure
*
* \return Nothing
*/
void q931_party_subaddress_copy_to_pri(struct pri_party_subaddress *pri_subaddress, const struct q931_party_subaddress *q931_subaddress)
{
int length;
/*
* The size of pri_subaddress->data[] is not the same as the size of
* q931_subaddress->data[].
*/
if (!q931_subaddress->valid) {
pri_subaddress->valid = 0;
pri_subaddress->type = 0;
pri_subaddress->odd_even_indicator = 0;
pri_subaddress->length = 0;
pri_subaddress->data[0] = '\0';
return;
}
pri_subaddress->valid = 1;
pri_subaddress->type = q931_subaddress->type;
pri_subaddress->odd_even_indicator = q931_subaddress->odd_even_indicator;
length = q931_subaddress->length;
pri_subaddress->length = length;
memcpy(pri_subaddress->data, q931_subaddress->data, length);
pri_subaddress->data[length] = '\0';
}
/*!
* \brief Copy the Q.931 party id to the PRI party id structure.
*
@ -510,6 +607,7 @@ void q931_party_id_copy_to_pri(struct pri_party_id *pri_id, const struct q931_pa
{
q931_party_name_copy_to_pri(&pri_id->name, &q931_id->name);
q931_party_number_copy_to_pri(&pri_id->number, &q931_id->number);
q931_party_subaddress_copy_to_pri(&pri_id->subaddress, &q931_id->subaddress);
}
/*!
@ -1390,6 +1488,93 @@ static void q931_get_number(unsigned char *num, int maxlen, unsigned char *src,
num[len] = 0;
}
static void q931_get_subaddr_specific(unsigned char *num, int maxlen, unsigned char *src, int len, char oddflag)
{
/* User Specified */
int x;
char *ptr = (char *) num;
if (len <= 0) {
num[0] = '\0';
return;
}
if (((len * 2) + 1) > maxlen) {
len = (maxlen / 2) - 1;
}
for (x = 0; x < (len - 1); ++x) {
ptr += sprintf(ptr, "%02x", src[x]);
}
if (oddflag) {
/* ODD */
sprintf(ptr, "%01x", (src[len - 1]) >> 4);
} else {
/* EVEN */
sprintf(ptr, "%02x", src[len - 1]);
}
}
static int transmit_subaddr_helper(int full_ie, struct pri *ctrl, struct q931_party_subaddress *q931_subaddress, int msgtype, q931_ie *ie, int offset, int len, int order)
{
size_t datalen;
if (!q931_subaddress->valid) {
return 0;
}
datalen = q931_subaddress->length;
if (!q931_subaddress->type) {
/* 0 = NSAP */
/* 0 = Odd/Even indicator */
ie->data[0] = 0x80;
} else {
/* 2 = User Specified */
ie->data[0] = q931_subaddress->odd_even_indicator ? 0xA8 : 0xA0;
}
memcpy(ie->data + offset, q931_subaddress->data, datalen);
return datalen + (offset + 2);
}
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)
{
if (len <= 0) {
return -1;
}
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_get_number(q931_subaddress->data, sizeof(q931_subaddress->data),
ie->data + offset, len);
return 0;
}
static void dump_subaddr_helper(int full_ie, struct pri *ctrl, q931_ie *ie, int offset, int len, int datalen, char prefix, const char *named)
{
unsigned char cnum[256];
if (!(ie->data[0] & 0x70)) {
/* NSAP */
q931_get_number(cnum, sizeof(cnum), ie->data + offset, datalen);
} else {
/* User Specified */
q931_get_subaddr_specific(cnum, sizeof(cnum), ie->data + offset, datalen,
ie->data[0] & 0x08);
}
pri_message(ctrl,
"%c %s Sub-Address (len=%2d) [ Ext: %d Type: %s (%d) O: %d '%s' ]\n",
prefix, named, len, ie->data[0] >> 7,
subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
(ie->data[0] & 0x08) >> 3, cnum);
}
static void dump_called_party_number(int full_ie, struct pri *ctrl, q931_ie *ie, int len, char prefix)
{
unsigned char cnum[256];
@ -1401,12 +1586,7 @@ static void dump_called_party_number(int full_ie, struct pri *ctrl, q931_ie *ie,
static void dump_called_party_subaddr(int full_ie, struct pri *ctrl, q931_ie *ie, int len, char prefix)
{
unsigned char cnum[256];
q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
pri_message(ctrl, "%c Called Sub-Address (len=%2d) [ Ext: %d Type: %s (%d) O: %d '%s' ]\n",
prefix, len, ie->data[0] >> 7,
subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
(ie->data[0] & 0x08) >> 3, cnum);
dump_subaddr_helper(full_ie, ctrl, ie, 1 , len, len - 3, prefix, "Called");
}
static void dump_calling_party_number(int full_ie, struct pri *ctrl, q931_ie *ie, int len, char prefix)
@ -1425,12 +1605,7 @@ static void dump_calling_party_number(int full_ie, struct pri *ctrl, q931_ie *ie
static void dump_calling_party_subaddr(int full_ie, struct pri *ctrl, q931_ie *ie, int len, char prefix)
{
unsigned char cnum[256];
q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
pri_message(ctrl, "%c Calling Sub-Address (len=%2d) [ Ext: %d Type: %s (%d) O: %d '%s' ]\n",
prefix, len, ie->data[0] >> 7,
subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
(ie->data[0] & 0x08) >> 3, cnum);
dump_subaddr_helper(full_ie, ctrl, ie, 1 , len, len - 3, prefix, "Calling");
}
static void dump_redirecting_number(int full_ie, struct pri *ctrl, q931_ie *ie, int len, char prefix)
@ -1547,6 +1722,26 @@ static void dump_connected_number(int full_ie, struct pri *ctrl, q931_ie *ie, in
pri_message(ctrl, " '%s' ]\n", cnum);
}
static int receive_connected_subaddr(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len)
{
if (len < 3) {
return -1;
}
return receive_subaddr_helper(full_ie, ctrl, &call->remote_id.subaddress, msgtype, ie,
1, len - 3);
}
static int transmit_connected_subaddr(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len, int order)
{
return transmit_subaddr_helper(full_ie, ctrl, &call->local_id.subaddress, msgtype, ie,
1, len, order);
}
static void dump_connected_subaddr(int full_ie, struct pri *ctrl, q931_ie *ie, int len, char prefix)
{
dump_subaddr_helper(full_ie, ctrl, ie, 1 , len, len - 3, prefix, "Connected");
}
static int receive_redirecting_number(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len)
{
@ -1603,12 +1798,7 @@ static int transmit_redirecting_number(int full_ie, struct pri *ctrl, q931_call
static void dump_redirecting_subaddr(int full_ie, struct pri *ctrl, q931_ie *ie, int len, char prefix)
{
unsigned char cnum[256];
q931_get_number(cnum, sizeof(cnum), ie->data + 2, len - 4);
pri_message(ctrl, "%c Redirecting Sub-Address (len=%2d) [ Ext: %d Type: %s (%d) O: %d '%s' ]\n",
prefix, len, ie->data[0] >> 7,
subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
(ie->data[0] & 0x08) >> 3, cnum);
dump_subaddr_helper(full_ie, ctrl, ie, 2, len, len - 4, prefix, "Redirecting");
}
static int receive_redirection_number(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len)
@ -1656,9 +1846,33 @@ static int transmit_redirection_number(int full_ie, struct pri *ctrl, q931_call
static int receive_calling_party_subaddr(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len)
{
/* copy digits to call->callingsubaddr */
q931_get_number((unsigned char *) call->callingsubaddr, sizeof(call->callingsubaddr), ie->data + 1, len - 3);
return 0;
if (len < 3) {
return -1;
}
return receive_subaddr_helper(full_ie, ctrl, &call->remote_id.subaddress, msgtype, ie,
1, len - 3);
}
static int transmit_calling_party_subaddr(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len, int order)
{
return transmit_subaddr_helper(full_ie, ctrl, &call->local_id.subaddress, msgtype, ie,
1, len, order);
}
static int receive_called_party_subaddr(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len)
{
if (len < 3) {
return -1;
}
return receive_subaddr_helper(full_ie, ctrl, &call->called.subaddress, msgtype, ie, 1,
len - 3);
}
static int transmit_called_party_subaddr(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len, int order)
{
return transmit_subaddr_helper(full_ie, ctrl, &call->called.subaddress, msgtype, ie,
1, len, order);
}
static int receive_called_party_number(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len)
@ -2854,9 +3068,9 @@ static struct ie ies[] = {
{ 1, Q931_CLOSED_USER_GROUP, "Closed User Group" },
{ 1, Q931_REVERSE_CHARGE_INDIC, "Reverse Charging Indication", dump_reverse_charging_indication, receive_reverse_charging_indication, transmit_reverse_charging_indication },
{ 1, Q931_CALLING_PARTY_NUMBER, "Calling Party Number", dump_calling_party_number, receive_calling_party_number, transmit_calling_party_number },
{ 1, Q931_CALLING_PARTY_SUBADDR, "Calling Party Subaddress", dump_calling_party_subaddr, receive_calling_party_subaddr },
{ 1, Q931_CALLING_PARTY_SUBADDR, "Calling Party Subaddress", dump_calling_party_subaddr, receive_calling_party_subaddr, transmit_calling_party_subaddr },
{ 1, Q931_CALLED_PARTY_NUMBER, "Called Party Number", dump_called_party_number, receive_called_party_number, transmit_called_party_number },
{ 1, Q931_CALLED_PARTY_SUBADDR, "Called Party Subaddress", dump_called_party_subaddr },
{ 1, Q931_CALLED_PARTY_SUBADDR, "Called Party Subaddress", dump_called_party_subaddr, receive_called_party_subaddr, transmit_called_party_subaddr },
{ 0, Q931_REDIRECTING_NUMBER, "Redirecting Number", dump_redirecting_number, receive_redirecting_number, transmit_redirecting_number },
{ 1, Q931_REDIRECTING_SUBADDR, "Redirecting Subaddress", dump_redirecting_subaddr },
{ 0, Q931_TRANSIT_NET_SELECT, "Transit Network Selection" },
@ -2885,6 +3099,7 @@ static struct ie ies[] = {
{ 1, Q931_IE_CHANGE_STATUS, "Change Status", dump_change_status, receive_change_status, transmit_change_status },
{ 1, Q931_IE_CONNECTED_ADDR, "Connected Number", dump_connected_number },
{ 1, Q931_IE_CONNECTED_NUM, "Connected Number", dump_connected_number, receive_connected_number, transmit_connected_number },
{ 1, Q931_IE_CONNECTED_SUBADDR, "Connected Subaddress", dump_connected_subaddr, receive_connected_subaddr, transmit_connected_subaddr },
{ 1, Q931_IE_ORIGINAL_CALLED_NUMBER, "Original Called Number", dump_redirecting_number, receive_redirecting_number, transmit_redirecting_number },
{ 1, Q931_IE_USER_USER_FACILITY, "User-User Facility" },
{ 1, Q931_IE_UPDATE, "Update" },
@ -3822,7 +4037,15 @@ static void pri_disconnect_timeout(void *data)
q931_release(ctrl, c, PRI_CAUSE_NORMAL_CLEARING);
}
static int connect_ies[] = { Q931_CHANNEL_IDENT, Q931_IE_FACILITY, Q931_PROGRESS_INDICATOR, Q931_DISPLAY, Q931_IE_CONNECTED_NUM, -1 };
static int connect_ies[] = {
Q931_CHANNEL_IDENT,
Q931_IE_FACILITY,
Q931_PROGRESS_INDICATOR,
Q931_DISPLAY,
Q931_IE_CONNECTED_NUM,
Q931_IE_CONNECTED_SUBADDR,
-1
};
int q931_connect(struct pri *ctrl, q931_call *c, int channel, int nonisdn)
{
@ -3951,7 +4174,9 @@ static int setup_ies[] = {
Q931_DISPLAY,
Q931_REVERSE_CHARGE_INDIC,
Q931_CALLING_PARTY_NUMBER,
Q931_CALLING_PARTY_SUBADDR,
Q931_CALLED_PARTY_NUMBER,
Q931_CALLED_PARTY_SUBADDR,
Q931_REDIRECTING_NUMBER,
Q931_IE_USER_USER,
Q931_SENDING_COMPLETE,
@ -3972,7 +4197,9 @@ static int cis_setup_ies[] = {
Q931_CHANNEL_IDENT,
Q931_IE_FACILITY,
Q931_CALLING_PARTY_NUMBER,
Q931_CALLING_PARTY_SUBADDR,
Q931_CALLED_PARTY_NUMBER,
Q931_CALLED_PARTY_SUBADDR,
Q931_SENDING_COMPLETE,
-1
};
@ -4714,13 +4941,20 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
}
libpri_copy_string(ctrl->ev.ring.callingnum, c->remote_id.number.str, sizeof(ctrl->ev.ring.callingnum));
libpri_copy_string(ctrl->ev.ring.callingname, c->remote_id.name.str, sizeof(ctrl->ev.ring.callingname));
libpri_copy_string(ctrl->ev.ring.callingsubaddr, c->callingsubaddr, sizeof(ctrl->ev.ring.callingsubaddr));
q931_party_id_copy_to_pri(&ctrl->ev.ring.calling, &c->remote_id);
/* for backwards compatibility, still need ctrl->ev.ring.callingsubaddr */
if (!c->remote_id.subaddress.type) { /* NSAP: Type = 0 */
libpri_copy_string(ctrl->ev.ring.callingsubaddr, (char *) c->remote_id.subaddress.data, sizeof(ctrl->ev.ring.callingsubaddr));
} else {
ctrl->ev.ring.callingsubaddr[0] = '\0';
}
ctrl->ev.ring.ani2 = c->ani2;
/* Called party information */
ctrl->ev.ring.calledplan = c->called.number.plan;
libpri_copy_string(ctrl->ev.ring.callednum, c->called.number.str, sizeof(ctrl->ev.ring.callednum));
q931_party_subaddress_copy_to_pri(&ctrl->ev.ring.called_subaddress, &c->called.subaddress);
/* Original called party information (For backward compatibility) */
libpri_copy_string(ctrl->ev.ring.origcalledname, c->redirecting.orig_called.name.str, sizeof(ctrl->ev.ring.origcalledname));
@ -5078,8 +5312,16 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
ctrl->ev.ring.call = c;
ctrl->ev.ring.channel = q931_encode_channel(c);
libpri_copy_string(ctrl->ev.ring.callednum, c->overlap_digits, sizeof(ctrl->ev.ring.callednum));
libpri_copy_string(ctrl->ev.ring.callingsubaddr, c->callingsubaddr, sizeof(ctrl->ev.ring.callingsubaddr));
ctrl->ev.ring.complete = c->complete; /* this covers IE 33 (Sending Complete) */
q931_party_id_copy_to_pri(&ctrl->ev.ring.calling, &c->remote_id);
/* for backwards compatibility, still need ctrl->ev.ring.callingsubaddr */
if (!c->remote_id.subaddress.type) { /* NSAP: Type = 0 */
libpri_copy_string(ctrl->ev.ring.callingsubaddr, (char *) c->remote_id.subaddress.data, sizeof(ctrl->ev.ring.callingsubaddr));
} else {
ctrl->ev.ring.callingsubaddr[0] = '\0';
}
ctrl->ev.ring.complete = c->complete; /* this covers IE 33 (Sending Complete) */
return Q931_RES_HAVEEVENT;
case Q931_STATUS_ENQUIRY:
if (c->newcall) {