[asterisk-commits] file: branch file/gulp_fax r394443 - /team/file/gulp_fax/res/res_sip_t38.c
SVN commits to the Asterisk project
asterisk-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, ¶meters, 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 asterisk-commits
mailing list