2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 2012, Luka Perkov
5 * Copyright (C) 2012, John Crispin
6 * Copyright (C) 2012, Andrej Vlašić
7 * Copyright (C) 2012, Kaspar Schleiser for T-Labs
8 * (Deutsche Telekom Innovation Laboratories)
9 * Copyright (C) 2012, Mirko Vogt for T-Labs
10 * (Deutsche Telekom Innovation Laboratories)
12 * Luka Perkov <openwrt@lukaperkov.net>
13 * John Crispin <blogic@openwrt.org>
14 * Andrej Vlašić <andrej.vlasic0@gmail.com>
15 * Kaspar Schleiser <kaspar@schleiser.de>
16 * Mirko Vogt <mirko@openwrt.org>
18 * See http://www.asterisk.org for more information about
19 * the Asterisk project. Please do not directly contact
20 * any of the maintainers of this project for assistance;
21 * the project provides a web site, mailing lists and IRC
22 * channels for your use.
24 * This program is free software, distributed under the terms of
25 * the GNU General Public License Version 2. See the LICENSE file
26 * at the top of the source tree.
31 * \brief Asterisk channel line driver for Lantiq based TAPI boards
33 * \author Luka Perkov <openwrt@lukaperkov.net>
34 * \author John Crispin <blogic@openwrt.org>
35 * \author Andrej Vlašić <andrej.vlasic0@gmail.com>
36 * \author Kaspar Schleiser <kaspar@schleiser.de>
37 * \author Mirko Vogt <mirko@openwrt.org>
39 * \ingroup channel_drivers
44 ASTERISK_FILE_VERSION(__FILE__, "$Revision: xxx $")
47 #include <sys/socket.h>
49 #include <arpa/inet.h>
51 #include <sys/ioctl.h>
53 #ifdef HAVE_LINUX_COMPILER_H
54 #include <linux/compiler.h>
56 #include <linux/telephony.h>
58 #include <asterisk/lock.h>
59 #include <asterisk/channel.h>
60 #include <asterisk/config.h>
61 #include <asterisk/module.h>
62 #include <asterisk/pbx.h>
63 #include <asterisk/utils.h>
64 #include <asterisk/callerid.h>
65 #include <asterisk/causes.h>
66 #include <asterisk/stringfields.h>
67 #include <asterisk/musiconhold.h>
68 #include <asterisk/sched.h>
70 /* Lantiq TAPI includes */
71 #include <drv_tapi/drv_tapi_io.h>
72 #include <drv_vmmc/vmmc_io.h>
74 #define RTP_HEADER_LEN 12
76 #define TAPI_AUDIO_PORT_NUM_MAX 2
77 #define TAPI_TONE_LOCALE_NONE 0
78 #define TAPI_TONE_LOCALE_RINGING_CODE 26
79 #define TAPI_TONE_LOCALE_BUSY_CODE 27
80 #define TAPI_TONE_LOCALE_CONGESTION_CODE 27
81 #define TAPI_TONE_LOCALE_DIAL_CODE 25
82 #define TAPI_TONE_LOCALE_WAITING_CODE 37
84 #define LANTIQ_CONTEXT_PREFIX "lantiq"
86 static const char config[] = "lantiq.conf";
88 static char firmware_filename[PATH_MAX] = "/lib/firmware/ifx_firmware.bin";
89 static char bbd_filename[PATH_MAX] = "/lib/firmware/ifx_bbd_fxs.bin";
90 static char base_path[PATH_MAX] = "/dev/vmmc";
91 static int per_channel_context = 0;
94 * The private structures of the Phone Jack channels are linked for selecting
107 static struct lantiq_pvt {
108 struct ast_channel *owner; /* Channel we belong to, possibly NULL */
109 int port_id; /* Port number of this object, 0..n */
111 char context[AST_MAX_CONTEXT]; /* this port's dialplan context */
112 char ext[AST_MAX_EXTENSION+1]; /* the extension this port is connecting*/
113 int dial_timer; /* timer handle for autodial timeout */
114 char dtmfbuf[AST_MAX_EXTENSION+1]; /* buffer holding dialed digits */
115 int dtmfbuf_len; /* lenght of dtmfbuf */
116 int rtp_timestamp; /* timestamp for RTP packets */
117 uint16_t rtp_seqno; /* Sequence nr for RTP packets */
120 static struct lantiq_ctx {
123 int ch_fd[TAPI_AUDIO_PORT_NUM_MAX];
126 static int ast_digit_begin(struct ast_channel *ast, char digit);
127 static int ast_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
128 static int ast_lantiq_call(struct ast_channel *ast, char *dest, int timeout);
129 static int ast_lantiq_hangup(struct ast_channel *ast);
130 static int ast_lantiq_answer(struct ast_channel *ast);
131 static struct ast_frame *ast_lantiq_read(struct ast_channel *ast);
132 static int ast_lantiq_write(struct ast_channel *ast, struct ast_frame *frame);
133 static struct ast_frame *ast_lantiq_exception(struct ast_channel *ast);
134 static int ast_lantiq_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
135 static int ast_lantiq_fixup(struct ast_channel *old, struct ast_channel *new);
136 static struct ast_channel *ast_lantiq_requester(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
138 static const struct ast_channel_tech lantiq_tech = {
140 .description = "Lantiq TAPI Telephony API Driver",
141 .capabilities = AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_G729A,
142 .send_digit_begin = ast_digit_begin,
143 .send_digit_end = ast_digit_end,
144 .call = ast_lantiq_call,
145 .hangup = ast_lantiq_hangup,
146 .answer = ast_lantiq_answer,
147 .read = ast_lantiq_read,
148 .write = ast_lantiq_write,
149 .exception = ast_lantiq_exception,
150 .indicate = ast_lantiq_indicate,
151 .fixup = ast_lantiq_fixup,
152 .requester = ast_lantiq_requester
155 /* Protect the interface list (of lantiq_pvt's) */
156 AST_MUTEX_DEFINE_STATIC(iflock);
159 * Protect the monitoring thread, so only one process can kill or start it, and
160 * not when it's doing something critical.
162 AST_MUTEX_DEFINE_STATIC(monlock);
164 /* Boolean value whether the monitoring thread shall continue. */
165 static unsigned int monitor;
167 /* The scheduling thread */
168 struct ast_sched_thread *sched_thread;
171 * This is the thread for the monitor which checks for input on the channels
172 * which are not currently in use.
174 static pthread_t monitor_thread = AST_PTHREADT_NULL;
177 #define WORDS_BIGENDIAN
178 /* struct taken from some GPLed code by Mike Borella */
179 typedef struct rtp_header
181 #if defined(WORDS_BIGENDIAN)
182 uint8_t version:2, padding:1, extension:1, csrc_count:4;
184 uint8_t csrc_count:4, extension:1, padding:1, version:2;
186 #if defined(WORDS_BIGENDIAN)
187 uint8_t marker:1, payload_type:7;
189 uint8_t payload_type:7, marker:1;
196 static int lantiq_dev_open(const char *dev_path, const int32_t ch_num)
198 char dev_name[PATH_MAX];
199 memset(dev_name, 0, sizeof(dev_name));
200 snprintf(dev_name, PATH_MAX, "%s%u%u", dev_path, 1, ch_num);
201 return open((const char*)dev_name, O_RDWR, 0644);
204 static void lantiq_ring(int c, int r)
209 status = (uint8_t) ioctl(dev_ctx.ch_fd[c], IFX_TAPI_RING_START, 0);
211 status = (uint8_t) ioctl(dev_ctx.ch_fd[c], IFX_TAPI_RING_STOP, 0);
215 ast_log(LOG_ERROR, "%s ioctl failed\n",
216 (r ? "IFX_TAPI_RING_START" : "IFX_TAPI_RING_STOP"));
220 static int lantiq_play_tone(int c, int t)
222 /* stop currently playing tone before starting new one */
223 if (t != TAPI_TONE_LOCALE_NONE) {
224 ioctl(dev_ctx.ch_fd[c], IFX_TAPI_TONE_LOCAL_PLAY, TAPI_TONE_LOCALE_NONE);
227 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_TONE_LOCAL_PLAY, t)) {
228 ast_log(LOG_ERROR, "IFX_TAPI_TONE_LOCAL_PLAY ioctl failed\n");
235 static enum channel_state lantiq_get_hookstatus(int port)
239 if (ioctl(dev_ctx.ch_fd[port], IFX_TAPI_LINE_HOOK_STATUS_GET, &status)) {
240 ast_log(LOG_ERROR, "IFX_TAPI_LINE_HOOK_STATUS_GET ioctl failed\n");
252 lantiq_dev_binary_buffer_create(const char *path, uint8_t **ppBuf, uint32_t *pBufSz)
255 struct stat file_stat;
258 fd = fopen(path, "rb");
260 ast_log(LOG_ERROR, "binary file %s open failed\n", path);
264 if (stat(path, &file_stat)) {
265 ast_log(LOG_ERROR, "file %s statistics get failed\n", path);
269 *ppBuf = malloc(file_stat.st_size);
270 if (*ppBuf == NULL) {
271 ast_log(LOG_ERROR, "binary file %s memory allocation failed\n", path);
276 if (fread (*ppBuf, sizeof(uint8_t), file_stat.st_size, fd) <= 0) {
277 ast_log(LOG_ERROR, "file %s read failed\n", path);
282 *pBufSz = file_stat.st_size;
288 if (*ppBuf != NULL && status)
294 static int32_t lantiq_dev_firmware_download(int32_t fd, const char *path)
296 uint8_t *firmware = NULL;
298 VMMC_IO_INIT vmmc_io_init;
300 ast_log(LOG_DEBUG, "loading firmware: \"%s\".", path);
302 if (lantiq_dev_binary_buffer_create(path, &firmware, &size))
305 memset(&vmmc_io_init, 0, sizeof(VMMC_IO_INIT));
306 vmmc_io_init.pPRAMfw = firmware;
307 vmmc_io_init.pram_size = size;
309 if (ioctl(fd, FIO_FW_DOWNLOAD, &vmmc_io_init)) {
310 ast_log(LOG_ERROR, "FIO_FW_DOWNLOAD ioctl failed\n");
314 if (firmware != NULL)
320 static const char *state_string(enum channel_state s)
323 case ONHOOK: return "ONHOOK";
324 case OFFHOOK: return "OFFHOOK";
325 case DIALING: return "DIALING";
326 case INCALL: return "INCALL";
327 case CALL_ENDED: return "CALL_ENDED";
328 case RINGING: return "RINGING";
329 default: return "UNKNOWN";
333 static const char *control_string(int c)
336 case AST_CONTROL_HANGUP: return "Other end has hungup";
337 case AST_CONTROL_RING: return "Local ring";
338 case AST_CONTROL_RINGING: return "Remote end is ringing";
339 case AST_CONTROL_ANSWER: return "Remote end has answered";
340 case AST_CONTROL_BUSY: return "Remote end is busy";
341 case AST_CONTROL_TAKEOFFHOOK: return "Make it go off hook";
342 case AST_CONTROL_OFFHOOK: return "Line is off hook";
343 case AST_CONTROL_CONGESTION: return "Congestion (circuits busy)";
344 case AST_CONTROL_FLASH: return "Flash hook";
345 case AST_CONTROL_WINK: return "Wink";
346 case AST_CONTROL_OPTION: return "Set a low-level option";
347 case AST_CONTROL_RADIO_KEY: return "Key Radio";
348 case AST_CONTROL_RADIO_UNKEY: return "Un-Key Radio";
349 case AST_CONTROL_PROGRESS: return "Remote end is making Progress";
350 case AST_CONTROL_PROCEEDING: return "Remote end is proceeding";
351 case AST_CONTROL_HOLD: return "Hold";
352 case AST_CONTROL_UNHOLD: return "Unhold";
353 case AST_CONTROL_SRCUPDATE: return "Media Source Update";
354 case AST_CONTROL_CONNECTED_LINE: return "Connected Line";
355 case AST_CONTROL_REDIRECTING: return "Redirecting";
356 case AST_CONTROL_INCOMPLETE: return "Incomplete";
357 case -1: return "Stop tone";
358 default: return "Unknown";
362 static int ast_lantiq_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
364 ast_verb(3, "phone indication \"%s\"\n", control_string(condition));
366 struct lantiq_pvt *pvt = chan->tech_pvt;
371 lantiq_play_tone(pvt->port_id, TAPI_TONE_LOCALE_NONE);
374 case AST_CONTROL_CONGESTION:
375 case AST_CONTROL_BUSY:
377 lantiq_play_tone(pvt->port_id, TAPI_TONE_LOCALE_BUSY_CODE);
380 case AST_CONTROL_RINGING:
382 lantiq_play_tone(pvt->port_id, TAPI_TONE_LOCALE_RINGING_CODE);
387 /* -1 lets asterisk generate the tone */
393 static int ast_lantiq_fixup(struct ast_channel *old, struct ast_channel *new)
395 ast_log(LOG_DEBUG, "entering... no code here...\n");
399 static int ast_digit_begin(struct ast_channel *chan, char digit)
401 /* TODO: Modify this callback to let Asterisk support controlling the length of DTMF */
402 ast_log(LOG_DEBUG, "entering... no code here...\n");
406 static int ast_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
408 ast_log(LOG_DEBUG, "entering... no code here...\n");
412 static int ast_lantiq_call(struct ast_channel *ast, char *dest, int timeout)
414 /* lock to prevent simultaneous access with do_monitor thread processing */
415 ast_mutex_lock(&iflock);
417 struct lantiq_pvt *pvt = ast->tech_pvt;
418 ast_log(LOG_DEBUG, "state: %s\n", state_string(pvt->channel_state));
420 if (pvt->channel_state == ONHOOK) {
421 ast_log(LOG_DEBUG, "port %i is ringing\n", pvt->port_id);
422 lantiq_ring(pvt->port_id, 1);
423 pvt->channel_state = RINGING;
425 ast_setstate(ast, AST_STATE_RINGING);
426 ast_queue_control(ast, AST_CONTROL_RINGING);
428 ast_log(LOG_DEBUG, "port %i is busy\n", pvt->port_id);
429 ast_setstate(ast, AST_STATE_BUSY);
430 ast_queue_control(ast, AST_CONTROL_BUSY);
433 ast_mutex_unlock(&iflock);
438 static int ast_lantiq_hangup(struct ast_channel *ast)
440 /* lock to prevent simultaneous access with do_monitor thread processing */
441 ast_mutex_lock(&iflock);
443 struct lantiq_pvt *pvt = ast->tech_pvt;
444 ast_log(LOG_DEBUG, "state: %s\n", state_string(pvt->channel_state));
446 if (ast->_state == AST_STATE_RINGING) {
448 ast_debug(1, "TAPI: ast_lantiq_hangup(): ast->_state == AST_STATE_RINGING\n");
451 switch (pvt->channel_state) {
454 lantiq_ring(pvt->port_id, 0);
455 pvt->channel_state = ONHOOK;
458 ast_log(LOG_DEBUG, "we were hung up, play busy tone\n");
459 pvt->channel_state = CALL_ENDED;
460 lantiq_play_tone(pvt->port_id, TAPI_TONE_LOCALE_BUSY_CODE);
463 ast_setstate(ast, AST_STATE_DOWN);
464 ast_module_unref(ast_module_info->self);
465 ast->tech_pvt = NULL;
468 ast_mutex_unlock(&iflock);
473 static int ast_lantiq_answer(struct ast_channel *ast)
475 ast_log(LOG_DEBUG, "entering... no code here...\n");
479 static struct ast_frame * ast_lantiq_read(struct ast_channel *ast)
481 ast_log(LOG_DEBUG, "entering... no code here...\n");
485 static int ast_lantiq_write(struct ast_channel *ast, struct ast_frame *frame)
488 struct lantiq_pvt *pvt = ast->tech_pvt;
490 rtp_header_t *rtp_header = (rtp_header_t *) buf;
492 if(frame->frametype != AST_FRAME_VOICE) {
493 ast_log(LOG_DEBUG, "unhandled frame type\n");
497 if (frame->datalen == 0) {
498 ast_log(LOG_DEBUG, "we've been prodded\n");
502 memset(buf, 0, sizeof(rtp_header_t));
503 rtp_header->version = 2;
504 rtp_header->padding = 0;
505 rtp_header->extension = 0;
506 rtp_header->csrc_count = 0;
507 rtp_header->marker = 0;
508 rtp_header->timestamp = pvt->rtp_timestamp;
509 rtp_header->seqno = pvt->rtp_seqno++;
510 rtp_header->ssrc = 0;
511 rtp_header->payload_type = (uint8_t) frame->subclass.codec;
513 pvt->rtp_timestamp += 160;
515 memcpy(buf+RTP_HEADER_LEN, frame->data.ptr, frame->datalen);
517 ret = write(dev_ctx.ch_fd[pvt->port_id], buf, frame->datalen+RTP_HEADER_LEN);
519 ast_debug(1, "TAPI: ast_lantiq_write(): error writing.\n");
523 #ifdef TODO_DEVEL_INFO
524 ast_debug(1, "ast_lantiq_write(): size: %i version: %i padding: %i extension: %i csrc_count: %i\n"
525 "marker: %i payload_type: %s seqno: %i timestamp: %i ssrc: %i\n",
527 (int)rtp_header->version,
528 (int)rtp_header->padding,
529 (int)rtp_header->extension,
530 (int)rtp_header->csrc_count,
531 (int)rtp_header->marker,
532 ast_codec2str(rtp_header->payload_type),
533 (int)rtp_header->seqno,
534 (int)rtp_header->timestamp,
535 (int)rtp_header->ssrc);
541 static struct ast_frame * ast_lantiq_exception(struct ast_channel *ast)
543 ast_log(LOG_DEBUG, "entering... no code here...\n");
547 static int lantiq_standby(int c)
549 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_LINE_FEED_SET, IFX_TAPI_LINE_FEED_STANDBY)) {
550 ast_log(LOG_ERROR, "IFX_TAPI_LINE_FEED_SET ioctl failed\n");
554 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_ENC_STOP, 0)) {
555 ast_log(LOG_ERROR, "IFX_TAPI_ENC_STOP ioctl failed\n");
559 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_DEC_STOP, 0)) {
560 ast_log(LOG_ERROR, "IFX_TAPI_DEC_STOP ioctl failed\n");
564 return lantiq_play_tone(c, TAPI_TONE_LOCALE_NONE);
567 static int lantiq_end_dialing(int c)
569 ast_log(LOG_DEBUG, "TODO - DEBUG MSG");
570 struct lantiq_pvt *pvt = &iflist[c];
572 if (pvt->dial_timer) {
573 ast_sched_thread_del(sched_thread, pvt->dial_timer);
578 ast_hangup(pvt->owner);
584 static int lantiq_end_call(int c)
586 ast_log(LOG_DEBUG, "TODO - DEBUG MSG");
588 struct lantiq_pvt *pvt = &iflist[c];
591 ast_queue_hangup(pvt->owner);
597 static struct ast_channel * lantiq_channel(int state, int c, char *ext, char *ctx)
599 ast_log(LOG_DEBUG, "TODO - DEBUG MSG");
601 struct ast_channel *chan = NULL;
603 struct lantiq_pvt *pvt = &iflist[c];
605 chan = ast_channel_alloc(1, state, NULL, NULL, "", ext, ctx, 0, c, "TAPI/%s", "1");
607 chan->tech = &lantiq_tech;
608 chan->nativeformats = AST_FORMAT_ULAW;
609 chan->readformat = AST_FORMAT_ULAW;
610 chan->writeformat = AST_FORMAT_ULAW;
611 chan->tech_pvt = pvt;
618 static struct ast_channel * ast_lantiq_requester(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
620 ast_mutex_lock(&iflock);
623 struct ast_channel *chan = NULL;
626 ast_debug(1, "Asked to create a TAPI channel with formats: %s\n", ast_getformatname_multiple(buf, sizeof(buf), format));
629 /* check for correct data argument */
630 if (ast_strlen_zero(data)) {
631 ast_log(LOG_ERROR, "Unable to create channel with empty destination.\n");
632 *cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
636 /* get our port number */
637 port_id = atoi((char*) data);
638 if (port_id < 1 || port_id > dev_ctx.channels) {
639 ast_log(LOG_ERROR, "Unknown channel ID: \"%s\"\n", (char*) data);
640 *cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
644 /* on asterisk user's side, we're using port 1-2.
645 * Here in non normal human's world, we begin
650 chan = lantiq_channel(AST_STATE_DOWN, port_id, NULL, NULL);
652 ast_mutex_unlock(&iflock);
656 static int lantiq_dev_data_handler(int c)
659 struct ast_frame frame = {0};
661 int res = read(dev_ctx.ch_fd[c], buf, sizeof(buf));
662 if (res <= 0) ast_log(LOG_ERROR, "we got read error %i\n", res);
664 rtp_header_t *rtp = (rtp_header_t*) buf;
667 frame.frametype = AST_FRAME_VOICE;
668 frame.subclass.codec = rtp->payload_type;
669 frame.samples = res - RTP_HEADER_LEN;
670 frame.datalen = res - RTP_HEADER_LEN;
671 frame.data.ptr = buf + RTP_HEADER_LEN;
673 ast_mutex_lock(&iflock);
674 struct lantiq_pvt *pvt = (struct lantiq_pvt *) &iflist[c];
675 if (pvt->owner && (pvt->owner->_state == AST_STATE_UP)) {
676 if(!ast_channel_trylock(pvt->owner)) {
677 ast_queue_frame(pvt->owner, &frame);
678 ast_channel_unlock(pvt->owner);
682 ast_mutex_unlock(&iflock);
684 /* ast_debug(1, "lantiq_dev_data_handler(): size: %i version: %i padding: %i extension: %i csrc_count: %i \n"
685 "marker: %i payload_type: %s seqno: %i timestamp: %i ssrc: %i\n",
690 (int)rtp->csrc_count,
692 ast_codec2str(rtp->payload_type),
700 static int accept_call(int c)
702 ast_log(LOG_DEBUG, "TODO - DEBUG MSG");
704 struct lantiq_pvt *pvt = &iflist[c];
707 struct ast_channel *chan = pvt->owner;
709 switch (chan->_state) {
710 case AST_STATE_RINGING:
711 ast_queue_control(pvt->owner, AST_CONTROL_ANSWER);
712 pvt->channel_state = INCALL;
715 ast_log(LOG_WARNING, "entered unhandled state %s\n", ast_state2str(chan->_state));
722 static int lantiq_dev_event_hook(int c, int state)
724 ast_mutex_lock(&iflock);
726 ast_log(LOG_DEBUG, "on port %i detected event %s hook\n", c, state ? "on" : "off");
730 switch (iflist[c].channel_state) {
732 ret = lantiq_standby(c);
735 ret = lantiq_end_dialing(c);
738 ret = lantiq_end_call(c);
741 ret = lantiq_standby(c); // TODO: are we sure for this ?
746 iflist[c].channel_state = ONHOOK;
748 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_LINE_FEED_SET, IFX_TAPI_LINE_FEED_ACTIVE)) {
749 ast_log(LOG_ERROR, "IFX_TAPI_LINE_FEED_SET ioctl failed\n");
753 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_ENC_START, 0)) {
754 ast_log(LOG_ERROR, "IFX_TAPI_ENC_START ioctl failed\n");
758 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_DEC_START, 0)) {
759 ast_log(LOG_ERROR, "IFX_TAPI_DEC_START ioctl failed\n");
763 switch (iflist[c].channel_state) {
765 ret = accept_call(c);
768 iflist[c].channel_state = OFFHOOK;
769 lantiq_play_tone(c, TAPI_TONE_LOCALE_DIAL_CODE);
777 ast_mutex_unlock(&iflock);
782 static void lantiq_reset_dtmfbuf(struct lantiq_pvt *pvt)
784 pvt->dtmfbuf[0] = '\0';
785 pvt->dtmfbuf_len = 0;
789 static void lantiq_dial(struct lantiq_pvt *pvt)
791 struct ast_channel *chan = NULL;
793 ast_log(LOG_DEBUG, "user want's to dial %s.\n", pvt->dtmfbuf);
795 if (ast_exists_extension(NULL, pvt->context, pvt->dtmfbuf, 1, NULL)) {
796 ast_debug(1, "found extension %s, dialing\n", pvt->dtmfbuf);
798 strcpy(pvt->ext, pvt->dtmfbuf);
800 ast_verbose(VERBOSE_PREFIX_3 " extension exists, starting PBX %s\n", pvt->ext);
802 chan = lantiq_channel(AST_STATE_UP, 1, pvt->ext+1, pvt->context);
803 chan->tech_pvt = pvt;
806 strcpy(chan->exten, pvt->ext);
807 ast_setstate(chan, AST_STATE_RING);
808 pvt->channel_state = INCALL;
810 if (ast_pbx_start(chan)) {
811 ast_log(LOG_WARNING, " unable to start PBX on %s\n", chan->name);
815 ast_log(LOG_DEBUG, "no extension found\n");
816 lantiq_play_tone(pvt->port_id, TAPI_TONE_LOCALE_BUSY_CODE);
817 pvt->channel_state = CALL_ENDED;
820 lantiq_reset_dtmfbuf(pvt);
823 static int lantiq_event_dial_timeout(const void* data)
825 ast_debug(1, "TAPI: lantiq_event_dial_timeout()\n");
827 struct lantiq_pvt *pvt = (struct lantiq_pvt *) data;
830 if (! pvt->channel_state == ONHOOK) {
833 ast_debug(1, "TAPI: lantiq_event_dial_timeout(): dial timeout in state ONHOOK.\n");
839 static int lantiq_send_digit(int c, char digit)
841 struct lantiq_pvt *pvt = &iflist[c];
843 struct ast_frame f = { .frametype = AST_FRAME_DTMF, .subclass.integer = digit };
846 ast_log(LOG_DEBUG, "Port %i transmitting digit \"%c\"\n", c, digit);
847 return ast_queue_frame(pvt->owner, &f);
849 ast_debug(1, "Warning: lantiq_send_digit() without owner!\n");
854 static void lantiq_dev_event_digit(int c, char digit)
856 ast_mutex_lock(&iflock);
858 ast_log(LOG_DEBUG, "on port %i detected digit \"%c\"\n", c, digit);
860 struct lantiq_pvt *pvt = &iflist[c];
862 switch (pvt->channel_state) {
865 lantiq_send_digit(c, digit);
869 pvt->channel_state = DIALING;
871 lantiq_play_tone(c, TAPI_TONE_LOCALE_NONE);
876 if (pvt->dial_timer) {
877 ast_sched_thread_del(sched_thread, pvt->dial_timer);
883 pvt->dtmfbuf[pvt->dtmfbuf_len] = digit;
885 pvt->dtmfbuf[pvt->dtmfbuf_len] = '\0';
887 /* setup autodial timer */
888 if (!pvt->dial_timer) {
889 ast_log(LOG_DEBUG, "setting new timer\n");
890 pvt->dial_timer = ast_sched_thread_add(sched_thread, 2000, lantiq_event_dial_timeout, (const void*) pvt);
892 ast_log(LOG_DEBUG, "replacing timer\n");
893 struct sched_context *sched = ast_sched_thread_get_context(sched_thread);
894 AST_SCHED_REPLACE(pvt->dial_timer, sched, 2000, lantiq_event_dial_timeout, (const void*) pvt);
899 ast_log(LOG_ERROR, "don't know what to do in unhandled state\n");
903 ast_mutex_unlock(&iflock);
907 static void lantiq_dev_event_handler(void)
909 IFX_TAPI_EVENT_t event;
912 for (i = 0; i < dev_ctx.channels ; i++) {
913 ast_mutex_lock(&iflock);
915 memset (&event, 0, sizeof(event));
917 if (ioctl(dev_ctx.dev_fd, IFX_TAPI_EVENT_GET, &event)) {
918 ast_mutex_unlock(&iflock);
921 if (event.id == IFX_TAPI_EVENT_NONE) {
922 ast_mutex_unlock(&iflock);
926 ast_mutex_unlock(&iflock);
929 case IFX_TAPI_EVENT_FXS_ONHOOK:
930 lantiq_dev_event_hook(i, 1);
932 case IFX_TAPI_EVENT_FXS_OFFHOOK:
933 lantiq_dev_event_hook(i, 0);
935 case IFX_TAPI_EVENT_DTMF_DIGIT:
936 lantiq_dev_event_digit(i, (char)event.data.dtmf.ascii);
938 case IFX_TAPI_EVENT_PULSE_DIGIT:
939 if (event.data.pulse.digit == 0xB) {
940 lantiq_dev_event_digit(i, '0');
942 lantiq_dev_event_digit(i, '0' + (char)event.data.pulse.digit);
945 case IFX_TAPI_EVENT_COD_DEC_CHG:
946 case IFX_TAPI_EVENT_TONE_GEN_END:
947 case IFX_TAPI_EVENT_CID_TX_SEQ_END:
950 ast_log(LOG_ERROR, "unknown TAPI event %08X\n", event.id);
956 static void * lantiq_events_monitor(void *data)
958 ast_verbose("TAPI thread started\n");
960 struct pollfd fds[3];
962 fds[0].fd = dev_ctx.dev_fd;
963 fds[0].events = POLLIN;
964 fds[1].fd = dev_ctx.ch_fd[0];
965 fds[1].events = POLLIN;
966 fds[2].fd = dev_ctx.ch_fd[1];
967 fds[2].events = POLLIN;
970 ast_mutex_lock(&monlock);
972 if (poll(fds, dev_ctx.channels + 1, 2000) <= 0) {
973 ast_mutex_unlock(&monlock);
977 if (fds[0].revents & POLLIN) {
978 lantiq_dev_event_handler();
981 ast_mutex_unlock(&monlock);
983 if ((fds[1].revents & POLLIN) && (lantiq_dev_data_handler(0))) {
984 ast_log(LOG_ERROR, "data handler 0 failed\n");
988 if ((fds[2].revents & POLLIN) && (lantiq_dev_data_handler(1))) {
989 ast_log(LOG_ERROR, "data handler 1 failed\n");
997 static int restart_monitor(void)
999 /* If we're supposed to be stopped -- stay stopped */
1000 if (monitor_thread == AST_PTHREADT_STOP)
1003 ast_mutex_lock(&monlock);
1005 if (monitor_thread == pthread_self()) {
1006 ast_mutex_unlock(&monlock);
1007 ast_log(LOG_WARNING, "Cannot kill myself\n");
1011 if (monitor_thread != AST_PTHREADT_NULL) {
1012 if (ast_mutex_lock(&iflock)) {
1013 ast_mutex_unlock(&monlock);
1014 ast_log(LOG_WARNING, "Unable to lock the interface list\n");
1018 while (pthread_kill(monitor_thread, SIGURG) == 0)
1020 pthread_join(monitor_thread, NULL);
1021 ast_mutex_unlock(&iflock);
1025 /* Start a new monitor */
1026 if (ast_pthread_create_background(&monitor_thread, NULL, lantiq_events_monitor, NULL) < 0) {
1027 ast_mutex_unlock(&monlock);
1028 ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
1032 ast_mutex_unlock(&monlock);
1037 static void lantiq_cleanup(void)
1041 for (c = 0; c < dev_ctx.channels ; c++) {
1042 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_LINE_FEED_SET, IFX_TAPI_LINE_FEED_STANDBY)) {
1043 ast_log(LOG_WARNING, "IFX_TAPI_LINE_FEED_SET ioctl failed\n");
1046 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_ENC_STOP, 0)) {
1047 ast_log(LOG_WARNING, "IFX_TAPI_ENC_STOP ioctl failed\n");
1050 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_DEC_STOP, 0)) {
1051 ast_log(LOG_WARNING, "IFX_TAPI_DEC_STOP ioctl failed\n");
1055 if (ioctl(dev_ctx.dev_fd, IFX_TAPI_DEV_STOP, 0)) {
1056 ast_log(LOG_WARNING, "IFX_TAPI_DEV_STOP ioctl failed\n");
1059 close(dev_ctx.dev_fd);
1062 static int unload_module(void)
1066 ast_channel_unregister(&lantiq_tech);
1068 if (!ast_mutex_lock(&iflock)) {
1069 for (c = 0; c < dev_ctx.channels ; c++) {
1070 if (iflist[c].owner)
1071 ast_softhangup(iflist[c].owner, AST_SOFTHANGUP_APPUNLOAD);
1073 ast_mutex_unlock(&iflock);
1075 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
1079 if (!ast_mutex_lock(&monlock)) {
1080 if (monitor_thread > AST_PTHREADT_NULL) {
1082 while (pthread_kill(monitor_thread, SIGURG) == 0)
1084 pthread_join(monitor_thread, NULL);
1086 monitor_thread = AST_PTHREADT_STOP;
1087 ast_mutex_unlock(&monlock);
1089 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
1096 static struct lantiq_pvt *lantiq_init_pvt(struct lantiq_pvt *pvt)
1101 pvt->channel_state = UNKNOWN;
1102 pvt->context[0] = '\0';
1104 pvt->dial_timer = 0;
1105 pvt->dtmfbuf[0] = '\0';
1106 pvt->dtmfbuf_len = 0;
1108 ast_log(LOG_ERROR, "unable to clear pvt structure\n");
1114 static int lantiq_create_pvts(void)
1118 iflist = ast_calloc(1, sizeof(struct lantiq_pvt) * dev_ctx.channels);
1121 for (i=0 ; i<dev_ctx.channels ; i++) {
1122 lantiq_init_pvt(&iflist[i]);
1123 iflist[i].port_id = i;
1124 if (per_channel_context) {
1125 snprintf(iflist[i].context, AST_MAX_CONTEXT, "%s%i", LANTIQ_CONTEXT_PREFIX, i+1);
1126 ast_debug(1, "Context for channel %i: %s\n", i, iflist[i].context);
1128 snprintf(iflist[i].context, AST_MAX_CONTEXT, "default");
1133 ast_log(LOG_ERROR, "unable to allocate memory\n");
1138 static int lantiq_setup_rtp(int c)
1140 /* Configure RTP payload type tables */
1141 IFX_TAPI_PKT_RTP_PT_CFG_t rtpPTConf;
1143 memset((char*)&rtpPTConf, '\0', sizeof(rtpPTConf));
1145 rtpPTConf.nPTup[IFX_TAPI_COD_TYPE_MLAW] = AST_FORMAT_ULAW;
1146 rtpPTConf.nPTup[IFX_TAPI_COD_TYPE_ALAW] = AST_FORMAT_ALAW;
1147 // rtpPTConf.nPTup[IFX_TAPI_COD_TYPE_G723_63] = AST_FORMAT_G723_1;
1148 // rtpPTConf.nPTup[IFX_TAPI_COD_TYPE_G723_53] = 4;
1149 // rtpPTConf.nPTup[IFX_TAPI_COD_TYPE_G729] = AST_FORMAT_G729A;
1150 // rtpPTConf.nPTup[IFX_TAPI_COD_TYPE_G722_64] = AST_FORMAT_G722;
1152 rtpPTConf.nPTdown[IFX_TAPI_COD_TYPE_MLAW] = AST_FORMAT_ULAW;
1153 rtpPTConf.nPTdown[IFX_TAPI_COD_TYPE_ALAW] = AST_FORMAT_ALAW;
1154 // rtpPTConf.nPTdown[IFX_TAPI_COD_TYPE_G723_63] = AST_FORMAT_G723_1;
1155 // rtpPTConf.nPTdown[IFX_TAPI_COD_TYPE_G723_53] = AST_FORMAT_G723_1;
1156 // rtpPTConf.nPTdown[IFX_TAPI_COD_TYPE_G729] = AST_FORMAT_G729A;
1157 // rtpPTConf.nPTdown[IFX_TAPI_COD_TYPE_G722_64] = AST_FORMAT_G722;
1160 if ((ret = ioctl(dev_ctx.ch_fd[c], IFX_TAPI_PKT_RTP_PT_CFG_SET, (IFX_int32_t) &rtpPTConf))) {
1161 ast_log(LOG_ERROR, "IFX_TAPI_PKT_RTP_PT_CFG_SET failed: ret=%i\n", ret);
1168 static int load_module(void)
1170 struct ast_config *cfg;
1171 struct ast_variable *v;
1179 int jb_type = IFX_TAPI_JB_TYPE_ADAPTIVE;
1180 int jb_pckadpt = IFX_TAPI_JB_PKT_ADAPT_VOICE;
1181 int jb_localadpt = IFX_TAPI_JB_LOCAL_ADAPT_DEFAULT;
1182 int jb_scaling = 0x10;
1183 int jb_initialsize = 0x2d0;
1184 int jb_minsize = 0x50;
1185 int jb_maxsize = 0x5a0;
1186 int cid_type = IFX_TAPI_CID_STD_TELCORDIA;
1187 int vad_type = IFX_TAPI_ENC_VAD_NOVAD;
1188 dev_ctx.channels = TAPI_AUDIO_PORT_NUM_MAX;
1189 struct ast_flags config_flags = { 0 };
1191 if (!(sched_thread = ast_sched_thread_create())) {
1192 ast_log(LOG_ERROR, "Unable to create scheduler thread\n");
1193 return AST_MODULE_LOAD_FAILURE;
1196 if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) {
1197 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config);
1198 return AST_MODULE_LOAD_DECLINE;
1201 /* We *must* have a config file otherwise stop immediately */
1203 ast_log(LOG_ERROR, "Unable to load config %s\n", config);
1204 return AST_MODULE_LOAD_DECLINE;
1207 if (ast_mutex_lock(&iflock)) {
1208 ast_log(LOG_ERROR, "Unable to lock interface list.\n");
1209 return AST_MODULE_LOAD_FAILURE;
1212 for (v = ast_variable_browse(cfg, "interfaces"); v; v = v->next) {
1213 if (!strcasecmp(v->name, "channels")) {
1214 dev_ctx.channels = atoi(v->value);
1215 if (!dev_ctx.channels) {
1216 ast_log(LOG_ERROR, "Invalid value for channels in config %s\n", config);
1217 ast_config_destroy(cfg);
1218 return AST_MODULE_LOAD_DECLINE;
1220 } else if (!strcasecmp(v->name, "firmwarefilename")) {
1221 ast_copy_string(firmware_filename, v->value, sizeof(firmware_filename));
1222 } else if (!strcasecmp(v->name, "bbdfilename")) {
1223 ast_copy_string(bbd_filename, v->value, sizeof(bbd_filename));
1224 } else if (!strcasecmp(v->name, "basepath")) {
1225 ast_copy_string(base_path, v->value, sizeof(base_path));
1226 } else if (!strcasecmp(v->name, "per_channel_context")) {
1227 if (!strcasecmp(v->value, "on")) {
1228 per_channel_context = 1;
1229 } else if (!strcasecmp(v->value, "off")) {
1230 per_channel_context = 0;
1232 ast_log(LOG_ERROR, "Unknown per_channel_context value '%s'. Try 'on' or 'off'.\n", v->value);
1233 ast_config_destroy(cfg);
1234 return AST_MODULE_LOAD_DECLINE;
1239 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
1240 if (!strcasecmp(v->name, "rxgain")) {
1241 rxgain = atoi(v->value);
1244 ast_log(LOG_WARNING, "Invalid rxgain: %s, using default.\n", v->value);
1246 } else if (!strcasecmp(v->name, "txgain")) {
1247 txgain = atoi(v->value);
1250 ast_log(LOG_WARNING, "Invalid txgain: %s, using default.\n", v->value);
1252 } else if (!strcasecmp(v->name, "echocancel")) {
1253 if (!strcasecmp(v->value, "off")) {
1254 wlec_type = IFX_TAPI_WLEC_TYPE_OFF;
1255 } else if (!strcasecmp(v->value, "nlec")) {
1256 wlec_type = IFX_TAPI_WLEC_TYPE_NE;
1257 if (!strcasecmp(v->name, "echocancelfixedwindowsize")) {
1258 wlec_nbne = atoi(v->value);
1260 } else if (!strcasecmp(v->value, "wlec")) {
1261 wlec_type = IFX_TAPI_WLEC_TYPE_NFE;
1262 if (!strcasecmp(v->name, "echocancelnfemovingwindowsize")) {
1263 wlec_nbfe = atoi(v->value);
1264 } else if (!strcasecmp(v->name, "echocancelfixedwindowsize")) {
1265 wlec_nbne = atoi(v->value);
1266 } else if (!strcasecmp(v->name, "echocancelwidefixedwindowsize")) {
1267 wlec_wbne = atoi(v->value);
1269 } else if (!strcasecmp(v->value, "nees")) {
1270 wlec_type = IFX_TAPI_WLEC_TYPE_NE_ES;
1271 } else if (!strcasecmp(v->value, "nfees")) {
1272 wlec_type = IFX_TAPI_WLEC_TYPE_NFE_ES;
1273 } else if (!strcasecmp(v->value, "es")) {
1274 wlec_type = IFX_TAPI_WLEC_TYPE_ES;
1276 wlec_type = IFX_TAPI_WLEC_TYPE_OFF;
1277 ast_log(LOG_ERROR, "Unknown echo cancellation type '%s'\n", v->value);
1278 ast_config_destroy(cfg);
1279 return AST_MODULE_LOAD_DECLINE;
1281 } else if (!strcasecmp(v->name, "echocancelnlp")) {
1282 if (!strcasecmp(v->value, "on")) {
1283 wlec_nlp = IFX_TAPI_WLEC_NLP_ON;
1284 } else if (!strcasecmp(v->value, "off")) {
1285 wlec_nlp = IFX_TAPI_WLEC_NLP_OFF;
1287 ast_log(LOG_ERROR, "Unknown echo cancellation nlp '%s'\n", v->value);
1288 ast_config_destroy(cfg);
1289 return AST_MODULE_LOAD_DECLINE;
1291 } else if (!strcasecmp(v->name, "jitterbuffertype")) {
1292 if (!strcasecmp(v->value, "fixed")) {
1293 jb_type = IFX_TAPI_JB_TYPE_FIXED;
1294 } else if (!strcasecmp(v->value, "adaptive")) {
1295 jb_type = IFX_TAPI_JB_TYPE_ADAPTIVE;
1296 jb_localadpt = IFX_TAPI_JB_LOCAL_ADAPT_DEFAULT;
1297 if (!strcasecmp(v->name, "jitterbufferadaptation")) {
1298 if (!strcasecmp(v->value, "on")) {
1299 jb_localadpt = IFX_TAPI_JB_LOCAL_ADAPT_ON;
1300 } else if (!strcasecmp(v->value, "off")) {
1301 jb_localadpt = IFX_TAPI_JB_LOCAL_ADAPT_OFF;
1303 } else if (!strcasecmp(v->name, "jitterbufferscalling")) {
1304 jb_scaling = atoi(v->value);
1305 } else if (!strcasecmp(v->name, "jitterbufferinitialsize")) {
1306 jb_initialsize = atoi(v->value);
1307 } else if (!strcasecmp(v->name, "jitterbufferminsize")) {
1308 jb_minsize = atoi(v->value);
1309 } else if (!strcasecmp(v->name, "jitterbuffermaxsize")) {
1310 jb_maxsize = atoi(v->value);
1313 ast_log(LOG_ERROR, "Unknown jitter buffer type '%s'\n", v->value);
1314 ast_config_destroy(cfg);
1315 return AST_MODULE_LOAD_DECLINE;
1317 } else if (!strcasecmp(v->name, "jitterbufferpackettype")) {
1318 if (!strcasecmp(v->value, "voice")) {
1319 jb_pckadpt = IFX_TAPI_JB_PKT_ADAPT_VOICE;
1320 } else if (!strcasecmp(v->value, "data")) {
1321 jb_pckadpt = IFX_TAPI_JB_PKT_ADAPT_DATA;
1322 } else if (!strcasecmp(v->value, "datanorep")) {
1323 jb_pckadpt = IFX_TAPI_JB_PKT_ADAPT_DATA_NO_REP;
1325 ast_log(LOG_ERROR, "Unknown jitter buffer packet adaptation type '%s'\n", v->value);
1326 ast_config_destroy(cfg);
1327 return AST_MODULE_LOAD_DECLINE;
1329 } else if (!strcasecmp(v->name, "calleridtype")) {
1330 if (!strcasecmp(v->value, "telecordia")) {
1331 cid_type = IFX_TAPI_CID_STD_TELCORDIA;
1332 } else if (!strcasecmp(v->value, "etsifsk")) {
1333 cid_type = IFX_TAPI_CID_STD_ETSI_FSK;
1334 } else if (!strcasecmp(v->value, "etsidtmf")) {
1335 cid_type = IFX_TAPI_CID_STD_ETSI_DTMF;
1336 } else if (!strcasecmp(v->value, "sin")) {
1337 cid_type = IFX_TAPI_CID_STD_SIN;
1338 } else if (!strcasecmp(v->value, "ntt")) {
1339 cid_type = IFX_TAPI_CID_STD_NTT;
1340 } else if (!strcasecmp(v->value, "kpndtmf")) {
1341 cid_type = IFX_TAPI_CID_STD_KPN_DTMF;
1342 } else if (!strcasecmp(v->value, "kpndtmffsk")) {
1343 cid_type = IFX_TAPI_CID_STD_KPN_DTMF_FSK;
1345 ast_log(LOG_ERROR, "Unknown caller id type '%s'\n", v->value);
1346 ast_config_destroy(cfg);
1347 return AST_MODULE_LOAD_DECLINE;
1349 } else if (!strcasecmp(v->name, "voiceactivitydetection")) {
1350 if (!strcasecmp(v->value, "on")) {
1351 vad_type = IFX_TAPI_ENC_VAD_ON;
1352 } else if (!strcasecmp(v->value, "g711")) {
1353 vad_type = IFX_TAPI_ENC_VAD_G711;
1354 } else if (!strcasecmp(v->value, "cng")) {
1355 vad_type = IFX_TAPI_ENC_VAD_CNG_ONLY;
1356 } else if (!strcasecmp(v->value, "sc")) {
1357 vad_type = IFX_TAPI_ENC_VAD_SC_ONLY;
1359 ast_log(LOG_ERROR, "Unknown voice activity detection value '%s'\n", v->value);
1360 ast_config_destroy(cfg);
1361 return AST_MODULE_LOAD_DECLINE;
1366 lantiq_create_pvts();
1368 ast_mutex_unlock(&iflock);
1370 if (ast_channel_register(&lantiq_tech)) {
1371 ast_log(LOG_ERROR, "Unable to register channel class 'Phone'\n");
1372 ast_config_destroy(cfg);
1374 return AST_MODULE_LOAD_FAILURE;
1376 ast_config_destroy(cfg);
1380 IFX_TAPI_TONE_t tone;
1382 IFX_TAPI_DEV_START_CFG_t dev_start;
1383 IFX_TAPI_MAP_DATA_t map_data;
1384 IFX_TAPI_ENC_CFG_t enc_cfg;
1385 IFX_TAPI_LINE_VOLUME_t line_vol;
1386 IFX_TAPI_WLEC_CFG_t wlec_cfg;
1387 IFX_TAPI_JB_CFG_t jb_cfg;
1388 IFX_TAPI_CID_CFG_t cid_cfg;
1392 dev_ctx.dev_fd = lantiq_dev_open(base_path, 0);
1394 if (dev_ctx.dev_fd < 0) {
1395 ast_log(LOG_ERROR, "lantiq tapi device open function failed\n");
1396 return AST_MODULE_LOAD_FAILURE;
1399 for (c = 0; c < dev_ctx.channels ; c++) {
1400 dev_ctx.ch_fd[c] = lantiq_dev_open(base_path, c + 1);
1402 if (dev_ctx.ch_fd[c] < 0) {
1403 ast_log(LOG_ERROR, "lantiq tapi channel %d open function failed\n", c);
1404 return AST_MODULE_LOAD_FAILURE;
1408 if (lantiq_dev_firmware_download(dev_ctx.dev_fd, firmware_filename)) {
1409 ast_log(LOG_ERROR, "voice firmware download failed\n");
1410 return AST_MODULE_LOAD_FAILURE;
1413 if (ioctl(dev_ctx.dev_fd, IFX_TAPI_DEV_STOP, 0)) {
1414 ast_log(LOG_ERROR, "IFX_TAPI_DEV_STOP ioctl failed\n");
1415 return AST_MODULE_LOAD_FAILURE;
1418 memset(&dev_start, 0x0, sizeof(IFX_TAPI_DEV_START_CFG_t));
1419 dev_start.nMode = IFX_TAPI_INIT_MODE_VOICE_CODER;
1422 if (ioctl(dev_ctx.dev_fd, IFX_TAPI_DEV_START, &dev_start)) {
1423 ast_log(LOG_ERROR, "IFX_TAPI_DEV_START ioctl failed\n");
1424 return AST_MODULE_LOAD_FAILURE;
1427 for (c = 0; c < dev_ctx.channels ; c++) {
1430 memset(&tone, 0, sizeof(IFX_TAPI_TONE_t));
1431 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_TONE_TABLE_CFG_SET, &tone)) {
1432 ast_log(LOG_ERROR, "IFX_TAPI_TONE_TABLE_CFG_SET %d failed\n", c);
1433 return AST_MODULE_LOAD_FAILURE;
1437 IFX_TAPI_RING_CFG_t ringingType;
1438 memset(&ringingType, 0, sizeof(IFX_TAPI_RING_CFG_t));
1439 ringingType.nMode = IFX_TAPI_RING_CFG_MODE_INTERNAL_BALANCED;
1440 ringingType.nSubmode = IFX_TAPI_RING_CFG_SUBMODE_DC_RNG_TRIP_FAST;
1441 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_RING_CFG_SET, (IFX_int32_t) &ringingType)) {
1442 ast_log(LOG_ERROR, "IFX_TAPI_RING_CFG_SET failed\n");
1443 return AST_MODULE_LOAD_FAILURE;
1447 IFX_char_t data[15] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1448 0x00, 0x00, 0x00, 0x00, 0x00,
1449 0x00, 0x00, 0x00, 0x00, 0x00 };
1451 IFX_TAPI_RING_CADENCE_t ringCadence;
1452 memset(&ringCadence, 0, sizeof(IFX_TAPI_RING_CADENCE_t));
1453 memcpy(&ringCadence.data, data, sizeof(data));
1454 ringCadence.nr = sizeof(data) * 8;
1456 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_RING_CADENCE_HR_SET, &ringCadence)) {
1457 ast_log(LOG_ERROR, "IFX_TAPI_RING_CADENCE_HR_SET failed\n");
1458 return AST_MODULE_LOAD_FAILURE;
1461 /* perform mapping */
1462 memset(&map_data, 0x0, sizeof(IFX_TAPI_MAP_DATA_t));
1463 map_data.nDstCh = c;
1464 map_data.nChType = IFX_TAPI_MAP_TYPE_PHONE;
1466 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_MAP_DATA_ADD, &map_data)) {
1467 ast_log(LOG_ERROR, "IFX_TAPI_MAP_DATA_ADD %d failed\n", c);
1468 return AST_MODULE_LOAD_FAILURE;
1472 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_LINE_FEED_SET, IFX_TAPI_LINE_FEED_STANDBY)) {
1473 ast_log(LOG_ERROR, "IFX_TAPI_LINE_FEED_SET %d failed\n", c);
1474 return AST_MODULE_LOAD_FAILURE;
1477 /* Configure encoder */
1478 memset(&enc_cfg, 0x0, sizeof(IFX_TAPI_ENC_CFG_t));
1479 enc_cfg.nFrameLen = IFX_TAPI_COD_LENGTH_20;
1480 enc_cfg.nEncType = IFX_TAPI_COD_TYPE_MLAW;
1482 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_ENC_CFG_SET, &enc_cfg)) {
1483 ast_log(LOG_ERROR, "IFX_TAPI_ENC_CFG_SET %d failed\n", c);
1484 return AST_MODULE_LOAD_FAILURE;
1488 memset(&line_vol, 0, sizeof(line_vol));
1489 line_vol.nGainRx = rxgain;
1490 line_vol.nGainTx = txgain;
1492 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_PHONE_VOLUME_SET, &line_vol)) {
1493 ast_log(LOG_ERROR, "IFX_TAPI_PHONE_VOLUME_SET %d failed\n", c);
1494 return AST_MODULE_LOAD_FAILURE;
1497 /* Configure line echo canceller */
1498 memset(&wlec_cfg, 0, sizeof(wlec_cfg));
1499 wlec_cfg.nType = wlec_type;
1500 wlec_cfg.bNlp = wlec_nlp;
1501 wlec_cfg.nNBFEwindow = wlec_nbfe;
1502 wlec_cfg.nNBNEwindow = wlec_nbne;
1503 wlec_cfg.nWBNEwindow = wlec_wbne;
1505 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_WLEC_PHONE_CFG_SET, &wlec_cfg)) {
1506 ast_log(LOG_ERROR, "IFX_TAPI_WLEC_PHONE_CFG_SET %d failed\n", c);
1507 return AST_MODULE_LOAD_FAILURE;
1510 /* Configure jitter buffer */
1511 memset(&jb_cfg, 0, sizeof(jb_cfg));
1512 jb_cfg.nJbType = jb_type;
1513 jb_cfg.nPckAdpt = jb_pckadpt;
1514 jb_cfg.nLocalAdpt = jb_localadpt;
1515 jb_cfg.nScaling = jb_scaling;
1516 jb_cfg.nInitialSize = jb_initialsize;
1517 jb_cfg.nMinSize = jb_minsize;
1518 jb_cfg.nMaxSize = jb_maxsize;
1520 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_JB_CFG_SET, &jb_cfg)) {
1521 ast_log(LOG_ERROR, "IFX_TAPI_JB_CFG_SET %d failed\n", c);
1522 return AST_MODULE_LOAD_FAILURE;
1525 /* Configure Caller ID type */
1526 memset(&cid_cfg, 0, sizeof(cid_cfg));
1527 cid_cfg.nStandard = cid_type;
1529 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_CID_CFG_SET, &cid_cfg)) {
1530 ast_log(LOG_ERROR, "IIFX_TAPI_CID_CFG_SET %d failed\n", c);
1531 return AST_MODULE_LOAD_FAILURE;
1534 /* Configure voice activity detection */
1535 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_ENC_VAD_CFG_SET, vad_type)) {
1536 ast_log(LOG_ERROR, "IFX_TAPI_ENC_VAD_CFG_SET %d failed\n", c);
1537 return AST_MODULE_LOAD_FAILURE;
1540 /* Setup TAPI <-> Asterisk codec type mapping */
1541 if (lantiq_setup_rtp(c)) {
1542 return AST_MODULE_LOAD_FAILURE;
1545 /* Set initial hook status */
1546 iflist[c].channel_state = lantiq_get_hookstatus(c);
1548 if (iflist[c].channel_state == UNKNOWN) {
1549 return AST_MODULE_LOAD_FAILURE;
1553 /* make sure our device will be closed properly */
1554 ast_register_atexit(lantiq_cleanup);
1557 return AST_MODULE_LOAD_SUCCESS;
1560 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Lantiq TAPI Telephony API Support");