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