res_pjsip/res_pjsip_callerid: NULL check on caller id name string
[asterisk/asterisk.git] / codecs / codec_dahdi.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * DAHDI native transcoding support
5  *
6  * Copyright (C) 1999 - 2008, Digium, Inc.
7  *
8  * Mark Spencer <markster@digium.com>
9  * Kevin P. Fleming <kpfleming@digium.com>
10  *
11  * See http://www.asterisk.org for more information about
12  * the Asterisk project. Please do not directly contact
13  * any of the maintainers of this project for assistance;
14  * the project provides a web site, mailing lists and IRC
15  * channels for your use.
16  *
17  * This program is free software, distributed under the terms of
18  * the GNU General Public License Version 2. See the LICENSE file
19  * at the top of the source tree.
20  */
21
22 /*! \file
23  *
24  * \brief Translate between various formats natively through DAHDI transcoding
25  *
26  * \ingroup codecs
27  */
28
29 /*** MODULEINFO
30         <support_level>core</support_level>
31         <depend>dahdi</depend>
32  ***/
33
34 #include "asterisk.h"
35 #include <stdbool.h>
36
37 #include <poll.h>
38 #include <fcntl.h>
39 #include <netinet/in.h>
40 #include <sys/ioctl.h>
41 #include <sys/mman.h>
42 #include <dahdi/user.h>
43
44 #include "asterisk/lock.h"
45 #include "asterisk/translate.h"
46 #include "asterisk/config.h"
47 #include "asterisk/module.h"
48 #include "asterisk/cli.h"
49 #include "asterisk/channel.h"
50 #include "asterisk/utils.h"
51 #include "asterisk/linkedlists.h"
52 #include "asterisk/ulaw.h"
53 #include "asterisk/format_compatibility.h"
54
55 #define BUFFER_SIZE 8000
56
57 #define G723_SAMPLES 240
58 #define G729_SAMPLES 160
59 #define ULAW_SAMPLES 160
60
61 /* Defines from DAHDI. */
62 #ifndef DAHDI_FORMAT_MAX_AUDIO
63 /*! G.723.1 compression */
64 #define DAHDI_FORMAT_G723_1    (1 << 0)
65 /*! GSM compression */
66 #define DAHDI_FORMAT_GSM       (1 << 1)
67 /*! Raw mu-law data (G.711) */
68 #define DAHDI_FORMAT_ULAW      (1 << 2)
69 /*! Raw A-law data (G.711) */
70 #define DAHDI_FORMAT_ALAW      (1 << 3)
71 /*! ADPCM (G.726, 32kbps) */
72 #define DAHDI_FORMAT_G726      (1 << 4)
73 /*! ADPCM (IMA) */
74 #define DAHDI_FORMAT_ADPCM     (1 << 5)
75 /*! Raw 16-bit Signed Linear (8000 Hz) PCM */
76 #define DAHDI_FORMAT_SLINEAR   (1 << 6)
77 /*! LPC10, 180 samples/frame */
78 #define DAHDI_FORMAT_LPC10     (1 << 7)
79 /*! G.729A audio */
80 #define DAHDI_FORMAT_G729A     (1 << 8)
81 /*! SpeeX Free Compression */
82 #define DAHDI_FORMAT_SPEEX     (1 << 9)
83 /*! iLBC Free Compression */
84 #define DAHDI_FORMAT_ILBC      (1 << 10)
85 #endif
86
87 static struct channel_usage {
88         int total;
89         int encoders;
90         int decoders;
91 } channels;
92
93 #if defined(NOT_NEEDED)
94 /*!
95  * \internal
96  * \brief Convert DAHDI format bitfield to old Asterisk format bitfield.
97  * \since 13.0.0
98  *
99  * \param dahdi Bitfield from DAHDI to convert.
100  *
101  * \note They should be the same values but they don't have to be.
102  *
103  * \return Old Asterisk bitfield equivalent.
104  */
105 static uint64_t bitfield_dahdi2ast(unsigned dahdi)
106 {
107         uint64_t ast;
108
109         switch (dahdi) {
110         case DAHDI_FORMAT_G723_1:
111                 ast = AST_FORMAT_G723;
112                 break;
113         case DAHDI_FORMAT_GSM:
114                 ast = AST_FORMAT_GSM;
115                 break;
116         case DAHDI_FORMAT_ULAW:
117                 ast = AST_FORMAT_ULAW;
118                 break;
119         case DAHDI_FORMAT_ALAW:
120                 ast = AST_FORMAT_ALAW;
121                 break;
122         case DAHDI_FORMAT_G726:
123                 ast = AST_FORMAT_G726_AAL2;
124                 break;
125         case DAHDI_FORMAT_ADPCM:
126                 ast = AST_FORMAT_ADPCM;
127                 break;
128         case DAHDI_FORMAT_SLINEAR:
129                 ast = AST_FORMAT_SLIN;
130                 break;
131         case DAHDI_FORMAT_LPC10:
132                 ast = AST_FORMAT_LPC10;
133                 break;
134         case DAHDI_FORMAT_G729A:
135                 ast = AST_FORMAT_G729;
136                 break;
137         case DAHDI_FORMAT_SPEEX:
138                 ast = AST_FORMAT_SPEEX;
139                 break;
140         case DAHDI_FORMAT_ILBC:
141                 ast = AST_FORMAT_ILBC;
142                 break;
143         default:
144                 ast = 0;
145                 break;
146         }
147
148         return ast;
149 }
150 #endif  /* defined(NOT_NEEDED) */
151
152 /*!
153  * \internal
154  * \brief Get the ast_codec by DAHDI format.
155  * \since 13.0.0
156  *
157  * \param dahdi_fmt DAHDI specific codec identifier.
158  *
159  * \return Specified codec if exists otherwise NULL.
160  */
161 static const struct ast_codec *get_dahdi_codec(uint32_t dahdi_fmt)
162 {
163         const struct ast_codec *codec;
164
165         static const struct ast_codec dahdi_g723_1 = {
166                 .name = "g723",
167                 .type = AST_MEDIA_TYPE_AUDIO,
168                 .sample_rate = 8000,
169         };
170         static const struct ast_codec dahdi_gsm = {
171                 .name = "gsm",
172                 .type = AST_MEDIA_TYPE_AUDIO,
173                 .sample_rate = 8000,
174         };
175         static const struct ast_codec dahdi_ulaw = {
176                 .name = "ulaw",
177                 .type = AST_MEDIA_TYPE_AUDIO,
178                 .sample_rate = 8000,
179         };
180         static const struct ast_codec dahdi_alaw = {
181                 .name = "alaw",
182                 .type = AST_MEDIA_TYPE_AUDIO,
183                 .sample_rate = 8000,
184         };
185         static const struct ast_codec dahdi_g726 = {
186                 .name = "g726",
187                 .type = AST_MEDIA_TYPE_AUDIO,
188                 .sample_rate = 8000,
189         };
190         static const struct ast_codec dahdi_adpcm = {
191                 .name = "adpcm",
192                 .type = AST_MEDIA_TYPE_AUDIO,
193                 .sample_rate = 8000,
194         };
195         static const struct ast_codec dahdi_slinear = {
196                 .name = "slin",
197                 .type = AST_MEDIA_TYPE_AUDIO,
198                 .sample_rate = 8000,
199         };
200         static const struct ast_codec dahdi_lpc10 = {
201                 .name = "lpc10",
202                 .type = AST_MEDIA_TYPE_AUDIO,
203                 .sample_rate = 8000,
204         };
205         static const struct ast_codec dahdi_g729a = {
206                 .name = "g729",
207                 .type = AST_MEDIA_TYPE_AUDIO,
208                 .sample_rate = 8000,
209         };
210         static const struct ast_codec dahdi_speex = {
211                 .name = "speex",
212                 .type = AST_MEDIA_TYPE_AUDIO,
213                 .sample_rate = 8000,
214         };
215         static const struct ast_codec dahdi_ilbc = {
216                 .name = "ilbc",
217                 .type = AST_MEDIA_TYPE_AUDIO,
218                 .sample_rate = 8000,
219         };
220
221         switch (dahdi_fmt) {
222         case DAHDI_FORMAT_G723_1:
223                 codec = &dahdi_g723_1;
224                 break;
225         case DAHDI_FORMAT_GSM:
226                 codec = &dahdi_gsm;
227                 break;
228         case DAHDI_FORMAT_ULAW:
229                 codec = &dahdi_ulaw;
230                 break;
231         case DAHDI_FORMAT_ALAW:
232                 codec = &dahdi_alaw;
233                 break;
234         case DAHDI_FORMAT_G726:
235                 codec = &dahdi_g726;
236                 break;
237         case DAHDI_FORMAT_ADPCM:
238                 codec = &dahdi_adpcm;
239                 break;
240         case DAHDI_FORMAT_SLINEAR:
241                 codec = &dahdi_slinear;
242                 break;
243         case DAHDI_FORMAT_LPC10:
244                 codec = &dahdi_lpc10;
245                 break;
246         case DAHDI_FORMAT_G729A:
247                 codec = &dahdi_g729a;
248                 break;
249         case DAHDI_FORMAT_SPEEX:
250                 codec = &dahdi_speex;
251                 break;
252         case DAHDI_FORMAT_ILBC:
253                 codec = &dahdi_ilbc;
254                 break;
255         default:
256                 codec = NULL;
257                 break;
258         }
259
260         return codec;
261 }
262
263 static char *handle_cli_transcoder_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
264
265 static struct ast_cli_entry cli[] = {
266         AST_CLI_DEFINE(handle_cli_transcoder_show, "Display DAHDI transcoder utilization.")
267 };
268
269 struct translator {
270         struct ast_translator t;
271         uint32_t src_dahdi_fmt;
272         uint32_t dst_dahdi_fmt;
273         AST_LIST_ENTRY(translator) entry;
274 };
275
276 #ifndef container_of
277 #define container_of(ptr, type, member) \
278         ((type *)((char *)(ptr) - offsetof(type, member)))
279 #endif
280
281 static AST_LIST_HEAD_STATIC(translators, translator);
282
283 struct codec_dahdi_pvt {
284         int fd;
285         struct dahdi_transcoder_formats fmts;
286         unsigned int softslin:1;
287         unsigned int fake:2;
288         uint16_t required_samples;
289         uint16_t samples_in_buffer;
290         uint16_t samples_written_to_hardware;
291         uint8_t ulaw_buffer[1024];
292 };
293
294 /* Only used by a decoder */
295 static int ulawtolin(struct ast_trans_pvt *pvt, int samples)
296 {
297         struct codec_dahdi_pvt *dahdip = pvt->pvt;
298         int i = samples;
299         uint8_t *src = &dahdip->ulaw_buffer[0];
300         int16_t *dst = pvt->outbuf.i16 + pvt->datalen;
301
302         /* convert and copy in outbuf */
303         while (i--) {
304                 *dst++ = AST_MULAW(*src++);
305         }
306
307         return 0;
308 }
309
310 /* Only used by an encoder. */
311 static int lintoulaw(struct ast_trans_pvt *pvt, struct ast_frame *f)
312 {
313         struct codec_dahdi_pvt *dahdip = pvt->pvt;
314         int i = f->samples;
315         uint8_t *dst = &dahdip->ulaw_buffer[dahdip->samples_in_buffer];
316         int16_t *src = f->data.ptr;
317
318         if (dahdip->samples_in_buffer + i > sizeof(dahdip->ulaw_buffer)) {
319                 ast_log(LOG_ERROR, "Out of buffer space!\n");
320                 return -i;
321         }
322
323         while (i--) {
324                 *dst++ = AST_LIN2MU(*src++);
325         }
326
327         dahdip->samples_in_buffer += f->samples;
328         return 0;
329 }
330
331 static char *handle_cli_transcoder_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
332 {
333         struct channel_usage copy;
334
335         switch (cmd) {
336         case CLI_INIT:
337                 e->command = "transcoder show";
338                 e->usage =
339                         "Usage: transcoder show\n"
340                         "       Displays channel utilization of DAHDI transcoder(s).\n";
341                 return NULL;
342         case CLI_GENERATE:
343                 return NULL;
344         }
345
346         if (a->argc != 2)
347                 return CLI_SHOWUSAGE;
348
349         copy = channels;
350
351         if (copy.total == 0)
352                 ast_cli(a->fd, "No DAHDI transcoders found.\n");
353         else
354                 ast_cli(a->fd, "%d/%d encoders/decoders of %d channels are in use.\n", copy.encoders, copy.decoders, copy.total);
355
356         return CLI_SUCCESS;
357 }
358
359 static void dahdi_write_frame(struct codec_dahdi_pvt *dahdip, const uint8_t *buffer, const ssize_t count)
360 {
361         int res;
362         if (!count) return;
363         res = write(dahdip->fd, buffer, count);
364         if (-1 == res) {
365                 ast_log(LOG_ERROR, "Failed to write to transcoder: %s\n", strerror(errno));
366         }
367         if (count != res) {
368                 ast_log(LOG_ERROR, "Requested write of %zd bytes, but only wrote %d bytes.\n", count, res);
369         }
370 }
371
372 static int dahdi_encoder_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
373 {
374         struct codec_dahdi_pvt *dahdip = pvt->pvt;
375
376         if (!f->subclass.format) {
377                 /* We're just faking a return for calculation purposes. */
378                 dahdip->fake = 2;
379                 pvt->samples = f->samples;
380                 return 0;
381         }
382
383         /* Buffer up the packets and send them to the hardware if we
384          * have enough samples set up. */
385         if (dahdip->softslin) {
386                 if (lintoulaw(pvt, f)) {
387                          return -1;
388                 }
389         } else {
390                 /* NOTE:  If softslin support is not needed, and the sample
391                  * size is equal to the required sample size, we wouldn't
392                  * need this copy operation.  But at the time this was
393                  * written, only softslin is supported. */
394                 if (dahdip->samples_in_buffer + f->samples > sizeof(dahdip->ulaw_buffer)) {
395                         ast_log(LOG_ERROR, "Out of buffer space.\n");
396                         return -1;
397                 }
398                 memcpy(&dahdip->ulaw_buffer[dahdip->samples_in_buffer], f->data.ptr, f->samples);
399                 dahdip->samples_in_buffer += f->samples;
400         }
401
402         while (dahdip->samples_in_buffer >= dahdip->required_samples) {
403                 dahdi_write_frame(dahdip, dahdip->ulaw_buffer, dahdip->required_samples);
404                 dahdip->samples_written_to_hardware += dahdip->required_samples;
405                 dahdip->samples_in_buffer -= dahdip->required_samples;
406                 if (dahdip->samples_in_buffer) {
407                         /* Shift any remaining bytes down. */
408                         memmove(dahdip->ulaw_buffer, &dahdip->ulaw_buffer[dahdip->required_samples],
409                                 dahdip->samples_in_buffer);
410                 }
411         }
412         pvt->samples += f->samples;
413         pvt->datalen = 0;
414         return -1;
415 }
416
417 static void dahdi_wait_for_packet(int fd)
418 {
419         struct pollfd p = {0};
420         p.fd = fd;
421         p.events = POLLIN;
422         poll(&p, 1, 10);
423 }
424
425 static struct ast_frame *dahdi_encoder_frameout(struct ast_trans_pvt *pvt)
426 {
427         struct codec_dahdi_pvt *dahdip = pvt->pvt;
428         int res;
429
430         if (2 == dahdip->fake) {
431                 struct ast_frame frm = {
432                         .frametype = AST_FRAME_VOICE,
433                         .samples = dahdip->required_samples,
434                         .src = pvt->t->name,
435                 };
436
437                 dahdip->fake = 1;
438                 pvt->samples = 0;
439
440                 return ast_frisolate(&frm);
441         } else if (1 == dahdip->fake) {
442                 dahdip->fake = 0;
443                 return NULL;
444         }
445
446         if (dahdip->samples_written_to_hardware >= dahdip->required_samples) {
447                 dahdi_wait_for_packet(dahdip->fd);
448         }
449
450         res = read(dahdip->fd, pvt->outbuf.c + pvt->datalen, pvt->t->buf_size - pvt->datalen);
451         if (-1 == res) {
452                 if (EWOULDBLOCK == errno) {
453                         /* Nothing waiting... */
454                         return NULL;
455                 } else {
456                         ast_log(LOG_ERROR, "Failed to read from transcoder: %s\n", strerror(errno));
457                         return NULL;
458                 }
459         } else {
460                 pvt->f.datalen = res;
461                 pvt->f.samples = ast_codec_samples_count(&pvt->f);
462
463                 dahdip->samples_written_to_hardware =
464                   (dahdip->samples_written_to_hardware >= pvt->f.samples) ?
465                      dahdip->samples_written_to_hardware - pvt->f.samples : 0;
466
467                 pvt->samples = 0;
468                 pvt->datalen = 0;
469                 return ast_frisolate(&pvt->f);
470         }
471
472         /* Shouldn't get here... */
473         return NULL;
474 }
475
476 static int dahdi_decoder_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
477 {
478         struct codec_dahdi_pvt *dahdip = pvt->pvt;
479
480         if (!f->subclass.format) {
481                 /* We're just faking a return for calculation purposes. */
482                 dahdip->fake = 2;
483                 pvt->samples = f->samples;
484                 return 0;
485         }
486
487         if (!f->datalen) {
488                 if (f->samples != dahdip->required_samples) {
489                         ast_log(LOG_ERROR, "%d != %d %d\n", f->samples, dahdip->required_samples, f->datalen);
490                 }
491         }
492         dahdi_write_frame(dahdip, f->data.ptr, f->datalen);
493         dahdip->samples_written_to_hardware += f->samples;
494         pvt->samples += f->samples;
495         pvt->datalen = 0;
496         return -1;
497 }
498
499 static struct ast_frame *dahdi_decoder_frameout(struct ast_trans_pvt *pvt)
500 {
501         int res;
502         struct codec_dahdi_pvt *dahdip = pvt->pvt;
503
504         if (2 == dahdip->fake) {
505                 struct ast_frame frm = {
506                         .frametype = AST_FRAME_VOICE,
507                         .samples = dahdip->required_samples,
508                         .src = pvt->t->name,
509                 };
510
511                 dahdip->fake = 1;
512                 pvt->samples = 0;
513
514                 return ast_frisolate(&frm);
515         } else if (1 == dahdip->fake) {
516                 pvt->samples = 0;
517                 dahdip->fake = 0;
518                 return NULL;
519         }
520
521         if (dahdip->samples_written_to_hardware >= ULAW_SAMPLES) {
522                 dahdi_wait_for_packet(dahdip->fd);
523         }
524
525         /* Let's check to see if there is a new frame for us.... */
526         if (dahdip->softslin) {
527                 res = read(dahdip->fd, dahdip->ulaw_buffer, sizeof(dahdip->ulaw_buffer));
528         } else {
529                 res = read(dahdip->fd, pvt->outbuf.c + pvt->datalen, pvt->t->buf_size - pvt->datalen);
530         }
531
532         if (-1 == res) {
533                 if (EWOULDBLOCK == errno) {
534                         /* Nothing waiting... */
535                         return NULL;
536                 } else {
537                         ast_log(LOG_ERROR, "Failed to read from transcoder: %s\n", strerror(errno));
538                         return NULL;
539                 }
540         } else {
541                 if (dahdip->softslin) {
542                         ulawtolin(pvt, res);
543                         pvt->f.datalen = res * 2;
544                 } else {
545                         pvt->f.datalen = res;
546                 }
547                 pvt->datalen = 0;
548                 pvt->f.samples = res;
549                 pvt->samples = 0;
550                 dahdip->samples_written_to_hardware =
551                         (dahdip->samples_written_to_hardware >= res) ?
552                                 dahdip->samples_written_to_hardware - res : 0;
553
554                 return ast_frisolate(&pvt->f);
555         }
556
557         /* Shouldn't get here... */
558         return NULL;
559 }
560
561
562 static void dahdi_destroy(struct ast_trans_pvt *pvt)
563 {
564         struct codec_dahdi_pvt *dahdip = pvt->pvt;
565
566         switch (dahdip->fmts.dstfmt) {
567         case DAHDI_FORMAT_G729A:
568         case DAHDI_FORMAT_G723_1:
569                 ast_atomic_fetchadd_int(&channels.encoders, -1);
570                 break;
571         default:
572                 ast_atomic_fetchadd_int(&channels.decoders, -1);
573                 break;
574         }
575
576         close(dahdip->fd);
577 }
578
579 static struct ast_format *dahdi_format_to_cached(int format)
580 {
581         switch (format) {
582         case DAHDI_FORMAT_G723_1:
583                 return ast_format_g723;
584         case DAHDI_FORMAT_GSM:
585                 return ast_format_gsm;
586         case DAHDI_FORMAT_ULAW:
587                 return ast_format_ulaw;
588         case DAHDI_FORMAT_ALAW:
589                 return ast_format_alaw;
590         case DAHDI_FORMAT_G726:
591                 return ast_format_g726;
592         case DAHDI_FORMAT_ADPCM:
593                 return ast_format_adpcm;
594         case DAHDI_FORMAT_SLINEAR:
595                 return ast_format_slin;
596         case DAHDI_FORMAT_LPC10:
597                 return ast_format_lpc10;
598         case DAHDI_FORMAT_G729A:
599                 return ast_format_g729;
600         case DAHDI_FORMAT_SPEEX:
601                 return ast_format_speex;
602         case DAHDI_FORMAT_ILBC:
603                 return ast_format_ilbc;
604         }
605
606         /* This will never be reached */
607         ast_assert(0);
608         return NULL;
609 }
610
611 static int dahdi_translate(struct ast_trans_pvt *pvt, uint32_t dst_dahdi_fmt, uint32_t src_dahdi_fmt)
612 {
613         /* Request translation through zap if possible */
614         int fd;
615         struct codec_dahdi_pvt *dahdip = pvt->pvt;
616         int flags;
617         int tried_once = 0;
618         const char *dev_filename = "/dev/dahdi/transcode";
619
620         if ((fd = open(dev_filename, O_RDWR)) < 0) {
621                 ast_log(LOG_ERROR, "Failed to open %s: %s\n", dev_filename, strerror(errno));
622                 return -1;
623         }
624
625         dahdip->fmts.srcfmt = src_dahdi_fmt;
626         dahdip->fmts.dstfmt = dst_dahdi_fmt;
627
628         ast_assert(pvt->f.subclass.format == NULL);
629         pvt->f.subclass.format = ao2_bump(dahdi_format_to_cached(dahdip->fmts.dstfmt));
630
631         ast_debug(1, "Opening transcoder channel from %s to %s.\n", pvt->t->src_codec.name, pvt->t->dst_codec.name);
632
633 retry:
634         if (ioctl(fd, DAHDI_TC_ALLOCATE, &dahdip->fmts)) {
635                 if ((ENODEV == errno) && !tried_once) {
636                         /* We requested to translate to/from an unsupported
637                          * format.  Most likely this is because signed linear
638                          * was not supported by any hardware devices even
639                          * though this module always registers signed linear
640                          * support. In this case we'll retry, requesting
641                          * support for ULAW instead of signed linear and then
642                          * we'll just convert from ulaw to signed linear in
643                          * software. */
644                         if (dahdip->fmts.srcfmt == DAHDI_FORMAT_SLINEAR) {
645                                 ast_debug(1, "Using soft_slin support on source\n");
646                                 dahdip->softslin = 1;
647                                 dahdip->fmts.srcfmt = DAHDI_FORMAT_ULAW;
648                         } else if (dahdip->fmts.dstfmt == DAHDI_FORMAT_SLINEAR) {
649                                 ast_debug(1, "Using soft_slin support on destination\n");
650                                 dahdip->softslin = 1;
651                                 dahdip->fmts.dstfmt = DAHDI_FORMAT_ULAW;
652                         }
653                         tried_once = 1;
654                         goto retry;
655                 }
656                 ast_log(LOG_ERROR, "Unable to attach to transcoder: %s\n", strerror(errno));
657                 close(fd);
658
659                 return -1;
660         }
661
662         flags = fcntl(fd, F_GETFL);
663         if (flags > - 1) {
664                 if (fcntl(fd, F_SETFL, flags | O_NONBLOCK))
665                         ast_log(LOG_WARNING, "Could not set non-block mode!\n");
666         }
667
668         dahdip->fd = fd;
669
670         dahdip->required_samples = ((dahdip->fmts.dstfmt|dahdip->fmts.srcfmt) & (DAHDI_FORMAT_G723_1)) ? G723_SAMPLES : G729_SAMPLES;
671
672         switch (dahdip->fmts.dstfmt) {
673         case DAHDI_FORMAT_G729A:
674                 ast_atomic_fetchadd_int(&channels.encoders, +1);
675                 break;
676         case DAHDI_FORMAT_G723_1:
677                 ast_atomic_fetchadd_int(&channels.encoders, +1);
678                 break;
679         default:
680                 ast_atomic_fetchadd_int(&channels.decoders, +1);
681                 break;
682         }
683
684         return 0;
685 }
686
687 static int dahdi_new(struct ast_trans_pvt *pvt)
688 {
689         struct translator *zt = container_of(pvt->t, struct translator, t);
690
691         return dahdi_translate(pvt, zt->dst_dahdi_fmt, zt->src_dahdi_fmt);
692 }
693
694 static struct ast_frame *fakesrc_sample(void)
695 {
696         /* Don't bother really trying to test hardware ones. */
697         static struct ast_frame f = {
698                 .frametype = AST_FRAME_VOICE,
699                 .samples = 160,
700                 .src = __PRETTY_FUNCTION__
701         };
702
703         return &f;
704 }
705
706 static bool is_encoder(uint32_t src_dahdi_fmt)
707 {
708         return ((src_dahdi_fmt & (DAHDI_FORMAT_ULAW | DAHDI_FORMAT_ALAW | DAHDI_FORMAT_SLINEAR)) > 0);
709 }
710
711 /* Must be called with the translators list locked. */
712 static int register_translator(uint32_t dst_dahdi_fmt, uint32_t src_dahdi_fmt)
713 {
714         const struct ast_codec *dst_codec;
715         const struct ast_codec *src_codec;
716         struct translator *zt;
717         int res;
718
719         dst_codec = get_dahdi_codec(dst_dahdi_fmt);
720         src_codec = get_dahdi_codec(src_dahdi_fmt);
721         if (!dst_codec || !src_codec) {
722                 return -1;
723         }
724
725         if (!(zt = ast_calloc(1, sizeof(*zt)))) {
726                 return -1;
727         }
728
729         zt->src_dahdi_fmt = src_dahdi_fmt;
730         zt->dst_dahdi_fmt = dst_dahdi_fmt;
731
732         snprintf(zt->t.name, sizeof(zt->t.name), "dahdi_%s_to_%s",
733                 src_codec->name, dst_codec->name);
734
735         memcpy(&zt->t.src_codec, src_codec, sizeof(*src_codec));
736         memcpy(&zt->t.dst_codec, dst_codec, sizeof(*dst_codec));
737         zt->t.buf_size = BUFFER_SIZE;
738         if (is_encoder(src_dahdi_fmt)) {
739                 zt->t.framein = dahdi_encoder_framein;
740                 zt->t.frameout = dahdi_encoder_frameout;
741         } else {
742                 zt->t.framein = dahdi_decoder_framein;
743                 zt->t.frameout = dahdi_decoder_frameout;
744         }
745         zt->t.destroy = dahdi_destroy;
746         zt->t.buffer_samples = 0;
747         zt->t.newpvt = dahdi_new;
748         zt->t.sample = fakesrc_sample;
749         zt->t.native_plc = 0;
750
751         zt->t.desc_size = sizeof(struct codec_dahdi_pvt);
752         if ((res = ast_register_translator(&zt->t))) {
753                 ast_free(zt);
754                 return -1;
755         }
756
757         AST_LIST_INSERT_HEAD(&translators, zt, entry);
758
759         return res;
760 }
761
762 static void unregister_translators(void)
763 {
764         struct translator *cur;
765
766         AST_LIST_LOCK(&translators);
767         while ((cur = AST_LIST_REMOVE_HEAD(&translators, entry))) {
768                 ast_unregister_translator(&cur->t);
769                 ast_free(cur);
770         }
771         AST_LIST_UNLOCK(&translators);
772 }
773
774 /* Must be called with the translators list locked. */
775 static bool is_already_registered(uint32_t dstfmt, uint32_t srcfmt)
776 {
777         bool res = false;
778         const struct translator *zt;
779
780         AST_LIST_TRAVERSE(&translators, zt, entry) {
781                 if ((zt->src_dahdi_fmt == srcfmt) && (zt->dst_dahdi_fmt == dstfmt)) {
782                         res = true;
783                         break;
784                 }
785         }
786
787         return res;
788 }
789
790 static void build_translators(uint32_t dstfmts, uint32_t srcfmts)
791 {
792         uint32_t srcfmt;
793         uint32_t dstfmt;
794
795         AST_LIST_LOCK(&translators);
796
797         for (srcfmt = 1; srcfmt != 0; srcfmt <<= 1) {
798                 for (dstfmt = 1; dstfmt != 0; dstfmt <<= 1) {
799                         if (!(dstfmts & dstfmt) || !(srcfmts & srcfmt)) {
800                                 continue;
801                         }
802                         if (is_already_registered(dstfmt, srcfmt)) {
803                                 continue;
804                         }
805                         register_translator(dstfmt, srcfmt);
806                 }
807         }
808
809         AST_LIST_UNLOCK(&translators);
810 }
811
812 static int find_transcoders(void)
813 {
814         struct dahdi_transcoder_info info = { 0, };
815         int fd;
816
817         if ((fd = open("/dev/dahdi/transcode", O_RDWR)) < 0) {
818                 ast_log(LOG_ERROR, "Failed to open /dev/dahdi/transcode: %s\n", strerror(errno));
819                 return 0;
820         }
821
822         for (info.tcnum = 0; !ioctl(fd, DAHDI_TC_GETINFO, &info); info.tcnum++) {
823                 ast_verb(2, "Found transcoder '%s'.\n", info.name);
824
825                 /* Complex codecs need to support signed linear.  If the
826                  * hardware transcoder does not natively support signed linear
827                  * format, we will emulate it in software directly in this
828                  * module. Also, do not allow direct ulaw/alaw to complex
829                  * codec translation, since that will prevent the generic PLC
830                  * functions from working. */
831                 if (info.dstfmts & (DAHDI_FORMAT_ULAW | DAHDI_FORMAT_ALAW)) {
832                         info.dstfmts |= DAHDI_FORMAT_SLINEAR;
833                         info.dstfmts &= ~(DAHDI_FORMAT_ULAW | DAHDI_FORMAT_ALAW);
834                 }
835                 if (info.srcfmts & (DAHDI_FORMAT_ULAW | DAHDI_FORMAT_ALAW)) {
836                         info.srcfmts |= DAHDI_FORMAT_SLINEAR;
837                         info.srcfmts &= ~(DAHDI_FORMAT_ULAW | DAHDI_FORMAT_ALAW);
838                 }
839
840                 build_translators(info.dstfmts, info.srcfmts);
841                 ast_atomic_fetchadd_int(&channels.total, info.numchannels / 2);
842         }
843
844         close(fd);
845
846         if (!info.tcnum) {
847                 ast_verb(2, "No hardware transcoders found.\n");
848         }
849
850         return 0;
851 }
852
853 static int reload(void)
854 {
855         return AST_MODULE_LOAD_SUCCESS;
856 }
857
858 static int unload_module(void)
859 {
860         ast_cli_unregister_multiple(cli, ARRAY_LEN(cli));
861         unregister_translators();
862
863         return 0;
864 }
865
866 static int load_module(void)
867 {
868         find_transcoders();
869         ast_cli_register_multiple(cli, ARRAY_LEN(cli));
870         return AST_MODULE_LOAD_SUCCESS;
871 }
872
873 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Generic DAHDI Transcoder Codec Translator",
874         .support_level = AST_MODULE_SUPPORT_CORE,
875         .load = load_module,
876         .unload = unload_module,
877         .reload = reload,
878 );