adc99c30d6b71d1272e8f0103046cfa8779a2d89
[asterisk/asterisk.git] / res / res_pjsip_t38.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Joshua Colp <jcolp@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \author Joshua Colp <jcolp@digium.com>
22  *
23  * \brief SIP T.38 handling
24  */
25
26 /*** MODULEINFO
27         <depend>pjproject</depend>
28         <depend>res_pjsip</depend>
29         <depend>res_pjsip_session</depend>
30         <support_level>core</support_level>
31  ***/
32
33 #include "asterisk.h"
34
35 #include <pjsip.h>
36 #include <pjsip_ua.h>
37 #include <pjmedia.h>
38 #include <pjlib.h>
39
40 #include "asterisk/module.h"
41 #include "asterisk/udptl.h"
42 #include "asterisk/netsock2.h"
43 #include "asterisk/channel.h"
44 #include "asterisk/acl.h"
45
46 #include "asterisk/res_pjsip.h"
47 #include "asterisk/res_pjsip_session.h"
48
49 /*! \brief The number of seconds after receiving a T.38 re-invite before automatically rejecting it */
50 #define T38_AUTOMATIC_REJECTION_SECONDS 5
51
52 /*! \brief Address for UDPTL */
53 static struct ast_sockaddr address;
54
55 /*! \brief T.38 state information */
56 struct t38_state {
57         /*! \brief Current state */
58         enum ast_sip_session_t38state state;
59         /*! \brief Our T.38 parameters */
60         struct ast_control_t38_parameters our_parms;
61         /*! \brief Their T.38 parameters */
62         struct ast_control_t38_parameters their_parms;
63         /*! \brief Timer entry for automatically rejecting an inbound re-invite */
64         pj_timer_entry timer;
65 };
66
67 /*! \brief Destructor for T.38 state information */
68 static void t38_state_destroy(void *obj)
69 {
70         ast_free(obj);
71 }
72
73 /*! \brief Datastore for attaching T.38 state information */
74 static const struct ast_datastore_info t38_datastore = {
75         .type = "t38",
76         .destroy = t38_state_destroy,
77 };
78
79 /*! \brief Structure for T.38 parameters task data */
80 struct t38_parameters_task_data {
81         /*! \brief Session itself */
82         struct ast_sip_session *session;
83         /*! \brief T.38 control frame */
84         struct ast_frame *frame;
85 };
86
87 /*! \brief Destructor for T.38 data */
88 static void t38_parameters_task_data_destroy(void *obj)
89 {
90         struct t38_parameters_task_data *data = obj;
91
92         ao2_cleanup(data->session);
93
94         if (data->frame) {
95                 ast_frfree(data->frame);
96         }
97 }
98
99 /*! \brief Allocator for T.38 data */
100 static struct t38_parameters_task_data *t38_parameters_task_data_alloc(struct ast_sip_session *session,
101         struct ast_frame *frame)
102 {
103         struct t38_parameters_task_data *data = ao2_alloc(sizeof(*data), t38_parameters_task_data_destroy);
104
105         if (!data) {
106                 return NULL;
107         }
108
109         data->session = session;
110         ao2_ref(session, +1);
111         data->frame = ast_frdup(frame);
112         if (!data->frame) {
113                 ao2_ref(data, -1);
114                 data = NULL;
115         }
116
117         return data;
118 }
119
120 /*! \brief Helper function for changing the T.38 state */
121 static void t38_change_state(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
122         struct t38_state *state, enum ast_sip_session_t38state new_state)
123 {
124         enum ast_sip_session_t38state old_state = session->t38state;
125         struct ast_control_t38_parameters parameters = { .request_response = 0, };
126         pj_time_val delay = { .sec = T38_AUTOMATIC_REJECTION_SECONDS };
127
128         if (old_state == new_state) {
129                 return;
130         }
131
132         session->t38state = new_state;
133         ast_debug(2, "T.38 state changed to '%u' from '%u' on channel '%s'\n",
134                 new_state, old_state,
135                 session->channel ? ast_channel_name(session->channel) : "<gone>");
136
137         if (pj_timer_heap_cancel(pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()), &state->timer)) {
138                 ast_debug(2, "Automatic T.38 rejection on channel '%s' terminated\n",
139                         session->channel ? ast_channel_name(session->channel) : "<gone>");
140                 ao2_ref(session, -1);
141         }
142
143         if (!session->channel) {
144                 return;
145         }
146
147         switch (new_state) {
148         case T38_PEER_REINVITE:
149                 ao2_ref(session, +1);
150                 if (pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(), &state->timer, &delay) != PJ_SUCCESS) {
151                         ast_log(LOG_WARNING, "Scheduling of automatic T.38 rejection for channel '%s' failed\n",
152                                 ast_channel_name(session->channel));
153                         ao2_ref(session, -1);
154                 }
155                 parameters = state->their_parms;
156                 parameters.max_ifp = ast_udptl_get_far_max_ifp(session_media->udptl);
157                 parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
158                 ast_udptl_set_tag(session_media->udptl, "%s", ast_channel_name(session->channel));
159
160                 /* Inform the bridge the channel is in that it needs to be reconfigured */
161                 ast_channel_set_unbridged(session->channel, 1);
162                 break;
163         case T38_ENABLED:
164                 parameters = state->their_parms;
165                 parameters.max_ifp = ast_udptl_get_far_max_ifp(session_media->udptl);
166                 parameters.request_response = AST_T38_NEGOTIATED;
167                 ast_udptl_set_tag(session_media->udptl, "%s", ast_channel_name(session->channel));
168                 break;
169         case T38_REJECTED:
170         case T38_DISABLED:
171                 if (old_state == T38_ENABLED) {
172                         parameters.request_response = AST_T38_TERMINATED;
173                 } else if (old_state == T38_LOCAL_REINVITE) {
174                         parameters.request_response = AST_T38_REFUSED;
175                 }
176                 break;
177         case T38_LOCAL_REINVITE:
178                 /* Inform the bridge the channel is in that it needs to be reconfigured */
179                 ast_channel_set_unbridged(session->channel, 1);
180                 break;
181         case T38_MAX_ENUM:
182                 /* Well, that shouldn't happen */
183                 ast_assert(0);
184                 break;
185         }
186
187         if (parameters.request_response) {
188                 ast_queue_control_data(session->channel, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
189         }
190 }
191
192 /*! \brief Task function which rejects a T.38 re-invite and resumes handling it */
193 static int t38_automatic_reject(void *obj)
194 {
195         RAII_VAR(struct ast_sip_session *, session, obj, ao2_cleanup);
196         RAII_VAR(struct ast_datastore *, datastore, ast_sip_session_get_datastore(session, "t38"), ao2_cleanup);
197         RAII_VAR(struct ast_sip_session_media *, session_media, ao2_find(session->media, "image", OBJ_KEY), ao2_cleanup);
198
199         if (!datastore) {
200                 return 0;
201         }
202
203         ast_debug(2, "Automatically rejecting T.38 request on channel '%s'\n",
204                 session->channel ? ast_channel_name(session->channel) : "<gone>");
205
206         t38_change_state(session, session_media, datastore->data, T38_REJECTED);
207         ast_sip_session_resume_reinvite(session);
208
209         return 0;
210 }
211
212 /*! \brief Timer entry callback which queues a task to reject a T.38 re-invite and resume handling it */
213 static void t38_automatic_reject_timer_cb(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry)
214 {
215         struct ast_sip_session *session = entry->user_data;
216
217         if (ast_sip_push_task(session->serializer, t38_automatic_reject, session)) {
218                 ao2_ref(session, -1);
219         }
220 }
221
222 /*! \brief Helper function which retrieves or allocates a T.38 state information datastore */
223 static struct t38_state *t38_state_get_or_alloc(struct ast_sip_session *session)
224 {
225         RAII_VAR(struct ast_datastore *, datastore, ast_sip_session_get_datastore(session, "t38"), ao2_cleanup);
226         struct t38_state *state;
227
228         /* While the datastore refcount is decremented this is operating in the serializer so it will remain valid regardless */
229         if (datastore) {
230                 return datastore->data;
231         }
232
233         if (!(datastore = ast_sip_session_alloc_datastore(&t38_datastore, "t38"))
234                 || !(datastore->data = ast_calloc(1, sizeof(struct t38_state)))
235                 || ast_sip_session_add_datastore(session, datastore)) {
236                 return NULL;
237         }
238
239         state = datastore->data;
240
241         /* This will get bumped up before scheduling */
242         state->timer.user_data = session;
243         state->timer.cb = t38_automatic_reject_timer_cb;
244
245         datastore->data = state;
246
247         return state;
248 }
249
250 /*! \brief Initializes UDPTL support on a session, only done when actually needed */
251 static int t38_initialize_session(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
252 {
253         if (session_media->udptl) {
254                 return 0;
255         }
256
257         if (!(session_media->udptl = ast_udptl_new_with_bindaddr(NULL, NULL, 0, &address))) {
258                 return -1;
259         }
260
261         ast_channel_set_fd(session->channel, 5, ast_udptl_fd(session_media->udptl));
262         ast_udptl_set_error_correction_scheme(session_media->udptl, session->endpoint->media.t38.error_correction);
263         ast_udptl_setnat(session_media->udptl, session->endpoint->media.t38.nat);
264         ast_udptl_set_far_max_datagram(session_media->udptl, session->endpoint->media.t38.maxdatagram);
265         ast_debug(3, "UDPTL initialized on session for %s\n", ast_channel_name(session->channel));
266
267         return 0;
268 }
269
270 /*! \brief Callback for when T.38 reinvite SDP is created */
271 static int t38_reinvite_sdp_cb(struct ast_sip_session *session, pjmedia_sdp_session *sdp)
272 {
273         int stream;
274
275         /* Move the image media stream to the front and have it as the only stream, pjmedia will fill in
276          * dummy streams for the rest
277          */
278         for (stream = 0; stream < sdp->media_count++; ++stream) {
279                 if (!pj_strcmp2(&sdp->media[stream]->desc.media, "image")) {
280                         sdp->media[0] = sdp->media[stream];
281                         sdp->media_count = 1;
282                         break;
283                 }
284         }
285
286         return 0;
287 }
288
289 /*! \brief Callback for when a response is received for a T.38 re-invite */
290 static int t38_reinvite_response_cb(struct ast_sip_session *session, pjsip_rx_data *rdata)
291 {
292         struct pjsip_status_line status = rdata->msg_info.msg->line.status;
293         struct t38_state *state;
294         RAII_VAR(struct ast_sip_session_media *, session_media, NULL, ao2_cleanup);
295
296         if (status.code == 100) {
297                 return 0;
298         }
299
300         if (!(state = t38_state_get_or_alloc(session)) ||
301                 !(session_media = ao2_find(session->media, "image", OBJ_KEY))) {
302                 ast_log(LOG_WARNING, "Received response to T.38 re-invite on '%s' but state unavailable\n",
303                         ast_channel_name(session->channel));
304                 return 0;
305         }
306
307         t38_change_state(session, session_media, state, (status.code == 200) ? T38_ENABLED : T38_REJECTED);
308
309         return 0;
310 }
311
312 /*! \brief Task for reacting to T.38 control frame */
313 static int t38_interpret_parameters(void *obj)
314 {
315         RAII_VAR(struct t38_parameters_task_data *, data, obj, ao2_cleanup);
316         const struct ast_control_t38_parameters *parameters = data->frame->data.ptr;
317         struct t38_state *state = t38_state_get_or_alloc(data->session);
318         RAII_VAR(struct ast_sip_session_media *, session_media, ao2_find(data->session->media, "image", OBJ_KEY), ao2_cleanup);
319
320         /* Without session media or state we can't interpret parameters */
321         if (!session_media || !state) {
322                 return 0;
323         }
324
325         switch (parameters->request_response) {
326         case AST_T38_NEGOTIATED:
327         case AST_T38_REQUEST_NEGOTIATE:         /* Request T38 */
328                 /* Negotiation can not take place without a valid max_ifp value. */
329                 if (!parameters->max_ifp) {
330                         if (data->session->t38state == T38_PEER_REINVITE) {
331                                 t38_change_state(data->session, session_media, state, T38_REJECTED);
332                                 ast_sip_session_resume_reinvite(data->session);
333                         } else if (data->session->t38state == T38_ENABLED) {
334                                 t38_change_state(data->session, session_media, state, T38_DISABLED);
335                                 ast_sip_session_refresh(data->session, NULL, NULL, NULL,
336                                         AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1);
337                         }
338                         break;
339                 } else if (data->session->t38state == T38_PEER_REINVITE) {
340                         state->our_parms = *parameters;
341                         /* modify our parameters to conform to the peer's parameters,
342                          * based on the rules in the ITU T.38 recommendation
343                          */
344                         if (!state->their_parms.fill_bit_removal) {
345                                 state->our_parms.fill_bit_removal = 0;
346                         }
347                         if (!state->their_parms.transcoding_mmr) {
348                                 state->our_parms.transcoding_mmr = 0;
349                         }
350                         if (!state->their_parms.transcoding_jbig) {
351                                 state->our_parms.transcoding_jbig = 0;
352                         }
353                         state->our_parms.version = MIN(state->our_parms.version, state->their_parms.version);
354                         state->our_parms.rate_management = state->their_parms.rate_management;
355                         ast_udptl_set_local_max_ifp(session_media->udptl, state->our_parms.max_ifp);
356                         t38_change_state(data->session, session_media, state, T38_ENABLED);
357                         ast_sip_session_resume_reinvite(data->session);
358                 } else if ((data->session->t38state != T38_ENABLED) ||
359                                 ((data->session->t38state == T38_ENABLED) &&
360                                 (parameters->request_response == AST_T38_REQUEST_NEGOTIATE))) {
361                         if (t38_initialize_session(data->session, session_media)) {
362                                 break;
363                         }
364                         state->our_parms = *parameters;
365                         ast_udptl_set_local_max_ifp(session_media->udptl, state->our_parms.max_ifp);
366                         t38_change_state(data->session, session_media, state, T38_LOCAL_REINVITE);
367                         ast_sip_session_refresh(data->session, NULL, t38_reinvite_sdp_cb, t38_reinvite_response_cb,
368                                 AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1);
369                 }
370                 break;
371         case AST_T38_TERMINATED:
372         case AST_T38_REFUSED:
373         case AST_T38_REQUEST_TERMINATE:         /* Shutdown T38 */
374                 if (data->session->t38state == T38_PEER_REINVITE) {
375                         t38_change_state(data->session, session_media, state, T38_REJECTED);
376                         ast_sip_session_resume_reinvite(data->session);
377                 } else if (data->session->t38state == T38_ENABLED) {
378                         t38_change_state(data->session, session_media, state, T38_DISABLED);
379                         ast_sip_session_refresh(data->session, NULL, NULL, NULL, AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1);
380                 }
381                 break;
382         case AST_T38_REQUEST_PARMS: {           /* Application wants remote's parameters re-sent */
383                 struct ast_control_t38_parameters parameters = state->their_parms;
384
385                 if (data->session->t38state == T38_PEER_REINVITE) {
386                         parameters.max_ifp = ast_udptl_get_far_max_ifp(session_media->udptl);
387                         parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
388                         ast_queue_control_data(data->session->channel, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
389                 }
390                 break;
391         }
392         default:
393                 break;
394         }
395
396         return 0;
397 }
398
399 /*! \brief Frame hook callback for writing */
400 static struct ast_frame *t38_framehook_write(struct ast_sip_session *session, struct ast_frame *f)
401 {
402         if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_T38_PARAMETERS &&
403                 session->endpoint->media.t38.enabled) {
404                 struct t38_parameters_task_data *data = t38_parameters_task_data_alloc(session, f);
405
406                 if (!data) {
407                         return f;
408                 }
409
410                 if (ast_sip_push_task(session->serializer, t38_interpret_parameters, data)) {
411                         ao2_ref(data, -1);
412                 }
413         } else if (f->frametype == AST_FRAME_MODEM) {
414                 RAII_VAR(struct ast_sip_session_media *, session_media, NULL, ao2_cleanup);
415
416                 if ((session_media = ao2_find(session->media, "image", OBJ_KEY)) &&
417                         session_media->udptl) {
418                         ast_udptl_write(session_media->udptl, f);
419                 }
420         }
421
422         return f;
423 }
424
425 /*! \brief Frame hook callback for reading */
426 static struct ast_frame *t38_framehook_read(struct ast_sip_session *session, struct ast_frame *f)
427 {
428         if (ast_channel_fdno(session->channel) == 5) {
429                 RAII_VAR(struct ast_sip_session_media *, session_media, NULL, ao2_cleanup);
430
431                 if ((session_media = ao2_find(session->media, "image", OBJ_KEY)) &&
432                         session_media->udptl) {
433                         f = ast_udptl_read(session_media->udptl);
434                 }
435         }
436
437         return f;
438 }
439
440 /*! \brief Frame hook callback for T.38 related stuff */
441 static struct ast_frame *t38_framehook(struct ast_channel *chan, struct ast_frame *f,
442         enum ast_framehook_event event, void *data)
443 {
444         struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
445
446         if (event == AST_FRAMEHOOK_EVENT_READ) {
447                 f = t38_framehook_read(channel->session, f);
448         } else if (event == AST_FRAMEHOOK_EVENT_WRITE) {
449                 f = t38_framehook_write(channel->session, f);
450         }
451
452         return f;
453 }
454
455 static void t38_masq(void *data, int framehook_id,
456         struct ast_channel *old_chan, struct ast_channel *new_chan)
457 {
458         if (ast_channel_tech(old_chan) == ast_channel_tech(new_chan)) {
459                 return;
460         }
461
462         /* This framehook is only applicable to PJSIP channels */
463         ast_framehook_detach(new_chan, framehook_id);
464 }
465
466 static int t38_consume(void *data, enum ast_frame_type type)
467 {
468         return 0;
469 }
470
471 static const struct ast_datastore_info t38_framehook_datastore = {
472         .type = "T38 framehook",
473 };
474
475 /*! \brief Function called to attach T.38 framehook to channel when appropriate */
476 static void t38_attach_framehook(struct ast_sip_session *session)
477 {
478         int framehook_id;
479         struct ast_datastore *datastore = NULL;
480         static struct ast_framehook_interface hook = {
481                 .version = AST_FRAMEHOOK_INTERFACE_VERSION,
482                 .event_cb = t38_framehook,
483                 .consume_cb = t38_consume,
484                 .chan_fixup_cb = t38_masq,
485                 .chan_breakdown_cb = t38_masq,
486         };
487
488         /* If the channel's already gone, bail */
489         if (!session->channel) {
490                 return;
491         }
492
493         /* Only attach the framehook if t38 is enabled for the endpoint */
494         if (!session->endpoint->media.t38.enabled) {
495                 return;
496         }
497
498         ast_channel_lock(session->channel);
499
500         /* Skip attaching the framehook if the T.38 datastore already exists for the channel */
501         datastore = ast_channel_datastore_find(session->channel, &t38_framehook_datastore,
502                 NULL);
503         if (datastore) {
504                 ast_channel_unlock(session->channel);
505                 return;
506         }
507
508         framehook_id = ast_framehook_attach(session->channel, &hook);
509         if (framehook_id < 0) {
510                 ast_log(LOG_WARNING, "Could not attach T.38 Frame hook, T.38 will be unavailable on '%s'\n",
511                         ast_channel_name(session->channel));
512                 ast_channel_unlock(session->channel);
513                 return;
514         }
515
516         datastore = ast_datastore_alloc(&t38_framehook_datastore, NULL);
517         if (!datastore) {
518                 ast_log(LOG_ERROR, "Could not alloc T.38 Frame hook datastore, T.38 will be unavailable on '%s'\n",
519                         ast_channel_name(session->channel));
520                 ast_framehook_detach(session->channel, framehook_id);
521                 ast_channel_unlock(session->channel);
522                 return;
523         }
524
525         ast_channel_datastore_add(session->channel, datastore);
526         ast_channel_unlock(session->channel);
527 }
528
529 /*! \brief Function called when an INVITE arrives */
530 static int t38_incoming_invite_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
531 {
532         t38_attach_framehook(session);
533         return 0;
534 }
535
536 /*! \brief Function called when an INVITE is sent */
537 static void t38_outgoing_invite_request(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
538 {
539         t38_attach_framehook(session);
540 }
541
542 /*! \brief Get Max T.38 Transmission rate from T38 capabilities */
543 static unsigned int t38_get_rate(enum ast_control_t38_rate rate)
544 {
545         switch (rate) {
546         case AST_T38_RATE_2400:
547                 return 2400;
548         case AST_T38_RATE_4800:
549                 return 4800;
550         case AST_T38_RATE_7200:
551                 return 7200;
552         case AST_T38_RATE_9600:
553                 return 9600;
554         case AST_T38_RATE_12000:
555                 return 12000;
556         case AST_T38_RATE_14400:
557                 return 14400;
558         default:
559                 return 0;
560         }
561 }
562
563 /*! \brief Supplement for adding framehook to session channel */
564 static struct ast_sip_session_supplement t38_supplement = {
565         .method = "INVITE",
566         .priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL + 1,
567         .incoming_request = t38_incoming_invite_request,
568         .outgoing_request = t38_outgoing_invite_request,
569 };
570
571 /*! \brief Parse a T.38 image stream and store the attribute information */
572 static void t38_interpret_sdp(struct t38_state *state, struct ast_sip_session *session, struct ast_sip_session_media *session_media,
573         const struct pjmedia_sdp_media *stream)
574 {
575         unsigned int attr_i;
576
577         for (attr_i = 0; attr_i < stream->attr_count; attr_i++) {
578                 pjmedia_sdp_attr *attr = stream->attr[attr_i];
579
580                 if (!pj_stricmp2(&attr->name, "t38faxmaxbuffer")) {
581                         /* This is purposely left empty, it is unused */
582                 } else if (!pj_stricmp2(&attr->name, "t38maxbitrate") || !pj_stricmp2(&attr->name, "t38faxmaxrate")) {
583                         switch (pj_strtoul(&attr->value)) {
584                         case 14400:
585                                 state->their_parms.rate = AST_T38_RATE_14400;
586                                 break;
587                         case 12000:
588                                 state->their_parms.rate = AST_T38_RATE_12000;
589                                 break;
590                         case 9600:
591                                 state->their_parms.rate = AST_T38_RATE_9600;
592                                 break;
593                         case 7200:
594                                 state->their_parms.rate = AST_T38_RATE_7200;
595                                 break;
596                         case 4800:
597                                 state->their_parms.rate = AST_T38_RATE_4800;
598                                 break;
599                         case 2400:
600                                 state->their_parms.rate = AST_T38_RATE_2400;
601                                 break;
602                         }
603                 } else if (!pj_stricmp2(&attr->name, "t38faxversion")) {
604                         state->their_parms.version = pj_strtoul(&attr->value);
605                 } else if (!pj_stricmp2(&attr->name, "t38faxmaxdatagram") || !pj_stricmp2(&attr->name, "t38maxdatagram")) {
606                         if (!session->endpoint->media.t38.maxdatagram) {
607                                 ast_udptl_set_far_max_datagram(session_media->udptl, pj_strtoul(&attr->value));
608                         }
609                 } else if (!pj_stricmp2(&attr->name, "t38faxfillbitremoval")) {
610                         state->their_parms.fill_bit_removal = 1;
611                 } else if (!pj_stricmp2(&attr->name, "t38faxtranscodingmmr")) {
612                         state->their_parms.transcoding_mmr = 1;
613                 } else if (!pj_stricmp2(&attr->name, "t38faxtranscodingjbig")) {
614                         state->their_parms.transcoding_jbig = 1;
615                 } else if (!pj_stricmp2(&attr->name, "t38faxratemanagement")) {
616                         if (!pj_stricmp2(&attr->value, "localTCF")) {
617                                 state->their_parms.rate_management = AST_T38_RATE_MANAGEMENT_LOCAL_TCF;
618                         } else if (!pj_stricmp2(&attr->value, "transferredTCF")) {
619                                 state->their_parms.rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF;
620                         }
621                 } else if (!pj_stricmp2(&attr->name, "t38faxudpec")) {
622                         if (!pj_stricmp2(&attr->value, "t38UDPRedundancy")) {
623                                 ast_udptl_set_error_correction_scheme(session_media->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY);
624                         } else if (!pj_stricmp2(&attr->value, "t38UDPFEC")) {
625                                 ast_udptl_set_error_correction_scheme(session_media->udptl, UDPTL_ERROR_CORRECTION_FEC);
626                         } else {
627                                 ast_udptl_set_error_correction_scheme(session_media->udptl, UDPTL_ERROR_CORRECTION_NONE);
628                         }
629                 }
630
631         }
632 }
633
634 /*! \brief Function which defers an incoming media stream */
635 static enum ast_sip_session_sdp_stream_defer defer_incoming_sdp_stream(
636         struct ast_sip_session *session, struct ast_sip_session_media *session_media,
637         const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream)
638 {
639         struct t38_state *state;
640
641         if (!session->endpoint->media.t38.enabled) {
642                 ast_debug(3, "Not deferring incoming SDP stream: T.38 not enabled on %s\n", ast_channel_name(session->channel));
643                 return AST_SIP_SESSION_SDP_DEFER_NOT_HANDLED;
644         }
645
646         if (t38_initialize_session(session, session_media)) {
647                 ast_debug(3, "Not deferring incoming SDP stream: Failed to initialize UDPTL on %s\n", ast_channel_name(session->channel));
648                 return AST_SIP_SESSION_SDP_DEFER_ERROR;
649         }
650
651         if (!(state = t38_state_get_or_alloc(session))) {
652                 return AST_SIP_SESSION_SDP_DEFER_ERROR;
653         }
654
655         t38_interpret_sdp(state, session, session_media, stream);
656
657         /* If they are initiating the re-invite we need to defer responding until later */
658         if (session->t38state == T38_DISABLED) {
659                 t38_change_state(session, session_media, state, T38_PEER_REINVITE);
660                 ast_debug(3, "Deferring incoming SDP stream on %s for peer re-invite\n", ast_channel_name(session->channel));
661                 return AST_SIP_SESSION_SDP_DEFER_NEEDED;
662         }
663
664         return AST_SIP_SESSION_SDP_DEFER_NOT_NEEDED;
665 }
666
667 /*! \brief Function which negotiates an incoming media stream */
668 static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
669                                          const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream)
670 {
671         struct t38_state *state;
672         char host[NI_MAXHOST];
673         RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free);
674
675         if (!session->endpoint->media.t38.enabled) {
676                 ast_debug(3, "Declining; T.38 not enabled on session\n");
677                 return -1;
678         }
679
680         if (!(state = t38_state_get_or_alloc(session))) {
681                 return -1;
682         }
683
684         if ((session->t38state == T38_REJECTED) || (session->t38state == T38_DISABLED)) {
685                 ast_debug(3, "Declining; T.38 state is rejected or declined\n");
686                 t38_change_state(session, session_media, state, T38_DISABLED);
687                 return -1;
688         }
689
690         ast_copy_pj_str(host, stream->conn ? &stream->conn->addr : &sdp->conn->addr, sizeof(host));
691
692         /* Ensure that the address provided is valid */
693         if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_INET) <= 0) {
694                 /* The provided host was actually invalid so we error out this negotiation */
695                 ast_debug(3, "Declining; provided host is invalid\n");
696                 return -1;
697         }
698
699         /* Check the address family to make sure it matches configured */
700         if ((ast_sockaddr_is_ipv6(addrs) && !session->endpoint->media.t38.ipv6) ||
701                 (ast_sockaddr_is_ipv4(addrs) && session->endpoint->media.t38.ipv6)) {
702                 /* The address does not match configured */
703                 ast_debug(3, "Declining, provided host does not match configured address family\n");
704                 return -1;
705         }
706
707         return 1;
708 }
709
710 /*! \brief Function which creates an outgoing stream */
711 static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
712                                       struct pjmedia_sdp_session *sdp)
713 {
714         pj_pool_t *pool = session->inv_session->pool_prov;
715         static const pj_str_t STR_IN = { "IN", 2 };
716         static const pj_str_t STR_IP4 = { "IP4", 3};
717         static const pj_str_t STR_IP6 = { "IP6", 3};
718         static const pj_str_t STR_UDPTL = { "udptl", 5 };
719         static const pj_str_t STR_T38 = { "t38", 3 };
720         static const pj_str_t STR_TRANSFERREDTCF = { "transferredTCF", 14 };
721         static const pj_str_t STR_LOCALTCF = { "localTCF", 8 };
722         static const pj_str_t STR_T38UDPFEC = { "t38UDPFEC", 9 };
723         static const pj_str_t STR_T38UDPREDUNDANCY = { "t38UDPRedundancy", 16 };
724         struct t38_state *state;
725         pjmedia_sdp_media *media;
726         const char *hostip = NULL;
727         struct ast_sockaddr addr;
728         char tmp[512];
729         pj_str_t stmp;
730
731         if (!session->endpoint->media.t38.enabled) {
732                 ast_debug(3, "Not creating outgoing SDP stream: T.38 not enabled\n");
733                 return 1;
734         } else if ((session->t38state != T38_LOCAL_REINVITE) && (session->t38state != T38_PEER_REINVITE) &&
735                 (session->t38state != T38_ENABLED)) {
736                 ast_debug(3, "Not creating outgoing SDP stream: T.38 not enabled\n");
737                 return 1;
738         } else if (!(state = t38_state_get_or_alloc(session))) {
739                 return -1;
740         } else if (t38_initialize_session(session, session_media)) {
741                 ast_debug(3, "Not creating outgoing SDP stream: Failed to initialize T.38 session\n");
742                 return -1;
743         }
744
745         if (!(media = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_media))) ||
746                 !(media->conn = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_conn)))) {
747                 return -1;
748         }
749
750         media->desc.media = pj_str(session_media->stream_type);
751         media->desc.transport = STR_UDPTL;
752
753         if (ast_strlen_zero(session->endpoint->media.address)) {
754                 hostip = ast_sip_get_host_ip_string(session->endpoint->media.t38.ipv6 ? pj_AF_INET6() : pj_AF_INET());
755         } else {
756                 hostip = session->endpoint->media.address;
757         }
758
759         if (ast_strlen_zero(hostip)) {
760                 ast_debug(3, "Not creating outgoing SDP stream: no known host IP\n");
761                 return -1;
762         }
763
764         media->conn->net_type = STR_IN;
765         media->conn->addr_type = session->endpoint->media.t38.ipv6 ? STR_IP6 : STR_IP4;
766         pj_strdup2(pool, &media->conn->addr, hostip);
767         ast_udptl_get_us(session_media->udptl, &addr);
768         media->desc.port = (pj_uint16_t) ast_sockaddr_port(&addr);
769         media->desc.port_count = 1;
770         media->desc.fmt[media->desc.fmt_count++] = STR_T38;
771
772         snprintf(tmp, sizeof(tmp), "%u", state->our_parms.version);
773         media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38FaxVersion", pj_cstr(&stmp, tmp));
774
775         snprintf(tmp, sizeof(tmp), "%u", t38_get_rate(state->our_parms.rate));
776         media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38MaxBitRate", pj_cstr(&stmp, tmp));
777
778         if (state->our_parms.fill_bit_removal) {
779                 media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38FaxFillBitRemoval", NULL);
780         }
781
782         if (state->our_parms.transcoding_mmr) {
783                 media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38FaxTranscodingMMR", NULL);
784         }
785
786         if (state->our_parms.transcoding_jbig) {
787                 media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38FaxTranscodingJBIG", NULL);
788         }
789
790         switch (state->our_parms.rate_management) {
791         case AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF:
792                 media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38FaxRateManagement", &STR_TRANSFERREDTCF);
793                 break;
794         case AST_T38_RATE_MANAGEMENT_LOCAL_TCF:
795                 media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38FaxRateManagement", &STR_LOCALTCF);
796                 break;
797         }
798
799         snprintf(tmp, sizeof(tmp), "%u", ast_udptl_get_local_max_datagram(session_media->udptl));
800         media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38FaxMaxDatagram", pj_cstr(&stmp, tmp));
801
802         switch (ast_udptl_get_error_correction_scheme(session_media->udptl)) {
803         case UDPTL_ERROR_CORRECTION_NONE:
804                 break;
805         case UDPTL_ERROR_CORRECTION_FEC:
806                 media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38FaxUdpEC", &STR_T38UDPFEC);
807                 break;
808         case UDPTL_ERROR_CORRECTION_REDUNDANCY:
809                 media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38FaxUdpEC", &STR_T38UDPREDUNDANCY);
810                 break;
811         }
812
813         sdp->media[sdp->media_count++] = media;
814
815         return 1;
816 }
817
818 /*! \brief Function which applies a negotiated stream */
819 static int apply_negotiated_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
820                                        const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_media *local_stream,
821                                        const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream)
822 {
823         RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free);
824         char host[NI_MAXHOST];
825         struct t38_state *state;
826
827         if (!session_media->udptl) {
828                 ast_debug(3, "Not applying negotiated SDP stream: no UDTPL session\n");
829                 return 0;
830         }
831
832         if (!(state = t38_state_get_or_alloc(session))) {
833                 return -1;
834         }
835
836         ast_copy_pj_str(host, remote_stream->conn ? &remote_stream->conn->addr : &remote->conn->addr, sizeof(host));
837
838         /* Ensure that the address provided is valid */
839         if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC) <= 0) {
840                 /* The provided host was actually invalid so we error out this negotiation */
841                 ast_debug(3, "Not applying negotiated SDP stream: failed to resolve remote stream host\n");
842                 return -1;
843         }
844
845         ast_sockaddr_set_port(addrs, remote_stream->desc.port);
846         ast_udptl_set_peer(session_media->udptl, addrs);
847
848         t38_interpret_sdp(state, session, session_media, remote_stream);
849
850         return 0;
851 }
852
853 /*! \brief Function which updates the media stream with external media address, if applicable */
854 static void change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struct pjmedia_sdp_media *stream, struct ast_sip_transport *transport)
855 {
856         RAII_VAR(struct ast_sip_transport_state *, transport_state, ast_sip_get_transport_state(ast_sorcery_object_get_id(transport)), ao2_cleanup);
857         char host[NI_MAXHOST];
858         struct ast_sockaddr addr = { { 0, } };
859
860         /* If the stream has been rejected there will be no connection line */
861         if (!stream->conn || !transport_state) {
862                 return;
863         }
864
865         ast_copy_pj_str(host, &stream->conn->addr, sizeof(host));
866         ast_sockaddr_parse(&addr, host, PARSE_PORT_FORBID);
867
868         /* Is the address within the SDP inside the same network? */
869         if (ast_apply_ha(transport_state->localnet, &addr) == AST_SENSE_ALLOW) {
870                 return;
871         }
872
873         pj_strdup2(tdata->pool, &stream->conn->addr, transport->external_media_address);
874 }
875
876 /*! \brief Function which destroys the UDPTL instance when session ends */
877 static void stream_destroy(struct ast_sip_session_media *session_media)
878 {
879         if (session_media->udptl) {
880                 ast_udptl_destroy(session_media->udptl);
881         }
882         session_media->udptl = NULL;
883 }
884
885 /*! \brief SDP handler for 'image' media stream */
886 static struct ast_sip_session_sdp_handler image_sdp_handler = {
887         .id = "image",
888         .defer_incoming_sdp_stream = defer_incoming_sdp_stream,
889         .negotiate_incoming_sdp_stream = negotiate_incoming_sdp_stream,
890         .create_outgoing_sdp_stream = create_outgoing_sdp_stream,
891         .apply_negotiated_sdp_stream = apply_negotiated_sdp_stream,
892         .change_outgoing_sdp_stream_media_address = change_outgoing_sdp_stream_media_address,
893         .stream_destroy = stream_destroy,
894 };
895
896 /*! \brief Unloads the SIP T.38 module from Asterisk */
897 static int unload_module(void)
898 {
899         ast_sip_session_unregister_sdp_handler(&image_sdp_handler, "image");
900         ast_sip_session_unregister_supplement(&t38_supplement);
901
902         return 0;
903 }
904
905 /*!
906  * \brief Load the module
907  *
908  * Module loading including tests for configuration or dependencies.
909  * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
910  * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
911  * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the
912  * configuration file or other non-critical problem return
913  * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
914  */
915 static int load_module(void)
916 {
917         CHECK_PJSIP_SESSION_MODULE_LOADED();
918
919         ast_sockaddr_parse(&address, "::", 0);
920
921         if (ast_sip_session_register_supplement(&t38_supplement)) {
922                 ast_log(LOG_ERROR, "Unable to register T.38 session supplement\n");
923                 goto end;
924         }
925
926         if (ast_sip_session_register_sdp_handler(&image_sdp_handler, "image")) {
927                 ast_log(LOG_ERROR, "Unable to register SDP handler for image stream type\n");
928                 goto end;
929         }
930
931         return AST_MODULE_LOAD_SUCCESS;
932 end:
933         unload_module();
934
935         return AST_MODULE_LOAD_FAILURE;
936 }
937
938 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP T.38 UDPTL Support",
939         .support_level = AST_MODULE_SUPPORT_CORE,
940         .load = load_module,
941         .unload = unload_module,
942         .load_pri = AST_MODPRI_CHANNEL_DRIVER,
943 );