Skip any non-content information when looking for and handling content.
[asterisk/asterisk.git] / channels / chan_motif.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2012, 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 Motif Jingle Channel Driver
24  *
25  * \extref Iksemel http://iksemel.jabberstudio.org/
26  *
27  * \ingroup channel_drivers
28  */
29
30 /*** MODULEINFO
31         <depend>iksemel</depend>
32         <depend>res_xmpp</depend>
33         <use type="external">openssl</use>
34         <support_level>core</support_level>
35  ***/
36
37 #include "asterisk.h"
38
39 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
40
41 #include <sys/socket.h>
42 #include <fcntl.h>
43 #include <netdb.h>
44 #include <netinet/in.h>
45 #include <arpa/inet.h>
46 #include <sys/signal.h>
47 #include <iksemel.h>
48 #include <pthread.h>
49
50 #include "asterisk/lock.h"
51 #include "asterisk/channel.h"
52 #include "asterisk/config_options.h"
53 #include "asterisk/module.h"
54 #include "asterisk/pbx.h"
55 #include "asterisk/sched.h"
56 #include "asterisk/io.h"
57 #include "asterisk/rtp_engine.h"
58 #include "asterisk/acl.h"
59 #include "asterisk/callerid.h"
60 #include "asterisk/file.h"
61 #include "asterisk/cli.h"
62 #include "asterisk/app.h"
63 #include "asterisk/musiconhold.h"
64 #include "asterisk/manager.h"
65 #include "asterisk/stringfields.h"
66 #include "asterisk/utils.h"
67 #include "asterisk/causes.h"
68 #include "asterisk/astobj.h"
69 #include "asterisk/abstract_jb.h"
70 #include "asterisk/xmpp.h"
71
72 /*! \brief Default maximum number of ICE candidates we will offer */
73 #define DEFAULT_MAX_ICE_CANDIDATES "10"
74
75 /*! \brief Default maximum number of payloads we will offer */
76 #define DEFAULT_MAX_PAYLOADS "30"
77
78 /*! \brief Number of buckets for endpoints */
79 #define ENDPOINT_BUCKETS 37
80
81 /*! \brief Number of buckets for sessions, on a per-endpoint basis */
82 #define SESSION_BUCKETS 37
83
84 /*! \brief Namespace for Jingle itself */
85 #define JINGLE_NS "urn:xmpp:jingle:1"
86
87 /*! \brief Namespace for Jingle RTP sessions */
88 #define JINGLE_RTP_NS "urn:xmpp:jingle:apps:rtp:1"
89
90 /*! \brief Namespace for Jingle RTP info */
91 #define JINGLE_RTP_INFO_NS "urn:xmpp:jingle:apps:rtp:info:1"
92
93 /*! \brief Namespace for Jingle ICE-UDP */
94 #define JINGLE_ICE_UDP_NS "urn:xmpp:jingle:transports:ice-udp:1"
95
96 /*! \brief Namespace for Google Talk ICE-UDP */
97 #define GOOGLE_TRANSPORT_NS "http://www.google.com/transport/p2p"
98
99 /*! \brief Namespace for Google Talk Raw UDP */
100 #define GOOGLE_TRANSPORT_RAW_NS "http://www.google.com/transport/raw-udp"
101
102 /*! \brief Namespace for Google Session */
103 #define GOOGLE_SESSION_NS "http://www.google.com/session"
104
105 /*! \brief Namespace for Google Phone description */
106 #define GOOGLE_PHONE_NS "http://www.google.com/session/phone"
107
108 /*! \brief Namespace for Google Video description */
109 #define GOOGLE_VIDEO_NS "http://www.google.com/session/video"
110
111 /*! \brief Namespace for XMPP stanzas */
112 #define XMPP_STANZAS_NS "urn:ietf:params:xml:ns:xmpp-stanzas"
113
114 /*! \brief The various transport methods supported, from highest priority to lowest priority when doing fallback */
115 enum jingle_transport {
116         JINGLE_TRANSPORT_ICE_UDP = 3,   /*!< XEP-0176 */
117         JINGLE_TRANSPORT_GOOGLE_V2 = 2, /*!< https://developers.google.com/talk/call_signaling */
118         JINGLE_TRANSPORT_GOOGLE_V1 = 1, /*!< Undocumented initial Google specification */
119         JINGLE_TRANSPORT_NONE = 0,      /*!< No transport specified */
120 };
121
122 /*! \brief Endpoint state information */
123 struct jingle_endpoint_state {
124         struct ao2_container *sessions; /*!< Active sessions to or from the endpoint */
125 };
126
127 /*! \brief Endpoint which contains configuration information and active sessions */
128 struct jingle_endpoint {
129         AST_DECLARE_STRING_FIELDS(
130                 AST_STRING_FIELD(name);              /*!< Name of the endpoint */
131                 AST_STRING_FIELD(context);           /*!< Context to place incoming calls into */
132                 AST_STRING_FIELD(accountcode);       /*!< Account code */
133                 AST_STRING_FIELD(language);          /*!< Default language for prompts */
134                 AST_STRING_FIELD(musicclass);        /*!< Configured music on hold class */
135                 AST_STRING_FIELD(parkinglot);        /*!< Configured parking lot */
136                 );
137         struct ast_xmpp_client *connection;     /*!< Connection to use for traffic */
138         iksrule *rule;                          /*!< Active matching rule */
139         unsigned int maxicecandidates;          /*!< Maximum number of ICE candidates we will offer */
140         unsigned int maxpayloads;               /*!< Maximum number of payloads we will offer */
141         struct ast_codec_pref prefs;            /*!< Codec preferences */
142         struct ast_format_cap *cap;             /*!< Formats to use */
143         ast_group_t callgroup;                  /*!< Call group */
144         ast_group_t pickupgroup;                /*!< Pickup group */
145         enum jingle_transport transport;        /*!< Default transport to use on outgoing sessions */
146         struct jingle_endpoint_state *state;    /*!< Endpoint state information */
147 };
148
149 /*! \brief Session which contains information about an active session */
150 struct jingle_session {
151         AST_DECLARE_STRING_FIELDS(
152                 AST_STRING_FIELD(sid);        /*!< Session identifier */
153                 AST_STRING_FIELD(audio_name); /*!< Name of the audio content */
154                 AST_STRING_FIELD(video_name); /*!< Name of the video content */
155                 );
156         struct jingle_endpoint_state *state;  /*!< Endpoint we are associated with */
157         struct ast_xmpp_client *connection;   /*!< Connection to use for traffic */
158         enum jingle_transport transport;      /*!< Transport type to use for this session */
159         unsigned int maxicecandidates;        /*!< Maximum number of ICE candidates we will offer */
160         unsigned int maxpayloads;             /*!< Maximum number of payloads we will offer */
161         char remote_original[XMPP_MAX_JIDLEN];/*!< Identifier of the original remote party (remote may have changed due to redirect) */
162         char remote[XMPP_MAX_JIDLEN];         /*!< Identifier of the remote party */
163         iksrule *rule;                        /*!< Session matching rule */
164         struct ast_codec_pref prefs;          /*!< Codec preferences */
165         struct ast_channel *owner;            /*!< Master Channel */
166         struct ast_rtp_instance *rtp;         /*!< RTP audio session */
167         struct ast_rtp_instance *vrtp;        /*!< RTP video session */
168         struct ast_format_cap *cap;           /*!< Local codec capabilities */
169         struct ast_format_cap *jointcap;      /*!< Joint codec capabilities */
170         struct ast_format_cap *peercap;       /*!< Peer codec capabilities */
171         unsigned int outgoing:1;              /*!< Whether this is an outgoing leg or not */
172         unsigned int gone:1;                  /*!< In the eyes of Jingle this session is already gone */
173         struct ast_callid *callid;            /*!< Bound session call-id */
174 };
175
176 static const char desc[] = "Motif Jingle Channel";
177 static const char channel_type[] = "Motif";
178
179 struct jingle_config {
180         struct ao2_container *endpoints; /*!< Configured endpoints */
181 };
182
183 static AO2_GLOBAL_OBJ_STATIC(globals);
184
185 static struct ast_sched_context *sched; /*!< Scheduling context for RTCP */
186
187 /* \brief Asterisk core interaction functions */
188 static struct ast_channel *jingle_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
189 static int jingle_sendtext(struct ast_channel *ast, const char *text);
190 static int jingle_digit_begin(struct ast_channel *ast, char digit);
191 static int jingle_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
192 static int jingle_call(struct ast_channel *ast, const char *dest, int timeout);
193 static int jingle_hangup(struct ast_channel *ast);
194 static int jingle_answer(struct ast_channel *ast);
195 static struct ast_frame *jingle_read(struct ast_channel *ast);
196 static int jingle_write(struct ast_channel *ast, struct ast_frame *f);
197 static int jingle_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
198 static int jingle_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
199 static struct jingle_session *jingle_alloc(struct jingle_endpoint *endpoint, const char *from, const char *sid);
200
201 /*! \brief Action handlers */
202 static void jingle_action_session_initiate(struct jingle_endpoint *endpoint, struct jingle_session *session, ikspak *pak);
203 static void jingle_action_transport_info(struct jingle_endpoint *endpoint, struct jingle_session *session, ikspak *pak);
204 static void jingle_action_session_accept(struct jingle_endpoint *endpoint, struct jingle_session *session, ikspak *pak);
205 static void jingle_action_session_info(struct jingle_endpoint *endpoint, struct jingle_session *session, ikspak *pak);
206 static void jingle_action_session_terminate(struct jingle_endpoint *endpoint, struct jingle_session *session, ikspak *pak);
207
208 /*! \brief PBX interface structure for channel registration */
209 static struct ast_channel_tech jingle_tech = {
210         .type = "Motif",
211         .description = "Motif Jingle Channel Driver",
212         .requester = jingle_request,
213         .send_text = jingle_sendtext,
214         .send_digit_begin = jingle_digit_begin,
215         .send_digit_end = jingle_digit_end,
216         .bridge = ast_rtp_instance_bridge,
217         .call = jingle_call,
218         .hangup = jingle_hangup,
219         .answer = jingle_answer,
220         .read = jingle_read,
221         .write = jingle_write,
222         .write_video = jingle_write,
223         .exception = jingle_read,
224         .indicate = jingle_indicate,
225         .fixup = jingle_fixup,
226         .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER
227 };
228
229 /*! \brief Defined handlers for different Jingle actions */
230 static const struct jingle_action_handler {
231         const char *action;
232         void (*handler)(struct jingle_endpoint *endpoint, struct jingle_session *session, ikspak *pak);
233 } jingle_action_handlers[] = {
234         /* Jingle actions */
235         { "session-initiate", jingle_action_session_initiate, },
236         { "transport-info", jingle_action_transport_info, },
237         { "session-accept", jingle_action_session_accept, },
238         { "session-info", jingle_action_session_info, },
239         { "session-terminate", jingle_action_session_terminate, },
240         /* Google-V1 actions */
241         { "initiate", jingle_action_session_initiate, },
242         { "candidates", jingle_action_transport_info, },
243         { "accept", jingle_action_session_accept, },
244         { "terminate", jingle_action_session_terminate, },
245         { "reject", jingle_action_session_terminate, },
246 };
247
248 /*! \brief Reason text <-> cause code mapping */
249 static const struct jingle_reason_mapping {
250         const char *reason;
251         int cause;
252 } jingle_reason_mappings[] = {
253         { "busy", AST_CAUSE_BUSY, },
254         { "cancel", AST_CAUSE_CALL_REJECTED, },
255         { "connectivity-error", AST_CAUSE_INTERWORKING, },
256         { "decline", AST_CAUSE_CALL_REJECTED, },
257         { "expired", AST_CAUSE_NO_USER_RESPONSE, },
258         { "failed-transport", AST_CAUSE_PROTOCOL_ERROR, },
259         { "failed-application", AST_CAUSE_SWITCH_CONGESTION, },
260         { "general-error", AST_CAUSE_CONGESTION, },
261         { "gone", AST_CAUSE_NORMAL_CLEARING, },
262         { "incompatible-parameters", AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, },
263         { "media-error", AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, },
264         { "security-error", AST_CAUSE_PROTOCOL_ERROR, },
265         { "success", AST_CAUSE_NORMAL_CLEARING, },
266         { "timeout", AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, },
267         { "unsupported-applications", AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, },
268         { "unsupported-transports", AST_CAUSE_FACILITY_NOT_IMPLEMENTED, },
269 };
270
271 /*! \brief Hashing function for Jingle sessions */
272 static int jingle_session_hash(const void *obj, const int flags)
273 {
274         const struct jingle_session *session = obj;
275         const char *sid = obj;
276
277         return ast_str_hash(flags & OBJ_KEY ? sid : session->sid);
278 }
279
280 /*! \brief Comparator function for Jingle sessions */
281 static int jingle_session_cmp(void *obj, void *arg, int flags)
282 {
283         struct jingle_session *session1 = obj, *session2 = arg;
284         const char *sid = arg;
285
286         return !strcmp(session1->sid, flags & OBJ_KEY ? sid : session2->sid) ? CMP_MATCH | CMP_STOP : 0;
287 }
288
289 /*! \brief Destructor for Jingle endpoint state */
290 static void jingle_endpoint_state_destructor(void *obj)
291 {
292         struct jingle_endpoint_state *state = obj;
293
294         ao2_ref(state->sessions, -1);
295 }
296
297 /*! \brief Destructor for Jingle endpoints */
298 static void jingle_endpoint_destructor(void *obj)
299 {
300         struct jingle_endpoint *endpoint = obj;
301
302         if (endpoint->rule) {
303                 iks_filter_remove_rule(endpoint->connection->filter, endpoint->rule);
304         }
305
306         if (endpoint->connection) {
307                 ast_xmpp_client_unref(endpoint->connection);
308         }
309
310         ast_format_cap_destroy(endpoint->cap);
311
312         ao2_ref(endpoint->state, -1);
313
314         ast_string_field_free_memory(endpoint);
315 }
316
317 /*! \brief Find function for Jingle endpoints */
318 static void *jingle_endpoint_find(struct ao2_container *tmp_container, const char *category)
319 {
320         return ao2_find(tmp_container, category, OBJ_KEY);
321 }
322
323 /*! \brief Allocator function for Jingle endpoint state */
324 static struct jingle_endpoint_state *jingle_endpoint_state_create(void)
325 {
326         struct jingle_endpoint_state *state;
327
328         if (!(state = ao2_alloc(sizeof(*state), jingle_endpoint_state_destructor))) {
329                 return NULL;
330         }
331
332         if (!(state->sessions = ao2_container_alloc(SESSION_BUCKETS, jingle_session_hash, jingle_session_cmp))) {
333                 ao2_ref(state, -1);
334                 return NULL;
335         }
336
337         return state;
338 }
339
340 /*! \brief State find/create function */
341 static struct jingle_endpoint_state *jingle_endpoint_state_find_or_create(const char *category)
342 {
343         RAII_VAR(struct jingle_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
344         RAII_VAR(struct jingle_endpoint *, endpoint, NULL, ao2_cleanup);
345
346         if (!cfg || !cfg->endpoints || !(endpoint = jingle_endpoint_find(cfg->endpoints, category))) {
347                 return jingle_endpoint_state_create();
348         }
349
350         ao2_ref(endpoint->state, +1);
351         return endpoint->state;
352 }
353
354 /*! \brief Allocator function for Jingle endpoints */
355 static void *jingle_endpoint_alloc(const char *cat)
356 {
357         struct jingle_endpoint *endpoint;
358
359         if (!(endpoint = ao2_alloc(sizeof(*endpoint), jingle_endpoint_destructor))) {
360                 return NULL;
361         }
362
363         if (ast_string_field_init(endpoint, 512)) {
364                 ao2_ref(endpoint, -1);
365                 return NULL;
366         }
367
368         if (!(endpoint->state = jingle_endpoint_state_find_or_create(cat))) {
369                 ao2_ref(endpoint, -1);
370                 return NULL;
371         }
372
373         ast_string_field_set(endpoint, name, cat);
374
375         endpoint->cap = ast_format_cap_alloc_nolock();
376         endpoint->transport = JINGLE_TRANSPORT_ICE_UDP;
377
378         return endpoint;
379 }
380
381 /*! \brief Hashing function for Jingle endpoints */
382 static int jingle_endpoint_hash(const void *obj, const int flags)
383 {
384         const struct jingle_endpoint *endpoint = obj;
385         const char *name = obj;
386
387         return ast_str_hash(flags & OBJ_KEY ? name : endpoint->name);
388 }
389
390 /*! \brief Comparator function for Jingle endpoints */
391 static int jingle_endpoint_cmp(void *obj, void *arg, int flags)
392 {
393         struct jingle_endpoint *endpoint1 = obj, *endpoint2 = arg;
394         const char *name = arg;
395
396         return !strcmp(endpoint1->name, flags & OBJ_KEY ? name : endpoint2->name) ? CMP_MATCH | CMP_STOP : 0;
397 }
398
399 static struct aco_type endpoint_option = {
400         .type = ACO_ITEM,
401         .category_match = ACO_BLACKLIST,
402         .category = "^general$",
403         .item_alloc = jingle_endpoint_alloc,
404         .item_find = jingle_endpoint_find,
405         .item_offset = offsetof(struct jingle_config, endpoints),
406 };
407
408 struct aco_type *endpoint_options[] = ACO_TYPES(&endpoint_option);
409
410 struct aco_file jingle_conf = {
411         .filename = "motif.conf",
412         .types = ACO_TYPES(&endpoint_option),
413 };
414
415 /*! \brief Destructor for Jingle sessions */
416 static void jingle_session_destructor(void *obj)
417 {
418         struct jingle_session *session = obj;
419
420         if (session->rule) {
421                 iks_filter_remove_rule(session->connection->filter, session->rule);
422         }
423
424         if (session->connection) {
425                 ast_xmpp_client_unref(session->connection);
426         }
427
428         if (session->rtp) {
429                 ast_rtp_instance_destroy(session->rtp);
430         }
431
432         if (session->vrtp) {
433                 ast_rtp_instance_destroy(session->vrtp);
434         }
435
436         ast_format_cap_destroy(session->cap);
437         ast_format_cap_destroy(session->jointcap);
438         ast_format_cap_destroy(session->peercap);
439
440         if (session->callid) {
441                 ast_callid_unref(session->callid);
442         }
443
444         ast_string_field_free_memory(session);
445 }
446
447 /*! \brief Destructor called when module configuration goes away */
448 static void jingle_config_destructor(void *obj)
449 {
450         struct jingle_config *cfg = obj;
451         ao2_cleanup(cfg->endpoints);
452 }
453
454 /*! \brief Allocator called when module configuration should appear */
455 static void *jingle_config_alloc(void)
456 {
457         struct jingle_config *cfg;
458
459         if (!(cfg = ao2_alloc(sizeof(*cfg), jingle_config_destructor))) {
460                 return NULL;
461         }
462
463         if (!(cfg->endpoints = ao2_container_alloc(ENDPOINT_BUCKETS, jingle_endpoint_hash, jingle_endpoint_cmp))) {
464                 ao2_ref(cfg, -1);
465                 return NULL;
466         }
467
468         return cfg;
469 }
470
471 CONFIG_INFO_STANDARD(cfg_info, globals, jingle_config_alloc,
472                      .files = ACO_FILES(&jingle_conf),
473         );
474
475 /*! \brief Function called by RTP engine to get local RTP peer */
476 static enum ast_rtp_glue_result jingle_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
477 {
478         struct jingle_session *session = ast_channel_tech_pvt(chan);
479         enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL;
480
481         if (!session->rtp) {
482                 return AST_RTP_GLUE_RESULT_FORBID;
483         }
484
485         ao2_ref(session->rtp, +1);
486         *instance = session->rtp;
487
488         return res;
489 }
490
491 /*! \brief Function called by RTP engine to get peer capabilities */
492 static void jingle_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
493 {
494 }
495
496 /*! \brief Function called by RTP engine to change where the remote party should send media */
497 static int jingle_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *tpeer, const struct ast_format_cap *cap, int nat_active)
498 {
499         return -1;
500 }
501
502 /*! \brief Local glue for interacting with the RTP engine core */
503 static struct ast_rtp_glue jingle_rtp_glue = {
504         .type = "Motif",
505         .get_rtp_info = jingle_get_rtp_peer,
506         .get_codec = jingle_get_codec,
507         .update_peer = jingle_set_rtp_peer,
508 };
509
510 /*! \brief Internal helper function which enables video support on a sesson if possible */
511 static void jingle_enable_video(struct jingle_session *session)
512 {
513         struct ast_sockaddr tmp;
514         struct ast_rtp_engine_ice *ice;
515
516         /* If video is already present don't do anything */
517         if (session->vrtp) {
518                 return;
519         }
520
521         /* If there are no configured video codecs do not turn video support on, it just won't work */
522         if (!ast_format_cap_has_type(session->cap, AST_FORMAT_TYPE_VIDEO)) {
523                 return;
524         }
525
526         ast_sockaddr_parse(&tmp, "0.0.0.0", 0);
527
528         if (!(session->vrtp = ast_rtp_instance_new("asterisk", sched, &tmp, NULL))) {
529                 return;
530         }
531
532         ast_rtp_instance_set_prop(session->vrtp, AST_RTP_PROPERTY_RTCP, 1);
533
534         ast_channel_set_fd(session->owner, 2, ast_rtp_instance_fd(session->vrtp, 0));
535         ast_channel_set_fd(session->owner, 3, ast_rtp_instance_fd(session->vrtp, 1));
536         ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(session->vrtp), session->vrtp, &session->prefs);
537
538         if (session->transport == JINGLE_TRANSPORT_GOOGLE_V2 && (ice = ast_rtp_instance_get_ice(session->vrtp))) {
539                 ice->stop(session->vrtp);
540         }
541 }
542
543 /*! \brief Internal helper function used to allocate Jingle session on an endpoint */
544 static struct jingle_session *jingle_alloc(struct jingle_endpoint *endpoint, const char *from, const char *sid)
545 {
546         struct jingle_session *session;
547         struct ast_callid *callid;
548         struct ast_sockaddr tmp;
549
550         if (!(session = ao2_alloc(sizeof(*session), jingle_session_destructor))) {
551                 return NULL;
552         }
553
554         callid = ast_read_threadstorage_callid();
555         session->callid = (callid ? callid : ast_create_callid());
556
557         if (ast_string_field_init(session, 512)) {
558                 ao2_ref(session, -1);
559                 return NULL;
560         }
561
562         if (!ast_strlen_zero(from)) {
563                 ast_copy_string(session->remote_original, from, sizeof(session->remote_original));
564                 ast_copy_string(session->remote, from, sizeof(session->remote));
565         }
566
567         if (ast_strlen_zero(sid)) {
568                 ast_string_field_build(session, sid, "%08lx%08lx", ast_random(), ast_random());
569                 session->outgoing = 1;
570                 ast_string_field_set(session, audio_name, "audio");
571                 ast_string_field_set(session, video_name, "video");
572         } else {
573                 ast_string_field_set(session, sid, sid);
574         }
575
576         ao2_ref(endpoint->state, +1);
577         session->state = endpoint->state;
578         ao2_ref(endpoint->connection, +1);
579         session->connection = endpoint->connection;
580         session->transport = endpoint->transport;
581
582         if (!(session->cap = ast_format_cap_alloc_nolock()) ||
583             !(session->jointcap = ast_format_cap_alloc_nolock()) ||
584             !(session->peercap = ast_format_cap_alloc_nolock()) ||
585             !session->callid) {
586                 ao2_ref(session, -1);
587                 return NULL;
588         }
589
590         ast_format_cap_copy(session->cap, endpoint->cap);
591
592         /* While we rely on res_xmpp for communication we still need a temporary ast_sockaddr to tell the RTP engine
593          * that we want IPv4 */
594         ast_sockaddr_parse(&tmp, "0.0.0.0", 0);
595
596         /* Sessions always carry audio, but video is optional so don't enable it here */
597         if (!(session->rtp = ast_rtp_instance_new("asterisk", sched, &tmp, NULL))) {
598                 ao2_ref(session, -1);
599                 return NULL;
600         }
601         ast_rtp_instance_set_prop(session->rtp, AST_RTP_PROPERTY_RTCP, 1);
602         ast_rtp_instance_set_prop(session->rtp, AST_RTP_PROPERTY_DTMF, 1);
603
604         memcpy(&session->prefs, &endpoint->prefs, sizeof(session->prefs));
605
606         session->maxicecandidates = endpoint->maxicecandidates;
607         session->maxpayloads = endpoint->maxpayloads;
608
609         return session;
610 }
611
612 /*! \brief Function called to create a new Jingle Asterisk channel */
613 static struct ast_channel *jingle_new(struct jingle_endpoint *endpoint, struct jingle_session *session, int state, const char *title, const char *linkedid, const char *cid_name)
614 {
615         struct ast_channel *chan;
616         const char *str = S_OR(title, session->remote);
617         struct ast_format tmpfmt;
618
619         if (ast_format_cap_is_empty(session->cap)) {
620                 return NULL;
621         }
622
623         if (!(chan = ast_channel_alloc(1, state, S_OR(title, ""), S_OR(cid_name, ""), "", "", "", linkedid, 0, "Motif/%s-%04lx", str, ast_random() & 0xffff))) {
624                 return NULL;
625         }
626
627         ast_channel_tech_set(chan, &jingle_tech);
628         ast_channel_tech_pvt_set(chan, session);
629         session->owner = chan;
630
631         ast_channel_callid_set(chan, session->callid);
632
633         ast_format_cap_copy(ast_channel_nativeformats(chan), session->cap);
634         ast_codec_choose(&session->prefs, session->cap, 1, &tmpfmt);
635
636         if (session->rtp) {
637                 struct ast_rtp_engine_ice *ice;
638
639                 ast_channel_set_fd(chan, 0, ast_rtp_instance_fd(session->rtp, 0));
640                 ast_channel_set_fd(chan, 1, ast_rtp_instance_fd(session->rtp, 1));
641                 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(session->rtp), session->rtp, &session->prefs);
642
643                 if (((session->transport == JINGLE_TRANSPORT_GOOGLE_V2) ||
644                      (session->transport == JINGLE_TRANSPORT_GOOGLE_V1)) &&
645                     (ice = ast_rtp_instance_get_ice(session->rtp))) {
646                         /* We stop built in ICE support because we need to fall back to old old old STUN support */
647                         ice->stop(session->rtp);
648                 }
649         }
650
651         if (state == AST_STATE_RING) {
652                 ast_channel_rings_set(chan, 1);
653         }
654
655         ast_channel_adsicpe_set(chan, AST_ADSI_UNAVAILABLE);
656
657         ast_best_codec(ast_channel_nativeformats(chan), &tmpfmt);
658         ast_format_copy(ast_channel_writeformat(chan), &tmpfmt);
659         ast_format_copy(ast_channel_rawwriteformat(chan), &tmpfmt);
660         ast_format_copy(ast_channel_readformat(chan), &tmpfmt);
661         ast_format_copy(ast_channel_rawreadformat(chan), &tmpfmt);
662
663         ao2_lock(endpoint);
664
665         ast_channel_callgroup_set(chan, endpoint->callgroup);
666         ast_channel_pickupgroup_set(chan, endpoint->pickupgroup);
667
668         if (!ast_strlen_zero(endpoint->accountcode)) {
669                 ast_channel_accountcode_set(chan, endpoint->accountcode);
670         }
671
672         if (!ast_strlen_zero(endpoint->language)) {
673                 ast_channel_language_set(chan, endpoint->language);
674         }
675
676         if (!ast_strlen_zero(endpoint->musicclass)) {
677                 ast_channel_musicclass_set(chan, endpoint->musicclass);
678         }
679
680         ast_channel_context_set(chan, endpoint->context);
681         ast_channel_exten_set(chan, "s");
682         ast_channel_priority_set(chan, 1);
683
684         ao2_unlock(endpoint);
685
686         return chan;
687 }
688
689 /*! \brief Internal helper function which sends a response */
690 static void jingle_send_response(struct ast_xmpp_client *connection, ikspak *pak)
691 {
692         iks *response;
693
694         if (!(response = iks_new("iq"))) {
695                 ast_log(LOG_ERROR, "Unable to allocate an IKS response stanza\n");
696                 return;
697         }
698
699         iks_insert_attrib(response, "type", "result");
700         iks_insert_attrib(response, "from", connection->jid->full);
701         iks_insert_attrib(response, "to", iks_find_attrib(pak->x, "from"));
702         iks_insert_attrib(response, "id", iks_find_attrib(pak->x, "id"));
703
704         ast_xmpp_client_send(connection, response);
705
706         iks_delete(response);
707 }
708
709 /*! \brief Internal helper function which sends an error response */
710 static void jingle_send_error_response(struct ast_xmpp_client *connection, ikspak *pak, const char *type, const char *reasonstr, const char *reasonstr2)
711 {
712         iks *response, *error = NULL, *reason = NULL, *reason2 = NULL;
713
714         if (!(response = iks_new("iq")) ||
715             !(error = iks_new("error")) ||
716             !(reason = iks_new(reasonstr))) {
717                 ast_log(LOG_ERROR, "Unable to allocate IKS error response stanzas\n");
718                 goto end;
719         }
720
721         iks_insert_attrib(response, "type", "error");
722         iks_insert_attrib(response, "from", connection->jid->full);
723         iks_insert_attrib(response, "to", iks_find_attrib(pak->x, "from"));
724         iks_insert_attrib(response, "id", iks_find_attrib(pak->x, "id"));
725
726         iks_insert_attrib(error, "type", type);
727         iks_insert_node(error, reason);
728
729         if (!ast_strlen_zero(reasonstr2) && (reason2 = iks_new(reasonstr2))) {
730                 iks_insert_node(error, reason2);
731         }
732
733         iks_insert_node(response, error);
734
735         ast_xmpp_client_send(connection, response);
736 end:
737         iks_delete(reason2);
738         iks_delete(reason);
739         iks_delete(error);
740         iks_delete(response);
741 }
742
743 /*! \brief Internal helper function which adds ICE-UDP candidates to a transport node */
744 static int jingle_add_ice_udp_candidates_to_transport(struct ast_rtp_instance *rtp, iks *transport, iks **candidates, unsigned int maximum)
745 {
746         struct ast_rtp_engine_ice *ice;
747         struct ao2_container *local_candidates;
748         struct ao2_iterator it;
749         struct ast_rtp_engine_ice_candidate *candidate;
750         int i = 0, res = 0;
751
752         if (!(ice = ast_rtp_instance_get_ice(rtp)) || !(local_candidates = ice->get_local_candidates(rtp))) {
753                 ast_log(LOG_ERROR, "Unable to add ICE-UDP candidates as ICE support not available or no candidates available\n");
754                 return -1;
755         }
756
757         iks_insert_attrib(transport, "xmlns", JINGLE_ICE_UDP_NS);
758         iks_insert_attrib(transport, "pwd", ice->get_password(rtp));
759         iks_insert_attrib(transport, "ufrag", ice->get_ufrag(rtp));
760
761         it = ao2_iterator_init(local_candidates, 0);
762
763         while ((candidate = ao2_iterator_next(&it)) && (i < maximum)) {
764                 iks *local_candidate;
765                 char tmp[30];
766
767                 if (!(local_candidate = iks_new("candidate"))) {
768                         res = -1;
769                         ast_log(LOG_ERROR, "Unable to allocate IKS candidate stanza for ICE-UDP transport\n");
770                         break;
771                 }
772
773                 snprintf(tmp, sizeof(tmp), "%d", candidate->id);
774                 iks_insert_attrib(local_candidate, "component", tmp);
775                 snprintf(tmp, sizeof(tmp), "%d", ast_str_hash(candidate->foundation));
776                 iks_insert_attrib(local_candidate, "foundation", tmp);
777                 iks_insert_attrib(local_candidate, "generation", "0");
778                 snprintf(tmp, sizeof(tmp), "%04lx", ast_random() & 0xffff);
779                 iks_insert_attrib(local_candidate, "id", tmp);
780                 iks_insert_attrib(local_candidate, "ip", ast_sockaddr_stringify_host(&candidate->address));
781                 iks_insert_attrib(local_candidate, "port", ast_sockaddr_stringify_port(&candidate->address));
782                 snprintf(tmp, sizeof(tmp), "%d", candidate->priority);
783                 iks_insert_attrib(local_candidate, "priority", tmp);
784                 iks_insert_attrib(local_candidate, "protocol", "udp");
785
786                 if (candidate->type == AST_RTP_ICE_CANDIDATE_TYPE_HOST) {
787                         iks_insert_attrib(local_candidate, "type", "host");
788                 } else if (candidate->type == AST_RTP_ICE_CANDIDATE_TYPE_SRFLX) {
789                         iks_insert_attrib(local_candidate, "type", "srflx");
790                 } else if (candidate->type == AST_RTP_ICE_CANDIDATE_TYPE_RELAYED) {
791                         iks_insert_attrib(local_candidate, "type", "relay");
792                 }
793
794                 iks_insert_node(transport, local_candidate);
795                 candidates[i++] = local_candidate;
796         }
797
798         ao2_iterator_destroy(&it);
799         ao2_ref(local_candidates, -1);
800
801         return res;
802 }
803
804 /*! \brief Internal helper function which adds Google candidates to a transport node */
805 static int jingle_add_google_candidates_to_transport(struct ast_rtp_instance *rtp, iks *transport, iks **candidates, unsigned int video, enum jingle_transport transport_type, unsigned int maximum)
806 {
807         struct ast_rtp_engine_ice *ice;
808         struct ao2_container *local_candidates;
809         struct ao2_iterator it;
810         struct ast_rtp_engine_ice_candidate *candidate;
811         int i = 0, res = 0;
812
813         if (!(ice = ast_rtp_instance_get_ice(rtp)) || !(local_candidates = ice->get_local_candidates(rtp))) {
814                 ast_log(LOG_ERROR, "Unable to add Google ICE candidates as ICE support not available or no candidates available\n");
815                 return -1;
816         }
817
818         if (transport_type != JINGLE_TRANSPORT_GOOGLE_V1) {
819                 iks_insert_attrib(transport, "xmlns", GOOGLE_TRANSPORT_NS);
820         }
821
822         it = ao2_iterator_init(local_candidates, 0);
823
824         while ((candidate = ao2_iterator_next(&it)) && (i < maximum)) {
825                 iks *local_candidate;
826                 /* In Google land a username is 16 bytes, explicitly */
827                 char ufrag[17] = "";
828
829                 if (!(local_candidate = iks_new("candidate"))) {
830                         res = -1;
831                         ast_log(LOG_ERROR, "Unable to allocate IKS candidate stanza for Google ICE transport\n");
832                         break;
833                 }
834
835                 if (candidate->id == 1) {
836                         iks_insert_attrib(local_candidate, "name", !video ? "rtp" : "video_rtp");
837                 } else if (candidate->id == 2) {
838                         iks_insert_attrib(local_candidate, "name", !video ? "rtcp" : "video_rtcp");
839                 } else {
840                         iks_delete(local_candidate);
841                         continue;
842                 }
843
844                 iks_insert_attrib(local_candidate, "address", ast_sockaddr_stringify_host(&candidate->address));
845                 iks_insert_attrib(local_candidate, "port", ast_sockaddr_stringify_port(&candidate->address));
846
847                 if (candidate->type == AST_RTP_ICE_CANDIDATE_TYPE_HOST) {
848                         iks_insert_attrib(local_candidate, "preference", "0.95");
849                         iks_insert_attrib(local_candidate, "type", "local");
850                 } else if (candidate->type == AST_RTP_ICE_CANDIDATE_TYPE_SRFLX) {
851                         iks_insert_attrib(local_candidate, "preference", "0.9");
852                         iks_insert_attrib(local_candidate, "type", "stun");
853                 }
854
855                 iks_insert_attrib(local_candidate, "protocol", "udp");
856                 iks_insert_attrib(local_candidate, "network", "0");
857                 snprintf(ufrag, sizeof(ufrag), "%s", ice->get_ufrag(rtp));
858                 iks_insert_attrib(local_candidate, "username", ufrag);
859                 iks_insert_attrib(local_candidate, "generation", "0");
860
861                 if (transport_type == JINGLE_TRANSPORT_GOOGLE_V1) {
862                         iks_insert_attrib(local_candidate, "password", "");
863                         iks_insert_attrib(local_candidate, "foundation", "0");
864                         iks_insert_attrib(local_candidate, "component", "1");
865                 } else {
866                         iks_insert_attrib(local_candidate, "password", ice->get_password(rtp));
867                 }
868
869                 /* You may notice a lack of relay support up above - this is because we don't support it for use with
870                  * the Google talk transport due to their arcane support. */
871
872                 iks_insert_node(transport, local_candidate);
873                 candidates[i++] = local_candidate;
874         }
875
876         ao2_iterator_destroy(&it);
877         ao2_ref(local_candidates, -1);
878
879         return res;
880 }
881
882 /*! \brief Internal function which sends a session-terminate message */
883 static void jingle_send_session_terminate(struct jingle_session *session, const char *reasontext)
884 {
885         iks *iq = NULL, *jingle = NULL, *reason = NULL, *text = NULL;
886
887         if (!(iq = iks_new("iq")) || !(jingle = iks_new(session->transport == JINGLE_TRANSPORT_GOOGLE_V1 ? "session" : "jingle")) ||
888             !(reason = iks_new("reason")) || !(text = iks_new(reasontext))) {
889                 ast_log(LOG_ERROR, "Failed to allocate stanzas for session-terminate message on session '%s'\n", session->sid);
890                 goto end;
891         }
892
893         iks_insert_attrib(iq, "to", session->remote);
894         iks_insert_attrib(iq, "type", "set");
895         iks_insert_attrib(iq, "id", session->connection->mid);
896         ast_xmpp_increment_mid(session->connection->mid);
897
898         if (session->transport == JINGLE_TRANSPORT_GOOGLE_V1) {
899                 iks_insert_attrib(jingle, "type", "terminate");
900                 iks_insert_attrib(jingle, "id", session->sid);
901                 iks_insert_attrib(jingle, "xmlns", GOOGLE_SESSION_NS);
902                 iks_insert_attrib(jingle, "initiator", session->outgoing ? session->connection->jid->full : session->remote);
903         } else {
904                 iks_insert_attrib(jingle, "action", "session-terminate");
905                 iks_insert_attrib(jingle, "sid", session->sid);
906                 iks_insert_attrib(jingle, "xmlns", JINGLE_NS);
907         }
908
909         iks_insert_node(iq, jingle);
910         iks_insert_node(jingle, reason);
911         iks_insert_node(reason, text);
912
913         ast_xmpp_client_send(session->connection, iq);
914
915 end:
916         iks_delete(text);
917         iks_delete(reason);
918         iks_delete(jingle);
919         iks_delete(iq);
920 }
921
922 /*! \brief Internal function which sends a session-info message */
923 static void jingle_send_session_info(struct jingle_session *session, const char *info)
924 {
925         iks *iq = NULL, *jingle = NULL, *text = NULL;
926
927         /* Google-V1 has no way to send informational messages so don't even bother trying */
928         if (session->transport == JINGLE_TRANSPORT_GOOGLE_V1) {
929                 return;
930         }
931
932         if (!(iq = iks_new("iq")) || !(jingle = iks_new("jingle")) || !(text = iks_new(info))) {
933                 ast_log(LOG_ERROR, "Failed to allocate stanzas for session-info message on session '%s'\n", session->sid);
934                 goto end;
935         }
936
937         iks_insert_attrib(iq, "to", session->remote);
938         iks_insert_attrib(iq, "type", "set");
939         iks_insert_attrib(iq, "id", session->connection->mid);
940         ast_xmpp_increment_mid(session->connection->mid);
941
942         iks_insert_attrib(jingle, "action", "session-info");
943         iks_insert_attrib(jingle, "sid", session->sid);
944         iks_insert_attrib(jingle, "xmlns", JINGLE_NS);
945         iks_insert_node(iq, jingle);
946         iks_insert_node(jingle, text);
947
948         ast_xmpp_client_send(session->connection, iq);
949
950 end:
951         iks_delete(text);
952         iks_delete(jingle);
953         iks_delete(iq);
954 }
955
956 /*! \internal
957  *
958  * \brief Locks both pvt and pvt owner if owner is present.
959  *
960  * \note This function gives a ref to pvt->owner if it is present and locked.
961  *       This reference must be decremented after pvt->owner is unlocked.
962  *
963  * \note This function will never give you up,
964  * \note This function will never let you down.
965  * \note This function will run around and desert you.
966  *
967  * \pre pvt is not locked
968  * \post pvt is locked
969  * \post pvt->owner is locked and its reference count is increased (if pvt->owner is not NULL)
970  *
971  * \returns a pointer to the locked and reffed pvt->owner channel if it exists.
972  */
973 static struct ast_channel *jingle_session_lock_full(struct jingle_session *pvt)
974 {
975         struct ast_channel *chan;
976
977         /* Locking is simple when it is done right.  If you see a deadlock resulting
978          * in this function, it is not this function's fault, Your problem exists elsewhere.
979          * This function is perfect... seriously. */
980         for (;;) {
981                 /* First, get the channel and grab a reference to it */
982                 ao2_lock(pvt);
983                 chan = pvt->owner;
984                 if (chan) {
985                         /* The channel can not go away while we hold the pvt lock.
986                          * Give the channel a ref so it will not go away after we let
987                          * the pvt lock go. */
988                         ast_channel_ref(chan);
989                 } else {
990                         /* no channel, return pvt locked */
991                         return NULL;
992                 }
993
994                 /* We had to hold the pvt lock while getting a ref to the owner channel
995                  * but now we have to let this lock go in order to preserve proper
996                  * locking order when grabbing the channel lock */
997                 ao2_unlock(pvt);
998
999                 /* Look, no deadlock avoidance, hooray! */
1000                 ast_channel_lock(chan);
1001                 ao2_lock(pvt);
1002                 if (pvt->owner == chan) {
1003                         /* done */
1004                         break;
1005                 }
1006
1007                 /* If the owner changed while everything was unlocked, no problem,
1008                  * just start over and everthing will work.  This is rare, do not be
1009                  * confused by this loop and think this it is an expensive operation.
1010                  * The majority of the calls to this function will never involve multiple
1011                  * executions of this loop. */
1012                 ast_channel_unlock(chan);
1013                 ast_channel_unref(chan);
1014                 ao2_unlock(pvt);
1015         }
1016
1017         /* If owner exists, it is locked and reffed */
1018         return pvt->owner;
1019 }
1020
1021 /*! \brief Helper function which queues a hangup frame with cause code */
1022 static void jingle_queue_hangup_with_cause(struct jingle_session *session, int cause)
1023 {
1024         struct ast_channel *chan;
1025
1026         if ((chan = jingle_session_lock_full(session))) {
1027                 ast_debug(3, "Hanging up channel '%s' with cause '%d'\n", ast_channel_name(chan), cause);
1028                 ast_queue_hangup_with_cause(chan, cause);
1029                 ast_channel_unlock(chan);
1030                 ast_channel_unref(chan);
1031         }
1032         ao2_unlock(session);
1033 }
1034
1035 /*! \brief Internal function which sends a transport-info message */
1036 static void jingle_send_transport_info(struct jingle_session *session, const char *from)
1037 {
1038         iks *iq, *jingle = NULL, *audio = NULL, *audio_transport = NULL, *video = NULL, *video_transport = NULL;
1039         iks *audio_candidates[session->maxicecandidates], *video_candidates[session->maxicecandidates];
1040         int i, res = 0;
1041
1042         if (!(iq = iks_new("iq")) ||
1043             !(jingle = iks_new(session->transport == JINGLE_TRANSPORT_GOOGLE_V1 ? "session" : "jingle"))) {
1044                 iks_delete(iq);
1045                 jingle_queue_hangup_with_cause(session, AST_CAUSE_SWITCH_CONGESTION);
1046                 ast_log(LOG_ERROR, "Failed to allocate stanzas for transport-info message, hanging up session '%s'\n", session->sid);
1047                 return;
1048         }
1049
1050         memset(audio_candidates, 0, sizeof(audio_candidates));
1051         memset(video_candidates, 0, sizeof(video_candidates));
1052
1053         iks_insert_attrib(iq, "from", session->connection->jid->full);
1054         iks_insert_attrib(iq, "to", from);
1055         iks_insert_attrib(iq, "type", "set");
1056         iks_insert_attrib(iq, "id", session->connection->mid);
1057         ast_xmpp_increment_mid(session->connection->mid);
1058
1059         if (session->transport == JINGLE_TRANSPORT_GOOGLE_V1) {
1060                 iks_insert_attrib(jingle, "type", "candidates");
1061                 iks_insert_attrib(jingle, "id", session->sid);
1062                 iks_insert_attrib(jingle, "xmlns", GOOGLE_SESSION_NS);
1063                 iks_insert_attrib(jingle, "initiator", session->outgoing ? session->connection->jid->full : from);
1064         } else {
1065                 iks_insert_attrib(jingle, "action", "transport-info");
1066                 iks_insert_attrib(jingle, "sid", session->sid);
1067                 iks_insert_attrib(jingle, "xmlns", JINGLE_NS);
1068         }
1069         iks_insert_node(iq, jingle);
1070
1071         if (session->rtp) {
1072                 if (session->transport == JINGLE_TRANSPORT_GOOGLE_V1) {
1073                         /* V1 protocol has the candidates directly in the session */
1074                         res = jingle_add_google_candidates_to_transport(session->rtp, jingle, audio_candidates, 0, session->transport, session->maxicecandidates);
1075                 } else if ((audio = iks_new("content")) && (audio_transport = iks_new("transport"))) {
1076                         iks_insert_attrib(audio, "creator", session->outgoing ? "initiator" : "responder");
1077                         iks_insert_attrib(audio, "name", session->audio_name);
1078                         iks_insert_node(jingle, audio);
1079                         iks_insert_node(audio, audio_transport);
1080
1081                         if (session->transport == JINGLE_TRANSPORT_ICE_UDP) {
1082                                 res = jingle_add_ice_udp_candidates_to_transport(session->rtp, audio_transport, audio_candidates, session->maxicecandidates);
1083                         } else if (session->transport == JINGLE_TRANSPORT_GOOGLE_V2) {
1084                                 res = jingle_add_google_candidates_to_transport(session->rtp, audio_transport, audio_candidates, 0, session->transport,
1085                                                                                 session->maxicecandidates);
1086                         }
1087                 } else {
1088                         res = -1;
1089                 }
1090         }
1091
1092         if ((session->transport != JINGLE_TRANSPORT_GOOGLE_V1) && !res && session->vrtp) {
1093                 if ((video = iks_new("content")) && (video_transport = iks_new("transport"))) {
1094                         iks_insert_attrib(video, "creator", session->outgoing ? "initiator" : "responder");
1095                         iks_insert_attrib(video, "name", session->video_name);
1096                         iks_insert_node(jingle, video);
1097                         iks_insert_node(video, video_transport);
1098
1099                         if (session->transport == JINGLE_TRANSPORT_ICE_UDP) {
1100                                 res = jingle_add_ice_udp_candidates_to_transport(session->vrtp, video_transport, video_candidates, session->maxicecandidates);
1101                         } else if (session->transport == JINGLE_TRANSPORT_GOOGLE_V2) {
1102                                 res = jingle_add_google_candidates_to_transport(session->vrtp, video_transport, video_candidates, 1, session->transport,
1103                                                                                 session->maxicecandidates);
1104                         }
1105                 } else {
1106                         res = -1;
1107                 }
1108         }
1109
1110         if (!res) {
1111                 ast_xmpp_client_send(session->connection, iq);
1112         } else {
1113                 jingle_queue_hangup_with_cause(session, AST_CAUSE_SWITCH_CONGESTION);
1114         }
1115
1116         /* Clean up after ourselves */
1117         for (i = 0; i < session->maxicecandidates; i++) {
1118                 iks_delete(video_candidates[i]);
1119                 iks_delete(audio_candidates[i]);
1120         }
1121
1122         iks_delete(video_transport);
1123         iks_delete(video);
1124         iks_delete(audio_transport);
1125         iks_delete(audio);
1126         iks_delete(jingle);
1127         iks_delete(iq);
1128 }
1129
1130 /*! \brief Internal helper function which adds payloads to a description */
1131 static int jingle_add_payloads_to_description(struct jingle_session *session, struct ast_rtp_instance *rtp, iks *description, iks **payloads, enum ast_format_type type)
1132 {
1133         struct ast_format format;
1134         int x = 0, i = 0, res = 0;
1135
1136         for (x = 0; (x < AST_CODEC_PREF_SIZE) && (i < (session->maxpayloads - 2)); x++) {
1137                 int rtp_code;
1138                 iks *payload;
1139                 char tmp[32];
1140
1141                 if (!ast_codec_pref_index(&session->prefs, x, &format)) {
1142                         break;
1143                 }
1144
1145                 if (AST_FORMAT_GET_TYPE(format.id) != type) {
1146                         continue;
1147                 }
1148
1149                 if (!ast_format_cap_iscompatible(session->jointcap, &format)) {
1150                         continue;
1151                 }
1152
1153                 if (((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(rtp), 1, &format, 0)) == -1) ||
1154                     (!(payload = iks_new("payload-type")))) {
1155                         return -1;
1156                 }
1157
1158                 if (session->transport == JINGLE_TRANSPORT_GOOGLE_V1) {
1159                         iks_insert_attrib(payload, "xmlns", GOOGLE_PHONE_NS);
1160                 }
1161
1162                 snprintf(tmp, sizeof(tmp), "%d", rtp_code);
1163                 iks_insert_attrib(payload, "id", tmp);
1164                 iks_insert_attrib(payload, "name", ast_rtp_lookup_mime_subtype2(1, &format, 0, 0));
1165                 iks_insert_attrib(payload, "channels", "1");
1166
1167                 if ((format.id == AST_FORMAT_G722) && ((session->transport == JINGLE_TRANSPORT_GOOGLE_V1) || (session->transport == JINGLE_TRANSPORT_GOOGLE_V2))) {
1168                         iks_insert_attrib(payload, "clockrate", "16000");
1169                 } else {
1170                         snprintf(tmp, sizeof(tmp), "%d", ast_rtp_lookup_sample_rate2(1, &format, 0));
1171                         iks_insert_attrib(payload, "clockrate", tmp);
1172                 }
1173
1174                 if ((type == AST_FORMAT_TYPE_VIDEO) && (session->transport == JINGLE_TRANSPORT_GOOGLE_V2)) {
1175                         iks *parameter;
1176
1177                         /* Google requires these parameters to be set, but alas we can not give accurate values so use some safe defaults */
1178                         if ((parameter = iks_new("parameter"))) {
1179                                 iks_insert_attrib(parameter, "name", "width");
1180                                 iks_insert_attrib(parameter, "value", "640");
1181                                 iks_insert_node(payload, parameter);
1182                         }
1183                         if ((parameter = iks_new("parameter"))) {
1184                                 iks_insert_attrib(parameter, "name", "height");
1185                                 iks_insert_attrib(parameter, "value", "480");
1186                                 iks_insert_node(payload, parameter);
1187                         }
1188                         if ((parameter = iks_new("parameter"))) {
1189                                 iks_insert_attrib(parameter, "name", "framerate");
1190                                 iks_insert_attrib(parameter, "value", "30");
1191                                 iks_insert_node(payload, parameter);
1192                         }
1193                 }
1194
1195                 iks_insert_node(description, payload);
1196                 payloads[i++] = payload;
1197         }
1198         /* If this is for audio and there is room for RFC2833 add it in */
1199         if ((type == AST_FORMAT_TYPE_AUDIO) && (i < session->maxpayloads)) {
1200                 iks *payload;
1201
1202                 if ((payload = iks_new("payload-type"))) {
1203                         if (session->transport == JINGLE_TRANSPORT_GOOGLE_V1) {
1204                                 iks_insert_attrib(payload, "xmlns", GOOGLE_PHONE_NS);
1205                         }
1206
1207                         iks_insert_attrib(payload, "id", "101");
1208                         iks_insert_attrib(payload, "name", "telephone-event");
1209                         iks_insert_attrib(payload, "channels", "1");
1210                         iks_insert_attrib(payload, "clockrate", "8000");
1211                         iks_insert_node(description, payload);
1212                         payloads[i++] = payload;
1213                 }
1214         }
1215
1216         return res;
1217 }
1218
1219 /*! \brief Helper function which adds content to a description */
1220 static int jingle_add_content(struct jingle_session *session, iks *jingle, iks *content, iks *description, iks *transport,
1221                               const char *name, enum ast_format_type type, struct ast_rtp_instance *rtp, iks **payloads)
1222 {
1223         int res = 0;
1224
1225         if (session->transport != JINGLE_TRANSPORT_GOOGLE_V1) {
1226                 iks_insert_attrib(content, "creator", session->outgoing ? "initiator" : "responder");
1227                 iks_insert_attrib(content, "name", name);
1228                 iks_insert_node(jingle, content);
1229
1230                 iks_insert_attrib(description, "xmlns", JINGLE_RTP_NS);
1231                 if (type == AST_FORMAT_TYPE_AUDIO) {
1232                         iks_insert_attrib(description, "media", "audio");
1233                 } else if (type == AST_FORMAT_TYPE_VIDEO) {
1234                         iks_insert_attrib(description, "media", "video");
1235                 } else {
1236                         return -1;
1237                 }
1238                 iks_insert_node(content, description);
1239         } else {
1240                 iks_insert_attrib(description, "xmlns", GOOGLE_PHONE_NS);
1241                 iks_insert_node(jingle, description);
1242         }
1243
1244         if (!(res = jingle_add_payloads_to_description(session, rtp, description, payloads, type))) {
1245                 if (session->transport == JINGLE_TRANSPORT_ICE_UDP) {
1246                         iks_insert_attrib(transport, "xmlns", JINGLE_ICE_UDP_NS);
1247                         iks_insert_node(content, transport);
1248                 } else if (session->transport == JINGLE_TRANSPORT_GOOGLE_V2) {
1249                         iks_insert_attrib(transport, "xmlns", GOOGLE_TRANSPORT_NS);
1250                         iks_insert_node(content, transport);
1251                 }
1252         }
1253
1254         return res;
1255 }
1256
1257 /*! \brief Internal function which sends a complete session message */
1258 static void jingle_send_session_action(struct jingle_session *session, const char *action)
1259 {
1260         iks *iq, *jingle, *audio = NULL, *audio_description = NULL, *video = NULL, *video_description = NULL;
1261         iks *audio_payloads[session->maxpayloads], *video_payloads[session->maxpayloads];
1262         iks *audio_transport = NULL, *video_transport = NULL;
1263         int i, res = 0;
1264
1265         if (!(iq = iks_new("iq")) ||
1266             !(jingle = iks_new(session->transport == JINGLE_TRANSPORT_GOOGLE_V1 ? "session" : "jingle"))) {
1267                 jingle_queue_hangup_with_cause(session, AST_CAUSE_SWITCH_CONGESTION);
1268                 iks_delete(iq);
1269                 return;
1270         }
1271
1272         memset(audio_payloads, 0, sizeof(audio_payloads));
1273         memset(video_payloads, 0, sizeof(video_payloads));
1274
1275         iks_insert_attrib(iq, "from", session->connection->jid->full);
1276         iks_insert_attrib(iq, "to", session->remote);
1277         iks_insert_attrib(iq, "type", "set");
1278         iks_insert_attrib(iq, "id", session->connection->mid);
1279         ast_xmpp_increment_mid(session->connection->mid);
1280
1281         if (session->transport == JINGLE_TRANSPORT_GOOGLE_V1) {
1282                 iks_insert_attrib(jingle, "type", action);
1283                 iks_insert_attrib(jingle, "id", session->sid);
1284                 iks_insert_attrib(jingle, "xmlns", GOOGLE_SESSION_NS);
1285         } else {
1286                 iks_insert_attrib(jingle, "action", action);
1287                 iks_insert_attrib(jingle, "sid", session->sid);
1288                 iks_insert_attrib(jingle, "xmlns", JINGLE_NS);
1289         }
1290
1291         if (!strcasecmp(action, "session-initiate") || !strcasecmp(action, "initiate") || !strcasecmp(action, "accept")) {
1292                 iks_insert_attrib(jingle, "initiator", session->outgoing ? session->connection->jid->full : session->remote);
1293         }
1294
1295         iks_insert_node(iq, jingle);
1296
1297         if (session->rtp && (audio = iks_new("content")) && (audio_description = iks_new("description")) &&
1298             (audio_transport = iks_new("transport"))) {
1299                 res = jingle_add_content(session, jingle, audio, audio_description, audio_transport, session->audio_name,
1300                                          AST_FORMAT_TYPE_AUDIO, session->rtp, audio_payloads);
1301         } else {
1302                 ast_log(LOG_ERROR, "Failed to allocate audio content stanzas for session '%s', hanging up\n", session->sid);
1303                 res = -1;
1304         }
1305
1306         if ((session->transport != JINGLE_TRANSPORT_GOOGLE_V1) && !res && session->vrtp) {
1307                 if ((video = iks_new("content")) && (video_description = iks_new("description")) &&
1308                     (video_transport = iks_new("transport"))) {
1309                         res = jingle_add_content(session, jingle, video, video_description, video_transport, session->video_name,
1310                                                  AST_FORMAT_TYPE_VIDEO, session->vrtp, video_payloads);
1311                 } else {
1312                         ast_log(LOG_ERROR, "Failed to allocate video content stanzas for session '%s', hanging up\n", session->sid);
1313                         res = -1;
1314                 }
1315         }
1316
1317         if (!res) {
1318                 ast_xmpp_client_send(session->connection, iq);
1319         } else {
1320                 jingle_queue_hangup_with_cause(session, AST_CAUSE_SWITCH_CONGESTION);
1321         }
1322
1323         iks_delete(video_transport);
1324         iks_delete(audio_transport);
1325
1326         for (i = 0; i < session->maxpayloads; i++) {
1327                 iks_delete(video_payloads[i]);
1328                 iks_delete(audio_payloads[i]);
1329         }
1330
1331         iks_delete(video_description);
1332         iks_delete(video);
1333         iks_delete(audio_description);
1334         iks_delete(audio);
1335         iks_delete(jingle);
1336         iks_delete(iq);
1337 }
1338
1339 /*! \brief Internal function which sends a session-inititate message */
1340 static void jingle_send_session_initiate(struct jingle_session *session)
1341 {
1342         jingle_send_session_action(session, session->transport == JINGLE_TRANSPORT_GOOGLE_V1 ? "initiate" : "session-initiate");
1343 }
1344
1345 /*! \brief Internal function which sends a session-accept message */
1346 static void jingle_send_session_accept(struct jingle_session *session)
1347 {
1348         jingle_send_session_action(session, session->transport == JINGLE_TRANSPORT_GOOGLE_V1 ? "accept" : "session-accept");
1349 }
1350
1351 /*! \brief Callback for when a response is received for an outgoing session-initiate message */
1352 static int jingle_outgoing_hook(void *data, ikspak *pak)
1353 {
1354         struct jingle_session *session = data;
1355         iks *error = iks_find(pak->x, "error"), *redirect;
1356
1357         /* In all cases this hook is done with */
1358         iks_filter_remove_rule(session->connection->filter, session->rule);
1359         session->rule = NULL;
1360
1361         ast_callid_threadassoc_add(session->callid);
1362
1363         /* If no error occurred they accepted our session-initiate message happily */
1364         if (!error) {
1365                 struct ast_channel *chan;
1366
1367                 if ((chan = jingle_session_lock_full(session))) {
1368                         ast_queue_control(chan, AST_CONTROL_PROCEEDING);
1369                         ast_channel_unlock(chan);
1370                         ast_channel_unref(chan);
1371                 }
1372                 ao2_unlock(session);
1373
1374                 jingle_send_transport_info(session, iks_find_attrib(pak->x, "from"));
1375
1376                 goto end;
1377         }
1378
1379         /* Assume that because this is an error the session is gone, there is only one case where this is incorrect - a redirect */
1380         session->gone = 1;
1381
1382         /* Map the error we received to an appropriate cause code and hang up the channel */
1383         if ((redirect = iks_find_with_attrib(error, "redirect", "xmlns", XMPP_STANZAS_NS))) {
1384                 iks *to = iks_child(redirect);
1385                 char *target;
1386
1387                 if (to && (target = iks_name(to)) && !ast_strlen_zero(target)) {
1388                         /* Make the xmpp: go away if it is present */
1389                         if (!strncmp(target, "xmpp:", 5)) {
1390                                 target += 5;
1391                         }
1392
1393                         /* This is actually a fairly simple operation - we update the remote and send another session-initiate */
1394                         ast_copy_string(session->remote, target, sizeof(session->remote));
1395
1396                         /* Add a new hook so we can get the status of redirected session */
1397                         session->rule = iks_filter_add_rule(session->connection->filter, jingle_outgoing_hook, session,
1398                                                             IKS_RULE_ID, session->connection->mid, IKS_RULE_DONE);
1399
1400                         jingle_send_session_initiate(session);
1401
1402                         session->gone = 0;
1403                 } else {
1404                         jingle_queue_hangup_with_cause(session, AST_CAUSE_PROTOCOL_ERROR);
1405                 }
1406         } else if (iks_find_with_attrib(error, "service-unavailable", "xmlns", XMPP_STANZAS_NS)) {
1407                 jingle_queue_hangup_with_cause(session, AST_CAUSE_CONGESTION);
1408         } else if (iks_find_with_attrib(error, "resource-constraint", "xmlns", XMPP_STANZAS_NS)) {
1409                 jingle_queue_hangup_with_cause(session, AST_CAUSE_REQUESTED_CHAN_UNAVAIL);
1410         } else if (iks_find_with_attrib(error, "bad-request", "xmlns", XMPP_STANZAS_NS)) {
1411                 jingle_queue_hangup_with_cause(session, AST_CAUSE_PROTOCOL_ERROR);
1412         } else if (iks_find_with_attrib(error, "remote-server-not-found", "xmlns", XMPP_STANZAS_NS)) {
1413                 jingle_queue_hangup_with_cause(session, AST_CAUSE_NO_ROUTE_DESTINATION);
1414         } else if (iks_find_with_attrib(error, "feature-not-implemented", "xmlns", XMPP_STANZAS_NS)) {
1415                 /* Assume that this occurred because the remote side does not support our transport, so drop it down one and try again */
1416                 session->transport--;
1417
1418                 /* If we still have a viable transport mechanism re-send the session-initiate */
1419                 if (session->transport != JINGLE_TRANSPORT_NONE) {
1420                         struct ast_rtp_engine_ice *ice;
1421
1422                         if (((session->transport == JINGLE_TRANSPORT_GOOGLE_V2) ||
1423                              (session->transport == JINGLE_TRANSPORT_GOOGLE_V1)) &&
1424                             (ice = ast_rtp_instance_get_ice(session->rtp))) {
1425                                 /* We stop built in ICE support because we need to fall back to old old old STUN support */
1426                                 ice->stop(session->rtp);
1427                         }
1428
1429                         /* Re-send the message to the *original* target and not a redirected one */
1430                         ast_copy_string(session->remote, session->remote_original, sizeof(session->remote));
1431
1432                         session->rule = iks_filter_add_rule(session->connection->filter, jingle_outgoing_hook, session,
1433                                                             IKS_RULE_ID, session->connection->mid, IKS_RULE_DONE);
1434
1435                         jingle_send_session_initiate(session);
1436
1437                         session->gone = 0;
1438                 } else {
1439                         /* Otherwise we have exhausted all transports */
1440                         jingle_queue_hangup_with_cause(session, AST_CAUSE_FACILITY_NOT_IMPLEMENTED);
1441                 }
1442         } else {
1443                 jingle_queue_hangup_with_cause(session, AST_CAUSE_PROTOCOL_ERROR);
1444         }
1445
1446 end:
1447         ast_callid_threadassoc_remove();
1448
1449         return IKS_FILTER_EAT;
1450 }
1451
1452 /*! \brief Function called by core when we should answer a Jingle session */
1453 static int jingle_answer(struct ast_channel *ast)
1454 {
1455         struct jingle_session *session = ast_channel_tech_pvt(ast);
1456
1457         /* The channel has already been answered so we don't need to do anything */
1458         if (ast_channel_state(ast) == AST_STATE_UP) {
1459                 return 0;
1460         }
1461
1462         jingle_send_session_accept(session);
1463
1464         return 0;
1465 }
1466
1467 /*! \brief Function called by core to read any waiting frames */
1468 static struct ast_frame *jingle_read(struct ast_channel *ast)
1469 {
1470         struct jingle_session *session = ast_channel_tech_pvt(ast);
1471         struct ast_frame *frame = &ast_null_frame;
1472
1473         switch (ast_channel_fdno(ast)) {
1474         case 0:
1475                 if (session->rtp) {
1476                         frame = ast_rtp_instance_read(session->rtp, 0);
1477                 }
1478                 break;
1479         case 1:
1480                 if (session->rtp) {
1481                         frame = ast_rtp_instance_read(session->rtp, 1);
1482                 }
1483                 break;
1484         case 2:
1485                 if (session->vrtp) {
1486                         frame = ast_rtp_instance_read(session->vrtp, 0);
1487                 }
1488                 break;
1489         case 3:
1490                 if (session->vrtp) {
1491                         frame = ast_rtp_instance_read(session->vrtp, 1);
1492                 }
1493                 break;
1494         default:
1495                 break;
1496         }
1497
1498         if (frame && frame->frametype == AST_FRAME_VOICE &&
1499             !ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &frame->subclass.format)) {
1500                 if (!ast_format_cap_iscompatible(session->jointcap, &frame->subclass.format)) {
1501                         ast_debug(1, "Bogus frame of format '%s' received from '%s'!\n",
1502                                   ast_getformatname(&frame->subclass.format), ast_channel_name(ast));
1503                         ast_frfree(frame);
1504                         frame = &ast_null_frame;
1505                 } else {
1506                         ast_debug(1, "Oooh, format changed to %s\n",
1507                                   ast_getformatname(&frame->subclass.format));
1508                         ast_format_cap_remove_bytype(ast_channel_nativeformats(ast), AST_FORMAT_TYPE_AUDIO);
1509                         ast_format_cap_add(ast_channel_nativeformats(ast), &frame->subclass.format);
1510                         ast_set_read_format(ast, ast_channel_readformat(ast));
1511                         ast_set_write_format(ast, ast_channel_writeformat(ast));
1512                 }
1513         }
1514
1515         return frame;
1516 }
1517
1518 /*! \brief Function called by core to write frames */
1519 static int jingle_write(struct ast_channel *ast, struct ast_frame *frame)
1520 {
1521         struct jingle_session *session = ast_channel_tech_pvt(ast);
1522         int res = 0;
1523         char buf[256];
1524
1525         switch (frame->frametype) {
1526         case AST_FRAME_VOICE:
1527                 if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &frame->subclass.format))) {
1528                         ast_log(LOG_WARNING,
1529                                 "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
1530                                 ast_getformatname(&frame->subclass.format),
1531                                 ast_getformatname_multiple(buf, sizeof(buf), ast_channel_nativeformats(ast)),
1532                                 ast_getformatname(ast_channel_readformat(ast)),
1533                                 ast_getformatname(ast_channel_writeformat(ast)));
1534                         return 0;
1535                 }
1536                 if (session && session->rtp) {
1537                         res = ast_rtp_instance_write(session->rtp, frame);
1538                 }
1539                 break;
1540         case AST_FRAME_VIDEO:
1541                 if (session && session->vrtp) {
1542                         res = ast_rtp_instance_write(session->vrtp, frame);
1543                 }
1544                 break;
1545         default:
1546                 ast_log(LOG_WARNING, "Can't send %d type frames with Jingle write\n",
1547                         frame->frametype);
1548                 return 0;
1549         }
1550
1551         return res;
1552 }
1553
1554 /*! \brief Function called by core to change the underlying owner channel */
1555 static int jingle_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
1556 {
1557         struct jingle_session *session = ast_channel_tech_pvt(newchan);
1558
1559         ao2_lock(session);
1560
1561         session->owner = newchan;
1562
1563         ao2_unlock(session);
1564
1565         return 0;
1566 }
1567
1568 /*! \brief Function called by core to ask the channel to indicate some sort of condition */
1569 static int jingle_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
1570 {
1571         struct jingle_session *session = ast_channel_tech_pvt(ast);
1572         int res = 0;
1573
1574         switch (condition) {
1575         case AST_CONTROL_RINGING:
1576                 if (ast_channel_state(ast) == AST_STATE_RING) {
1577                         jingle_send_session_info(session, "ringing xmlns='urn:xmpp:jingle:apps:rtp:info:1'");
1578                 } else {
1579                         res = -1;
1580                 }
1581                 break;
1582         case AST_CONTROL_BUSY:
1583                 if (ast_channel_state(ast) != AST_STATE_UP) {
1584                         ast_channel_hangupcause_set(ast, AST_CAUSE_BUSY);
1585                         ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
1586                 } else {
1587                         res = -1;
1588                 }
1589                 break;
1590         case AST_CONTROL_CONGESTION:
1591                 if (ast_channel_state(ast) != AST_STATE_UP) {
1592                         ast_channel_hangupcause_set(ast, AST_CAUSE_CONGESTION);
1593                         ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
1594                 } else {
1595                         res = -1;
1596                 }
1597                 break;
1598         case AST_CONTROL_INCOMPLETE:
1599                 if (ast_channel_state(ast) != AST_STATE_UP) {
1600                         ast_channel_hangupcause_set(ast, AST_CAUSE_CONGESTION);
1601                         ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
1602                 }
1603                 break;
1604         case AST_CONTROL_HOLD:
1605                 ast_moh_start(ast, data, NULL);
1606                 break;
1607         case AST_CONTROL_UNHOLD:
1608                 ast_moh_stop(ast);
1609                 break;
1610         case AST_CONTROL_SRCUPDATE:
1611                 if (session->rtp) {
1612                         ast_rtp_instance_update_source(session->rtp);
1613                 }
1614                 break;
1615         case AST_CONTROL_SRCCHANGE:
1616                 if (session->rtp) {
1617                         ast_rtp_instance_change_source(session->rtp);
1618                 }
1619                 break;
1620         case AST_CONTROL_VIDUPDATE:
1621         case AST_CONTROL_UPDATE_RTP_PEER:
1622         case AST_CONTROL_CONNECTED_LINE:
1623                 break;
1624         case AST_CONTROL_PVT_CAUSE_CODE:
1625         case -1:
1626                 res = -1;
1627                 break;
1628         default:
1629                 ast_log(LOG_NOTICE, "Don't know how to indicate condition '%d'\n", condition);
1630                 res = -1;
1631         }
1632
1633         return res;
1634 }
1635
1636 /*! \brief Function called by core to send text to the remote party of the Jingle session */
1637 static int jingle_sendtext(struct ast_channel *chan, const char *text)
1638 {
1639         struct jingle_session *session = ast_channel_tech_pvt(chan);
1640
1641         return ast_xmpp_client_send_message(session->connection, session->remote, text);
1642 }
1643
1644 /*! \brief Function called by core to start a DTMF digit */
1645 static int jingle_digit_begin(struct ast_channel *chan, char digit)
1646 {
1647         struct jingle_session *session = ast_channel_tech_pvt(chan);
1648
1649         if (session->rtp) {
1650                 ast_rtp_instance_dtmf_begin(session->rtp, digit);
1651         }
1652
1653         return 0;
1654 }
1655
1656 /*! \brief Function called by core to stop a DTMF digit */
1657 static int jingle_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
1658 {
1659         struct jingle_session *session = ast_channel_tech_pvt(ast);
1660
1661         if (session->rtp) {
1662                 ast_rtp_instance_dtmf_end_with_duration(session->rtp, digit, duration);
1663         }
1664
1665         return 0;
1666 }
1667
1668 /*! \brief Function called by core to actually start calling a remote party */
1669 static int jingle_call(struct ast_channel *ast, const char *dest, int timeout)
1670 {
1671         struct jingle_session *session = ast_channel_tech_pvt(ast);
1672
1673         ast_setstate(ast, AST_STATE_RING);
1674
1675         /* Since we have no idea of the remote capabilities use ours for now */
1676         ast_format_cap_copy(session->jointcap, session->cap);
1677
1678         /* We set up a hook so we can know when our session-initiate message was accepted or rejected */
1679         session->rule = iks_filter_add_rule(session->connection->filter, jingle_outgoing_hook, session,
1680                                             IKS_RULE_ID, session->connection->mid, IKS_RULE_DONE);
1681
1682         jingle_send_session_initiate(session);
1683
1684         return 0;
1685 }
1686
1687 /*! \brief Function called by core to hang up a Jingle session */
1688 static int jingle_hangup(struct ast_channel *ast)
1689 {
1690         struct jingle_session *session = ast_channel_tech_pvt(ast);
1691
1692         ao2_lock(session);
1693
1694         if ((ast_channel_state(ast) != AST_STATE_DOWN) && !session->gone) {
1695                 int cause = (session->owner ? ast_channel_hangupcause(session->owner) : AST_CAUSE_CONGESTION);
1696                 const char *reason = "success";
1697                 int i;
1698
1699                 /* Get the appropriate reason and send a session-terminate */
1700                 for (i = 0; i < ARRAY_LEN(jingle_reason_mappings); i++) {
1701                         if (jingle_reason_mappings[i].cause == cause) {
1702                                 reason = jingle_reason_mappings[i].reason;
1703                                 break;
1704                         }
1705                 }
1706
1707                 jingle_send_session_terminate(session, reason);
1708         }
1709
1710         ast_channel_tech_pvt_set(ast, NULL);
1711         session->owner = NULL;
1712
1713         ao2_unlink(session->state->sessions, session);
1714         ao2_ref(session->state, -1);
1715
1716         ao2_unlock(session);
1717         ao2_ref(session, -1);
1718
1719         return 0;
1720 }
1721
1722 /*! \brief Function called by core to create a new outgoing Jingle session */
1723 static struct ast_channel *jingle_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
1724 {
1725         RAII_VAR(struct jingle_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
1726         RAII_VAR(struct jingle_endpoint *, endpoint, NULL, ao2_cleanup);
1727         char *dialed, target[200] = "";
1728         struct ast_xmpp_buddy *buddy;
1729         struct jingle_session *session;
1730         struct ast_channel *chan;
1731         enum jingle_transport transport = JINGLE_TRANSPORT_NONE;
1732         AST_DECLARE_APP_ARGS(args,
1733                              AST_APP_ARG(name);
1734                              AST_APP_ARG(target);
1735                 );
1736
1737         /* We require at a minimum one audio format to be requested */
1738         if (!ast_format_cap_has_type(cap, AST_FORMAT_TYPE_AUDIO)) {
1739                 ast_log(LOG_ERROR, "Motif channel driver requires an audio format when dialing a destination\n");
1740                 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
1741                 return NULL;
1742         }
1743
1744         if (ast_strlen_zero(data) || !(dialed = ast_strdupa(data))) {
1745                 ast_log(LOG_ERROR, "Unable to create channel with empty destination.\n");
1746                 *cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
1747                 return NULL;
1748         }
1749
1750         /* Parse the given dial string and validate the results */
1751         AST_NONSTANDARD_APP_ARGS(args, dialed, '/');
1752
1753         if (ast_strlen_zero(args.name) || ast_strlen_zero(args.target)) {
1754                 ast_log(LOG_ERROR, "Unable to determine endpoint name and target.\n");
1755                 *cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
1756                 return NULL;
1757         }
1758
1759         if (!(endpoint = jingle_endpoint_find(cfg->endpoints, args.name))) {
1760                 ast_log(LOG_ERROR, "Endpoint '%s' does not exist.\n", args.name);
1761                 *cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
1762                 return NULL;
1763         }
1764
1765         ao2_lock(endpoint->state);
1766
1767         /* If we don't have a connection for the endpoint we can't exactly start a session on it */
1768         if (!endpoint->connection) {
1769                 ast_log(LOG_ERROR, "Unable to create Jingle session on endpoint '%s' as no valid connection exists\n", args.name);
1770                 *cause = AST_CAUSE_SWITCH_CONGESTION;
1771                 ao2_unlock(endpoint->state);
1772                 return NULL;
1773         }
1774
1775         /* Find the target in the roster so we can choose a resource */
1776         if ((buddy = ao2_find(endpoint->connection->buddies, args.target, OBJ_KEY))) {
1777                 struct ao2_iterator res;
1778                 struct ast_xmpp_resource *resource;
1779
1780                 /* Iterate through finding the first viable Jingle capable resource */
1781                 res = ao2_iterator_init(buddy->resources, 0);
1782                 while ((resource = ao2_iterator_next(&res))) {
1783                         if (resource->caps.jingle) {
1784                                 snprintf(target, sizeof(target), "%s/%s", args.target, resource->resource);
1785                                 transport = JINGLE_TRANSPORT_ICE_UDP;
1786                                 break;
1787                         } else if (resource->caps.google) {
1788                                 snprintf(target, sizeof(target), "%s/%s", args.target, resource->resource);
1789                                 transport = JINGLE_TRANSPORT_GOOGLE_V2;
1790                                 break;
1791                         }
1792                         ao2_ref(resource, -1);
1793                 }
1794                 ao2_iterator_destroy(&res);
1795
1796                 ao2_ref(buddy, -1);
1797         } else {
1798                 /* If the target is NOT in the roster use the provided target as-is */
1799                 ast_copy_string(target, args.target, sizeof(target));
1800         }
1801
1802         ao2_unlock(endpoint->state);
1803
1804         /* If no target was found we can't set up a session */
1805         if (ast_strlen_zero(target)) {
1806                 ast_log(LOG_ERROR, "Unable to create Jingle session on endpoint '%s' as no capable resource for target '%s' was found\n", args.name, args.target);
1807                 *cause = AST_CAUSE_SWITCH_CONGESTION;
1808                 return NULL;
1809         }
1810
1811         if (!(session = jingle_alloc(endpoint, target, NULL))) {
1812                 ast_log(LOG_ERROR, "Unable to create Jingle session on endpoint '%s'\n", args.name);
1813                 *cause = AST_CAUSE_SWITCH_CONGESTION;
1814                 return NULL;
1815         }
1816
1817         /* Update the transport if we learned what we should actually use */
1818         if (transport != JINGLE_TRANSPORT_NONE) {
1819                 session->transport = transport;
1820                 /* Note that for Google-V1 and Google-V2 we don't stop built-in ICE support, this will happen in jingle_new */
1821         }
1822
1823         if (!(chan = jingle_new(endpoint, session, AST_STATE_DOWN, target, requestor ? ast_channel_linkedid(requestor) : NULL, NULL))) {
1824                 ast_log(LOG_ERROR, "Unable to create Jingle channel on endpoint '%s'\n", args.name);
1825                 *cause = AST_CAUSE_SWITCH_CONGESTION;
1826                 ao2_ref(session, -1);
1827                 return NULL;
1828         }
1829
1830         /* If video was requested try to enable it on the session */
1831         if (ast_format_cap_has_type(cap, AST_FORMAT_TYPE_VIDEO)) {
1832                 jingle_enable_video(session);
1833         }
1834
1835         /* We purposely don't decrement the session here as there is a reference on the channel */
1836         ao2_link(endpoint->state->sessions, session);
1837
1838         return chan;
1839 }
1840
1841 /*! \brief Helper function which handles content descriptions */
1842 static int jingle_interpret_description(struct jingle_session *session, iks *description, const char *name, struct ast_rtp_instance **rtp)
1843 {
1844         char *media = iks_find_attrib(description, "media");
1845         struct ast_rtp_codecs codecs;
1846         iks *codec;
1847         int othercapability = 0;
1848
1849         /* Google-V1 is always carrying audio, but just doesn't tell us so */
1850         if (session->transport == JINGLE_TRANSPORT_GOOGLE_V1) {
1851                 media = "audio";
1852         } else if (ast_strlen_zero(media)) {
1853                 jingle_queue_hangup_with_cause(session, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
1854                 ast_log(LOG_ERROR, "Received a content description on session '%s' without a name\n", session->sid);
1855                 return -1;
1856         }
1857
1858         /* Determine the type of media that is being carried and update the RTP instance, as well as the name */
1859         if (!strcasecmp(media, "audio")) {
1860                 if (!ast_strlen_zero(name)) {
1861                         ast_string_field_set(session, audio_name, name);
1862                 }
1863                 *rtp = session->rtp;
1864                 ast_format_cap_remove_bytype(session->peercap, AST_FORMAT_TYPE_AUDIO);
1865                 ast_format_cap_remove_bytype(session->jointcap, AST_FORMAT_TYPE_AUDIO);
1866         } else if (!strcasecmp(media, "video")) {
1867                 if (!ast_strlen_zero(name)) {
1868                         ast_string_field_set(session, video_name, name);
1869                 }
1870
1871                 jingle_enable_video(session);
1872                 *rtp = session->vrtp;
1873
1874                 /* If video is not present cancel this session */
1875                 if (!session->vrtp) {
1876                         jingle_queue_hangup_with_cause(session, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
1877                         ast_log(LOG_ERROR, "Received a video content description on session '%s' but could not enable video\n", session->sid);
1878                         return -1;
1879                 }
1880
1881                 ast_format_cap_remove_bytype(session->peercap, AST_FORMAT_TYPE_VIDEO);
1882                 ast_format_cap_remove_bytype(session->jointcap, AST_FORMAT_TYPE_VIDEO);
1883         } else {
1884                 /* Unknown media type */
1885                 jingle_queue_hangup_with_cause(session, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
1886                 ast_log(LOG_ERROR, "Unsupported media type '%s' received in content description on session '%s'\n", media, session->sid);
1887                 return -1;
1888         }
1889
1890         if (ast_rtp_codecs_payloads_initialize(&codecs)) {
1891                 jingle_queue_hangup_with_cause(session, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
1892                 ast_log(LOG_ERROR, "Could not initialize codecs for negotiation on session '%s'\n", session->sid);
1893                 return -1;
1894         }
1895
1896         /* Iterate the codecs updating the relevant RTP instance as we go */
1897         for (codec = iks_child(description); codec; codec = iks_next(codec)) {
1898                 char *id = iks_find_attrib(codec, "id"), *name = iks_find_attrib(codec, "name");
1899                 char *clockrate = iks_find_attrib(codec, "clockrate");
1900                 int rtp_id, rtp_clockrate;
1901
1902                 if (!ast_strlen_zero(id) && !ast_strlen_zero(name) && (sscanf(id, "%30d", &rtp_id) == 1)) {
1903                         ast_rtp_codecs_payloads_set_m_type(&codecs, NULL, rtp_id);
1904
1905                         if (!ast_strlen_zero(clockrate) && (sscanf(clockrate, "%30d", &rtp_clockrate) == 1)) {
1906                                 ast_rtp_codecs_payloads_set_rtpmap_type_rate(&codecs, NULL, rtp_id, media, name, 0, rtp_clockrate);
1907                         } else {
1908                                 ast_rtp_codecs_payloads_set_rtpmap_type(&codecs, NULL, rtp_id, media, name, 0);
1909                         }
1910                 }
1911         }
1912
1913         ast_rtp_codecs_payload_formats(&codecs, session->peercap, &othercapability);
1914         ast_format_cap_joint_append(session->cap, session->peercap, session->jointcap);
1915
1916         if (ast_format_cap_is_empty(session->jointcap)) {
1917                 /* We have no compatible codecs, so terminate the session appropriately */
1918                 jingle_queue_hangup_with_cause(session, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
1919                 ast_rtp_codecs_payloads_destroy(&codecs);
1920                 return -1;
1921         }
1922
1923         ast_rtp_codecs_payloads_copy(&codecs, ast_rtp_instance_get_codecs(*rtp), *rtp);
1924         ast_rtp_codecs_payloads_destroy(&codecs);
1925
1926         return 0;
1927 }
1928
1929 /*! \brief Helper function which handles ICE-UDP transport information */
1930 static int jingle_interpret_ice_udp_transport(struct jingle_session *session, iks *transport, struct ast_rtp_instance *rtp)
1931 {
1932         struct ast_rtp_engine_ice *ice = ast_rtp_instance_get_ice(rtp);
1933         char *ufrag = iks_find_attrib(transport, "ufrag"), *pwd = iks_find_attrib(transport, "pwd");
1934         iks *candidate;
1935
1936         if (!ice) {
1937                 jingle_queue_hangup_with_cause(session, AST_CAUSE_SWITCH_CONGESTION);
1938                 ast_log(LOG_ERROR, "Received ICE-UDP transport information on session '%s' but ICE support not available\n", session->sid);
1939                 return -1;
1940         }
1941
1942         if (ast_strlen_zero(ufrag) || ast_strlen_zero(pwd)) {
1943                 jingle_queue_hangup_with_cause(session, AST_CAUSE_PROTOCOL_ERROR);
1944                 ast_log(LOG_ERROR, "Invalid ICE-UDP transport information received on session '%s', ufrag or pwd not present\n", session->sid);
1945                 return -1;
1946         }
1947
1948         ice->set_authentication(rtp, ufrag, pwd);
1949
1950         for (candidate = iks_child(transport); candidate; candidate = iks_next(candidate)) {
1951                 char *component = iks_find_attrib(candidate, "component"), *foundation = iks_find_attrib(candidate, "foundation");
1952                 char *generation = iks_find_attrib(candidate, "generation"), *id = iks_find_attrib(candidate, "id");
1953                 char *ip = iks_find_attrib(candidate, "ip"), *network = iks_find_attrib(candidate, "network");
1954                 char *port = iks_find_attrib(candidate, "port"), *priority = iks_find_attrib(candidate, "priority");
1955                 char *protocol = iks_find_attrib(candidate, "protocol"), *type = iks_find_attrib(candidate, "type");
1956                 struct ast_rtp_engine_ice_candidate local_candidate = { 0, };
1957                 int real_port;
1958                 struct ast_sockaddr remote_address = { { 0, } };
1959
1960                 /* If this candidate is incomplete skip it */
1961                 if (ast_strlen_zero(component) || ast_strlen_zero(foundation) || ast_strlen_zero(generation) || ast_strlen_zero(id) ||
1962                     ast_strlen_zero(ip) || ast_strlen_zero(network) || ast_strlen_zero(port) || ast_strlen_zero(priority) ||
1963                     ast_strlen_zero(protocol) || ast_strlen_zero(type)) {
1964                         jingle_queue_hangup_with_cause(session, AST_CAUSE_PROTOCOL_ERROR);
1965                         ast_log(LOG_ERROR, "Incomplete ICE-UDP candidate received on session '%s'\n", session->sid);
1966                         return -1;
1967                 }
1968
1969                 if ((sscanf(component, "%30u", &local_candidate.id) != 1) ||
1970                     (sscanf(priority, "%30u", &local_candidate.priority) != 1) ||
1971                     (sscanf(port, "%30d", &real_port) != 1)) {
1972                         jingle_queue_hangup_with_cause(session, AST_CAUSE_PROTOCOL_ERROR);
1973                         ast_log(LOG_ERROR, "Invalid ICE-UDP candidate information received on session '%s'\n", session->sid);
1974                         return -1;
1975                 }
1976
1977                 local_candidate.foundation = foundation;
1978                 local_candidate.transport = protocol;
1979
1980                 ast_sockaddr_parse(&local_candidate.address, ip, PARSE_PORT_FORBID);
1981
1982                 /* We only support IPv4 right now */
1983                 if (!ast_sockaddr_is_ipv4(&local_candidate.address)) {
1984                         continue;
1985                 }
1986
1987                 ast_sockaddr_set_port(&local_candidate.address, real_port);
1988
1989                 if (!strcasecmp(type, "host")) {
1990                         local_candidate.type = AST_RTP_ICE_CANDIDATE_TYPE_HOST;
1991                 } else if (!strcasecmp(type, "srflx")) {
1992                         local_candidate.type = AST_RTP_ICE_CANDIDATE_TYPE_SRFLX;
1993                 } else if (!strcasecmp(type, "relay")) {
1994                         local_candidate.type = AST_RTP_ICE_CANDIDATE_TYPE_RELAYED;
1995                 } else {
1996                         continue;
1997                 }
1998
1999                 /* Worst case use the first viable address */
2000                 ast_rtp_instance_get_remote_address(rtp, &remote_address);
2001
2002                 if (ast_sockaddr_is_ipv4(&local_candidate.address) && ast_sockaddr_isnull(&remote_address)) {
2003                         ast_rtp_instance_set_remote_address(rtp, &local_candidate.address);
2004                 }
2005
2006                 ice->add_remote_candidate(rtp, &local_candidate);
2007         }
2008
2009         ice->start(rtp);
2010
2011         return 0;
2012 }
2013
2014 /*! \brief Helper function which handles Google transport information */
2015 static int jingle_interpret_google_transport(struct jingle_session *session, iks *transport, struct ast_rtp_instance *rtp)
2016 {
2017         struct ast_rtp_engine_ice *ice = ast_rtp_instance_get_ice(rtp);
2018         iks *candidate;
2019
2020         if (!ice) {
2021                 jingle_queue_hangup_with_cause(session, AST_CAUSE_SWITCH_CONGESTION);
2022                 ast_log(LOG_ERROR, "Received Google transport information on session '%s' but ICE support not available\n", session->sid);
2023                 return -1;
2024         }
2025
2026         /* If this session has not transitioned to the Google transport do so now */
2027         if ((session->transport != JINGLE_TRANSPORT_GOOGLE_V2) &&
2028             (session->transport != JINGLE_TRANSPORT_GOOGLE_V1)) {
2029                 /* Stop built-in ICE support... we need to fall back to the old old old STUN */
2030                 ice->stop(rtp);
2031
2032                 session->transport = JINGLE_TRANSPORT_GOOGLE_V2;
2033         }
2034
2035         for (candidate = iks_child(transport); candidate; candidate = iks_next(candidate)) {
2036                 char *address = iks_find_attrib(candidate, "address"), *port = iks_find_attrib(candidate, "port");
2037                 char *username = iks_find_attrib(candidate, "username"), *name = iks_find_attrib(candidate, "name");
2038                 char *protocol = iks_find_attrib(candidate, "protocol");
2039                 int real_port;
2040                 struct ast_sockaddr target = { { 0, } };
2041                 /* In Google land the combined value is 32 bytes */
2042                 char combined[33] = "";
2043
2044                 /* If this is NOT actually a candidate just skip it */
2045                 if (strcasecmp(iks_name(candidate), "candidate") &&
2046                     strcasecmp(iks_name(candidate), "p:candidate") &&
2047                     strcasecmp(iks_name(candidate), "ses:candidate")) {
2048                         continue;
2049                 }
2050
2051                 /* If this candidate is incomplete skip it */
2052                 if (ast_strlen_zero(address) || ast_strlen_zero(port) || ast_strlen_zero(username) ||
2053                     ast_strlen_zero(name)) {
2054                         jingle_queue_hangup_with_cause(session, AST_CAUSE_PROTOCOL_ERROR);
2055                         ast_log(LOG_ERROR, "Incomplete Google candidate received on session '%s'\n", session->sid);
2056                         return -1;
2057                 }
2058
2059                 /* We only support UDP so skip any other protocols */
2060                 if (!ast_strlen_zero(protocol) && strcasecmp(protocol, "udp")) {
2061                         continue;
2062                 }
2063
2064                 /* We only permit audio and video, not RTCP */
2065                 if (strcasecmp(name, "rtp") && strcasecmp(name, "video_rtp")) {
2066                         continue;
2067                 }
2068
2069                 /* Parse the target information so we can send a STUN request to the candidate */
2070                 if (sscanf(port, "%30d", &real_port) != 1) {
2071                         jingle_queue_hangup_with_cause(session, AST_CAUSE_PROTOCOL_ERROR);
2072                         ast_log(LOG_ERROR, "Invalid Google candidate port '%s' received on session '%s'\n", port, session->sid);
2073                         return -1;
2074                 }
2075                 ast_sockaddr_parse(&target, address, PARSE_PORT_FORBID);
2076                 ast_sockaddr_set_port(&target, real_port);
2077
2078                 /* Per the STUN support Google talk uses combine the two usernames */
2079                 snprintf(combined, sizeof(combined), "%s%s", username, ice->get_ufrag(rtp));
2080
2081                 /* This should appease the masses... we will actually change the remote address when we get their STUN packet */
2082                 ast_rtp_instance_stun_request(rtp, &target, combined);
2083         }
2084
2085         return 0;
2086 }
2087
2088 /*!
2089  * \brief Helper function which locates content stanzas and interprets them
2090  *
2091  * \note The session *must not* be locked before calling this
2092  */
2093 static int jingle_interpret_content(struct jingle_session *session, ikspak *pak)
2094 {
2095         iks *content;
2096         unsigned int changed = 0;
2097         struct ast_channel *chan;
2098
2099         /* Look at the content in the session initiation */
2100         for (content = iks_child(iks_child(pak->x)); content; content = iks_next(content)) {
2101                 char *name;
2102                 struct ast_rtp_instance *rtp = NULL;
2103                 iks *description, *transport;
2104
2105                 if (strcmp(iks_name(content), "content")) {
2106                         continue;
2107                 }
2108
2109                 name = iks_find_attrib(content, "name");
2110
2111                 if (session->transport != JINGLE_TRANSPORT_GOOGLE_V1) {
2112                         /* If this content stanza has no name consider it invalid and move on */
2113                         if (ast_strlen_zero(name) && !(name = iks_find_attrib(content, "jin:name"))) {
2114                                 jingle_queue_hangup_with_cause(session, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
2115                                 ast_log(LOG_ERROR, "Received content without a name on session '%s'\n", session->sid);
2116                                 return -1;
2117                         }
2118
2119                         /* Try to pre-populate which RTP instance this content is relevant to */
2120                         if (!strcmp(session->audio_name, name)) {
2121                                 rtp = session->rtp;
2122                         } else if (!strcmp(session->video_name, name)) {
2123                                 rtp = session->vrtp;
2124                         }
2125                 } else {
2126                         /* Google-V1 has no concept of assocating things like the above does, so since we only support audio over it assume they want audio */
2127                         rtp = session->rtp;
2128                 }
2129
2130                 /* If description information is available use it */
2131                 if ((description = iks_find_with_attrib(content, "description", "xmlns", JINGLE_RTP_NS)) ||
2132                     (description = iks_find_with_attrib(content, "rtp:description", "xmlns:rtp", JINGLE_RTP_NS)) ||
2133                     (description = iks_find_with_attrib(content, "pho:description", "xmlns:pho", GOOGLE_PHONE_NS)) ||
2134                     (description = iks_find_with_attrib(pak->query, "description", "xmlns", GOOGLE_PHONE_NS)) ||
2135                     (description = iks_find_with_attrib(pak->query, "pho:description", "xmlns:pho", GOOGLE_PHONE_NS)) ||
2136                     (description = iks_find_with_attrib(pak->query, "vid:description", "xmlns", GOOGLE_VIDEO_NS))) {
2137                         /* If we failed to do something with the content description abort immediately */
2138                         if (jingle_interpret_description(session, description, name, &rtp)) {
2139                                 return -1;
2140                         }
2141
2142                         /* If we successfully interpret the description then the codecs need updating */
2143                         changed = 1;
2144                 }
2145
2146                 /* If we get past the description handling and we still don't know what RTP instance this is for... it is unknown content */
2147                 if (!rtp) {
2148                         ast_log(LOG_ERROR, "Received a content stanza but have no RTP instance for it on session '%s'\n", session->sid);
2149                         jingle_queue_hangup_with_cause(session, AST_CAUSE_SWITCH_CONGESTION);
2150                         return -1;
2151                 }
2152
2153                 /* If ICE UDP transport information is available use it */
2154                 if ((transport = iks_find_with_attrib(content, "transport", "xmlns", JINGLE_ICE_UDP_NS))) {
2155                         if (jingle_interpret_ice_udp_transport(session, transport, rtp)) {
2156                                 return -1;
2157                         }
2158                 } else if ((transport = iks_find_with_attrib(content, "transport", "xmlns", GOOGLE_TRANSPORT_NS)) ||
2159                            (transport = iks_find_with_attrib(content, "p:transport", "xmlns:p", GOOGLE_TRANSPORT_NS)) ||
2160                            (transport = iks_find_with_attrib(pak->x, "session", "xmlns", GOOGLE_SESSION_NS)) ||
2161                            (transport = iks_find_with_attrib(pak->x, "ses:session", "xmlns:ses", GOOGLE_SESSION_NS))) {
2162                         /* If Google transport support is available use it */
2163                         if (jingle_interpret_google_transport(session, transport, rtp)) {
2164                                 return -1;
2165                         }
2166                 } else if (iks_find(content, "transport")) {
2167                         /* If this is a transport we do not support terminate the session as it probably won't work out in the end */
2168                         jingle_queue_hangup_with_cause(session, AST_CAUSE_FACILITY_NOT_IMPLEMENTED);
2169                         ast_log(LOG_ERROR, "Unsupported transport type received on session '%s'\n", session->sid);
2170                         return -1;
2171                 }
2172         }
2173
2174         if (!changed) {
2175                 return 0;
2176         }
2177
2178         if ((chan = jingle_session_lock_full(session))) {
2179                 struct ast_format fmt;
2180
2181                 ast_format_cap_copy(ast_channel_nativeformats(chan), session->jointcap);
2182                 ast_codec_choose(&session->prefs, session->jointcap, 1, &fmt);
2183                 ast_set_read_format(chan, &fmt);
2184                 ast_set_write_format(chan, &fmt);
2185
2186                 ast_channel_unlock(chan);
2187                 ast_channel_unref(chan);
2188         }
2189         ao2_unlock(session);
2190
2191         return 0;
2192 }
2193
2194 /*! \brief Handler function for the 'session-initiate' action */
2195 static void jingle_action_session_initiate(struct jingle_endpoint *endpoint, struct jingle_session *session, ikspak *pak)
2196 {
2197         char *sid;
2198         enum jingle_transport transport = JINGLE_TRANSPORT_NONE;
2199         struct ast_channel *chan;
2200         int res;
2201
2202         if (session) {
2203                 /* This is a duplicate session setup, so respond accordingly */
2204                 jingle_send_error_response(endpoint->connection, pak, "result", "out-of-order", NULL);
2205                 return;
2206         }
2207
2208         /* Retrieve the session identifier from the message, note that this may alter the transport */
2209         if ((sid = iks_find_attrib(pak->query, "id"))) {
2210                 /* The presence of the session identifier in the 'id' attribute tells us that this is Google-V1 as everything else uses 'sid' */
2211                 transport = JINGLE_TRANSPORT_GOOGLE_V1;
2212         } else if (!(sid = iks_find_attrib(pak->query, "sid"))) {
2213                 jingle_send_error_response(endpoint->connection, pak, "bad-request", NULL, NULL);
2214                 return;
2215         }
2216
2217         /* Create a new local session */
2218         if (!(session = jingle_alloc(endpoint, pak->from->full, sid))) {
2219                 jingle_send_error_response(endpoint->connection, pak, "cancel", "service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'", NULL);
2220                 return;
2221         }
2222
2223         /* If we determined that the transport should change as a result of how we got the SID change it */
2224         if (transport != JINGLE_TRANSPORT_NONE) {
2225                 session->transport = transport;
2226         }
2227
2228         /* Create a new Asterisk channel using the above local session */
2229         if (!(chan = jingle_new(endpoint, session, AST_STATE_DOWN, pak->from->user, NULL, pak->from->full))) {
2230                 ao2_ref(session, -1);
2231                 jingle_send_error_response(endpoint->connection, pak, "cancel", "service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'", NULL);
2232                 return;
2233         }
2234
2235         ao2_link(endpoint->state->sessions, session);
2236
2237         ast_setstate(chan, AST_STATE_RING);
2238         res = ast_pbx_start(chan);
2239
2240         switch (res) {
2241         case AST_PBX_FAILED:
2242                 ast_log(LOG_WARNING, "Failed to start PBX :(\n");
2243                 jingle_send_error_response(endpoint->connection, pak, "cancel", "service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'", NULL);
2244                 session->gone = 1;
2245                 ast_hangup(chan);
2246                 break;
2247         case AST_PBX_CALL_LIMIT:
2248                 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
2249                 jingle_send_error_response(endpoint->connection, pak, "wait", "resource-constraint xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'", NULL);
2250                 ast_hangup(chan);
2251                 break;
2252         case AST_PBX_SUCCESS:
2253                 jingle_send_response(endpoint->connection, pak);
2254
2255                 /* Only send a transport-info message if we successfully interpreted the available content */
2256                 if (!jingle_interpret_content(session, pak)) {
2257                         jingle_send_transport_info(session, iks_find_attrib(pak->x, "from"));
2258                 }
2259                 break;
2260         }
2261 }
2262
2263 /*! \brief Handler function for the 'transport-info' action */
2264 static void jingle_action_transport_info(struct jingle_endpoint *endpoint, struct jingle_session *session, ikspak *pak)
2265 {
2266         if (!session) {
2267                 jingle_send_error_response(endpoint->connection, pak, "cancel", "item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'",
2268                                            "unknown-session xmlns='urn:xmpp:jingle:errors:1'");
2269                 return;
2270         }
2271
2272         jingle_interpret_content(session, pak);
2273         jingle_send_response(endpoint->connection, pak);
2274 }
2275
2276 /*! \brief Handler function for the 'session-accept' action */
2277 static void jingle_action_session_accept(struct jingle_endpoint *endpoint, struct jingle_session *session, ikspak *pak)
2278 {
2279         struct ast_channel *chan;
2280
2281         if (!session) {
2282                 jingle_send_error_response(endpoint->connection, pak, "cancel", "item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'",
2283                                            "unknown-session xmlns='urn:xmpp:jingle:errors:1'");
2284                 return;
2285         }
2286
2287
2288         jingle_interpret_content(session, pak);
2289
2290         if ((chan = jingle_session_lock_full(session))) {
2291                 ast_queue_control(chan, AST_CONTROL_ANSWER);
2292                 ast_channel_unlock(chan);
2293                 ast_channel_unref(chan);
2294         }
2295         ao2_unlock(session);
2296
2297         jingle_send_response(endpoint->connection, pak);
2298 }
2299
2300 /*! \brief Handler function for the 'session-info' action */
2301 static void jingle_action_session_info(struct jingle_endpoint *endpoint, struct jingle_session *session, ikspak *pak)
2302 {
2303         struct ast_channel *chan;
2304
2305         if (!session) {
2306                 jingle_send_error_response(endpoint->connection, pak, "cancel", "item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'",
2307                                            "unknown-session xmlns='urn:xmpp:jingle:errors:1'");
2308                 return;
2309         }
2310
2311         if (!(chan = jingle_session_lock_full(session))) {
2312                 ao2_unlock(session);
2313                 jingle_send_response(endpoint->connection, pak);
2314                 return;
2315         }
2316
2317         if (iks_find_with_attrib(pak->query, "ringing", "xmlns", JINGLE_RTP_INFO_NS)) {
2318                 ast_queue_control(chan, AST_CONTROL_RINGING);
2319                 if (ast_channel_state(chan) != AST_STATE_UP) {
2320                         ast_setstate(chan, AST_STATE_RINGING);
2321                 }
2322         } else if (iks_find_with_attrib(pak->query, "hold", "xmlns", JINGLE_RTP_INFO_NS)) {
2323                 ast_queue_control(chan, AST_CONTROL_HOLD);
2324         } else if (iks_find_with_attrib(pak->query, "unhold", "xmlns", JINGLE_RTP_INFO_NS)) {
2325                 ast_queue_control(chan, AST_CONTROL_UNHOLD);
2326         }
2327
2328         ast_channel_unlock(chan);
2329         ast_channel_unref(chan);
2330         ao2_unlock(session);
2331
2332         jingle_send_response(endpoint->connection, pak);
2333 }
2334
2335 /*! \brief Handler function for the 'session-terminate' action */
2336 static void jingle_action_session_terminate(struct jingle_endpoint *endpoint, struct jingle_session *session, ikspak *pak)
2337 {
2338         struct ast_channel *chan;
2339         iks *reason, *text;
2340         int cause = AST_CAUSE_NORMAL;
2341
2342         if (!session) {
2343                 jingle_send_error_response(endpoint->connection, pak, "cancel", "item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'",
2344                                            "unknown-session xmlns='urn:xmpp:jingle:errors:1'");
2345                 return;
2346         }
2347
2348         if (!(chan = jingle_session_lock_full(session))) {
2349                 ao2_unlock(session);
2350                 jingle_send_response(endpoint->connection, pak);
2351                 return;
2352         }
2353
2354         /* Pull the reason text from the session-terminate message and translate it into a cause code */
2355         if ((reason = iks_find(pak->query, "reason")) && (text = iks_child(reason))) {
2356                 int i;
2357
2358                 /* Get the appropriate cause code mapping for this reason */
2359                 for (i = 0; i < ARRAY_LEN(jingle_reason_mappings); i++) {
2360                         if (!strcasecmp(jingle_reason_mappings[i].reason, iks_name(text))) {
2361                                 cause = jingle_reason_mappings[i].cause;
2362                                 break;
2363                         }
2364                 }
2365         }
2366
2367         ast_debug(3, "Hanging up channel '%s' due to session terminate message with cause '%d'\n", ast_channel_name(chan), cause);
2368         ast_queue_hangup_with_cause(chan, cause);
2369         session->gone = 1;
2370
2371         ast_channel_unlock(chan);
2372         ast_channel_unref(chan);
2373         ao2_unlock(session);
2374
2375         jingle_send_response(endpoint->connection, pak);
2376 }
2377
2378 /*! \brief Callback for when a Jingle action is received from an endpoint */
2379 static int jingle_action_hook(void *data, ikspak *pak)
2380 {
2381         char *action;
2382         const char *sid = NULL;
2383         struct jingle_session *session = NULL;
2384         struct jingle_endpoint *endpoint = data;
2385         int i, handled = 0;
2386
2387         /* We accept both Jingle and Google-V1 */
2388         if (!(action = iks_find_attrib(pak->query, "action")) &&
2389             !(action = iks_find_attrib(pak->query, "type"))) {
2390                 /* This occurs if either receive a packet masquerading as Jingle or Google-V1 that is actually not OR we receive a response
2391                  * to a message that has no response hook. */
2392                 return IKS_FILTER_EAT;
2393         }
2394
2395         /* Bump the endpoint reference count up in case a reload occurs. Unfortunately the available synchronization between iksemel and us
2396          * does not permit us to make this completely safe. */
2397         ao2_ref(endpoint, +1);
2398
2399         /* If a Jingle session identifier is present use it */
2400         if (!(sid = iks_find_attrib(pak->query, "sid"))) {
2401                 /* If a Google-V1 session identifier is present use it */
2402                 sid = iks_find_attrib(pak->query, "id");
2403         }
2404
2405         /* If a session identifier was present in the message attempt to find the session, it is up to the action handler whether
2406          * this is required or not */
2407         if (!ast_strlen_zero(sid)) {
2408                 session = ao2_find(endpoint->state->sessions, sid, OBJ_KEY);
2409         }
2410
2411         /* If a session is present associate the callid with this thread */
2412         if (session) {
2413                 ast_callid_threadassoc_add(session->callid);
2414         }
2415
2416         /* Iterate through supported action handlers looking for one that is able to handle this */
2417         for (i = 0; i < ARRAY_LEN(jingle_action_handlers); i++) {
2418                 if (!strcasecmp(jingle_action_handlers[i].action, action)) {
2419                         jingle_action_handlers[i].handler(endpoint, session, pak);
2420                         handled = 1;
2421                         break;
2422                 }
2423         }
2424
2425         /* If no action handler is present for the action they sent us make it evident */
2426         if (!handled) {
2427                 ast_log(LOG_NOTICE, "Received action '%s' for session '%s' that has no handler\n", action, sid);
2428         }
2429
2430         /* If a session was successfully found for this message deref it now since the handler is done */
2431         if (session) {
2432                 ast_callid_threadassoc_remove();
2433                 ao2_ref(session, -1);
2434         }
2435
2436         ao2_ref(endpoint, -1);
2437
2438         return IKS_FILTER_EAT;
2439 }
2440
2441 /*! \brief Custom handler for groups */
2442 static int custom_group_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
2443 {
2444         struct jingle_endpoint *endpoint = obj;
2445
2446         if (!strcasecmp(var->name, "callgroup")) {
2447                 endpoint->callgroup = ast_get_group(var->value);
2448         } else if (!strcasecmp(var->name, "pickupgroup")) {
2449                 endpoint->pickupgroup = ast_get_group(var->value);
2450         } else {
2451                 return -1;
2452         }
2453
2454         return 0;
2455 }
2456
2457 /*! \brief Custom handler for connection */
2458 static int custom_connection_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
2459 {
2460         struct jingle_endpoint *endpoint = obj;
2461
2462         /* You might think... but Josh, shouldn't you do this in a prelink callback? Well I *could* but until the original is destroyed
2463          * this will not actually get called, so even if the config turns out to be bogus this is harmless.
2464          */
2465         if (!(endpoint->connection = ast_xmpp_client_find(var->value))) {
2466                 ast_log(LOG_ERROR, "Connection '%s' configured on endpoint '%s' could not be found\n", var->value, endpoint->name);
2467                 return -1;
2468         }
2469
2470         if (!(endpoint->rule = iks_filter_add_rule(endpoint->connection->filter, jingle_action_hook, endpoint,
2471                                                    IKS_RULE_TYPE, IKS_PAK_IQ,
2472                                                    IKS_RULE_NS, JINGLE_NS,
2473                                                    IKS_RULE_NS, GOOGLE_SESSION_NS,
2474                                                    IKS_RULE_DONE))) {
2475                 ast_log(LOG_ERROR, "Action hook could not be added to connection '%s' on endpoint '%s'\n", var->value, endpoint->name);
2476                 return -1;
2477         }
2478
2479         return 0;
2480 }
2481
2482 /*! \brief Custom handler for transport */
2483 static int custom_transport_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
2484 {
2485         struct jingle_endpoint *endpoint = obj;
2486
2487         if (!strcasecmp(var->value, "ice-udp")) {
2488                 endpoint->transport = JINGLE_TRANSPORT_ICE_UDP;
2489         } else if (!strcasecmp(var->value, "google")) {
2490                 endpoint->transport = JINGLE_TRANSPORT_GOOGLE_V2;
2491         } else if (!strcasecmp(var->value, "google-v1")) {
2492                 endpoint->transport = JINGLE_TRANSPORT_GOOGLE_V1;
2493         } else {
2494                 ast_log(LOG_WARNING, "Unknown transport type '%s' on endpoint '%s', defaulting to 'ice-udp'\n", var->value, endpoint->name);
2495                 endpoint->transport = JINGLE_TRANSPORT_ICE_UDP;
2496         }
2497
2498         return 0;
2499 }
2500
2501 /*! \brief Load module into PBX, register channel */
2502 static int load_module(void)
2503 {
2504         if (!(jingle_tech.capabilities = ast_format_cap_alloc())) {
2505                 return AST_MODULE_LOAD_DECLINE;
2506         }
2507
2508         if (aco_info_init(&cfg_info)) {
2509                 ast_log(LOG_ERROR, "Unable to intialize configuration for chan_motif.\n");
2510                 goto end;
2511         }
2512
2513         aco_option_register(&cfg_info, "context", ACO_EXACT, endpoint_options, "default", OPT_STRINGFIELD_T, 0, STRFLDSET(struct jingle_endpoint, context));
2514         aco_option_register_custom(&cfg_info, "callgroup", ACO_EXACT, endpoint_options, NULL, custom_group_handler, 0);
2515         aco_option_register_custom(&cfg_info, "pickupgroup", ACO_EXACT, endpoint_options, NULL, custom_group_handler, 0);
2516         aco_option_register(&cfg_info, "language", ACO_EXACT, endpoint_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct jingle_endpoint, language));
2517         aco_option_register(&cfg_info, "musicclass", ACO_EXACT, endpoint_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct jingle_endpoint, musicclass));
2518         aco_option_register(&cfg_info, "parkinglot", ACO_EXACT, endpoint_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct jingle_endpoint, parkinglot));
2519         aco_option_register(&cfg_info, "accountcode", ACO_EXACT, endpoint_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct jingle_endpoint, accountcode));
2520         aco_option_register(&cfg_info, "allow", ACO_EXACT, endpoint_options, "ulaw,alaw", OPT_CODEC_T, 1, FLDSET(struct jingle_endpoint, prefs, cap));
2521         aco_option_register(&cfg_info, "disallow", ACO_EXACT, endpoint_options, "all", OPT_CODEC_T, 0, FLDSET(struct jingle_endpoint, prefs, cap));
2522         aco_option_register_custom(&cfg_info, "connection", ACO_EXACT, endpoint_options, NULL, custom_connection_handler, 0);
2523         aco_option_register_custom(&cfg_info, "transport", ACO_EXACT, endpoint_options, NULL, custom_transport_handler, 0);
2524         aco_option_register(&cfg_info, "maxicecandidates", ACO_EXACT, endpoint_options, DEFAULT_MAX_ICE_CANDIDATES, OPT_UINT_T, PARSE_DEFAULT,
2525                             FLDSET(struct jingle_endpoint, maxicecandidates));
2526         aco_option_register(&cfg_info, "maxpayloads", ACO_EXACT, endpoint_options, DEFAULT_MAX_PAYLOADS, OPT_UINT_T, PARSE_DEFAULT,
2527                             FLDSET(struct jingle_endpoint, maxpayloads));
2528
2529         ast_format_cap_add_all_by_type(jingle_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
2530
2531         if (aco_process_config(&cfg_info, 0)) {
2532                 ast_log(LOG_ERROR, "Unable to read config file motif.conf. Not loading module.\n");
2533                 aco_info_destroy(&cfg_info);
2534                 return AST_MODULE_LOAD_DECLINE;
2535         }
2536
2537         if (!(sched = ast_sched_context_create())) {
2538                 ast_log(LOG_ERROR, "Unable to create scheduler context.\n");
2539                 goto end;
2540         }
2541
2542         if (ast_sched_start_thread(sched)) {
2543                 ast_log(LOG_ERROR, "Unable to create scheduler context thread.\n");
2544                 goto end;
2545         }
2546
2547         ast_rtp_glue_register(&jingle_rtp_glue);
2548
2549         if (ast_channel_register(&jingle_tech)) {
2550                 ast_log(LOG_ERROR, "Unable to register channel class %s\n", channel_type);
2551                 goto end;
2552         }
2553
2554         return 0;
2555
2556 end:
2557         ast_rtp_glue_unregister(&jingle_rtp_glue);
2558
2559         if (sched) {
2560                 ast_sched_context_destroy(sched);
2561         }
2562
2563         aco_info_destroy(&cfg_info);
2564
2565         return AST_MODULE_LOAD_FAILURE;
2566 }
2567
2568 /*! \brief Reload module */
2569 static int reload(void)
2570 {
2571         return aco_process_config(&cfg_info, 1);
2572 }
2573
2574 /*! \brief Unload the jingle channel from Asterisk */
2575 static int unload_module(void)
2576 {
2577         ast_channel_unregister(&jingle_tech);
2578         ast_rtp_glue_unregister(&jingle_rtp_glue);
2579         ast_sched_context_destroy(sched);
2580         aco_info_destroy(&cfg_info);
2581         ao2_global_obj_release(globals);
2582
2583         return 0;
2584 }
2585
2586 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Motif Jingle Channel Driver",
2587                 .load = load_module,
2588                 .unload = unload_module,
2589                 .reload = reload,
2590                 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
2591                );