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