[svn-commits] rmudgett: branch dvossel/aoc_send r1650 - /team/dvossel/aoc_send/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Apr 21 16:14:49 CDT 2010


Author: rmudgett
Date: Wed Apr 21 16:14:47 2010
New Revision: 1650

URL: http://svnview.digium.com/svn/libpri?view=rev&rev=1650
Log:
Add APDU response "timeout" support if we receive specified Q.931 messages.

AOC requests do not have a specified timeout time.  They essentially
timeout when the CONNECT message comes in.

Modified:
    team/dvossel/aoc_send/pri_aoc.c
    team/dvossel/aoc_send/pri_facility.h
    team/dvossel/aoc_send/q931.c

Modified: team/dvossel/aoc_send/pri_aoc.c
URL: http://svnview.digium.com/svn/libpri/team/dvossel/aoc_send/pri_aoc.c?view=diff&rev=1650&r1=1649&r2=1650
==============================================================================
--- team/dvossel/aoc_send/pri_aoc.c (original)
+++ team/dvossel/aoc_send/pri_aoc.c Wed Apr 21 16:14:47 2010
@@ -1477,17 +1477,15 @@
 	struct apdu_callback_data response;
 
 	end = enc_etsi_aoc_request(ctrl, buffer, buffer + sizeof(buffer), request);
-
 	if (!end) {
 		return -1;
 	}
 
 	memset(&response, 0, sizeof(response));
 	response.invoke_id = ctrl->last_invoke;
-	 /* Set a custom timeout period. Wait 60 seconds for AOC-S response
-	  * TODO, "Timing out" when a specific message comes in would be a
-	  * better solution than a simple timout in this case */
-	response.timeout_time = 60000;
+	response.timeout_time = APDU_TIMEOUT_MSGS_ONLY;
+	response.num_messages = 1;
+	response.message_type[0] = Q931_CONNECT;
 	response.callback = pri_aoc_request_get_response;
 	response.user.value = request;
 
@@ -1655,14 +1653,19 @@
 
 int pri_aoc_charging_request_send(struct pri *ctrl, q931_call *call, enum PRI_AOC_REQUEST aoc_request_flag)
 {
-	if (!ctrl || !call)
-		return -1;
+	int res;
 
 	switch (ctrl->switchtype) {
 	case PRI_SWITCH_EUROISDN_E1:
 	case PRI_SWITCH_EUROISDN_T1:
-	{
-		int res = 0;
+		if (BRI_NT_PTMP(ctrl)) {
+			/*
+			 * We are not setup to handle responses from multiple phones.
+			 * Besides, it is silly to ask for AOC from a phone.
+			 */
+			return -1;
+		}
+		res = 0;
 		if (aoc_request_flag & PRI_AOC_REQUEST_S) {
 			res |= aoc_charging_request_encode(ctrl, call, PRI_AOC_REQUEST_S);
 		}
@@ -1673,7 +1676,6 @@
 			res |= aoc_charging_request_encode(ctrl, call, PRI_AOC_REQUEST_E);
 		}
 		return res;
-	}
 	case PRI_SWITCH_QSIG:
 		break;
 	default:

Modified: team/dvossel/aoc_send/pri_facility.h
URL: http://svnview.digium.com/svn/libpri/team/dvossel/aoc_send/pri_facility.h?view=diff&rev=1650&r1=1649&r2=1650
==============================================================================
--- team/dvossel/aoc_send/pri_facility.h (original)
+++ team/dvossel/aoc_send/pri_facility.h Wed Apr 21 16:14:47 2010
@@ -128,15 +128,21 @@
 /* So calls to pri_call_apdu_find() will not find an aliased event. */
 #define APDU_INVALID_INVOKE_ID  0x10000
 
+#define APDU_TIMEOUT_MSGS_ONLY	-1
+
 struct apdu_callback_data {
 	/*! APDU invoke id to match with any response messages. (Result/Error/Reject) */
 	int invoke_id;
 	/*!
 	 * \brief Time to wait for responses to APDU in ms.
 	 * \note Set to 0 if send the message only.
-	 * \note Set to less than 0 for PRI_TIMER_T_RESPONSE time.
+	 * \note Set to APDU_TIMEOUT_MSGS_ONLY to "timeout" with the message_type list only.
 	 */
 	int timeout_time;
+	/*! Number of Q.931 messages the APDU can "timeout" on. */
+	unsigned num_messages;
+	/*! Q.931 message list to "timeout" on. */
+	int message_type[5];
 	/*!
 	 * \brief APDU callback function.
 	 *

Modified: team/dvossel/aoc_send/q931.c
URL: http://svnview.digium.com/svn/libpri/team/dvossel/aoc_send/q931.c?view=diff&rev=1650&r1=1649&r2=1650
==============================================================================
--- team/dvossel/aoc_send/q931.c (original)
+++ team/dvossel/aoc_send/q931.c Wed Apr 21 16:14:47 2010
@@ -2429,17 +2429,18 @@
 	cur->sent = 1;
 
 	if (cur->response.callback && cur->response.timeout_time) {
-		int duration;
+		int failed;
 
 		if (0 < cur->response.timeout_time) {
-			/* Sender specified timeout duration. */
-			duration = cur->response.timeout_time;
+			/* Sender specified a timeout duration. */
+			cur->timer = pri_schedule_event(ctrl, cur->response.timeout_time,
+				q931_apdu_timeout, cur);
+			failed = !cur->timer;
 		} else {
-			/* Sender wants to use the typical timeout duration. */
-			duration = ctrl->timers[PRI_TIMER_T_RESPONSE];
-		}
-		cur->timer = pri_schedule_event(ctrl, duration, q931_apdu_timeout, cur);
-		if (!cur->timer) {
+			/* Sender wants to "timeout" only when specified messages are received. */
+			failed = !cur->response.num_messages;
+		}
+		if (failed) {
 			/* Remove APDU from list. */
 			*prev = cur->next;
 
@@ -2448,7 +2449,7 @@
 
 			free(cur);
 		}
-	} else if (!cur->timer) {
+	} else {
 		/* Remove APDU from list. */
 		*prev = cur->next;
 		free(cur);
@@ -2565,6 +2566,52 @@
 			pri_message(ctrl, "-- Delayed processing IE %d (cs%d, %s)\n", ie->ie, codeset, ie2str(full_ie));
 		}
 		process_facility(ctrl, call, msgtype, ie);
