1 /*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3 * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4 *
5 * Version: MPL 1.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is FreeSWITCH Modular Media Switching Software Library / DAHDI codec module
18 *
19 * The Initial Developer of the Original Code is
20 * Moises Silva <moy@sangoma.com>
21 * Portions created by the Initial Developer are Copyright (C)
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 * Moises Silva <moy@sangoma.com>
26 *
27 * mod_dahdi_codec -- DAHDI Codecs (G729A 8.0kbit, G723.1 5.3kbit)
28 *
29 * Thanks to Voiceway for sponsoring this module and Neocenter for providing the DAHDI hardware to test
30 *
31 */
32
33 #include <switch.h>
34 #include <g711.h>
35 #include <poll.h>
36 #if defined(__FreeBSD__)
37 #include <dahdi/compat/types.h>
38 #else
39 #include <linux/types.h> /* __u32 */
40 #endif
41 #include <sys/ioctl.h>
42 #include <unistd.h>
43 #include <fcntl.h>
44 #include <errno.h>
45
46 /*
47 * some rules to keep in mind for G729 (the frame size may be different for G723)
48 * we cannot write more than SFRAME_SIZE (320) - sizeof(struct rtp_packet) which
49 * seems to be 266 bytes
50 * if we write less than 160 bytes (1 ulaw frame which is 20 bytes of G729 bytes, a read will block forever)
51 * TODO: do buffering ourselves to provide just the fixed amount of samples that the card expects
52 * */
53 #define DAHDI_G729_INPUT_FRAME_SIZE 160
54 #define DAHDI_G729_OUTPUT_FRAME_SIZE 20
55
56 /*#define DEBUG_DAHDI_CODEC 1*/
57
58 #define CODEC_G729_IANA_CODE 18
59 #define CODEC_G723_IANA_CODE 4
60
61 switch_mutex_t *transcoder_counter_mutex;
62 static uint32_t total_encoders = 0;
63 static uint32_t total_encoders_usage = 0;
64 static uint32_t total_decoders = 0;
65 static uint32_t total_decoders_usage = 0;
66
67 /*
68 Zaptel/DAHDI definitions to not require the headers installed
69 Zaptel and DAHDI are binary compatible (at least in the transcoder interface)
70 */
71
72 #define DAHDI_TC_CODE 'T'
73 #define DAHDI_TC_ALLOCATE _IOW(DAHDI_TC_CODE, 1, struct dahdi_transcoder_formats)
74 #define DAHDI_TC_GETINFO _IOWR(DAHDI_TC_CODE, 2, struct dahdi_transcoder_info)
75
76 #define DAHDI_FORMAT_G723_1 (1 << 0)
77 #define DAHDI_FORMAT_ULAW (1 << 2)
78 #define DAHDI_FORMAT_SLINEAR (1 << 6)
79 #define DAHDI_FORMAT_G729A (1 << 8)
80
81 struct dahdi_transcoder_formats {
82 __u32 srcfmt;
83 __u32 dstfmt;
84 };
85
86 struct dahdi_transcoder_info {
87 __u32 tcnum;
88 char name[80];
89 __u32 numchannels;
90 __u32 dstfmts;
91 __u32 srcfmts;
92 };
93
94 static const char transcoding_device_dahdi[] = "/dev/dahdi/transcode";
95 static const char transcoder_name_dahdi[] = "DAHDI";
96 static const char transcoding_device_zap[] = "/dev/zap/transcode";
97 static const char transcoder_name_zap[] = "Zap";
98 static const char *transcoding_device = NULL;
99 static const char *transcoder_name = NULL;
100
101 SWITCH_MODULE_LOAD_FUNCTION(mod_dahdi_codec_load);
102 SWITCH_MODULE_DEFINITION(mod_dahdi_codec, mod_dahdi_codec_load, NULL, NULL);
103
104 struct dahdi_context {
105 int32_t encoding_fd;
106 int32_t decoding_fd;
107 uint8_t codec_r;
108 };
109
switch_dahdi_get_transcoder(struct dahdi_transcoder_formats * fmts)110 static int32_t switch_dahdi_get_transcoder(struct dahdi_transcoder_formats *fmts)
111 {
112 int32_t fdflags;
113 int32_t fd = open(transcoding_device, O_RDWR);
114 if (fd < 0) {
115 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open %s transcoder device: %s.\n", transcoder_name, strerror(errno));
116 return -1;
117 }
118 if (ioctl(fd, DAHDI_TC_ALLOCATE, fmts)) {
119 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to attach to transcoder: %s.\n", strerror(errno));
120 close(fd);
121 return -1;
122 }
123 fdflags = fcntl(fd, F_GETFL);
124 if (fdflags > -1) {
125 fdflags |= O_NONBLOCK;
126 if (fcntl(fd, F_SETFL, fdflags)) {
127 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not set non-block mode in %s transcoder FD: %s\n",
128 transcoder_name, strerror(errno));
129 /* should we abort? this may cause channels to hangup when overruning the device
130 * see jira dahdi codec issue MODCODEC-8 (Hung Calls and Codec DAHDI G.729A 8.0k decoder error!)
131 * */
132 }
133 } else {
134 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not get flags from %s transcoder FD: %s\n", transcoder_name, strerror(errno));
135 }
136
137 if (fmts->srcfmt & DAHDI_FORMAT_ULAW) {
138 switch_mutex_lock(transcoder_counter_mutex);
139 total_encoders_usage++;
140 switch_mutex_unlock(transcoder_counter_mutex);
141 } else {
142 switch_mutex_lock(transcoder_counter_mutex);
143 total_decoders_usage++;
144 switch_mutex_unlock(transcoder_counter_mutex);
145 }
146
147 return fd;
148 }
149
init_encoder(switch_codec_t * codec)150 static switch_status_t init_encoder(switch_codec_t *codec)
151 {
152 struct dahdi_transcoder_formats fmts;
153 struct dahdi_context *context = codec->private_info;
154
155 fmts.srcfmt = DAHDI_FORMAT_ULAW;
156 fmts.dstfmt = (codec->implementation->ianacode == CODEC_G729_IANA_CODE)
157 ? DAHDI_FORMAT_G729A : DAHDI_FORMAT_G723_1;
158 context->encoding_fd = switch_dahdi_get_transcoder(&fmts);
159 if (context->encoding_fd < 0) {
160 #ifdef DEBUG_DAHDI_CODEC
161 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "encoding requested and denied with %d/%d.\n", fmts.srcfmt, fmts.dstfmt);
162 #endif
163 return SWITCH_STATUS_FALSE;
164 }
165 #ifdef DEBUG_DAHDI_CODEC
166 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Encoding requested and granted with %d/%d.\n", fmts.srcfmt, fmts.dstfmt);
167 #endif
168
169
170 return SWITCH_STATUS_SUCCESS;
171 }
172
173
init_decoder(switch_codec_t * codec)174 static switch_status_t init_decoder(switch_codec_t *codec)
175 {
176 struct dahdi_transcoder_formats fmts;
177 struct dahdi_context *context = codec->private_info;
178
179 fmts.dstfmt = DAHDI_FORMAT_ULAW;
180 fmts.srcfmt = (codec->implementation->ianacode == CODEC_G729_IANA_CODE)
181 ? DAHDI_FORMAT_G729A : DAHDI_FORMAT_G723_1;
182 context->decoding_fd = switch_dahdi_get_transcoder(&fmts);
183 if (context->decoding_fd < 0) {
184 #ifdef DEBUG_DAHDI_CODEC
185 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Decoding requested and denied with %d/%d.\n", fmts.srcfmt, fmts.dstfmt);
186 #endif
187 return SWITCH_STATUS_FALSE;
188 }
189 #ifdef DEBUG_DAHDI_CODEC
190 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Decoding requested and granted with %d/%d.\n", fmts.srcfmt, fmts.dstfmt);
191 #endif
192
193 return SWITCH_STATUS_SUCCESS;
194 }
195
switch_dahdi_init(switch_codec_t * codec,switch_codec_flag_t flags,const switch_codec_settings_t * codec_settings)196 static switch_status_t switch_dahdi_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
197 {
198 uint32_t encoding, decoding;
199 struct dahdi_context *context = NULL;
200 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Switch DAHDI init called.\n");
201
202 encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
203 decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
204
205 if (!(encoding || decoding)) {
206 #ifdef DEBUG_DAHDI_CODEC
207 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No encoding or decoding requested for DAHDI transcoder?.\n");
208 #endif
209 return SWITCH_STATUS_FALSE;
210 }
211
212 if (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context)))) {
213 #ifdef DEBUG_DAHDI_CODEC
214 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to allocate memory for dahdi codec context.\n");
215 #endif
216 return SWITCH_STATUS_FALSE;
217 }
218
219 codec->private_info = context;
220 context->encoding_fd = -1;
221 context->decoding_fd = -1;
222
223 /* ulaw requires 8 times more storage than g729 and 12 times more than G723, right?
224 * this can be used to calculate the target buffer when encoding and decoding
225 * */
226 context->codec_r = (codec->implementation->ianacode == CODEC_G729_IANA_CODE)
227 ? 8 : 12;
228
229
230 return SWITCH_STATUS_SUCCESS;
231 }
232
wait_for_transcoder(int fd)233 static int wait_for_transcoder(int fd)
234 {
235 /* let's wait a bit for the transcoder, if in 20msthe driver does not notify us that its ready to give us something
236 then just bail out with 0 bytes encoded/decoded as result, I'd expect the card to hold that buffer and return it later */
237 int res = 0;
238 struct pollfd readpoll;
239 memset(&readpoll, 0, sizeof(readpoll));
240 readpoll.fd = fd;
241 readpoll.events = POLLIN;
242 /* my testing shows that it does not take more than 1ms to encode a 160 bytes frame ulaw to g729,
243 I dont think there is much difference decoding and for g723, waiting 10ms seems more than reasonable */
244 res = poll(&readpoll, 1, 10);
245 return res;
246 }
247
switch_dahdi_encode(switch_codec_t * codec,switch_codec_t * other_codec,void * decoded_data,uint32_t decoded_data_len,uint32_t decoded_rate,void * encoded_data,uint32_t * encoded_data_len,uint32_t * encoded_rate,unsigned int * flag)248 static switch_status_t switch_dahdi_encode(switch_codec_t *codec,
249 switch_codec_t *other_codec,
250 void *decoded_data,
251 uint32_t decoded_data_len,
252 uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate,
253 unsigned int *flag)
254 {
255 int32_t res;
256 short *dbuf_linear;
257 unsigned char ebuf_ulaw[decoded_data_len / 2];
258 uint32_t i;
259 struct dahdi_context *context = NULL;
260 switch_status_t status;
261
262 #ifdef DEBUG_DAHDI_CODEC
263 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Switch DAHDI encode called to encode %d bytes.\n", decoded_data_len);
264 #endif
265 context = codec->private_info;
266
267 if (context->encoding_fd == -1) {
268 if ((status = init_encoder(codec)) != SWITCH_STATUS_SUCCESS) {
269 return status;
270 }
271 }
272
273 dbuf_linear = decoded_data;
274 for (i = 0; i < decoded_data_len / sizeof(short); i++) {
275 ebuf_ulaw[i] = linear_to_ulaw(dbuf_linear[i]);
276 }
277 #ifdef DEBUG_DAHDI_CODEC
278 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Writing %d bytes of decoded ulaw data.\n", i);
279 #endif
280 res = write(context->encoding_fd, ebuf_ulaw, i);
281 if (-1 == res) {
282 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to write to %s encoder device.\n", transcoder_name);
283 return SWITCH_STATUS_FALSE;
284 }
285 if (i != res) {
286 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested to write %d bytes to %s encoder device, but only wrote %d bytes.\n", i,
287 transcoder_name, res);
288 return SWITCH_STATUS_FALSE;
289 }
290 res = wait_for_transcoder(context->encoding_fd);
291 if (-1 == res) {
292 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to poll on %s encoder device: %s.\n", transcoder_name, strerror(errno));
293 return SWITCH_STATUS_FALSE;
294 }
295 if (0 == res) {
296 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output on %s encoder device.\n", transcoder_name);
297 *encoded_data_len = 0;
298 return SWITCH_STATUS_SUCCESS;
299 }
300 #ifdef DEBUG_DAHDI_CODEC
301 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Attempting to read %d bytes of encoded data.\n", *encoded_data_len);
302 #endif
303 res = read(context->encoding_fd, encoded_data, *encoded_data_len);
304 if (-1 == res) {
305 if (EAGAIN == errno || EWOULDBLOCK == errno) {
306 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output on %s encoder device (%s).\n", transcoder_name, strerror(errno));
307 *encoded_data_len = 0;
308 return SWITCH_STATUS_SUCCESS;
309 }
310 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read from %s encoder device: %s.\n", transcoder_name, strerror(errno));
311 return SWITCH_STATUS_FALSE;
312 }
313 *encoded_data_len = res;
314 #ifdef DEBUG_DAHDI_CODEC
315 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Read %d bytes of encoded data.\n", res);
316 #endif
317 return SWITCH_STATUS_SUCCESS;
318 }
319
switch_dahdi_decode(switch_codec_t * codec,switch_codec_t * other_codec,void * encoded_data,uint32_t encoded_data_len,uint32_t encoded_rate,void * decoded_data,uint32_t * decoded_data_len,uint32_t * decoded_rate,unsigned int * flag)320 static switch_status_t switch_dahdi_decode(switch_codec_t *codec,
321 switch_codec_t *other_codec,
322 void *encoded_data,
323 uint32_t encoded_data_len,
324 uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate,
325 unsigned int *flag)
326 {
327 int32_t res;
328 short *dbuf_linear;
329 // we only can decode up to half ulaw bytes of whatever their destiny linear buffer is
330 unsigned char dbuf_ulaw[*decoded_data_len / 2];
331 unsigned char *ebuf_g729;
332 uint32_t i;
333 struct dahdi_context *context;
334 switch_status_t status;
335
336 #ifdef DEBUG_DAHDI_CODEC
337 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Switch DAHDI decode called to decode %d bytes.\n", encoded_data_len);
338 #endif
339
340 context = codec->private_info;
341 dbuf_linear = decoded_data;
342 ebuf_g729 = encoded_data;
343
344 if (context->decoding_fd == -1) {
345 if ((status = init_decoder(codec)) != SWITCH_STATUS_SUCCESS) {
346 return status;
347 }
348 }
349
350 if (*flag & SWITCH_CODEC_FLAG_SILENCE) {
351 memset(dbuf_linear, 0, codec->implementation->decoded_bytes_per_packet);
352 *decoded_data_len = codec->implementation->decoded_bytes_per_packet;
353 #ifdef DEBUG_DAHDI_CODEC
354 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Switch DAHDI decode in silence returned %d bytes.\n", *decoded_data_len);
355 #endif
356 return SWITCH_STATUS_SUCCESS;
357 }
358 #ifdef DEBUG_DAHDI_CODEC
359 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Writing %d bytes to decode.\n", encoded_data_len);
360 #endif
361 res = write(context->decoding_fd, ebuf_g729, encoded_data_len);
362 if (-1 == res) {
363 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to write to %s decoder device: %s.\n", transcoder_name, strerror(errno));
364 return SWITCH_STATUS_FALSE;
365 }
366 if (encoded_data_len != res) {
367 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested to write %d bytes to %s decoder device, but only wrote %d bytes.\n",
368 encoded_data_len, transcoder_name, res);
369 return SWITCH_STATUS_FALSE;
370 }
371 #ifdef DEBUG_DAHDI_CODEC
372 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Attempting to read from device %d bytes of decoded ulaw data.\n", sizeof(dbuf_ulaw));
373 #endif
374 res = wait_for_transcoder(context->decoding_fd);
375 if (-1 == res) {
376 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to poll on %s decoder device: %s.\n", transcoder_name, strerror(errno));
377 return SWITCH_STATUS_FALSE;
378 }
379 if (0 == res) {
380 memset(dbuf_linear, 0, codec->implementation->decoded_bytes_per_packet);
381 *decoded_data_len = codec->implementation->decoded_bytes_per_packet;
382 #ifdef DEBUG_DAHDI_CODEC
383 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output on %s decoder device, returning silence frame of %d bytes.\n", transcoder_name,
384 *decoded_data_len);
385 #endif
386 return SWITCH_STATUS_SUCCESS;
387 }
388 res = read(context->decoding_fd, dbuf_ulaw, sizeof(dbuf_ulaw));
389 if (-1 == res) {
390 if (EAGAIN == errno || EWOULDBLOCK == errno) {
391 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output on %s decoder device (%s).\n", transcoder_name, strerror(errno));
392 *decoded_data_len = 0;
393 return SWITCH_STATUS_SUCCESS;
394 }
395 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read from %s decoder device: %s.\n", transcoder_name, strerror(errno));
396 return SWITCH_STATUS_FALSE;
397 }
398 for (i = 0; i < res; i++) {
399 dbuf_linear[i] = ulaw_to_linear(dbuf_ulaw[i]);
400 }
401 *decoded_data_len = i * 2;
402 #ifdef DEBUG_DAHDI_CODEC
403 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Switch DAHDI decode returned %d bytes.\n", *decoded_data_len);
404 #endif
405 return SWITCH_STATUS_SUCCESS;
406 }
407
switch_dahdi_destroy(switch_codec_t * codec)408 static switch_status_t switch_dahdi_destroy(switch_codec_t *codec)
409 {
410 /* memory pool takes care of the private_info memory */
411 struct dahdi_context *context = codec->private_info;
412 if (context->encoding_fd >= 0) {
413 switch_mutex_lock(transcoder_counter_mutex);
414 total_encoders_usage--;
415 switch_mutex_unlock(transcoder_counter_mutex);
416 close(context->encoding_fd);
417 }
418 if (context->decoding_fd >= 0) {
419 switch_mutex_lock(transcoder_counter_mutex);
420 total_decoders_usage--;
421 switch_mutex_unlock(transcoder_counter_mutex);
422 close(context->decoding_fd);
423 }
424 codec->private_info = NULL;
425 return SWITCH_STATUS_SUCCESS;
426 }
427
SWITCH_STANDARD_API(dahdi_transcode_usage)428 SWITCH_STANDARD_API(dahdi_transcode_usage)
429 {
430 if (!total_encoders && !total_decoders) {
431 stream->write_function(stream, "No DAHDI transcoding hardware found.\n");
432 return SWITCH_STATUS_SUCCESS;
433 }
434 switch_mutex_lock(transcoder_counter_mutex);
435 stream->write_function(stream, "Using %d encoders of a total of %d available.\n", total_encoders_usage, total_encoders);
436 stream->write_function(stream, "Using %d decoders of a total of %d available.\n", total_decoders_usage, total_decoders);
437 switch_mutex_unlock(transcoder_counter_mutex);
438 return SWITCH_STATUS_SUCCESS;
439 }
440
SWITCH_MODULE_LOAD_FUNCTION(mod_dahdi_codec_load)441 SWITCH_MODULE_LOAD_FUNCTION(mod_dahdi_codec_load)
442 {
443 switch_api_interface_t *api_interface;
444 switch_codec_interface_t *codec_interface;
445 struct stat statbuf;
446 struct dahdi_transcoder_info info = { 0 };
447 int32_t fd, res;
448 int mpf = 20000; /* Algorithmic delay of 15ms with 5ms of look-ahead delay */
449 int spf = 160;
450 int bpfd = 320;
451 int bpfc = 20;
452 int fpnp = 20;
453
454 total_encoders = 0;
455 total_encoders_usage = 0;
456 total_decoders = 0;
457 total_decoders_usage = 0;
458
459 /* Let's check if DAHDI or Zaptel device should be used */
460 if (!stat(transcoding_device_dahdi, &statbuf)) {
461 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "DAHDI transcoding device found.\n");
462 transcoding_device = transcoding_device_dahdi;
463 transcoder_name = transcoder_name_dahdi;
464 } else if (!stat(transcoding_device_zap, &statbuf)) {
465 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Zap transcoding device found.\n");
466 transcoding_device = transcoding_device_zap;
467 transcoder_name = transcoder_name_zap;
468 } else {
469 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No DAHDI or Zap transcoder device was found in /dev/.\n");
470 return SWITCH_STATUS_FALSE;
471 }
472
473 fd = open(transcoding_device, O_RDWR);
474 if (fd < 0) {
475 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open %s transcoder device: %s.\n", transcoder_name, strerror(errno));
476 return SWITCH_STATUS_FALSE;
477 }
478
479 for (info.tcnum = 0; !(res = ioctl(fd, DAHDI_TC_GETINFO, &info)); info.tcnum++) {
480 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found dahdi transcoder name: %s\n", info.name);
481 if ((info.srcfmts & DAHDI_FORMAT_ULAW) && (info.dstfmts & (DAHDI_FORMAT_G729A | DAHDI_FORMAT_G723_1))) {
482 total_encoders += info.numchannels;
483 continue;
484 }
485 if ((info.dstfmts & DAHDI_FORMAT_ULAW) && (info.srcfmts & (DAHDI_FORMAT_G729A | DAHDI_FORMAT_G723_1))) {
486 total_decoders += info.numchannels;
487 continue;
488 }
489 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Not using transcoder %s, we just support ULAW and G723.1/G729A", info.name);
490 }
491 close(fd);
492
493 if (!total_encoders && !total_decoders) {
494 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No DAHDI transcoders found.\n");
495 return SWITCH_STATUS_FALSE;
496 }
497 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Found %d ULAW to G729A/G723.1 encoders.\n", total_encoders);
498 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Found %d G729A/G723.1 to ULAW decoders.\n", total_decoders);
499
500 switch_mutex_init(&transcoder_counter_mutex, SWITCH_MUTEX_UNNESTED, pool);
501
502 /* connect my internal structure to the blank pointer passed to me */
503 *module_interface = switch_loadable_module_create_module_interface(pool, modname);
504
505 SWITCH_ADD_CODEC(codec_interface, "DAHDI G.729A 8.0k"); /* 8.0kbit */
506
507 switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
508 18, /* the IANA code number */
509 "G729", /* the IANA code name */
510 NULL, /* default fmtp to send (can be overridden by the init function) */
511 8000, /* samples transferred per second */
512 8000, /* actual samples transferred per second */
513 8000, /* bits transferred per second */
514 mpf, /* number of microseconds per frame */
515 spf, /* number of samples per frame */
516 bpfd, /* number of bytes per frame decompressed */
517 bpfc, /* number of bytes per frame compressed */
518 1, /* number of channels represented */
519 fpnp, /* number of frames per network packet */
520 switch_dahdi_init, /* function to initialize a codec handle using this implementation */
521 switch_dahdi_encode, /* function to encode raw data into encoded data */
522 switch_dahdi_decode, /* function to decode encoded data into raw data */
523 switch_dahdi_destroy); /* deinitalize a codec handle using this implementation */
524
525 mpf = 30000;
526 spf = 240;
527 bpfd = 480;
528 bpfc = 30;
529 fpnp = 30;
530 switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
531 18, /* the IANA code number */
532 "G729", /* the IANA code name */
533 NULL, /* default fmtp to send (can be overridden by the init function) */
534 8000, /* samples transferred per second */
535 8000, /* actual samples transferred per second */
536 8000, /* bits transferred per second */
537 mpf, /* number of microseconds per frame */
538 spf, /* number of samples per frame */
539 bpfd, /* number of bytes per frame decompressed */
540 bpfc, /* number of bytes per frame compressed */
541 1, /* number of channels represented */
542 fpnp, /* number of frames per network packet */
543 switch_dahdi_init, /* function to initialize a codec handle using this implementation */
544 switch_dahdi_encode, /* function to encode raw data into encoded data */
545 switch_dahdi_decode, /* function to decode encoded data into raw data */
546 switch_dahdi_destroy); /* deinitalize a codec handle using this implementation */
547
548 SWITCH_ADD_CODEC(codec_interface, "DAHDI G.723.1 5.3k"); /* 5.3kbit */
549 mpf = 30000; /* Algorithmic delay of 37.5ms with 7.5ms of look-ahead delay */
550 spf = 240;
551 bpfd = 480;
552 bpfc = 20;
553 fpnp = 10;
554 switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */
555 4, /* the IANA code number */
556 "G723", /* the IANA code name */
557 NULL, /* default fmtp to send (can be overridden by the init function) */
558 8000, /* samples transferred per second */
559 8000, /* actual samples transferred per second */
560 8000, /* bits transferred per second */
561 mpf, /* number of microseconds per frame */
562 spf, /* number of samples per frame */
563 bpfd, /* number of bytes per frame decompressed */
564 bpfc, /* number of bytes per frame compressed */
565 1, /* number of channels represented */
566 fpnp, /* number of frames per network packet */
567 switch_dahdi_init, /* function to initialize a codec handle using this implementation */
568 switch_dahdi_encode, /* function to encode raw data into encoded data */
569 switch_dahdi_decode, /* function to decode encoded data into raw data */
570 switch_dahdi_destroy); /* deinitalize a codec handle using this implementation */
571
572 SWITCH_ADD_API(api_interface, "dahdi_transcode", "DAHDI Transcode", dahdi_transcode_usage, NULL);
573 switch_console_set_complete("add dahdi_transcode");
574 /* indicate that the module should continue to be loaded */
575 return SWITCH_STATUS_SUCCESS;
576 }
577
578 /* For Emacs:
579 * Local Variables:
580 * mode:c
581 * indent-tabs-mode:t
582 * tab-width:4
583 * c-basic-offset:4
584 * End:
585 * For VIM:
586 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
587 */
588