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