diff --git a/pri_facility.c b/pri_facility.c index 6248608..291b620 100644 --- a/pri_facility.c +++ b/pri_facility.c @@ -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); } /*! diff --git a/pri_facility.h b/pri_facility.h index 19de253..6c9bbdd 100644 --- a/pri_facility.h +++ b/pri_facility.h @@ -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); diff --git a/pri_internal.h b/pri_internal.h index e997f1a..3f496cd 100644 --- a/pri_internal.h +++ b/pri_internal.h @@ -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); diff --git a/q931.c b/q931.c index 53f6133..0c117b0 100644 --- a/q931.c +++ b/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;xev.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;