another round of version tag updates, along with 'show version files' pattern filtering
[asterisk/asterisk.git] / channels / chan_local.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Local Proxy Channel
5  * 
6  * Copyright (C) 1999, Mark Spencer
7  *
8  * Mark Spencer <markster@linux-support.net>
9  *
10  * This program is free software, distributed under the terms of
11  * the GNU General Public License
12  */
13
14 #include <stdio.h>
15 #include <string.h>
16 #include <sys/socket.h>
17 #include <errno.h>
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <fcntl.h>
21 #include <netdb.h>
22 #include <arpa/inet.h>
23 #include <sys/signal.h>
24
25 #include "asterisk.h"
26
27 ASTERISK_FILE_VERSION("$Revision$")
28
29 #include "asterisk/lock.h"
30 #include "asterisk/channel.h"
31 #include "asterisk/config.h"
32 #include "asterisk/logger.h"
33 #include "asterisk/module.h"
34 #include "asterisk/pbx.h"
35 #include "asterisk/options.h"
36 #include "asterisk/lock.h"
37 #include "asterisk/sched.h"
38 #include "asterisk/io.h"
39 #include "asterisk/rtp.h"
40 #include "asterisk/acl.h"
41 #include "asterisk/callerid.h"
42 #include "asterisk/file.h"
43 #include "asterisk/cli.h"
44 #include "asterisk/app.h"
45 #include "asterisk/musiconhold.h"
46 #include "asterisk/manager.h"
47
48 static const char desc[] = "Local Proxy Channel";
49 static const char type[] = "Local";
50 static const char tdesc[] = "Local Proxy Channel Driver";
51
52 static int usecnt =0;
53 AST_MUTEX_DEFINE_STATIC(usecnt_lock);
54
55 #define IS_OUTBOUND(a,b) (a == b->chan ? 1 : 0)
56
57 /* Protect the interface list (of sip_pvt's) */
58 AST_MUTEX_DEFINE_STATIC(locallock);
59
60 static struct ast_channel *local_request(const char *type, int format, void *data, int *cause);
61 static int local_digit(struct ast_channel *ast, char digit);
62 static int local_call(struct ast_channel *ast, char *dest, int timeout);
63 static int local_hangup(struct ast_channel *ast);
64 static int local_answer(struct ast_channel *ast);
65 static struct ast_frame *local_read(struct ast_channel *ast);
66 static int local_write(struct ast_channel *ast, struct ast_frame *f);
67 static int local_indicate(struct ast_channel *ast, int condition);
68 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
69 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
70
71 static const struct ast_channel_tech local_tech = {
72         .type = type,
73         .description = tdesc,
74         .capabilities = -1,
75         .requester = local_request,
76         .send_digit = local_digit,
77         .call = local_call,
78         .hangup = local_hangup,
79         .answer = local_answer,
80         .read = local_read,
81         .write = local_write,
82         .exception = local_read,
83         .indicate = local_indicate,
84         .fixup = local_fixup,
85         .send_html = local_sendhtml,
86 };
87
88 static struct local_pvt {
89         ast_mutex_t lock;                               /* Channel private lock */
90         char context[AST_MAX_EXTENSION];        /* Context to call */
91         char exten[AST_MAX_EXTENSION];          /* Extension to call */
92         int reqformat;                                          /* Requested format */
93         int glaredetect;                                        /* Detect glare on hangup */
94         int cancelqueue;                                        /* Cancel queue */
95         int alreadymasqed;                                      /* Already masqueraded */
96         int launchedpbx;                                        /* Did we launch the PBX */
97         int nooptimization;
98         struct ast_channel *owner;                      /* Master Channel */
99         struct ast_channel *chan;                       /* Outbound channel */
100         struct local_pvt *next;                         /* Next entity */
101 } *locals = NULL;
102
103 static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us)
104 {
105         struct ast_channel *other;
106 retrylock:              
107         /* Recalculate outbound channel */
108         if (isoutbound) {
109                 other = p->owner;
110         } else {
111                 other = p->chan;
112         }
113         /* Set glare detection */
114         p->glaredetect = 1;
115         if (p->cancelqueue) {
116                 /* We had a glare on the hangup.  Forget all this business,
117                 return and destroy p.  */
118                 ast_mutex_unlock(&p->lock);
119                 ast_mutex_destroy(&p->lock);
120                 free(p);
121                 return -1;
122         }
123         if (!other) {
124                 p->glaredetect = 0;
125                 return 0;
126         }
127         if (ast_mutex_trylock(&other->lock)) {
128                 /* Failed to lock.  Release main lock and try again */
129                 ast_mutex_unlock(&p->lock);
130                 if (us) {
131                         if (ast_mutex_unlock(&us->lock)) {
132                                 ast_log(LOG_WARNING, "%s wasn't locked while sending %d/%d\n",
133                                         us->name, f->frametype, f->subclass);
134                                 us = NULL;
135                         }
136                 }
137                 /* Wait just a bit */
138                 usleep(1);
139                 /* Only we can destroy ourselves, so we can't disappear here */
140                 if (us)
141                         ast_mutex_lock(&us->lock);
142                 ast_mutex_lock(&p->lock);
143                 goto retrylock;
144         }
145         ast_queue_frame(other, f);
146         ast_mutex_unlock(&other->lock);
147         p->glaredetect = 0;
148         return 0;
149 }
150
151 static int local_answer(struct ast_channel *ast)
152 {
153         struct local_pvt *p = ast->tech_pvt;
154         int isoutbound;
155         int res = -1;
156         ast_mutex_lock(&p->lock);
157         isoutbound = IS_OUTBOUND(ast, p);
158         if (isoutbound) {
159                 /* Pass along answer since somebody answered us */
160                 struct ast_frame answer = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
161                 res = local_queue_frame(p, isoutbound, &answer, ast);
162         } else
163                 ast_log(LOG_WARNING, "Huh?  Local is being asked to answer?\n");
164         ast_mutex_unlock(&p->lock);
165         return res;
166 }
167
168 static void check_bridge(struct local_pvt *p, int isoutbound)
169 {
170         if (p->alreadymasqed || p->nooptimization)
171                 return;
172         if (isoutbound && p->chan && p->chan->_bridge /* Not ast_bridged_channel!  Only go one step! */ && p->owner && !p->owner->readq) {
173                 /* Masquerade bridged channel into owner */
174                 /* Lock everything we need, one by one, and give up if
175                    we can't get everything.  Remember, we'll get another
176                    chance in just a little bit */
177                 if (!ast_mutex_trylock(&(p->chan->_bridge)->lock)) {
178                         if (!ast_mutex_trylock(&p->owner->lock)) {
179                                 ast_channel_masquerade(p->owner, p->chan->_bridge);
180                                 p->alreadymasqed = 1;
181                                 ast_mutex_unlock(&p->owner->lock);
182                         }
183                         ast_mutex_unlock(&(p->chan->_bridge)->lock);
184                 }
185         } else if (!isoutbound && p->owner && p->owner->_bridge && p->chan && !p->chan->readq) {
186                 /* Masquerade bridged channel into chan */
187                 if (!ast_mutex_trylock(&(p->owner->_bridge)->lock)) {
188                         if (!ast_mutex_trylock(&p->chan->lock)) {
189                                 ast_channel_masquerade(p->chan, p->owner->_bridge);
190                                 p->alreadymasqed = 1;
191                                 ast_mutex_unlock(&p->chan->lock);
192                         }
193                         ast_mutex_unlock(&(p->owner->_bridge)->lock);
194                 }
195         }
196 }
197
198 static struct ast_frame  *local_read(struct ast_channel *ast)
199 {
200         static struct ast_frame null = { AST_FRAME_NULL, };
201         return &null;
202 }
203
204 static int local_write(struct ast_channel *ast, struct ast_frame *f)
205 {
206         struct local_pvt *p = ast->tech_pvt;
207         int res = -1;
208         int isoutbound;
209
210
211         /* Just queue for delivery to the other side */
212         ast_mutex_lock(&p->lock);
213         isoutbound = IS_OUTBOUND(ast, p);
214         if (f && (f->frametype == AST_FRAME_VOICE)) 
215                 check_bridge(p, isoutbound);
216         if (!p->alreadymasqed)
217                 res = local_queue_frame(p, isoutbound, f, ast);
218         else {
219                 ast_log(LOG_DEBUG, "Not posting to queue since already masked on '%s'\n", ast->name);
220                 res = 0;
221         }
222         ast_mutex_unlock(&p->lock);
223         return res;
224 }
225
226 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
227 {
228         struct local_pvt *p = newchan->tech_pvt;
229         ast_mutex_lock(&p->lock);
230         if ((p->owner != oldchan) && (p->chan != oldchan)) {
231                 ast_log(LOG_WARNING, "old channel wasn't %p but was %p/%p\n", oldchan, p->owner, p->chan);
232                 ast_mutex_unlock(&p->lock);
233                 return -1;
234         }
235         if (p->owner == oldchan)
236                 p->owner = newchan;
237         else
238                 p->chan = newchan;      
239         ast_mutex_unlock(&p->lock);
240         return 0;
241 }
242
243 static int local_indicate(struct ast_channel *ast, int condition)
244 {
245         struct local_pvt *p = ast->tech_pvt;
246         int res = -1;
247         struct ast_frame f = { AST_FRAME_CONTROL, };
248         int isoutbound;
249         /* Queue up a frame representing the indication as a control frame */
250         ast_mutex_lock(&p->lock);
251         isoutbound = IS_OUTBOUND(ast, p);
252         f.subclass = condition;
253         res = local_queue_frame(p, isoutbound, &f, ast);
254         ast_mutex_unlock(&p->lock);
255         return res;
256 }
257
258 static int local_digit(struct ast_channel *ast, char digit)
259 {
260         struct local_pvt *p = ast->tech_pvt;
261         int res = -1;
262         struct ast_frame f = { AST_FRAME_DTMF, };
263         int isoutbound;
264         ast_mutex_lock(&p->lock);
265         isoutbound = IS_OUTBOUND(ast, p);
266         f.subclass = digit;
267         res = local_queue_frame(p, isoutbound, &f, ast);
268         ast_mutex_unlock(&p->lock);
269         return res;
270 }
271
272 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
273 {
274         struct local_pvt *p = ast->tech_pvt;
275         int res = -1;
276         struct ast_frame f = { AST_FRAME_HTML, };
277         int isoutbound;
278         ast_mutex_lock(&p->lock);
279         isoutbound = IS_OUTBOUND(ast, p);
280         f.subclass = subclass;
281         f.data = (char *)data;
282         f.datalen = datalen;
283         res = local_queue_frame(p, isoutbound, &f, ast);
284         ast_mutex_unlock(&p->lock);
285         return res;
286 }
287
288 static int local_call(struct ast_channel *ast, char *dest, int timeout)
289 {
290         struct local_pvt *p = ast->tech_pvt;
291         int res;
292         
293         ast_mutex_lock(&p->lock);
294         if (p->owner->cid.cid_num)
295                 p->chan->cid.cid_num = strdup(p->owner->cid.cid_num);
296         else 
297                 p->chan->cid.cid_num = NULL;
298
299         if (p->owner->cid.cid_name)
300                 p->chan->cid.cid_name = strdup(p->owner->cid.cid_name);
301         else 
302                 p->chan->cid.cid_name = NULL;
303
304         if (p->owner->cid.cid_rdnis)
305                 p->chan->cid.cid_rdnis = strdup(p->owner->cid.cid_rdnis);
306         else
307                 p->chan->cid.cid_rdnis = NULL;
308
309         if (p->owner->cid.cid_ani)
310                 p->chan->cid.cid_ani = strdup(p->owner->cid.cid_ani);
311         else
312                 p->chan->cid.cid_ani = NULL;
313
314         strncpy(p->chan->language, p->owner->language, sizeof(p->chan->language) - 1);
315         strncpy(p->chan->accountcode, p->owner->accountcode, sizeof(p->chan->accountcode) - 1);
316         p->chan->cdrflags = p->owner->cdrflags;
317         ast_channel_inherit_variables(p->owner, p->chan);
318         p->launchedpbx = 1;
319         /* Start switch on sub channel */
320         res = ast_pbx_start(p->chan);
321         ast_mutex_unlock(&p->lock);
322         return res;
323 }
324
325 /*
326 static void local_destroy(struct local_pvt *p)
327 {
328         struct local_pvt *cur, *prev = NULL;
329         ast_mutex_lock(&locallock);
330         cur = locals;
331         while(cur) {
332                 if (cur == p) {
333                         if (prev)
334                                 prev->next = cur->next;
335                         else
336                                 locals = cur->next;
337                         ast_mutex_destroy(cur);
338                         free(cur);
339                         break;
340                 }
341                 prev = cur;
342                 cur = cur->next;
343         }
344         ast_mutex_unlock(&locallock);
345         if (!cur)
346                 ast_log(LOG_WARNING, "Unable ot find local '%s@%s' in local list\n", p->exten, p->context);
347 }
348 */
349
350 static int local_hangup(struct ast_channel *ast)
351 {
352         struct local_pvt *p = ast->tech_pvt;
353         int isoutbound;
354         struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
355         struct local_pvt *cur, *prev=NULL;
356         struct ast_channel *ochan = NULL;
357         int glaredetect;
358         ast_mutex_lock(&p->lock);
359         isoutbound = IS_OUTBOUND(ast, p);
360         if (isoutbound) {
361                 p->chan = NULL;
362                 p->launchedpbx = 0;
363         } else
364                 p->owner = NULL;
365         ast->tech_pvt = NULL;
366         
367         ast_mutex_lock(&usecnt_lock);
368         usecnt--;
369         ast_mutex_unlock(&usecnt_lock);
370         
371         if (!p->owner && !p->chan) {
372                 /* Okay, done with the private part now, too. */
373                 glaredetect = p->glaredetect;
374                 /* If we have a queue holding, don't actually destroy p yet, but
375                    let local_queue do it. */
376                 if (p->glaredetect)
377                         p->cancelqueue = 1;
378                 ast_mutex_unlock(&p->lock);
379                 /* Remove from list */
380                 ast_mutex_lock(&locallock);
381                 cur = locals;
382                 while(cur) {
383                         if (cur == p) {
384                                 if (prev)
385                                         prev->next = cur->next;
386                                 else
387                                         locals = cur->next;
388                                 break;
389                         }
390                         prev = cur;
391                         cur = cur->next;
392                 }
393                 ast_mutex_unlock(&locallock);
394                 /* Grab / release lock just in case */
395                 ast_mutex_lock(&p->lock);
396                 ast_mutex_unlock(&p->lock);
397                 /* And destroy */
398                 if (!glaredetect) {
399                         ast_mutex_destroy(&p->lock);
400                         free(p);
401                 }
402                 return 0;
403         }
404         if (p->chan && !p->launchedpbx)
405                 /* Need to actually hangup since there is no PBX */
406                 ochan = p->chan;
407         else
408                 local_queue_frame(p, isoutbound, &f, NULL);
409         ast_mutex_unlock(&p->lock);
410         if (ochan)
411                 ast_hangup(ochan);
412         return 0;
413 }
414
415 static struct local_pvt *local_alloc(char *data, int format)
416 {
417         struct local_pvt *tmp;
418         char *c;
419         char *opts;
420         tmp = malloc(sizeof(struct local_pvt));
421         if (tmp) {
422                 memset(tmp, 0, sizeof(struct local_pvt));
423                 ast_mutex_init(&tmp->lock);
424                 strncpy(tmp->exten, data, sizeof(tmp->exten) - 1);
425                 opts = strchr(tmp->exten, '/');
426                 if (opts) {
427                         *opts='\0';
428                         opts++;
429                         if (strchr(opts, 'n'))
430                                 tmp->nooptimization = 1;
431                 }
432                 c = strchr(tmp->exten, '@');
433                 if (c) {
434                         *c = '\0';
435                         c++;
436                         strncpy(tmp->context, c, sizeof(tmp->context) - 1);
437                 } else
438                         strncpy(tmp->context, "default", sizeof(tmp->context) - 1);
439                 tmp->reqformat = format;
440                 if (!ast_exists_extension(NULL, tmp->context, tmp->exten, 1, NULL)) {
441                         ast_log(LOG_NOTICE, "No such extension/context %s@%s creating local channel\n", tmp->exten, tmp->context);
442                         ast_mutex_destroy(&tmp->lock);
443                         free(tmp);
444                         tmp = NULL;
445                 } else {
446                         /* Add to list */
447                         ast_mutex_lock(&locallock);
448                         tmp->next = locals;
449                         locals = tmp;
450                         ast_mutex_unlock(&locallock);
451                 }
452                 
453         }
454         return tmp;
455 }
456
457 static struct ast_channel *local_new(struct local_pvt *p, int state)
458 {
459         struct ast_channel *tmp, *tmp2;
460         int randnum = rand() & 0xffff;
461         tmp = ast_channel_alloc(1);
462         tmp2 = ast_channel_alloc(1);
463         if (!tmp || !tmp2) {
464                 if (tmp)
465                         ast_channel_free(tmp);
466                 if (tmp2)
467                         ast_channel_free(tmp2);
468                 tmp = NULL;
469         }
470         if (tmp) {
471                 tmp2->tech = tmp->tech = &local_tech;
472                 tmp->nativeformats = p->reqformat;
473                 tmp2->nativeformats = p->reqformat;
474                 snprintf(tmp->name, sizeof(tmp->name), "Local/%s@%s-%04x,1", p->exten, p->context, randnum);
475                 snprintf(tmp2->name, sizeof(tmp2->name), "Local/%s@%s-%04x,2", p->exten, p->context, randnum);
476                 tmp->type = type;
477                 tmp2->type = type;
478                 ast_setstate(tmp, state);
479                 ast_setstate(tmp2, AST_STATE_RING);
480                 tmp->writeformat = p->reqformat;;
481                 tmp2->writeformat = p->reqformat;
482                 tmp->rawwriteformat = p->reqformat;
483                 tmp2->rawwriteformat = p->reqformat;
484                 tmp->readformat = p->reqformat;
485                 tmp2->readformat = p->reqformat;
486                 tmp->rawreadformat = p->reqformat;
487                 tmp2->rawreadformat = p->reqformat;
488                 tmp->tech_pvt = p;
489                 tmp2->tech_pvt = p;
490                 p->owner = tmp;
491                 p->chan = tmp2;
492                 ast_mutex_lock(&usecnt_lock);
493                 usecnt++;
494                 usecnt++;
495                 ast_mutex_unlock(&usecnt_lock);
496                 ast_update_use_count();
497                 strncpy(tmp->context, p->context, sizeof(tmp->context)-1);
498                 strncpy(tmp2->context, p->context, sizeof(tmp2->context)-1);
499                 strncpy(tmp2->exten, p->exten, sizeof(tmp->exten)-1);
500                 tmp->priority = 1;
501                 tmp2->priority = 1;
502         } else
503                 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
504         return tmp;
505 }
506
507
508 static struct ast_channel *local_request(const char *type, int format, void *data, int *cause)
509 {
510         struct local_pvt *p;
511         struct ast_channel *chan = NULL;
512         p = local_alloc(data, format);
513         if (p)
514                 chan = local_new(p, AST_STATE_DOWN);
515         return chan;
516 }
517
518 static int locals_show(int fd, int argc, char **argv)
519 {
520         struct local_pvt *p;
521
522         if (argc != 3)
523                 return RESULT_SHOWUSAGE;
524         ast_mutex_lock(&locallock);
525         p = locals;
526         while(p) {
527                 ast_mutex_lock(&p->lock);
528                 ast_cli(fd, "%s -- %s@%s\n", p->owner ? p->owner->name : "<unowned>", p->exten, p->context);
529                 ast_mutex_unlock(&p->lock);
530                 p = p->next;
531         }
532         if (!locals)
533                 ast_cli(fd, "No local channels in use\n");
534         ast_mutex_unlock(&locallock);
535         return RESULT_SUCCESS;
536 }
537
538 static char show_locals_usage[] = 
539 "Usage: local show channels\n"
540 "       Provides summary information on local channels.\n";
541
542 static struct ast_cli_entry cli_show_locals = {
543         { "local", "show", "channels", NULL }, locals_show, 
544         "Show status of local channels", show_locals_usage, NULL };
545
546 int load_module()
547 {
548         /* Make sure we can register our channel type */
549         if (ast_channel_register(&local_tech)) {
550                 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
551                 return -1;
552         }
553         ast_cli_register(&cli_show_locals);
554         return 0;
555 }
556
557 int reload()
558 {
559         return 0;
560 }
561
562 int unload_module()
563 {
564         struct local_pvt *p;
565         /* First, take us out of the channel loop */
566         ast_cli_unregister(&cli_show_locals);
567         ast_channel_unregister(&local_tech);
568         if (!ast_mutex_lock(&locallock)) {
569                 /* Hangup all interfaces if they have an owner */
570                 p = locals;
571                 while(p) {
572                         if (p->owner)
573                                 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
574                         p = p->next;
575                 }
576                 locals = NULL;
577                 ast_mutex_unlock(&locallock);
578         } else {
579                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
580                 return -1;
581         }               
582         return 0;
583 }
584
585 int usecount()
586 {
587         int res;
588         ast_mutex_lock(&usecnt_lock);
589         res = usecnt;
590         ast_mutex_unlock(&usecnt_lock);
591         return res;
592 }
593
594 char *key()
595 {
596         return ASTERISK_GPL_KEY;
597 }
598
599 char *description()
600 {
601         return (char *) desc;
602 }
603