Version 0.1.7 from FTP
[asterisk/asterisk.git] / channel.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Channel Management
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 <stdlib.h>
16 #include <pthread.h>
17 #include <string.h>
18 #include <sys/time.h>
19 #include <signal.h>
20 #include <errno.h>
21 #include <unistd.h>
22 #include <asterisk/sched.h>
23 #include <asterisk/options.h>
24 #include <asterisk/channel.h>
25 #include <asterisk/channel_pvt.h>
26 #include <asterisk/logger.h>
27 #include <asterisk/file.h>
28 #include <asterisk/translate.h>
29
30
31
32 #ifdef DEBUG_MUTEX
33 /* Convenient mutex debugging functions */
34 #define PTHREAD_MUTEX_LOCK(a) __PTHREAD_MUTEX_LOCK(__FUNCTION__, a)
35 #define PTHREAD_MUTEX_UNLOCK(a) __PTHREAD_MUTEX_UNLOCK(__FUNCTION__, a)
36
37 static int __PTHREAD_MUTEX_LOCK(char *f, pthread_mutex_t *a) {
38         ast_log(LOG_DEBUG, "Locking %p (%s)\n", a, f); 
39         return pthread_mutex_lock(a);
40 }
41
42 static int __PTHREAD_MUTEX_UNLOCK(char *f, pthread_mutex_t *a) {
43         ast_log(LOG_DEBUG, "Unlocking %p (%s)\n", a, f); 
44         return pthread_mutex_unlock(a);
45 }
46 #else
47 #define PTHREAD_MUTEX_LOCK(a) pthread_mutex_lock(a)
48 #define PTHREAD_MUTEX_UNLOCK(a) pthread_mutex_unlock(a)
49 #endif
50
51 struct chanlist {
52         char type[80];
53         char description[80];
54         int capabilities;
55         struct ast_channel * (*requester)(char *type, int format, void *data);
56         struct chanlist *next;
57 } *backends = NULL;
58 struct ast_channel *channels = NULL;
59
60 /* Protect the channel list (highly unlikely that two things would change
61    it at the same time, but still! */
62    
63 static pthread_mutex_t chlock = PTHREAD_MUTEX_INITIALIZER;
64
65 int ast_channel_register(char *type, char *description, int capabilities,
66                 struct ast_channel *(*requester)(char *type, int format, void *data))
67 {
68         struct chanlist *chan, *last=NULL;
69         if (PTHREAD_MUTEX_LOCK(&chlock)) {
70                 ast_log(LOG_WARNING, "Unable to lock channel list\n");
71                 return -1;
72         }
73         chan = backends;
74         while(chan) {
75                 if (!strcasecmp(type, chan->type)) {
76                         ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", type);
77                         PTHREAD_MUTEX_UNLOCK(&chlock);
78                         return -1;
79                 }
80                 last = chan;
81                 chan = chan->next;
82         }
83         chan = malloc(sizeof(struct chanlist));
84         if (!chan) {
85                 ast_log(LOG_WARNING, "Out of memory\n");
86                 PTHREAD_MUTEX_UNLOCK(&chlock);
87                 return -1;
88         }
89         strncpy(chan->type, type, sizeof(chan->type));
90         strncpy(chan->description, description, sizeof(chan->description));
91         chan->capabilities = capabilities;
92         chan->requester = requester;
93         chan->next = NULL;
94         if (last)
95                 last->next = chan;
96         else
97                 backends = chan;
98         if (option_debug)
99                 ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->type, chan->description);
100         else if (option_verbose > 1)
101                 ast_verbose( VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->type, chan->description);
102         PTHREAD_MUTEX_UNLOCK(&chlock);
103         return 0;
104 }
105
106 struct ast_channel *ast_channel_alloc(void)
107 {
108         struct ast_channel *tmp;
109         struct ast_channel_pvt *pvt;
110         PTHREAD_MUTEX_LOCK(&chlock);
111         tmp = malloc(sizeof(struct ast_channel));
112         memset(tmp, 0, sizeof(struct ast_channel));
113         if (tmp) {
114                 pvt = malloc(sizeof(struct ast_channel_pvt));
115                 if (pvt) {
116                         memset(pvt, 0, sizeof(struct ast_channel_pvt));
117                         tmp->sched = sched_context_create();
118                         if (tmp->sched) {
119                                 tmp->fd = -1;
120                                 strncpy(tmp->name, "**Unknown**", sizeof(tmp->name));
121                                 tmp->pvt = pvt;
122                                 tmp->state = AST_STATE_DOWN;
123                                 tmp->stack = -1;
124                                 tmp->streamid = -1;
125                                 tmp->appl = NULL;
126                                 tmp->data = NULL;
127                                 pthread_mutex_init(&tmp->lock, NULL);
128                                 strncpy(tmp->context, "default", sizeof(tmp->context));
129                                 strncpy(tmp->language, defaultlanguage, sizeof(tmp->language));
130                                 strncpy(tmp->exten, "s", sizeof(tmp->exten));
131                                 tmp->priority=1;
132                                 tmp->next = channels;
133                                 channels= tmp;
134                         } else {
135                                 ast_log(LOG_WARNING, "Unable to create schedule context\n");
136                                 free(tmp);
137                                 tmp = NULL;
138                         }
139                 } else {
140                         ast_log(LOG_WARNING, "Out of memory\n");
141                         free(tmp);
142                         tmp = NULL;
143                 }
144         } else 
145                 ast_log(LOG_WARNING, "Out of memory\n");
146         PTHREAD_MUTEX_UNLOCK(&chlock);
147         return tmp;
148 }
149
150 struct ast_channel *ast_channel_walk(struct ast_channel *prev)
151 {
152         struct ast_channel *l, *ret=NULL;
153         PTHREAD_MUTEX_LOCK(&chlock);
154         l = channels;
155         if (!prev) {
156                 PTHREAD_MUTEX_UNLOCK(&chlock);
157                 return l;
158         }
159         while(l) {
160                 if (l == prev)
161                         ret = l->next;
162                 l = l->next;
163         }
164         PTHREAD_MUTEX_UNLOCK(&chlock);
165         return ret;
166         
167 }
168
169 void ast_channel_free(struct ast_channel *chan)
170 {
171         struct ast_channel *last=NULL, *cur;
172         PTHREAD_MUTEX_LOCK(&chlock);
173         cur = channels;
174         while(cur) {
175                 if (cur == chan) {
176                         if (last)
177                                 last->next = cur->next;
178                         else
179                                 channels = cur->next;
180                         break;
181                 }
182                 last = cur;
183                 cur = cur->next;
184         }
185         if (!cur)
186                 ast_log(LOG_WARNING, "Unable to find channel in list\n");
187         if (chan->pvt->pvt)
188                 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
189         if (chan->trans)
190                 ast_log(LOG_WARNING, "Hard hangup called on '%s' while a translator is in place!  Expect a failure.\n", chan->name);
191         if (chan->pbx) 
192                 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
193         if (chan->dnid)
194                 free(chan->dnid);
195         if (chan->callerid)
196                 free(chan->callerid);   
197         pthread_mutex_destroy(&chan->lock);
198         free(chan);
199         PTHREAD_MUTEX_UNLOCK(&chlock);
200 }
201
202 int ast_softhangup(struct ast_channel *chan)
203 {
204         int res = 0;
205         if (chan->stream)
206                 ast_stopstream(chan);
207         if (option_debug)
208                 ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
209         if (chan->trans)
210                 ast_log(LOG_WARNING, "Soft hangup called on '%s' while a translator is in place!  Expect a failure.\n", chan->name);
211         if (chan->pvt->hangup)
212                 res = chan->pvt->hangup(chan);
213         if (chan->pvt->pvt)
214                 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
215         if (chan->pbx) 
216                 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);        
217         /* Interrupt any select call or such */
218         if (chan->blocking)
219                 pthread_kill(chan->blocker, SIGURG);
220         return res;
221 }
222
223 int ast_hangup(struct ast_channel *chan)
224 {
225         int res = 0;
226         if (chan->stream)
227                 ast_stopstream(chan);
228         if (chan->sched)
229                 sched_context_destroy(chan->sched);
230         if (chan->blocking)
231                 ast_log(LOG_WARNING, "Hard hangup called, while fd is blocking!  Expect a failure\n");
232         if (option_debug)
233                 ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
234         if (chan->pvt->hangup)
235                 res = chan->pvt->hangup(chan);
236         ast_channel_free(chan);
237         return res;
238 }
239
240 void ast_channel_unregister(char *type)
241 {
242         struct chanlist *chan, *last=NULL;
243         if (option_debug)
244                 ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", type);
245         if (PTHREAD_MUTEX_LOCK(&chlock)) {
246                 ast_log(LOG_WARNING, "Unable to lock channel list\n");
247                 return;
248         }
249         chan = backends;
250         while(chan) {
251                 if (!strcasecmp(chan->type, type)) {
252                         if (last)
253                                 last->next = chan->next;
254                         else
255                                 backends = backends->next;
256                         free(chan);
257                         PTHREAD_MUTEX_UNLOCK(&chlock);
258                         return;
259                 }
260                 last = chan;
261                 chan = chan->next;
262         }
263         PTHREAD_MUTEX_UNLOCK(&chlock);
264 }
265
266 int ast_answer(struct ast_channel *chan)
267 {
268         /* Answer the line, if possible */
269         if (chan->state == AST_STATE_RING) {
270                 if (chan->pvt->answer)
271                         return chan->pvt->answer(chan);
272         }
273         return 0;
274 }
275
276 int ast_waitfor_n_fd(int *fds, int n, int *ms)
277 {
278         /* Wait for x amount of time on a file descriptor to have input.  */
279         struct timeval tv;
280         fd_set rfds, efds;
281         int res;
282         int x, max=-1;
283         int winner = -1;
284         
285         tv.tv_sec = *ms / 1000;
286         tv.tv_usec = (*ms % 1000) * 1000;
287         FD_ZERO(&rfds);
288         FD_ZERO(&efds);
289         for (x=0;x<n;x++) {
290                 FD_SET(fds[x], &rfds);
291                 FD_SET(fds[x], &efds);
292                 if (fds[x] > max)
293                         max = fds[x];
294         }
295         if (*ms >= 0) 
296                 res = select(max + 1, &rfds, NULL, &efds, &tv);
297         else
298                 res = select(max + 1, &rfds, NULL, &efds, NULL);
299         for (x=0;x<n;x++) {
300                 if ((FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && (winner < 0))
301                         winner = fds[x];
302         }
303         *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
304         if (res < 0)
305                 *ms = -10;
306         return winner;
307 }
308
309 struct ast_channel *ast_waitfor_n(struct ast_channel **c, int n, int *ms)
310 {
311         /* Wait for x amount of time on a file descriptor to have input.  */
312         struct timeval tv;
313         fd_set rfds, efds;
314         int res;
315         int x, max=-1;
316         struct ast_channel *winner = NULL;
317         
318         tv.tv_sec = *ms / 1000;
319         tv.tv_usec = (*ms % 1000) * 1000;
320         FD_ZERO(&rfds);
321         FD_ZERO(&efds);
322         for (x=0;x<n;x++) {
323                 FD_SET(c[x]->fd, &rfds);
324                 FD_SET(c[x]->fd, &efds);
325                 CHECK_BLOCKING(c[x]);
326                 if (c[x]->fd > max)
327                         max = c[x]->fd;
328         }
329         if (*ms >= 0) 
330                 res = select(max + 1, &rfds, NULL, &efds, &tv);
331         else
332                 res = select(max + 1, &rfds, NULL, &efds, NULL);
333         for (x=0;x<n;x++) {
334                 c[x]->blocking = 0;
335                 if ((FD_ISSET(c[x]->fd, &rfds) || FD_ISSET(c[x]->fd, &efds)) && !winner)
336                         winner = c[x];
337         }
338         *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
339         if (res < 0)
340                 *ms = -10;
341         return winner;
342 }
343
344 int ast_waitfor(struct ast_channel *c, int ms)
345 {
346         if (ast_waitfor_n(&c, 1, &ms)) {
347                 if (ms < 0)
348                         return -ms;
349                 return ms;
350         }
351         /* Error if ms < 0 */
352         if (ms < 0) 
353                 return -1;
354         return 0;
355 }
356
357 char ast_waitfordigit(struct ast_channel *c, int ms)
358 {
359         struct ast_frame *f;
360         char result = 0;
361         /* Wait for a digit, no more than ms milliseconds total. */
362         while(ms && !result) {
363                 ms = ast_waitfor(c, ms);
364                 if (ms < 0) /* Error */
365                         result = -1; 
366                 else if (ms > 0) {
367                         /* Read something */
368                         f = ast_read(c);
369                         if (f) {
370                                 if (f->frametype == AST_FRAME_DTMF) 
371                                         result = f->subclass;
372                                 ast_frfree(f);
373                         } else
374                                 result = -1;
375                 }
376         }
377         return result;
378 }
379
380 struct ast_frame *ast_read(struct ast_channel *chan)
381 {
382         struct ast_frame *f = NULL;
383         chan->blocker = pthread_self();
384         if (chan->pvt->read)
385                 f = chan->pvt->read(chan);
386         else
387                 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan);
388         return f;
389 }
390
391 int ast_sendtext(struct ast_channel *chan, char *text)
392 {
393         int res = 0;
394         CHECK_BLOCKING(chan);
395         if (chan->pvt->send_text)
396                 res = chan->pvt->send_text(chan, text);
397         chan->blocking = 0;
398         return res;
399 }
400
401 int ast_write(struct ast_channel *chan, struct ast_frame *fr)
402 {
403         int res = -1;
404         CHECK_BLOCKING(chan);
405         switch(fr->frametype) {
406         case AST_FRAME_CONTROL:
407                 /* XXX Interpret control frames XXX */
408                 ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n");
409                 break;
410         case AST_FRAME_DTMF:
411                 
412                 if (chan->pvt->send_digit)
413                         res = chan->pvt->send_digit(chan, fr->subclass);
414                 break;
415         default:
416                 if (chan->pvt->write)
417                         res = chan->pvt->write(chan, fr);
418         }
419         chan->blocking = 0;
420         return res;
421 }
422
423 struct ast_channel *ast_request(char *type, int format, void *data)
424 {
425         struct chanlist *chan;
426         struct ast_channel *c = NULL;
427         if (PTHREAD_MUTEX_LOCK(&chlock)) {
428                 ast_log(LOG_WARNING, "Unable to lock channel list\n");
429                 return NULL;
430         }
431         chan = backends;
432         while(chan) {
433                 if (!strcasecmp(type, chan->type)) {
434                         if (!(chan->capabilities & format)) {
435                                 format = ast_translator_best_choice(format, chan->capabilities);
436                         }
437                         PTHREAD_MUTEX_UNLOCK(&chlock);
438                         if (chan->requester)
439                                 c = chan->requester(type, format, data);
440                         return c;
441                 }
442                 chan = chan->next;
443         }
444         if (!chan)
445                 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
446         PTHREAD_MUTEX_UNLOCK(&chlock);
447         return c;
448 }
449
450 int ast_call(struct ast_channel *chan, char *addr, int timeout) 
451 {
452         /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 
453            If the remote end does not answer within the timeout, then do NOT hang up, but 
454            return anyway.  */
455         int res = -1;
456         if (chan->pvt->call)
457                 res = chan->pvt->call(chan, addr, timeout);
458         return res;
459 }
460
461 int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
462 {
463         int pos=0;
464         int to = ftimeout;
465         char d;
466         if (!len)
467                 return -1;
468         do {
469                 if ((c->streamid > -1) || (c->trans && (c->trans->streamid > -1))) {
470                         d = ast_waitstream(c, AST_DIGIT_ANY);
471                         ast_stopstream(c);
472                         usleep(1000);
473                         if (!d)
474                                 d = ast_waitfordigit(c, to);
475                 } else {
476                         d = ast_waitfordigit(c, to);
477                 }
478                 if (d < 0)
479                         return -1;
480                 if (!strchr(enders, d))
481                         s[pos++] = d;
482                 if ((d == 0) || strchr(enders, d) || (pos >= len - 1)) {
483                         s[pos]='\0';
484                         return 0;
485                 }
486                 to = timeout;
487         } while(1);
488         /* Never reached */
489         return 0;
490 }