Revert half of the fix, as this part may have been unnecessary (related to issue...
[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         /* Set glare detection */
207         ast_set_flag(p, LOCAL_GLARE_DETECT);
208         if (ast_test_flag(p, LOCAL_CANCEL_QUEUE)) {
209                 /* We had a glare on the hangup.  Forget all this business,
210                 return and destroy p.  */
211                 ast_mutex_unlock(&p->lock);
212                 p = local_pvt_destroy(p);
213                 return -1;
214         }
215         if (!other) {
216                 ast_clear_flag(p, LOCAL_GLARE_DETECT);
217                 return 0;
218         }
219
220         /* Ensure that we have both channels locked */
221         while (other && ast_channel_trylock(other)) {
222                 ast_mutex_unlock(&p->lock);
223                 if (us && us_locked) {
224                         do {
225                                 CHANNEL_DEADLOCK_AVOIDANCE(us);
226                         } while (ast_mutex_trylock(&p->lock));
227                 } else {
228                         usleep(1);
229                         ast_mutex_lock(&p->lock);
230                 }
231                 other = isoutbound ? p->owner : p->chan;
232         }
233
234         if (other) {
235                 ast_queue_frame(other, f);
236                 ast_channel_unlock(other);
237         }
238
239         ast_clear_flag(p, LOCAL_GLARE_DETECT);
240
241         return 0;
242 }
243
244 static int local_answer(struct ast_channel *ast)
245 {
246         struct local_pvt *p = ast->tech_pvt;
247         int isoutbound;
248         int res = -1;
249
250         if (!p)
251                 return -1;
252
253         ast_mutex_lock(&p->lock);
254         isoutbound = IS_OUTBOUND(ast, p);
255         if (isoutbound) {
256                 /* Pass along answer since somebody answered us */
257                 struct ast_frame answer = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
258                 res = local_queue_frame(p, isoutbound, &answer, ast, 1);
259         } else
260                 ast_log(LOG_WARNING, "Huh?  Local is being asked to answer?\n");
261         if (!res)
262                 ast_mutex_unlock(&p->lock);
263         return res;
264 }
265
266 static void check_bridge(struct local_pvt *p, int isoutbound)
267 {
268         struct ast_channel_monitor *tmp;
269         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)))
270                 return;
271
272         /* only do the masquerade if we are being called on the outbound channel,
273            if it has been bridged to another channel and if there are no pending
274            frames on the owner channel (because they would be transferred to the
275            outbound channel during the masquerade)
276         */
277         if (isoutbound && p->chan->_bridge /* Not ast_bridged_channel!  Only go one step! */ && AST_LIST_EMPTY(&p->owner->readq)) {
278                 /* Masquerade bridged channel into owner */
279                 /* Lock everything we need, one by one, and give up if
280                    we can't get everything.  Remember, we'll get another
281                    chance in just a little bit */
282                 if (!ast_channel_trylock(p->chan->_bridge)) {
283                         if (!ast_check_hangup(p->chan->_bridge)) {
284                                 if (!ast_channel_trylock(p->owner)) {
285                                         if (!ast_check_hangup(p->owner)) {
286                                                 if(p->owner->monitor && !p->chan->_bridge->monitor) {
287                                                         /* If a local channel is being monitored, we don't want a masquerade
288                                                          * to cause the monitor to go away. Since the masquerade swaps the monitors,
289                                                          * pre-swapping the monitors before the masquerade will ensure that the monitor
290                                                          * ends up where it is expected.
291                                                          */
292                                                         tmp = p->owner->monitor;
293                                                         p->owner->monitor = p->chan->_bridge->monitor;
294                                                         p->chan->_bridge->monitor = tmp;
295                                                 }
296                                                 ast_channel_masquerade(p->owner, p->chan->_bridge);
297                                                 ast_set_flag(p, LOCAL_ALREADY_MASQED);
298                                         }
299                                         ast_channel_unlock(p->owner);
300                                 }
301                                 ast_channel_unlock(p->chan->_bridge);
302                         }
303                 }
304         /* We only allow masquerading in one 'direction'... it's important to preserve the state
305            (group variables, etc.) that live on p->chan->_bridge (and were put there by the dialplan)
306            when the local channels go away.
307         */
308 #if 0
309         } else if (!isoutbound && p->owner && p->owner->_bridge && p->chan && AST_LIST_EMPTY(&p->chan->readq)) {
310                 /* Masquerade bridged channel into chan */
311                 if (!ast_mutex_trylock(&(p->owner->_bridge)->lock)) {
312                         if (!ast_check_hangup(p->owner->_bridge)) {
313                                 if (!ast_mutex_trylock(&p->chan->lock)) {
314                                         if (!ast_check_hangup(p->chan)) {
315                                                 ast_channel_masquerade(p->chan, p->owner->_bridge);
316                                                 ast_set_flag(p, LOCAL_ALREADY_MASQED);
317                                         }
318                                         ast_mutex_unlock(&p->chan->lock);
319                                 }
320                         }
321                         ast_mutex_unlock(&(p->owner->_bridge)->lock);
322                 }
323 #endif
324         }
325 }
326
327 static struct ast_frame  *local_read(struct ast_channel *ast)
328 {
329         return &ast_null_frame;
330 }
331
332 static int local_write(struct ast_channel *ast, struct ast_frame *f)
333 {
334         struct local_pvt *p = ast->tech_pvt;
335         int res = -1;
336         int isoutbound;
337
338         if (!p)
339                 return -1;
340
341         /* Just queue for delivery to the other side */
342         ast_mutex_lock(&p->lock);
343         isoutbound = IS_OUTBOUND(ast, p);
344         if (f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO))
345                 check_bridge(p, isoutbound);
346         if (!ast_test_flag(p, LOCAL_ALREADY_MASQED))
347                 res = local_queue_frame(p, isoutbound, f, ast, 1);
348         else {
349                 ast_debug(1, "Not posting to queue since already masked on '%s'\n", ast->name);
350                 res = 0;
351         }
352         if (!res)
353                 ast_mutex_unlock(&p->lock);
354         return res;
355 }
356
357 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
358 {
359         struct local_pvt *p = newchan->tech_pvt;
360
361         if (!p)
362                 return -1;
363
364         ast_mutex_lock(&p->lock);
365
366         if ((p->owner != oldchan) && (p->chan != oldchan)) {
367                 ast_log(LOG_WARNING, "Old channel wasn't %p but was %p/%p\n", oldchan, p->owner, p->chan);
368                 ast_mutex_unlock(&p->lock);
369                 return -1;
370         }
371         if (p->owner == oldchan)
372                 p->owner = newchan;
373         else
374                 p->chan = newchan;
375         ast_mutex_unlock(&p->lock);
376         return 0;
377 }
378
379 static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
380 {
381         struct local_pvt *p = ast->tech_pvt;
382         int res = 0;
383         struct ast_frame f = { AST_FRAME_CONTROL, };
384         int isoutbound;
385
386         if (!p)
387                 return -1;
388
389         /* If this is an MOH hold or unhold, do it on the Local channel versus real channel */
390         if (condition == AST_CONTROL_HOLD) {
391                 ast_moh_start(ast, data, NULL);
392         } else if (condition == AST_CONTROL_UNHOLD) {
393                 ast_moh_stop(ast);
394         } else {
395                 /* Queue up a frame representing the indication as a control frame */
396                 ast_mutex_lock(&p->lock);
397                 isoutbound = IS_OUTBOUND(ast, p);
398                 f.subclass = condition;
399                 f.data.ptr = (void*)data;
400                 f.datalen = datalen;
401                 if (!(res = local_queue_frame(p, isoutbound, &f, ast, 1)))
402                         ast_mutex_unlock(&p->lock);
403         }
404
405         return res;
406 }
407
408 static int local_digit_begin(struct ast_channel *ast, char digit)
409 {
410         struct local_pvt *p = ast->tech_pvt;
411         int res = -1;
412         struct ast_frame f = { AST_FRAME_DTMF_BEGIN, };
413         int isoutbound;
414
415         if (!p)
416                 return -1;
417
418         ast_mutex_lock(&p->lock);
419         isoutbound = IS_OUTBOUND(ast, p);
420         f.subclass = digit;
421         if (!(res = local_queue_frame(p, isoutbound, &f, ast, 0)))
422                 ast_mutex_unlock(&p->lock);
423
424         return res;
425 }
426
427 static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
428 {
429         struct local_pvt *p = ast->tech_pvt;
430         int res = -1;
431         struct ast_frame f = { AST_FRAME_DTMF_END, };
432         int isoutbound;
433
434         if (!p)
435                 return -1;
436
437         ast_mutex_lock(&p->lock);
438         isoutbound = IS_OUTBOUND(ast, p);
439         f.subclass = digit;
440         f.len = duration;
441         if (!(res = local_queue_frame(p, isoutbound, &f, ast, 0)))
442                 ast_mutex_unlock(&p->lock);
443
444         return res;
445 }
446
447 static int local_sendtext(struct ast_channel *ast, const char *text)
448 {
449         struct local_pvt *p = ast->tech_pvt;
450         int res = -1;
451         struct ast_frame f = { AST_FRAME_TEXT, };
452         int isoutbound;
453
454         if (!p)
455                 return -1;
456
457         ast_mutex_lock(&p->lock);
458         isoutbound = IS_OUTBOUND(ast, p);
459         f.data.ptr = (char *) text;
460         f.datalen = strlen(text) + 1;
461         if (!(res = local_queue_frame(p, isoutbound, &f, ast, 0)))
462                 ast_mutex_unlock(&p->lock);
463         return res;
464 }
465
466 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
467 {
468         struct local_pvt *p = ast->tech_pvt;
469         int res = -1;
470         struct ast_frame f = { AST_FRAME_HTML, };
471         int isoutbound;
472
473         if (!p)
474                 return -1;
475         
476         ast_mutex_lock(&p->lock);
477         isoutbound = IS_OUTBOUND(ast, p);
478         f.subclass = subclass;
479         f.data.ptr = (char *)data;
480         f.datalen = datalen;
481         if (!(res = local_queue_frame(p, isoutbound, &f, ast, 0)))
482                 ast_mutex_unlock(&p->lock);
483         return res;
484 }
485
486 /*! \brief Initiate new call, part of PBX interface 
487  *      dest is the dial string */
488 static int local_call(struct ast_channel *ast, char *dest, int timeout)
489 {
490         struct local_pvt *p = ast->tech_pvt;
491         int res;
492         struct ast_var_t *varptr = NULL, *new;
493         size_t len, namelen;
494
495         if (!p)
496                 return -1;
497         
498         ast_mutex_lock(&p->lock);
499
500         /*
501          * Note that cid_num and cid_name aren't passed in the ast_channel_alloc
502          * call, so it's done here instead.
503          */
504         p->chan->cid.cid_num = ast_strdup(p->owner->cid.cid_num);
505         p->chan->cid.cid_name = ast_strdup(p->owner->cid.cid_name);
506         p->chan->cid.cid_rdnis = ast_strdup(p->owner->cid.cid_rdnis);
507         p->chan->cid.cid_ani = ast_strdup(p->owner->cid.cid_ani);
508         p->chan->cid.cid_pres = p->owner->cid.cid_pres;
509         ast_string_field_set(p->chan, language, p->owner->language);
510         ast_string_field_set(p->chan, accountcode, p->owner->accountcode);
511         ast_cdr_update(p->chan);
512         p->chan->cdrflags = p->owner->cdrflags;
513
514         /* copy the channel variables from the incoming channel to the outgoing channel */
515         /* Note that due to certain assumptions, they MUST be in the same order */
516         AST_LIST_TRAVERSE(&p->owner->varshead, varptr, entries) {
517                 namelen = strlen(varptr->name);
518                 len = sizeof(struct ast_var_t) + namelen + strlen(varptr->value) + 2;
519                 if ((new = ast_calloc(1, len))) {
520                         memcpy(new, varptr, len);
521                         new->value = &(new->name[0]) + namelen + 1;
522                         AST_LIST_INSERT_TAIL(&p->chan->varshead, new, entries);
523                 }
524         }
525         ast_channel_datastore_inherit(p->owner, p->chan);
526
527         /* Start switch on sub channel */
528         if (!(res = ast_pbx_start(p->chan)))
529                 ast_set_flag(p, LOCAL_LAUNCHED_PBX);
530
531         ast_mutex_unlock(&p->lock);
532         return res;
533 }
534
535 /*! \brief Hangup a call through the local proxy channel */
536 static int local_hangup(struct ast_channel *ast)
537 {
538         struct local_pvt *p = ast->tech_pvt;
539         int isoutbound;
540         struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, .data.uint32 = ast->hangupcause };
541         struct ast_channel *ochan = NULL;
542         int glaredetect = 0, res = 0;
543
544         if (!p)
545                 return -1;
546
547         ast_mutex_lock(&p->lock);
548
549         if (p->chan && ast_test_flag(ast, AST_FLAG_ANSWERED_ELSEWHERE)) 
550                 ast_set_flag(p->chan, AST_FLAG_ANSWERED_ELSEWHERE);
551         isoutbound = IS_OUTBOUND(ast, p);
552         if (isoutbound) {
553                 const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
554                 if ((status) && (p->owner)) {
555                         /* Deadlock avoidance */
556                         while (p->owner && ast_channel_trylock(p->owner)) {
557                                 ast_mutex_unlock(&p->lock);
558                                 if (ast) {
559                                         ast_channel_unlock(ast);
560                                 }
561                                 usleep(1);
562                                 if (ast) {
563                                         ast_channel_lock(ast);
564                                 }
565                                 ast_mutex_lock(&p->lock);
566                         }
567                         if (p->owner) {
568                                 pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
569                                 ast_channel_unlock(p->owner);
570                         }
571                 }
572                 p->chan = NULL;
573                 ast_clear_flag(p, LOCAL_LAUNCHED_PBX);
574                 ast_module_user_remove(p->u_chan);
575         } else {
576                 p->owner = NULL;
577                 ast_module_user_remove(p->u_owner);
578                 if (p->chan) {
579                         ast_queue_hangup(p->chan);
580                 }
581         }
582         
583         ast->tech_pvt = NULL;
584         
585         if (!p->owner && !p->chan) {
586                 /* Okay, done with the private part now, too. */
587                 glaredetect = ast_test_flag(p, LOCAL_GLARE_DETECT);
588                 /* If we have a queue holding, don't actually destroy p yet, but
589                    let local_queue do it. */
590                 if (glaredetect)
591                         ast_set_flag(p, LOCAL_CANCEL_QUEUE);
592                 ast_mutex_unlock(&p->lock);
593                 /* Remove from list */
594                 AST_LIST_LOCK(&locals);
595                 AST_LIST_REMOVE(&locals, p, list);
596                 AST_LIST_UNLOCK(&locals);
597                 /* Grab / release lock just in case */
598                 ast_mutex_lock(&p->lock);
599                 ast_mutex_unlock(&p->lock);
600                 /* And destroy */
601                 if (!glaredetect) {
602                         p = local_pvt_destroy(p);
603                 }
604                 return 0;
605         }
606         if (p->chan && !ast_test_flag(p, LOCAL_LAUNCHED_PBX))
607                 /* Need to actually hangup since there is no PBX */
608                 ochan = p->chan;
609         else
610                 res = local_queue_frame(p, isoutbound, &f, NULL, 1);
611         if (!res)
612                 ast_mutex_unlock(&p->lock);
613         if (ochan)
614                 ast_hangup(ochan);
615         return 0;
616 }
617
618 /*! \brief Create a call structure */
619 static struct local_pvt *local_alloc(const char *data, int format)
620 {
621         struct local_pvt *tmp = NULL;
622         char *c = NULL, *opts = NULL;
623
624         if (!(tmp = ast_calloc(1, sizeof(*tmp))))
625                 return NULL;
626
627         /* Initialize private structure information */
628         ast_mutex_init(&tmp->lock);
629         ast_copy_string(tmp->exten, data, sizeof(tmp->exten));
630
631         memcpy(&tmp->jb_conf, &g_jb_conf, sizeof(tmp->jb_conf));
632
633         /* Look for options */
634         if ((opts = strchr(tmp->exten, '/'))) {
635                 *opts++ = '\0';
636                 if (strchr(opts, 'n'))
637                         ast_set_flag(tmp, LOCAL_NO_OPTIMIZATION);
638                 if (strchr(opts, 'j')) {
639                         if (ast_test_flag(tmp, LOCAL_NO_OPTIMIZATION))
640                                 ast_set_flag(&tmp->jb_conf, AST_JB_ENABLED);
641                         else {
642                                 ast_log(LOG_ERROR, "You must use the 'n' option for chan_local "
643                                         "to use the 'j' option to enable the jitterbuffer\n");
644                         }
645                 }
646                 if (strchr(opts, 'b')) {
647                         ast_set_flag(tmp, LOCAL_BRIDGE);
648                 }
649         }
650
651         /* Look for a context */
652         if ((c = strchr(tmp->exten, '@')))
653                 *c++ = '\0';
654
655         ast_copy_string(tmp->context, c ? c : "default", sizeof(tmp->context));
656
657         tmp->reqformat = format;
658
659         if (!ast_exists_extension(NULL, tmp->context, tmp->exten, 1, NULL)) {
660                 ast_log(LOG_NOTICE, "No such extension/context %s@%s creating local channel\n", tmp->exten, tmp->context);
661                 tmp = local_pvt_destroy(tmp);
662         } else {
663                 /* Add to list */
664                 AST_LIST_LOCK(&locals);
665                 AST_LIST_INSERT_HEAD(&locals, tmp, list);
666                 AST_LIST_UNLOCK(&locals);
667         }
668         
669         return tmp;
670 }
671
672 /*! \brief Start new local channel */
673 static struct ast_channel *local_new(struct local_pvt *p, int state)
674 {
675         struct ast_channel *tmp = NULL, *tmp2 = NULL;
676         int randnum = ast_random() & 0xffff, fmt = 0;
677         const char *t;
678         int ama;
679
680         /* Allocate two new Asterisk channels */
681         /* safe accountcode */
682         if (p->owner && p->owner->accountcode)
683                 t = p->owner->accountcode;
684         else
685                 t = "";
686
687         if (p->owner)
688                 ama = p->owner->amaflags;
689         else
690                 ama = 0;
691         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)) 
692                         || !(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))) {
693                 if (tmp)
694                         ast_channel_free(tmp);
695                 if (tmp2)
696                         ast_channel_free(tmp2);
697                 ast_log(LOG_WARNING, "Unable to allocate channel structure(s)\n");
698                 return NULL;
699         } 
700
701         tmp2->tech = tmp->tech = &local_tech;
702
703         tmp->nativeformats = p->reqformat;
704         tmp2->nativeformats = p->reqformat;
705
706         /* Determine our read/write format and set it on each channel */
707         fmt = ast_best_codec(p->reqformat);
708         tmp->writeformat = fmt;
709         tmp2->writeformat = fmt;
710         tmp->rawwriteformat = fmt;
711         tmp2->rawwriteformat = fmt;
712         tmp->readformat = fmt;
713         tmp2->readformat = fmt;
714         tmp->rawreadformat = fmt;
715         tmp2->rawreadformat = fmt;
716
717         tmp->tech_pvt = p;
718         tmp2->tech_pvt = p;
719
720         p->owner = tmp;
721         p->chan = tmp2;
722         p->u_owner = ast_module_user_add(p->owner);
723         p->u_chan = ast_module_user_add(p->chan);
724
725         ast_copy_string(tmp->context, p->context, sizeof(tmp->context));
726         ast_copy_string(tmp2->context, p->context, sizeof(tmp2->context));
727         ast_copy_string(tmp2->exten, p->exten, sizeof(tmp->exten));
728         tmp->priority = 1;
729         tmp2->priority = 1;
730
731         ast_jb_configure(tmp, &p->jb_conf);
732
733         return tmp;
734 }
735
736 /*! \brief Part of PBX interface */
737 static struct ast_channel *local_request(const char *type, int format, void *data, int *cause)
738 {
739         struct local_pvt *p = NULL;
740         struct ast_channel *chan = NULL;
741
742         /* Allocate a new private structure and then Asterisk channel */
743         if ((p = local_alloc(data, format))) {
744                 if (!(chan = local_new(p, AST_STATE_DOWN))) {
745                         AST_LIST_LOCK(&locals);
746                         AST_LIST_REMOVE(&locals, p, list);
747                         AST_LIST_UNLOCK(&locals);
748                         p = local_pvt_destroy(p);
749                 }
750         }
751
752         return chan;
753 }
754
755 /*! \brief CLI command "local show channels" */
756 static char *locals_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
757 {
758         struct local_pvt *p = NULL;
759
760         switch (cmd) {
761         case CLI_INIT:
762                 e->command = "local show channels";
763                 e->usage =
764                         "Usage: local show channels\n"
765                         "       Provides summary information on active local proxy channels.\n";
766                 return NULL;
767         case CLI_GENERATE:
768                 return NULL;
769         }
770
771         if (a->argc != 3)
772                 return CLI_SHOWUSAGE;
773
774         AST_LIST_LOCK(&locals);
775         if (!AST_LIST_EMPTY(&locals)) {
776                 AST_LIST_TRAVERSE(&locals, p, list) {
777                         ast_mutex_lock(&p->lock);
778                         ast_cli(a->fd, "%s -- %s@%s\n", p->owner ? p->owner->name : "<unowned>", p->exten, p->context);
779                         ast_mutex_unlock(&p->lock);
780                 }
781         } else
782                 ast_cli(a->fd, "No local channels in use\n");
783         AST_LIST_UNLOCK(&locals);
784
785         return CLI_SUCCESS;
786 }
787
788 static struct ast_cli_entry cli_local[] = {
789         AST_CLI_DEFINE(locals_show, "List status of local channels"),
790 };
791
792 /*! \brief Load module into PBX, register channel */
793 static int load_module(void)
794 {
795         /* Make sure we can register our channel type */
796         if (ast_channel_register(&local_tech)) {
797                 ast_log(LOG_ERROR, "Unable to register channel class 'Local'\n");
798                 return AST_MODULE_LOAD_FAILURE;
799         }
800         ast_cli_register_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
801         return AST_MODULE_LOAD_SUCCESS;
802 }
803
804 /*! \brief Unload the local proxy channel from Asterisk */
805 static int unload_module(void)
806 {
807         struct local_pvt *p = NULL;
808
809         /* First, take us out of the channel loop */
810         ast_cli_unregister_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
811         ast_channel_unregister(&local_tech);
812         if (!AST_LIST_LOCK(&locals)) {
813                 /* Hangup all interfaces if they have an owner */
814                 AST_LIST_TRAVERSE(&locals, p, list) {
815                         if (p->owner)
816                                 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
817                 }
818                 AST_LIST_UNLOCK(&locals);
819         } else {
820                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
821                 return -1;
822         }               
823         return 0;
824 }
825
826 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Local Proxy Channel (Note: used internally by other modules)");