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