Constify some more channel driver technology callback parameters.
[asterisk/asterisk.git] / channels / chan_jingle.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Matt O'Gorman <mogorman@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 Matt O'Gorman <mogorman@digium.com>
22  *
23  * \brief 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_jabber</depend>
33         <use type="external">openssl</use>
34         <defaultenabled>no</defaultenabled>
35         <support_level>extended</support_level>
36  ***/
37
38 #include "asterisk.h"
39
40 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
41
42 #include <sys/socket.h>
43 #include <fcntl.h>
44 #include <netdb.h>
45 #include <netinet/in.h>
46 #include <arpa/inet.h>
47 #include <sys/signal.h>
48 #include <iksemel.h>
49 #include <pthread.h>
50
51 #include "asterisk/lock.h"
52 #include "asterisk/channel.h"
53 #include "asterisk/config.h"
54 #include "asterisk/module.h"
55 #include "asterisk/pbx.h"
56 #include "asterisk/sched.h"
57 #include "asterisk/io.h"
58 #include "asterisk/rtp_engine.h"
59 #include "asterisk/acl.h"
60 #include "asterisk/callerid.h"
61 #include "asterisk/file.h"
62 #include "asterisk/cli.h"
63 #include "asterisk/app.h"
64 #include "asterisk/musiconhold.h"
65 #include "asterisk/manager.h"
66 #include "asterisk/stringfields.h"
67 #include "asterisk/utils.h"
68 #include "asterisk/causes.h"
69 #include "asterisk/astobj.h"
70 #include "asterisk/abstract_jb.h"
71 #include "asterisk/jabber.h"
72 #include "asterisk/jingle.h"
73
74 #define JINGLE_CONFIG "jingle.conf"
75
76 /*! Global jitterbuffer configuration - by default, jb is disabled */
77 static struct ast_jb_conf default_jbconf =
78 {
79         .flags = 0,
80         .max_size = -1,
81         .resync_threshold = -1,
82         .impl = "",
83         .target_extra = -1,
84 };
85 static struct ast_jb_conf global_jbconf;
86
87 enum jingle_protocol {
88         AJI_PROTOCOL_UDP,
89         AJI_PROTOCOL_SSLTCP,
90 };
91
92 enum jingle_connect_type {
93         AJI_CONNECT_HOST,
94         AJI_CONNECT_PRFLX,
95         AJI_CONNECT_RELAY,
96         AJI_CONNECT_SRFLX,
97 };
98
99 struct jingle_pvt {
100         ast_mutex_t lock;                /*!< Channel private lock */
101         time_t laststun;
102         struct jingle *parent;           /*!< Parent client */
103         char sid[100];
104         char them[AJI_MAX_JIDLEN];
105         char ring[10];                   /*!< Message ID of ring */
106         iksrule *ringrule;               /*!< Rule for matching RING request */
107         int initiator;                   /*!< If we're the initiator */
108         int alreadygone;
109         struct ast_codec_pref prefs;
110         struct jingle_candidate *theircandidates;
111         struct jingle_candidate *ourcandidates;
112         char cid_num[80];                /*!< Caller ID num */
113         char cid_name[80];               /*!< Caller ID name */
114         char exten[80];                  /*!< Called extension */
115         struct ast_channel *owner;       /*!< Master Channel */
116         char audio_content_name[100];    /*!< name attribute of content tag */
117         struct ast_rtp_instance *rtp;             /*!< RTP audio session */
118         char video_content_name[100];    /*!< name attribute of content tag */
119         struct ast_rtp_instance *vrtp;            /*!< RTP video session */
120         struct ast_format_cap *cap;
121         struct ast_format_cap *jointcap;             /*!< Supported capability at both ends (codecs ) */
122         struct ast_format_cap *peercap;
123         struct jingle_pvt *next;        /* Next entity */
124 };
125
126 struct jingle_candidate {
127         unsigned int component;          /*!< ex. : 1 for RTP, 2 for RTCP */
128         unsigned int foundation;         /*!< Function of IP, protocol, type */
129         unsigned int generation;
130         char ip[16];
131         unsigned int network;
132         unsigned int port;
133         unsigned int priority;
134         enum jingle_protocol protocol;
135         char password[100];
136         enum jingle_connect_type type;
137         char ufrag[100];
138         unsigned int preference;
139         struct jingle_candidate *next;
140 };
141
142 struct jingle {
143         ASTOBJ_COMPONENTS(struct jingle);
144         struct aji_client *connection;
145         struct aji_buddy *buddy;
146         struct jingle_pvt *p;
147         struct ast_codec_pref prefs;
148         int amaflags;                   /*!< AMA Flags */
149         char user[100];
150         char context[100];
151         char accountcode[AST_MAX_ACCOUNT_CODE]; /*!< Account code */
152         struct ast_format_cap *cap;
153         ast_group_t callgroup;  /*!< Call group */
154         ast_group_t pickupgroup;        /*!< Pickup group */
155         int callingpres;                /*!< Calling presentation */
156         int allowguest;
157         char language[MAX_LANGUAGE];    /*!<  Default language for prompts */
158         char musicclass[MAX_MUSICCLASS];        /*!<  Music on Hold class */
159         char parkinglot[AST_MAX_CONTEXT];   /*!< Parkinglot */
160 };
161
162 struct jingle_container {
163         ASTOBJ_CONTAINER_COMPONENTS(struct jingle);
164 };
165
166 static const char desc[] = "Jingle Channel";
167 static const char channel_type[] = "Jingle";
168
169 static struct ast_format_cap *global_capability;
170
171 AST_MUTEX_DEFINE_STATIC(jinglelock); /*!< Protect the interface list (of jingle_pvt's) */
172
173 /* Forward declarations */
174 static struct ast_channel *jingle_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
175 static int jingle_sendtext(struct ast_channel *ast, const char *text);
176 static int jingle_digit_begin(struct ast_channel *ast, char digit);
177 static int jingle_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
178 static int jingle_call(struct ast_channel *ast, const char *dest, int timeout);
179 static int jingle_hangup(struct ast_channel *ast);
180 static int jingle_answer(struct ast_channel *ast);
181 static int jingle_newcall(struct jingle *client, ikspak *pak);
182 static struct ast_frame *jingle_read(struct ast_channel *ast);
183 static int jingle_write(struct ast_channel *ast, struct ast_frame *f);
184 static int jingle_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
185 static int jingle_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
186 static int jingle_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
187 static struct jingle_pvt *jingle_alloc(struct jingle *client, const char *from, const char *sid);
188 static char *jingle_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
189 static char *jingle_do_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
190
191 /*! \brief PBX interface structure for channel registration */
192 static struct ast_channel_tech jingle_tech = {
193         .type = "Jingle",
194         .description = "Jingle Channel Driver",
195         .requester = jingle_request,
196         .send_text = jingle_sendtext,
197         .send_digit_begin = jingle_digit_begin,
198         .send_digit_end = jingle_digit_end,
199         .bridge = ast_rtp_instance_bridge,
200         .call = jingle_call,
201         .hangup = jingle_hangup,
202         .answer = jingle_answer,
203         .read = jingle_read,
204         .write = jingle_write,
205         .exception = jingle_read,
206         .indicate = jingle_indicate,
207         .fixup = jingle_fixup,
208         .send_html = jingle_sendhtml,
209         .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER
210 };
211
212 static struct sockaddr_in bindaddr = { 0, };    /*!< The address we bind to */
213
214 static struct ast_sched_context *sched; /*!< The scheduling context */
215 static struct io_context *io;   /*!< The IO context */
216 static struct in_addr __ourip;
217
218 static struct ast_cli_entry jingle_cli[] = {
219         AST_CLI_DEFINE(jingle_do_reload, "Reload Jingle configuration"),
220         AST_CLI_DEFINE(jingle_show_channels, "Show Jingle channels"),
221 };
222
223
224 static char externip[16];
225
226 static struct jingle_container jingle_list;
227
228 static void jingle_member_destroy(struct jingle *obj)
229 {
230         obj->cap = ast_format_cap_destroy(obj->cap);
231         if (obj->connection) {
232                 ASTOBJ_UNREF(obj->connection, ast_aji_client_destroy);
233         }
234         if (obj->buddy) {
235                 ASTOBJ_UNREF(obj->buddy, ast_aji_buddy_destroy);
236         }
237         ast_free(obj);
238 }
239
240 /* XXX This could be a source of reference leaks given that the CONTAINER_FIND
241  * macros bump the refcount while the traversal does not. */
242 static struct jingle *find_jingle(char *name, char *connection)
243 {
244         struct jingle *jingle = NULL;
245
246         jingle = ASTOBJ_CONTAINER_FIND(&jingle_list, name);
247         if (!jingle && strchr(name, '@'))
248                 jingle = ASTOBJ_CONTAINER_FIND_FULL(&jingle_list, name, user,,, strcasecmp);
249
250         if (!jingle) {                          
251                 /* guest call */
252                 ASTOBJ_CONTAINER_TRAVERSE(&jingle_list, 1, {
253                         ASTOBJ_RDLOCK(iterator);
254                         if (!strcasecmp(iterator->name, "guest")) {
255                                 jingle = iterator;
256                         }
257                         ASTOBJ_UNLOCK(iterator);
258
259                         if (jingle)
260                                 break;
261                 });
262
263         }
264         return jingle;
265 }
266
267
268 static void add_codec_to_answer(const struct jingle_pvt *p, struct ast_format *codec, iks *dcodecs)
269 {
270         const char *format = ast_getformatname(codec);
271
272         if (!strcasecmp("ulaw", format)) {
273                 iks *payload_eg711u, *payload_pcmu;
274                 payload_pcmu = iks_new("payload-type");
275                 iks_insert_attrib(payload_pcmu, "id", "0");
276                 iks_insert_attrib(payload_pcmu, "name", "PCMU");
277                 payload_eg711u = iks_new("payload-type");
278                 iks_insert_attrib(payload_eg711u, "id", "100");
279                 iks_insert_attrib(payload_eg711u, "name", "EG711U");
280                 iks_insert_node(dcodecs, payload_pcmu);
281                 iks_insert_node(dcodecs, payload_eg711u);
282         }
283         if (!strcasecmp("alaw", format)) {
284                 iks *payload_eg711a;
285                 iks *payload_pcma = iks_new("payload-type");
286                 iks_insert_attrib(payload_pcma, "id", "8");
287                 iks_insert_attrib(payload_pcma, "name", "PCMA");
288                 payload_eg711a = iks_new("payload-type");
289                 iks_insert_attrib(payload_eg711a, "id", "101");
290                 iks_insert_attrib(payload_eg711a, "name", "EG711A");
291                 iks_insert_node(dcodecs, payload_pcma);
292                 iks_insert_node(dcodecs, payload_eg711a);
293         }
294         if (!strcasecmp("ilbc", format)) {
295                 iks *payload_ilbc = iks_new("payload-type");
296                 iks_insert_attrib(payload_ilbc, "id", "97");
297                 iks_insert_attrib(payload_ilbc, "name", "iLBC");
298                 iks_insert_node(dcodecs, payload_ilbc);
299         }
300         if (!strcasecmp("g723", format)) {
301                 iks *payload_g723 = iks_new("payload-type");
302                 iks_insert_attrib(payload_g723, "id", "4");
303                 iks_insert_attrib(payload_g723, "name", "G723");
304                 iks_insert_node(dcodecs, payload_g723);
305         }
306 }
307
308 static int jingle_accept_call(struct jingle *client, struct jingle_pvt *p)
309 {
310         struct jingle_pvt *tmp = client->p;
311         struct aji_client *c = client->connection;
312         iks *iq, *jingle, *dcodecs, *payload_red, *payload_audio, *payload_cn;
313         int x;
314         struct ast_format pref_codec;
315         struct ast_format_cap *alreadysent = ast_format_cap_alloc_nolock();
316
317         if (p->initiator || !alreadysent)
318                 return 1;
319
320         iq = iks_new("iq");
321         jingle = iks_new(JINGLE_NODE);
322         dcodecs = iks_new("description");
323         if (iq && jingle && dcodecs) {
324                 iks_insert_attrib(dcodecs, "xmlns", JINGLE_AUDIO_RTP_NS);
325
326                 for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
327                         if (!(ast_codec_pref_index(&client->prefs, x, &pref_codec)))
328                                 break;
329                         if (!(ast_format_cap_iscompatible(client->cap, &pref_codec)))
330                                 continue;
331                         if ((ast_format_cap_iscompatible(alreadysent, &pref_codec)))
332                                 continue;
333                         add_codec_to_answer(p, &pref_codec, dcodecs);
334                         ast_format_cap_add(alreadysent, &pref_codec);
335                 }
336                 payload_red = iks_new("payload-type");
337                 iks_insert_attrib(payload_red, "id", "117");
338                 iks_insert_attrib(payload_red, "name", "red");
339                 payload_audio = iks_new("payload-type");
340                 iks_insert_attrib(payload_audio, "id", "106");
341                 iks_insert_attrib(payload_audio, "name", "audio/telephone-event");
342                 payload_cn = iks_new("payload-type");
343                 iks_insert_attrib(payload_cn, "id", "13");
344                 iks_insert_attrib(payload_cn, "name", "CN");
345
346
347                 iks_insert_attrib(iq, "type", "set");
348                 iks_insert_attrib(iq, "to", (p->them) ? p->them : client->user);
349                 iks_insert_attrib(iq, "id", client->connection->mid);
350                 ast_aji_increment_mid(client->connection->mid);
351
352                 iks_insert_attrib(jingle, "xmlns", JINGLE_NS);
353                 iks_insert_attrib(jingle, "action", JINGLE_ACCEPT);
354                 iks_insert_attrib(jingle, "initiator", p->initiator ? client->connection->jid->full : p->them);
355                 iks_insert_attrib(jingle, JINGLE_SID, tmp->sid);
356                 iks_insert_node(iq, jingle);
357                 iks_insert_node(jingle, dcodecs);
358                 iks_insert_node(dcodecs, payload_red);
359                 iks_insert_node(dcodecs, payload_audio);
360                 iks_insert_node(dcodecs, payload_cn);
361
362                 ast_aji_send(c, iq);
363
364                 iks_delete(payload_red);
365                 iks_delete(payload_audio);
366                 iks_delete(payload_cn);
367                 iks_delete(dcodecs);
368                 iks_delete(jingle);
369                 iks_delete(iq);
370         }
371         alreadysent = ast_format_cap_destroy(alreadysent);
372         return 1;
373 }
374
375 static int jingle_ringing_ack(void *data, ikspak *pak)
376 {
377         struct jingle_pvt *p = data;
378
379         if (p->ringrule)
380                 iks_filter_remove_rule(p->parent->connection->f, p->ringrule);
381         p->ringrule = NULL;
382         if (p->owner)
383                 ast_queue_control(p->owner, AST_CONTROL_RINGING);
384         return IKS_FILTER_EAT;
385 }
386
387 static int jingle_answer(struct ast_channel *ast)
388 {
389         struct jingle_pvt *p = ast->tech_pvt;
390         struct jingle *client = p->parent;
391         int res = 0;
392
393         ast_debug(1, "Answer!\n");
394         ast_mutex_lock(&p->lock);
395         jingle_accept_call(client, p);
396         ast_mutex_unlock(&p->lock);
397         return res;
398 }
399
400 static enum ast_rtp_glue_result jingle_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
401 {
402         struct jingle_pvt *p = chan->tech_pvt;
403         enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID;
404
405         if (!p)
406                 return res;
407
408         ast_mutex_lock(&p->lock);
409         if (p->rtp) {
410                 ao2_ref(p->rtp, +1);
411                 *instance = p->rtp;
412                 res = AST_RTP_GLUE_RESULT_LOCAL;
413         }
414         ast_mutex_unlock(&p->lock);
415
416         return res;
417 }
418
419 static void jingle_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
420 {
421         struct jingle_pvt *p = chan->tech_pvt;
422         ast_mutex_lock(&p->lock);
423         ast_format_cap_copy(result, p->peercap);
424         ast_mutex_unlock(&p->lock);
425 }
426
427 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)
428 {
429         struct jingle_pvt *p;
430
431         p = chan->tech_pvt;
432         if (!p)
433                 return -1;
434         ast_mutex_lock(&p->lock);
435
436 /*      if (rtp)
437                 ast_rtp_get_peer(rtp, &p->redirip);
438         else
439                 memset(&p->redirip, 0, sizeof(p->redirip));
440         p->redircodecs = codecs; */
441
442         /* Reset lastrtprx timer */
443         ast_mutex_unlock(&p->lock);
444         return 0;
445 }
446
447 static struct ast_rtp_glue jingle_rtp_glue = {
448         .type = "Jingle",
449         .get_rtp_info = jingle_get_rtp_peer,
450         .get_codec = jingle_get_codec,
451         .update_peer = jingle_set_rtp_peer,
452 };
453
454 static int jingle_response(struct jingle *client, ikspak *pak, const char *reasonstr, const char *reasonstr2)
455 {
456         iks *response = NULL, *error = NULL, *reason = NULL;
457         int res = -1;
458
459         response = iks_new("iq");
460         if (response) {
461                 iks_insert_attrib(response, "type", "result");
462                 iks_insert_attrib(response, "from", client->connection->jid->full);
463                 iks_insert_attrib(response, "to", iks_find_attrib(pak->x, "from"));
464                 iks_insert_attrib(response, "id", iks_find_attrib(pak->x, "id"));
465                 if (reasonstr) {
466                         error = iks_new("error");
467                         if (error) {
468                                 iks_insert_attrib(error, "type", "cancel");
469                                 reason = iks_new(reasonstr);
470                                 if (reason)
471                                         iks_insert_node(error, reason);
472                                 iks_insert_node(response, error);
473                         }
474                 }
475                 ast_aji_send(client->connection, response);
476                 res = 0;
477         }
478         
479         iks_delete(reason);
480         iks_delete(error);
481         iks_delete(response);
482
483         return res;
484 }
485
486 static int jingle_is_answered(struct jingle *client, ikspak *pak)
487 {
488         struct jingle_pvt *tmp;
489
490         ast_debug(1, "The client is %s\n", client->name);
491         /* Make sure our new call doesn't exist yet */
492         for (tmp = client->p; tmp; tmp = tmp->next) {
493                 if (iks_find_with_attrib(pak->x, JINGLE_NODE, JINGLE_SID, tmp->sid))
494                         break;
495         }
496
497         if (tmp) {
498                 if (tmp->owner)
499                         ast_queue_control(tmp->owner, AST_CONTROL_ANSWER);
500         } else
501                 ast_log(LOG_NOTICE, "Whoa, didn't find call!\n");
502         jingle_response(client, pak, NULL, NULL);
503         return 1;
504 }
505
506 static int jingle_handle_dtmf(struct jingle *client, ikspak *pak)
507 {
508         struct jingle_pvt *tmp;
509         iks *dtmfnode = NULL, *dtmfchild = NULL;
510         char *dtmf;
511         /* Make sure our new call doesn't exist yet */
512         for (tmp = client->p; tmp; tmp = tmp->next) {
513                 if (iks_find_with_attrib(pak->x, JINGLE_NODE, JINGLE_SID, tmp->sid))
514                         break;
515         }
516
517         if (tmp) {
518                 if(iks_find_with_attrib(pak->x, "dtmf-method", "method", "rtp")) {
519                         jingle_response(client,pak,
520                                         "feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'",
521                                         "unsupported-dtmf-method xmlns='http://www.xmpp.org/extensions/xep-0181.html#ns-errors'");
522                         return -1;
523                 }
524                 if ((dtmfnode = iks_find(pak->x, "dtmf"))) {
525                         if((dtmf = iks_find_attrib(dtmfnode, "code"))) {
526                                 if(iks_find_with_attrib(pak->x, "dtmf", "action", "button-up")) {
527                                         struct ast_frame f = {AST_FRAME_DTMF_BEGIN, };
528                                         f.subclass.integer = dtmf[0];
529                                         ast_queue_frame(tmp->owner, &f);
530                                         ast_verbose("JINGLE! DTMF-relay event received: %c\n", f.subclass.integer);
531                                 } else if(iks_find_with_attrib(pak->x, "dtmf", "action", "button-down")) {
532                                         struct ast_frame f = {AST_FRAME_DTMF_END, };
533                                         f.subclass.integer = dtmf[0];
534                                         ast_queue_frame(tmp->owner, &f);
535                                         ast_verbose("JINGLE! DTMF-relay event received: %c\n", f.subclass.integer);
536                                 } else if(iks_find_attrib(pak->x, "dtmf")) { /* 250 millasecond default */
537                                         struct ast_frame f = {AST_FRAME_DTMF, };
538                                         f.subclass.integer = dtmf[0];
539                                         ast_queue_frame(tmp->owner, &f);
540                                         ast_verbose("JINGLE! DTMF-relay event received: %c\n", f.subclass.integer);
541                                 }
542                         }
543                 } else if ((dtmfnode = iks_find_with_attrib(pak->x, JINGLE_NODE, "action", "session-info"))) {
544                         if((dtmfchild = iks_find(dtmfnode, "dtmf"))) {
545                                 if((dtmf = iks_find_attrib(dtmfchild, "code"))) {
546                                         if(iks_find_with_attrib(dtmfnode, "dtmf", "action", "button-up")) {
547                                                 struct ast_frame f = {AST_FRAME_DTMF_END, };
548                                                 f.subclass.integer = dtmf[0];
549                                                 ast_queue_frame(tmp->owner, &f);
550                                                 ast_verbose("JINGLE! DTMF-relay event received: %c\n", f.subclass.integer);
551                                         } else if(iks_find_with_attrib(dtmfnode, "dtmf", "action", "button-down")) {
552                                                 struct ast_frame f = {AST_FRAME_DTMF_BEGIN, };
553                                                 f.subclass.integer = dtmf[0];
554                                                 ast_queue_frame(tmp->owner, &f);
555                                                 ast_verbose("JINGLE! DTMF-relay event received: %c\n", f.subclass.integer);
556                                         }
557                                 }
558                         }
559                 }
560                 jingle_response(client, pak, NULL, NULL);
561                 return 1;
562         } else
563                 ast_log(LOG_NOTICE, "Whoa, didn't find call!\n");
564
565         jingle_response(client, pak, NULL, NULL);
566         return 1;
567 }
568
569
570 static int jingle_hangup_farend(struct jingle *client, ikspak *pak)
571 {
572         struct jingle_pvt *tmp;
573
574         ast_debug(1, "The client is %s\n", client->name);
575         /* Make sure our new call doesn't exist yet */
576         for (tmp = client->p; tmp; tmp = tmp->next) {
577                 if (iks_find_with_attrib(pak->x, JINGLE_NODE, JINGLE_SID, tmp->sid))
578                         break;
579         }
580
581         if (tmp) {
582                 tmp->alreadygone = 1;
583                 if (tmp->owner)
584                         ast_queue_hangup(tmp->owner);
585         } else
586                 ast_log(LOG_NOTICE, "Whoa, didn't find call!\n");
587         jingle_response(client, pak, NULL, NULL);
588         return 1;
589 }
590
591 static int jingle_create_candidates(struct jingle *client, struct jingle_pvt *p, char *sid, char *from)
592 {
593         struct jingle_candidate *tmp;
594         struct aji_client *c = client->connection;
595         struct jingle_candidate *ours1 = NULL, *ours2 = NULL;
596         struct sockaddr_in sin = { 0, };
597         struct ast_sockaddr sin_tmp;
598         struct ast_sockaddr us_tmp;
599         struct ast_sockaddr bindaddr_tmp;
600         struct in_addr us;
601         struct in_addr externaddr;
602         iks *iq, *jingle, *content, *transport, *candidate;
603         char component[16], foundation[16], generation[16], network[16], pass[16], port[7], priority[16], user[16];
604
605
606         iq = iks_new("iq");
607         jingle = iks_new(JINGLE_NODE);
608         content = iks_new("content");
609         transport = iks_new("transport");
610         candidate = iks_new("candidate");
611         if (!iq || !jingle || !content || !transport || !candidate) {
612                 ast_log(LOG_ERROR, "Memory allocation error\n");
613                 goto safeout;
614         }
615         ours1 = ast_calloc(1, sizeof(*ours1));
616         ours2 = ast_calloc(1, sizeof(*ours2));
617         if (!ours1 || !ours2)
618                 goto safeout;
619
620         iks_insert_node(iq, jingle);
621         iks_insert_node(jingle, content);
622         iks_insert_node(content, transport);
623         iks_insert_node(transport, candidate);
624
625         for (; p; p = p->next) {
626                 if (!strcasecmp(p->sid, sid))
627                         break;
628         }
629
630         if (!p) {
631                 ast_log(LOG_NOTICE, "No matching jingle session - SID %s!\n", sid);
632                 goto safeout;
633         }
634
635         ast_rtp_instance_get_local_address(p->rtp, &sin_tmp);
636         ast_sockaddr_to_sin(&sin_tmp, &sin);
637         ast_sockaddr_from_sin(&bindaddr_tmp, &bindaddr);
638         ast_find_ourip(&us_tmp, &bindaddr_tmp, AF_INET);
639         us.s_addr = htonl(ast_sockaddr_ipv4(&us_tmp));
640
641         /* Setup our first jingle candidate */
642         ours1->component = 1;
643         ours1->foundation = (unsigned int)bindaddr.sin_addr.s_addr | AJI_CONNECT_HOST | AJI_PROTOCOL_UDP;
644         ours1->generation = 0;
645         ast_copy_string(ours1->ip, ast_inet_ntoa(us), sizeof(ours1->ip));
646         ours1->network = 0;
647         ours1->port = ntohs(sin.sin_port);
648         ours1->priority = 1678246398;
649         ours1->protocol = AJI_PROTOCOL_UDP;
650         snprintf(pass, sizeof(pass), "%08lx%08lx", ast_random(), ast_random());
651         ast_copy_string(ours1->password, pass, sizeof(ours1->password));
652         ours1->type = AJI_CONNECT_HOST;
653         snprintf(user, sizeof(user), "%08lx%08lx", ast_random(), ast_random());
654         ast_copy_string(ours1->ufrag, user, sizeof(ours1->ufrag));
655         p->ourcandidates = ours1;
656
657         if (!ast_strlen_zero(externip)) {
658                 /* XXX We should really stun for this one not just go with externip XXX */
659                 if (inet_aton(externip, &externaddr))
660                         ast_log(LOG_WARNING, "Invalid extern IP : %s\n", externip);
661
662                 ours2->component = 1;
663                 ours2->foundation = (unsigned int)externaddr.s_addr | AJI_CONNECT_PRFLX | AJI_PROTOCOL_UDP;
664                 ours2->generation = 0;
665                 ast_copy_string(ours2->ip, externip, sizeof(ours2->ip));
666                 ours2->network = 0;
667                 ours2->port = ntohs(sin.sin_port);
668                 ours2->priority = 1678246397;
669                 ours2->protocol = AJI_PROTOCOL_UDP;
670                 snprintf(pass, sizeof(pass), "%08lx%08lx", ast_random(), ast_random());
671                 ast_copy_string(ours2->password, pass, sizeof(ours2->password));
672                 ours2->type = AJI_CONNECT_PRFLX;
673
674                 snprintf(user, sizeof(user), "%08lx%08lx", ast_random(), ast_random());
675                 ast_copy_string(ours2->ufrag, user, sizeof(ours2->ufrag));
676                 ours1->next = ours2;
677                 ours2 = NULL;
678         }
679         ours1 = NULL;
680
681         for (tmp = p->ourcandidates; tmp; tmp = tmp->next) {
682                 snprintf(component, sizeof(component), "%u", tmp->component);
683                 snprintf(foundation, sizeof(foundation), "%u", tmp->foundation);
684                 snprintf(generation, sizeof(generation), "%u", tmp->generation);
685                 snprintf(network, sizeof(network), "%u", tmp->network);
686                 snprintf(port, sizeof(port), "%u", tmp->port);
687                 snprintf(priority, sizeof(priority), "%u", tmp->priority);
688
689                 iks_insert_attrib(iq, "from", c->jid->full);
690                 iks_insert_attrib(iq, "to", from);
691                 iks_insert_attrib(iq, "type", "set");
692                 iks_insert_attrib(iq, "id", c->mid);
693                 ast_aji_increment_mid(c->mid);
694                 iks_insert_attrib(jingle, "action", JINGLE_NEGOTIATE);
695                 iks_insert_attrib(jingle, JINGLE_SID, sid);
696                 iks_insert_attrib(jingle, "initiator", (p->initiator) ? c->jid->full : from);
697                 iks_insert_attrib(jingle, "xmlns", JINGLE_NS);
698                 iks_insert_attrib(content, "creator", p->initiator ? "initiator" : "responder");
699                 iks_insert_attrib(content, "name", "asterisk-audio-content");
700                 iks_insert_attrib(transport, "xmlns", JINGLE_ICE_UDP_NS);
701                 iks_insert_attrib(candidate, "component", component);
702                 iks_insert_attrib(candidate, "foundation", foundation);
703                 iks_insert_attrib(candidate, "generation", generation);
704                 iks_insert_attrib(candidate, "ip", tmp->ip);
705                 iks_insert_attrib(candidate, "network", network);
706                 iks_insert_attrib(candidate, "port", port);
707                 iks_insert_attrib(candidate, "priority", priority);
708                 switch (tmp->protocol) {
709                 case AJI_PROTOCOL_UDP:
710                         iks_insert_attrib(candidate, "protocol", "udp");
711                         break;
712                 case AJI_PROTOCOL_SSLTCP:
713                         iks_insert_attrib(candidate, "protocol", "ssltcp");
714                         break;
715                 }
716                 iks_insert_attrib(candidate, "pwd", tmp->password);
717                 switch (tmp->type) {
718                 case AJI_CONNECT_HOST:
719                         iks_insert_attrib(candidate, "type", "host");
720                         break;
721                 case AJI_CONNECT_PRFLX:
722                         iks_insert_attrib(candidate, "type", "prflx");
723                         break;
724                 case AJI_CONNECT_RELAY:
725                         iks_insert_attrib(candidate, "type", "relay");
726                         break;
727                 case AJI_CONNECT_SRFLX:
728                         iks_insert_attrib(candidate, "type", "srflx");
729                         break;
730                 }
731                 iks_insert_attrib(candidate, "ufrag", tmp->ufrag);
732
733                 ast_aji_send(c, iq);
734         }
735         p->laststun = 0;
736
737 safeout:
738         if (ours1)
739                 ast_free(ours1);
740         if (ours2)
741                 ast_free(ours2);
742         iks_delete(iq);
743         iks_delete(jingle);
744         iks_delete(content);
745         iks_delete(transport);
746         iks_delete(candidate);
747
748         return 1;
749 }
750
751 static struct jingle_pvt *jingle_alloc(struct jingle *client, const char *from, const char *sid)
752 {
753         struct jingle_pvt *tmp = NULL;
754         struct aji_resource *resources = NULL;
755         struct aji_buddy *buddy = NULL;
756         char idroster[200];
757         struct ast_sockaddr bindaddr_tmp;
758
759         ast_debug(1, "The client is %s for alloc\n", client->name);
760         if (!sid && !strchr(from, '/')) {       /* I started call! */
761                 if (!strcasecmp(client->name, "guest")) {
762                         buddy = ASTOBJ_CONTAINER_FIND(&client->connection->buddies, from);
763                         if (buddy) {
764                                 resources = buddy->resources;
765                         }
766                 } else if (client->buddy)
767                         resources = client->buddy->resources;
768                 while (resources) {
769                         if (resources->cap->jingle) {
770                                 break;
771                         }
772                         resources = resources->next;
773                 }
774                 if (resources)
775                         snprintf(idroster, sizeof(idroster), "%s/%s", from, resources->resource);
776                 else {
777                         ast_log(LOG_ERROR, "no jingle capable clients to talk to.\n");
778                         if (buddy) {
779                                 ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy);
780                         }
781                         return NULL;
782                 }
783                 if (buddy) {
784                         ASTOBJ_UNREF(buddy, ast_aji_buddy_destroy);
785                 }
786         }
787         if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
788                 return NULL;
789         }
790
791         tmp->cap = ast_format_cap_alloc_nolock();
792         tmp->jointcap = ast_format_cap_alloc_nolock();
793         tmp->peercap = ast_format_cap_alloc_nolock();
794         if (!tmp->cap || !tmp->jointcap || !tmp->peercap) {
795                 tmp->cap = ast_format_cap_destroy(tmp->cap);
796                 tmp->jointcap = ast_format_cap_destroy(tmp->jointcap);
797                 tmp->peercap = ast_format_cap_destroy(tmp->peercap);
798                 ast_free(tmp);
799                 return NULL;
800         }
801         memcpy(&tmp->prefs, &client->prefs, sizeof(tmp->prefs));
802
803         if (sid) {
804                 ast_copy_string(tmp->sid, sid, sizeof(tmp->sid));
805                 ast_copy_string(tmp->them, from, sizeof(tmp->them));
806         } else {
807                 snprintf(tmp->sid, sizeof(tmp->sid), "%08lx%08lx", ast_random(), ast_random());
808                 ast_copy_string(tmp->them, idroster, sizeof(tmp->them));
809                 tmp->initiator = 1;
810         }
811         ast_sockaddr_from_sin(&bindaddr_tmp, &bindaddr);
812         tmp->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL);
813         tmp->parent = client;
814         if (!tmp->rtp) {
815                 ast_log(LOG_WARNING, "Out of RTP sessions?\n");
816                 ast_free(tmp);
817                 return NULL;
818         }
819         ast_copy_string(tmp->exten, "s", sizeof(tmp->exten));
820         ast_mutex_init(&tmp->lock);
821         ast_mutex_lock(&jinglelock);
822         tmp->next = client->p;
823         client->p = tmp;
824         ast_mutex_unlock(&jinglelock);
825         return tmp;
826 }
827
828 /*! \brief Start new jingle channel */
829 static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *i, int state, const char *title, const char *linkedid)
830 {
831         struct ast_channel *tmp;
832         struct ast_format_cap *what;  /* SHALLOW COPY DO NOT DESTROY */
833         struct ast_format tmpfmt;
834         const char *str;
835
836         if (title)
837                 str = title;
838         else
839                 str = i->them;
840         tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", "", "", linkedid, 0, "Jingle/%s-%04lx", str, ast_random() & 0xffff);
841         if (!tmp) {
842                 ast_log(LOG_WARNING, "Unable to allocate Jingle channel structure!\n");
843                 return NULL;
844         }
845         tmp->tech = &jingle_tech;
846
847         /* Select our native format based on codec preference until we receive
848            something from another device to the contrary. */
849         if (!ast_format_cap_is_empty(i->jointcap))
850                 what = i->jointcap;
851         else if (!(ast_format_cap_is_empty(i->cap)))
852                 what = i->cap;
853         else
854                 what = global_capability;
855
856         /* Set Frame packetization */
857         if (i->rtp)
858                 ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(i->rtp), i->rtp, &i->prefs);
859
860         ast_codec_choose(&i->prefs, what, 1, &tmpfmt);
861         ast_format_cap_add(tmp->nativeformats, &tmpfmt);
862
863         ast_format_cap_iter_start(i->jointcap);
864         while (!(ast_format_cap_iter_next(i->jointcap, &tmpfmt))) {
865                 if (AST_FORMAT_GET_TYPE(tmpfmt.id) == AST_FORMAT_TYPE_VIDEO) {
866                         ast_format_cap_add(tmp->nativeformats, &tmpfmt);
867                 }
868         }
869         ast_format_cap_iter_end(i->jointcap);
870
871         if (i->rtp) {
872                 ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(i->rtp, 0));
873                 ast_channel_set_fd(tmp, 1, ast_rtp_instance_fd(i->rtp, 1));
874         }
875         if (i->vrtp) {
876                 ast_channel_set_fd(tmp, 2, ast_rtp_instance_fd(i->vrtp, 0));
877                 ast_channel_set_fd(tmp, 3, ast_rtp_instance_fd(i->vrtp, 1));
878         }
879         if (state == AST_STATE_RING)
880                 tmp->rings = 1;
881         tmp->adsicpe = AST_ADSI_UNAVAILABLE;
882
883
884         ast_best_codec(tmp->nativeformats, &tmpfmt);
885         ast_format_copy(&tmp->writeformat, &tmpfmt);
886         ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
887         ast_format_copy(&tmp->readformat, &tmpfmt);
888         ast_format_copy(&tmp->rawreadformat, &tmpfmt);
889         tmp->tech_pvt = i;
890
891         tmp->callgroup = client->callgroup;
892         tmp->pickupgroup = client->pickupgroup;
893         tmp->caller.id.name.presentation = client->callingpres;
894         tmp->caller.id.number.presentation = client->callingpres;
895         if (!ast_strlen_zero(client->accountcode))
896                 ast_channel_accountcode_set(tmp, client->accountcode);
897         if (client->amaflags)
898                 tmp->amaflags = client->amaflags;
899         if (!ast_strlen_zero(client->language))
900                 ast_channel_language_set(tmp, client->language);
901         if (!ast_strlen_zero(client->musicclass))
902                 ast_channel_musicclass_set(tmp, client->musicclass);
903         i->owner = tmp;
904         ast_copy_string(tmp->context, client->context, sizeof(tmp->context));
905         ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
906         /* Don't use ast_set_callerid() here because it will
907          * generate an unnecessary NewCallerID event  */
908         if (!ast_strlen_zero(i->cid_num)) {
909                 tmp->caller.ani.number.valid = 1;
910                 tmp->caller.ani.number.str = ast_strdup(i->cid_num);
911         }
912         if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) {
913                 tmp->dialed.number.str = ast_strdup(i->exten);
914         }
915         tmp->priority = 1;
916         if (i->rtp)
917                 ast_jb_configure(tmp, &global_jbconf);
918         if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {
919                 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
920                 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
921                 ast_hangup(tmp);
922                 tmp = NULL;
923         }
924
925         return tmp;
926 }
927
928 static int jingle_action(struct jingle *client, struct jingle_pvt *p, const char *action)
929 {
930         iks *iq, *jingle = NULL;
931         int res = -1;
932
933         iq = iks_new("iq");
934         jingle = iks_new("jingle");
935         
936         if (iq) {
937                 iks_insert_attrib(iq, "type", "set");
938                 iks_insert_attrib(iq, "from", client->connection->jid->full);
939                 iks_insert_attrib(iq, "to", p->them);
940                 iks_insert_attrib(iq, "id", client->connection->mid);
941                 ast_aji_increment_mid(client->connection->mid);
942                 if (jingle) {
943                         iks_insert_attrib(jingle, "action", action);
944                         iks_insert_attrib(jingle, JINGLE_SID, p->sid);
945                         iks_insert_attrib(jingle, "initiator", p->initiator ? client->connection->jid->full : p->them);
946                         iks_insert_attrib(jingle, "xmlns", JINGLE_NS);
947
948                         iks_insert_node(iq, jingle);
949
950                         ast_aji_send(client->connection, iq);
951                         res = 0;
952                 }
953         }
954         
955         iks_delete(jingle);
956         iks_delete(iq);
957         
958         return res;
959 }
960
961 static void jingle_free_candidates(struct jingle_candidate *candidate)
962 {
963         struct jingle_candidate *last;
964         while (candidate) {
965                 last = candidate;
966                 candidate = candidate->next;
967                 ast_free(last);
968         }
969 }
970
971 static void jingle_free_pvt(struct jingle *client, struct jingle_pvt *p)
972 {
973         struct jingle_pvt *cur, *prev = NULL;
974         cur = client->p;
975         while (cur) {
976                 if (cur == p) {
977                         if (prev)
978                                 prev->next = p->next;
979                         else
980                                 client->p = p->next;
981                         break;
982                 }
983                 prev = cur;
984                 cur = cur->next;
985         }
986         if (p->ringrule)
987                 iks_filter_remove_rule(p->parent->connection->f, p->ringrule);
988         if (p->owner)
989                 ast_log(LOG_WARNING, "Uh oh, there's an owner, this is going to be messy.\n");
990         if (p->rtp)
991                 ast_rtp_instance_destroy(p->rtp);
992         if (p->vrtp)
993                 ast_rtp_instance_destroy(p->vrtp);
994         jingle_free_candidates(p->theircandidates);
995         p->cap = ast_format_cap_destroy(p->cap);
996         p->jointcap = ast_format_cap_destroy(p->jointcap);
997         p->peercap = ast_format_cap_destroy(p->peercap);
998
999         ast_free(p);
1000 }
1001
1002
1003 static int jingle_newcall(struct jingle *client, ikspak *pak)
1004 {
1005         struct jingle_pvt *p, *tmp = client->p;
1006         struct ast_channel *chan;
1007         int res;
1008         iks *codec, *content, *description;
1009         char *from = NULL;
1010
1011         /* Make sure our new call doesn't exist yet */
1012         from = iks_find_attrib(pak->x,"to");
1013         if(!from)
1014                 from = client->connection->jid->full;
1015
1016         while (tmp) {
1017                 if (iks_find_with_attrib(pak->x, JINGLE_NODE, JINGLE_SID, tmp->sid)) {
1018                         ast_log(LOG_NOTICE, "Ignoring duplicate call setup on SID %s\n", tmp->sid);
1019                         jingle_response(client, pak, "out-of-order", NULL);
1020                         return -1;
1021                 }
1022                 tmp = tmp->next;
1023         }
1024
1025         if (!strcasecmp(client->name, "guest")){
1026                 /* the guest account is not tied to any configured XMPP client,
1027                    let's set it now */
1028                 if (client->connection) {
1029                         ASTOBJ_UNREF(client->connection, ast_aji_client_destroy);
1030                 }
1031                 client->connection = ast_aji_get_client(from);
1032                 if (!client->connection) {
1033                         ast_log(LOG_ERROR, "No XMPP client to talk to, us (partial JID) : %s\n", from);
1034                         return -1;
1035                 }
1036         }
1037
1038         p = jingle_alloc(client, pak->from->partial, iks_find_attrib(pak->query, JINGLE_SID));
1039         if (!p) {
1040                 ast_log(LOG_WARNING, "Unable to allocate jingle structure!\n");
1041                 return -1;
1042         }
1043         chan = jingle_new(client, p, AST_STATE_DOWN, pak->from->user, NULL);
1044         if (!chan) {
1045                 jingle_free_pvt(client, p);
1046                 return -1;
1047         }
1048         ast_mutex_lock(&p->lock);
1049         ast_copy_string(p->them, pak->from->full, sizeof(p->them));
1050         if (iks_find_attrib(pak->query, JINGLE_SID)) {
1051                 ast_copy_string(p->sid, iks_find_attrib(pak->query, JINGLE_SID),
1052                                 sizeof(p->sid));
1053         }
1054         
1055         /* content points to the first <content/> tag */        
1056         content = iks_child(iks_child(pak->x));
1057         while (content) {
1058                 description = iks_find_with_attrib(content, "description", "xmlns", JINGLE_AUDIO_RTP_NS);
1059                 if (description) {
1060                         /* audio content found */
1061                         codec = iks_child(iks_child(content));
1062                         ast_copy_string(p->audio_content_name, iks_find_attrib(content, "name"), sizeof(p->audio_content_name));
1063
1064                         while (codec) {
1065                                 ast_rtp_codecs_payloads_set_m_type(ast_rtp_instance_get_codecs(p->rtp), p->rtp, atoi(iks_find_attrib(codec, "id")));
1066                                 ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp), p->rtp, atoi(iks_find_attrib(codec, "id")), "audio", iks_find_attrib(codec, "name"), 0);
1067                                 codec = iks_next(codec);
1068                         }
1069                 }
1070                 
1071                 description = NULL;
1072                 codec = NULL;
1073
1074                 description = iks_find_with_attrib(content, "description", "xmlns", JINGLE_VIDEO_RTP_NS);
1075                 if (description) {
1076                         /* video content found */
1077                         codec = iks_child(iks_child(content));
1078                         ast_copy_string(p->video_content_name, iks_find_attrib(content, "name"), sizeof(p->video_content_name));
1079
1080                         while (codec) {
1081                                 ast_rtp_codecs_payloads_set_m_type(ast_rtp_instance_get_codecs(p->rtp), p->rtp, atoi(iks_find_attrib(codec, "id")));
1082                                 ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp), p->rtp, atoi(iks_find_attrib(codec, "id")), "audio", iks_find_attrib(codec, "name"), 0);
1083                                 codec = iks_next(codec);
1084                         }
1085                 }
1086                 
1087                 content = iks_next(content);
1088         }
1089
1090         ast_mutex_unlock(&p->lock);
1091         ast_setstate(chan, AST_STATE_RING);
1092         res = ast_pbx_start(chan);
1093         
1094         switch (res) {
1095         case AST_PBX_FAILED:
1096                 ast_log(LOG_WARNING, "Failed to start PBX :(\n");
1097                 jingle_response(client, pak, "service-unavailable", NULL);
1098                 break;
1099         case AST_PBX_CALL_LIMIT:
1100                 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
1101                 jingle_response(client, pak, "service-unavailable", NULL);
1102                 break;
1103         case AST_PBX_SUCCESS:
1104                 jingle_response(client, pak, NULL, NULL);
1105                 jingle_create_candidates(client, p,
1106                                          iks_find_attrib(pak->query, JINGLE_SID),
1107                                          iks_find_attrib(pak->x, "from"));
1108                 /* nothing to do */
1109                 break;
1110         }
1111
1112         return 1;
1113 }
1114
1115 static int jingle_update_stun(struct jingle *client, struct jingle_pvt *p)
1116 {
1117         struct jingle_candidate *tmp;
1118         struct hostent *hp;
1119         struct ast_hostent ahp;
1120         struct sockaddr_in sin;
1121         struct ast_sockaddr sin_tmp;
1122
1123         if (time(NULL) == p->laststun)
1124                 return 0;
1125
1126         tmp = p->theircandidates;
1127         p->laststun = time(NULL);
1128         while (tmp) {
1129                 char username[256];
1130                 hp = ast_gethostbyname(tmp->ip, &ahp);
1131                 sin.sin_family = AF_INET;
1132                 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
1133                 sin.sin_port = htons(tmp->port);
1134                 snprintf(username, sizeof(username), "%s:%s", tmp->ufrag, p->ourcandidates->ufrag);
1135
1136                 ast_sockaddr_from_sin(&sin_tmp, &sin);
1137                 ast_rtp_instance_stun_request(p->rtp, &sin_tmp, username);
1138                 tmp = tmp->next;
1139         }
1140         return 1;
1141 }
1142
1143 static int jingle_add_candidate(struct jingle *client, ikspak *pak)
1144 {
1145         struct jingle_pvt *p = NULL, *tmp = NULL;
1146         struct aji_client *c = client->connection;
1147         struct jingle_candidate *newcandidate = NULL;
1148         iks *traversenodes = NULL, *receipt = NULL;
1149
1150         for (tmp = client->p; tmp; tmp = tmp->next) {
1151                 if (iks_find_with_attrib(pak->x, JINGLE_NODE, JINGLE_SID, tmp->sid)) {
1152                         p = tmp;
1153                         break;
1154                 }
1155         }
1156
1157         if (!p)
1158                 return -1;
1159
1160         traversenodes = pak->query;
1161         while(traversenodes) {
1162                 if(!strcasecmp(iks_name(traversenodes), "jingle")) {
1163                         traversenodes = iks_child(traversenodes);
1164                         continue;
1165                 }
1166                 if(!strcasecmp(iks_name(traversenodes), "content")) {
1167                         traversenodes = iks_child(traversenodes);
1168                         continue;
1169                 }
1170                 if(!strcasecmp(iks_name(traversenodes), "transport")) {
1171                         traversenodes = iks_child(traversenodes);
1172                         continue;
1173                 }
1174
1175                 if(!strcasecmp(iks_name(traversenodes), "candidate")) {
1176                         newcandidate = ast_calloc(1, sizeof(*newcandidate));
1177                         if (!newcandidate)
1178                                 return 0;
1179                         ast_copy_string(newcandidate->ip, iks_find_attrib(traversenodes, "ip"), sizeof(newcandidate->ip));
1180                         newcandidate->port = atoi(iks_find_attrib(traversenodes, "port"));
1181                         ast_copy_string(newcandidate->password, iks_find_attrib(traversenodes, "pwd"), sizeof(newcandidate->password));
1182                         if (!strcasecmp(iks_find_attrib(traversenodes, "protocol"), "udp"))
1183                                 newcandidate->protocol = AJI_PROTOCOL_UDP;
1184                         else if (!strcasecmp(iks_find_attrib(traversenodes, "protocol"), "ssltcp"))
1185                                 newcandidate->protocol = AJI_PROTOCOL_SSLTCP;
1186                         
1187                         if (!strcasecmp(iks_find_attrib(traversenodes, "type"), "host"))
1188                                 newcandidate->type = AJI_CONNECT_HOST;
1189                         else if (!strcasecmp(iks_find_attrib(traversenodes, "type"), "prflx"))
1190                                 newcandidate->type = AJI_CONNECT_PRFLX;
1191                         else if (!strcasecmp(iks_find_attrib(traversenodes, "type"), "relay"))
1192                                 newcandidate->type = AJI_CONNECT_RELAY;
1193                         else if (!strcasecmp(iks_find_attrib(traversenodes, "type"), "srflx"))
1194                                 newcandidate->type = AJI_CONNECT_SRFLX;
1195
1196                         newcandidate->network = atoi(iks_find_attrib(traversenodes, "network"));
1197                         newcandidate->generation = atoi(iks_find_attrib(traversenodes, "generation"));
1198                         newcandidate->next = NULL;
1199                 
1200                         newcandidate->next = p->theircandidates;
1201                         p->theircandidates = newcandidate;
1202                         p->laststun = 0;
1203                         jingle_update_stun(p->parent, p);
1204                         newcandidate = NULL;
1205                 }
1206                 traversenodes = iks_next(traversenodes);
1207         }
1208         
1209         receipt = iks_new("iq");
1210         iks_insert_attrib(receipt, "type", "result");
1211         iks_insert_attrib(receipt, "from", c->jid->full);
1212         iks_insert_attrib(receipt, "to", iks_find_attrib(pak->x, "from"));
1213         iks_insert_attrib(receipt, "id", iks_find_attrib(pak->x, "id"));
1214         ast_aji_send(c, receipt);
1215
1216         iks_delete(receipt);
1217
1218         return 1;
1219 }
1220
1221 static struct ast_frame *jingle_rtp_read(struct ast_channel *ast, struct jingle_pvt *p)
1222 {
1223         struct ast_frame *f;
1224
1225         if (!p->rtp)
1226                 return &ast_null_frame;
1227         f = ast_rtp_instance_read(p->rtp, 0);
1228         jingle_update_stun(p->parent, p);
1229         if (p->owner) {
1230                 /* We already hold the channel lock */
1231                 if (f->frametype == AST_FRAME_VOICE) {
1232                         if (!(ast_format_cap_iscompatible(p->owner->nativeformats, &f->subclass.format))) {
1233                                 ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
1234                                 ast_format_cap_remove_bytype(p->owner->nativeformats, AST_FORMAT_TYPE_AUDIO);
1235                                 ast_format_cap_add(p->owner->nativeformats, &f->subclass.format);
1236                                 ast_set_read_format(p->owner, &p->owner->readformat);
1237                                 ast_set_write_format(p->owner, &p->owner->writeformat);
1238                         }
1239 /*                      if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
1240                                 f = ast_dsp_process(p->owner, p->vad, f);
1241                                 if (f && (f->frametype == AST_FRAME_DTMF))
1242                                         ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass.codec);
1243                         } */
1244                 }
1245         }
1246         return f;
1247 }
1248
1249 static struct ast_frame *jingle_read(struct ast_channel *ast)
1250 {
1251         struct ast_frame *fr;
1252         struct jingle_pvt *p = ast->tech_pvt;
1253
1254         ast_mutex_lock(&p->lock);
1255         fr = jingle_rtp_read(ast, p);
1256         ast_mutex_unlock(&p->lock);
1257         return fr;
1258 }
1259
1260 /*! \brief Send frame to media channel (rtp) */
1261 static int jingle_write(struct ast_channel *ast, struct ast_frame *frame)
1262 {
1263         struct jingle_pvt *p = ast->tech_pvt;
1264         int res = 0;
1265         char buf[256];
1266
1267         switch (frame->frametype) {
1268         case AST_FRAME_VOICE:
1269                 if (!(ast_format_cap_iscompatible(ast->nativeformats, &frame->subclass.format))) {
1270                         ast_log(LOG_WARNING,
1271                                         "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
1272                                         ast_getformatname(&frame->subclass.format),
1273                                         ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats),
1274                                         ast_getformatname(&ast->readformat),
1275                                         ast_getformatname(&ast->writeformat));
1276                         return 0;
1277                 }
1278                 if (p) {
1279                         ast_mutex_lock(&p->lock);
1280                         if (p->rtp) {
1281                                 res = ast_rtp_instance_write(p->rtp, frame);
1282                         }
1283                         ast_mutex_unlock(&p->lock);
1284                 }
1285                 break;
1286         case AST_FRAME_VIDEO:
1287                 if (p) {
1288                         ast_mutex_lock(&p->lock);
1289                         if (p->vrtp) {
1290                                 res = ast_rtp_instance_write(p->vrtp, frame);
1291                         }
1292                         ast_mutex_unlock(&p->lock);
1293                 }
1294                 break;
1295         case AST_FRAME_IMAGE:
1296                 return 0;
1297                 break;
1298         default:
1299                 ast_log(LOG_WARNING, "Can't send %d type frames with Jingle write\n",
1300                                 frame->frametype);
1301                 return 0;
1302         }
1303
1304         return res;
1305 }
1306
1307 static int jingle_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
1308 {
1309         struct jingle_pvt *p = newchan->tech_pvt;
1310         ast_mutex_lock(&p->lock);
1311
1312         if ((p->owner != oldchan)) {
1313                 ast_mutex_unlock(&p->lock);
1314                 return -1;
1315         }
1316         if (p->owner == oldchan)
1317                 p->owner = newchan;
1318         ast_mutex_unlock(&p->lock);
1319         return 0;
1320 }
1321
1322 static int jingle_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
1323 {
1324         int res = 0;
1325
1326         switch (condition) {
1327         case AST_CONTROL_HOLD:
1328                 ast_moh_start(ast, data, NULL);
1329                 break;
1330         case AST_CONTROL_UNHOLD:
1331                 ast_moh_stop(ast);
1332                 break;
1333         default:
1334                 ast_log(LOG_NOTICE, "Don't know how to indicate condition '%d'\n", condition);
1335                 res = -1;
1336         }
1337
1338         return res;
1339 }
1340
1341 static int jingle_sendtext(struct ast_channel *chan, const char *text)
1342 {
1343         int res = 0;
1344         struct aji_client *client = NULL;
1345         struct jingle_pvt *p = chan->tech_pvt;
1346
1347
1348         if (!p->parent) {
1349                 ast_log(LOG_ERROR, "Parent channel not found\n");
1350                 return -1;
1351         }
1352         if (!p->parent->connection) {
1353                 ast_log(LOG_ERROR, "XMPP client not found\n");
1354                 return -1;
1355         }
1356         client = p->parent->connection;
1357         res = ast_aji_send_chat(client, p->them, text);
1358         return res;
1359 }
1360
1361 static int jingle_digit(struct ast_channel *ast, char digit, unsigned int duration)
1362 {
1363         struct jingle_pvt *p = ast->tech_pvt;
1364         struct jingle *client = p->parent;
1365         iks *iq, *jingle, *dtmf;
1366         char buffer[2] = {digit, '\0'};
1367         iq = iks_new("iq");
1368         jingle = iks_new("jingle");
1369         dtmf = iks_new("dtmf");
1370         if(!iq || !jingle || !dtmf) {
1371                 iks_delete(iq);
1372                 iks_delete(jingle);
1373                 iks_delete(dtmf);
1374                 ast_log(LOG_ERROR, "Did not send dtmf do to memory issue\n");
1375                 return -1;
1376         }
1377
1378         iks_insert_attrib(iq, "type", "set");
1379         iks_insert_attrib(iq, "to", p->them);
1380         iks_insert_attrib(iq, "from", client->connection->jid->full);
1381         iks_insert_attrib(iq, "id", client->connection->mid);
1382         ast_aji_increment_mid(client->connection->mid);
1383         iks_insert_attrib(jingle, "xmlns", JINGLE_NS);
1384         iks_insert_attrib(jingle, "action", "session-info");
1385         iks_insert_attrib(jingle, "initiator", p->initiator ? client->connection->jid->full : p->them);
1386         iks_insert_attrib(jingle, "sid", p->sid);
1387         iks_insert_attrib(dtmf, "xmlns", JINGLE_DTMF_NS);
1388         iks_insert_attrib(dtmf, "code", buffer);
1389         iks_insert_node(iq, jingle);
1390         iks_insert_node(jingle, dtmf);
1391
1392         ast_mutex_lock(&p->lock);
1393         if (ast->dtmff.frametype == AST_FRAME_DTMF_BEGIN || duration == 0) {
1394                 iks_insert_attrib(dtmf, "action", "button-down");
1395         } else if (ast->dtmff.frametype == AST_FRAME_DTMF_END || duration != 0) {
1396                 iks_insert_attrib(dtmf, "action", "button-up");
1397         }
1398         ast_aji_send(client->connection, iq);
1399
1400         iks_delete(iq);
1401         iks_delete(jingle);
1402         iks_delete(dtmf);
1403         ast_mutex_unlock(&p->lock);
1404         return 0;
1405 }
1406
1407 static int jingle_digit_begin(struct ast_channel *chan, char digit)
1408 {
1409         return jingle_digit(chan, digit, 0);
1410 }
1411
1412 static int jingle_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
1413 {
1414         return jingle_digit(ast, digit, duration);
1415 }
1416
1417 static int jingle_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
1418 {
1419         ast_log(LOG_NOTICE, "XXX Implement jingle sendhtml XXX\n");
1420
1421         return -1;
1422 }
1423 static int jingle_transmit_invite(struct jingle_pvt *p)
1424 {
1425         struct jingle *aux = NULL;
1426         struct aji_client *client = NULL;
1427         iks *iq, *jingle, *content, *description, *transport;
1428         iks *payload_eg711u, *payload_pcmu;
1429
1430         aux = p->parent;
1431         client = aux->connection;
1432         iq = iks_new("iq");
1433         jingle = iks_new(JINGLE_NODE);
1434         content = iks_new("content");
1435         description = iks_new("description");
1436         transport = iks_new("transport");
1437         payload_pcmu = iks_new("payload-type");
1438         payload_eg711u = iks_new("payload-type");
1439
1440         ast_copy_string(p->audio_content_name, "asterisk-audio-content", sizeof(p->audio_content_name));
1441
1442         iks_insert_attrib(iq, "type", "set");
1443         iks_insert_attrib(iq, "to", p->them);
1444         iks_insert_attrib(iq, "from", client->jid->full);
1445         iks_insert_attrib(iq, "id", client->mid);
1446         ast_aji_increment_mid(client->mid);
1447         iks_insert_attrib(jingle, "action", JINGLE_INITIATE);
1448         iks_insert_attrib(jingle, JINGLE_SID, p->sid);
1449         iks_insert_attrib(jingle, "initiator", client->jid->full);
1450         iks_insert_attrib(jingle, "xmlns", JINGLE_NS);
1451
1452         /* For now, we only send one audio based content */
1453         iks_insert_attrib(content, "creator", "initiator");
1454         iks_insert_attrib(content, "name", p->audio_content_name);
1455         iks_insert_attrib(content, "profile", "RTP/AVP");
1456         iks_insert_attrib(description, "xmlns", JINGLE_AUDIO_RTP_NS);
1457         iks_insert_attrib(transport, "xmlns", JINGLE_ICE_UDP_NS);
1458         iks_insert_attrib(payload_pcmu, "id", "0");
1459         iks_insert_attrib(payload_pcmu, "name", "PCMU");
1460         iks_insert_attrib(payload_eg711u, "id", "100");
1461         iks_insert_attrib(payload_eg711u, "name", "EG711U");
1462         iks_insert_node(description, payload_pcmu);
1463         iks_insert_node(description, payload_eg711u);
1464         iks_insert_node(content, description);
1465         iks_insert_node(content, transport);
1466         iks_insert_node(jingle, content);
1467         iks_insert_node(iq, jingle);
1468
1469         ast_aji_send(client, iq);
1470
1471         iks_delete(iq);
1472         iks_delete(jingle);
1473         iks_delete(content);
1474         iks_delete(description);
1475         iks_delete(transport);
1476         iks_delete(payload_eg711u);
1477         iks_delete(payload_pcmu);
1478         return 0;
1479 }
1480
1481 /* Not in use right now.
1482 static int jingle_auto_congest(void *nothing)
1483 {
1484         struct jingle_pvt *p = nothing;
1485
1486         ast_mutex_lock(&p->lock);
1487         if (p->owner) {
1488                 if (!ast_channel_trylock(p->owner)) {
1489                         ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name);
1490                         ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
1491                         ast_channel_unlock(p->owner);
1492                 }
1493         }
1494         ast_mutex_unlock(&p->lock);
1495         return 0;
1496 }
1497 */
1498
1499 /*! \brief Initiate new call, part of PBX interface 
1500  *      dest is the dial string */
1501 static int jingle_call(struct ast_channel *ast, const char *dest, int timeout)
1502 {
1503         struct jingle_pvt *p = ast->tech_pvt;
1504
1505         if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
1506                 ast_log(LOG_WARNING, "jingle_call called on %s, neither down nor reserved\n", ast_channel_name(ast));
1507                 return -1;
1508         }
1509
1510         ast_setstate(ast, AST_STATE_RING);
1511         ast_format_cap_copy(p->jointcap, p->cap);
1512         if (!p->ringrule) {
1513                 ast_copy_string(p->ring, p->parent->connection->mid, sizeof(p->ring));
1514                 p->ringrule = iks_filter_add_rule(p->parent->connection->f, jingle_ringing_ack, p,
1515                                                         IKS_RULE_ID, p->ring, IKS_RULE_DONE);
1516         } else
1517                 ast_log(LOG_WARNING, "Whoa, already have a ring rule!\n");
1518
1519         jingle_transmit_invite(p);
1520         jingle_create_candidates(p->parent, p, p->sid, p->them);
1521
1522         return 0;
1523 }
1524
1525 /*! \brief Hangup a call through the jingle proxy channel */
1526 static int jingle_hangup(struct ast_channel *ast)
1527 {
1528         struct jingle_pvt *p = ast->tech_pvt;
1529         struct jingle *client;
1530
1531         ast_mutex_lock(&p->lock);
1532         client = p->parent;
1533         p->owner = NULL;
1534         ast->tech_pvt = NULL;
1535         if (!p->alreadygone)
1536                 jingle_action(client, p, JINGLE_TERMINATE);
1537         ast_mutex_unlock(&p->lock);
1538
1539         jingle_free_pvt(client, p);
1540
1541         return 0;
1542 }
1543
1544 /*! \brief Part of PBX interface */
1545 static struct ast_channel *jingle_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
1546 {
1547         struct jingle_pvt *p = NULL;
1548         struct jingle *client = NULL;
1549         char *sender = NULL, *to = NULL, *s = NULL;
1550         struct ast_channel *chan = NULL;
1551
1552         if (data) {
1553                 s = ast_strdupa(data);
1554                 if (s) {
1555                         sender = strsep(&s, "/");
1556                         if (sender && (sender[0] != '\0'))
1557                                 to = strsep(&s, "/");
1558                         if (!to) {
1559                                 ast_log(LOG_ERROR, "Bad arguments in Jingle Dialstring: %s\n", data);
1560                                 return NULL;
1561                         }
1562                 }
1563         }
1564
1565         client = find_jingle(to, sender);
1566         if (!client) {
1567                 ast_log(LOG_WARNING, "Could not find recipient.\n");
1568                 return NULL;
1569         }
1570         if (!strcasecmp(client->name, "guest")){
1571                 /* the guest account is not tied to any configured XMPP client,
1572                    let's set it now */
1573                 if (client->connection) {
1574                         ASTOBJ_UNREF(client->connection, ast_aji_client_destroy);
1575                 }
1576                 client->connection = ast_aji_get_client(sender);
1577                 if (!client->connection) {
1578                         ast_log(LOG_ERROR, "No XMPP client to talk to, us (partial JID) : %s\n", sender);
1579                         return NULL;
1580                 }
1581         }
1582        
1583         ASTOBJ_WRLOCK(client);
1584         p = jingle_alloc(client, to, NULL);
1585         if (p)
1586                 chan = jingle_new(client, p, AST_STATE_DOWN, to, requestor ? ast_channel_linkedid(requestor) : NULL);
1587         ASTOBJ_UNLOCK(client);
1588
1589         return chan;
1590 }
1591
1592 /*! \brief CLI command "jingle show channels" */
1593 static char *jingle_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1594 {
1595 #define FORMAT  "%-30.30s  %-30.30s  %-15.15s  %-5.5s %-5.5s \n"
1596         struct jingle_pvt *p;
1597         struct ast_channel *chan;
1598         int numchans = 0;
1599         char them[AJI_MAX_JIDLEN];
1600         char *jid = NULL;
1601         char *resource = NULL;
1602
1603         switch (cmd) {
1604         case CLI_INIT:
1605                 e->command = "jingle show channels";
1606                 e->usage =
1607                         "Usage: jingle show channels\n"
1608                         "       Shows current state of the Jingle channels.\n";
1609                 return NULL;
1610         case CLI_GENERATE:
1611                 return NULL;
1612         }
1613
1614         if (a->argc != 3)
1615                 return CLI_SHOWUSAGE;
1616
1617         ast_mutex_lock(&jinglelock);
1618         ast_cli(a->fd, FORMAT, "Channel", "Jabber ID", "Resource", "Read", "Write");
1619         ASTOBJ_CONTAINER_TRAVERSE(&jingle_list, 1, {
1620                 ASTOBJ_WRLOCK(iterator);
1621                 p = iterator->p;
1622                 while(p) {
1623                         chan = p->owner;
1624                         ast_copy_string(them, p->them, sizeof(them));
1625                         jid = them;
1626                         resource = strchr(them, '/');
1627                         if (!resource)
1628                                 resource = "None";
1629                         else {
1630                                 *resource = '\0';
1631                                 resource ++;
1632                         }
1633                         if (chan)
1634                                 ast_cli(a->fd, FORMAT, 
1635                                         ast_channel_name(chan),
1636                                         jid,
1637                                         resource,
1638                                         ast_getformatname(&chan->readformat),
1639                                         ast_getformatname(&chan->writeformat)
1640                                         );
1641                         else 
1642                                 ast_log(LOG_WARNING, "No available channel\n");
1643                         numchans ++;
1644                         p = p->next;
1645                 }
1646                 ASTOBJ_UNLOCK(iterator);
1647         });
1648
1649         ast_mutex_unlock(&jinglelock);
1650
1651         ast_cli(a->fd, "%d active jingle channel%s\n", numchans, (numchans != 1) ? "s" : "");
1652         return CLI_SUCCESS;
1653 #undef FORMAT
1654 }
1655
1656 /*! \brief CLI command "jingle reload" */
1657 static char *jingle_do_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1658 {
1659         switch (cmd) {
1660         case CLI_INIT:
1661                 e->command = "jingle reload";
1662                 e->usage =
1663                         "Usage: jingle reload\n"
1664                         "       Reload jingle channel driver.\n";
1665                 return NULL;
1666         case CLI_GENERATE:
1667                 return NULL;
1668         }       
1669         
1670         return CLI_SUCCESS;
1671 }
1672
1673 static int jingle_parser(void *data, ikspak *pak)
1674 {
1675         struct jingle *client = ASTOBJ_REF((struct jingle *) data);
1676         ast_log(LOG_NOTICE, "Filter matched\n");
1677
1678         if (iks_find_with_attrib(pak->x, JINGLE_NODE, "action", JINGLE_INITIATE)) {
1679                 /* New call */
1680                 jingle_newcall(client, pak);
1681         } else if (iks_find_with_attrib(pak->x, JINGLE_NODE, "action", JINGLE_NEGOTIATE)) {
1682                 ast_debug(3, "About to add candidate!\n");
1683                 jingle_add_candidate(client, pak);
1684                 ast_debug(3, "Candidate Added!\n");
1685         } else if (iks_find_with_attrib(pak->x, JINGLE_NODE, "action", JINGLE_ACCEPT)) {
1686                 jingle_is_answered(client, pak);
1687         } else if (iks_find_with_attrib(pak->x, JINGLE_NODE, "action", JINGLE_INFO)) {
1688                 jingle_handle_dtmf(client, pak);
1689         } else if (iks_find_with_attrib(pak->x, JINGLE_NODE, "action", JINGLE_TERMINATE)) {
1690                 jingle_hangup_farend(client, pak);
1691         } else if (iks_find_with_attrib(pak->x, JINGLE_NODE, "action", "reject")) {
1692                 jingle_hangup_farend(client, pak);
1693         }
1694         ASTOBJ_UNREF(client, jingle_member_destroy);
1695         return IKS_FILTER_EAT;
1696 }
1697 /* Not using this anymore probably take out soon 
1698 static struct jingle_candidate *jingle_create_candidate(char *args)
1699 {
1700         char *name, *type, *preference, *protocol;
1701         struct jingle_candidate *res;
1702         res = ast_calloc(1, sizeof(*res));
1703         if (args)
1704                 name = args;
1705         if ((args = strchr(args, ','))) {
1706                 *args = '\0';
1707                 args++;
1708                 preference = args;
1709         }
1710         if ((args = strchr(args, ','))) {
1711                 *args = '\0';
1712                 args++;
1713                 protocol = args;
1714         }
1715         if ((args = strchr(args, ','))) {
1716                 *args = '\0';
1717                 args++;
1718                 type = args;
1719         }
1720         if (name)
1721                 ast_copy_string(res->name, name, sizeof(res->name));
1722         if (preference) {
1723                 res->preference = atof(preference);
1724         }
1725         if (protocol) {
1726                 if (!strcasecmp("udp", protocol))
1727                         res->protocol = AJI_PROTOCOL_UDP;
1728                 if (!strcasecmp("ssltcp", protocol))
1729                         res->protocol = AJI_PROTOCOL_SSLTCP;
1730         }
1731         if (type) {
1732                 if (!strcasecmp("host", type))
1733                         res->type = AJI_CONNECT_HOST;
1734                 if (!strcasecmp("prflx", type))
1735                         res->type = AJI_CONNECT_PRFLX;
1736                 if (!strcasecmp("relay", type))
1737                         res->type = AJI_CONNECT_RELAY;
1738                 if (!strcasecmp("srflx", type))
1739                         res->type = AJI_CONNECT_SRFLX;
1740         }
1741
1742         return res;
1743 }
1744 */
1745
1746 static int jingle_create_member(char *label, struct ast_variable *var, int allowguest,
1747                                                                 struct ast_codec_pref prefs, char *context,
1748                                                                 struct jingle *member)
1749 {
1750         struct aji_client *client;
1751
1752         if (!member)
1753                 ast_log(LOG_WARNING, "Out of memory.\n");
1754
1755         ast_copy_string(member->name, label, sizeof(member->name));
1756         ast_copy_string(member->user, label, sizeof(member->user));
1757         ast_copy_string(member->context, context, sizeof(member->context));
1758         member->allowguest = allowguest;
1759         member->prefs = prefs;
1760         while (var) {
1761 #if 0
1762                 struct jingle_candidate *candidate = NULL;
1763 #endif
1764                 if (!strcasecmp(var->name, "username"))
1765                         ast_copy_string(member->user, var->value, sizeof(member->user));
1766                 else if (!strcasecmp(var->name, "disallow"))
1767                         ast_parse_allow_disallow(&member->prefs, member->cap, var->value, 0);
1768                 else if (!strcasecmp(var->name, "allow"))
1769                         ast_parse_allow_disallow(&member->prefs, member->cap, var->value, 1);
1770                 else if (!strcasecmp(var->name, "context"))
1771                         ast_copy_string(member->context, var->value, sizeof(member->context));
1772 #if 0
1773                 else if (!strcasecmp(var->name, "candidate")) {
1774                         candidate = jingle_create_candidate(var->value);
1775                         if (candidate) {
1776                                 candidate->next = member->ourcandidates;
1777                                 member->ourcandidates = candidate;
1778                         }
1779                 }
1780 #endif
1781                 else if (!strcasecmp(var->name, "connection")) {
1782                         if ((client = ast_aji_get_client(var->value))) {
1783                                 member->connection = client;
1784                                 iks_filter_add_rule(client->f, jingle_parser, member,
1785                                                     IKS_RULE_TYPE, IKS_PAK_IQ,
1786                                                     IKS_RULE_FROM_PARTIAL, member->user,
1787                                                     IKS_RULE_NS, JINGLE_NS,
1788                                                     IKS_RULE_DONE);
1789                         } else {
1790                                 ast_log(LOG_ERROR, "connection referenced not found!\n");
1791                                 return 0;
1792                         }
1793                 }
1794                 var = var->next;
1795         }
1796         if (member->connection && member->user)
1797                 member->buddy = ASTOBJ_CONTAINER_FIND(&member->connection->buddies, member->user);
1798         else {
1799                 ast_log(LOG_ERROR, "No Connection or Username!\n");
1800         }
1801         return 1;
1802 }
1803
1804 static int jingle_load_config(void)
1805 {
1806         char *cat = NULL;
1807         struct ast_config *cfg = NULL;
1808         char context[100];
1809         int allowguest = 1;
1810         struct ast_variable *var;
1811         struct jingle *member;
1812         struct hostent *hp;
1813         struct ast_hostent ahp;
1814         struct ast_codec_pref prefs;
1815         struct aji_client_container *clients;
1816         struct jingle_candidate *global_candidates = NULL;
1817         struct ast_flags config_flags = { 0 };
1818
1819         cfg = ast_config_load(JINGLE_CONFIG, config_flags);
1820         if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
1821                 return 0;
1822         }
1823
1824         /* Copy the default jb config over global_jbconf */
1825         memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
1826
1827         cat = ast_category_browse(cfg, NULL);
1828         for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
1829                 /* handle jb conf */
1830                 if (!ast_jb_read_conf(&global_jbconf, var->name, var->value))
1831                         continue;
1832
1833                 if (!strcasecmp(var->name, "allowguest"))
1834                         allowguest =
1835                                 (ast_true(ast_variable_retrieve(cfg, "general", "allowguest"))) ? 1 : 0;
1836                 else if (!strcasecmp(var->name, "disallow"))
1837                         ast_parse_allow_disallow(&prefs, global_capability, var->value, 0);
1838                 else if (!strcasecmp(var->name, "allow"))
1839                         ast_parse_allow_disallow(&prefs, global_capability, var->value, 1);
1840                 else if (!strcasecmp(var->name, "context"))
1841                         ast_copy_string(context, var->value, sizeof(context));
1842                 else if (!strcasecmp(var->name, "externip"))
1843                         ast_copy_string(externip, var->value, sizeof(externip));
1844                 else if (!strcasecmp(var->name, "bindaddr")) {
1845                         if (!(hp = ast_gethostbyname(var->value, &ahp))) {
1846                                 ast_log(LOG_WARNING, "Invalid address: %s\n", var->value);
1847                         } else {
1848                                 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
1849                         }
1850                 }
1851 /*  Idea to allow for custom candidates  */
1852 /*
1853                 else if (!strcasecmp(var->name, "candidate")) {
1854                         candidate = jingle_create_candidate(var->value);
1855                         if (candidate) {
1856                                 candidate->next = global_candidates;
1857                                 global_candidates = candidate;
1858                         }
1859                 }
1860 */
1861         }
1862         while (cat) {
1863                 if (strcasecmp(cat, "general")) {
1864                         var = ast_variable_browse(cfg, cat);
1865                         member = ast_calloc(1, sizeof(*member));
1866                         ASTOBJ_INIT(member);
1867                         ASTOBJ_WRLOCK(member);
1868                         member->cap = ast_format_cap_alloc_nolock();
1869                         if (!strcasecmp(cat, "guest")) {
1870                                 ast_copy_string(member->name, "guest", sizeof(member->name));
1871                                 ast_copy_string(member->user, "guest", sizeof(member->user));
1872                                 ast_copy_string(member->context, context, sizeof(member->context));
1873                                 member->allowguest = allowguest;
1874                                 member->prefs = prefs;
1875                                 while (var) {
1876                                         if (!strcasecmp(var->name, "disallow"))
1877                                                 ast_parse_allow_disallow(&member->prefs, member->cap,
1878                                                                                                  var->value, 0);
1879                                         else if (!strcasecmp(var->name, "allow"))
1880                                                 ast_parse_allow_disallow(&member->prefs, member->cap,
1881                                                                                                  var->value, 1);
1882                                         else if (!strcasecmp(var->name, "context"))
1883                                                 ast_copy_string(member->context, var->value,
1884                                                                                 sizeof(member->context));
1885                                         else if (!strcasecmp(var->name, "parkinglot"))
1886                                                 ast_copy_string(member->parkinglot, var->value,
1887                                                                                 sizeof(member->parkinglot));
1888 /*  Idea to allow for custom candidates  */
1889 /*
1890                                         else if (!strcasecmp(var->name, "candidate")) {
1891                                                 candidate = jingle_create_candidate(var->value);
1892                                                 if (candidate) {
1893                                                         candidate->next = member->ourcandidates;
1894                                                         member->ourcandidates = candidate;
1895                                                 }
1896                                         }
1897 */
1898                                         var = var->next;
1899                                 }
1900                                 ASTOBJ_UNLOCK(member);
1901                                 clients = ast_aji_get_clients();
1902                                 if (clients) {
1903                                         ASTOBJ_CONTAINER_TRAVERSE(clients, 1, {
1904                                                 ASTOBJ_WRLOCK(iterator);
1905                                                 ASTOBJ_WRLOCK(member);
1906                                                 if (member->connection) {
1907                                                         ASTOBJ_UNREF(member->connection, ast_aji_client_destroy);
1908                                                 }
1909                                                 member->connection = NULL;
1910                                                 iks_filter_add_rule(iterator->f, jingle_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, JINGLE_NS, IKS_RULE_DONE);
1911                                                 iks_filter_add_rule(iterator->f, jingle_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, JINGLE_DTMF_NS, IKS_RULE_DONE);
1912                                                 ASTOBJ_UNLOCK(member);
1913                                                 ASTOBJ_UNLOCK(iterator);
1914                                         });
1915                                         ASTOBJ_CONTAINER_LINK(&jingle_list, member);
1916                                 } else {
1917                                         ASTOBJ_UNLOCK(member);
1918                                         ASTOBJ_UNREF(member, jingle_member_destroy);
1919                                 }
1920                         } else {
1921                                 ASTOBJ_UNLOCK(member);
1922                                 if (jingle_create_member(cat, var, allowguest, prefs, context, member))
1923                                         ASTOBJ_CONTAINER_LINK(&jingle_list, member);
1924                                 ASTOBJ_UNREF(member, jingle_member_destroy);
1925                         }
1926                 }
1927                 cat = ast_category_browse(cfg, cat);
1928         }
1929         jingle_free_candidates(global_candidates);
1930         return 1;
1931 }
1932
1933 /*! \brief Load module into PBX, register channel */
1934 static int load_module(void)
1935 {
1936         struct ast_sockaddr ourip_tmp;
1937         struct ast_sockaddr bindaddr_tmp;
1938         struct ast_format tmpfmt;
1939
1940         char *jabber_loaded = ast_module_helper("", "res_jabber.so", 0, 0, 0, 0);
1941
1942         if (!(jingle_tech.capabilities = ast_format_cap_alloc())) {
1943                 return AST_MODULE_LOAD_DECLINE;
1944         }
1945
1946         ast_format_cap_add_all_by_type(jingle_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
1947         if (!(global_capability = ast_format_cap_alloc())) {
1948                 return AST_MODULE_LOAD_DECLINE;
1949         }
1950         ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
1951         ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_GSM, 0));
1952         ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
1953         ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_H263, 0));
1954
1955         free(jabber_loaded);
1956         if (!jabber_loaded) {
1957                 /* Dependency module has a different name, if embedded */
1958                 jabber_loaded = ast_module_helper("", "res_jabber", 0, 0, 0, 0);
1959                 free(jabber_loaded);
1960                 if (!jabber_loaded) {
1961                         ast_log(LOG_ERROR, "chan_jingle.so depends upon res_jabber.so\n");
1962                         return AST_MODULE_LOAD_DECLINE;
1963                 }
1964         }
1965
1966         ASTOBJ_CONTAINER_INIT(&jingle_list);
1967         if (!jingle_load_config()) {
1968                 ast_log(LOG_ERROR, "Unable to read config file %s. Not loading module.\n", JINGLE_CONFIG);
1969                 return AST_MODULE_LOAD_DECLINE;
1970         }
1971
1972         sched = ast_sched_context_create();
1973         if (!sched) {
1974                 ast_log(LOG_WARNING, "Unable to create schedule context\n");
1975         }
1976
1977         io = io_context_create();
1978         if (!io) {
1979                 ast_log(LOG_WARNING, "Unable to create I/O context\n");
1980         }
1981
1982         ast_sockaddr_from_sin(&bindaddr_tmp, &bindaddr);
1983         if (ast_find_ourip(&ourip_tmp, &bindaddr_tmp, AF_INET)) {
1984                 ast_log(LOG_WARNING, "Unable to get own IP address, Jingle disabled\n");
1985                 return 0;
1986         }
1987         __ourip.s_addr = htonl(ast_sockaddr_ipv4(&ourip_tmp));
1988
1989         ast_rtp_glue_register(&jingle_rtp_glue);
1990         ast_cli_register_multiple(jingle_cli, ARRAY_LEN(jingle_cli));
1991         /* Make sure we can register our channel type */
1992         if (ast_channel_register(&jingle_tech)) {
1993                 ast_log(LOG_ERROR, "Unable to register channel class %s\n", channel_type);
1994                 return -1;
1995         }
1996         return 0;
1997 }
1998
1999 /*! \brief Reload module */
2000 static int reload(void)
2001 {
2002         return 0;
2003 }
2004
2005 /*! \brief Unload the jingle channel from Asterisk */
2006 static int unload_module(void)
2007 {
2008         struct jingle_pvt *privates = NULL;
2009         ast_cli_unregister_multiple(jingle_cli, ARRAY_LEN(jingle_cli));
2010         /* First, take us out of the channel loop */
2011         ast_channel_unregister(&jingle_tech);
2012         ast_rtp_glue_unregister(&jingle_rtp_glue);
2013
2014         if (!ast_mutex_lock(&jinglelock)) {
2015                 /* Hangup all interfaces if they have an owner */
2016                 ASTOBJ_CONTAINER_TRAVERSE(&jingle_list, 1, {
2017                         ASTOBJ_WRLOCK(iterator);
2018                         privates = iterator->p;
2019                         while(privates) {
2020                                 if (privates->owner)
2021                                         ast_softhangup(privates->owner, AST_SOFTHANGUP_APPUNLOAD);
2022                                 privates = privates->next;
2023                         }
2024                         iterator->p = NULL;
2025                         ASTOBJ_UNLOCK(iterator);
2026                 });
2027                 ast_mutex_unlock(&jinglelock);
2028         } else {
2029                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
2030                 return -1;
2031         }
2032         ASTOBJ_CONTAINER_DESTROYALL(&jingle_list, jingle_member_destroy);
2033         ASTOBJ_CONTAINER_DESTROY(&jingle_list);
2034
2035         global_capability = ast_format_cap_destroy(global_capability);
2036         return 0;
2037 }
2038
2039 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Jingle Channel Driver",
2040                 .load = load_module,
2041                 .unload = unload_module,
2042                 .reload = reload,
2043                 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
2044                );