509e69b108999d7c0ac404eb879f13120d50e7c9
[asterisk/asterisk.git] / channels / chan_local.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@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 Mark Spencer <markster@digium.com>
22  *
23  * \brief Local Proxy Channel
24  * 
25  * \ingroup channel_drivers
26  */
27
28 #include "asterisk.h"
29
30 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
31
32 #include <fcntl.h>
33 #include <sys/signal.h>
34
35 #include "asterisk/lock.h"
36 #include "asterisk/channel.h"
37 #include "asterisk/config.h"
38 #include "asterisk/module.h"
39 #include "asterisk/pbx.h"
40 #include "asterisk/sched.h"
41 #include "asterisk/io.h"
42 #include "asterisk/acl.h"
43 #include "asterisk/callerid.h"
44 #include "asterisk/file.h"
45 #include "asterisk/cli.h"
46 #include "asterisk/app.h"
47 #include "asterisk/musiconhold.h"
48 #include "asterisk/manager.h"
49 #include "asterisk/stringfields.h"
50 #include "asterisk/devicestate.h"
51
52 static const char tdesc[] = "Local Proxy Channel Driver";
53
54 #define IS_OUTBOUND(a,b) (a == b->chan ? 1 : 0)
55
56 static struct ast_jb_conf g_jb_conf = {
57         .flags = 0,
58         .max_size = -1,
59         .resync_threshold = -1,
60         .impl = "",
61 };
62
63 static struct ast_channel *local_request(const char *type, int format, void *data, int *cause);
64 static int local_digit_begin(struct ast_channel *ast, char digit);
65 static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
66 static int local_call(struct ast_channel *ast, char *dest, int timeout);
67 static int local_hangup(struct ast_channel *ast);
68 static int local_answer(struct ast_channel *ast);
69 static struct ast_frame *local_read(struct ast_channel *ast);
70 static int local_write(struct ast_channel *ast, struct ast_frame *f);
71 static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
72 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
73 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
74 static int local_sendtext(struct ast_channel *ast, const char *text);
75 static int local_devicestate(void *data);
76 static struct ast_channel *local_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge);
77
78 /* PBX interface structure for channel registration */
79 static const struct ast_channel_tech local_tech = {
80         .type = "Local",
81         .description = tdesc,
82         .capabilities = -1,
83         .requester = local_request,
84         .send_digit_begin = local_digit_begin,
85         .send_digit_end = local_digit_end,
86         .call = local_call,
87         .hangup = local_hangup,
88         .answer = local_answer,
89         .read = local_read,
90         .write = local_write,
91         .write_video = local_write,
92         .exception = local_read,
93         .indicate = local_indicate,
94         .fixup = local_fixup,
95         .send_html = local_sendhtml,
96         .send_text = local_sendtext,
97         .devicestate = local_devicestate,
98         .bridged_channel = local_bridgedchannel,
99 };
100
101 struct local_pvt {
102         ast_mutex_t lock;                       /* Channel private lock */
103         unsigned int flags;                     /* Private flags */
104         char context[AST_MAX_CONTEXT];          /* Context to call */
105         char exten[AST_MAX_EXTENSION];          /* Extension to call */
106         int reqformat;                          /* Requested format */
107         struct ast_jb_conf jb_conf;             /*!< jitterbuffer configuration for this local channel */
108         struct ast_channel *owner;              /* Master Channel - Bridging happens here */
109         struct ast_channel *chan;               /* Outbound channel - PBX is run here */
110         struct ast_module_user *u_owner;        /*! reference to keep the module loaded while in use */
111         struct ast_module_user *u_chan;         /*! reference to keep the module loaded while in use */
112         AST_LIST_ENTRY(local_pvt) list;         /* Next entity */
113 };
114
115 #define LOCAL_GLARE_DETECT    (1 << 0) /*!< Detect glare on hangup */
116 #define LOCAL_CANCEL_QUEUE    (1 << 1) /*!< Cancel queue */
117 #define LOCAL_ALREADY_MASQED  (1 << 2) /*!< Already masqueraded */
118 #define LOCAL_LAUNCHED_PBX    (1 << 3) /*!< PBX was launched */
119 #define LOCAL_NO_OPTIMIZATION (1 << 4) /*!< Do not optimize using masquerading */
120 #define LOCAL_BRIDGE          (1 << 5) /*!< Report back the "true" channel as being bridged to */
121
122 static AST_LIST_HEAD_STATIC(locals, local_pvt);
123
124 /*! \brief Adds devicestate to local channels */
125 static int local_devicestate(void *data)
126 {
127         char *exten = ast_strdupa(data);
128         char *context = NULL, *opts = NULL;
129         int res;
130         struct local_pvt *lp;
131
132         if (!(context = strchr(exten, '@'))) {
133                 ast_log(LOG_WARNING, "Someone used Local/%s somewhere without a @context. This is bad.\n", exten);
134                 return AST_DEVICE_INVALID;      
135         }
136
137         *context++ = '\0';
138
139         /* Strip options if they exist */
140         if ((opts = strchr(context, '/')))
141                 *opts = '\0';
142
143         ast_debug(3, "Checking if extension %s@%s exists (devicestate)\n", exten, context);
144
145         res = ast_exists_extension(NULL, context, exten, 1, NULL);
146         if (!res)               
147                 return AST_DEVICE_INVALID;
148         
149         res = AST_DEVICE_NOT_INUSE;
150         AST_LIST_LOCK(&locals);
151         AST_LIST_TRAVERSE(&locals, lp, list) {
152                 if (!strcmp(exten, lp->exten) && !strcmp(context, lp->context) && lp->owner) {
153                         res = AST_DEVICE_INUSE;
154                         break;
155                 }
156         }
157         AST_LIST_UNLOCK(&locals);
158
159         return res;
160 }
161
162 /*!
163  * \note Assumes the pvt is no longer in the pvts list
164  */
165 static struct local_pvt *local_pvt_destroy(struct local_pvt *pvt)
166 {
167         ast_mutex_destroy(&pvt->lock);
168         ast_free(pvt);
169         return NULL;
170 }
171
172 /*! \brief Return the bridged channel of a Local channel */
173 static struct ast_channel *local_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge)
174 {
175         struct local_pvt *p = bridge->tech_pvt;
176         struct ast_channel *bridged = bridge;
177
178         ast_mutex_lock(&p->lock);
179
180         if (ast_test_flag(p, LOCAL_BRIDGE)) {
181                 /* Find the opposite channel */
182                 bridged = (bridge == p->owner ? p->chan : p->owner);
183                 
184                 /* Now see if the opposite channel is bridged to anything */
185                 if (!bridged) {
186                         bridged = bridge;
187                 } else if (bridged->_bridge) {
188                         bridged = bridged->_bridge;
189                 }
190         }
191
192         ast_mutex_unlock(&p->lock);
193
194         return bridged;
195 }
196
197 static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, 
198         struct ast_channel *us, int us_locked)
199 {
200         struct ast_channel *other = NULL;
201
202         /* Recalculate outbound channel */
203         other = isoutbound ? p->owner : p->chan;
204
205         if (!other) {
206                 return 0;
207         }
208
209         /* do not queue frame if generator is on both local channels */
210         if (us && us->generator && other->generator) {
211                 return 0;
212         }
213
214         /* Set glare detection */
215         ast_set_flag(p, LOCAL_GLARE_DETECT);
216
217         /* Ensure that we have both channels locked */
218         while (other && ast_channel_trylock(other)) {
219                 ast_mutex_unlock(&p->lock);
220                 if (us && us_locked) {
221                         do {
222                                 CHANNEL_DEADLOCK_AVOIDANCE(us);
223                         } while (ast_mutex_trylock(&p->lock));
224                 } else {
225                         usleep(1);
226                         ast_mutex_lock(&p->lock);
227                 }
228                 other = isoutbound ? p->owner : p->chan;
229         }
230
231         /* Since glare detection only occurs within this function, and because
232          * a pvt flag cannot be set without having the pvt lock, this is the only
233          * location where we could detect a cancelling of the queue. */
234         if (ast_test_flag(p, LOCAL_CANCEL_QUEUE)) {
235                 /* We had a glare on the hangup.  Forget all this business,
236                 return and destroy p.  */
237                 ast_mutex_unlock(&p->lock);
238                 p = local_pvt_destroy(p);
239                 return -1;
240         }
241
242         if (other) {
243                 ast_queue_frame(other, f);
244                 ast_channel_unlock(other);
245         }
246
247         ast_clear_flag(p, LOCAL_GLARE_DETECT);
248
249         return 0;
250 }
251
252 static int local_answer(struct ast_channel *ast)
253 {
254         struct local_pvt *p = ast->tech_pvt;
255         int isoutbound;
256         int res = -1;
257
258         if (!p)
259                 return -1;
260
261         ast_mutex_lock(&p->lock);
262         isoutbound = IS_OUTBOUND(ast, p);
263         if (isoutbound) {
264                 /* Pass along answer since somebody answered us */
265                 struct ast_frame answer = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
266                 res = local_queue_frame(p, isoutbound, &answer, ast, 1);
267         } else
268                 ast_log(LOG_WARNING, "Huh?  Local is being asked to answer?\n");
269         if (!res)
270                 ast_mutex_unlock(&p->lock);
271         return res;
272 }
273
274 static void check_bridge(struct local_pvt *p, int isoutbound)
275 {
276         struct ast_channel_monitor *tmp;
277         if (ast_test_flag(p, LOCAL_ALREADY_MASQED) || ast_test_flag(p, LOCAL_NO_OPTIMIZATION) || !p->chan || !p->owner || (p->chan->_bridge != ast_bridged_channel(p->chan)))
278                 return;
279
280         /* only do the masquerade if we are being called on the outbound channel,
281            if it has been bridged to another channel and if there are no pending
282            frames on the owner channel (because they would be transferred to the
283            outbound channel during the masquerade)
284         */
285         if (isoutbound && p->chan->_bridge /* Not ast_bridged_channel!  Only go one step! */ && AST_LIST_EMPTY(&p->owner->readq)) {
286                 /* Masquerade bridged channel into owner */
287                 /* Lock everything we need, one by one, and give up if
288                    we can't get everything.  Remember, we'll get another
289                    chance in just a little bit */
290                 if (!ast_channel_trylock(p->chan->_bridge)) {
291                         if (!ast_check_hangup(p->chan->_bridge)) {
292                                 if (!ast_channel_trylock(p->owner)) {
293                                         if (!ast_check_hangup(p->owner)) {
294                                                 if (p->owner->monitor && !p->chan->_bridge->monitor) {
295                                                         /* If a local channel is being monitored, we don't want a masquerade
296                                                          * to cause the monitor to go away. Since the masquerade swaps the monitors,
297                                                          * pre-swapping the monitors before the masquerade will ensure that the monitor
298                                                          * ends up where it is expected.
299                                                          */
300                                                         tmp = p->owner->monitor;
301                                                         p->owner->monitor = p->chan->_bridge->monitor;
302                                                         p->chan->_bridge->monitor = tmp;
303                                                 }
304                                                 if (p->chan->audiohooks) {
305                                                         struct ast_audiohook_list *audiohooks_swapper;
306                                                         audiohooks_swapper = p->chan->audiohooks;
307                                                         p->chan->audiohooks = p->owner->audiohooks;
308                                                         p->owner->audiohooks = audiohooks_swapper;
309                                                 }
310                                                 ast_app_group_update(p->chan, p->owner);
311                                                 ast_channel_masquerade(p->owner, p->chan->_bridge);
312                                                 ast_set_flag(p, LOCAL_ALREADY_MASQED);
313                                         }
314                                         ast_channel_unlock(p->owner);
315                                 }
316                                 ast_channel_unlock(p->chan->_bridge);
317                         }
318                 }
319         /* We only allow masquerading in one 'direction'... it's important to preserve the state
320            (group variables, etc.) that live on p->chan->_bridge (and were put there by the dialplan)
321            when the local channels go away.
322         */
323 #if 0
324         } else if (!isoutbound && p->owner && p->owner->_bridge && p->chan && AST_LIST_EMPTY(&p->chan->readq)) {
325                 /* Masquerade bridged channel into chan */
326                 if (!ast_mutex_trylock(&(p->owner->_bridge)->lock)) {
327                         if (!ast_check_hangup(p->owner->_bridge)) {
328                                 if (!ast_mutex_trylock(&p->chan->lock)) {
329                                         if (!ast_check_hangup(p->chan)) {
330                                                 ast_channel_masquerade(p->chan, p->owner->_bridge);
331                                                 ast_set_flag(p, LOCAL_ALREADY_MASQED);
332                                         }
333                                         ast_mutex_unlock(&p->chan->lock);
334                                 }
335                         }
336                         ast_mutex_unlock(&(p->owner->_bridge)->lock);
337                 }
338 #endif
339         }
340 }
341
342 static struct ast_frame  *local_read(struct ast_channel *ast)
343 {
344         return &ast_null_frame;
345 }
346
347 static int local_write(struct ast_channel *ast, struct ast_frame *f)
348 {
349         struct local_pvt *p = ast->tech_pvt;
350         int res = -1;
351         int isoutbound;
352
353         if (!p)
354                 return -1;
355
356         /* Just queue for delivery to the other side */
357         ast_mutex_lock(&p->lock);
358         isoutbound = IS_OUTBOUND(ast, p);
359         if (f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO))
360                 check_bridge(p, isoutbound);
361         if (!ast_test_flag(p, LOCAL_ALREADY_MASQED))
362                 res = local_queue_frame(p, isoutbound, f, ast, 1);
363         else {
364                 ast_debug(1, "Not posting to queue since already masked on '%s'\n", ast->name);
365                 res = 0;
366         }
367         if (!res)
368                 ast_mutex_unlock(&p->lock);
369         return res;
370 }
371
372 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
373 {
374         struct local_pvt *p = newchan->tech_pvt;
375
376         if (!p)
377                 return -1;
378
379         ast_mutex_lock(&p->lock);
380
381         if ((p->owner != oldchan) && (p->chan != oldchan)) {
382                 ast_log(LOG_WARNING, "Old channel wasn't %p but was %p/%p\n", oldchan, p->owner, p->chan);
383                 ast_mutex_unlock(&p->lock);
384                 return -1;
385         }
386         if (p->owner == oldchan)
387                 p->owner = newchan;
388         else
389                 p->chan = newchan;
390         ast_mutex_unlock(&p->lock);
391         return 0;
392 }
393
394 static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
395 {
396         struct local_pvt *p = ast->tech_pvt;
397         int res = 0;
398         struct ast_frame f = { AST_FRAME_CONTROL, };
399         int isoutbound;
400
401         if (!p)
402                 return -1;
403
404         /* If this is an MOH hold or unhold, do it on the Local channel versus real channel */
405         if (condition == AST_CONTROL_HOLD) {
406                 ast_moh_start(ast, data, NULL);
407         } else if (condition == AST_CONTROL_UNHOLD) {
408                 ast_moh_stop(ast);
409         } else if (condition == AST_CONTROL_CONNECTED_LINE || condition == AST_CONTROL_REDIRECTING) {
410                 struct ast_channel *this_channel;
411                 struct ast_channel *the_other_channel;
412                 /* A connected line update frame may only contain a partial amount of data, such
413                  * as just a source, or just a ton, and not the full amount of information. However,
414                  * the collected information is all stored in the outgoing channel's connectedline
415                  * structure, so when receiving a connected line update on an outgoing local channel,
416                  * we need to transmit the collected connected line information instead of whatever
417                  * happens to be in this control frame. The same applies for redirecting information, which
418                  * is why it is handled here as well.*/
419                 isoutbound = IS_OUTBOUND(ast, p);
420                 if (isoutbound) {
421                         this_channel = p->chan;
422                         the_other_channel = p->owner;
423                 } else {
424                         this_channel = p->owner;
425                         the_other_channel = p->chan;
426                 }
427                 if (the_other_channel) {
428                         unsigned char frame_data[1024];
429                         if (condition == AST_CONTROL_CONNECTED_LINE) {
430                                 f.datalen = ast_connected_line_build_data(frame_data, sizeof(frame_data), &this_channel->connected);
431                         } else {
432                                 f.datalen = ast_redirecting_build_data(frame_data, sizeof(frame_data), &this_channel->redirecting);
433                         }
434                         f.subclass = condition;
435                         f.data.ptr = frame_data;
436                         if (!(res = local_queue_frame(p, isoutbound, &f, ast, 1))) {
437                                 ast_mutex_unlock(&p->lock);
438                         }
439                 }
440         } else {
441                 /* Queue up a frame representing the indication as a control frame */
442                 ast_mutex_lock(&p->lock);
443                 isoutbound = IS_OUTBOUND(ast, p);
444                 f.subclass = condition;
445                 f.data.ptr = (void*)data;
446                 f.datalen = datalen;
447                 if (!(res = local_queue_frame(p, isoutbound, &f, ast, 1)))
448                         ast_mutex_unlock(&p->lock);
449         }
450
451         return res;
452 }
453
454 static int local_digit_begin(struct ast_channel *ast, char digit)
455 {
456         struct local_pvt *p = ast->tech_pvt;
457         int res = -1;
458         struct ast_frame f = { AST_FRAME_DTMF_BEGIN, };
459         int isoutbound;
460
461         if (!p)
462                 return -1;
463
464         ast_mutex_lock(&p->lock);
465         isoutbound = IS_OUTBOUND(ast, p);
466         f.subclass = digit;
467         if (!(res = local_queue_frame(p, isoutbound, &f, ast, 0)))
468                 ast_mutex_unlock(&p->lock);
469
470         return res;
471 }
472
473 static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
474 {
475         struct local_pvt *p = ast->tech_pvt;
476         int res = -1;
477         struct ast_frame f = { AST_FRAME_DTMF_END, };
478         int isoutbound;
479
480         if (!p)
481                 return -1;
482
483         ast_mutex_lock(&p->lock);
484         isoutbound = IS_OUTBOUND(ast, p);
485         f.subclass = digit;
486         f.len = duration;
487         if (!(res = local_queue_frame(p, isoutbound, &f, ast, 0)))
488                 ast_mutex_unlock(&p->lock);
489
490         return res;
491 }
492
493 static int local_sendtext(struct ast_channel *ast, const char *text)
494 {
495         struct local_pvt *p = ast->tech_pvt;
496         int res = -1;
497         struct ast_frame f = { AST_FRAME_TEXT, };
498         int isoutbound;
499
500         if (!p)
501                 return -1;
502
503         ast_mutex_lock(&p->lock);
504         isoutbound = IS_OUTBOUND(ast, p);
505         f.data.ptr = (char *) text;
506         f.datalen = strlen(text) + 1;
507         if (!(res = local_queue_frame(p, isoutbound, &f, ast, 0)))
508                 ast_mutex_unlock(&p->lock);
509         return res;
510 }
511
512 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
513 {
514         struct local_pvt *p = ast->tech_pvt;
515         int res = -1;
516         struct ast_frame f = { AST_FRAME_HTML, };
517         int isoutbound;
518
519         if (!p)
520                 return -1;
521         
522         ast_mutex_lock(&p->lock);
523         isoutbound = IS_OUTBOUND(ast, p);
524         f.subclass = subclass;
525         f.data.ptr = (char *)data;
526         f.datalen = datalen;
527         if (!(res = local_queue_frame(p, isoutbound, &f, ast, 0)))
528                 ast_mutex_unlock(&p->lock);
529         return res;
530 }
531
532 /*! \brief Initiate new call, part of PBX interface 
533  *      dest is the dial string */
534 static int local_call(struct ast_channel *ast, char *dest, int timeout)
535 {
536         struct local_pvt *p = ast->tech_pvt;
537         int res;
538         struct ast_var_t *varptr = NULL, *new;
539         size_t len, namelen;
540
541         if (!p)
542                 return -1;
543
544         /* If you value your sanity, please don't look at this code */
545 start_over:
546         while (ast_channel_trylock(p->chan)) {
547                 ast_channel_unlock(p->owner);
548                 usleep(1);
549                 ast_channel_lock(p->owner);
550         }
551
552         /* p->owner and p->chan are locked now. Let's get p locked */
553         if (ast_mutex_trylock(&p->lock)) {
554                 /* @#$&$@ */
555                 ast_channel_unlock(p->chan);
556                 ast_channel_unlock(p->owner);
557                 usleep(1);
558                 ast_channel_lock(p->owner);
559                 goto start_over;
560         }
561
562         /*
563          * Note that cid_num and cid_name aren't passed in the ast_channel_alloc
564          * call, so it's done here instead.
565          *
566          * All these failure points just return -1. The individual strings will
567          * be cleared when we destroy the channel.
568          */
569         if (!(p->chan->cid.cid_rdnis = ast_strdup(p->owner->cid.cid_rdnis))) {
570                 return -1;
571         }
572         ast_party_redirecting_copy(&p->chan->redirecting, &p->owner->redirecting);
573
574         if (!(p->chan->cid.cid_dnid = ast_strdup(p->owner->cid.cid_dnid))) {
575                 return -1;
576         }
577         p->chan->cid.cid_tns = p->owner->cid.cid_tns;
578
579         ast_connected_line_copy_to_caller(&p->chan->cid, &p->owner->connected);
580         ast_connected_line_copy_from_caller(&p->chan->connected, &p->owner->cid);
581
582         ast_string_field_set(p->chan, language, p->owner->language);
583         ast_string_field_set(p->chan, accountcode, p->owner->accountcode);
584         ast_string_field_set(p->chan, musicclass, p->owner->musicclass);
585         ast_cdr_update(p->chan);
586         p->chan->cdrflags = p->owner->cdrflags;
587
588         if (!ast_exists_extension(NULL, p->chan->context, p->chan->exten, 1, p->owner->cid.cid_num)) {
589                 ast_log(LOG_NOTICE, "No such extension/context %s@%s while calling Local channel\n", p->chan->exten, p->chan->context);
590                 ast_mutex_unlock(&p->lock);
591                 return -1;
592         }
593
594         /* Make sure we inherit the ANSWERED_ELSEWHERE flag if it's set on the queue/dial call request in the dialplan */
595         if (ast_test_flag(ast, AST_FLAG_ANSWERED_ELSEWHERE)) {
596                 ast_set_flag(p->chan, AST_FLAG_ANSWERED_ELSEWHERE);
597         }
598
599         /* copy the channel variables from the incoming channel to the outgoing channel */
600         /* Note that due to certain assumptions, they MUST be in the same order */
601         AST_LIST_TRAVERSE(&p->owner->varshead, varptr, entries) {
602                 namelen = strlen(varptr->name);
603                 len = sizeof(struct ast_var_t) + namelen + strlen(varptr->value) + 2;
604                 if ((new = ast_calloc(1, len))) {
605                         memcpy(new, varptr, len);
606                         new->value = &(new->name[0]) + namelen + 1;
607                         AST_LIST_INSERT_TAIL(&p->chan->varshead, new, entries);
608                 }
609         }
610         ast_channel_datastore_inherit(p->owner, p->chan);
611
612         /* Start switch on sub channel */
613         if (!(res = ast_pbx_start(p->chan)))
614                 ast_set_flag(p, LOCAL_LAUNCHED_PBX);
615
616         ast_mutex_unlock(&p->lock);
617         ast_channel_unlock(p->chan);
618         return res;
619 }
620
621 /*! \brief Hangup a call through the local proxy channel */
622 static int local_hangup(struct ast_channel *ast)
623 {
624         struct local_pvt *p = ast->tech_pvt;
625         int isoutbound;
626         struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, .data.uint32 = ast->hangupcause };
627         struct ast_channel *ochan = NULL;
628         int glaredetect = 0, res = 0;
629
630         if (!p)
631                 return -1;
632
633         ast_mutex_lock(&p->lock);
634
635         isoutbound = IS_OUTBOUND(ast, p);
636
637         if (p->chan && ast_test_flag(ast, AST_FLAG_ANSWERED_ELSEWHERE)) {
638                 ast_set_flag(p->chan, AST_FLAG_ANSWERED_ELSEWHERE);
639                 ast_debug(2, "This local call has the ANSWERED_ELSEWHERE flag set.\n");
640         }
641
642         if (isoutbound) {
643                 const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
644                 if ((status) && (p->owner)) {
645                         /* Deadlock avoidance */
646                         while (p->owner && ast_channel_trylock(p->owner)) {
647                                 ast_mutex_unlock(&p->lock);
648                                 if (ast) {
649                                         ast_channel_unlock(ast);
650                                 }
651                                 usleep(1);
652                                 if (ast) {
653                                         ast_channel_lock(ast);
654                                 }
655                                 ast_mutex_lock(&p->lock);
656                         }
657                         if (p->owner) {
658                                 pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
659                                 ast_channel_unlock(p->owner);
660                         }
661                 }
662                 p->chan = NULL;
663                 ast_clear_flag(p, LOCAL_LAUNCHED_PBX);
664                 ast_module_user_remove(p->u_chan);
665         } else {
666                 p->owner = NULL;
667                 ast_module_user_remove(p->u_owner);
668                 while (p->chan && ast_channel_trylock(p->chan)) {
669                         DEADLOCK_AVOIDANCE(&p->lock);
670                 }
671                 if (p->chan) {
672                         ast_queue_hangup(p->chan);
673                         ast_channel_unlock(p->chan);
674                 }
675         }
676         
677         ast->tech_pvt = NULL;
678         
679         if (!p->owner && !p->chan) {
680                 /* Okay, done with the private part now, too. */
681                 glaredetect = ast_test_flag(p, LOCAL_GLARE_DETECT);
682                 /* If we have a queue holding, don't actually destroy p yet, but
683                    let local_queue do it. */
684                 if (glaredetect)
685                         ast_set_flag(p, LOCAL_CANCEL_QUEUE);
686                 ast_mutex_unlock(&p->lock);
687                 /* Remove from list */
688                 AST_LIST_LOCK(&locals);
689                 AST_LIST_REMOVE(&locals, p, list);
690                 AST_LIST_UNLOCK(&locals);
691                 /* Grab / release lock just in case */
692                 ast_mutex_lock(&p->lock);
693                 ast_mutex_unlock(&p->lock);
694                 /* And destroy */
695                 if (!glaredetect) {
696                         p = local_pvt_destroy(p);
697                 }
698                 return 0;
699         }
700         if (p->chan && !ast_test_flag(p, LOCAL_LAUNCHED_PBX))
701                 /* Need to actually hangup since there is no PBX */
702                 ochan = p->chan;
703         else
704                 res = local_queue_frame(p, isoutbound, &f, NULL, 1);
705         if (!res)
706                 ast_mutex_unlock(&p->lock);
707         if (ochan)
708                 ast_hangup(ochan);
709         return 0;
710 }
711
712 /*! \brief Create a call structure */
713 static struct local_pvt *local_alloc(const char *data, int format)
714 {
715         struct local_pvt *tmp = NULL;
716         char *c = NULL, *opts = NULL;
717
718         if (!(tmp = ast_calloc(1, sizeof(*tmp))))
719                 return NULL;
720
721         /* Initialize private structure information */
722         ast_mutex_init(&tmp->lock);
723         ast_copy_string(tmp->exten, data, sizeof(tmp->exten));
724
725         memcpy(&tmp->jb_conf, &g_jb_conf, sizeof(tmp->jb_conf));
726
727         /* Look for options */
728         if ((opts = strchr(tmp->exten, '/'))) {
729                 *opts++ = '\0';
730                 if (strchr(opts, 'n'))
731                         ast_set_flag(tmp, LOCAL_NO_OPTIMIZATION);
732                 if (strchr(opts, 'j')) {
733                         if (ast_test_flag(tmp, LOCAL_NO_OPTIMIZATION))
734                                 ast_set_flag(&tmp->jb_conf, AST_JB_ENABLED);
735                         else {
736                                 ast_log(LOG_ERROR, "You must use the 'n' option for chan_local "
737                                         "to use the 'j' option to enable the jitterbuffer\n");
738                         }
739                 }
740                 if (strchr(opts, 'b')) {
741                         ast_set_flag(tmp, LOCAL_BRIDGE);
742                 }
743         }
744
745         /* Look for a context */
746         if ((c = strchr(tmp->exten, '@')))
747                 *c++ = '\0';
748
749         ast_copy_string(tmp->context, c ? c : "default", sizeof(tmp->context));
750
751         tmp->reqformat = format;
752
753 #if 0
754         /* We can't do this check here, because we don't know the CallerID yet, and
755          * the CallerID could potentially affect what step is actually taken (or
756          * even if that step exists). */
757         if (!ast_exists_extension(NULL, tmp->context, tmp->exten, 1, NULL)) {
758                 ast_log(LOG_NOTICE, "No such extension/context %s@%s creating local channel\n", tmp->exten, tmp->context);
759                 tmp = local_pvt_destroy(tmp);
760         } else {
761 #endif
762                 /* Add to list */
763                 AST_LIST_LOCK(&locals);
764                 AST_LIST_INSERT_HEAD(&locals, tmp, list);
765                 AST_LIST_UNLOCK(&locals);
766 #if 0
767         }
768 #endif
769         
770         return tmp;
771 }
772
773 /*! \brief Start new local channel */
774 static struct ast_channel *local_new(struct local_pvt *p, int state)
775 {
776         struct ast_channel *tmp = NULL, *tmp2 = NULL;
777         int randnum = ast_random() & 0xffff, fmt = 0;
778         const char *t;
779         int ama;
780
781         /* Allocate two new Asterisk channels */
782         /* safe accountcode */
783         if (p->owner && p->owner->accountcode)
784                 t = p->owner->accountcode;
785         else
786                 t = "";
787
788         if (p->owner)
789                 ama = p->owner->amaflags;
790         else
791                 ama = 0;
792         if (!(tmp = ast_channel_alloc(1, state, 0, 0, t, p->exten, p->context, ama, "Local/%s@%s-%04x;1", p->exten, p->context, randnum)) 
793                         || !(tmp2 = ast_channel_alloc(1, AST_STATE_RING, 0, 0, t, p->exten, p->context, ama, "Local/%s@%s-%04x;2", p->exten, p->context, randnum))) {
794                 if (tmp)
795                         ast_channel_free(tmp);
796                 if (tmp2)
797                         ast_channel_free(tmp2);
798                 ast_log(LOG_WARNING, "Unable to allocate channel structure(s)\n");
799                 return NULL;
800         } 
801
802         tmp2->tech = tmp->tech = &local_tech;
803
804         tmp->nativeformats = p->reqformat;
805         tmp2->nativeformats = p->reqformat;
806
807         /* Determine our read/write format and set it on each channel */
808         fmt = ast_best_codec(p->reqformat);
809         tmp->writeformat = fmt;
810         tmp2->writeformat = fmt;
811         tmp->rawwriteformat = fmt;
812         tmp2->rawwriteformat = fmt;
813         tmp->readformat = fmt;
814         tmp2->readformat = fmt;
815         tmp->rawreadformat = fmt;
816         tmp2->rawreadformat = fmt;
817
818         tmp->tech_pvt = p;
819         tmp2->tech_pvt = p;
820
821         p->owner = tmp;
822         p->chan = tmp2;
823         p->u_owner = ast_module_user_add(p->owner);
824         p->u_chan = ast_module_user_add(p->chan);
825
826         ast_copy_string(tmp->context, p->context, sizeof(tmp->context));
827         ast_copy_string(tmp2->context, p->context, sizeof(tmp2->context));
828         ast_copy_string(tmp2->exten, p->exten, sizeof(tmp->exten));
829         tmp->priority = 1;
830         tmp2->priority = 1;
831
832         ast_jb_configure(tmp, &p->jb_conf);
833
834         return tmp;
835 }
836
837 /*! \brief Part of PBX interface */
838 static struct ast_channel *local_request(const char *type, int format, void *data, int *cause)
839 {
840         struct local_pvt *p = NULL;
841         struct ast_channel *chan = NULL;
842
843         /* Allocate a new private structure and then Asterisk channel */
844         if ((p = local_alloc(data, format))) {
845                 if (!(chan = local_new(p, AST_STATE_DOWN))) {
846                         AST_LIST_LOCK(&locals);
847                         AST_LIST_REMOVE(&locals, p, list);
848                         AST_LIST_UNLOCK(&locals);
849                         p = local_pvt_destroy(p);
850                 }
851         }
852
853         return chan;
854 }
855
856 /*! \brief CLI command "local show channels" */
857 static char *locals_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
858 {
859         struct local_pvt *p = NULL;
860
861         switch (cmd) {
862         case CLI_INIT:
863                 e->command = "local show channels";
864                 e->usage =
865                         "Usage: local show channels\n"
866                         "       Provides summary information on active local proxy channels.\n";
867                 return NULL;
868         case CLI_GENERATE:
869                 return NULL;
870         }
871
872         if (a->argc != 3)
873                 return CLI_SHOWUSAGE;
874
875         AST_LIST_LOCK(&locals);
876         if (!AST_LIST_EMPTY(&locals)) {
877                 AST_LIST_TRAVERSE(&locals, p, list) {
878                         ast_mutex_lock(&p->lock);
879                         ast_cli(a->fd, "%s -- %s@%s\n", p->owner ? p->owner->name : "<unowned>", p->exten, p->context);
880                         ast_mutex_unlock(&p->lock);
881                 }
882         } else
883                 ast_cli(a->fd, "No local channels in use\n");
884         AST_LIST_UNLOCK(&locals);
885
886         return CLI_SUCCESS;
887 }
888
889 static struct ast_cli_entry cli_local[] = {
890         AST_CLI_DEFINE(locals_show, "List status of local channels"),
891 };
892
893 /*! \brief Load module into PBX, register channel */
894 static int load_module(void)
895 {
896         /* Make sure we can register our channel type */
897         if (ast_channel_register(&local_tech)) {
898                 ast_log(LOG_ERROR, "Unable to register channel class 'Local'\n");
899                 return AST_MODULE_LOAD_FAILURE;
900         }
901         ast_cli_register_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
902         return AST_MODULE_LOAD_SUCCESS;
903 }
904
905 /*! \brief Unload the local proxy channel from Asterisk */
906 static int unload_module(void)
907 {
908         struct local_pvt *p = NULL;
909
910         /* First, take us out of the channel loop */
911         ast_cli_unregister_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
912         ast_channel_unregister(&local_tech);
913         if (!AST_LIST_LOCK(&locals)) {
914                 /* Hangup all interfaces if they have an owner */
915                 AST_LIST_TRAVERSE(&locals, p, list) {
916                         if (p->owner)
917                                 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
918                 }
919                 AST_LIST_UNLOCK(&locals);
920         } else {
921                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
922                 return -1;
923         }               
924         return 0;
925 }
926
927 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Local Proxy Channel (Note: used internally by other modules)");