Add preliminary chan_local, fix chan_sip to delete unknown calls
[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 <pthread.h>
16 #include <string.h>
17 #include <asterisk/lock.h>
18 #include <asterisk/channel.h>
19 #include <asterisk/channel_pvt.h>
20 #include <asterisk/config.h>
21 #include <asterisk/logger.h>
22 #include <asterisk/module.h>
23 #include <asterisk/pbx.h>
24 #include <asterisk/options.h>
25 #include <asterisk/lock.h>
26 #include <asterisk/sched.h>
27 #include <asterisk/io.h>
28 #include <asterisk/rtp.h>
29 #include <asterisk/acl.h>
30 #include <asterisk/callerid.h>
31 #include <asterisk/file.h>
32 #include <asterisk/cli.h>
33 #include <asterisk/app.h>
34 #include <asterisk/musiconhold.h>
35 #include <asterisk/manager.h>
36 #include <sys/socket.h>
37 #include <errno.h>
38 #include <unistd.h>
39 #include <stdlib.h>
40 #include <fcntl.h>
41 #include <netdb.h>
42 #include <arpa/inet.h>
43 #include <sys/signal.h>
44
45 static char *desc = "Local Proxy Channel";
46 static char *type = "Local";
47 static char *tdesc = "Local Proxy Channel Driver";
48
49 static int capability = -1;
50
51 static int usecnt =0;
52 static pthread_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
53
54 #define IS_OUTBOUND(a,b) (a == b->chan ? 1 : 0)
55
56 /* Protect the interface list (of sip_pvt's) */
57 static pthread_mutex_t locallock = AST_MUTEX_INITIALIZER;
58
59 static struct local_pvt {
60         pthread_mutex_t lock;                           /* Channel private lock */
61         char context[AST_MAX_EXTENSION];        /* Context to call */
62         char exten[AST_MAX_EXTENSION];          /* Extension to call */
63         int reqformat;                                          /* Requested format */
64         struct ast_channel *owner;                      /* Master Channel */
65         struct ast_channel *chan;                       /* Outbound channel */
66         struct local_pvt *next;                         /* Next entity */
67 } *locals = NULL;
68
69 static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f)
70 {
71         struct ast_channel *other;
72         if (isoutbound)
73                 other = p->owner;
74         else
75                 other = p->chan;
76         if (!other)
77                 return 0;
78 retrylock:              
79         if (pthread_mutex_trylock(&other->lock)) {
80                 /* Failed to lock.  Release main lock and try again */
81                 ast_pthread_mutex_unlock(&p->lock);
82                 /* Wait just a bit */
83                 usleep(1);
84                 ast_pthread_mutex_lock(&p->lock);
85                 goto retrylock;
86         }
87         ast_queue_frame(other, f, 0);
88         ast_pthread_mutex_unlock(&other->lock);
89         return 0;
90 }
91
92 static int local_answer(struct ast_channel *ast)
93 {
94         struct local_pvt *p = ast->pvt->pvt;
95         int isoutbound = IS_OUTBOUND(ast, p);
96         int res = -1;
97         ast_pthread_mutex_lock(&p->lock);
98         if (isoutbound) {
99                 /* Pass along answer since somebody answered us */
100                 struct ast_frame answer = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
101                 local_queue_frame(p, isoutbound, &answer);
102         } else
103                 ast_log(LOG_WARNING, "Huh?  Local is being asked to answer?\n");
104         ast_pthread_mutex_unlock(&p->lock);
105         return res;
106 }
107
108 static struct ast_frame  *local_read(struct ast_channel *ast)
109 {
110         static struct ast_frame null = { AST_FRAME_NULL, };
111         return &null;
112 }
113
114 static int local_write(struct ast_channel *ast, struct ast_frame *f)
115 {
116         struct local_pvt *p = ast->pvt->pvt;
117         int res = -1;
118         ast_pthread_mutex_lock(&p->lock);
119         int isoutbound = IS_OUTBOUND(ast, p);
120
121         /* Just queue for delivery to the other side */
122         ast_pthread_mutex_lock(&p->lock);
123         res = local_queue_frame(p, isoutbound, f);
124         ast_pthread_mutex_unlock(&p->lock);
125         return res;
126 }
127
128 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
129 {
130         struct local_pvt *p = newchan->pvt->pvt;
131         ast_pthread_mutex_lock(&p->lock);
132         if ((p->owner != oldchan) && (p->chan != oldchan)) {
133                 ast_log(LOG_WARNING, "old channel wasn't %p but was %p/%p\n", oldchan, p->owner, p->chan);
134                 ast_pthread_mutex_unlock(&p->lock);
135                 return -1;
136         }
137         if (p->owner == oldchan)
138                 p->owner = newchan;
139         else
140                 p->chan = newchan;      
141         ast_pthread_mutex_unlock(&p->lock);
142         return 0;
143 }
144
145 static int local_indicate(struct ast_channel *ast, int condition)
146 {
147         struct local_pvt *p = ast->pvt->pvt;
148         int res = -1;
149         struct ast_frame f = { AST_FRAME_CONTROL, };
150         int isoutbound = IS_OUTBOUND(ast, p);
151         /* Queue up a frame representing the indication as a control frame */
152         ast_pthread_mutex_lock(&p->lock);
153         f.subclass = condition;
154         res = local_queue_frame(p, isoutbound, &f);
155         ast_pthread_mutex_unlock(&p->lock);
156         return res;
157 }
158
159 static int local_digit(struct ast_channel *ast, char digit)
160 {
161         struct local_pvt *p = ast->pvt->pvt;
162         int res = -1;
163         struct ast_frame f = { AST_FRAME_DTMF, };
164         int isoutbound = IS_OUTBOUND(ast, p);
165         ast_pthread_mutex_lock(&p->lock);
166         f.subclass = digit;
167         res = local_queue_frame(p, isoutbound, &f);
168         ast_pthread_mutex_unlock(&p->lock);
169         return res;
170 }
171
172 static int local_call(struct ast_channel *ast, char *dest, int timeout)
173 {
174         struct local_pvt *p = ast->pvt->pvt;
175         /* Start switch on sub channel */
176         return ast_pbx_start(p->chan);
177 }
178
179 static void local_destroy(struct local_pvt *p)
180 {
181         struct local_pvt *cur, *prev = NULL;
182         ast_pthread_mutex_lock(&locallock);
183         cur = locals;
184         while(cur) {
185                 if (cur == p) {
186                         if (prev)
187                                 prev->next = cur->next;
188                         else
189                                 locals = cur->next;
190                         free(cur);
191                         break;
192                 }
193                 prev = cur;
194                 cur = cur->next;
195         }
196         ast_pthread_mutex_unlock(&locallock);
197         if (!cur)
198                 ast_log(LOG_WARNING, "Unable ot find local '%s@%s' in local list\n", p->exten, p->context);
199 }
200
201 static int local_hangup(struct ast_channel *ast)
202 {
203         struct local_pvt *p = ast->pvt->pvt;
204         int isoutbound = IS_OUTBOUND(ast, p);
205         struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
206         ast_pthread_mutex_lock(&p->lock);
207         if (isoutbound)
208                 p->chan = NULL;
209         else
210                 p->owner = NULL;
211         ast->pvt->pvt = NULL;
212         if (!p->owner && !p->chan) {
213                 /* Okay, done with the private part now, too. */
214                 ast_pthread_mutex_unlock(&p->lock);
215                 free(p);
216                 return 0;
217         }
218         local_queue_frame(p, isoutbound, &f);
219         ast_pthread_mutex_unlock(&p->lock);
220         return 0;
221 }
222
223 static struct local_pvt *local_alloc(char *data, int format)
224 {
225         struct local_pvt *tmp;
226         char *c;
227         tmp = malloc(sizeof(struct local_pvt));
228         if (tmp) {
229                 memset(tmp, 0, sizeof(struct local_pvt));
230                 ast_pthread_mutex_init(&tmp->lock);
231                 strncpy(tmp->exten, data, sizeof(tmp->exten) - 1);
232                 c = strchr(tmp->exten, '@');
233                 if (c) {
234                         *c = '\0';
235                         c++;
236                         strncpy(tmp->context, data, sizeof(tmp->context) - 1);
237                 }
238                 tmp->reqformat = format;
239                 /* Add to list */
240                 ast_pthread_mutex_lock(&locallock);
241                 tmp->next = locals;
242                 locals = tmp;
243                 ast_pthread_mutex_unlock(&locallock);
244                 
245         }
246         return tmp;
247 }
248
249 static struct ast_channel *local_new(struct local_pvt *p, int state)
250 {
251         struct ast_channel *tmp, *tmp2;
252         tmp = ast_channel_alloc(1);
253         tmp2 = ast_channel_alloc(1);
254         if (!tmp || !tmp2) {
255                 if (tmp)
256                         ast_channel_free(tmp);
257                 if (tmp2)
258                         ast_channel_free(tmp2);
259                 tmp = NULL;
260         }
261         if (tmp) {
262                 tmp->nativeformats = p->reqformat;
263                 tmp->nativeformats = p->reqformat;
264                 snprintf(tmp->name, sizeof(tmp->name), "Local/%s@%s-1", p->exten, p->context);
265                 snprintf(tmp2->name, sizeof(tmp2->name), "Local/%s@%s-2", p->exten, p->context);
266                 tmp->type = type;
267                 tmp2->type = type;
268                 ast_setstate(tmp, state);
269                 ast_setstate(tmp2, AST_STATE_RING);
270                 tmp->writeformat = p->reqformat;;
271                 tmp2->writeformat = p->reqformat;
272                 tmp->pvt->rawwriteformat = p->reqformat;
273                 tmp2->pvt->rawwriteformat = p->reqformat;
274                 tmp->readformat = p->reqformat;
275                 tmp2->readformat = p->reqformat;
276                 tmp->pvt->rawreadformat = p->reqformat;
277                 tmp2->pvt->rawreadformat = p->reqformat;
278                 tmp->pvt->pvt = p;
279                 tmp2->pvt->pvt = p;
280                 tmp->pvt->send_digit = local_digit;
281                 tmp2->pvt->send_digit = local_digit;
282                 tmp->pvt->call = local_call;
283                 tmp2->pvt->call = local_call;
284                 tmp->pvt->hangup = local_hangup;
285                 tmp2->pvt->hangup = local_hangup;
286                 tmp->pvt->answer = local_answer;
287                 tmp2->pvt->answer = local_answer;
288                 tmp->pvt->read = local_read;
289                 tmp2->pvt->read = local_read;
290                 tmp->pvt->write = local_write;
291                 tmp2->pvt->write = local_write;
292                 tmp->pvt->exception = local_read;
293                 tmp2->pvt->exception = local_read;
294                 tmp->pvt->indicate = local_indicate;
295                 tmp2->pvt->indicate = local_indicate;
296                 tmp->pvt->fixup = local_fixup;
297                 tmp2->pvt->fixup = local_fixup;
298                 p->owner = tmp;
299                 p->chan = tmp2;
300                 ast_pthread_mutex_lock(&usecnt_lock);
301                 usecnt++;
302                 ast_pthread_mutex_unlock(&usecnt_lock);
303                 ast_update_use_count();
304                 strncpy(tmp->context, p->context, sizeof(tmp->context)-1);
305                 strncpy(tmp2->context, p->context, sizeof(tmp2->context)-1);
306                 strncpy(tmp2->exten, p->exten, sizeof(tmp->exten)-1);
307                 tmp->priority = 1;
308                 tmp2->priority = 1;
309         } else
310                 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
311         return tmp;
312 }
313
314
315 static struct ast_channel *local_request(char *type, int format, void *data)
316 {
317         struct local_pvt *p;
318         struct ast_channel *chan = NULL;
319         p = local_alloc(data, format);
320         chan = local_new(p, AST_STATE_DOWN);
321         return chan;
322 }
323
324 static int locals_show(int fd, int argc, char **argv)
325 {
326         struct local_pvt *p;
327
328         if (argc != 2)
329                 return RESULT_SHOWUSAGE;
330         ast_pthread_mutex_lock(&locallock);
331         p = locals;
332         while(p) {
333                 ast_pthread_mutex_lock(&p->lock);
334                 ast_cli(fd, "%s -- %s@%s\n", p->owner ? p->owner->name : "<unowned>", p->exten, p->context);
335                 ast_pthread_mutex_unlock(&p->lock);
336                 p = p->next;
337         }
338         if (!locals)
339                 ast_cli(fd, "No local channels in use\n");
340         ast_pthread_mutex_unlock(&locallock);
341         return RESULT_SUCCESS;
342 }
343
344 static char show_locals_usage[] = 
345 "Usage: show locals\n"
346 "       Provides summary information on locals.\n";
347
348 static struct ast_cli_entry cli_show_locals = {
349         { "show", "locals", NULL }, locals_show, 
350         "Show status of local channels", show_locals_usage, NULL };
351
352 int load_module()
353 {
354         /* Make sure we can register our sip channel type */
355         if (ast_channel_register(type, tdesc, capability, local_request)) {
356                 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
357                 return -1;
358         }
359         ast_cli_register(&cli_show_locals);
360         return 0;
361 }
362
363 int reload()
364 {
365         return 0;
366 }
367
368 int unload_module()
369 {
370         struct local_pvt *p;
371         /* First, take us out of the channel loop */
372         ast_cli_unregister(&cli_show_locals);
373         ast_channel_unregister(type);
374         if (!ast_pthread_mutex_lock(&locallock)) {
375                 /* Hangup all interfaces if they have an owner */
376                 p = locals;
377                 while(p) {
378                         if (p->owner)
379                                 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
380                         p = p->next;
381                 }
382                 locals = NULL;
383                 ast_pthread_mutex_unlock(&locallock);
384         } else {
385                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
386                 return -1;
387         }               
388         return 0;
389 }
390
391 int usecount()
392 {
393         int res;
394         ast_pthread_mutex_lock(&usecnt_lock);
395         res = usecnt;
396         ast_pthread_mutex_unlock(&usecnt_lock);
397         return res;
398 }
399
400 char *key()
401 {
402         return ASTERISK_GPL_KEY;
403 }
404
405 char *description()
406 {
407         return desc;
408 }
409