another few errno.h removals
[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/options.h"
41 #include "asterisk/sched.h"
42 #include "asterisk/io.h"
43 #include "asterisk/rtp.h"
44 #include "asterisk/acl.h"
45 #include "asterisk/callerid.h"
46 #include "asterisk/file.h"
47 #include "asterisk/cli.h"
48 #include "asterisk/app.h"
49 #include "asterisk/musiconhold.h"
50 #include "asterisk/manager.h"
51 #include "asterisk/stringfields.h"
52 #include "asterisk/devicestate.h"
53
54 static const char tdesc[] = "Local Proxy Channel Driver";
55
56 #define IS_OUTBOUND(a,b) (a == b->chan ? 1 : 0)
57
58 static struct ast_jb_conf g_jb_conf = {
59         .flags = 0,
60         .max_size = -1,
61         .resync_threshold = -1,
62         .impl = "",
63 };
64
65 static struct ast_channel *local_request(const char *type, int format, void *data, int *cause);
66 static int local_digit_begin(struct ast_channel *ast, char digit);
67 static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
68 static int local_call(struct ast_channel *ast, char *dest, int timeout);
69 static int local_hangup(struct ast_channel *ast);
70 static int local_answer(struct ast_channel *ast);
71 static struct ast_frame *local_read(struct ast_channel *ast);
72 static int local_write(struct ast_channel *ast, struct ast_frame *f);
73 static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
74 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
75 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
76 static int local_sendtext(struct ast_channel *ast, const char *text);
77 static int local_devicestate(void *data);
78
79 /* PBX interface structure for channel registration */
80 static const struct ast_channel_tech local_tech = {
81         .type = "Local",
82         .description = tdesc,
83         .capabilities = -1,
84         .requester = local_request,
85         .send_digit_begin = local_digit_begin,
86         .send_digit_end = local_digit_end,
87         .call = local_call,
88         .hangup = local_hangup,
89         .answer = local_answer,
90         .read = local_read,
91         .write = local_write,
92         .write_video = local_write,
93         .exception = local_read,
94         .indicate = local_indicate,
95         .fixup = local_fixup,
96         .send_html = local_sendhtml,
97         .send_text = local_sendtext,
98         .devicestate = local_devicestate,
99 };
100
101 struct local_pvt {
102         ast_mutex_t lock;                       /* Channel private lock */
103         unsigned int flags;                     /* Private flags */
104         char context[AST_MAX_CONTEXT];          /* Context to call */
105         char exten[AST_MAX_EXTENSION];          /* Extension to call */
106         int reqformat;                          /* Requested format */
107         struct ast_jb_conf jb_conf;             /*!< jitterbuffer configuration for this local channel */
108         struct ast_channel *owner;              /* Master Channel */
109         struct ast_channel *chan;               /* Outbound channel */
110         struct ast_module_user *u_owner;        /*! reference to keep the module loaded while in use */
111         struct ast_module_user *u_chan;         /*! reference to keep the module loaded while in use */
112         AST_LIST_ENTRY(local_pvt) list;         /* Next entity */
113 };
114
115 #define LOCAL_GLARE_DETECT    (1 << 0) /*!< Detect glare on hangup */
116 #define LOCAL_CANCEL_QUEUE    (1 << 1) /*!< Cancel queue */
117 #define LOCAL_ALREADY_MASQED  (1 << 2) /*!< Already masqueraded */
118 #define LOCAL_LAUNCHED_PBX    (1 << 3) /*!< PBX was launched */
119 #define LOCAL_NO_OPTIMIZATION (1 << 4) /*!< Do not optimize using masquerading */
120
121 static AST_LIST_HEAD_STATIC(locals, local_pvt);
122
123 /*! \brief Adds devicestate to local channels */
124 static int local_devicestate(void *data)
125 {
126         char *exten = ast_strdupa(data);
127         char *context = NULL, *opts = NULL;
128         int res;
129         struct local_pvt *lp;
130
131         if (!(context = strchr(exten, '@'))) {
132                 ast_log(LOG_WARNING, "Someone used Local/%s somewhere without a @context. This is bad.\n", exten);
133                 return AST_DEVICE_INVALID;      
134         }
135
136         *context++ = '\0';
137
138         /* Strip options if they exist */
139         if ((opts = strchr(context, '/')))
140                 *opts = '\0';
141
142         ast_debug(3, "Checking if extension %s@%s exists (devicestate)\n", exten, context);
143
144         res = ast_exists_extension(NULL, context, exten, 1, NULL);
145         if (!res)               
146                 return AST_DEVICE_INVALID;
147         
148         res = AST_DEVICE_NOT_INUSE;
149         AST_LIST_LOCK(&locals);
150         AST_LIST_TRAVERSE(&locals, lp, list) {
151                 if (!strcmp(exten, lp->exten) && !strcmp(context, lp->context) && lp->owner) {
152                         res = AST_DEVICE_INUSE;
153                         break;
154                 }
155         }
156         AST_LIST_UNLOCK(&locals);
157
158         return res;
159 }
160
161 static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us)
162 {
163         struct ast_channel *other = NULL;
164
165 retrylock:              
166
167         /* Recalculate outbound channel */
168         other = isoutbound ? p->owner : p->chan;
169
170         /* Set glare detection */
171         ast_set_flag(p, LOCAL_GLARE_DETECT);
172         if (ast_test_flag(p, LOCAL_CANCEL_QUEUE)) {
173                 /* We had a glare on the hangup.  Forget all this business,
174                 return and destroy p.  */
175                 ast_mutex_unlock(&p->lock);
176                 ast_mutex_destroy(&p->lock);
177                 ast_free(p);
178                 return -1;
179         }
180         if (!other) {
181                 ast_clear_flag(p, LOCAL_GLARE_DETECT);
182                 return 0;
183         }
184         if (ast_channel_trylock(other)) {
185                 /* Failed to lock.  Release main lock and try again */
186                 ast_mutex_unlock(&p->lock);
187                 if (us) {
188                         if (ast_channel_unlock(us)) {
189                                 ast_log(LOG_WARNING, "%s wasn't locked while sending %d/%d\n",
190                                         us->name, f->frametype, f->subclass);
191                                 us = NULL;
192                         }
193                 }
194                 /* Wait just a bit */
195                 usleep(1);
196                 /* Only we can destroy ourselves, so we can't disappear here */
197                 if (us)
198                         ast_channel_lock(us);
199                 ast_mutex_lock(&p->lock);
200                 goto retrylock;
201         }
202         ast_queue_frame(other, f);
203         ast_channel_unlock(other);
204         ast_clear_flag(p, LOCAL_GLARE_DETECT);
205         return 0;
206 }
207
208 static int local_answer(struct ast_channel *ast)
209 {
210         struct local_pvt *p = ast->tech_pvt;
211         int isoutbound;
212         int res = -1;
213
214         if (!p)
215                 return -1;
216
217         ast_mutex_lock(&p->lock);
218         isoutbound = IS_OUTBOUND(ast, p);
219         if (isoutbound) {
220                 /* Pass along answer since somebody answered us */
221                 struct ast_frame answer = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
222                 res = local_queue_frame(p, isoutbound, &answer, ast);
223         } else
224                 ast_log(LOG_WARNING, "Huh?  Local is being asked to answer?\n");
225         if (!res)
226                 ast_mutex_unlock(&p->lock);
227         return res;
228 }
229
230 static void check_bridge(struct local_pvt *p, int isoutbound)
231 {
232         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)))
233                 return;
234
235         /* only do the masquerade if we are being called on the outbound channel,
236            if it has been bridged to another channel and if there are no pending
237            frames on the owner channel (because they would be transferred to the
238            outbound channel during the masquerade)
239         */
240         if (isoutbound && p->chan->_bridge /* Not ast_bridged_channel!  Only go one step! */ && AST_LIST_EMPTY(&p->owner->readq)) {
241                 /* Masquerade bridged channel into owner */
242                 /* Lock everything we need, one by one, and give up if
243                    we can't get everything.  Remember, we'll get another
244                    chance in just a little bit */
245                 if (!ast_channel_trylock(p->chan->_bridge)) {
246                         if (!ast_check_hangup(p->chan->_bridge)) {
247                                 if (!ast_channel_trylock(p->owner)) {
248                                         if (!ast_check_hangup(p->owner)) {
249                                                 ast_channel_masquerade(p->owner, p->chan->_bridge);
250                                                 ast_set_flag(p, LOCAL_ALREADY_MASQED);
251                                         }
252                                         ast_channel_unlock(p->owner);
253                                 }
254                                 ast_channel_unlock(p->chan->_bridge);
255                         }
256                 }
257         /* We only allow masquerading in one 'direction'... it's important to preserve the state
258            (group variables, etc.) that live on p->chan->_bridge (and were put there by the dialplan)
259            when the local channels go away.
260         */
261 #if 0
262         } else if (!isoutbound && p->owner && p->owner->_bridge && p->chan && AST_LIST_EMPTY(&p->chan->readq)) {
263                 /* Masquerade bridged channel into chan */
264                 if (!ast_mutex_trylock(&(p->owner->_bridge)->lock)) {
265                         if (!ast_check_hangup(p->owner->_bridge)) {
266                                 if (!ast_mutex_trylock(&p->chan->lock)) {
267                                         if (!ast_check_hangup(p->chan)) {
268                                                 ast_channel_masquerade(p->chan, p->owner->_bridge);
269                                                 ast_set_flag(p, LOCAL_ALREADY_MASQED);
270                                         }
271                                         ast_mutex_unlock(&p->chan->lock);
272                                 }
273                         }
274                         ast_mutex_unlock(&(p->owner->_bridge)->lock);
275                 }
276 #endif
277         }
278 }
279
280 static struct ast_frame  *local_read(struct ast_channel *ast)
281 {
282         return &ast_null_frame;
283 }
284
285 static int local_write(struct ast_channel *ast, struct ast_frame *f)
286 {
287         struct local_pvt *p = ast->tech_pvt;
288         int res = -1;
289         int isoutbound;
290
291         if (!p)
292                 return -1;
293
294         /* Just queue for delivery to the other side */
295         ast_mutex_lock(&p->lock);
296         isoutbound = IS_OUTBOUND(ast, p);
297         if (f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO))
298                 check_bridge(p, isoutbound);
299         if (!ast_test_flag(p, LOCAL_ALREADY_MASQED))
300                 res = local_queue_frame(p, isoutbound, f, ast);
301         else {
302                 ast_debug(1, "Not posting to queue since already masked on '%s'\n", ast->name);
303                 res = 0;
304         }
305         if (!res)
306                 ast_mutex_unlock(&p->lock);
307         return res;
308 }
309
310 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
311 {
312         struct local_pvt *p = newchan->tech_pvt;
313
314         if (!p)
315                 return -1;
316
317         ast_mutex_lock(&p->lock);
318
319         if ((p->owner != oldchan) && (p->chan != oldchan)) {
320                 ast_log(LOG_WARNING, "Old channel wasn't %p but was %p/%p\n", oldchan, p->owner, p->chan);
321                 ast_mutex_unlock(&p->lock);
322                 return -1;
323         }
324         if (p->owner == oldchan)
325                 p->owner = newchan;
326         else
327                 p->chan = newchan;
328         ast_mutex_unlock(&p->lock);
329         return 0;
330 }
331
332 static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
333 {
334         struct local_pvt *p = ast->tech_pvt;
335         int res = 0;
336         struct ast_frame f = { AST_FRAME_CONTROL, };
337         int isoutbound;
338
339         if (!p)
340                 return -1;
341
342         /* If this is an MOH hold or unhold, do it on the Local channel versus real channel */
343         if (condition == AST_CONTROL_HOLD) {
344                 ast_moh_start(ast, data, NULL);
345         } else if (condition == AST_CONTROL_UNHOLD) {
346                 ast_moh_stop(ast);
347         } else {
348                 /* Queue up a frame representing the indication as a control frame */
349                 ast_mutex_lock(&p->lock);
350                 isoutbound = IS_OUTBOUND(ast, p);
351                 f.subclass = condition;
352                 f.data = (void*)data;
353                 f.datalen = datalen;
354                 if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
355                         ast_mutex_unlock(&p->lock);
356         }
357
358         return res;
359 }
360
361 static int local_digit_begin(struct ast_channel *ast, char digit)
362 {
363         struct local_pvt *p = ast->tech_pvt;
364         int res = -1;
365         struct ast_frame f = { AST_FRAME_DTMF_BEGIN, };
366         int isoutbound;
367
368         if (!p)
369                 return -1;
370
371         ast_mutex_lock(&p->lock);
372         isoutbound = IS_OUTBOUND(ast, p);
373         f.subclass = digit;
374         if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
375                 ast_mutex_unlock(&p->lock);
376
377         return res;
378 }
379
380 static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
381 {
382         struct local_pvt *p = ast->tech_pvt;
383         int res = -1;
384         struct ast_frame f = { AST_FRAME_DTMF_END, };
385         int isoutbound;
386
387         if (!p)
388                 return -1;
389
390         ast_mutex_lock(&p->lock);
391         isoutbound = IS_OUTBOUND(ast, p);
392         f.subclass = digit;
393         f.len = duration;
394         if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
395                 ast_mutex_unlock(&p->lock);
396
397         return res;
398 }
399
400 static int local_sendtext(struct ast_channel *ast, const char *text)
401 {
402         struct local_pvt *p = ast->tech_pvt;
403         int res = -1;
404         struct ast_frame f = { AST_FRAME_TEXT, };
405         int isoutbound;
406
407         if (!p)
408                 return -1;
409
410         ast_mutex_lock(&p->lock);
411         isoutbound = IS_OUTBOUND(ast, p);
412         f.data = (char *) text;
413         f.datalen = strlen(text) + 1;
414         if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
415                 ast_mutex_unlock(&p->lock);
416         return res;
417 }
418
419 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
420 {
421         struct local_pvt *p = ast->tech_pvt;
422         int res = -1;
423         struct ast_frame f = { AST_FRAME_HTML, };
424         int isoutbound;
425
426         if (!p)
427                 return -1;
428         
429         ast_mutex_lock(&p->lock);
430         isoutbound = IS_OUTBOUND(ast, p);
431         f.subclass = subclass;
432         f.data = (char *)data;
433         f.datalen = datalen;
434         if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
435                 ast_mutex_unlock(&p->lock);
436         return res;
437 }
438
439 /*! \brief Initiate new call, part of PBX interface 
440  *      dest is the dial string */
441 static int local_call(struct ast_channel *ast, char *dest, int timeout)
442 {
443         struct local_pvt *p = ast->tech_pvt;
444         int res;
445         struct ast_var_t *varptr = NULL, *new;
446         size_t len, namelen;
447
448         if (!p)
449                 return -1;
450         
451         ast_mutex_lock(&p->lock);
452
453         /*
454          * Note that cid_num and cid_name aren't passed in the ast_channel_alloc
455          * call, so it's done here instead.
456          */
457         p->chan->cid.cid_num = ast_strdup(p->owner->cid.cid_num);
458         p->chan->cid.cid_name = ast_strdup(p->owner->cid.cid_name);
459         p->chan->cid.cid_rdnis = ast_strdup(p->owner->cid.cid_rdnis);
460         p->chan->cid.cid_ani = ast_strdup(p->owner->cid.cid_ani);
461         p->chan->cid.cid_pres = p->owner->cid.cid_pres;
462         ast_string_field_set(p->chan, language, p->owner->language);
463         ast_string_field_set(p->chan, accountcode, p->owner->accountcode);
464         p->chan->cdrflags = p->owner->cdrflags;
465
466         /* copy the channel variables from the incoming channel to the outgoing channel */
467         /* Note that due to certain assumptions, they MUST be in the same order */
468         AST_LIST_TRAVERSE(&p->owner->varshead, varptr, entries) {
469                 namelen = strlen(varptr->name);
470                 len = sizeof(struct ast_var_t) + namelen + strlen(varptr->value) + 2;
471                 if ((new = ast_calloc(1, len))) {
472                         memcpy(new, varptr, len);
473                         new->value = &(new->name[0]) + namelen + 1;
474                         AST_LIST_INSERT_TAIL(&p->chan->varshead, new, entries);
475                 }
476         }
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");