+	}
+}
+
+/*!
+ * \internal
+ * \brief Check if any APDU responses "timeout" with the current Q.931 message.
+ *
+ * \param ctrl D channel controller.
+ * \param call Q.931 call leg.
+ * \param msgtype Q.931 message type received.
+ *
+ * \return Nothing
+ */
+static void q931_apdu_msg_expire(struct pri *ctrl, struct q931_call *call, int msgtype)
+{
+	struct apdu_event **prev;
+	struct apdu_event **prev_next;
+	struct apdu_event *cur;
+	unsigned idx;
+
+	for (prev = &call->apdus; *prev; prev = prev_next) {
+		cur = *prev;
+		prev_next = &cur->next;
+		if (cur->sent) {
+			for (idx = 0; idx < cur->response.num_messages; ++idx) {
+				if (cur->response.message_type[idx] == msgtype) {
+					/*
+					 * APDU response message "timeout".
+					 *
+					 * Extract the APDU from the list so it cannot be
+					 * deleted from under us by the callback.
+					 */
+					prev_next = prev;
+					*prev = cur->next;
+
+					/* Stop any response timeout. */
+					pri_schedule_del(ctrl, cur->timer);
+					cur->timer = 0;
+
+					cur->response.callback(APDU_CALLBACK_REASON_TIMEOUT, ctrl, call, cur, NULL);
+
+					free(cur);
+					break;
+				}
+			}
+		}
 	}
 }
 
@@ -6291,6 +6338,7 @@
 		/* Now handle the facility ie's after all the other ie's were processed. */
 		q931_handle_facilities(ctrl, c, mh->msg);
 	}
+	q931_apdu_msg_expire(ctrl, c, mh->msg);
 
 	/* Post handling */
 	if ((h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_1) || (h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_2)) {
@@ -6300,6 +6348,9 @@
 
 		if (c->master_call->outboundbroadcast) {
 			nt_ptmp_handle_q931_message(ctrl, mh, c, &allow_event, &allow_posthandle);
+			if (allow_event) {
+				q931_apdu_msg_expire(ctrl, c->master_call, mh->msg);
+			}
 		}
 
 		if (allow_posthandle) {




More information about the svn-commits mailing list