2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2005, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
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.
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.
21 * \author Mark Spencer <markster@digium.com>
23 * \brief Local Proxy Channel
25 * \ingroup channel_drivers
30 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
35 #include <sys/socket.h>
40 #include <netinet/in.h>
41 #include <arpa/inet.h>
42 #include <sys/signal.h>
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"
65 static const char tdesc[] = "Local Proxy Channel Driver";
67 #define IS_OUTBOUND(a,b) (a == b->chan ? 1 : 0)
69 static struct ast_channel *local_request(const char *type, int format, void *data, int *cause);
70 static int local_digit_begin(struct ast_channel *ast, char digit);
71 static int local_digit_end(struct ast_channel *ast, char digit);
72 static int local_call(struct ast_channel *ast, char *dest, int timeout);
73 static int local_hangup(struct ast_channel *ast);
74 static int local_answer(struct ast_channel *ast);
75 static struct ast_frame *local_read(struct ast_channel *ast);
76 static int local_write(struct ast_channel *ast, struct ast_frame *f);
77 static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
78 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
79 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
80 static int local_sendtext(struct ast_channel *ast, const char *text);
81 static int local_devicestate(void *data);
83 /* PBX interface structure for channel registration */
84 static const struct ast_channel_tech local_tech = {
88 .requester = local_request,
89 .send_digit_begin = local_digit_begin,
90 .send_digit_end = local_digit_end,
92 .hangup = local_hangup,
93 .answer = local_answer,
96 .write_video = local_write,
97 .exception = local_read,
98 .indicate = local_indicate,
100 .send_html = local_sendhtml,
101 .send_text = local_sendtext,
102 .devicestate = local_devicestate,
106 ast_mutex_t lock; /* Channel private lock */
107 unsigned int flags; /* Private flags */
108 char context[AST_MAX_CONTEXT]; /* Context to call */
109 char exten[AST_MAX_EXTENSION]; /* Extension to call */
110 int reqformat; /* Requested format */
111 struct ast_channel *owner; /* Master Channel */
112 struct ast_channel *chan; /* Outbound channel */
113 struct ast_module_user *u_owner; /*! reference to keep the module loaded while in use */
114 struct ast_module_user *u_chan; /*! reference to keep the module loaded while in use */
115 AST_LIST_ENTRY(local_pvt) list; /* Next entity */
118 #define LOCAL_GLARE_DETECT (1 << 0) /*!< Detect glare on hangup */
119 #define LOCAL_CANCEL_QUEUE (1 << 1) /*!< Cancel queue */
120 #define LOCAL_ALREADY_MASQED (1 << 2) /*!< Already masqueraded */
121 #define LOCAL_LAUNCHED_PBX (1 << 3) /*!< PBX was launched */
122 #define LOCAL_NO_OPTIMIZATION (1 << 4) /*!< Do not optimize using masquerading */
124 static AST_LIST_HEAD_STATIC(locals, local_pvt);
126 /*! \brief Adds devicestate to local channels */
127 static int local_devicestate(void *data)
129 char *exten = ast_strdupa(data);
130 char *context = NULL, *opts = NULL;
133 if (!(context = strchr(exten, '@'))) {
134 ast_log(LOG_WARNING, "Someone used Local/%s somewhere without a @context. This is bad.\n", exten);
135 return AST_DEVICE_INVALID;
140 /* Strip options if they exist */
141 if ((opts = strchr(context, '/')))
144 if (option_debug > 2)
145 ast_log(LOG_DEBUG, "Checking if extension %s@%s exists (devicestate)\n", exten, context);
146 res = ast_exists_extension(NULL, context, exten, 1, NULL);
148 return AST_DEVICE_INVALID;
150 return AST_DEVICE_UNKNOWN;
153 static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us)
155 struct ast_channel *other = NULL;
159 /* Recalculate outbound channel */
160 other = isoutbound ? p->owner : p->chan;
162 /* Set glare detection */
163 ast_set_flag(p, LOCAL_GLARE_DETECT);
164 if (ast_test_flag(p, LOCAL_CANCEL_QUEUE)) {
165 /* We had a glare on the hangup. Forget all this business,
166 return and destroy p. */
167 ast_mutex_unlock(&p->lock);
168 ast_mutex_destroy(&p->lock);
173 ast_clear_flag(p, LOCAL_GLARE_DETECT);
176 if (ast_mutex_trylock(&other->lock)) {
177 /* Failed to lock. Release main lock and try again */
178 ast_mutex_unlock(&p->lock);
180 if (ast_mutex_unlock(&us->lock)) {
181 ast_log(LOG_WARNING, "%s wasn't locked while sending %d/%d\n",
182 us->name, f->frametype, f->subclass);
186 /* Wait just a bit */
188 /* Only we can destroy ourselves, so we can't disappear here */
190 ast_mutex_lock(&us->lock);
191 ast_mutex_lock(&p->lock);
194 ast_queue_frame(other, f);
195 ast_mutex_unlock(&other->lock);
196 ast_clear_flag(p, LOCAL_GLARE_DETECT);
200 static int local_answer(struct ast_channel *ast)
202 struct local_pvt *p = ast->tech_pvt;
206 ast_mutex_lock(&p->lock);
207 isoutbound = IS_OUTBOUND(ast, p);
209 /* Pass along answer since somebody answered us */
210 struct ast_frame answer = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
211 res = local_queue_frame(p, isoutbound, &answer, ast);
213 ast_log(LOG_WARNING, "Huh? Local is being asked to answer?\n");
214 ast_mutex_unlock(&p->lock);
218 static void check_bridge(struct local_pvt *p, int isoutbound)
220 if (ast_test_flag(p, LOCAL_ALREADY_MASQED) || ast_test_flag(p, LOCAL_NO_OPTIMIZATION) || !p->chan || !p->owner)
223 /* only do the masquerade if we are being called on the outbound channel,
224 if it has been bridged to another channel and if there are no pending
225 frames on the owner channel (because they would be transferred to the
226 outbound channel during the masquerade)
228 if (isoutbound && p->chan->_bridge /* Not ast_bridged_channel! Only go one step! */ && AST_LIST_EMPTY(&p->owner->readq)) {
229 /* Masquerade bridged channel into owner */
230 /* Lock everything we need, one by one, and give up if
231 we can't get everything. Remember, we'll get another
232 chance in just a little bit */
233 if (!ast_mutex_trylock(&(p->chan->_bridge)->lock)) {
234 if (!p->chan->_bridge->_softhangup) {
235 if (!ast_mutex_trylock(&p->owner->lock)) {
236 if (!p->owner->_softhangup) {
237 ast_channel_masquerade(p->owner, p->chan->_bridge);
238 ast_set_flag(p, LOCAL_ALREADY_MASQED);
240 ast_mutex_unlock(&p->owner->lock);
242 ast_mutex_unlock(&(p->chan->_bridge)->lock);
245 /* We only allow masquerading in one 'direction'... it's important to preserve the state
246 (group variables, etc.) that live on p->chan->_bridge (and were put there by the dialplan)
247 when the local channels go away.
250 } else if (!isoutbound && p->owner && p->owner->_bridge && p->chan && AST_LIST_EMPTY(&p->chan->readq)) {
251 /* Masquerade bridged channel into chan */
252 if (!ast_mutex_trylock(&(p->owner->_bridge)->lock)) {
253 if (!p->owner->_bridge->_softhangup) {
254 if (!ast_mutex_trylock(&p->chan->lock)) {
255 if (!p->chan->_softhangup) {
256 ast_channel_masquerade(p->chan, p->owner->_bridge);
257 ast_set_flag(p, LOCAL_ALREADY_MASQED);
259 ast_mutex_unlock(&p->chan->lock);
262 ast_mutex_unlock(&(p->owner->_bridge)->lock);
268 static struct ast_frame *local_read(struct ast_channel *ast)
270 return &ast_null_frame;
273 static int local_write(struct ast_channel *ast, struct ast_frame *f)
275 struct local_pvt *p = ast->tech_pvt;
279 /* Just queue for delivery to the other side */
280 ast_mutex_lock(&p->lock);
281 isoutbound = IS_OUTBOUND(ast, p);
282 if (f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO))
283 check_bridge(p, isoutbound);
284 if (!ast_test_flag(p, LOCAL_ALREADY_MASQED))
285 res = local_queue_frame(p, isoutbound, f, ast);
288 ast_log(LOG_DEBUG, "Not posting to queue since already masked on '%s'\n", ast->name);
291 ast_mutex_unlock(&p->lock);
295 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
297 struct local_pvt *p = newchan->tech_pvt;
298 ast_mutex_lock(&p->lock);
300 if ((p->owner != oldchan) && (p->chan != oldchan)) {
301 ast_log(LOG_WARNING, "Old channel wasn't %p but was %p/%p\n", oldchan, p->owner, p->chan);
302 ast_mutex_unlock(&p->lock);
305 if (p->owner == oldchan)
309 ast_mutex_unlock(&p->lock);
313 static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
315 struct local_pvt *p = ast->tech_pvt;
317 struct ast_frame f = { AST_FRAME_CONTROL, };
320 /* If this is an MOH hold or unhold, do it on the Local channel versus real channel */
321 if (condition == AST_CONTROL_HOLD) {
322 ast_moh_start(ast, data, NULL);
323 } else if (condition == AST_CONTROL_UNHOLD) {
326 /* Queue up a frame representing the indication as a control frame */
327 ast_mutex_lock(&p->lock);
328 isoutbound = IS_OUTBOUND(ast, p);
329 f.subclass = condition;
330 f.data = (void*)data;
332 res = local_queue_frame(p, isoutbound, &f, ast);
333 ast_mutex_unlock(&p->lock);
339 static int local_digit_begin(struct ast_channel *ast, char digit)
341 struct local_pvt *p = ast->tech_pvt;
343 struct ast_frame f = { AST_FRAME_DTMF_BEGIN, };
346 ast_mutex_lock(&p->lock);
347 isoutbound = IS_OUTBOUND(ast, p);
349 res = local_queue_frame(p, isoutbound, &f, ast);
350 ast_mutex_unlock(&p->lock);
355 static int local_digit_end(struct ast_channel *ast, char digit)
357 struct local_pvt *p = ast->tech_pvt;
359 struct ast_frame f = { AST_FRAME_DTMF_END, };
362 ast_mutex_lock(&p->lock);
363 isoutbound = IS_OUTBOUND(ast, p);
365 res = local_queue_frame(p, isoutbound, &f, ast);
366 ast_mutex_unlock(&p->lock);
371 static int local_sendtext(struct ast_channel *ast, const char *text)
373 struct local_pvt *p = ast->tech_pvt;
375 struct ast_frame f = { AST_FRAME_TEXT, };
378 ast_mutex_lock(&p->lock);
379 isoutbound = IS_OUTBOUND(ast, p);
380 f.data = (char *) text;
381 f.datalen = strlen(text) + 1;
382 res = local_queue_frame(p, isoutbound, &f, ast);
383 ast_mutex_unlock(&p->lock);
387 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
389 struct local_pvt *p = ast->tech_pvt;
391 struct ast_frame f = { AST_FRAME_HTML, };
394 ast_mutex_lock(&p->lock);
395 isoutbound = IS_OUTBOUND(ast, p);
396 f.subclass = subclass;
397 f.data = (char *)data;
399 res = local_queue_frame(p, isoutbound, &f, ast);
400 ast_mutex_unlock(&p->lock);
404 /*! \brief Initiate new call, part of PBX interface
405 * dest is the dial string */
406 static int local_call(struct ast_channel *ast, char *dest, int timeout)
408 struct local_pvt *p = ast->tech_pvt;
410 struct ast_var_t *varptr = NULL, *new;
413 ast_mutex_lock(&p->lock);
415 p->chan->cid.cid_num = ast_strdup(p->owner->cid.cid_num);
416 p->chan->cid.cid_name = ast_strdup(p->owner->cid.cid_name);
417 p->chan->cid.cid_rdnis = ast_strdup(p->owner->cid.cid_rdnis);
418 p->chan->cid.cid_ani = ast_strdup(p->owner->cid.cid_ani);
419 p->chan->cid.cid_pres = p->owner->cid.cid_pres;
420 ast_string_field_set(p->chan, language, p->owner->language);
421 ast_string_field_set(p->chan, accountcode, p->owner->accountcode);
422 p->chan->cdrflags = p->owner->cdrflags;
424 /* copy the channel variables from the incoming channel to the outgoing channel */
425 /* Note that due to certain assumptions, they MUST be in the same order */
426 AST_LIST_TRAVERSE(&p->owner->varshead, varptr, entries) {
427 namelen = strlen(varptr->name);
428 len = sizeof(struct ast_var_t) + namelen + strlen(varptr->value) + 2;
429 if ((new = ast_calloc(1, len))) {
430 memcpy(new, varptr, len);
431 new->value = &(new->name[0]) + namelen + 1;
432 AST_LIST_INSERT_TAIL(&p->chan->varshead, new, entries);
436 ast_set_flag(p, LOCAL_LAUNCHED_PBX);
438 /* Start switch on sub channel */
439 res = ast_pbx_start(p->chan);
440 ast_mutex_unlock(&p->lock);
444 /*! \brief Hangup a call through the local proxy channel */
445 static int local_hangup(struct ast_channel *ast)
447 struct local_pvt *p = ast->tech_pvt;
449 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
450 struct ast_channel *ochan = NULL;
453 ast_mutex_lock(&p->lock);
454 isoutbound = IS_OUTBOUND(ast, p);
456 const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
457 if ((status) && (p->owner))
458 pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
460 ast_clear_flag(p, LOCAL_LAUNCHED_PBX);
461 ast_module_user_remove(p->u_chan);
464 ast_module_user_remove(p->u_owner);
467 ast->tech_pvt = NULL;
469 if (!p->owner && !p->chan) {
470 /* Okay, done with the private part now, too. */
471 glaredetect = ast_test_flag(p, LOCAL_GLARE_DETECT);
472 /* If we have a queue holding, don't actually destroy p yet, but
473 let local_queue do it. */
475 ast_set_flag(p, LOCAL_CANCEL_QUEUE);
476 ast_mutex_unlock(&p->lock);
477 /* Remove from list */
478 AST_LIST_LOCK(&locals);
479 AST_LIST_REMOVE(&locals, p, list);
480 AST_LIST_UNLOCK(&locals);
481 /* Grab / release lock just in case */
482 ast_mutex_lock(&p->lock);
483 ast_mutex_unlock(&p->lock);
486 ast_mutex_destroy(&p->lock);
491 if (p->chan && !ast_test_flag(p, LOCAL_LAUNCHED_PBX))
492 /* Need to actually hangup since there is no PBX */
495 local_queue_frame(p, isoutbound, &f, NULL);
496 ast_mutex_unlock(&p->lock);
502 /*! \brief Create a call structure */
503 static struct local_pvt *local_alloc(const char *data, int format)
505 struct local_pvt *tmp = NULL;
506 char *c = NULL, *opts = NULL;
508 if (!(tmp = ast_calloc(1, sizeof(*tmp))))
511 /* Initialize private structure information */
512 ast_mutex_init(&tmp->lock);
513 ast_copy_string(tmp->exten, data, sizeof(tmp->exten));
515 /* Look for options */
516 if ((opts = strchr(tmp->exten, '/'))) {
518 if (strchr(opts, 'n'))
519 ast_set_flag(tmp, LOCAL_NO_OPTIMIZATION);
522 /* Look for a context */
523 if ((c = strchr(tmp->exten, '@')))
526 ast_copy_string(tmp->context, c ? c : "default", sizeof(tmp->context));
528 tmp->reqformat = format;
530 if (!ast_exists_extension(NULL, tmp->context, tmp->exten, 1, NULL)) {
531 ast_log(LOG_NOTICE, "No such extension/context %s@%s creating local channel\n", tmp->exten, tmp->context);
532 ast_mutex_destroy(&tmp->lock);
537 AST_LIST_LOCK(&locals);
538 AST_LIST_INSERT_HEAD(&locals, tmp, list);
539 AST_LIST_UNLOCK(&locals);
545 /*! \brief Start new local channel */
546 static struct ast_channel *local_new(struct local_pvt *p, int state)
548 struct ast_channel *tmp = NULL, *tmp2 = NULL;
549 int randnum = ast_random() & 0xffff, fmt = 0;
551 /* Allocate two new Asterisk channels */
552 if (!(tmp = ast_channel_alloc(1)) || !(tmp2 = ast_channel_alloc(1))) {
554 ast_channel_free(tmp);
556 ast_channel_free(tmp2);
557 ast_log(LOG_WARNING, "Unable to allocate channel structure(s)\n");
561 tmp2->tech = tmp->tech = &local_tech;
563 tmp->nativeformats = p->reqformat;
564 tmp2->nativeformats = p->reqformat;
566 ast_string_field_build(tmp, name, "Local/%s@%s-%04x,1", p->exten, p->context, randnum);
567 ast_string_field_build(tmp2, name, "Local/%s@%s-%04x,2", p->exten, p->context, randnum);
569 ast_setstate(tmp, state);
570 ast_setstate(tmp2, AST_STATE_RING);
572 /* Determine our read/write format and set it on each channel */
573 fmt = ast_best_codec(p->reqformat);
574 tmp->writeformat = fmt;
575 tmp2->writeformat = fmt;
576 tmp->rawwriteformat = fmt;
577 tmp2->rawwriteformat = fmt;
578 tmp->readformat = fmt;
579 tmp2->readformat = fmt;
580 tmp->rawreadformat = fmt;
581 tmp2->rawreadformat = fmt;
588 p->u_owner = ast_module_user_add(p->owner);
589 p->u_chan = ast_module_user_add(p->chan);
591 ast_copy_string(tmp->context, p->context, sizeof(tmp->context));
592 ast_copy_string(tmp2->context, p->context, sizeof(tmp2->context));
593 ast_copy_string(tmp2->exten, p->exten, sizeof(tmp->exten));
601 /*! \brief Part of PBX interface */
602 static struct ast_channel *local_request(const char *type, int format, void *data, int *cause)
604 struct local_pvt *p = NULL;
605 struct ast_channel *chan = NULL;
607 /* Allocate a new private structure and then Asterisk channel */
608 if ((p = local_alloc(data, format)))
609 chan = local_new(p, AST_STATE_DOWN);
614 /*! \brief CLI command "local show channels" */
615 static int locals_show(int fd, int argc, char **argv)
617 struct local_pvt *p = NULL;
620 return RESULT_SHOWUSAGE;
622 AST_LIST_LOCK(&locals);
623 if (!AST_LIST_EMPTY(&locals)) {
624 AST_LIST_TRAVERSE(&locals, p, list) {
625 ast_mutex_lock(&p->lock);
626 ast_cli(fd, "%s -- %s@%s\n", p->owner ? p->owner->name : "<unowned>", p->exten, p->context);
627 ast_mutex_unlock(&p->lock);
630 ast_cli(fd, "No local channels in use\n");
631 AST_LIST_UNLOCK(&locals);
633 return RESULT_SUCCESS;
636 static char show_locals_usage[] =
637 "Usage: local show channels\n"
638 " Provides summary information on active local proxy channels.\n";
640 static struct ast_cli_entry cli_local[] = {
641 { { "local", "show", "channels", NULL },
642 locals_show, "List status of local channels",
646 /*! \brief Load module into PBX, register channel */
647 static int load_module(void)
649 /* Make sure we can register our channel type */
650 if (ast_channel_register(&local_tech)) {
651 ast_log(LOG_ERROR, "Unable to register channel class 'Local'\n");
654 ast_cli_register_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
658 /*! \brief Unload the local proxy channel from Asterisk */
659 static int unload_module(void)
661 struct local_pvt *p = NULL;
663 /* First, take us out of the channel loop */
664 ast_cli_unregister_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
665 ast_channel_unregister(&local_tech);
666 if (!AST_LIST_LOCK(&locals)) {
667 /* Hangup all interfaces if they have an owner */
668 AST_LIST_TRAVERSE(&locals, p, list) {
670 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
672 AST_LIST_UNLOCK(&locals);
673 AST_LIST_HEAD_DESTROY(&locals);
675 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
681 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Local Proxy Channel");