The facility ie queue needs to remove facilities that have been sent.
The facility ie queue needs to remove facilities that have been sent. Otherwise, the queue just grows until the call is terminated. AOC messages can clog the queue during a long call and the dummy call reference may never be deleted. Also removed unneeded elements of struct apdu_event. The callback function was not a good idea since many facility messages do not have responses and the callback would prevents removal of events from the list. git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@1283 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
parent
44ad020fe8
commit
6a121d4c74
@ -1022,7 +1022,7 @@ int rose_diverting_leg_information1_encode(struct pri *ctrl, q931_call *call)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL, NULL);
|
||||
return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1191,7 +1191,7 @@ static int rose_diverting_leg_information2_encode(struct pri *ctrl, q931_call *c
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pri_call_apdu_queue(call, Q931_SETUP, buffer, end - buffer, NULL, NULL);
|
||||
return pri_call_apdu_queue(call, Q931_SETUP, buffer, end - buffer);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1313,7 +1313,7 @@ int rose_diverting_leg_information3_encode(struct pri *ctrl, q931_call *call,
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pri_call_apdu_queue(call, messagetype, buffer, end - buffer, NULL, NULL);
|
||||
return pri_call_apdu_queue(call, messagetype, buffer, end - buffer);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1384,7 +1384,7 @@ int rlt_initiate_transfer(struct pri *ctrl, q931_call *c1, q931_call *c2)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pri_call_apdu_queue(apdubearer, Q931_FACILITY, buffer, end - buffer, NULL, NULL)) {
|
||||
if (pri_call_apdu_queue(apdubearer, Q931_FACILITY, buffer, end - buffer)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1447,7 +1447,7 @@ static int add_dms100_transfer_ability_apdu(struct pri *ctrl, q931_call *call)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pri_call_apdu_queue(call, Q931_SETUP, buffer, end - buffer, NULL, NULL);
|
||||
return pri_call_apdu_queue(call, Q931_SETUP, buffer, end - buffer);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1556,7 +1556,7 @@ static int add_callername_facility_ies(struct pri *ctrl, q931_call *call, int cp
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pri_call_apdu_queue(call, Q931_SETUP, buffer, end - buffer, NULL, NULL)) {
|
||||
if (pri_call_apdu_queue(call, Q931_SETUP, buffer, end - buffer)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1579,15 +1579,11 @@ static int add_callername_facility_ies(struct pri *ctrl, q931_call *call, int cp
|
||||
mymessage = Q931_FACILITY;
|
||||
}
|
||||
|
||||
return pri_call_apdu_queue(call, mymessage, buffer, end - buffer, NULL, NULL);
|
||||
return pri_call_apdu_queue(call, mymessage, buffer, end - buffer);
|
||||
}
|
||||
/* End Callername */
|
||||
|
||||
/* MWI related encode and decode functions */
|
||||
static void mwi_activate_encode_cb(void *data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
@ -1717,8 +1713,7 @@ int mwi_message_send(struct pri *ctrl, q931_call *call, struct pri_sr *req, int
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pri_call_apdu_queue(call, Q931_SETUP, buffer, end - buffer,
|
||||
mwi_activate_encode_cb, NULL);
|
||||
return pri_call_apdu_queue(call, Q931_SETUP, buffer, end - buffer);
|
||||
}
|
||||
/* End MWI */
|
||||
|
||||
@ -1777,7 +1772,7 @@ int eect_initiate_transfer(struct pri *ctrl, q931_call *c1, q931_call *c2)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pri_call_apdu_queue(c1, Q931_FACILITY, buffer, end - buffer, NULL, NULL)) {
|
||||
if (pri_call_apdu_queue(c1, Q931_FACILITY, buffer, end - buffer)) {
|
||||
pri_message(ctrl, "Could not queue APDU in facility message\n");
|
||||
return -1;
|
||||
}
|
||||
@ -2098,7 +2093,7 @@ static int rose_reroute_request_encode(struct pri *ctrl, q931_call *call,
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL, NULL);
|
||||
return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2232,9 +2227,7 @@ static int anfpr_pathreplacement_respond(struct pri *ctrl, q931_call *call, q931
|
||||
}
|
||||
|
||||
/* Send message */
|
||||
res =
|
||||
pri_call_apdu_queue(call->bridged_call, Q931_FACILITY, ie->data, ie->len, NULL,
|
||||
NULL);
|
||||
res = pri_call_apdu_queue(call->bridged_call, Q931_FACILITY, ie->data, ie->len);
|
||||
if (res) {
|
||||
pri_message(ctrl, "Could not queue ADPU in facility message\n");
|
||||
return -1;
|
||||
@ -2302,7 +2295,7 @@ int anfpr_initiate_transfer(struct pri *ctrl, q931_call *c1, q931_call *c2)
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = pri_call_apdu_queue(c1, Q931_FACILITY, buffer, pos - buffer, NULL, NULL);
|
||||
res = pri_call_apdu_queue(c1, Q931_FACILITY, buffer, pos - buffer);
|
||||
if (res) {
|
||||
pri_message(ctrl, "Could not queue ADPU in facility message\n");
|
||||
return -1;
|
||||
@ -2331,7 +2324,7 @@ int anfpr_initiate_transfer(struct pri *ctrl, q931_call *c1, q931_call *c2)
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = pri_call_apdu_queue(c2, Q931_FACILITY, buffer, pos - buffer, NULL, NULL);
|
||||
res = pri_call_apdu_queue(c2, Q931_FACILITY, buffer, pos - buffer);
|
||||
if (res) {
|
||||
pri_message(ctrl, "Could not queue ADPU in facility message\n");
|
||||
return -1;
|
||||
@ -2416,7 +2409,7 @@ static int aoc_aoce_charging_unit_encode(struct pri *ctrl, q931_call *call,
|
||||
|
||||
/* Remember that if we queue a facility IE for a facility message we
|
||||
* have to explicitly send the facility message ourselves */
|
||||
if (pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL, NULL)
|
||||
if (pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer)
|
||||
|| q931_facility(call->pri, call)) {
|
||||
pri_message(ctrl, "Could not schedule facility message for call %d\n", call->cr);
|
||||
return -1;
|
||||
@ -2562,7 +2555,7 @@ static int rose_call_transfer_complete_encode(struct pri *ctrl, q931_call *call,
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL, NULL);
|
||||
return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer);
|
||||
}
|
||||
|
||||
/* ===== End Call Transfer Supplementary Service (ECMA-178) ===== */
|
||||
@ -2630,7 +2623,7 @@ int rose_called_name_encode(struct pri *ctrl, q931_call *call, int messagetype)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pri_call_apdu_queue(call, messagetype, buffer, end - buffer, NULL, NULL);
|
||||
return pri_call_apdu_queue(call, messagetype, buffer, end - buffer);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2696,7 +2689,7 @@ int rose_connected_name_encode(struct pri *ctrl, q931_call *call, int messagetyp
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pri_call_apdu_queue(call, messagetype, buffer, end - buffer, NULL, NULL);
|
||||
return pri_call_apdu_queue(call, messagetype, buffer, end - buffer);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2706,40 +2699,49 @@ int rose_connected_name_encode(struct pri *ctrl, q931_call *call, int messagetyp
|
||||
* \param messagetype Q.931 message type.
|
||||
* \param apdu Facility ie contents buffer.
|
||||
* \param apdu_len Length of the contents buffer.
|
||||
* \param function Callback function for when response is received. (Not implemented)
|
||||
* \param data Parameter to callback function.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int pri_call_apdu_queue(q931_call *call, int messagetype, void *apdu, int apdu_len,
|
||||
void (*function)(void *data), void *data)
|
||||
int pri_call_apdu_queue(q931_call *call, int messagetype, const unsigned char *apdu, int apdu_len)
|
||||
{
|
||||
struct apdu_event *cur = NULL;
|
||||
struct apdu_event *new_event = NULL;
|
||||
|
||||
if (!call || !messagetype || !apdu || (apdu_len < 1) || (apdu_len > 255))
|
||||
if (!call || !messagetype || !apdu
|
||||
|| apdu_len < 1 || sizeof(new_event->apdu) < apdu_len) {
|
||||
return -1;
|
||||
}
|
||||
switch (messagetype) {
|
||||
case Q931_FACILITY:
|
||||
break;
|
||||
default:
|
||||
if (q931_is_dummy_call(call)) {
|
||||
pri_error(call->pri, "!! Cannot send %s message on dummy call reference.\n",
|
||||
msg2str(messagetype));
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(new_event = calloc(1, sizeof(*new_event)))) {
|
||||
new_event = calloc(1, sizeof(*new_event));
|
||||
if (!new_event) {
|
||||
pri_error(call->pri, "!! Malloc failed!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
new_event->message = messagetype;
|
||||
new_event->callback = function;
|
||||
new_event->data = data;
|
||||
memcpy(new_event->apdu, apdu, apdu_len);
|
||||
new_event->apdu_len = apdu_len;
|
||||
memcpy(new_event->apdu, apdu, apdu_len);
|
||||
|
||||
/* Append APDU to the end of the list. */
|
||||
if (call->apdus) {
|
||||
cur = call->apdus;
|
||||
while (cur->next) {
|
||||
cur = cur->next;
|
||||
for (cur = call->apdus; cur->next; cur = cur->next) {
|
||||
}
|
||||
cur->next = new_event;
|
||||
} else
|
||||
} else {
|
||||
call->apdus = new_event;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2750,13 +2752,13 @@ int pri_call_apdu_queue_cleanup(q931_call *call)
|
||||
|
||||
if (call && call->apdus) {
|
||||
cur_event = call->apdus;
|
||||
call->apdus = NULL;
|
||||
while (cur_event) {
|
||||
/* TODO: callbacks, some way of giving return res on status of apdu */
|
||||
free_event = cur_event;
|
||||
cur_event = cur_event->next;
|
||||
free(free_event);
|
||||
}
|
||||
call->apdus = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -2945,7 +2947,7 @@ static int rose_facility_error_encode(struct pri *ctrl, q931_call *call, int inv
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL, NULL);
|
||||
return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3077,7 +3079,7 @@ static int rose_result_ok_encode(struct pri *ctrl, q931_call *call, int msgtype,
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pri_call_apdu_queue(call, msgtype, buffer, end - buffer, NULL, NULL);
|
||||
return pri_call_apdu_queue(call, msgtype, buffer, end - buffer);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -87,10 +87,7 @@ int rose_diverting_leg_information3_encode(struct pri *pri, q931_call *call, int
|
||||
int rose_connected_name_encode(struct pri *pri, q931_call *call, int messagetype);
|
||||
int rose_called_name_encode(struct pri *pri, q931_call *call, int messagetype);
|
||||
|
||||
/* 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 */
|
||||
int pri_call_apdu_queue(q931_call *call, int messagetype, void *apdu, int apdu_len, void (*function)(void *data), void *data);
|
||||
int pri_call_apdu_queue(q931_call *call, int messagetype, const unsigned char *apdu, int apdu_len);
|
||||
|
||||
/* Used by q931.c to cleanup the apdu queue upon destruction of a call */
|
||||
int pri_call_apdu_queue_cleanup(q931_call *call);
|
||||
|
@ -308,13 +308,10 @@ struct pri_sr {
|
||||
#define Q931_MAX_TEI 8
|
||||
|
||||
struct apdu_event {
|
||||
int message; /* What message to send the ADPU in */
|
||||
void (*callback)(void *data); /* Callback function for when response is received */
|
||||
void *data; /* Data to callback */
|
||||
unsigned char apdu[255]; /* ADPU to send */
|
||||
int apdu_len; /* Length of ADPU */
|
||||
int sent; /* Have we been sent already? */
|
||||
struct apdu_event *next; /* Linked list pointer */
|
||||
int message; /* What message to send the ADPU in */
|
||||
int apdu_len; /* Length of ADPU */
|
||||
unsigned char apdu[255]; /* ADPU to send */
|
||||
};
|
||||
|
||||
/*! \brief Incoming call transfer states. */
|
||||
@ -568,6 +565,7 @@ void q931_party_id_fixup(const struct pri *ctrl, struct q931_party_id *id);
|
||||
int q931_party_id_presentation(const struct q931_party_id *id);
|
||||
|
||||
const char *q931_call_state_str(enum Q931_CALL_STATE callstate);
|
||||
const char *msg2str(int msg);
|
||||
|
||||
int q931_is_ptmp(const struct pri *ctrl);
|
||||
int q931_master_pass_event(struct pri *ctrl, struct q931_call *subcall, int msg_type);
|
||||
|
54
q931.c
54
q931.c
@ -228,7 +228,6 @@ static struct msgtype facilities[] = {
|
||||
#define LOC_NETWORK_BEYOND_INTERWORKING 0xa
|
||||
|
||||
static char *ie2str(int ie);
|
||||
static char *msg2str(int msg);
|
||||
|
||||
|
||||
#define FUNC_DUMP(name) void (name)(int full_ie, struct pri *pri, q931_ie *ie, int len, char prefix)
|
||||
@ -2269,32 +2268,41 @@ static int receive_progress_indicator(int full_ie, struct pri *ctrl, q931_call *
|
||||
|
||||
static int transmit_facility(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len, int order)
|
||||
{
|
||||
struct apdu_event *tmp;
|
||||
int i = 0;
|
||||
struct apdu_event **prev;
|
||||
struct apdu_event *cur;
|
||||
int apdu_len;
|
||||
|
||||
for (tmp = call->apdus; tmp; tmp = tmp->next) {
|
||||
if ((tmp->message == msgtype) && !tmp->sent)
|
||||
for (prev = &call->apdus, cur = call->apdus;
|
||||
cur;
|
||||
prev = &cur->next, cur = cur->next) {
|
||||
if (cur->message == msgtype) {
|
||||
/* Remove APDU from list. */
|
||||
*prev = cur->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!tmp) /* No APDU found */
|
||||
if (!cur) {
|
||||
/* No APDU found */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, "Adding facility ie contents to send in %s message:\n",
|
||||
msg2str(msgtype));
|
||||
facility_decode_dump(ctrl, tmp->apdu, tmp->apdu_len);
|
||||
facility_decode_dump(ctrl, cur->apdu, cur->apdu_len);
|
||||
}
|
||||
|
||||
if (tmp->apdu_len > 235) { /* TODO: find out how much space we can use */
|
||||
pri_message(ctrl, "Requested APDU (%d bytes) is too long\n", tmp->apdu_len);
|
||||
if (cur->apdu_len > 235) { /* TODO: find out how much space we can use */
|
||||
pri_message(ctrl, "Requested APDU (%d bytes) is too long\n", cur->apdu_len);
|
||||
free(cur);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(&ie->data[i], tmp->apdu, tmp->apdu_len);
|
||||
i += tmp->apdu_len;
|
||||
tmp->sent = 1;
|
||||
memcpy(ie->data, cur->apdu, cur->apdu_len);
|
||||
apdu_len = cur->apdu_len;
|
||||
free(cur);
|
||||
|
||||
return i + 2;
|
||||
return apdu_len + 2;
|
||||
}
|
||||
|
||||
static int receive_facility(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len)
|
||||
@ -3277,7 +3285,7 @@ static inline unsigned int ielen(q931_ie *ie)
|
||||
return 2 + ie->len;
|
||||
}
|
||||
|
||||
static char *msg2str(int msg)
|
||||
const char *msg2str(int msg)
|
||||
{
|
||||
unsigned int x;
|
||||
for (x=0;x<sizeof(msgs) / sizeof(msgs[0]); x++)
|
||||
@ -6501,13 +6509,11 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
|
||||
libpri_copy_string(ctrl->ev.ringing.useruserinfo, c->useruserinfo, sizeof(ctrl->ev.ringing.useruserinfo));
|
||||
c->useruserinfo[0] = '\0';
|
||||
|
||||
cur = c->apdus;
|
||||
while (cur) {
|
||||
if (!cur->sent && cur->message == Q931_FACILITY) {
|
||||
for (cur = c->apdus; cur; cur = cur->next) {
|
||||
if (cur->message == Q931_FACILITY) {
|
||||
q931_facility(ctrl, c);
|
||||
break;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
return Q931_RES_HAVEEVENT;
|
||||
@ -6608,13 +6614,11 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
|
||||
ctrl->ev.proceeding.cref = c->cr;
|
||||
ctrl->ev.proceeding.call = c->master_call;
|
||||
|
||||
cur = c->apdus;
|
||||
while (cur) {
|
||||
if (!cur->sent && cur->message == Q931_FACILITY) {
|
||||
for (cur = c->apdus; cur; cur = cur->next) {
|
||||
if (cur->message == Q931_FACILITY) {
|
||||
q931_facility(ctrl, c);
|
||||
break;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
return Q931_RES_HAVEEVENT;
|
||||
case Q931_CONNECT_ACKNOWLEDGE:
|
||||
@ -6887,13 +6891,11 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
|
||||
ctrl->ev.setup_ack.channel = q931_encode_channel(c);
|
||||
ctrl->ev.setup_ack.call = c->master_call;
|
||||
|
||||
cur = c->apdus;
|
||||
while (cur) {
|
||||
if (!cur->sent && cur->message == Q931_FACILITY) {
|
||||
for (cur = c->apdus; cur; cur = cur->next) {
|
||||
if (cur->message == Q931_FACILITY) {
|
||||
q931_facility(ctrl, c);
|
||||
break;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
return Q931_RES_HAVEEVENT;
|
||||
|
Loading…
Reference in New Issue
Block a user