Wed Jan 8 2020 09:49:46

Asterisk developer's documentation


codec_dahdi.c
Go to the documentation of this file.
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 
36 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 365989 $")
37 
38 #include <fcntl.h>
39 #include <netinet/in.h>
40 #include <sys/ioctl.h>
41 #include <sys/mman.h>
42 #include <sys/poll.h>
43 #include <dahdi/user.h>
44 
45 #include "asterisk/lock.h"
46 #include "asterisk/translate.h"
47 #include "asterisk/config.h"
48 #include "asterisk/module.h"
49 #include "asterisk/cli.h"
50 #include "asterisk/channel.h"
51 #include "asterisk/utils.h"
52 #include "asterisk/linkedlists.h"
53 #include "asterisk/ulaw.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 static struct channel_usage {
62  int total;
63  int encoders;
64  int decoders;
65 } channels;
66 
67 static char *handle_cli_transcoder_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
68 
69 static struct ast_cli_entry cli[] = {
70  AST_CLI_DEFINE(handle_cli_transcoder_show, "Display DAHDI transcoder utilization.")
71 };
72 
73 struct format_map {
74  unsigned int map[32][32];
75 };
76 
77 static struct format_map global_format_map = { { { 0 } } };
78 
79 struct translator {
80  struct ast_translator t;
82 };
83 
85 
87  int fd;
88  struct dahdi_transcoder_formats fmts;
89  unsigned int softslin:1;
90  unsigned int fake:2;
91  uint16_t required_samples;
94  uint8_t ulaw_buffer[1024];
95 };
96 
97 /* Only used by a decoder */
98 static int ulawtolin(struct ast_trans_pvt *pvt, int samples)
99 {
100  struct codec_dahdi_pvt *dahdip = pvt->pvt;
101  int i = samples;
102  uint8_t *src = &dahdip->ulaw_buffer[0];
103  int16_t *dst = pvt->outbuf.i16 + pvt->datalen;
104 
105  /* convert and copy in outbuf */
106  while (i--) {
107  *dst++ = AST_MULAW(*src++);
108  }
109 
110  return 0;
111 }
112 
113 /* Only used by an encoder. */
114 static int lintoulaw(struct ast_trans_pvt *pvt, struct ast_frame *f)
115 {
116  struct codec_dahdi_pvt *dahdip = pvt->pvt;
117  int i = f->samples;
118  uint8_t *dst = &dahdip->ulaw_buffer[dahdip->samples_in_buffer];
119  int16_t *src = f->data.ptr;
120 
121  if (dahdip->samples_in_buffer + i > sizeof(dahdip->ulaw_buffer)) {
122  ast_log(LOG_ERROR, "Out of buffer space!\n");
123  return -i;
124  }
125 
126  while (i--) {
127  *dst++ = AST_LIN2MU(*src++);
128  }
129 
130  dahdip->samples_in_buffer += f->samples;
131  return 0;
132 }
133 
134 static char *handle_cli_transcoder_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
135 {
136  struct channel_usage copy;
137 
138  switch (cmd) {
139  case CLI_INIT:
140  e->command = "transcoder show";
141  e->usage =
142  "Usage: transcoder show\n"
143  " Displays channel utilization of DAHDI transcoder(s).\n";
144  return NULL;
145  case CLI_GENERATE:
146  return NULL;
147  }
148 
149  if (a->argc != 2)
150  return CLI_SHOWUSAGE;
151 
152  copy = channels;
153 
154  if (copy.total == 0)
155  ast_cli(a->fd, "No DAHDI transcoders found.\n");
156  else
157  ast_cli(a->fd, "%d/%d encoders/decoders of %d channels are in use.\n", copy.encoders, copy.decoders, copy.total);
158 
159  return CLI_SUCCESS;
160 }
161 
162 static void dahdi_write_frame(struct codec_dahdi_pvt *dahdip, const uint8_t *buffer, const ssize_t count)
163 {
164  int res;
165  if (!count) return;
166  res = write(dahdip->fd, buffer, count);
167  if (option_verbose > 10) {
168  if (-1 == res) {
169  ast_log(LOG_ERROR, "Failed to write to transcoder: %s\n", strerror(errno));
170  }
171  if (count != res) {
172  ast_log(LOG_ERROR, "Requested write of %zd bytes, but only wrote %d bytes.\n", count, res);
173  }
174  }
175 }
176 
177 static int dahdi_encoder_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
178 {
179  struct codec_dahdi_pvt *dahdip = pvt->pvt;
180 
181  if (!f->subclass.codec) {
182  /* We're just faking a return for calculation purposes. */
183  dahdip->fake = 2;
184  pvt->samples = f->samples;
185  return 0;
186  }
187 
188  /* Buffer up the packets and send them to the hardware if we
189  * have enough samples set up. */
190  if (dahdip->softslin) {
191  if (lintoulaw(pvt, f)) {
192  return -1;
193  }
194  } else {
195  /* NOTE: If softslin support is not needed, and the sample
196  * size is equal to the required sample size, we wouldn't
197  * need this copy operation. But at the time this was
198  * written, only softslin is supported. */
199  if (dahdip->samples_in_buffer + f->samples > sizeof(dahdip->ulaw_buffer)) {
200  ast_log(LOG_ERROR, "Out of buffer space.\n");
201  return -1;
202  }
203  memcpy(&dahdip->ulaw_buffer[dahdip->samples_in_buffer], f->data.ptr, f->samples);
204  dahdip->samples_in_buffer += f->samples;
205  }
206 
207  while (dahdip->samples_in_buffer >= dahdip->required_samples) {
208  dahdi_write_frame(dahdip, dahdip->ulaw_buffer, dahdip->required_samples);
210  dahdip->samples_in_buffer -= dahdip->required_samples;
211  if (dahdip->samples_in_buffer) {
212  /* Shift any remaining bytes down. */
213  memmove(dahdip->ulaw_buffer, &dahdip->ulaw_buffer[dahdip->required_samples],
214  dahdip->samples_in_buffer);
215  }
216  }
217  pvt->samples += f->samples;
218  pvt->datalen = 0;
219  return -1;
220 }
221 
222 static void dahdi_wait_for_packet(int fd)
223 {
224  struct pollfd p = {0};
225  p.fd = fd;
226  p.events = POLLIN;
227  poll(&p, 1, 10);
228 }
229 
230 static struct ast_frame *dahdi_encoder_frameout(struct ast_trans_pvt *pvt)
231 {
232  struct codec_dahdi_pvt *dahdip = pvt->pvt;
233  int res;
234 
235  if (2 == dahdip->fake) {
236  dahdip->fake = 1;
237  pvt->f.frametype = AST_FRAME_VOICE;
238  pvt->f.subclass.codec = 0;
239  pvt->f.samples = dahdip->required_samples;
240  pvt->f.data.ptr = NULL;
241  pvt->f.offset = 0;
242  pvt->f.datalen = 0;
243  pvt->f.mallocd = 0;
244  pvt->samples = 0;
245 
246  return ast_frisolate(&pvt->f);
247 
248  } else if (1 == dahdip->fake) {
249  dahdip->fake = 0;
250  return NULL;
251  }
252 
253  if (dahdip->samples_written_to_hardware >= dahdip->required_samples) {
254  dahdi_wait_for_packet(dahdip->fd);
255  }
256 
257  res = read(dahdip->fd, pvt->outbuf.c + pvt->datalen, pvt->t->buf_size - pvt->datalen);
258  if (-1 == res) {
259  if (EWOULDBLOCK == errno) {
260  /* Nothing waiting... */
261  return NULL;
262  } else {
263  ast_log(LOG_ERROR, "Failed to read from transcoder: %s\n", strerror(errno));
264  return NULL;
265  }
266  } else {
267  pvt->f.datalen = res;
268  pvt->f.frametype = AST_FRAME_VOICE;
269  pvt->f.subclass.codec = 1 << (pvt->t->dstfmt);
270  pvt->f.mallocd = 0;
272  pvt->f.src = pvt->t->name;
273  pvt->f.data.ptr = pvt->outbuf.c;
274  pvt->f.samples = ast_codec_get_samples(&pvt->f);
275 
277  (dahdip->samples_written_to_hardware >= pvt->f.samples) ?
278  dahdip->samples_written_to_hardware - pvt->f.samples : 0;
279 
280  pvt->samples = 0;
281  pvt->datalen = 0;
282  return ast_frisolate(&pvt->f);
283  }
284 
285  /* Shouldn't get here... */
286  return NULL;
287 }
288 
289 static int dahdi_decoder_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
290 {
291  struct codec_dahdi_pvt *dahdip = pvt->pvt;
292 
293  if (!f->subclass.codec) {
294  /* We're just faking a return for calculation purposes. */
295  dahdip->fake = 2;
296  pvt->samples = f->samples;
297  return 0;
298  }
299 
300  if (!f->datalen) {
301  if (f->samples != dahdip->required_samples) {
302  ast_log(LOG_ERROR, "%d != %d %d\n", f->samples, dahdip->required_samples, f->datalen);
303  }
304  }
305  dahdi_write_frame(dahdip, f->data.ptr, f->datalen);
306  dahdip->samples_written_to_hardware += f->samples;
307  pvt->samples += f->samples;
308  pvt->datalen = 0;
309  return -1;
310 }
311 
312 static struct ast_frame *dahdi_decoder_frameout(struct ast_trans_pvt *pvt)
313 {
314  int res;
315  struct codec_dahdi_pvt *dahdip = pvt->pvt;
316 
317  if (2 == dahdip->fake) {
318  dahdip->fake = 1;
319  pvt->f.frametype = AST_FRAME_VOICE;
320  pvt->f.subclass.codec = 0;
321  pvt->f.samples = dahdip->required_samples;
322  pvt->f.data.ptr = NULL;
323  pvt->f.offset = 0;
324  pvt->f.datalen = 0;
325  pvt->f.mallocd = 0;
326  pvt->samples = 0;
327  return ast_frisolate(&pvt->f);
328  } else if (1 == dahdip->fake) {
329  pvt->samples = 0;
330  dahdip->fake = 0;
331  return NULL;
332  }
333 
334  if (dahdip->samples_written_to_hardware >= ULAW_SAMPLES) {
335  dahdi_wait_for_packet(dahdip->fd);
336  }
337 
338  /* Let's check to see if there is a new frame for us.... */
339  if (dahdip->softslin) {
340  res = read(dahdip->fd, dahdip->ulaw_buffer, sizeof(dahdip->ulaw_buffer));
341  } else {
342  res = read(dahdip->fd, pvt->outbuf.c + pvt->datalen, pvt->t->buf_size - pvt->datalen);
343  }
344 
345  if (-1 == res) {
346  if (EWOULDBLOCK == errno) {
347  /* Nothing waiting... */
348  return NULL;
349  } else {
350  ast_log(LOG_ERROR, "Failed to read from transcoder: %s\n", strerror(errno));
351  return NULL;
352  }
353  } else {
354  if (dahdip->softslin) {
355  ulawtolin(pvt, res);
356  pvt->f.datalen = res * 2;
357  } else {
358  pvt->f.datalen = res;
359  }
360  pvt->datalen = 0;
361  pvt->f.frametype = AST_FRAME_VOICE;
362  pvt->f.subclass.codec = 1 << (pvt->t->dstfmt);
363  pvt->f.mallocd = 0;
365  pvt->f.src = pvt->t->name;
366  pvt->f.data.ptr = pvt->outbuf.c;
367  pvt->f.samples = res;
368  pvt->samples = 0;
370  (dahdip->samples_written_to_hardware >= res) ?
371  dahdip->samples_written_to_hardware - res : 0;
372 
373  return ast_frisolate(&pvt->f);
374  }
375 
376  /* Shouldn't get here... */
377  return NULL;
378 }
379 
380 
381 static void dahdi_destroy(struct ast_trans_pvt *pvt)
382 {
383  struct codec_dahdi_pvt *dahdip = pvt->pvt;
384 
385  switch (dahdip->fmts.dstfmt) {
386  case AST_FORMAT_G729A:
387  case AST_FORMAT_G723_1:
389  break;
390  default:
392  break;
393  }
394 
395  close(dahdip->fd);
396 }
397 
398 static int dahdi_translate(struct ast_trans_pvt *pvt, int dest, int source)
399 {
400  /* Request translation through zap if possible */
401  int fd;
402  struct codec_dahdi_pvt *dahdip = pvt->pvt;
403  int flags;
404  int tried_once = 0;
405  const char *dev_filename = "/dev/dahdi/transcode";
406 
407  if ((fd = open(dev_filename, O_RDWR)) < 0) {
408  ast_log(LOG_ERROR, "Failed to open %s: %s\n", dev_filename, strerror(errno));
409  return -1;
410  }
411 
412  dahdip->fmts.srcfmt = (1 << source);
413  dahdip->fmts.dstfmt = (1 << dest);
414 
415  ast_debug(1, "Opening transcoder channel from %d to %d.\n", source, dest);
416 
417 retry:
418  if (ioctl(fd, DAHDI_TC_ALLOCATE, &dahdip->fmts)) {
419  if ((ENODEV == errno) && !tried_once) {
420  /* We requested to translate to/from an unsupported
421  * format. Most likely this is because signed linear
422  * was not supported by any hardware devices even
423  * though this module always registers signed linear
424  * support. In this case we'll retry, requesting
425  * support for ULAW instead of signed linear and then
426  * we'll just convert from ulaw to signed linear in
427  * software. */
428  if (AST_FORMAT_SLINEAR == dahdip->fmts.srcfmt) {
429  ast_debug(1, "Using soft_slin support on source\n");
430  dahdip->softslin = 1;
431  dahdip->fmts.srcfmt = AST_FORMAT_ULAW;
432  } else if (AST_FORMAT_SLINEAR == dahdip->fmts.dstfmt) {
433  ast_debug(1, "Using soft_slin support on destination\n");
434  dahdip->softslin = 1;
435  dahdip->fmts.dstfmt = AST_FORMAT_ULAW;
436  }
437  tried_once = 1;
438  goto retry;
439  }
440  ast_log(LOG_ERROR, "Unable to attach to transcoder: %s\n", strerror(errno));
441  close(fd);
442 
443  return -1;
444  }
445 
446  flags = fcntl(fd, F_GETFL);
447  if (flags > - 1) {
448  if (fcntl(fd, F_SETFL, flags | O_NONBLOCK))
449  ast_log(LOG_WARNING, "Could not set non-block mode!\n");
450  }
451 
452  dahdip->fd = fd;
453 
454  dahdip->required_samples = ((dahdip->fmts.dstfmt|dahdip->fmts.srcfmt)&AST_FORMAT_G723_1) ? G723_SAMPLES : G729_SAMPLES;
455 
456  switch (dahdip->fmts.dstfmt) {
457  case AST_FORMAT_G729A:
459  break;
460  case AST_FORMAT_G723_1:
462  break;
463  default:
465  break;
466  }
467 
468  return 0;
469 }
470 
471 static int dahdi_new(struct ast_trans_pvt *pvt)
472 {
473  return dahdi_translate(pvt, pvt->t->dstfmt, pvt->t->srcfmt);
474 }
475 
476 static struct ast_frame *fakesrc_sample(void)
477 {
478  /* Don't bother really trying to test hardware ones. */
479  static struct ast_frame f = {
481  .samples = 160,
482  .src = __PRETTY_FUNCTION__
483  };
484 
485  return &f;
486 }
487 
488 static int is_encoder(struct translator *zt)
489 {
491  return 1;
492  } else {
493  return 0;
494  }
495 }
496 
497 static int register_translator(int dst, int src)
498 {
499  struct translator *zt;
500  int res;
501 
502  if (!(zt = ast_calloc(1, sizeof(*zt)))) {
503  return -1;
504  }
505 
506  snprintf((char *) (zt->t.name), sizeof(zt->t.name), "zap%sto%s",
507  ast_getformatname((1 << src)), ast_getformatname((1 << dst)));
508  zt->t.srcfmt = (1 << src);
509  zt->t.dstfmt = (1 << dst);
510  zt->t.buf_size = BUFFER_SIZE;
511  if (is_encoder(zt)) {
514  } else {
517  }
518  zt->t.destroy = dahdi_destroy;
519  zt->t.buffer_samples = 0;
520  zt->t.newpvt = dahdi_new;
521  zt->t.sample = fakesrc_sample;
522  zt->t.native_plc = 0;
523 
524  zt->t.desc_size = sizeof(struct codec_dahdi_pvt);
525  if ((res = ast_register_translator(&zt->t))) {
526  ast_free(zt);
527  return -1;
528  }
529 
533 
534  global_format_map.map[dst][src] = 1;
535 
536  return res;
537 }
538 
539 static void drop_translator(int dst, int src)
540 {
541  struct translator *cur;
542 
545  if (cur->t.srcfmt != src)
546  continue;
547 
548  if (cur->t.dstfmt != dst)
549  continue;
550 
553  ast_free(cur);
554  global_format_map.map[dst][src] = 0;
555  break;
556  }
559 }
560 
561 static void unregister_translators(void)
562 {
563  struct translator *cur;
564 
566  while ((cur = AST_LIST_REMOVE_HEAD(&translators, entry))) {
568  ast_free(cur);
569  }
571 }
572 
573 static void build_translators(struct format_map *map, unsigned int dstfmts, unsigned int srcfmts)
574 {
575  unsigned int src, dst;
576 
577  for (src = 0; src < 32; src++) {
578  for (dst = 0; dst < 32; dst++) {
579  if (!(srcfmts & (1 << src)))
580  continue;
581 
582  if (!(dstfmts & (1 << dst)))
583  continue;
584 
585  if (global_format_map.map[dst][src])
586  continue;
587 
588  if (!register_translator(dst, src))
589  map->map[dst][src] = 1;
590  }
591  }
592 }
593 
594 static int find_transcoders(void)
595 {
596  struct dahdi_transcoder_info info = { 0, };
597  struct format_map map = { { { 0 } } };
598  int fd, res;
599  unsigned int x, y;
600 
601  if ((fd = open("/dev/dahdi/transcode", O_RDWR)) < 0) {
602  ast_log(LOG_ERROR, "Failed to open /dev/dahdi/transcode: %s\n", strerror(errno));
603  return 0;
604  }
605 
606  for (info.tcnum = 0; !(res = ioctl(fd, DAHDI_TC_GETINFO, &info)); info.tcnum++) {
607  if (option_verbose > 1)
608  ast_verbose(VERBOSE_PREFIX_2 "Found transcoder '%s'.\n", info.name);
609 
610  /* Complex codecs need to support signed linear. If the
611  * hardware transcoder does not natively support signed linear
612  * format, we will emulate it in software directly in this
613  * module. Also, do not allow direct ulaw/alaw to complex
614  * codec translation, since that will prevent the generic PLC
615  * functions from working. */
616  if (info.dstfmts & (AST_FORMAT_ULAW | AST_FORMAT_ALAW)) {
617  info.dstfmts |= AST_FORMAT_SLINEAR;
618  info.dstfmts &= ~(AST_FORMAT_ULAW | AST_FORMAT_ALAW);
619  }
620  if (info.srcfmts & (AST_FORMAT_ULAW | AST_FORMAT_ALAW)) {
621  info.srcfmts |= AST_FORMAT_SLINEAR;
622  info.srcfmts &= ~(AST_FORMAT_ULAW | AST_FORMAT_ALAW);
623  }
624 
625  build_translators(&map, info.dstfmts, info.srcfmts);
626  ast_atomic_fetchadd_int(&channels.total, info.numchannels / 2);
627 
628  }
629 
630  close(fd);
631 
632  if (!info.tcnum && (option_verbose > 1))
633  ast_verbose(VERBOSE_PREFIX_2 "No hardware transcoders found.\n");
634 
635  for (x = 0; x < 32; x++) {
636  for (y = 0; y < 32; y++) {
637  if (!map.map[x][y] && global_format_map.map[x][y])
638  drop_translator(x, y);
639  }
640  }
641 
642  return 0;
643 }
644 
645 static int reload(void)
646 {
648 }
649 
650 static int unload_module(void)
651 {
654 
655  return 0;
656 }
657 
658 static int load_module(void)
659 {
660  ast_ulaw_init();
664 }
665 
666 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Generic DAHDI Transcoder Codec Translator",
667  .load = load_module,
668  .unload = unload_module,
669  .reload = reload,
670  );
struct dahdi_transcoder_formats fmts
Definition: codec_dahdi.c:88
union ast_frame_subclass subclass
Definition: frame.h:146
int datalen
actual space used in outbuf
Definition: translate.h:140
static int register_translator(int dst, int src)
Definition: codec_dahdi.c:497
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
struct ast_frame *(* sample)(void)
Definition: translate.h:93
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int offset
Definition: frame.h:156
union ast_trans_pvt::@213 outbuf
static struct ast_frame * dahdi_encoder_frameout(struct ast_trans_pvt *pvt)
Definition: codec_dahdi.c:230
Descriptor of a translator.
Definition: translate.h:71
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
uint8_t ulaw_buffer[1024]
Definition: codec_dahdi.c:94
Support for translation of data formats. translate.c.
#define AST_FORMAT_G723_1
Definition: frame.h:242
void * ptr
Definition: frame.h:160
static int * map
Definition: misdn_config.c:434
struct ast_frame f
Definition: translate.h:137
descriptor for a cli entry.
Definition: cli.h:165
const int argc
Definition: cli.h:154
#define LOG_WARNING
Definition: logger.h:144
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static struct format_map global_format_map
Definition: codec_dahdi.c:77
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
static int is_encoder(struct translator *zt)
Definition: codec_dahdi.c:488
struct translator::@127 entry
Definition: cli.h:146
Configuration File Parser.
int option_verbose
Definition: asterisk.c:181
const char name[80]
Definition: translate.h:72
static void unregister_translators(void)
Definition: codec_dahdi.c:561
static struct ast_frame * fakesrc_sample(void)
Definition: codec_dahdi.c:476
static int dahdi_new(struct ast_trans_pvt *pvt)
Definition: codec_dahdi.c:471
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:374
struct ast_frame * ast_frisolate(struct ast_frame *fr)
Makes a frame independent of any static storage.
Definition: frame.c:391
format_t codec
Definition: frame.h:137
void * pvt
Definition: translate.h:141
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
static int find_transcoders(void)
Definition: codec_dahdi.c:594
#define G729_SAMPLES
Definition: codec_dahdi.c:58
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
#define AST_FORMAT_G729A
Definition: frame.h:258
int16_t * i16
Definition: translate.h:145
Utility functions.
struct ast_translator t
Definition: codec_dahdi.c:80
unsigned int softslin
Definition: codec_dahdi.c:89
struct ast_frame *(* frameout)(struct ast_trans_pvt *pvt)
Definition: translate.h:85
static void dahdi_write_frame(struct codec_dahdi_pvt *dahdip, const uint8_t *buffer, const ssize_t count)
Definition: codec_dahdi.c:162
uint16_t required_samples
Definition: codec_dahdi.c:91
static int load_module(void)
Definition: codec_dahdi.c:658
static void dahdi_wait_for_packet(int fd)
Definition: codec_dahdi.c:222
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
u-Law to Signed linear conversion
#define ULAW_SAMPLES
Definition: codec_dahdi.c:59
General Asterisk PBX channel definitions.
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
Definition: frame.h:204
#define VERBOSE_PREFIX_2
Definition: logger.h:42
const char * src
Definition: frame.h:158
static int dahdi_decoder_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
Definition: codec_dahdi.c:289
const int fd
Definition: cli.h:153
#define AST_FORMAT_ALAW
Definition: frame.h:248
#define AST_MULAW(a)
Definition: ulaw.h:85
#define BUFFER_SIZE
Definition: codec_dahdi.c:55
int datalen
Definition: frame.h:148
#define ast_register_translator(t)
See __ast_register_translator()
Definition: translate.h:170
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
int ast_unregister_translator(struct ast_translator *t)
Unregister a translator Unregisters the given tranlator.
Definition: translate.c:942
A set of macros to manage forward-linked lists.
static struct channel_usage channels
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
int buf_size
size of outbuf, in bytes. Mandatory. The wrapper code will also allocate an AST_FRIENDLY_OFFSET space...
Definition: translate.h:105
#define AST_LIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
Definition: linkedlists.h:290
static struct ast_cli_entry cli[]
Definition: codec_dahdi.c:69
static void build_translators(struct format_map *map, unsigned int dstfmts, unsigned int srcfmts)
Definition: codec_dahdi.c:573
the list of translators
Definition: codec_dahdi.c:84
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
void ast_ulaw_init(void)
Set up mu-law conversion table.
Definition: ulaw.c:175
#define LOG_ERROR
Definition: logger.h:155
static int dahdi_translate(struct ast_trans_pvt *pvt, int dest, int source)
Definition: codec_dahdi.c:398
static int unload_module(void)
Definition: codec_dahdi.c:650
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:135
int(* newpvt)(struct ast_trans_pvt *)
Definition: translate.h:78
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define AST_FORMAT_ULAW
Definition: frame.h:246
static int dahdi_encoder_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
Definition: codec_dahdi.c:177
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
Definition: linkedlists.h:409
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:696
int errno
unsigned int map[32][32]
Definition: codec_dahdi.c:74
#define ast_free(a)
Definition: astmm.h:97
char * command
Definition: cli.h:180
format_t dstfmt
Definition: translate.h:75
static struct ast_format f[]
Definition: format_g726.c:181
#define G723_SAMPLES
Definition: codec_dahdi.c:57
int mallocd
Definition: frame.h:152
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
uint16_t samples_in_buffer
Definition: codec_dahdi.c:92
static int ulawtolin(struct ast_trans_pvt *pvt, int samples)
Definition: codec_dahdi.c:98
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
static void dahdi_destroy(struct ast_trans_pvt *pvt)
Definition: codec_dahdi.c:381
static void drop_translator(int dst, int src)
Definition: codec_dahdi.c:539
Standard Command Line Interface.
#define ast_calloc(a, b)
Definition: astmm.h:82
int(* framein)(struct ast_trans_pvt *pvt, struct ast_frame *in)
Definition: translate.h:81
int ast_codec_get_samples(struct ast_frame *f)
Returns the number of samples contained in the frame.
Definition: frame.c:1470
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
Data structure associated with a single frame of data.
Definition: frame.h:142
static int reload(void)
Definition: codec_dahdi.c:645
format_t srcfmt
Definition: translate.h:73
static struct ast_frame * dahdi_decoder_frameout(struct ast_trans_pvt *pvt)
Definition: codec_dahdi.c:312
struct ast_translator * t
Definition: translate.h:136
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
enum ast_frame_type frametype
Definition: frame.h:144
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
Asterisk module definitions.
union ast_frame::@172 data
static int lintoulaw(struct ast_trans_pvt *pvt, struct ast_frame *f)
Definition: codec_dahdi.c:114
static char * handle_cli_transcoder_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: codec_dahdi.c:134
uint16_t samples_written_to_hardware
Definition: codec_dahdi.c:93
#define AST_LIN2MU(a)
Definition: ulaw.h:49
unsigned int fake
Definition: codec_dahdi.c:90
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180
int samples
Definition: frame.h:150
void(* destroy)(struct ast_trans_pvt *pvt)
Definition: translate.h:89
int buffer_samples
size of outbuf, in samples. Leave it 0 if you want the framein callback deal with the frame...
Definition: translate.h:100