Version 0.1.1 from FTP
[asterisk/asterisk.git] / translate.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Translate via the use of pseudo channels
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 <asterisk/channel.h>
15 #include <asterisk/channel_pvt.h>
16 #include <asterisk/logger.h>
17 #include <asterisk/translate.h>
18 #include <asterisk/options.h>
19 #include <sys/socket.h>
20 #include <sys/time.h>
21 #include <unistd.h>
22 #include <stdlib.h>
23 #include <pthread.h>
24 #include <string.h>
25 #include <stdio.h>
26
27 static char *type = "Trans";
28
29 static pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER;
30 static struct ast_translator *list = NULL;
31
32 struct ast_translator_dir {
33         struct ast_translator *step;    /* Next step translator */
34         int cost;                                               /* Complete cost to destination */
35 };
36
37 static struct ast_translator_dir tr_matrix[MAX_FORMAT][MAX_FORMAT];
38
39 struct ast_trans_pvt {
40         struct ast_translator *step;
41         struct ast_translator_pvt *state;
42         struct ast_trans_pvt *next;
43 };
44
45
46 static int powerof(int d)
47 {
48         int x;
49         for (x = 0; x < 32; x++)
50                 if ((1 << x) & d)
51                         return x;
52         ast_log(LOG_WARNING, "Powerof %d: No power??\n", d);
53         return -1;
54 }
55
56 struct translator_pvt {
57         /* Sockets for communication */
58         int comm[2];
59         struct ast_trans_pvt *system;
60         struct ast_trans_pvt *rsystem;
61         struct timeval lastpass;
62         pthread_t       threadid;
63 };
64
65 static int translator_hangup(struct ast_channel *chan)
66 {
67         ast_log(LOG_WARNING, "Explicit hangup on '%s' not recommended!  Call translator_destroy() instead.\n", chan->name);
68         chan->master->trans = NULL;
69         ast_hangup(chan->master);
70         chan->master = NULL;
71         return 0;
72 }
73
74 static int translator_send_digit(struct ast_channel *chan, char digit)
75 {
76         /* Pass digits right along */
77         if (chan->master->pvt->send_digit)
78                 return chan->master->pvt->send_digit(chan->master, digit);
79         return -1;
80 }
81
82 static int translator_call(struct ast_channel *chan, char *addr, int timeout)
83 {
84         if (chan->master->pvt->call)
85                 return chan->master->pvt->call(chan->master, addr, timeout);
86         return -1;
87 }
88
89 static int translator_answer(struct ast_channel *chan)
90 {
91         if (chan->master->pvt->answer)
92                 return chan->master->pvt->answer(chan->master);
93         return -1;
94 }
95
96 void ast_translator_free_path(struct ast_trans_pvt *p)
97 {
98         struct ast_trans_pvt *pl;
99         while(p) {
100                 pl = p;
101                 p = p->next;
102                 if (pl->state && pl->step->destroy)
103                         pl->step->destroy(pl->state);
104                 free(pl);
105         }
106 }
107
108 static void ast_translator_free(struct translator_pvt *pvt)
109 {
110         ast_translator_free_path(pvt->system);
111         ast_translator_free_path(pvt->rsystem);
112         if (pvt->comm[0] > -1)
113                 close(pvt->comm[0]);
114         if (pvt->comm[1] > -1)
115                 close(pvt->comm[1]);
116         free(pvt);
117 }
118
119 struct ast_trans_pvt *ast_translator_build_path(int source, int dest)
120 {
121         struct ast_trans_pvt *tmpr = NULL, *tmp = NULL;
122         /* One of the hardest parts:  Build a set of translators based upon
123            the given source and destination formats */
124         source = powerof(source);
125         dest = powerof(dest);
126         while(source != dest) {
127                 if (tr_matrix[source][dest].step) {
128                         if (tmp) {
129                                 tmp->next = malloc(sizeof(struct ast_trans_pvt));
130                                 tmp = tmp->next;
131                         } else
132                                 tmp = malloc(sizeof(struct ast_trans_pvt));
133
134                                 
135                         if (tmp) {
136                                 tmp->next = NULL;
137                                 tmp->step = tr_matrix[source][dest].step;
138                                 tmp->state = tmp->step->new();
139                                 if (!tmp->state) {
140                                         free(tmp);
141                                         tmp = NULL;
142                                 }
143                                 /* Set the root, if it doesn't exist yet... */
144                                 if (!tmpr)
145                                         tmpr = tmp;
146                                 /* Keep going if this isn't the final destination */
147                                 source = tmp->step->dstfmt;
148                         } else {
149                                 /* XXX This could leak XXX */
150                                 ast_log(LOG_WARNING, "Out of memory\n");
151                                 return NULL;
152                         }
153                 }
154         }
155         return tmpr;
156 }
157
158 static struct ast_frame *fd_read(int fd)
159 {
160         char buf[4096];
161         int res;
162         struct ast_frame *f = (struct ast_frame *)buf;
163         /* Read a frame directly from there.  They're always in the
164            right format. */
165         
166         if (read(fd, buf, sizeof(struct ast_frame)) 
167                                                 == sizeof(struct ast_frame)) {
168                 /* read the frame header */
169                 f->mallocd = 0;
170                 /* Re-write data position */
171                 f->data = buf + sizeof(struct ast_frame) + AST_FRIENDLY_OFFSET;
172                 f->offset = AST_FRIENDLY_OFFSET;
173                 /* Forget about being mallocd */
174                 f->mallocd = 0;
175                 /* Re-write the source */
176                 f->src = __FUNCTION__;
177                 if (f->datalen > sizeof(buf) - sizeof(struct ast_frame) - AST_FRIENDLY_OFFSET) {
178                         /* Really bad read */
179                         ast_log(LOG_WARNING, "Strange read (%d bytes)\n", f->datalen);
180                         return NULL;
181                 }
182                 if (f->datalen) {
183                         if ((res = read(fd, f->data, f->datalen)) != f->datalen) {
184                                 /* Bad read */
185                                 ast_log(LOG_WARNING, "How very strange, expected %d, got %d\n", f->datalen, res);
186                                 return NULL;
187                         }
188                 }
189                 return ast_frisolate(f);
190         } else if (option_debug)
191                 ast_log(LOG_DEBUG, "NULL or invalid header\n");
192         /* Null if there was an error */
193         return NULL;
194 }
195
196 static struct ast_frame *translator_read(struct ast_channel *chan)
197 {
198         return fd_read(chan->fd);
199 }
200
201 static int fd_write(int fd, struct ast_frame *frame)
202 {
203         /* Write the frame exactly */
204         if (write(fd, frame, sizeof(struct ast_frame)) != sizeof(struct ast_frame)) {
205                 ast_log(LOG_WARNING, "Write error\n");
206                 return -1;
207         }
208         if (write(fd, frame->data, frame->datalen) != frame->datalen) {
209                 ast_log(LOG_WARNING, "Write error\n");
210                 return -1;
211         }
212         return 0;
213 }
214
215 static int translator_write(struct ast_channel *chan, struct ast_frame *frame)
216 {
217         return fd_write(chan->fd, frame);
218 }
219
220 struct ast_frame_chain *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f)
221 {
222         struct ast_trans_pvt *p;
223         struct ast_frame *out;
224         struct ast_frame_chain *outc = NULL, *prev = NULL, *cur;
225         p = path;
226         /* Feed the first frame into the first translator */
227         p->step->framein(p->state, f);
228         while(p) {
229                 /* Read all the frames from the current translator */
230                 while((out = p->step->frameout(p->state)))  {
231                         if (p->next) {
232                                 /* Feed to next layer */
233                                 p->next->step->framein(p->next->state, out);
234                         } else {
235                                 /* Last layer -- actually do something */
236                                 cur = malloc(sizeof(struct ast_frame_chain));
237                                 if (!cur) {
238                                         /* XXX Leak majorly on a problem XXX */
239                                         ast_log(LOG_WARNING, "Out of memory\n");
240                                         return NULL;
241                                 }
242                                 if (prev) 
243                                         prev->next = cur;
244                                 else
245                                         outc = cur;
246                                 cur->fr = ast_frisolate(out);
247                                 cur->next = NULL;
248                                 if (prev)
249                                         prev = prev->next;
250                                 else
251                                         prev = outc;
252                         }
253                 }
254                 p = p->next;
255         }
256         return outc;
257 }
258
259 #define FUDGE 2
260
261 static void translator_apply(struct ast_trans_pvt *path, struct ast_frame *f, int fd, struct ast_channel *c, struct timeval *last)
262 {
263         struct ast_trans_pvt *p;
264         struct ast_frame *out;
265         struct timeval tv;
266         int ms;
267         p = path;
268         /* Feed the first frame into the first translator */
269         p->step->framein(p->state, f);
270         while(p) {
271                 /* Read all the frames from the current translator */
272                 while((out = p->step->frameout(p->state)))  {
273                         if (p->next) {
274                                 /* Feed to next layer */
275                                 p->next->step->framein(p->next->state, out);
276                         } else {
277                                 /* Delay if needed */
278                                 if (last->tv_sec || last->tv_usec) {
279                                         gettimeofday(&tv, NULL);
280                                         ms = 1000 * (tv.tv_sec - last->tv_sec) +
281                                                 (tv.tv_usec - last->tv_usec) / 1000;
282                                         if (ms + FUDGE < out->timelen) 
283                                                 usleep((out->timelen - ms - FUDGE) * 1000);
284                                         last->tv_sec = tv.tv_sec;
285                                         last->tv_usec = tv.tv_usec;
286                                 }
287                                 if (c)
288                                         ast_write(c, out);
289                                 else
290                                         fd_write(fd, out);
291                         }
292                         ast_frfree(out);
293                 }
294                 p = p->next;
295         }
296 }
297
298 static void *translator_thread(void *data)
299 {
300         struct ast_channel *real = data;
301         struct ast_frame *f;
302         int ms = -1;
303         struct translator_pvt *pvt = NULL;
304         int fd = -1;
305         int fds[2];
306         int res;
307         /* Read from the real, translate, write as necessary to the fake */
308         for(;;) {
309                 /* Break here if need be */
310                 pthread_testcancel();
311                 if (!real->trans) {
312                         ast_log(LOG_WARNING, "No translator anymore\n");
313                         break;
314                 }
315                 pvt = real->trans->pvt->pvt;
316                 fd = pvt->comm[1];
317                 fds[0] = fd;
318                 fds[1] = real->fd;
319                 CHECK_BLOCKING(real);
320                 res = ast_waitfor_n_fd(fds, 2, &ms);
321                 real->blocking = 0;
322                 /* Or we can die here, that's fine too */
323                 pthread_testcancel();
324                 if (res >= 0) {
325                         if (res == real->fd) {
326                                 f = ast_read(real);
327                                 if (!f) {
328                                         if (option_debug)
329                                                 ast_log(LOG_DEBUG, "Empty frame\n");
330                                         break;
331                                 }
332                                 if (f->frametype ==  AST_FRAME_VOICE) {
333                                         if (pvt->system)
334                                                 translator_apply(pvt->system, f, fd, NULL, &pvt->lastpass);
335                                 } else {
336                                         /* If it's not voice, just pass it along */
337                                         fd_write(fd, f);
338                                 }
339                                 ast_frfree(f);
340                         } else {
341                                 f = fd_read(res);
342                                 if (!f) {
343                                         if (option_debug)
344                                                 ast_log(LOG_DEBUG, "Empty (hangup) frame\n");
345                                         break;
346                                 }
347                                 
348                                 if (f->frametype == AST_FRAME_VOICE) {
349                                         if (pvt->rsystem)
350                                                 translator_apply(pvt->rsystem, f, -1, real, &pvt->lastpass);
351                                 } else {
352                                         ast_write(real, f);
353                                 }
354                                 ast_frfree(f);
355                         }
356                 } else {
357                         ast_log(LOG_DEBUG, "Waitfor returned non-zero\n");
358                         break;
359                 }
360         }
361         if (pvt)
362                 pvt->comm[1] = -1;
363         if (fd > -1) {
364                 /* Write a bogus frame */
365                 write(fd, data, 1);
366                 close(fd);
367         }
368         return NULL;
369 }
370
371 struct ast_channel *ast_translator_create(struct ast_channel *real, int format, int direction)
372 {
373         struct ast_channel *tmp;
374         struct translator_pvt *pvt;
375         if (real->trans) {
376                 ast_log(LOG_WARNING, "Translator already exists on '%s'\n", real->name);
377                 return NULL;
378         }
379         if (!(pvt = malloc(sizeof(struct translator_pvt)))) {
380                 ast_log(LOG_WARNING, "Unable to allocate private translator on '%s'\n", real->name);
381                 return NULL;
382         }
383         pvt->comm[0] = -1;
384         pvt->comm[1] = -1;
385         pvt->lastpass.tv_usec = 0;
386         pvt->lastpass.tv_sec = 0;
387         if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pvt->comm)) {
388                 ast_log(LOG_WARNING, "Unable to create UNIX domain socket on '%s'\n", real->name);
389                 ast_translator_free(pvt);
390         }
391         /* In to the system */
392         if (direction & AST_DIRECTION_IN)
393                 pvt->system = ast_translator_build_path(real->format, format);
394         else
395                 pvt->system = NULL;
396         /* Out from the system */
397         if (direction & AST_DIRECTION_OUT)
398                 pvt->rsystem = ast_translator_build_path(format, real->format);
399         else
400                 pvt->rsystem = NULL;
401         if (!pvt->system && !pvt->rsystem) {
402                 ast_log(LOG_WARNING, "Unable to build a translation path for %s (%d to %d)\n", real->name, real->format, format);
403                 ast_translator_free(pvt);
404                 return NULL;
405         }
406         if (!pvt->system && (direction & AST_DIRECTION_IN)) {
407                 ast_log(LOG_WARNING, "Translation path for '%s' is one-way (reverse)\n", real->name);
408                 ast_translator_free(pvt);
409                 return NULL;
410         }
411         if (!pvt->rsystem && (direction & AST_DIRECTION_OUT)) {
412                 ast_log(LOG_WARNING, "Translation path for '%s' is one-way (forward)\n", real->name);
413                 ast_translator_free(pvt);
414                 return NULL;
415         }
416         if ((tmp = ast_channel_alloc())) {
417                 snprintf(tmp->name, sizeof(tmp->name), "%s/Translate:%d", real->name, format);
418                 tmp->type = type;
419                 tmp->fd = pvt->comm[0];
420                 tmp->format = format;
421                 tmp->state = real->state;
422                 tmp->rings = 0;
423                 tmp->pvt->pvt = pvt;
424                 tmp->master = real;
425                 tmp->pvt->send_digit = translator_send_digit;
426                 tmp->pvt->call = translator_call;
427                 tmp->pvt->hangup = translator_hangup;
428                 tmp->pvt->answer = translator_answer;
429                 tmp->pvt->read = translator_read;
430                 tmp->pvt->write = translator_write;
431                 tmp->pvt->pvt = pvt;
432                 real->trans = tmp;
433                 if (option_verbose > 2)
434                         ast_verbose(VERBOSE_PREFIX_3 "Created translator %s\n", tmp->name);
435                 if (pthread_create(&pvt->threadid, NULL, translator_thread, real) < 0) {
436                         ast_translator_destroy(tmp);
437                         tmp = NULL;
438                         ast_log(LOG_WARNING, "Failed to start thread\n");
439                 }
440         } else {
441                 ast_translator_free(pvt);
442                 ast_log(LOG_WARNING, "Unable to allocate channel\n");
443         }
444         return tmp;
445
446
447 static void rebuild_matrix()
448 {
449         struct ast_translator *t;
450         int changed;
451         int x,y,z;
452         if (option_debug)
453                 ast_log(LOG_DEBUG, "Reseting translation matrix\n");
454         /* Use the list of translators to build a translation matrix */
455         bzero(tr_matrix, sizeof(tr_matrix));
456         t = list;
457         while(t) {
458                 if (!tr_matrix[t->srcfmt][t->dstfmt].step ||
459                      tr_matrix[t->srcfmt][t->dstfmt].cost > t->cost) {
460                         tr_matrix[t->srcfmt][t->dstfmt].step = t;
461                         tr_matrix[t->srcfmt][t->dstfmt].cost = t->cost;
462                 }
463                 t = t->next;
464         }
465         do {
466                 changed = 0;
467                 /* Don't you just love O(N^3) operations? */
468                 for (x=0; x< MAX_FORMAT; x++)                           /* For each source format */
469                         for (y=0; y < MAX_FORMAT; y++)                  /* And each destination format */
470                                 if (x != y)                                                     /* Except ourselves, of course */
471                                         for (z=0; z < MAX_FORMAT; z++)  /* And each format it might convert to */
472                                                 if ((x!=z) && (y!=z))           /* Don't ever convert back to us */
473                                                         if (tr_matrix[x][y].step && /* We can convert from x to y */
474                                                                 tr_matrix[y][z].step && /* And from y to z and... */
475                                                                 (!tr_matrix[x][z].step ||       /* Either there isn't an x->z conversion */
476                                                                 (tr_matrix[x][y].cost + 
477                                                                  tr_matrix[y][z].cost < /* Or we're cheaper than the existing */
478                                                                  tr_matrix[x][z].cost)  /* solution */
479                                                              )) {
480                                                                                         /* We can get from x to z via y with a cost that
481                                                                                            is the sum of the transition from x to y and
482                                                                                            from y to z */
483                                                                  
484                                                                         tr_matrix[x][z].step = tr_matrix[x][y].step;
485                                                                         tr_matrix[x][z].cost = tr_matrix[x][y].cost + 
486                                                                                                                    tr_matrix[y][z].cost;
487                                                                         if (option_debug)
488                                                                                 ast_log(LOG_DEBUG, "Discovered %d cost path from %d to %d, via %d\n", tr_matrix[x][z].cost, x, z, y);
489                                                                         changed++;
490                                                                  }
491                 
492         } while (changed);
493 }
494
495 static void calc_cost(struct ast_translator *t)
496 {
497         int sofar=0;
498         struct ast_translator_pvt *pvt;
499         struct ast_frame *f, *out;
500         struct timeval start, finish;
501         int cost;
502         /* If they don't make samples, give them a terrible score */
503         if (!t->sample) {
504                 ast_log(LOG_WARNING, "Translator '%s' does not produce sample frames.\n", t->name);
505                 t->cost = 99999;
506                 return;
507         }
508         pvt = t->new();
509         if (!pvt) {
510                 ast_log(LOG_WARNING, "Translator '%s' appears to be broken and will probably fail.\n", t->name);
511                 t->cost = 99999;
512                 return;
513         }
514         gettimeofday(&start, NULL);
515         /* Call the encoder until we've processed one second of time */
516         while(sofar < 1000) {
517                 f = t->sample();
518                 if (!f) {
519                         ast_log(LOG_WARNING, "Translator '%s' failed to produce a sample frame.\n", t->name);
520                         t->destroy(pvt);
521                         t->cost = 99999;
522                         return;
523                 }
524                 t->framein(pvt, f);
525                 ast_frfree(f);
526                 while((out = t->frameout(pvt))) {
527                         sofar += out->timelen;
528                         ast_frfree(out);
529                 }
530         }
531         gettimeofday(&finish, NULL);
532         t->destroy(pvt);
533         cost = (finish.tv_sec - start.tv_sec) * 1000 + (finish.tv_usec - start.tv_usec) / 1000;
534         t->cost = cost;
535 }
536
537 int ast_register_translator(struct ast_translator *t)
538 {
539         t->srcfmt = powerof(t->srcfmt);
540         t->dstfmt = powerof(t->dstfmt);
541         if ((t->srcfmt >= MAX_FORMAT) || (t->dstfmt >= MAX_FORMAT)) {
542                 ast_log(LOG_WARNING, "Format %d is larger than MAX_FORMAT\n", t->srcfmt);
543                 return -1;
544         }
545         calc_cost(t);
546         if (option_verbose > 1)
547                 ast_verbose(VERBOSE_PREFIX_2 "Registered translator '%s' from format %d to %d, cost %d\n", t->name, t->srcfmt, t->dstfmt, t->cost);
548         pthread_mutex_lock(&list_lock);
549         t->next = list;
550         list = t;
551         rebuild_matrix();
552         pthread_mutex_unlock(&list_lock);
553         return 0;
554 }
555
556 int ast_unregister_translator(struct ast_translator *t)
557 {
558         struct ast_translator *u, *ul = NULL;
559         pthread_mutex_lock(&list_lock);
560         u = list;
561         while(u) {
562                 if (u == t) {
563                         if (ul)
564                                 ul->next = u->next;
565                         else
566                                 list = u->next;
567                         break;
568                 }
569                 u = u->next;
570         }
571         rebuild_matrix();
572         pthread_mutex_unlock(&list_lock);
573         return (u ? 0 : -1);
574 }
575
576 void ast_translator_destroy(struct ast_channel *trans)
577 {
578         struct translator_pvt *pvt;
579         if (!trans->master) {
580                 ast_log(LOG_WARNING, "Translator is not part of a real channel?\n");
581                 return;
582         }
583         if (trans->master->trans != trans) {
584                 ast_log(LOG_WARNING, "Translator is not the right one!?!?\n");
585                 return;
586         }
587         trans->master->trans = NULL;
588         pvt = trans->pvt->pvt;
589         /* Cancel the running translator thread */
590         pthread_cancel(pvt->threadid);
591         pthread_join(pvt->threadid, NULL);
592         ast_translator_free(pvt);
593         trans->pvt->pvt = NULL;
594         if (option_verbose > 2)
595                 ast_verbose(VERBOSE_PREFIX_3 "Destroyed translator %s\n", trans->name);
596         ast_channel_free(trans);
597 }
598
599 int ast_translator_best_choice(int dst, int srcs)
600 {
601         /* Calculate our best source format, given costs, and a desired destination */
602         int x;
603         int best=-1;
604         int besttime=999999999;
605         dst = powerof(dst);
606         pthread_mutex_lock(&list_lock);
607         for (x=0;x<MAX_FORMAT;x++) {
608                 if (tr_matrix[x][dst].step &&   /* There's a step */
609                     (tr_matrix[x][dst].cost < besttime) && /* We're better than what exists now */
610                         (srcs & (1 << x)))                      /* x is a valid source format */
611                         {
612                                 best = 1 << x;
613                                 besttime = tr_matrix[x][dst].cost;
614                         }
615                                 
616         }
617         pthread_mutex_unlock(&list_lock);
618         return best;
619 }