967349e0b966ab01ba33b6cf98a21d5a7566cb5f
[asterisk/asterisk.git] / channels / chan_gulp.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 Gulp SIP Channel Driver
24  *
25  * \ingroup channel_drivers
26  */
27
28 /*** MODULEINFO
29         <depend>pjproject</depend>
30         <depend>res_sip</depend>
31         <depend>res_sip_session</depend>
32         <support_level>core</support_level>
33  ***/
34
35 #include "asterisk.h"
36
37 #include <pjsip.h>
38 #include <pjsip_ua.h>
39 #include <pjlib.h>
40
41 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
42
43 #include "asterisk/lock.h"
44 #include "asterisk/channel.h"
45 #include "asterisk/module.h"
46 #include "asterisk/pbx.h"
47 #include "asterisk/rtp_engine.h"
48 #include "asterisk/acl.h"
49 #include "asterisk/callerid.h"
50 #include "asterisk/file.h"
51 #include "asterisk/cli.h"
52 #include "asterisk/app.h"
53 #include "asterisk/musiconhold.h"
54 #include "asterisk/causes.h"
55 #include "asterisk/taskprocessor.h"
56
57 #include "asterisk/res_sip.h"
58 #include "asterisk/res_sip_session.h"
59
60 /*** DOCUMENTATION
61         <function name="GULP_DIAL_CONTACTS" language="en_US">
62                 <synopsis>
63                         Return a dial string for dialing all contacts on an AOR.
64                 </synopsis>
65                 <syntax>
66                         <parameter name="endpoint" required="true">
67                                 <para>Name of the endpoint</para>
68                         </parameter>
69                         <parameter name="aor" required="false">
70                                 <para>Name of an AOR to use, if not specified the configured AORs on the endpoint are used</para>
71                         </parameter>
72                         <parameter name="request_user" required="false">
73                                 <para>Optional request user to use in the request URI</para>
74                         </parameter>
75                 </syntax>
76                 <description>
77                         <para>Returns a properly formatted dial string for dialing all contacts on an AOR.</para>
78                 </description>
79         </function>
80  ***/
81
82 static const char desc[] = "Gulp SIP Channel";
83 static const char channel_type[] = "Gulp";
84
85 /*!
86  * \brief Positions of various media
87  */
88 enum sip_session_media_position {
89         /*! \brief First is audio */
90         SIP_MEDIA_AUDIO = 0,
91         /*! \brief Second is video */
92         SIP_MEDIA_VIDEO,
93         /*! \brief Last is the size for media details */
94         SIP_MEDIA_SIZE,
95 };
96
97 struct gulp_pvt {
98         struct ast_sip_session *session;
99         struct ast_sip_session_media *media[SIP_MEDIA_SIZE];
100 };
101
102 static void gulp_pvt_dtor(void *obj)
103 {
104         struct gulp_pvt *pvt = obj;
105         int i;
106
107         ao2_cleanup(pvt->session);
108         pvt->session = NULL;
109
110         for (i = 0; i < SIP_MEDIA_SIZE; ++i) {
111                 ao2_cleanup(pvt->media[i]);
112                 pvt->media[i] = NULL;
113         }
114 }
115
116 /* \brief Asterisk core interaction functions */
117 static struct ast_channel *gulp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
118 static int gulp_sendtext(struct ast_channel *ast, const char *text);
119 static int gulp_digit_begin(struct ast_channel *ast, char digit);
120 static int gulp_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
121 static int gulp_call(struct ast_channel *ast, const char *dest, int timeout);
122 static int gulp_hangup(struct ast_channel *ast);
123 static int gulp_answer(struct ast_channel *ast);
124 static struct ast_frame *gulp_read(struct ast_channel *ast);
125 static int gulp_write(struct ast_channel *ast, struct ast_frame *f);
126 static int gulp_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
127 static int gulp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
128
129 /*! \brief PBX interface structure for channel registration */
130 static struct ast_channel_tech gulp_tech = {
131         .type = channel_type,
132         .description = "Gulp SIP Channel Driver",
133         .requester = gulp_request,
134         .send_text = gulp_sendtext,
135         .send_digit_begin = gulp_digit_begin,
136         .send_digit_end = gulp_digit_end,
137         .call = gulp_call,
138         .hangup = gulp_hangup,
139         .answer = gulp_answer,
140         .read = gulp_read,
141         .write = gulp_write,
142         .write_video = gulp_write,
143         .exception = gulp_read,
144         .indicate = gulp_indicate,
145         .fixup = gulp_fixup,
146         .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER
147 };
148
149 /*! \brief SIP session interaction functions */
150 static void gulp_session_begin(struct ast_sip_session *session);
151 static void gulp_session_end(struct ast_sip_session *session);
152 static int gulp_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
153 static void gulp_incoming_response(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
154
155 /*! \brief SIP session supplement structure */
156 static struct ast_sip_session_supplement gulp_supplement = {
157         .method = "INVITE",
158         .priority = AST_SIP_SESSION_SUPPLEMENT_PRIORITY_CHANNEL,
159         .session_begin = gulp_session_begin,
160         .session_end = gulp_session_end,
161         .incoming_request = gulp_incoming_request,
162         .incoming_response = gulp_incoming_response,
163 };
164
165 static int gulp_incoming_ack(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
166
167 static struct ast_sip_session_supplement gulp_ack_supplement = {
168         .method = "ACK",
169         .priority = AST_SIP_SESSION_SUPPLEMENT_PRIORITY_CHANNEL,
170         .incoming_request = gulp_incoming_ack,
171 };
172
173 /*! \brief Dialplan function for constructing a dial string for calling all contacts */
174 static int gulp_dial_contacts(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
175 {
176         RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
177         RAII_VAR(struct ast_str *, dial, NULL, ast_free_ptr);
178         const char *aor_name;
179         char *rest;
180
181         AST_DECLARE_APP_ARGS(args,
182                 AST_APP_ARG(endpoint_name);
183                 AST_APP_ARG(aor_name);
184                 AST_APP_ARG(request_user);
185         );
186
187         AST_STANDARD_APP_ARGS(args, data);
188
189         if (ast_strlen_zero(args.endpoint_name)) {
190                 ast_log(LOG_WARNING, "An endpoint name must be specified when using the '%s' dialplan function\n", cmd);
191                 return -1;
192         } else if (!(endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", args.endpoint_name))) {
193                 ast_log(LOG_WARNING, "Specified endpoint '%s' was not found\n", args.endpoint_name);
194                 return -1;
195         }
196
197         aor_name = S_OR(args.aor_name, endpoint->aors);
198
199         if (ast_strlen_zero(aor_name)) {
200                 ast_log(LOG_WARNING, "No AOR has been provided and no AORs are configured on endpoint '%s'\n", args.endpoint_name);
201                 return -1;
202         } else if (!(dial = ast_str_create(len))) {
203                 ast_log(LOG_WARNING, "Could not get enough buffer space for dialing contacts\n");
204                 return -1;
205         } else if (!(rest = ast_strdupa(aor_name))) {
206                 ast_log(LOG_WARNING, "Could not duplicate provided AORs\n");
207                 return -1;
208         }
209
210         while ((aor_name = strsep(&rest, ","))) {
211                 RAII_VAR(struct ast_sip_aor *, aor, ast_sip_location_retrieve_aor(aor_name), ao2_cleanup);
212                 RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
213                 struct ao2_iterator it_contacts;
214                 struct ast_sip_contact *contact;
215
216                 if (!aor) {
217                         /* If the AOR provided is not found skip it, there may be more */
218                         continue;
219                 } else if (!(contacts = ast_sip_location_retrieve_aor_contacts(aor))) {
220                         /* No contacts are available, skip it as well */
221                         continue;
222                 } else if (!ao2_container_count(contacts)) {
223                         /* We were given a container but no contacts are in it... */
224                         continue;
225                 }
226
227                 it_contacts = ao2_iterator_init(contacts, 0);
228                 for (; (contact = ao2_iterator_next(&it_contacts)); ao2_ref(contact, -1)) {
229                         ast_str_append(&dial, -1, "Gulp/");
230
231                         if (!ast_strlen_zero(args.request_user)) {
232                                 ast_str_append(&dial, -1, "%s@", args.request_user);
233                         }
234                         ast_str_append(&dial, -1, "%s/%s&", args.endpoint_name, contact->uri);
235                 }
236                 ao2_iterator_destroy(&it_contacts);
237         }
238
239         /* Trim the '&' at the end off */
240         ast_str_truncate(dial, ast_str_strlen(dial) - 1);
241
242         ast_copy_string(buf, ast_str_buffer(dial), len);
243
244         return 0;
245 }
246
247 static struct ast_custom_function gulp_dial_contacts_function = {
248         .name = "GULP_DIAL_CONTACTS",
249         .read = gulp_dial_contacts,
250 };
251
252 /*! \brief Function called by RTP engine to get local audio RTP peer */
253 static enum ast_rtp_glue_result gulp_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
254 {
255         struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
256         struct ast_sip_endpoint *endpoint;
257
258         if (!pvt || !pvt->session || !pvt->media[SIP_MEDIA_AUDIO]->rtp) {
259                 return AST_RTP_GLUE_RESULT_FORBID;
260         }
261
262         endpoint = pvt->session->endpoint;
263
264         *instance = pvt->media[SIP_MEDIA_AUDIO]->rtp;
265         ao2_ref(*instance, +1);
266
267         ast_assert(endpoint != NULL);
268         if (endpoint->direct_media) {
269                 return AST_RTP_GLUE_RESULT_REMOTE;
270         }
271
272         return AST_RTP_GLUE_RESULT_LOCAL;
273 }
274
275 /*! \brief Function called by RTP engine to get local video RTP peer */
276 static enum ast_rtp_glue_result gulp_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
277 {
278         struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
279
280         if (!pvt || !pvt->session || !pvt->media[SIP_MEDIA_VIDEO]->rtp) {
281                 return AST_RTP_GLUE_RESULT_FORBID;
282         }
283
284         *instance = pvt->media[SIP_MEDIA_VIDEO]->rtp;
285         ao2_ref(*instance, +1);
286
287         return AST_RTP_GLUE_RESULT_LOCAL;
288 }
289
290 /*! \brief Function called by RTP engine to get peer capabilities */
291 static void gulp_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
292 {
293         struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
294
295         ast_format_cap_copy(result, pvt->session->endpoint->codecs);
296 }
297
298 static int send_direct_media_request(void *data)
299 {
300         RAII_VAR(struct ast_sip_session *, session, data, ao2_cleanup);
301
302         return ast_sip_session_refresh(session, NULL, NULL, session->endpoint->direct_media_method, 1);
303 }
304
305 static struct ast_datastore_info direct_media_mitigation_info = { };
306
307 static int direct_media_mitigate_glare(struct ast_sip_session *session)
308 {
309         RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
310
311         if (session->endpoint->direct_media_glare_mitigation == 
312                         AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE) {
313                 return 0;
314         }
315
316         datastore = ast_sip_session_get_datastore(session, "direct_media_glare_mitigation");
317         if (!datastore) {
318                 return 0;
319         }
320
321         /* Removing the datastore ensures we won't try to mitigate glare on subsequent reinvites */
322         ast_sip_session_remove_datastore(session, "direct_media_glare_mitigation");
323
324         if ((session->endpoint->direct_media_glare_mitigation ==
325                         AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_OUTGOING &&
326                         session->inv_session->role == PJSIP_ROLE_UAC) ||
327                         (session->endpoint->direct_media_glare_mitigation ==
328                         AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_INCOMING &&
329                         session->inv_session->role == PJSIP_ROLE_UAS)) {
330                 return 1;
331         }
332
333         return 0;
334 }
335
336 static int check_for_rtp_changes(struct ast_channel *chan, struct ast_rtp_instance *rtp,
337                 struct ast_sip_session_media *media, int rtcp_fd)
338 {
339         int changed = 0;
340
341         if (rtp) {
342                 changed = ast_rtp_instance_get_and_cmp_remote_address(rtp, &media->direct_media_addr);
343                 if (media->rtp) {
344                         ast_channel_set_fd(chan, rtcp_fd, -1);
345                         ast_rtp_instance_set_prop(media->rtp, AST_RTP_PROPERTY_RTCP, 0);
346                 }
347         } else if (!ast_sockaddr_isnull(&media->direct_media_addr)){
348                 ast_sockaddr_setnull(&media->direct_media_addr);
349                 changed = 1;
350                 if (media->rtp) {
351                         ast_rtp_instance_set_prop(media->rtp, AST_RTP_PROPERTY_RTCP, 1);
352                         ast_channel_set_fd(chan, rtcp_fd, ast_rtp_instance_fd(media->rtp, 1));
353                 }
354         }
355
356         return changed;
357 }
358
359 /*! \brief Function called by RTP engine to change where the remote party should send media */
360 static int gulp_set_rtp_peer(struct ast_channel *chan,
361                 struct ast_rtp_instance *rtp,
362                 struct ast_rtp_instance *vrtp,
363                 struct ast_rtp_instance *tpeer,
364                 const struct ast_format_cap *cap,
365                 int nat_active)
366 {
367         struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
368         struct ast_sip_session *session = pvt->session;
369         int changed = 0;
370
371         /* BUGBUG - ast_bridged_channel will always return NULL, meaning direct media will never occur */
372         /* Don't try to do any direct media shenanigans on early bridges */
373         if ((rtp || vrtp || tpeer) && !ast_bridged_channel(chan)) {
374                 return 0;
375         }
376
377         if (nat_active && session->endpoint->disable_direct_media_on_nat) {
378                 return 0;
379         }
380
381         if (pvt->media[SIP_MEDIA_AUDIO]) {
382                 changed |= check_for_rtp_changes(chan, rtp, pvt->media[SIP_MEDIA_AUDIO], 1);
383         }
384         if (pvt->media[SIP_MEDIA_VIDEO]) {
385                 changed |= check_for_rtp_changes(chan, vrtp, pvt->media[SIP_MEDIA_VIDEO], 3);
386         }
387
388         if (direct_media_mitigate_glare(session)) {
389                 return 0;
390         }
391
392         if (cap && !ast_format_cap_is_empty(cap) && !ast_format_cap_identical(session->direct_media_cap, cap)) {
393                 ast_format_cap_copy(session->direct_media_cap, cap);
394                 changed = 1;
395         }
396
397         if (changed) {
398                 ao2_ref(session, +1);
399                 ast_sip_push_task(session->serializer, send_direct_media_request, session);
400         }
401
402         return 0;
403 }
404
405 /*! \brief Local glue for interacting with the RTP engine core */
406 static struct ast_rtp_glue gulp_rtp_glue = {
407         .type = "Gulp",
408         .get_rtp_info = gulp_get_rtp_peer,
409         .get_vrtp_info = gulp_get_vrtp_peer,
410         .get_codec = gulp_get_codec,
411         .update_peer = gulp_set_rtp_peer,
412 };
413
414 /*! \brief Function called to create a new Gulp Asterisk channel */
415 static struct ast_channel *gulp_new(struct ast_sip_session *session, int state, const char *exten, const char *title, const char *linkedid, const char *cid_name)
416 {
417         struct ast_channel *chan;
418         struct ast_format fmt;
419         struct gulp_pvt *pvt;
420
421         if (!(pvt = ao2_alloc(sizeof(*pvt), gulp_pvt_dtor))) {
422                 return NULL;
423         }
424
425         if (!(chan = ast_channel_alloc(1, state, S_OR(session->id.number.str, ""), S_OR(session->id.name.str, ""), "", "", "", linkedid, 0, "Gulp/%s-%.*s", ast_sorcery_object_get_id(session->endpoint),
426                 (int)session->inv_session->dlg->call_id->id.slen, session->inv_session->dlg->call_id->id.ptr))) {
427                 ao2_cleanup(pvt);
428                 return NULL;
429         }
430
431         ast_channel_tech_set(chan, &gulp_tech);
432
433         ao2_ref(session, +1);
434         pvt->session = session;
435         /* If res_sip_session is ever updated to create/destroy ast_sip_session_media
436          * during a call such as if multiple same-type stream support is introduced,
437          * these will need to be recaptured as well */
438         pvt->media[SIP_MEDIA_AUDIO] = ao2_find(session->media, "audio", OBJ_KEY);
439         pvt->media[SIP_MEDIA_VIDEO] = ao2_find(session->media, "video", OBJ_KEY);
440         ast_channel_tech_pvt_set(chan, pvt);
441
442         if (ast_format_cap_is_empty(session->req_caps) || !ast_format_cap_has_joint(session->req_caps, session->endpoint->codecs)) {
443                 ast_format_cap_copy(ast_channel_nativeformats(chan), session->endpoint->codecs);
444         } else {
445                 ast_format_cap_copy(ast_channel_nativeformats(chan), session->req_caps);
446         }
447
448         ast_codec_choose(&session->endpoint->prefs, ast_channel_nativeformats(chan), 1, &fmt);
449         ast_format_copy(ast_channel_writeformat(chan), &fmt);
450         ast_format_copy(ast_channel_rawwriteformat(chan), &fmt);
451         ast_format_copy(ast_channel_readformat(chan), &fmt);
452         ast_format_copy(ast_channel_rawreadformat(chan), &fmt);
453
454         if (state == AST_STATE_RING) {
455                 ast_channel_rings_set(chan, 1);
456         }
457
458         ast_channel_adsicpe_set(chan, AST_ADSI_UNAVAILABLE);
459
460         ast_channel_context_set(chan, session->endpoint->context);
461         ast_channel_exten_set(chan, S_OR(exten, "s"));
462         ast_channel_priority_set(chan, 1);
463
464         return chan;
465 }
466
467 static int answer(void *data)
468 {
469         pj_status_t status;
470         pjsip_tx_data *packet;
471         struct ast_sip_session *session = data;
472
473         if ((status = pjsip_inv_answer(session->inv_session, 200, NULL, NULL, &packet)) == PJ_SUCCESS) {
474                 ast_sip_session_send_response(session, packet);
475         }
476
477         ao2_ref(session, -1);
478
479         return (status == PJ_SUCCESS) ? 0 : -1;
480 }
481
482 /*! \brief Function called by core when we should answer a Gulp session */
483 static int gulp_answer(struct ast_channel *ast)
484 {
485         struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
486         struct ast_sip_session *session = pvt->session;
487
488         if (ast_channel_state(ast) == AST_STATE_UP) {
489                 return 0;
490         }
491
492         ast_setstate(ast, AST_STATE_UP);
493
494         ao2_ref(session, +1);
495         if (ast_sip_push_task(session->serializer, answer, session)) {
496                 ast_log(LOG_WARNING, "Unable to push answer task to the threadpool. Cannot answer call\n");
497                 ao2_cleanup(session);
498                 return -1;
499         }
500
501         return 0;
502 }
503
504 /*! \brief Function called by core to read any waiting frames */
505 static struct ast_frame *gulp_read(struct ast_channel *ast)
506 {
507         struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
508         struct ast_frame *f;
509         struct ast_sip_session_media *media = NULL;
510         int rtcp = 0;
511         int fdno = ast_channel_fdno(ast);
512
513         switch (fdno) {
514         case 0:
515                 media = pvt->media[SIP_MEDIA_AUDIO];
516                 break;
517         case 1:
518                 media = pvt->media[SIP_MEDIA_AUDIO];
519                 rtcp = 1;
520                 break;
521         case 2:
522                 media = pvt->media[SIP_MEDIA_VIDEO];
523                 break;
524         case 3:
525                 media = pvt->media[SIP_MEDIA_VIDEO];
526                 rtcp = 1;
527                 break;
528         }
529
530         if (!media || !media->rtp) {
531                 return &ast_null_frame;
532         }
533
534         f = ast_rtp_instance_read(media->rtp, rtcp);
535
536         if (f && f->frametype == AST_FRAME_VOICE) {
537                 if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &f->subclass.format))) {
538                         ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
539                         ast_format_cap_set(ast_channel_nativeformats(ast), &f->subclass.format);
540                         ast_set_read_format(ast, ast_channel_readformat(ast));
541                         ast_set_write_format(ast, ast_channel_writeformat(ast));
542                 }
543         }
544
545         return f;
546 }
547
548 /*! \brief Function called by core to write frames */
549 static int gulp_write(struct ast_channel *ast, struct ast_frame *frame)
550 {
551         struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
552         struct ast_sip_session_media *media;
553         int res = 0;
554
555         switch (frame->frametype) {
556         case AST_FRAME_VOICE:
557                 media = pvt->media[SIP_MEDIA_AUDIO];
558
559                 if (!media) {
560                         return 0;
561                 }
562                 if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &frame->subclass.format))) {
563                         char buf[256];
564
565                         ast_log(LOG_WARNING,
566                                 "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
567                                 ast_getformatname(&frame->subclass.format),
568                                 ast_getformatname_multiple(buf, sizeof(buf), ast_channel_nativeformats(ast)),
569                                 ast_getformatname(ast_channel_readformat(ast)),
570                                 ast_getformatname(ast_channel_writeformat(ast)));
571                         return 0;
572                 }
573                 if (media->rtp) {
574                         res = ast_rtp_instance_write(media->rtp, frame);
575                 }
576                 break;
577         case AST_FRAME_VIDEO:
578                 if ((media = pvt->media[SIP_MEDIA_VIDEO]) && media->rtp) {
579                         res = ast_rtp_instance_write(media->rtp, frame);
580                 }
581                 break;
582         default:
583                 ast_log(LOG_WARNING, "Can't send %d type frames with Gulp\n", frame->frametype);
584                 break;
585         }
586
587         return res;
588 }
589
590 struct fixup_data {
591         struct ast_sip_session *session;
592         struct ast_channel *chan;
593 };
594
595 static int fixup(void *data)
596 {
597         struct fixup_data *fix_data = data;
598
599         fix_data->session->channel = fix_data->chan;
600
601         return 0;
602 }
603
604 /*! \brief Function called by core to change the underlying owner channel */
605 static int gulp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
606 {
607         struct gulp_pvt *pvt = ast_channel_tech_pvt(newchan);
608         struct ast_sip_session *session = pvt->session;
609         struct fixup_data fix_data;
610
611         fix_data.session = session;
612         fix_data.chan = newchan;
613
614         if (session->channel != oldchan) {
615                 return -1;
616         }
617
618         if (ast_sip_push_task_synchronous(session->serializer, fixup, &fix_data)) {
619                 ast_log(LOG_WARNING, "Unable to perform channel fixup\n");
620                 return -1;
621         }
622
623         return 0;
624 }
625
626 struct indicate_data {
627         struct ast_sip_session *session;
628         int condition;
629         int response_code;
630         void *frame_data;
631         size_t datalen;
632 };
633
634 static void indicate_data_destroy(void *obj)
635 {
636         struct indicate_data *ind_data = obj;
637
638         ast_free(ind_data->frame_data);
639         ao2_ref(ind_data->session, -1);
640 }
641
642 static struct indicate_data *indicate_data_alloc(struct ast_sip_session *session,
643                 int condition, int response_code, const void *frame_data, size_t datalen)
644 {
645         struct indicate_data *ind_data = ao2_alloc(sizeof(*ind_data), indicate_data_destroy);
646
647         if (!ind_data) {
648                 return NULL;
649         }
650
651         ind_data->frame_data = ast_malloc(datalen);
652         if (!ind_data->frame_data) {
653                 ao2_ref(ind_data, -1);
654                 return NULL;
655         }
656
657         memcpy(ind_data->frame_data, frame_data, datalen);
658         ind_data->datalen = datalen;
659         ind_data->condition = condition;
660         ind_data->response_code = response_code;
661         ao2_ref(session, +1);
662         ind_data->session = session;
663
664         return ind_data;
665 }
666
667 static int indicate(void *data)
668 {
669         pjsip_tx_data *packet = NULL;
670         struct indicate_data *ind_data = data;
671         struct ast_sip_session *session = ind_data->session;
672         int response_code = ind_data->response_code;
673
674         if (pjsip_inv_answer(session->inv_session, response_code, NULL, NULL, &packet) == PJ_SUCCESS) {
675                 ast_sip_session_send_response(session, packet);
676         }
677
678         ao2_ref(ind_data, -1);
679
680         return 0;
681 }
682
683 /*! \brief Send SIP INFO with video update request */
684 static int transmit_info_with_vidupdate(void *data)
685 {
686         const char * xml =
687                 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
688                 " <media_control>\r\n"
689                 "  <vc_primitive>\r\n"
690                 "   <to_encoder>\r\n"
691                 "    <picture_fast_update/>\r\n"
692                 "   </to_encoder>\r\n"
693                 "  </vc_primitive>\r\n"
694                 " </media_control>\r\n";
695
696         const struct ast_sip_body body = {
697                 .type = "application",
698                 .subtype = "media_control+xml",
699                 .body_text = xml
700         };
701
702         struct ast_sip_session *session = data;
703         struct pjsip_tx_data *tdata;
704
705         if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, &tdata)) {
706                 ast_log(LOG_ERROR, "Could not create text video update INFO request\n");
707                 return -1;
708         }
709         if (ast_sip_add_body(tdata, &body)) {
710                 ast_log(LOG_ERROR, "Could not add body to text video update INFO request\n");
711                 return -1;
712         }
713         ast_sip_session_send_request(session, tdata);
714
715         return 0;
716 }
717
718 /*! \brief Function called by core to ask the channel to indicate some sort of condition */
719 static int gulp_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
720 {
721         struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
722         struct ast_sip_session *session = pvt->session;
723         struct ast_sip_session_media *media;
724         int response_code = 0;
725         int res = 0;
726
727         switch (condition) {
728         case AST_CONTROL_RINGING:
729                 if (ast_channel_state(ast) == AST_STATE_RING) {
730                         response_code = 180;
731                 } else {
732                         res = -1;
733                 }
734                 break;
735         case AST_CONTROL_BUSY:
736                 if (ast_channel_state(ast) != AST_STATE_UP) {
737                         response_code = 486;
738                 } else {
739                         res = -1;
740                 }
741                 break;
742         case AST_CONTROL_CONGESTION:
743                 if (ast_channel_state(ast) != AST_STATE_UP) {
744                         response_code = 503;
745                 } else {
746                         res = -1;
747                 }
748                 break;
749         case AST_CONTROL_INCOMPLETE:
750                 if (ast_channel_state(ast) != AST_STATE_UP) {
751                         response_code = 484;
752                 } else {
753                         res = -1;
754                 }
755                 break;
756         case AST_CONTROL_PROCEEDING:
757                 if (ast_channel_state(ast) != AST_STATE_UP) {
758                         response_code = 100;
759                 } else {
760                         res = -1;
761                 }
762                 break;
763         case AST_CONTROL_PROGRESS:
764                 if (ast_channel_state(ast) != AST_STATE_UP) {
765                         response_code = 183;
766                 } else {
767                         res = -1;
768                 }
769                 break;
770         case AST_CONTROL_VIDUPDATE:
771                 media = pvt->media[SIP_MEDIA_VIDEO];
772                 if (media && media->rtp) {
773                         ast_sip_push_task(session->serializer, transmit_info_with_vidupdate, session);
774                 } else
775                         res = -1;
776                 break;
777         case AST_CONTROL_UPDATE_RTP_PEER:
778         case AST_CONTROL_PVT_CAUSE_CODE:
779                 break;
780         case AST_CONTROL_HOLD:
781                 ast_moh_start(ast, data, NULL);
782                 break;
783         case AST_CONTROL_UNHOLD:
784                 ast_moh_stop(ast);
785                 break;
786         case AST_CONTROL_SRCUPDATE:
787                 break;
788         case AST_CONTROL_SRCCHANGE:
789                 break;
790         case -1:
791                 res = -1;
792                 break;
793         default:
794                 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
795                 res = -1;
796                 break;
797         }
798
799         if (!res && response_code) {
800                 struct indicate_data *ind_data = indicate_data_alloc(session, condition, response_code, data, datalen);
801                 if (ind_data) {
802                         res = ast_sip_push_task(session->serializer, indicate, ind_data);
803                         if (res) {
804                                 ast_log(LOG_NOTICE, "Cannot send response code %d to endpoint %s. Could not queue task properly\n",
805                                                 response_code, ast_sorcery_object_get_id(session->endpoint));
806                                 ao2_cleanup(ind_data);
807                         }
808                 } else {
809                         res = -1;
810                 }
811         }
812
813         return res;
814 }
815
816 /*! \brief Function called by core to start a DTMF digit */
817 static int gulp_digit_begin(struct ast_channel *chan, char digit)
818 {
819         struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
820         struct ast_sip_session *session = pvt->session;
821         struct ast_sip_session_media *media = pvt->media[SIP_MEDIA_AUDIO];
822         int res = 0;
823
824         switch (session->endpoint->dtmf) {
825         case AST_SIP_DTMF_RFC_4733:
826                 if (!media || !media->rtp) {
827                         return -1;
828                 }
829
830                 ast_rtp_instance_dtmf_begin(media->rtp, digit);
831         case AST_SIP_DTMF_NONE:
832                 break;
833         case AST_SIP_DTMF_INBAND:
834                 res = -1;
835                 break;
836         default:
837                 break;
838         }
839
840         return res;
841 }
842
843 struct info_dtmf_data {
844         struct ast_sip_session *session;
845         char digit;
846         unsigned int duration;
847 };
848
849 static void info_dtmf_data_destroy(void *obj)
850 {
851         struct info_dtmf_data *dtmf_data = obj;
852         ao2_ref(dtmf_data->session, -1);
853 }
854
855 static struct info_dtmf_data *info_dtmf_data_alloc(struct ast_sip_session *session, char digit, unsigned int duration)
856 {
857         struct info_dtmf_data *dtmf_data = ao2_alloc(sizeof(*dtmf_data), info_dtmf_data_destroy);
858         if (!dtmf_data) {
859                 return NULL;
860         }
861         ao2_ref(session, +1);
862         dtmf_data->session = session;
863         dtmf_data->digit = digit;
864         dtmf_data->duration = duration;
865         return dtmf_data;
866 }
867
868 static int transmit_info_dtmf(void *data)
869 {
870         RAII_VAR(struct info_dtmf_data *, dtmf_data, data, ao2_cleanup);
871
872         struct ast_sip_session *session = dtmf_data->session;
873         struct pjsip_tx_data *tdata;
874
875         RAII_VAR(struct ast_str *, body_text, NULL, ast_free_ptr);
876
877         struct ast_sip_body body = {
878                 .type = "application",
879                 .subtype = "dtmf-relay",
880         };
881
882         if (!(body_text = ast_str_create(32))) {
883                 ast_log(LOG_ERROR, "Could not allocate buffer for INFO DTMF.\n");
884                 return -1;
885         }
886         ast_str_set(&body_text, 0, "Signal=%c\r\nDuration=%u\r\n", dtmf_data->digit, dtmf_data->duration);
887
888         body.body_text = ast_str_buffer(body_text);
889
890         if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, &tdata)) {
891                 ast_log(LOG_ERROR, "Could not create DTMF INFO request\n");
892                 return -1;
893         }
894         if (ast_sip_add_body(tdata, &body)) {
895                 ast_log(LOG_ERROR, "Could not add body to DTMF INFO request\n");
896                 pjsip_tx_data_dec_ref(tdata);
897                 return -1;
898         }
899         ast_sip_session_send_request(session, tdata);
900
901         return 0;
902 }
903
904 /*! \brief Function called by core to stop a DTMF digit */
905 static int gulp_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
906 {
907         struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
908         struct ast_sip_session *session = pvt->session;
909         struct ast_sip_session_media *media = pvt->media[SIP_MEDIA_AUDIO];
910         int res = 0;
911
912         switch (session->endpoint->dtmf) {
913         case AST_SIP_DTMF_INFO:
914         {
915                 struct info_dtmf_data *dtmf_data = info_dtmf_data_alloc(session, digit, duration);
916
917                 if (!dtmf_data) {
918                         return -1;
919                 }
920
921                 if (ast_sip_push_task(session->serializer, transmit_info_dtmf, dtmf_data)) {
922                         ast_log(LOG_WARNING, "Error sending DTMF via INFO.\n");
923                         ao2_cleanup(dtmf_data);
924                         return -1;
925                 }
926                 break;
927         }
928         case AST_SIP_DTMF_RFC_4733:
929                 if (!media || !media->rtp) {
930                         return -1;
931                 }
932
933                 ast_rtp_instance_dtmf_end_with_duration(media->rtp, digit, duration);
934         case AST_SIP_DTMF_NONE:
935                 break;
936         case AST_SIP_DTMF_INBAND:
937                 res = -1;
938                 break;
939         }
940
941         return res;
942 }
943
944 static int call(void *data)
945 {
946         pjsip_tx_data *packet;
947         struct ast_sip_session *session = data;
948
949         if (pjsip_inv_invite(session->inv_session, &packet) != PJ_SUCCESS) {
950                 ast_queue_hangup(session->channel);
951         } else {
952                 ast_sip_session_send_request(session, packet);
953         }
954
955         ao2_ref(session, -1);
956
957         return 0;
958 }
959
960 /*! \brief Function called by core to actually start calling a remote party */
961 static int gulp_call(struct ast_channel *ast, const char *dest, int timeout)
962 {
963         struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
964         struct ast_sip_session *session = pvt->session;
965
966         ao2_ref(session, +1);
967         if (ast_sip_push_task(session->serializer, call, session)) {
968                 ast_log(LOG_WARNING, "Error attempting to place outbound call to call '%s'\n", dest);
969                 ao2_cleanup(session);
970                 return -1;
971         }
972
973         return 0;
974 }
975
976 /*! \brief Internal function which translates from Asterisk cause codes to SIP response codes */
977 static int hangup_cause2sip(int cause)
978 {
979         switch (cause) {
980         case AST_CAUSE_UNALLOCATED:             /* 1 */
981         case AST_CAUSE_NO_ROUTE_DESTINATION:    /* 3 IAX2: Can't find extension in context */
982         case AST_CAUSE_NO_ROUTE_TRANSIT_NET:    /* 2 */
983                 return 404;
984         case AST_CAUSE_CONGESTION:              /* 34 */
985         case AST_CAUSE_SWITCH_CONGESTION:       /* 42 */
986                 return 503;
987         case AST_CAUSE_NO_USER_RESPONSE:        /* 18 */
988                 return 408;
989         case AST_CAUSE_NO_ANSWER:               /* 19 */
990         case AST_CAUSE_UNREGISTERED:        /* 20 */
991                 return 480;
992         case AST_CAUSE_CALL_REJECTED:           /* 21 */
993                 return 403;
994         case AST_CAUSE_NUMBER_CHANGED:          /* 22 */
995                 return 410;
996         case AST_CAUSE_NORMAL_UNSPECIFIED:      /* 31 */
997                 return 480;
998         case AST_CAUSE_INVALID_NUMBER_FORMAT:
999                 return 484;
1000         case AST_CAUSE_USER_BUSY:
1001                 return 486;
1002         case AST_CAUSE_FAILURE:
1003                 return 500;
1004         case AST_CAUSE_FACILITY_REJECTED:       /* 29 */
1005                 return 501;
1006         case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
1007                 return 503;
1008         case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
1009                 return 502;
1010         case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL:       /* Can't find codec to connect to host */
1011                 return 488;
1012         case AST_CAUSE_INTERWORKING:    /* Unspecified Interworking issues */
1013                 return 500;
1014         case AST_CAUSE_NOTDEFINED:
1015         default:
1016                 ast_debug(1, "AST hangup cause %d (no match found in PJSIP)\n", cause);
1017                 return 0;
1018         }
1019
1020         /* Never reached */
1021         return 0;
1022 }
1023
1024 struct hangup_data {
1025         int cause;
1026         struct ast_channel *chan;
1027 };
1028
1029 static void hangup_data_destroy(void *obj)
1030 {
1031         struct hangup_data *h_data = obj;
1032
1033         h_data->chan = ast_channel_unref(h_data->chan);
1034 }
1035
1036 static struct hangup_data *hangup_data_alloc(int cause, struct ast_channel *chan)
1037 {
1038         struct hangup_data *h_data = ao2_alloc(sizeof(*h_data), hangup_data_destroy);
1039
1040         if (!h_data) {
1041                 return NULL;
1042         }
1043
1044         h_data->cause = cause;
1045         h_data->chan = ast_channel_ref(chan);
1046
1047         return h_data;
1048 }
1049
1050 static int hangup(void *data)
1051 {
1052         pj_status_t status;
1053         pjsip_tx_data *packet = NULL;
1054         struct hangup_data *h_data = data;
1055         struct ast_channel *ast = h_data->chan;
1056         struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
1057         struct ast_sip_session *session = pvt->session;
1058         int cause = h_data->cause;
1059
1060         if (((status = pjsip_inv_end_session(session->inv_session, cause ? cause : 603, NULL, &packet)) == PJ_SUCCESS) && packet) {
1061                 if (packet->msg->type == PJSIP_RESPONSE_MSG) {
1062                         ast_sip_session_send_response(session, packet);
1063                 } else {
1064                         ast_sip_session_send_request(session, packet);
1065                 }
1066         }
1067
1068         session->channel = NULL;
1069         ast_channel_tech_pvt_set(ast, NULL);
1070
1071         ao2_cleanup(pvt);
1072         ao2_cleanup(h_data);
1073
1074         return 0;
1075 }
1076
1077 /*! \brief Function called by core to hang up a Gulp session */
1078 static int gulp_hangup(struct ast_channel *ast)
1079 {
1080         struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
1081         struct ast_sip_session *session = pvt->session;
1082         int cause = hangup_cause2sip(ast_channel_hangupcause(session->channel));
1083         struct hangup_data *h_data = hangup_data_alloc(cause, ast);
1084
1085         if (!h_data) {
1086                 goto failure;
1087         }
1088
1089         if (ast_sip_push_task(session->serializer, hangup, h_data)) {
1090                 ast_log(LOG_WARNING, "Unable to push hangup task to the threadpool. Expect bad things\n");
1091                 goto failure;
1092         }
1093
1094         return 0;
1095
1096 failure:
1097         /* Go ahead and do our cleanup of the session and channel even if we're not going
1098          * to be able to send our SIP request/response
1099          */
1100         ao2_cleanup(h_data);
1101         session->channel = NULL;
1102         ast_channel_tech_pvt_set(ast, NULL);
1103
1104         ao2_cleanup(pvt);
1105
1106         return -1;
1107 }
1108
1109 struct request_data {
1110         struct ast_sip_session *session;
1111         struct ast_format_cap *caps;
1112         const char *dest;
1113         int cause;
1114 };
1115
1116 static int request(void *obj)
1117 {
1118         struct request_data *req_data = obj;
1119         struct ast_sip_session *session = NULL;
1120         char *tmp = ast_strdupa(req_data->dest), *endpoint_name = NULL, *request_user = NULL;
1121         RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
1122
1123         AST_DECLARE_APP_ARGS(args,
1124                 AST_APP_ARG(endpoint);
1125                 AST_APP_ARG(aor);
1126         );
1127
1128         if (ast_strlen_zero(tmp)) {
1129                 ast_log(LOG_ERROR, "Unable to create Gulp channel with empty destination\n");
1130                 req_data->cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
1131                 return -1;
1132         }
1133
1134         AST_NONSTANDARD_APP_ARGS(args, tmp, '/');
1135
1136         /* If a request user has been specified extract it from the endpoint name portion */
1137         if ((endpoint_name = strchr(args.endpoint, '@'))) {
1138                 request_user = args.endpoint;
1139                 *endpoint_name++ = '\0';
1140         } else {
1141                 endpoint_name = args.endpoint;
1142         }
1143
1144         if (ast_strlen_zero(endpoint_name)) {
1145                 ast_log(LOG_ERROR, "Unable to create Gulp channel with empty endpoint name\n");
1146                 req_data->cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
1147         } else if (!(endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", endpoint_name))) {
1148                 ast_log(LOG_ERROR, "Unable to create Gulp channel - endpoint '%s' was not found\n", endpoint_name);
1149                 req_data->cause = AST_CAUSE_NO_ROUTE_DESTINATION;
1150                 return -1;
1151         }
1152
1153         if (!(session = ast_sip_session_create_outgoing(endpoint, args.aor, request_user, req_data->caps))) {
1154                 req_data->cause = AST_CAUSE_NO_ROUTE_DESTINATION;
1155                 return -1;
1156         }
1157
1158         req_data->session = session;
1159
1160         return 0;
1161 }
1162
1163 /*! \brief Function called by core to create a new outgoing Gulp session */
1164 static struct ast_channel *gulp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
1165 {
1166         struct request_data req_data;
1167         struct ast_sip_session *session;
1168
1169         req_data.caps = cap;
1170         req_data.dest = data;
1171
1172         if (ast_sip_push_task_synchronous(NULL, request, &req_data)) {
1173                 *cause = req_data.cause;
1174                 return NULL;
1175         }
1176
1177         session = req_data.session;
1178
1179         if (!(session->channel = gulp_new(session, AST_STATE_DOWN, NULL, NULL, requestor ? ast_channel_linkedid(requestor) : NULL, NULL))) {
1180                 /* Session needs to be terminated prematurely */
1181                 return NULL;
1182         }
1183
1184         return session->channel;
1185 }
1186
1187 /*! \brief Function called by core to send text on Gulp session */
1188 static int gulp_sendtext(struct ast_channel *ast, const char *text)
1189 {
1190         return 0;
1191 }
1192
1193 /*! \brief Convert SIP hangup causes to Asterisk hangup causes */
1194 static int hangup_sip2cause(int cause)
1195 {
1196         /* Possible values taken from causes.h */
1197
1198         switch(cause) {
1199         case 401:       /* Unauthorized */
1200                 return AST_CAUSE_CALL_REJECTED;
1201         case 403:       /* Not found */
1202                 return AST_CAUSE_CALL_REJECTED;
1203         case 404:       /* Not found */
1204                 return AST_CAUSE_UNALLOCATED;
1205         case 405:       /* Method not allowed */
1206                 return AST_CAUSE_INTERWORKING;
1207         case 407:       /* Proxy authentication required */
1208                 return AST_CAUSE_CALL_REJECTED;
1209         case 408:       /* No reaction */
1210                 return AST_CAUSE_NO_USER_RESPONSE;
1211         case 409:       /* Conflict */
1212                 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
1213         case 410:       /* Gone */
1214                 return AST_CAUSE_NUMBER_CHANGED;
1215         case 411:       /* Length required */
1216                 return AST_CAUSE_INTERWORKING;
1217         case 413:       /* Request entity too large */
1218                 return AST_CAUSE_INTERWORKING;
1219         case 414:       /* Request URI too large */
1220                 return AST_CAUSE_INTERWORKING;
1221         case 415:       /* Unsupported media type */
1222                 return AST_CAUSE_INTERWORKING;
1223         case 420:       /* Bad extension */
1224                 return AST_CAUSE_NO_ROUTE_DESTINATION;
1225         case 480:       /* No answer */
1226                 return AST_CAUSE_NO_ANSWER;
1227         case 481:       /* No answer */
1228                 return AST_CAUSE_INTERWORKING;
1229         case 482:       /* Loop detected */
1230                 return AST_CAUSE_INTERWORKING;
1231         case 483:       /* Too many hops */
1232                 return AST_CAUSE_NO_ANSWER;
1233         case 484:       /* Address incomplete */
1234                 return AST_CAUSE_INVALID_NUMBER_FORMAT;
1235         case 485:       /* Ambiguous */
1236                 return AST_CAUSE_UNALLOCATED;
1237         case 486:       /* Busy everywhere */
1238                 return AST_CAUSE_BUSY;
1239         case 487:       /* Request terminated */
1240                 return AST_CAUSE_INTERWORKING;
1241         case 488:       /* No codecs approved */
1242                 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
1243         case 491:       /* Request pending */
1244                 return AST_CAUSE_INTERWORKING;
1245         case 493:       /* Undecipherable */
1246                 return AST_CAUSE_INTERWORKING;
1247         case 500:       /* Server internal failure */
1248                 return AST_CAUSE_FAILURE;
1249         case 501:       /* Call rejected */
1250                 return AST_CAUSE_FACILITY_REJECTED;
1251         case 502:
1252                 return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
1253         case 503:       /* Service unavailable */
1254                 return AST_CAUSE_CONGESTION;
1255         case 504:       /* Gateway timeout */
1256                 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
1257         case 505:       /* SIP version not supported */
1258                 return AST_CAUSE_INTERWORKING;
1259         case 600:       /* Busy everywhere */
1260                 return AST_CAUSE_USER_BUSY;
1261         case 603:       /* Decline */
1262                 return AST_CAUSE_CALL_REJECTED;
1263         case 604:       /* Does not exist anywhere */
1264                 return AST_CAUSE_UNALLOCATED;
1265         case 606:       /* Not acceptable */
1266                 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
1267         default:
1268                 if (cause < 500 && cause >= 400) {
1269                         /* 4xx class error that is unknown - someting wrong with our request */
1270                         return AST_CAUSE_INTERWORKING;
1271                 } else if (cause < 600 && cause >= 500) {
1272                         /* 5xx class error - problem in the remote end */
1273                         return AST_CAUSE_CONGESTION;
1274                 } else if (cause < 700 && cause >= 600) {
1275                         /* 6xx - global errors in the 4xx class */
1276                         return AST_CAUSE_INTERWORKING;
1277                 }
1278                 return AST_CAUSE_NORMAL;
1279         }
1280         /* Never reached */
1281         return 0;
1282 }
1283
1284 static void gulp_session_begin(struct ast_sip_session *session)
1285 {
1286         RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
1287
1288         if (session->endpoint->direct_media_glare_mitigation ==
1289                         AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE) {
1290                 return;
1291         }
1292
1293         datastore = ast_sip_session_alloc_datastore(&direct_media_mitigation_info,
1294                         "direct_media_glare_mitigation");
1295
1296         if (!datastore) {
1297                 return;
1298         }
1299
1300         ast_sip_session_add_datastore(session, datastore);
1301 }
1302
1303 /*! \brief Function called when the session ends */
1304 static void gulp_session_end(struct ast_sip_session *session)
1305 {
1306         if (!session->channel) {
1307                 return;
1308         }
1309
1310         if (!ast_channel_hangupcause(session->channel) && session->inv_session) {
1311                 int cause = hangup_sip2cause(session->inv_session->cause);
1312
1313                 ast_queue_hangup_with_cause(session->channel, cause);
1314         } else {
1315                 ast_queue_hangup(session->channel);
1316         }
1317 }
1318
1319 /*! \brief Function called when a request is received on the session */
1320 static int gulp_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
1321 {
1322         pjsip_tx_data *packet = NULL;
1323         int res = AST_PBX_FAILED;
1324
1325         if (session->channel) {
1326                 return 0;
1327         }
1328
1329         if (!(session->channel = gulp_new(session, AST_STATE_DOWN, session->exten, NULL, NULL, NULL))) {
1330                 if (pjsip_inv_end_session(session->inv_session, 503, NULL, &packet) == PJ_SUCCESS) {
1331                         ast_sip_session_send_response(session, packet);
1332                 }
1333
1334                 ast_log(LOG_ERROR, "Failed to allocate new GULP channel on incoming SIP INVITE\n");
1335                 return -1;
1336         }
1337
1338         ast_setstate(session->channel, AST_STATE_RING);
1339         res = ast_pbx_start(session->channel);
1340
1341         switch (res) {
1342         case AST_PBX_FAILED:
1343                 ast_log(LOG_WARNING, "Failed to start PBX ;(\n");
1344                 ast_channel_hangupcause_set(session->channel, AST_CAUSE_SWITCH_CONGESTION);
1345                 ast_hangup(session->channel);
1346                 break;
1347         case AST_PBX_CALL_LIMIT:
1348                 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
1349                 ast_channel_hangupcause_set(session->channel, AST_CAUSE_SWITCH_CONGESTION);
1350                 ast_hangup(session->channel);
1351                 break;
1352         case AST_PBX_SUCCESS:
1353         default:
1354                 break;
1355         }
1356
1357         ast_debug(3, "Started PBX on new GULP channel %s\n", ast_channel_name(session->channel));
1358
1359         return (res == AST_PBX_SUCCESS) ? 0 : -1;
1360 }
1361
1362 /*! \brief Function called when a response is received on the session */
1363 static void gulp_incoming_response(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
1364 {
1365         struct pjsip_status_line status = rdata->msg_info.msg->line.status;
1366
1367         if (!session->channel) {
1368                 return;
1369         }
1370
1371         switch (status.code) {
1372         case 180:
1373                 ast_queue_control(session->channel, AST_CONTROL_RINGING);
1374                 if (ast_channel_state(session->channel) != AST_STATE_UP) {
1375                         ast_setstate(session->channel, AST_STATE_RINGING);
1376                 }
1377                 break;
1378         case 183:
1379                 ast_queue_control(session->channel, AST_CONTROL_PROGRESS);
1380                 break;
1381         case 200:
1382                 ast_queue_control(session->channel, AST_CONTROL_ANSWER);
1383                 break;
1384         default:
1385                 break;
1386         }
1387 }
1388
1389 static int gulp_incoming_ack(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
1390 {
1391         if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) {
1392                 if (session->endpoint->direct_media) {
1393                         ast_queue_control(session->channel, AST_CONTROL_SRCCHANGE);
1394                 }
1395         }
1396         return 0;
1397 }
1398
1399 /*!
1400  * \brief Load the module
1401  *
1402  * Module loading including tests for configuration or dependencies.
1403  * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
1404  * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
1405  * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the 
1406  * configuration file or other non-critical problem return 
1407  * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
1408  */
1409 static int load_module(void)
1410 {
1411         if (!(gulp_tech.capabilities = ast_format_cap_alloc())) {
1412                 return AST_MODULE_LOAD_DECLINE;
1413         }
1414
1415         ast_format_cap_add_all_by_type(gulp_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
1416
1417         ast_rtp_glue_register(&gulp_rtp_glue);
1418
1419         if (ast_channel_register(&gulp_tech)) {
1420                 ast_log(LOG_ERROR, "Unable to register channel class %s\n", channel_type);
1421                 goto end;
1422         }
1423
1424         if (ast_custom_function_register(&gulp_dial_contacts_function)) {
1425                 ast_log(LOG_ERROR, "Unable to register GULP_DIAL_CONTACTS dialplan function\n");
1426                 goto end;
1427         }
1428
1429         if (ast_sip_session_register_supplement(&gulp_supplement)) {
1430                 ast_log(LOG_ERROR, "Unable to register Gulp supplement\n");
1431                 goto end;
1432         }
1433
1434         if (ast_sip_session_register_supplement(&gulp_ack_supplement)) {
1435                 ast_log(LOG_ERROR, "Unable to register Gulp ACK supplement\n");
1436                 ast_sip_session_unregister_supplement(&gulp_supplement);
1437                 goto end;
1438         }
1439
1440         return 0;
1441
1442 end:
1443         ast_custom_function_unregister(&gulp_dial_contacts_function);
1444         ast_channel_unregister(&gulp_tech);
1445         ast_rtp_glue_unregister(&gulp_rtp_glue);
1446
1447         return AST_MODULE_LOAD_FAILURE;
1448 }
1449
1450 /*! \brief Reload module */
1451 static int reload(void)
1452 {
1453         return -1;
1454 }
1455
1456 /*! \brief Unload the Gulp channel from Asterisk */
1457 static int unload_module(void)
1458 {
1459         ast_sip_session_unregister_supplement(&gulp_supplement);
1460         ast_custom_function_unregister(&gulp_dial_contacts_function);
1461         ast_channel_unregister(&gulp_tech);
1462         ast_rtp_glue_unregister(&gulp_rtp_glue);
1463
1464         return 0;
1465 }
1466
1467 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Gulp SIP Channel Driver",
1468                 .load = load_module,
1469                 .unload = unload_module,
1470                 .reload = reload,
1471                 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
1472                );