Version 0.1.6 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->exten, "s", sizeof(tmp->exten));
130                                 tmp->priority=1;
131                                 tmp->next = channels;
132                                 channels= tmp;
133                         } else {
134                                 ast_log(LOG_WARNING, "Unable to create schedule context\n");
135                                 free(tmp);
136                                 tmp = NULL;
137                         }
138                 } else {
139                         ast_log(LOG_WARNING, "Out of memory\n");
140                         free(tmp);
141                         tmp = NULL;
142                 }
143         } else 
144                 ast_log(LOG_WARNING, "Out of memory\n");
145         PTHREAD_MUTEX_UNLOCK(&chlock);
146         return tmp;
147 }
148
149 struct ast_channel *ast_channel_walk(struct ast_channel *prev)
150 {
151         struct ast_channel *l, *ret=NULL;
152         PTHREAD_MUTEX_LOCK(&chlock);
153         l = channels;
154         if (!prev) {
155                 PTHREAD_MUTEX_UNLOCK(&chlock);
156                 return l;
157         }
158         while(l) {
159                 if (l == prev)
160                         ret = l->next;
161                 l = l->next;
162         }
163         PTHREAD_MUTEX_UNLOCK(&chlock);
164         return ret;
165         
166 }
167
168 void ast_channel_free(struct ast_channel *chan)
169 {
170         struct ast_channel *last=NULL, *cur;
171         PTHREAD_MUTEX_LOCK(&chlock);
172         cur = channels;
173         while(cur) {
174                 if (cur == chan) {
175                         if (last)
176                                 last->next = cur->next;
177                         else
178                                 channels = cur->next;
179                         break;
180                 }
181                 last = cur;
182                 cur = cur->next;
183         }
184         if (!cur)
185                 ast_log(LOG_WARNING, "Unable to find channel in list\n");
186         if (chan->pvt->pvt)
187                 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
188         if (chan->trans)
189                 ast_log(LOG_WARNING, "Hard hangup called on '%s' while a translator is in place!  Expect a failure.\n", chan->name);
190         if (chan->pbx) 
191                 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
192         if (chan->dnid)
193                 free(chan->dnid);
194         if (chan->callerid)
195                 free(chan->callerid);   
196         pthread_mutex_destroy(&chan->lock);
197         free(chan);
198         PTHREAD_MUTEX_UNLOCK(&chlock);
199 }
200
201 int ast_softhangup(struct ast_channel *chan)
202 {
203         int res = 0;
204         if (chan->stream)
205                 ast_stopstream(chan);
206         if (option_debug)
207                 ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
208         if (chan->trans)
209                 ast_log(LOG_WARNING, "Soft hangup called on '%s' while a translator is in place!  Expect a failure.\n", chan->name);
210         if (chan->pvt->hangup)
211                 res = chan->pvt->hangup(chan);
212         if (chan->pvt->pvt)
213                 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
214         if (chan->pbx) 
215                 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);        
216         /* Interrupt any select call or such */
217         if (chan->blocking)
218                 pthread_kill(chan->blocker, SIGURG);
219         return res;
220 }
221
222 int ast_hangup(struct ast_channel *chan)
223 {
224         int res = 0;
225         if (chan->stream)
226                 ast_stopstream(chan);
227         if (chan->sched)
228                 sched_context_destroy(chan->sched);
229         if (chan->blocking)
230                 ast_log(LOG_WARNING, "Hard hangup called, while fd is blocking!  Expect a failure\n");
231         if (option_debug)
232                 ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
233         if (chan->pvt->hangup)
234                 res = chan->pvt->hangup(chan);
235         ast_channel_free(chan);
236         return res;
237 }
238
239 void ast_channel_unregister(char *type)
240 {
241         struct chanlist *chan, *last=NULL;
242         if (option_debug)
243                 ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", type);
244         if (PTHREAD_MUTEX_LOCK(&chlock)) {
245                 ast_log(LOG_WARNING, "Unable to lock channel list\n");
246                 return;
247         }
248         chan = backends;
249         while(chan) {
250                 if (!strcasecmp(chan->type, type)) {
251                         if (last)
252                                 last->next = chan->next;
253                         else
254                                 backends = backends->next;
255                         free(chan);
256                         PTHREAD_MUTEX_UNLOCK(&chlock);
257                         return;
258                 }
259                 last = chan;
260                 chan = chan->next;
261         }
262         PTHREAD_MUTEX_UNLOCK(&chlock);
263 }
264
265 int ast_answer(struct ast_channel *chan)
266 {
267         /* Answer the line, if possible */
268         if (chan->state == AST_STATE_RING) {
269                 if (chan->pvt->answer)
270                         return chan->pvt->answer(chan);
271         }
272         return 0;
273 }
274
275 int ast_waitfor_n_fd(int *fds, int n, int *ms)
276 {
277         /* Wait for x amount of time on a file descriptor to have input.  */
278         struct timeval tv;
279         fd_set rfds, efds;
280         int res;
281         int x, max=-1;
282         int winner = -1;
283         
284         tv.tv_sec = *ms / 1000;
285         tv.tv_usec = (*ms % 1000) * 1000;
286         FD_ZERO(&rfds);
287         FD_ZERO(&efds);
288         for (x=0;x<n;x++) {
289                 FD_SET(fds[x], &rfds);
290                 FD_SET(fds[x], &efds);
291                 if (fds[x] > max)
292                         max = fds[x];
293         }
294         if (*ms >= 0) 
295                 res = select(max + 1, &rfds, NULL, &efds, &tv);
296         else
297                 res = select(max + 1, &rfds, NULL, &efds, NULL);
298         for (x=0;x<n;x++) {
299                 if ((FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && (winner < 0))
300                         winner = fds[x];
301         }
302         *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
303         if (res < 0)
304                 *ms = -10;
305         return winner;
306 }
307
308 struct ast_channel *ast_waitfor_n(struct ast_channel **c, int n, int *ms)
309 {
310         /* Wait for x amount of time on a file descriptor to have input.  */
311         struct timeval tv;
312         fd_set rfds, efds;
313         int res;
314         int x, max=-1;
315         struct ast_channel *winner = NULL;
316         
317         tv.tv_sec = *ms / 1000;
318         tv.tv_usec = (*ms % 1000) * 1000;
319         FD_ZERO(&rfds);
320         FD_ZERO(&efds);
321         for (x=0;x<n;x++) {
322                 FD_SET(c[x]->fd, &rfds);
323                 FD_SET(c[x]->fd, &efds);
324                 CHECK_BLOCKING(c[x]);
325                 if (c[x]->fd > max)
326                         max = c[x]->fd;
327         }
328         if (*ms >= 0) 
329                 res = select(max + 1, &rfds, NULL, &efds, &tv);
330         else
331                 res = select(max + 1, &rfds, NULL, &efds, NULL);
332         for (x=0;x<n;x++) {
333                 c[x]->blocking = 0;
334                 if ((FD_ISSET(c[x]->fd, &rfds) || FD_ISSET(c[x]->fd, &efds)) && !winner)
335                         winner = c[x];
336         }
337         *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
338         if (res < 0)
339                 *ms = -10;
340         return winner;
341 }
342
343 int ast_waitfor(struct ast_channel *c, int ms)
344 {
345         if (ast_waitfor_n(&c, 1, &ms)) {
346                 if (ms < 0)
347                         return -ms;
348                 return ms;
349         }
350         /* Error if ms < 0 */
351         if (ms < 0) 
352                 return -1;
353         return 0;
354 }
355
356 char ast_waitfordigit(struct ast_channel *c, int ms)
357 {
358         struct ast_frame *f;
359         char result = 0;
360         /* Wait for a digit, no more than ms milliseconds total. */
361         while(ms && !result) {
362                 ms = ast_waitfor(c, ms);
363                 if (ms < 0) /* Error */
364                         result = -1; 
365                 else if (ms > 0) {
366                         /* Read something */
367                         f = ast_read(c);
368                         if (f) {
369                                 if (f->frametype == AST_FRAME_DTMF) 
370                                         result = f->subclass;
371                                 ast_frfree(f);
372                         } else
373                                 result = -1;
374                 }
375         }
376         return result;
377 }
378
379 struct ast_frame *ast_read(struct ast_channel *chan)
380 {
381         struct ast_frame *f = NULL;
382         chan->blocker = pthread_self();
383         if (chan->pvt->read)
384                 f = chan->pvt->read(chan);
385         else
386                 ast_log(LOG_WARNING, "No read routine on channel %s\n", chan);
387         return f;
388 }
389
390 int ast_write(struct ast_channel *chan, struct ast_frame *fr)
391 {
392         int res = -1;
393         CHECK_BLOCKING(chan);
394         switch(fr->frametype) {
395         case AST_FRAME_CONTROL:
396                 /* XXX Interpret control frames XXX */
397                 ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n");
398                 break;
399         case AST_FRAME_DTMF:
400                 
401                 if (chan->pvt->send_digit)
402                         res = chan->pvt->send_digit(chan, fr->subclass);
403                 break;
404         default:
405                 if (chan->pvt->write)
406                         res = chan->pvt->write(chan, fr);
407         }
408         chan->blocking = 0;
409         return res;
410 }
411
412 struct ast_channel *ast_request(char *type, int format, void *data)
413 {
414         struct chanlist *chan;
415         struct ast_channel *c = NULL;
416         if (PTHREAD_MUTEX_LOCK(&chlock)) {
417                 ast_log(LOG_WARNING, "Unable to lock channel list\n");
418                 return NULL;
419         }
420         chan = backends;
421         while(chan) {
422                 if (!strcasecmp(type, chan->type)) {
423                         if (!(chan->capabilities & format)) {
424                                 format = ast_translator_best_choice(format, chan->capabilities);
425                         }
426                         PTHREAD_MUTEX_UNLOCK(&chlock);
427                         if (chan->requester)
428                                 c = chan->requester(type, format, data);
429                         return c;
430                 }
431                 chan = chan->next;
432         }
433         if (!chan)
434                 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
435         PTHREAD_MUTEX_UNLOCK(&chlock);
436         return c;
437 }
438
439 int ast_call(struct ast_channel *chan, char *addr, int timeout) 
440 {
441         /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 
442            If the remote end does not answer within the timeout, then do NOT hang up, but 
443            return anyway.  */
444         int res = -1;
445         if (chan->pvt->call)
446                 res = chan->pvt->call(chan, addr, timeout);
447         return res;
448 }
449
450 int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
451 {
452         int pos=0;
453         int to = ftimeout;
454         char d;
455         if (!len)
456                 return -1;
457         do {
458                 if ((c->streamid > -1) || (c->trans && (c->trans->streamid > -1))) {
459                         d = ast_waitstream(c, AST_DIGIT_ANY);
460                         ast_stopstream(c);
461                         usleep(1000);
462                         if (!d)
463                                 d = ast_waitfordigit(c, to);
464                 } else {
465                         d = ast_waitfordigit(c, to);
466                 }
467                 if (d < 0)
468                         return -1;
469                 if (!strchr(enders, d))
470                         s[pos++] = d;
471                 if ((d == 0) || strchr(enders, d) || (pos >= len - 1)) {
472                         s[pos]='\0';
473                         return 0;
474                 }
475                 to = timeout;
476         } while(1);
477         /* Never reached */
478         return 0;
479 }