Merged revisions 96318 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/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
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 };
99
100 struct local_pvt {
101         ast_mutex_t lock;                       /* Channel private lock */
102         unsigned int flags;                     /* Private flags */
103         char context[AST_MAX_CONTEXT];          /* Context to call */
104         char exten[AST_MAX_EXTENSION];          /* Extension to call */
105         int reqformat;                          /* Requested format */
106         struct ast_jb_conf jb_conf;             /*!< jitterbuffer configuration for this local channel */
107         struct ast_channel *owner;              /* Master Channel */
108         struct ast_channel *chan;               /* Outbound channel */
109         struct ast_module_user *u_owner;        /*! reference to keep the module loaded while in use */
110         struct ast_module_user *u_chan;         /*! reference to keep the module loaded while in use */
111         AST_LIST_ENTRY(local_pvt) list;         /* Next entity */
112 };
113
114 #define LOCAL_GLARE_DETECT    (1 << 0) /*!< Detect glare on hangup */
115 #define LOCAL_CANCEL_QUEUE    (1 << 1) /*!< Cancel queue */
116 #define LOCAL_ALREADY_MASQED  (1 << 2) /*!< Already masqueraded */
117 #define LOCAL_LAUNCHED_PBX    (1 << 3) /*!< PBX was launched */
118 #define LOCAL_NO_OPTIMIZATION (1 << 4) /*!< Do not optimize using masquerading */
119
120 static AST_LIST_HEAD_STATIC(locals, local_pvt);
121
122 /*! \brief Adds devicestate to local channels */
123 static int local_devicestate(void *data)
124 {
125         char *exten = ast_strdupa(data);
126         char *context = NULL, *opts = NULL;
127         int res;
128         struct local_pvt *lp;
129
130         if (!(context = strchr(exten, '@'))) {
131                 ast_log(LOG_WARNING, "Someone used Local/%s somewhere without a @context. This is bad.\n", exten);
132                 return AST_DEVICE_INVALID;      
133         }
134
135         *context++ = '\0';
136
137         /* Strip options if they exist */
138         if ((opts = strchr(context, '/')))
139                 *opts = '\0';
140
141         ast_debug(3, "Checking if extension %s@%s exists (devicestate)\n", exten, context);
142
143         res = ast_exists_extension(NULL, context, exten, 1, NULL);
144         if (!res)               
145                 return AST_DEVICE_INVALID;
146         
147         res = AST_DEVICE_NOT_INUSE;
148         AST_LIST_LOCK(&locals);
149         AST_LIST_TRAVERSE(&locals, lp, list) {
150                 if (!strcmp(exten, lp->exten) && !strcmp(context, lp->context) && lp->owner) {
151                         res = AST_DEVICE_INUSE;
152                         break;
153                 }
154         }
155         AST_LIST_UNLOCK(&locals);
156
157         return res;
158 }
159
160 static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us)
161 {
162         struct ast_channel *other = NULL;
163
164 retrylock:              
165
166         /* Recalculate outbound channel */
167         other = isoutbound ? p->owner : p->chan;
168
169         /* Set glare detection */
170         ast_set_flag(p, LOCAL_GLARE_DETECT);
171         if (ast_test_flag(p, LOCAL_CANCEL_QUEUE)) {
172                 /* We had a glare on the hangup.  Forget all this business,
173                 return and destroy p.  */
174                 ast_mutex_unlock(&p->lock);
175                 ast_mutex_destroy(&p->lock);
176                 ast_free(p);
177                 return -1;
178         }
179         if (!other) {
180                 ast_clear_flag(p, LOCAL_GLARE_DETECT);
181                 return 0;
182         }
183         if (ast_channel_trylock(other)) {
184                 /* Failed to lock.  Release main lock and try again */
185                 ast_mutex_unlock(&p->lock);
186                 if (us) {
187                         if (ast_channel_unlock(us)) {
188                                 ast_log(LOG_WARNING, "%s wasn't locked while sending %d/%d\n",
189                                         us->name, f->frametype, f->subclass);
190                                 us = NULL;
191                         }
192                 }
193                 /* Wait just a bit */
194                 usleep(1);
195                 /* Only we can destroy ourselves, so we can't disappear here */
196                 if (us)
197                         ast_channel_lock(us);
198                 ast_mutex_lock(&p->lock);
199                 goto retrylock;
200         }
201         ast_queue_frame(other, f);
202         ast_channel_unlock(other);
203         ast_clear_flag(p, LOCAL_GLARE_DETECT);
204         return 0;
205 }
206
207 static int local_answer(struct ast_channel *ast)
208 {
209         struct local_pvt *p = ast->tech_pvt;
210         int isoutbound;
211         int res = -1;
212
213         if (!p)
214                 return -1;
215
216         ast_mutex_lock(&p->lock);
217         isoutbound = IS_OUTBOUND(ast, p);
218         if (isoutbound) {
219                 /* Pass along answer since somebody answered us */
220                 struct ast_frame answer = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
221                 res = local_queue_frame(p, isoutbound, &answer, ast);
222         } else
223                 ast_log(LOG_WARNING, "Huh?  Local is being asked to answer?\n");
224         if (!res)
225                 ast_mutex_unlock(&p->lock);
226         return res;
227 }
228
229 static void check_bridge(struct local_pvt *p, int isoutbound)
230 {
231         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)))
232                 return;
233
234         /* only do the masquerade if we are being called on the outbound channel,
235            if it has been bridged to another channel and if there are no pending
236            frames on the owner channel (because they would be transferred to the
237            outbound channel during the masquerade)
238         */
239         if (isoutbound && p->chan->_bridge /* Not ast_bridged_channel!  Only go one step! */ && AST_LIST_EMPTY(&p->owner->readq)) {
240                 /* Masquerade bridged channel into owner */
241                 /* Lock everything we need, one by one, and give up if
242                    we can't get everything.  Remember, we'll get another
243                    chance in just a little bit */
244                 if (!ast_channel_trylock(p->chan->_bridge)) {
245                         if (!ast_check_hangup(p->chan->_bridge)) {
246                                 if (!ast_channel_trylock(p->owner)) {
247                                         if (!ast_check_hangup(p->owner)) {
248                                                 ast_channel_masquerade(p->owner, p->chan->_bridge);
249                                                 ast_set_flag(p, LOCAL_ALREADY_MASQED);
250                                         }
251                                         ast_channel_unlock(p->owner);
252                                 }
253                                 ast_channel_unlock(p->chan->_bridge);
254                         }
255                 }
256         /* We only allow masquerading in one 'direction'... it's important to preserve the state
257            (group variables, etc.) that live on p->chan->_bridge (and were put there by the dialplan)
258            when the local channels go away.
259         */
260 #if 0
261         } else if (!isoutbound && p->owner && p->owner->_bridge && p->chan && AST_LIST_EMPTY(&p->chan->readq)) {
262                 /* Masquerade bridged channel into chan */
263                 if (!ast_mutex_trylock(&(p->owner->_bridge)->lock)) {
264                         if (!ast_check_hangup(p->owner->_bridge)) {
265                                 if (!ast_mutex_trylock(&p->chan->lock)) {
266                                         if (!ast_check_hangup(p->chan)) {
267                                                 ast_channel_masquerade(p->chan, p->owner->_bridge);
268                                                 ast_set_flag(p, LOCAL_ALREADY_MASQED);
269                                         }
270                                         ast_mutex_unlock(&p->chan->lock);
271                                 }
272                         }
273                         ast_mutex_unlock(&(p->owner->_bridge)->lock);
274                 }
275 #endif
276         }
277 }
278
279 static struct ast_frame  *local_read(struct ast_channel *ast)
280 {
281         return &ast_null_frame;
282 }
283
284 static int local_write(struct ast_channel *ast, struct ast_frame *f)
285 {
286         struct local_pvt *p = ast->tech_pvt;
287         int res = -1;
288         int isoutbound;
289
290         if (!p)
291                 return -1;
292
293         /* Just queue for delivery to the other side */
294         ast_mutex_lock(&p->lock);
295         isoutbound = IS_OUTBOUND(ast, p);
296         if (f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO))
297                 check_bridge(p, isoutbound);
298         if (!ast_test_flag(p, LOCAL_ALREADY_MASQED))
299                 res = local_queue_frame(p, isoutbound, f, ast);
300         else {
301                 ast_debug(1, "Not posting to queue since already masked on '%s'\n", ast->name);
302                 res = 0;
303         }
304         if (!res)
305                 ast_mutex_unlock(&p->lock);
306         return res;
307 }
308
309 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
310 {
311         struct local_pvt *p = newchan->tech_pvt;
312
313         if (!p)
314                 return -1;
315
316         ast_mutex_lock(&p->lock);
317
318         if ((p->owner != oldchan) && (p->chan != oldchan)) {
319                 ast_log(LOG_WARNING, "Old channel wasn't %p but was %p/%p\n", oldchan, p->owner, p->chan);
320                 ast_mutex_unlock(&p->lock);
321                 return -1;
322         }
323         if (p->owner == oldchan)
324                 p->owner = newchan;
325         else
326                 p->chan = newchan;
327         ast_mutex_unlock(&p->lock);
328         return 0;
329 }
330
331 static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
332 {
333         struct local_pvt *p = ast->tech_pvt;
334         int res = 0;
335         struct ast_frame f = { AST_FRAME_CONTROL, };
336         int isoutbound;
337
338         if (!p)
339                 return -1;
340
341         /* If this is an MOH hold or unhold, do it on the Local channel versus real channel */
342         if (condition == AST_CONTROL_HOLD) {
343                 ast_moh_start(ast, data, NULL);
344         } else if (condition == AST_CONTROL_UNHOLD) {
345                 ast_moh_stop(ast);
346         } else {
347                 /* Queue up a frame representing the indication as a control frame */
348                 ast_mutex_lock(&p->lock);
349                 isoutbound = IS_OUTBOUND(ast, p);
350                 f.subclass = condition;
351                 f.data = (void*)data;
352                 f.datalen = datalen;
353                 if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
354                         ast_mutex_unlock(&p->lock);
355         }
356
357         return res;
358 }
359
360 static int local_digit_begin(struct ast_channel *ast, char digit)
361 {
362         struct local_pvt *p = ast->tech_pvt;
363         int res = -1;
364         struct ast_frame f = { AST_FRAME_DTMF_BEGIN, };
365         int isoutbound;
366
367         if (!p)
368                 return -1;
369
370         ast_mutex_lock(&p->lock);
371         isoutbound = IS_OUTBOUND(ast, p);
372         f.subclass = digit;
373         if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
374                 ast_mutex_unlock(&p->lock);
375
376         return res;
377 }
378
379 static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
380 {
381         struct local_pvt *p = ast->tech_pvt;
382         int res = -1;
383         struct ast_frame f = { AST_FRAME_DTMF_END, };
384         int isoutbound;
385
386         if (!p)
387                 return -1;
388
389         ast_mutex_lock(&p->lock);
390         isoutbound = IS_OUTBOUND(ast, p);
391         f.subclass = digit;
392         f.len = duration;
393         if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
394                 ast_mutex_unlock(&p->lock);
395
396         return res;
397 }
398
399 static int local_sendtext(struct ast_channel *ast, const char *text)
400 {
401         struct local_pvt *p = ast->tech_pvt;
402         int res = -1;
403         struct ast_frame f = { AST_FRAME_TEXT, };
404         int isoutbound;
405
406         if (!p)
407                 return -1;
408
409         ast_mutex_lock(&p->lock);
410         isoutbound = IS_OUTBOUND(ast, p);
411         f.data = (char *) text;
412         f.datalen = strlen(text) + 1;
413         if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
414                 ast_mutex_unlock(&p->lock);
415         return res;
416 }
417
418 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
419 {
420         struct local_pvt *p = ast->tech_pvt;
421         int res = -1;
422         struct ast_frame f = { AST_FRAME_HTML, };
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 = subclass;
431         f.data = (char *)data;
432         f.datalen = datalen;
433         if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
434                 ast_mutex_unlock(&p->lock);
435         return res;
436 }
437
438 /*! \brief Initiate new call, part of PBX interface 
439  *      dest is the dial string */
440 static int local_call(struct ast_channel *ast, char *dest, int timeout)
441 {
442         struct local_pvt *p = ast->tech_pvt;
443         int res;
444         struct ast_var_t *varptr = NULL, *new;
445         size_t len, namelen;
446
447         if (!p)
448                 return -1;
449         
450         ast_mutex_lock(&p->lock);
451
452         /*
453          * Note that cid_num and cid_name aren't passed in the ast_channel_alloc
454          * call, so it's done here instead.
455          */
456         p->chan->cid.cid_num = ast_strdup(p->owner->cid.cid_num);
457         p->chan->cid.cid_name = ast_strdup(p->owner->cid.cid_name);
458         p->chan->cid.cid_rdnis = ast_strdup(p->owner->cid.cid_rdnis);
459         p->chan->cid.cid_ani = ast_strdup(p->owner->cid.cid_ani);
460         p->chan->cid.cid_pres = p->owner->cid.cid_pres;
461         ast_string_field_set(p->chan, language, p->owner->language);
462         ast_string_field_set(p->chan, accountcode, p->owner->accountcode);
463         p->chan->cdrflags = p->owner->cdrflags;
464
465         /* copy the channel variables from the incoming channel to the outgoing channel */
466         /* Note that due to certain assumptions, they MUST be in the same order */
467         AST_LIST_TRAVERSE(&p->owner->varshead, varptr, entries) {
468                 namelen = strlen(varptr->name);
469                 len = sizeof(struct ast_var_t) + namelen + strlen(varptr->value) + 2;
470                 if ((new = ast_calloc(1, len))) {
471                         memcpy(new, varptr, len);
472                         new->value = &(new->name[0]) + namelen + 1;
473                         AST_LIST_INSERT_TAIL(&p->chan->varshead, new, entries);
474                 }
475         }
476         ast_channel_datastore_inherit(p->owner, p->chan);
477
478         /* Start switch on sub channel */
479         if (!(res = ast_pbx_start(p->chan)))
480                 ast_set_flag(p, LOCAL_LAUNCHED_PBX);
481
482         ast_mutex_unlock(&p->lock);
483         return res;
484 }
485
486 /*! \brief Hangup a call through the local proxy channel */
487 static int local_hangup(struct ast_channel *ast)
488 {
489         struct local_pvt *p = ast->tech_pvt;
490         int isoutbound;
491         struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
492         struct ast_channel *ochan = NULL;
493         int glaredetect = 0, res = 0;
494
495         if (!p)
496                 return -1;
497
498         ast_mutex_lock(&p->lock);
499         if (p->chan && ast_test_flag(ast, AST_FLAG_ANSWERED_ELSEWHERE)) 
500                 ast_set_flag(p->chan, AST_FLAG_ANSWERED_ELSEWHERE);
501         isoutbound = IS_OUTBOUND(ast, p);
502         if (isoutbound) {
503                 const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
504                 if ((status) && (p->owner))
505                         pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
506                 p->chan = NULL;
507                 ast_clear_flag(p, LOCAL_LAUNCHED_PBX);
508                 ast_module_user_remove(p->u_chan);
509         } else {
510                 p->owner = NULL;
511                 ast_module_user_remove(p->u_owner);
512         }
513         
514         ast->tech_pvt = NULL;
515         
516         if (!p->owner && !p->chan) {
517                 /* Okay, done with the private part now, too. */
518                 glaredetect = ast_test_flag(p, LOCAL_GLARE_DETECT);
519                 /* If we have a queue holding, don't actually destroy p yet, but
520                    let local_queue do it. */
521                 if (glaredetect)
522                         ast_set_flag(p, LOCAL_CANCEL_QUEUE);
523                 ast_mutex_unlock(&p->lock);
524                 /* Remove from list */
525                 AST_LIST_LOCK(&locals);
526                 AST_LIST_REMOVE(&locals, p, list);
527                 AST_LIST_UNLOCK(&locals);
528                 /* Grab / release lock just in case */
529                 ast_mutex_lock(&p->lock);
530                 ast_mutex_unlock(&p->lock);
531                 /* And destroy */
532                 if (!glaredetect) {
533                         ast_mutex_destroy(&p->lock);
534                         ast_free(p);
535                 }
536                 return 0;
537         }
538         if (p->chan && !ast_test_flag(p, LOCAL_LAUNCHED_PBX))
539                 /* Need to actually hangup since there is no PBX */
540                 ochan = p->chan;
541         else
542                 res = local_queue_frame(p, isoutbound, &f, NULL);
543         if (!res)
544                 ast_mutex_unlock(&p->lock);
545         if (ochan)
546                 ast_hangup(ochan);
547         return 0;
548 }
549
550 /*! \brief Create a call structure */
551 static struct local_pvt *local_alloc(const char *data, int format)
552 {
553         struct local_pvt *tmp = NULL;
554         char *c = NULL, *opts = NULL;
555
556         if (!(tmp = ast_calloc(1, sizeof(*tmp))))
557                 return NULL;
558
559         /* Initialize private structure information */
560         ast_mutex_init(&tmp->lock);
561         ast_copy_string(tmp->exten, data, sizeof(tmp->exten));
562
563         memcpy(&tmp->jb_conf, &g_jb_conf, sizeof(tmp->jb_conf));
564
565         /* Look for options */
566         if ((opts = strchr(tmp->exten, '/'))) {
567                 *opts++ = '\0';
568                 if (strchr(opts, 'n'))
569                         ast_set_flag(tmp, LOCAL_NO_OPTIMIZATION);
570                 if (strchr(opts, 'j')) {
571                         if (ast_test_flag(tmp, LOCAL_NO_OPTIMIZATION))
572                                 ast_set_flag(&tmp->jb_conf, AST_JB_ENABLED);
573                         else {
574                                 ast_log(LOG_ERROR, "You must use the 'n' option for chan_local "
575                                         "to use the 'j' option to enable the jitterbuffer\n");
576                         }
577                 }
578         }
579
580         /* Look for a context */
581         if ((c = strchr(tmp->exten, '@')))
582                 *c++ = '\0';
583
584         ast_copy_string(tmp->context, c ? c : "default", sizeof(tmp->context));
585
586         tmp->reqformat = format;
587
588         if (!ast_exists_extension(NULL, tmp->context, tmp->exten, 1, NULL)) {
589                 ast_log(LOG_NOTICE, "No such extension/context %s@%s creating local channel\n", tmp->exten, tmp->context);
590                 ast_mutex_destroy(&tmp->lock);
591                 ast_free(tmp);
592                 tmp = NULL;
593         } else {
594                 /* Add to list */
595                 AST_LIST_LOCK(&locals);
596                 AST_LIST_INSERT_HEAD(&locals, tmp, list);
597                 AST_LIST_UNLOCK(&locals);
598         }
599         
600         return tmp;
601 }
602
603 /*! \brief Start new local channel */
604 static struct ast_channel *local_new(struct local_pvt *p, int state)
605 {
606         struct ast_channel *tmp = NULL, *tmp2 = NULL;
607         int randnum = ast_random() & 0xffff, fmt = 0;
608         const char *t;
609         int ama;
610
611         /* Allocate two new Asterisk channels */
612         /* safe accountcode */
613         if (p->owner && p->owner->accountcode)
614                 t = p->owner->accountcode;
615         else
616                 t = "";
617
618         if (p->owner)
619                 ama = p->owner->amaflags;
620         else
621                 ama = 0;
622         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)) 
623                         || !(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))) {
624                 if (tmp)
625                         ast_channel_free(tmp);
626                 if (tmp2)
627                         ast_channel_free(tmp2);
628                 ast_log(LOG_WARNING, "Unable to allocate channel structure(s)\n");
629                 return NULL;
630         } 
631
632         tmp2->tech = tmp->tech = &local_tech;
633
634         tmp->nativeformats = p->reqformat;
635         tmp2->nativeformats = p->reqformat;
636
637         /* Determine our read/write format and set it on each channel */
638         fmt = ast_best_codec(p->reqformat);
639         tmp->writeformat = fmt;
640         tmp2->writeformat = fmt;
641         tmp->rawwriteformat = fmt;
642         tmp2->rawwriteformat = fmt;
643         tmp->readformat = fmt;
644         tmp2->readformat = fmt;
645         tmp->rawreadformat = fmt;
646         tmp2->rawreadformat = fmt;
647
648         tmp->tech_pvt = p;
649         tmp2->tech_pvt = p;
650
651         p->owner = tmp;
652         p->chan = tmp2;
653         p->u_owner = ast_module_user_add(p->owner);
654         p->u_chan = ast_module_user_add(p->chan);
655
656         ast_copy_string(tmp->context, p->context, sizeof(tmp->context));
657         ast_copy_string(tmp2->context, p->context, sizeof(tmp2->context));
658         ast_copy_string(tmp2->exten, p->exten, sizeof(tmp->exten));
659         tmp->priority = 1;
660         tmp2->priority = 1;
661
662         ast_jb_configure(tmp, &p->jb_conf);
663
664         return tmp;
665 }
666
667
668 /*! \brief Part of PBX interface */
669 static struct ast_channel *local_request(const char *type, int format, void *data, int *cause)
670 {
671         struct local_pvt *p = NULL;
672         struct ast_channel *chan = NULL;
673
674         /* Allocate a new private structure and then Asterisk channel */
675         if ((p = local_alloc(data, format)))
676                 chan = local_new(p, AST_STATE_DOWN);
677
678         return chan;
679 }
680
681 /*! \brief CLI command "local show channels" */
682 static char *locals_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
683 {
684         struct local_pvt *p = NULL;
685
686         switch (cmd) {
687         case CLI_INIT:
688                 e->command = "local show channels";
689                 e->usage =
690                         "Usage: local show channels\n"
691                         "       Provides summary information on active local proxy channels.\n";
692                 return NULL;
693         case CLI_GENERATE:
694                 return NULL;
695         }
696
697         if (a->argc != 3)
698                 return CLI_SHOWUSAGE;
699
700         AST_LIST_LOCK(&locals);
701         if (!AST_LIST_EMPTY(&locals)) {
702                 AST_LIST_TRAVERSE(&locals, p, list) {
703                         ast_mutex_lock(&p->lock);
704                         ast_cli(a->fd, "%s -- %s@%s\n", p->owner ? p->owner->name : "<unowned>", p->exten, p->context);
705                         ast_mutex_unlock(&p->lock);
706                 }
707         } else
708                 ast_cli(a->fd, "No local channels in use\n");
709         AST_LIST_UNLOCK(&locals);
710
711         return CLI_SUCCESS;
712 }
713
714 static struct ast_cli_entry cli_local[] = {
715         AST_CLI_DEFINE(locals_show, "List status of local channels"),
716 };
717
718 /*! \brief Load module into PBX, register channel */
719 static int load_module(void)
720 {
721         /* Make sure we can register our channel type */
722         if (ast_channel_register(&local_tech)) {
723                 ast_log(LOG_ERROR, "Unable to register channel class 'Local'\n");
724                 return AST_MODULE_LOAD_FAILURE;
725         }
726         ast_cli_register_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
727         return AST_MODULE_LOAD_SUCCESS;
728 }
729
730 /*! \brief Unload the local proxy channel from Asterisk */
731 static int unload_module(void)
732 {
733         struct local_pvt *p = NULL;
734
735         /* First, take us out of the channel loop */
736         ast_cli_unregister_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
737         ast_channel_unregister(&local_tech);
738         if (!AST_LIST_LOCK(&locals)) {
739                 /* Hangup all interfaces if they have an owner */
740                 AST_LIST_TRAVERSE(&locals, p, list) {
741                         if (p->owner)
742                                 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
743                 }
744                 AST_LIST_UNLOCK(&locals);
745                 AST_LIST_HEAD_DESTROY(&locals);
746         } else {
747                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
748                 return -1;
749         }               
750         return 0;
751 }
752
753 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Local Proxy Channel");