[svn-commits] file: branch file/gulp_fax r394443 - /team/file/gulp_fax/res/res_sip_t38.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Jul 16 10:35:34 CDT 2013


Author: file
Date: Tue Jul 16 10:35:33 2013
New Revision: 394443

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=394443
Log:
Add automatic rejection of a T.38 re-invite when nothing in the core accepts it after a period of time.

Modified:
    team/file/gulp_fax/res/res_sip_t38.c

Modified: team/file/gulp_fax/res/res_sip_t38.c
URL: http://svnview.digium.com/svn/asterisk/team/file/gulp_fax/res/res_sip_t38.c?view=diff&rev=394443&r1=394442&r2=394443
==============================================================================
--- team/file/gulp_fax/res/res_sip_t38.c (original)
+++ team/file/gulp_fax/res/res_sip_t38.c Tue Jul 16 10:35:33 2013
@@ -67,6 +67,9 @@
 	struct ast_sip_session_media *media[SIP_MEDIA_SIZE];
 };
 
+/*! \brief The number of seconds after receiving a T.38 re-invite before automatically rejecting it */
+#define T38_AUTOMATIC_REJECTION_SECONDS 5
+
 /*! \brief Address for IPv4 UDPTL */
 static struct ast_sockaddr address_ipv4;
 
@@ -78,6 +81,8 @@
 	struct ast_control_t38_parameters our_parms;
 	/*! \brief Their T.38 parameters */
 	struct ast_control_t38_parameters their_parms;
+	/*! \brief Timer entry for automatically rejecting an inbound re-invite */
+	pj_timer_entry timer;
 };
 
 /*! \brief Destructor for T.38 state information */
@@ -133,31 +138,13 @@
 	return data;
 }
 
-/*! \brief Helper function which retrieves or allocates a T.38 state information datastore */
-static struct t38_state *t38_state_get_or_alloc(struct ast_sip_session *session)
-{
-	RAII_VAR(struct ast_datastore *, datastore, ast_sip_session_get_datastore(session, "t38"), ao2_cleanup);
-
-	/* While the datastore refcount is decremented this is operating in the serializer so it will remain valid regardless */
-	if (datastore) {
-		return datastore->data;
-	}
-
-	if (!(datastore = ast_sip_session_alloc_datastore(&t38_datastore, "t38")) ||
-		!(datastore->data = ast_calloc(1, sizeof(struct t38_state))) ||
-		ast_sip_session_add_datastore(session, datastore)) {
-		return NULL;
-	}
-
-	return datastore->data;
-}
-
 /*! \brief Helper function for changing the T.38 state */
 static void t38_change_state(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
 	struct t38_state *state, enum ast_sip_session_t38state new_state)
 {
 	enum ast_sip_session_t38state old_state = session->t38state;
 	struct ast_control_t38_parameters parameters = { .request_response = 0, };
+	pj_time_val delay = { .sec = T38_AUTOMATIC_REJECTION_SECONDS };
 
 	if (old_state == new_state) {
 		return;
@@ -166,12 +153,23 @@
 	session->t38state = new_state;
 	ast_debug(2, "T.38 state changed to '%d' from '%d' on channel '%s'\n", new_state, old_state, ast_channel_name(session->channel));
 
+	if (pj_timer_heap_cancel(pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()), &state->timer)) {
+		ast_debug(2, "Automatic T.38 rejection on channel '%s' terminated\n", ast_channel_name(session->channel));
+		ao2_ref(session, -1);
+	}
+
 	if (!session->channel) {
 		return;
 	}
 
 	switch (new_state) {
 	case T38_PEER_REINVITE:
+		ao2_ref(session, +1);
+		if (pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(), &state->timer, &delay) != PJ_SUCCESS) {
+			ast_log(LOG_WARNING, "Scheduling of automatic T.38 rejection for channel '%s' failed\n",
+				ast_channel_name(session->channel));
+			ao2_ref(session, -1);
+		}
 		parameters = state->their_parms;
 		parameters.max_ifp = ast_udptl_get_far_max_ifp(session_media->udptl);
 		parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
@@ -199,6 +197,63 @@
 	if (parameters.request_response) {
 		ast_queue_control_data(session->channel, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
 	}
+}
+
+/*! \brief Task function which rejects a T.38 re-invite and resumes handling it */
+static int t38_automatic_reject(void *obj)
+{
+	RAII_VAR(struct ast_sip_session *, session, obj, ao2_cleanup);
+	RAII_VAR(struct ast_datastore *, datastore, ast_sip_session_get_datastore(session, "t38"), ao2_cleanup);
+	RAII_VAR(struct ast_sip_session_media *, session_media, ao2_find(session->media, "image", OBJ_KEY), ao2_cleanup);
+
+	if (!datastore) {
+		return 0;
+	}
+
+	ast_debug(2, "Automatically rejecting T.38 request on channel '%s'\n", ast_channel_name(session->channel));
+
+	t38_change_state(session, session_media, datastore->data, T38_REJECTED);
+	ast_sip_session_resume_reinvite(session);
+
+	return 0;
+}
+
+/*! \brief Timer entry callback which queues a task to reject a T.38 re-invite and resume handling it */
+static void t38_automatic_reject_timer_cb(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry)
+{
+	struct ast_sip_session *session = entry->user_data;
+
+	if (ast_sip_push_task(session->serializer, t38_automatic_reject, session)) {
+		ao2_ref(session, -1);
+	}
+}
+
+/*! \brief Helper function which retrieves or allocates a T.38 state information datastore */
+static struct t38_state *t38_state_get_or_alloc(struct ast_sip_session *session)
+{
+	RAII_VAR(struct ast_datastore *, datastore, ast_sip_session_get_datastore(session, "t38"), ao2_cleanup);
+	struct t38_state *state;
+
+	/* While the datastore refcount is decremented this is operating in the serializer so it will remain valid regardless */
+	if (datastore) {
+		return datastore->data;
+	}
+
+	if (!(datastore = ast_sip_session_alloc_datastore(&t38_datastore, "t38")) ||
+		!(datastore->data = ast_calloc(1, sizeof(struct t38_state))) ||
+		ast_sip_session_add_datastore(session, datastore)) {
+		return NULL;
+	}
+
+	state = datastore->data;
+
+	/* This will get bumped up before scheduling */
+	state->timer.user_data = session;
+	state->timer.cb = t38_automatic_reject_timer_cb;
+
+	datastore->data = state;
+
+	return state;
 }
 
 /*! \brief Initializes UDPTL support on a session, only done when actually needed */




More information about the svn-commits mailing list