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