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