Directory structure restructuralized.
[feed/telephony.git] / net / asterisk-1.8.x / src-lantiq / channels / chan_lantiq.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
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)
11  *
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>
17  *
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.
23  *
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.
27  */
28
29 /*! \file
30  *
31  * \brief Asterisk channel line driver for Lantiq based TAPI boards
32  *
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>
38  * 
39  * \ingroup channel_drivers
40  */
41
42 #include "asterisk.h"
43
44 ASTERISK_FILE_VERSION(__FILE__, "$Revision: xxx $")
45
46 #include <ctype.h>
47 #include <sys/socket.h>
48 #include <sys/time.h>
49 #include <arpa/inet.h>
50 #include <fcntl.h>
51 #include <sys/ioctl.h>
52 #include <signal.h>
53 #ifdef HAVE_LINUX_COMPILER_H
54 #include <linux/compiler.h>
55 #endif
56 #include <linux/telephony.h>
57
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>
69
70 /* Lantiq TAPI includes */
71 #include <drv_tapi/drv_tapi_io.h>
72 #include <drv_vmmc/vmmc_io.h>
73
74 #define RTP_HEADER_LEN 12
75
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
83
84 #define LANTIQ_CONTEXT_PREFIX "lantiq"
85
86 static const char config[] = "lantiq.conf";
87
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;
92
93 /*
94  * The private structures of the Phone Jack channels are linked for selecting
95  * outgoing channels.
96  */
97 enum channel_state {
98         ONHOOK,
99         OFFHOOK,
100         DIALING,
101         INCALL,
102         CALL_ENDED,
103         RINGING,
104         UNKNOWN
105 };
106
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      */
110         int channel_state;
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           */
118         uint32_t call_setup_start;         /* Start of dialling in ms               */
119         uint32_t call_setup_delay;         /* time between ^ and 1st ring in ms     */
120         uint16_t jb_size;                  /* Jitter buffer size                    */
121         uint32_t jb_underflow;             /* Jitter buffer injected samples        */
122         uint32_t jb_overflow;              /* Jitter buffer dropped samples         */
123         uint16_t jb_delay;                 /* Jitter buffer: playout delay          */
124         uint16_t jb_invalid;               /* Jitter buffer: Nr. of invalid packets */
125
126 } *iflist = NULL;
127
128 static struct lantiq_ctx {
129                 int dev_fd;
130                 int channels;
131                 int ch_fd[TAPI_AUDIO_PORT_NUM_MAX];
132 } dev_ctx;
133
134 static int ast_digit_begin(struct ast_channel *ast, char digit);
135 static int ast_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
136 static int ast_lantiq_call(struct ast_channel *ast, char *dest, int timeout);
137 static int ast_lantiq_hangup(struct ast_channel *ast);
138 static int ast_lantiq_answer(struct ast_channel *ast);
139 static struct ast_frame *ast_lantiq_read(struct ast_channel *ast);
140 static int ast_lantiq_write(struct ast_channel *ast, struct ast_frame *frame);
141 static struct ast_frame *ast_lantiq_exception(struct ast_channel *ast);
142 static int ast_lantiq_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
143 static int ast_lantiq_fixup(struct ast_channel *old, struct ast_channel *new);
144 static struct ast_channel *ast_lantiq_requester(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
145 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen);
146 static void lantiq_jb_get_stats(int c);
147
148 static const struct ast_channel_tech lantiq_tech = {
149         .type = "TAPI",
150         .description = "Lantiq TAPI Telephony API Driver",
151         .capabilities = AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_G729A,
152         .send_digit_begin = ast_digit_begin,
153         .send_digit_end = ast_digit_end,
154         .call = ast_lantiq_call,
155         .hangup = ast_lantiq_hangup,
156         .answer = ast_lantiq_answer,
157         .read = ast_lantiq_read,
158         .write = ast_lantiq_write,
159         .exception = ast_lantiq_exception,
160         .indicate = ast_lantiq_indicate,
161         .fixup = ast_lantiq_fixup,
162         .requester = ast_lantiq_requester,
163         .func_channel_read = acf_channel_read
164 };
165
166 /* Protect the interface list (of lantiq_pvt's) */
167 AST_MUTEX_DEFINE_STATIC(iflock);
168
169 /*
170  * Protect the monitoring thread, so only one process can kill or start it, and
171  * not when it's doing something critical.
172  */
173 AST_MUTEX_DEFINE_STATIC(monlock);
174
175 /* Boolean value whether the monitoring thread shall continue. */
176 static unsigned int monitor;
177
178 /* The scheduling thread */
179 struct ast_sched_thread *sched_thread;
180    
181 /*
182  * This is the thread for the monitor which checks for input on the channels
183  * which are not currently in use.
184  */
185 static pthread_t monitor_thread = AST_PTHREADT_NULL;
186
187
188 #define WORDS_BIGENDIAN
189 /* struct taken from some GPLed code by  Mike Borella */
190 typedef struct rtp_header
191 {
192 #if defined(WORDS_BIGENDIAN)
193   uint8_t version:2, padding:1, extension:1, csrc_count:4;
194 #else
195   uint8_t csrc_count:4, extension:1, padding:1, version:2;
196 #endif
197 #if defined(WORDS_BIGENDIAN)
198   uint8_t marker:1, payload_type:7;
199 #else
200   uint8_t payload_type:7, marker:1;
201 #endif
202   uint16_t seqno;
203   uint32_t timestamp;
204   uint32_t ssrc;
205 } rtp_header_t;
206
207 static uint32_t now(void) {
208         struct timespec ts;
209         clock_gettime(CLOCK_MONOTONIC, &ts);
210
211         uint64_t tmp = ts.tv_sec*1000 + (ts.tv_nsec/1000000);
212         return (uint32_t) tmp;
213 }
214
215 static int lantiq_dev_open(const char *dev_path, const int32_t ch_num)
216 {
217         char dev_name[PATH_MAX];
218         memset(dev_name, 0, sizeof(dev_name));
219         snprintf(dev_name, PATH_MAX, "%s%u%u", dev_path, 1, ch_num);
220         return open((const char*)dev_name, O_RDWR, 0644);
221 }
222
223 static void lantiq_ring(int c, int r, const char *cid)
224 {
225         uint8_t status;
226
227         if (r) {
228                 if (!cid) {
229                         status = (uint8_t) ioctl(dev_ctx.ch_fd[c], IFX_TAPI_RING_START, 0);
230                 } else {
231                         IFX_TAPI_CID_MSG_t msg;
232                         IFX_TAPI_CID_MSG_STRING_t cid_el;
233
234                         memset(&msg, 0, sizeof(msg));
235                         memset(&cid_el, 0, sizeof(cid_el));
236                         
237                         cid_el.elementType = IFX_TAPI_CID_ST_CLI;
238                         cid_el.len = strlen(cid);
239                         strncpy((char*)cid_el.element, cid, (size_t)cid_el.len);
240
241                         msg.txMode = IFX_TAPI_CID_HM_ONHOOK;
242                         msg.messageType = IFX_TAPI_CID_MT_CSUP;
243                         msg.message = (IFX_TAPI_CID_MSG_ELEMENT_t *)&cid_el;
244                         msg.nMsgElements = 1;
245
246                         status = (uint8_t) ioctl(dev_ctx.ch_fd[c], IFX_TAPI_CID_TX_SEQ_START, (IFX_int32_t) &msg);
247                 }
248         } else {
249                 status = (uint8_t) ioctl(dev_ctx.ch_fd[c], IFX_TAPI_RING_STOP, 0);
250         }
251
252         if (status) {
253                 ast_log(LOG_ERROR, "%s ioctl failed\n",
254                         (r ? "IFX_TAPI_RING_START" : "IFX_TAPI_RING_STOP"));
255         }
256 }
257
258 static int lantiq_play_tone(int c, int t)
259 {
260         /* stop currently playing tone before starting new one */
261         if (t != TAPI_TONE_LOCALE_NONE) {
262                 ioctl(dev_ctx.ch_fd[c], IFX_TAPI_TONE_LOCAL_PLAY, TAPI_TONE_LOCALE_NONE);
263         }
264
265         if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_TONE_LOCAL_PLAY, t)) {
266                 ast_log(LOG_ERROR, "IFX_TAPI_TONE_LOCAL_PLAY ioctl failed\n");
267                 return -1;
268         }
269
270         return 0;
271 }
272
273 static enum channel_state lantiq_get_hookstatus(int port)
274 {
275         uint8_t status;
276
277         if (ioctl(dev_ctx.ch_fd[port], IFX_TAPI_LINE_HOOK_STATUS_GET, &status)) {
278                 ast_log(LOG_ERROR, "IFX_TAPI_LINE_HOOK_STATUS_GET ioctl failed\n");
279                 return UNKNOWN;
280         }
281
282         if (status) {
283                 return OFFHOOK;
284         } else {
285                 return ONHOOK;
286         }
287 }
288
289 static int
290 lantiq_dev_binary_buffer_create(const char *path, uint8_t **ppBuf, uint32_t *pBufSz)
291 {
292         FILE *fd;
293         struct stat file_stat;
294         int32_t status = 0;
295
296         fd = fopen(path, "rb");
297         if (fd == NULL) {
298                 ast_log(LOG_ERROR, "binary file %s open failed\n", path);
299                 return -1;
300         }
301
302         if (stat(path, &file_stat)) {
303                 ast_log(LOG_ERROR, "file %s statistics get failed\n", path);
304                 return -1;
305         }
306
307         *ppBuf = malloc(file_stat.st_size);
308         if (*ppBuf == NULL) {
309                 ast_log(LOG_ERROR, "binary file %s memory allocation failed\n", path);
310                 status = -1;
311                 goto on_exit;
312         }
313
314         if (fread (*ppBuf, sizeof(uint8_t), file_stat.st_size, fd) <= 0) {
315                 ast_log(LOG_ERROR, "file %s read failed\n", path);
316                 status = -1;
317                 goto on_exit;
318         }
319
320         *pBufSz = file_stat.st_size;
321
322 on_exit:
323         if (fd != NULL)
324                 fclose(fd);
325
326         if (*ppBuf != NULL && status)
327                 free(*ppBuf);
328
329         return status;
330 }
331
332 static int32_t lantiq_dev_firmware_download(int32_t fd, const char *path)
333 {
334         uint8_t *firmware = NULL;
335         uint32_t size = 0;
336         VMMC_IO_INIT vmmc_io_init;
337
338         ast_log(LOG_DEBUG, "loading firmware: \"%s\".", path);
339
340         if (lantiq_dev_binary_buffer_create(path, &firmware, &size))
341                 return -1;
342
343         memset(&vmmc_io_init, 0, sizeof(VMMC_IO_INIT));
344         vmmc_io_init.pPRAMfw = firmware;
345         vmmc_io_init.pram_size = size;
346
347         if (ioctl(fd, FIO_FW_DOWNLOAD, &vmmc_io_init)) {
348                 ast_log(LOG_ERROR, "FIO_FW_DOWNLOAD ioctl failed\n");
349                 return -1;
350         }
351
352         if (firmware != NULL)
353                 free(firmware);
354
355         return 0;
356 }
357
358 static const char *state_string(enum channel_state s)
359 {
360         switch (s) {
361                 case ONHOOK: return "ONHOOK";
362                 case OFFHOOK: return "OFFHOOK";
363                 case DIALING: return "DIALING";
364                 case INCALL: return "INCALL";
365                 case CALL_ENDED: return "CALL_ENDED";
366                 case RINGING: return "RINGING";
367                 default: return "UNKNOWN";
368         }
369 }
370
371 static const char *control_string(int c)
372 {
373         switch (c) {
374                 case AST_CONTROL_HANGUP: return "Other end has hungup";
375                 case AST_CONTROL_RING: return "Local ring";
376                 case AST_CONTROL_RINGING: return "Remote end is ringing";
377                 case AST_CONTROL_ANSWER: return "Remote end has answered";
378                 case AST_CONTROL_BUSY: return "Remote end is busy";
379                 case AST_CONTROL_TAKEOFFHOOK: return "Make it go off hook";
380                 case AST_CONTROL_OFFHOOK: return "Line is off hook";
381                 case AST_CONTROL_CONGESTION: return "Congestion (circuits busy)";
382                 case AST_CONTROL_FLASH: return "Flash hook";
383                 case AST_CONTROL_WINK: return "Wink";
384                 case AST_CONTROL_OPTION: return "Set a low-level option";
385                 case AST_CONTROL_RADIO_KEY: return "Key Radio";
386                 case AST_CONTROL_RADIO_UNKEY: return "Un-Key Radio";
387                 case AST_CONTROL_PROGRESS: return "Remote end is making Progress";
388                 case AST_CONTROL_PROCEEDING: return "Remote end is proceeding";
389                 case AST_CONTROL_HOLD: return "Hold";
390                 case AST_CONTROL_UNHOLD: return "Unhold";
391                 case AST_CONTROL_SRCUPDATE: return "Media Source Update";
392                 case AST_CONTROL_CONNECTED_LINE: return "Connected Line";
393                 case AST_CONTROL_REDIRECTING: return "Redirecting";
394                 case AST_CONTROL_INCOMPLETE: return "Incomplete";
395                 case -1: return "Stop tone";
396                 default: return "Unknown";
397         }
398 }
399
400 static int ast_lantiq_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
401 {
402         ast_verb(3, "phone indication \"%s\"\n", control_string(condition));
403
404         struct lantiq_pvt *pvt = chan->tech_pvt;
405
406         switch (condition) {
407                 case -1:
408                         {
409                                 lantiq_play_tone(pvt->port_id, TAPI_TONE_LOCALE_NONE);
410                                 return 0;
411                         }
412                 case AST_CONTROL_CONGESTION:
413                 case AST_CONTROL_BUSY:
414                         {
415                                 lantiq_play_tone(pvt->port_id, TAPI_TONE_LOCALE_BUSY_CODE);
416                                 return 0;
417                         }
418                 case AST_CONTROL_RINGING:
419                         {
420                                 pvt->call_setup_delay = now() - pvt->call_setup_start;
421                                 lantiq_play_tone(pvt->port_id, TAPI_TONE_LOCALE_RINGING_CODE);
422                                 return 0;
423                         }
424                 default:
425                         {
426                                 /* -1 lets asterisk generate the tone */
427                                 return -1;
428                         }
429         }
430 }
431
432 static int ast_lantiq_fixup(struct ast_channel *old, struct ast_channel *new)
433 {
434         ast_log(LOG_DEBUG, "entering... no code here...\n");
435         return 0;
436 }
437
438 static int ast_digit_begin(struct ast_channel *chan, char digit)
439 {
440         /* TODO: Modify this callback to let Asterisk support controlling the length of DTMF */
441         ast_log(LOG_DEBUG, "entering... no code here...\n");
442         return 0;
443 }
444
445 static int ast_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
446 {
447         ast_log(LOG_DEBUG, "entering... no code here...\n");
448         return 0;
449 }
450
451 static int ast_lantiq_call(struct ast_channel *ast, char *dest, int timeout)
452 {
453         /* lock to prevent simultaneous access with do_monitor thread processing */
454         ast_mutex_lock(&iflock);
455
456         struct lantiq_pvt *pvt = ast->tech_pvt;
457         ast_log(LOG_DEBUG, "state: %s\n", state_string(pvt->channel_state));
458
459         if (pvt->channel_state == ONHOOK) {
460                 ast_log(LOG_DEBUG, "port %i is ringing\n", pvt->port_id);
461
462                 char *cid = ast->connected.id.number.valid ? ast->connected.id.number.str : NULL;
463                 ast_log(LOG_DEBUG, "port %i CID: %s\n", pvt->port_id, cid ? cid : "none");
464
465                 lantiq_ring(pvt->port_id, 1, cid);
466                 pvt->channel_state = RINGING;
467
468                 ast_setstate(ast, AST_STATE_RINGING);
469                 ast_queue_control(ast, AST_CONTROL_RINGING);
470         } else {
471                 ast_log(LOG_DEBUG, "port %i is busy\n", pvt->port_id);
472                 ast_setstate(ast, AST_STATE_BUSY);
473                 ast_queue_control(ast, AST_CONTROL_BUSY);
474         }
475
476         ast_mutex_unlock(&iflock);
477
478         return 0;
479 }
480
481 static int ast_lantiq_hangup(struct ast_channel *ast)
482 {
483         /* lock to prevent simultaneous access with do_monitor thread processing */
484         ast_mutex_lock(&iflock);
485
486         struct lantiq_pvt *pvt = ast->tech_pvt;
487         ast_log(LOG_DEBUG, "state: %s\n", state_string(pvt->channel_state));
488         
489         if (ast->_state == AST_STATE_RINGING) {
490                 // FIXME
491                 ast_debug(1, "TAPI: ast_lantiq_hangup(): ast->_state == AST_STATE_RINGING\n");
492         }
493
494         switch (pvt->channel_state) {
495                 case RINGING:
496                 case ONHOOK: 
497                         lantiq_ring(pvt->port_id, 0, NULL);
498                         pvt->channel_state = ONHOOK;
499                         break;
500                 default:
501                         ast_log(LOG_DEBUG, "we were hung up, play busy tone\n");
502                         pvt->channel_state = CALL_ENDED;
503                         lantiq_play_tone(pvt->port_id, TAPI_TONE_LOCALE_BUSY_CODE);
504         }
505
506         lantiq_jb_get_stats(pvt->port_id);
507
508         ast_setstate(ast, AST_STATE_DOWN);
509         ast_module_unref(ast_module_info->self);
510         ast->tech_pvt = NULL;
511         pvt->owner = NULL;
512
513         ast_mutex_unlock(&iflock);
514
515         return 0;
516 }
517
518 static int ast_lantiq_answer(struct ast_channel *ast)
519 {
520         ast_log(LOG_DEBUG, "entering... no code here...\n");
521         return 0;
522 }
523
524 static struct ast_frame * ast_lantiq_read(struct ast_channel *ast)
525 {
526         ast_log(LOG_DEBUG, "entering... no code here...\n");
527         return NULL;
528 }
529
530 static int ast_lantiq_write(struct ast_channel *ast, struct ast_frame *frame)
531 {
532         char buf[2048];
533         struct lantiq_pvt *pvt = ast->tech_pvt;
534         int ret = -1;
535         rtp_header_t *rtp_header = (rtp_header_t *) buf;
536
537         if(frame->frametype != AST_FRAME_VOICE) {
538                 ast_log(LOG_DEBUG, "unhandled frame type\n");
539                 return 0;
540         }
541         
542         if (frame->datalen == 0) {
543                 ast_log(LOG_DEBUG, "we've been prodded\n");
544                 return 0;
545         }
546
547         memset(buf, 0, sizeof(rtp_header_t));
548         rtp_header->version      = 2;
549         rtp_header->padding      = 0;
550         rtp_header->extension    = 0;
551         rtp_header->csrc_count   = 0;
552         rtp_header->marker       = 0;
553         rtp_header->timestamp    = pvt->rtp_timestamp;
554         rtp_header->seqno        = pvt->rtp_seqno++;
555         rtp_header->ssrc         = 0;
556         rtp_header->payload_type = (uint8_t) frame->subclass.codec;
557
558         pvt->rtp_timestamp += 160;
559
560         memcpy(buf+RTP_HEADER_LEN, frame->data.ptr, frame->datalen);
561
562         ret = write(dev_ctx.ch_fd[pvt->port_id], buf, frame->datalen+RTP_HEADER_LEN);
563         if (ret <= 0) {
564                 ast_debug(1, "TAPI: ast_lantiq_write(): error writing.\n");
565                 return -1;
566         }
567
568 #ifdef TODO_DEVEL_INFO
569         ast_debug(1, "ast_lantiq_write(): size: %i version: %i padding: %i extension: %i csrc_count: %i\n"
570                  "marker: %i payload_type: %s seqno: %i timestamp: %i ssrc: %i\n", 
571                          (int)ret,
572                          (int)rtp_header->version,
573                          (int)rtp_header->padding,
574                          (int)rtp_header->extension,
575                          (int)rtp_header->csrc_count,
576                          (int)rtp_header->marker,
577                          ast_codec2str(rtp_header->payload_type),
578                          (int)rtp_header->seqno,
579                          (int)rtp_header->timestamp,
580                          (int)rtp_header->ssrc);
581 #endif
582
583         return 0;
584 }
585
586 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
587 {
588         struct lantiq_pvt *pvt;
589         int res = 0;
590
591         if (!chan || chan->tech != &lantiq_tech) {
592                 ast_log(LOG_ERROR, "This function requires a valid Lantiq TAPI channel\n");
593                 return -1;
594         }
595
596         ast_mutex_lock(&iflock);
597
598         pvt = (struct lantiq_pvt*) chan->tech_pvt;
599
600         if (!strcasecmp(args, "csd")) {
601                 snprintf(buf, buflen, "%lu", (unsigned long int) pvt->call_setup_delay);
602         } else if (!strcasecmp(args, "jitter_stats")){
603                 lantiq_jb_get_stats(pvt->port_id);
604                 snprintf(buf, buflen, "jbBufSize=%u,jbUnderflow=%u,jbOverflow=%u,jbDelay=%u,jbInvalid=%u",
605                                 (uint32_t) pvt->jb_size,
606                                 (uint32_t) pvt->jb_underflow,
607                                 (uint32_t) pvt->jb_overflow,
608                                 (uint32_t) pvt->jb_delay,
609                                 (uint32_t) pvt->jb_invalid);
610         } else {
611                 res = -1;
612         }
613
614         ast_mutex_unlock(&iflock);
615
616         return res;
617 }
618
619
620 static struct ast_frame * ast_lantiq_exception(struct ast_channel *ast)
621 {
622         ast_log(LOG_DEBUG, "entering... no code here...\n");
623         return NULL;
624 }
625
626 static void lantiq_jb_get_stats(int c) {
627         struct lantiq_pvt *pvt = &iflist[c];
628
629         IFX_TAPI_JB_STATISTICS_t param;
630         memset (&param, 0, sizeof (param));
631         if (ioctl (dev_ctx.ch_fd[c], IFX_TAPI_JB_STATISTICS_GET, (IFX_int32_t) &param) != IFX_SUCCESS) {
632                 ast_debug(1, "Error getting jitter buffer  stats.\n");
633         } else {
634 #if !defined (TAPI_VERSION3) && defined (TAPI_VERSION4)
635                 ast_debug(1, "Jitter buffer stats:  dev=%u, ch=%u, nType=%u, nBufSize=%u, nIsUnderflow=%u, nDsOverflow=%u, nPODelay=%u, nInvalid=%u", 
636                                 (uint32_t) param.dev,
637                                 (uint32_t) param.ch,
638 #else
639                 ast_debug(1, "Jitter buffer stats:  nType=%u, nBufSize=%u, nIsUnderflow=%u, nDsOverflow=%u, nPODelay=%u, nInvalid=%u", 
640 #endif
641                                 (uint32_t) param.nType,
642                                 (uint32_t) param.nBufSize,
643                                 (uint32_t) param.nIsUnderflow,
644                                 (uint32_t) param.nDsOverflow,
645                                 (uint32_t) param.nPODelay,
646                                 (uint32_t) param.nInvalid);
647                 
648                 pvt->jb_size = param.nBufSize;
649                 pvt->jb_underflow = param.nIsUnderflow;
650                 pvt->jb_overflow = param.nDsOverflow;
651                 pvt->jb_invalid = param.nInvalid;
652                 pvt->jb_delay = param.nPODelay;
653         }
654 }
655
656
657 static int lantiq_standby(int c)
658 {
659         if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_LINE_FEED_SET, IFX_TAPI_LINE_FEED_STANDBY)) {
660                 ast_log(LOG_ERROR, "IFX_TAPI_LINE_FEED_SET ioctl failed\n");
661                 return -1;
662         }
663
664         if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_ENC_STOP, 0)) {
665                 ast_log(LOG_ERROR, "IFX_TAPI_ENC_STOP ioctl failed\n");
666                 return -1;
667         }
668
669         if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_DEC_STOP, 0)) {
670                 ast_log(LOG_ERROR, "IFX_TAPI_DEC_STOP ioctl failed\n");
671                 return -1;
672         }
673
674         return lantiq_play_tone(c, TAPI_TONE_LOCALE_NONE);
675 }
676
677 static int lantiq_end_dialing(int c)
678 {
679         ast_log(LOG_DEBUG, "TODO - DEBUG MSG\n");
680         struct lantiq_pvt *pvt = &iflist[c];
681
682         if (pvt->dial_timer) {
683                 ast_sched_thread_del(sched_thread, pvt->dial_timer);
684                 pvt->dial_timer = 0;
685         }
686
687         if(pvt->owner) {
688                 ast_hangup(pvt->owner);
689         }
690
691         return 0;
692 }
693
694 static int lantiq_end_call(int c)
695 {
696         ast_log(LOG_DEBUG, "TODO - DEBUG MSG\n");
697
698         struct lantiq_pvt *pvt = &iflist[c];
699         
700         if(pvt->owner) {
701                 lantiq_jb_get_stats(c);
702                 ast_queue_hangup(pvt->owner);
703         }
704
705         return 0;
706 }
707
708 static struct ast_channel * lantiq_channel(int state, int c, char *ext, char *ctx)
709 {
710         ast_log(LOG_DEBUG, "TODO - DEBUG MSG\n");
711
712         struct ast_channel *chan = NULL;
713
714         struct lantiq_pvt *pvt = &iflist[c];
715
716         chan = ast_channel_alloc(1, state, NULL, NULL, "", ext, ctx, 0, c, "TAPI/%s", "1");
717
718         chan->tech = &lantiq_tech;
719         chan->nativeformats = AST_FORMAT_ULAW;
720         chan->readformat  = AST_FORMAT_ULAW;
721         chan->writeformat = AST_FORMAT_ULAW;
722         chan->tech_pvt = pvt;
723
724         pvt->owner = chan;
725
726         return chan;
727 }
728
729 static struct ast_channel * ast_lantiq_requester(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
730 {
731         ast_mutex_lock(&iflock);
732
733         char buf[BUFSIZ];
734         struct ast_channel *chan = NULL;
735         int port_id = -1;
736
737         ast_debug(1, "Asked to create a TAPI channel with formats: %s\n", ast_getformatname_multiple(buf, sizeof(buf), format));
738
739
740         /* check for correct data argument */
741         if (ast_strlen_zero(data)) {
742                 ast_log(LOG_ERROR, "Unable to create channel with empty destination.\n");
743                 *cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
744                 return NULL;
745         }
746
747         /* get our port number */
748         port_id = atoi((char*) data);
749         if (port_id < 1 || port_id > dev_ctx.channels) {
750                 ast_log(LOG_ERROR, "Unknown channel ID: \"%s\"\n", (char*) data);
751                 *cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
752                 return NULL;
753         }
754
755         /* on asterisk user's side, we're using port 1-2.
756          * Here in non normal human's world, we begin
757          * counting at 0.
758          */
759         port_id -= 1;
760
761         chan = lantiq_channel(AST_STATE_DOWN, port_id, NULL, NULL);
762
763         ast_mutex_unlock(&iflock);
764         return chan;
765 }
766
767 static int lantiq_dev_data_handler(int c)
768 {
769         char buf[BUFSIZ];
770         struct ast_frame frame = {0};
771
772         int res = read(dev_ctx.ch_fd[c], buf, sizeof(buf));
773         if (res <= 0) ast_log(LOG_ERROR, "we got read error %i\n", res);
774         
775         rtp_header_t *rtp = (rtp_header_t*) buf;
776
777         frame.src = "TAPI";
778         frame.frametype = AST_FRAME_VOICE;
779         frame.subclass.codec = rtp->payload_type;
780         frame.samples = res - RTP_HEADER_LEN;
781         frame.datalen = res - RTP_HEADER_LEN;
782         frame.data.ptr = buf + RTP_HEADER_LEN;
783
784         struct lantiq_pvt *pvt = (struct lantiq_pvt *) &iflist[c];
785         if (pvt->owner && (pvt->owner->_state == AST_STATE_UP)) {
786                 if(!ast_channel_trylock(pvt->owner)) {
787                         ast_queue_frame(pvt->owner, &frame);
788                         ast_channel_unlock(pvt->owner);
789                 }
790         }
791
792 /*      ast_debug(1, "lantiq_dev_data_handler(): size: %i version: %i padding: %i extension: %i csrc_count: %i \n"
793                                  "marker: %i payload_type: %s seqno: %i timestamp: %i ssrc: %i\n", 
794                                  (int)res,
795                                  (int)rtp->version,
796                                  (int)rtp->padding,
797                                  (int)rtp->extension,
798                                  (int)rtp->csrc_count,
799                                  (int)rtp->marker,
800                                  ast_codec2str(rtp->payload_type),
801                                  (int)rtp->seqno,
802                                  (int)rtp->timestamp,
803                                  (int)rtp->ssrc);
804 */
805         return 0;
806 }
807
808 static int accept_call(int c)
809
810         ast_log(LOG_DEBUG, "TODO - DEBUG MSG\n");
811
812         struct lantiq_pvt *pvt = &iflist[c];
813
814         if (pvt->owner) {
815                 struct ast_channel *chan = pvt->owner;
816
817                 switch (chan->_state) {
818                         case AST_STATE_RINGING:
819                                 lantiq_play_tone(c, TAPI_TONE_LOCALE_NONE);
820                                 ast_queue_control(pvt->owner, AST_CONTROL_ANSWER);
821                                 pvt->channel_state = INCALL;
822                                 break;
823                         default:
824                                 ast_log(LOG_WARNING, "entered unhandled state %s\n", ast_state2str(chan->_state));
825                 }
826         }
827
828         return 0;
829 }
830
831 static int lantiq_dev_event_hook(int c, int state)
832 {
833         ast_mutex_lock(&iflock);
834
835         ast_log(LOG_DEBUG, "on port %i detected event %s hook\n", c, state ? "on" : "off");
836
837         int ret = -1;
838         if (state) { /* going onhook */
839                 switch (iflist[c].channel_state) {
840                         case OFFHOOK: 
841                                 ret = lantiq_standby(c);
842                                 break;
843                         case DIALING: 
844                                 ret = lantiq_end_dialing(c);
845                                 break;
846                         case INCALL: 
847                                 ret = lantiq_end_call(c);
848                                 break;
849                         case CALL_ENDED:
850                                 ret = lantiq_standby(c); // TODO: are we sure for this ?
851                                 break;
852                         default:
853                                 break;
854                 }
855                 iflist[c].channel_state = ONHOOK;
856         } else { /* going offhook */
857                 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_LINE_FEED_SET, IFX_TAPI_LINE_FEED_ACTIVE)) {
858                         ast_log(LOG_ERROR, "IFX_TAPI_LINE_FEED_SET ioctl failed\n");
859                         goto out;
860                 }
861
862                 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_ENC_START, 0)) {
863                         ast_log(LOG_ERROR, "IFX_TAPI_ENC_START ioctl failed\n");
864                         goto out;
865                 }
866
867                 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_DEC_START, 0)) {
868                         ast_log(LOG_ERROR, "IFX_TAPI_DEC_START ioctl failed\n");
869                         goto out;
870                 }
871
872                 switch (iflist[c].channel_state) {
873                         case RINGING: 
874                                 ret = accept_call(c);
875                                 break;
876                         default:
877                                 iflist[c].channel_state = OFFHOOK;
878                                 lantiq_play_tone(c, TAPI_TONE_LOCALE_DIAL_CODE);
879                                 ret = 0;
880                                 break;
881                 }
882
883         }
884
885 out:
886         ast_mutex_unlock(&iflock);
887
888         return ret;
889 }
890
891 static void lantiq_reset_dtmfbuf(struct lantiq_pvt *pvt)
892 {
893         pvt->dtmfbuf[0] = '\0';
894         pvt->dtmfbuf_len = 0;
895         pvt->ext[0] = '\0';
896 }
897
898 static void lantiq_dial(struct lantiq_pvt *pvt)
899 {
900         struct ast_channel *chan = NULL;
901
902         ast_log(LOG_DEBUG, "user want's to dial %s.\n", pvt->dtmfbuf);
903
904         if (ast_exists_extension(NULL, pvt->context, pvt->dtmfbuf, 1, NULL)) {
905                 ast_debug(1, "found extension %s, dialing\n", pvt->dtmfbuf);
906
907                 strcpy(pvt->ext, pvt->dtmfbuf);
908
909                 ast_verbose(VERBOSE_PREFIX_3 " extension exists, starting PBX %s\n", pvt->ext);
910
911                 chan = lantiq_channel(AST_STATE_UP, pvt->port_id, pvt->ext+1, pvt->context);
912                 chan->tech_pvt = pvt;
913                 pvt->owner = chan;
914
915                 strcpy(chan->exten, pvt->ext);
916                 ast_setstate(chan, AST_STATE_RING);
917                 pvt->channel_state = INCALL;
918
919                 pvt->call_setup_start = now();
920
921                 if (ast_pbx_start(chan)) {
922                         ast_log(LOG_WARNING, " unable to start PBX on %s\n", chan->name);
923                         ast_hangup(chan);
924                 }
925         } else {
926                 ast_log(LOG_DEBUG, "no extension found\n");
927                 lantiq_play_tone(pvt->port_id, TAPI_TONE_LOCALE_BUSY_CODE);
928                 pvt->channel_state = CALL_ENDED;
929         }
930         
931         lantiq_reset_dtmfbuf(pvt);
932 }
933
934 static int lantiq_event_dial_timeout(const void* data)
935 {
936         ast_debug(1, "TAPI: lantiq_event_dial_timeout()\n");
937
938         struct lantiq_pvt *pvt = (struct lantiq_pvt *) data;
939         pvt->dial_timer = 0;
940
941         if (! pvt->channel_state == ONHOOK) {
942                 lantiq_dial(pvt);
943         } else {
944                 ast_debug(1, "TAPI: lantiq_event_dial_timeout(): dial timeout in state ONHOOK.\n");
945         }
946
947         return 0;
948 }
949
950 static int lantiq_send_digit(int c, char digit) 
951 {
952         struct lantiq_pvt *pvt = &iflist[c];
953
954         struct ast_frame f = { .frametype = AST_FRAME_DTMF, .subclass.integer = digit };
955
956         if (pvt->owner) {
957                 ast_log(LOG_DEBUG, "Port %i transmitting digit \"%c\"\n", c, digit);
958                 return ast_queue_frame(pvt->owner, &f);
959         } else {
960                 ast_debug(1, "Warning: lantiq_send_digit() without owner!\n");
961                 return -1;
962         }
963 }
964
965 static void lantiq_dev_event_digit(int c, char digit)
966 {
967         ast_mutex_lock(&iflock);
968
969         ast_log(LOG_DEBUG, "on port %i detected digit \"%c\"\n", c, digit);
970
971         struct lantiq_pvt *pvt = &iflist[c];
972
973         switch (pvt->channel_state) {
974                 case INCALL:
975                         {
976                                 lantiq_send_digit(c, digit);
977                                 break;
978                         }
979                 case OFFHOOK:  
980                         pvt->channel_state = DIALING;
981
982                         lantiq_play_tone(c, TAPI_TONE_LOCALE_NONE);
983
984                         /* fall through */
985                 case DIALING: 
986                         if (digit == '#') {
987                                 if (pvt->dial_timer) {
988                                         ast_sched_thread_del(sched_thread, pvt->dial_timer);
989                                         pvt->dial_timer = 0;
990                                 }
991
992                                 lantiq_dial(pvt);
993                         } else {
994                                 pvt->dtmfbuf[pvt->dtmfbuf_len] = digit;
995                                 pvt->dtmfbuf_len++;
996                                 pvt->dtmfbuf[pvt->dtmfbuf_len] = '\0';
997
998                                 /* setup autodial timer */
999                                 if (!pvt->dial_timer) {
1000                                         ast_log(LOG_DEBUG, "setting new timer\n");
1001                                         pvt->dial_timer = ast_sched_thread_add(sched_thread, 2000, lantiq_event_dial_timeout, (const void*) pvt);
1002                                 } else {
1003                                         ast_log(LOG_DEBUG, "replacing timer\n");
1004                                         struct sched_context *sched = ast_sched_thread_get_context(sched_thread);
1005                                         AST_SCHED_REPLACE(pvt->dial_timer, sched, 2000, lantiq_event_dial_timeout, (const void*) pvt);
1006                                 }
1007                         }
1008                         break;
1009                 default:
1010                         ast_log(LOG_ERROR, "don't know what to do in unhandled state\n");
1011                         break;
1012         }
1013
1014         ast_mutex_unlock(&iflock);
1015         return;
1016 }
1017
1018 static void lantiq_dev_event_handler(void)
1019 {
1020         IFX_TAPI_EVENT_t event;
1021         unsigned int i;
1022
1023         for (i = 0; i < dev_ctx.channels ; i++) {
1024                 ast_mutex_lock(&iflock);
1025
1026                 memset (&event, 0, sizeof(event));
1027                 event.ch = i;
1028                 if (ioctl(dev_ctx.dev_fd, IFX_TAPI_EVENT_GET, &event)) {
1029                         ast_mutex_unlock(&iflock);
1030                         continue;
1031                 }
1032                 if (event.id == IFX_TAPI_EVENT_NONE) {
1033                         ast_mutex_unlock(&iflock);
1034                         continue;
1035                 }
1036
1037                 ast_mutex_unlock(&iflock);
1038
1039                 switch(event.id) {
1040                         case IFX_TAPI_EVENT_FXS_ONHOOK:
1041                                 lantiq_dev_event_hook(i, 1);
1042                                 break;
1043                         case IFX_TAPI_EVENT_FXS_OFFHOOK:
1044                                 lantiq_dev_event_hook(i, 0);
1045                                 break;
1046                         case IFX_TAPI_EVENT_DTMF_DIGIT:
1047                                 lantiq_dev_event_digit(i, (char)event.data.dtmf.ascii);
1048                                 break;
1049                         case IFX_TAPI_EVENT_PULSE_DIGIT:
1050                                 if (event.data.pulse.digit == 0xB) {
1051                                         lantiq_dev_event_digit(i, '0');
1052                                 } else {
1053                                         lantiq_dev_event_digit(i, '0' + (char)event.data.pulse.digit);
1054                                 }
1055                                 break;
1056                         case IFX_TAPI_EVENT_COD_DEC_CHG:
1057                         case IFX_TAPI_EVENT_TONE_GEN_END:
1058                         case IFX_TAPI_EVENT_CID_TX_SEQ_END:
1059                                 break;
1060                         default:
1061                                 ast_log(LOG_ERROR, "unknown TAPI event %08X\n", event.id);
1062                                 break;
1063                 }
1064         }
1065 }
1066
1067 static void * lantiq_events_monitor(void *data)
1068 {
1069         ast_verbose("TAPI thread started\n");
1070
1071         struct pollfd fds[3];
1072
1073         fds[0].fd = dev_ctx.dev_fd;
1074         fds[0].events = POLLIN;
1075         fds[1].fd = dev_ctx.ch_fd[0];
1076         fds[1].events = POLLIN;
1077         fds[2].fd = dev_ctx.ch_fd[1];
1078         fds[2].events = POLLIN;
1079
1080         while (monitor) {
1081                 ast_mutex_lock(&monlock);
1082
1083                 if (poll(fds, dev_ctx.channels + 1, 2000) <= 0) {
1084                         ast_mutex_unlock(&monlock);
1085                         continue;
1086                 }
1087
1088                 if (fds[0].revents & POLLIN) {
1089                         lantiq_dev_event_handler();
1090                 }
1091
1092                 ast_mutex_unlock(&monlock);
1093
1094                 if ((fds[1].revents & POLLIN) && (lantiq_dev_data_handler(0))) {
1095                         ast_log(LOG_ERROR, "data handler 0 failed\n");
1096                         break;
1097                 }
1098
1099                 if ((fds[2].revents & POLLIN) && (lantiq_dev_data_handler(1))) {
1100                         ast_log(LOG_ERROR, "data handler 1 failed\n");
1101                         break;
1102                 }
1103         }
1104
1105         return NULL;
1106 }
1107
1108 static int restart_monitor(void)
1109 {
1110         /* If we're supposed to be stopped -- stay stopped */
1111         if (monitor_thread == AST_PTHREADT_STOP)
1112                 return 0;
1113
1114         ast_mutex_lock(&monlock);
1115
1116         if (monitor_thread == pthread_self()) {
1117                 ast_mutex_unlock(&monlock);
1118                 ast_log(LOG_WARNING, "Cannot kill myself\n");
1119                 return -1;
1120         }
1121
1122         if (monitor_thread != AST_PTHREADT_NULL) {
1123                 if (ast_mutex_lock(&iflock)) {
1124                         ast_mutex_unlock(&monlock);
1125                         ast_log(LOG_WARNING, "Unable to lock the interface list\n");
1126                         return -1;
1127                 }
1128                 monitor = 0;
1129                 while (pthread_kill(monitor_thread, SIGURG) == 0)
1130                         sched_yield();
1131                 pthread_join(monitor_thread, NULL);
1132                 ast_mutex_unlock(&iflock);
1133         }
1134
1135         monitor = 1;
1136         /* Start a new monitor */
1137         if (ast_pthread_create_background(&monitor_thread, NULL, lantiq_events_monitor, NULL) < 0) {
1138                 ast_mutex_unlock(&monlock);
1139                 ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
1140                 return -1;
1141         }
1142
1143         ast_mutex_unlock(&monlock);
1144
1145         return 0;
1146 }
1147
1148 static void lantiq_cleanup(void)
1149 {
1150         int c;
1151
1152         for (c = 0; c < dev_ctx.channels ; c++) { 
1153                 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_LINE_FEED_SET, IFX_TAPI_LINE_FEED_STANDBY)) {
1154                         ast_log(LOG_WARNING, "IFX_TAPI_LINE_FEED_SET ioctl failed\n");
1155                 }
1156
1157                 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_ENC_STOP, 0)) {
1158                         ast_log(LOG_WARNING, "IFX_TAPI_ENC_STOP ioctl failed\n");
1159                 }
1160
1161                 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_DEC_STOP, 0)) {
1162                         ast_log(LOG_WARNING, "IFX_TAPI_DEC_STOP ioctl failed\n");
1163                 }
1164         }
1165
1166         if (ioctl(dev_ctx.dev_fd, IFX_TAPI_DEV_STOP, 0)) {
1167                 ast_log(LOG_WARNING, "IFX_TAPI_DEV_STOP ioctl failed\n");
1168         }
1169
1170         close(dev_ctx.dev_fd);
1171 }
1172
1173 static int unload_module(void)
1174 {
1175         int c;
1176
1177         ast_channel_unregister(&lantiq_tech);
1178
1179         if (!ast_mutex_lock(&iflock)) {
1180                 for (c = 0; c < dev_ctx.channels ; c++) {
1181                         if (iflist[c].owner)
1182                                 ast_softhangup(iflist[c].owner, AST_SOFTHANGUP_APPUNLOAD);
1183                 }
1184                 ast_mutex_unlock(&iflock);
1185         } else {
1186                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
1187                 return -1;
1188         }
1189
1190         if (!ast_mutex_lock(&monlock)) {
1191                 if (monitor_thread > AST_PTHREADT_NULL) {
1192                         monitor = 0;
1193                         while (pthread_kill(monitor_thread, SIGURG) == 0)
1194                                 sched_yield();
1195                         pthread_join(monitor_thread, NULL);
1196                 }
1197                 monitor_thread = AST_PTHREADT_STOP;
1198                 ast_mutex_unlock(&monlock);
1199         } else {
1200                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
1201                 return -1;
1202         }
1203
1204         return 0;
1205 }
1206
1207 static struct lantiq_pvt *lantiq_init_pvt(struct lantiq_pvt *pvt)
1208 {
1209         if (pvt) {
1210                 pvt->owner = NULL;
1211                 pvt->port_id = -1;
1212                 pvt->channel_state = UNKNOWN;
1213                 pvt->context[0] = '\0';
1214                 pvt->ext[0] = '\0';
1215                 pvt->dial_timer = 0;
1216                 pvt->dtmfbuf[0] = '\0';
1217                 pvt->dtmfbuf_len = 0;
1218                 pvt->call_setup_start = 0;
1219                 pvt->call_setup_delay = 0;
1220                 pvt->jb_size = 0;
1221                 pvt->jb_underflow = 0;
1222                 pvt->jb_overflow = 0;
1223                 pvt->jb_delay = 0;
1224                 pvt->jb_invalid = 0;
1225         } else {
1226                 ast_log(LOG_ERROR, "unable to clear pvt structure\n");
1227         }
1228
1229         return pvt;
1230 }
1231
1232 static int lantiq_create_pvts(void)
1233 {
1234         int i;
1235
1236         iflist = ast_calloc(1, sizeof(struct lantiq_pvt) * dev_ctx.channels);
1237
1238         if (iflist) { 
1239                 for (i=0 ; i<dev_ctx.channels ; i++) {
1240                         lantiq_init_pvt(&iflist[i]);
1241                         iflist[i].port_id = i;
1242                         if (per_channel_context) {
1243                                 snprintf(iflist[i].context, AST_MAX_CONTEXT, "%s%i", LANTIQ_CONTEXT_PREFIX, i+1);
1244                                 ast_debug(1, "Context for channel %i: %s\n", i, iflist[i].context);
1245                         } else {
1246                                 snprintf(iflist[i].context, AST_MAX_CONTEXT, "default");
1247                         }
1248                 }
1249                 return 0;
1250         } else {
1251                 ast_log(LOG_ERROR, "unable to allocate memory\n");
1252                 return -1;
1253         }
1254 }
1255
1256 static int lantiq_setup_rtp(int c)
1257 {
1258         /* Configure RTP payload type tables */
1259         IFX_TAPI_PKT_RTP_PT_CFG_t rtpPTConf;
1260
1261         memset((char*)&rtpPTConf, '\0', sizeof(rtpPTConf));
1262
1263         rtpPTConf.nPTup[IFX_TAPI_COD_TYPE_MLAW] = AST_FORMAT_ULAW;
1264         rtpPTConf.nPTup[IFX_TAPI_COD_TYPE_ALAW] = AST_FORMAT_ALAW;
1265 //      rtpPTConf.nPTup[IFX_TAPI_COD_TYPE_G723_63] = AST_FORMAT_G723_1;
1266 //      rtpPTConf.nPTup[IFX_TAPI_COD_TYPE_G723_53] = 4;
1267 //      rtpPTConf.nPTup[IFX_TAPI_COD_TYPE_G729] = AST_FORMAT_G729A;
1268 //      rtpPTConf.nPTup[IFX_TAPI_COD_TYPE_G722_64] = AST_FORMAT_G722;
1269
1270         rtpPTConf.nPTdown[IFX_TAPI_COD_TYPE_MLAW] = AST_FORMAT_ULAW;
1271         rtpPTConf.nPTdown[IFX_TAPI_COD_TYPE_ALAW] = AST_FORMAT_ALAW;
1272 //      rtpPTConf.nPTdown[IFX_TAPI_COD_TYPE_G723_63] = AST_FORMAT_G723_1;
1273 //      rtpPTConf.nPTdown[IFX_TAPI_COD_TYPE_G723_53] = AST_FORMAT_G723_1;
1274 //      rtpPTConf.nPTdown[IFX_TAPI_COD_TYPE_G729] = AST_FORMAT_G729A;
1275 //      rtpPTConf.nPTdown[IFX_TAPI_COD_TYPE_G722_64] = AST_FORMAT_G722;
1276
1277         int ret;
1278         if ((ret = ioctl(dev_ctx.ch_fd[c], IFX_TAPI_PKT_RTP_PT_CFG_SET, (IFX_int32_t) &rtpPTConf))) {
1279                 ast_log(LOG_ERROR, "IFX_TAPI_PKT_RTP_PT_CFG_SET failed: ret=%i\n", ret);
1280                 return -1;
1281         }
1282
1283         return 0;
1284 }
1285
1286 static int load_module(void)
1287 {
1288         struct ast_config *cfg;
1289         struct ast_variable *v;
1290         int txgain = 0;
1291         int rxgain = 0;
1292         int wlec_type = 0;
1293         int wlec_nlp = 0;
1294         int wlec_nbfe = 0;
1295         int wlec_nbne = 0;
1296         int wlec_wbne = 0;
1297         int jb_type = IFX_TAPI_JB_TYPE_ADAPTIVE;
1298         int jb_pckadpt = IFX_TAPI_JB_PKT_ADAPT_VOICE;
1299         int jb_localadpt = IFX_TAPI_JB_LOCAL_ADAPT_DEFAULT;
1300         int jb_scaling = 0x10;
1301         int jb_initialsize = 0x2d0;
1302         int jb_minsize = 0x50;
1303         int jb_maxsize = 0x5a0;
1304         int cid_type = IFX_TAPI_CID_STD_TELCORDIA;
1305         int vad_type = IFX_TAPI_ENC_VAD_NOVAD;
1306         dev_ctx.channels = TAPI_AUDIO_PORT_NUM_MAX;
1307         struct ast_flags config_flags = { 0 };
1308         
1309         if (!(sched_thread = ast_sched_thread_create())) {
1310                 ast_log(LOG_ERROR, "Unable to create scheduler thread\n");
1311                 return AST_MODULE_LOAD_FAILURE;
1312         }
1313
1314         if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) {
1315                 ast_log(LOG_ERROR, "Config file %s is in an invalid format.  Aborting.\n", config);
1316                 return AST_MODULE_LOAD_DECLINE;
1317         }
1318
1319         /* We *must* have a config file otherwise stop immediately */
1320         if (!cfg) {
1321                 ast_log(LOG_ERROR, "Unable to load config %s\n", config);
1322                 return AST_MODULE_LOAD_DECLINE;
1323         }
1324
1325         if (ast_mutex_lock(&iflock)) {
1326                 ast_log(LOG_ERROR, "Unable to lock interface list.\n");
1327                 return AST_MODULE_LOAD_FAILURE;
1328         }
1329
1330         for (v = ast_variable_browse(cfg, "interfaces"); v; v = v->next) {
1331                 if (!strcasecmp(v->name, "channels")) {
1332                         dev_ctx.channels = atoi(v->value);
1333                         if (!dev_ctx.channels) {
1334                                 ast_log(LOG_ERROR, "Invalid value for channels in config %s\n", config);
1335                                 ast_config_destroy(cfg);
1336                                 return AST_MODULE_LOAD_DECLINE;
1337                         }
1338                 } else if (!strcasecmp(v->name, "firmwarefilename")) {
1339                         ast_copy_string(firmware_filename, v->value, sizeof(firmware_filename));
1340                 } else if (!strcasecmp(v->name, "bbdfilename")) {
1341                         ast_copy_string(bbd_filename, v->value, sizeof(bbd_filename));
1342                 } else if (!strcasecmp(v->name, "basepath")) {
1343                         ast_copy_string(base_path, v->value, sizeof(base_path));
1344                 } else if (!strcasecmp(v->name, "per_channel_context")) {
1345                         if (!strcasecmp(v->value, "on")) {
1346                                 per_channel_context = 1;
1347                         } else if (!strcasecmp(v->value, "off")) {
1348                                 per_channel_context = 0;
1349                         } else {
1350                                 ast_log(LOG_ERROR, "Unknown per_channel_context value '%s'. Try 'on' or 'off'.\n", v->value);
1351                                 ast_config_destroy(cfg);
1352                                 return AST_MODULE_LOAD_DECLINE;
1353                         }
1354                 }
1355         }
1356
1357         for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
1358                 if (!strcasecmp(v->name, "rxgain")) {
1359                         rxgain = atoi(v->value);
1360                         if (!rxgain) {
1361                                 rxgain = 0;
1362                                 ast_log(LOG_WARNING, "Invalid rxgain: %s, using default.\n", v->value);
1363                         }
1364                 } else if (!strcasecmp(v->name, "txgain")) {
1365                         txgain = atoi(v->value);
1366                         if (!txgain) {
1367                                 txgain = 0;
1368                                 ast_log(LOG_WARNING, "Invalid txgain: %s, using default.\n", v->value);
1369                         }
1370                 } else if (!strcasecmp(v->name, "echocancel")) {
1371                         if (!strcasecmp(v->value, "off")) {
1372                                 wlec_type = IFX_TAPI_WLEC_TYPE_OFF;
1373                         } else if (!strcasecmp(v->value, "nlec")) {
1374                                 wlec_type = IFX_TAPI_WLEC_TYPE_NE;
1375                                 if (!strcasecmp(v->name, "echocancelfixedwindowsize")) {
1376                                         wlec_nbne = atoi(v->value);
1377                                 }
1378                         } else if (!strcasecmp(v->value, "wlec")) {
1379                                 wlec_type = IFX_TAPI_WLEC_TYPE_NFE;
1380                                 if (!strcasecmp(v->name, "echocancelnfemovingwindowsize")) {
1381                                         wlec_nbfe = atoi(v->value);
1382                                 } else if (!strcasecmp(v->name, "echocancelfixedwindowsize")) {
1383                                         wlec_nbne = atoi(v->value);
1384                                 } else if (!strcasecmp(v->name, "echocancelwidefixedwindowsize")) {
1385                                         wlec_wbne = atoi(v->value);
1386                                 }
1387                         } else if (!strcasecmp(v->value, "nees")) {
1388                                 wlec_type = IFX_TAPI_WLEC_TYPE_NE_ES;
1389                         } else if (!strcasecmp(v->value, "nfees")) {
1390                                 wlec_type = IFX_TAPI_WLEC_TYPE_NFE_ES;
1391                         } else if (!strcasecmp(v->value, "es")) {
1392                                 wlec_type = IFX_TAPI_WLEC_TYPE_ES;
1393                         } else {
1394                                 wlec_type = IFX_TAPI_WLEC_TYPE_OFF;
1395                                 ast_log(LOG_ERROR, "Unknown echo cancellation type '%s'\n", v->value);
1396                                 ast_config_destroy(cfg);
1397                                 return AST_MODULE_LOAD_DECLINE;
1398                         }
1399                 } else if (!strcasecmp(v->name, "echocancelnlp")) {
1400                         if (!strcasecmp(v->value, "on")) {
1401                                 wlec_nlp = IFX_TAPI_WLEC_NLP_ON;
1402                         } else if (!strcasecmp(v->value, "off")) {
1403                                 wlec_nlp = IFX_TAPI_WLEC_NLP_OFF;
1404                         } else {
1405                                 ast_log(LOG_ERROR, "Unknown echo cancellation nlp '%s'\n", v->value);
1406                                 ast_config_destroy(cfg);
1407                                 return AST_MODULE_LOAD_DECLINE;
1408                         }
1409                 } else if (!strcasecmp(v->name, "jitterbuffertype")) {
1410                         if (!strcasecmp(v->value, "fixed")) {
1411                                 jb_type = IFX_TAPI_JB_TYPE_FIXED;
1412                         } else if (!strcasecmp(v->value, "adaptive")) {
1413                                 jb_type = IFX_TAPI_JB_TYPE_ADAPTIVE;
1414                                 jb_localadpt = IFX_TAPI_JB_LOCAL_ADAPT_DEFAULT;
1415                                 if (!strcasecmp(v->name, "jitterbufferadaptation")) {
1416                                         if (!strcasecmp(v->value, "on")) {
1417                                                 jb_localadpt = IFX_TAPI_JB_LOCAL_ADAPT_ON;
1418                                         } else if (!strcasecmp(v->value, "off")) {
1419                                                 jb_localadpt = IFX_TAPI_JB_LOCAL_ADAPT_OFF;
1420                                         }
1421                                 } else if (!strcasecmp(v->name, "jitterbufferscalling")) {
1422                                         jb_scaling = atoi(v->value);
1423                                 } else if (!strcasecmp(v->name, "jitterbufferinitialsize")) {
1424                                         jb_initialsize = atoi(v->value);
1425                                 } else if (!strcasecmp(v->name, "jitterbufferminsize")) {
1426                                         jb_minsize = atoi(v->value);
1427                                 } else if (!strcasecmp(v->name, "jitterbuffermaxsize")) {
1428                                         jb_maxsize = atoi(v->value);
1429                                 }
1430                         } else {
1431                                 ast_log(LOG_ERROR, "Unknown jitter buffer type '%s'\n", v->value);
1432                                 ast_config_destroy(cfg);
1433                                 return AST_MODULE_LOAD_DECLINE;
1434                         }
1435                 } else if (!strcasecmp(v->name, "jitterbufferpackettype")) {
1436                         if (!strcasecmp(v->value, "voice")) {
1437                                 jb_pckadpt = IFX_TAPI_JB_PKT_ADAPT_VOICE;
1438                         } else if (!strcasecmp(v->value, "data")) {
1439                                 jb_pckadpt = IFX_TAPI_JB_PKT_ADAPT_DATA;
1440                         } else if (!strcasecmp(v->value, "datanorep")) {
1441                                 jb_pckadpt = IFX_TAPI_JB_PKT_ADAPT_DATA_NO_REP;
1442                         } else {
1443                                 ast_log(LOG_ERROR, "Unknown jitter buffer packet adaptation type '%s'\n", v->value);
1444                                 ast_config_destroy(cfg);
1445                                 return AST_MODULE_LOAD_DECLINE;
1446                         }
1447                 } else if (!strcasecmp(v->name, "calleridtype")) {
1448                         ast_log(LOG_DEBUG, "Setting CID type to %s.\n", v->value);
1449                         if (!strcasecmp(v->value, "telecordia")) {
1450                                 cid_type = IFX_TAPI_CID_STD_TELCORDIA;
1451                         } else if (!strcasecmp(v->value, "etsifsk")) {
1452                                 cid_type = IFX_TAPI_CID_STD_ETSI_FSK;
1453                         } else if (!strcasecmp(v->value, "etsidtmf")) {
1454                                 cid_type = IFX_TAPI_CID_STD_ETSI_DTMF;
1455                         } else if (!strcasecmp(v->value, "sin")) {
1456                                 cid_type = IFX_TAPI_CID_STD_SIN;
1457                         } else if (!strcasecmp(v->value, "ntt")) {
1458                                 cid_type = IFX_TAPI_CID_STD_NTT;
1459                         } else if (!strcasecmp(v->value, "kpndtmf")) {
1460                                 cid_type = IFX_TAPI_CID_STD_KPN_DTMF;
1461                         } else if (!strcasecmp(v->value, "kpndtmffsk")) {
1462                                 cid_type = IFX_TAPI_CID_STD_KPN_DTMF_FSK;
1463                         } else {
1464                                 ast_log(LOG_ERROR, "Unknown caller id type '%s'\n", v->value);
1465                                 ast_config_destroy(cfg);
1466                                 return AST_MODULE_LOAD_DECLINE;
1467                         }
1468                 } else if (!strcasecmp(v->name, "voiceactivitydetection")) {
1469                         if (!strcasecmp(v->value, "on")) {
1470                                 vad_type = IFX_TAPI_ENC_VAD_ON;
1471                         } else if (!strcasecmp(v->value, "g711")) {
1472                                 vad_type = IFX_TAPI_ENC_VAD_G711;
1473                         } else if (!strcasecmp(v->value, "cng")) {
1474                                 vad_type = IFX_TAPI_ENC_VAD_CNG_ONLY;
1475                         } else if (!strcasecmp(v->value, "sc")) {
1476                                 vad_type = IFX_TAPI_ENC_VAD_SC_ONLY;
1477                         } else {
1478                                 ast_log(LOG_ERROR, "Unknown voice activity detection value '%s'\n", v->value);
1479                                 ast_config_destroy(cfg);
1480                                 return AST_MODULE_LOAD_DECLINE;
1481                         }
1482                 }
1483         }
1484
1485         lantiq_create_pvts();
1486
1487         ast_mutex_unlock(&iflock);
1488
1489         if (ast_channel_register(&lantiq_tech)) {
1490                 ast_log(LOG_ERROR, "Unable to register channel class 'Phone'\n");
1491                 ast_config_destroy(cfg);
1492                 unload_module();
1493                 return AST_MODULE_LOAD_FAILURE;
1494         }
1495         ast_config_destroy(cfg);
1496         
1497         /* tapi */
1498 #ifdef TODO_TONES
1499         IFX_TAPI_TONE_t tone;
1500 #endif
1501         IFX_TAPI_DEV_START_CFG_t dev_start;
1502         IFX_TAPI_MAP_DATA_t map_data;
1503         IFX_TAPI_ENC_CFG_t enc_cfg;
1504         IFX_TAPI_LINE_VOLUME_t line_vol;
1505         IFX_TAPI_WLEC_CFG_t wlec_cfg;
1506         IFX_TAPI_JB_CFG_t jb_cfg;
1507         IFX_TAPI_CID_CFG_t cid_cfg;
1508         uint8_t c;
1509
1510         /* open device */
1511         dev_ctx.dev_fd = lantiq_dev_open(base_path, 0);
1512
1513         if (dev_ctx.dev_fd < 0) {
1514                 ast_log(LOG_ERROR, "lantiq tapi device open function failed\n");
1515                 return AST_MODULE_LOAD_FAILURE;
1516         }
1517
1518         for (c = 0; c < dev_ctx.channels ; c++) {
1519                 dev_ctx.ch_fd[c] = lantiq_dev_open(base_path, c + 1);
1520
1521                 if (dev_ctx.ch_fd[c] < 0) {
1522                         ast_log(LOG_ERROR, "lantiq tapi channel %d open function failed\n", c);
1523                         return AST_MODULE_LOAD_FAILURE;
1524                 }
1525         }
1526
1527         if (lantiq_dev_firmware_download(dev_ctx.dev_fd, firmware_filename)) {
1528                 ast_log(LOG_ERROR, "voice firmware download failed\n");
1529                 return AST_MODULE_LOAD_FAILURE;
1530         }
1531
1532         if (ioctl(dev_ctx.dev_fd, IFX_TAPI_DEV_STOP, 0)) {
1533                 ast_log(LOG_ERROR, "IFX_TAPI_DEV_STOP ioctl failed\n");
1534                 return AST_MODULE_LOAD_FAILURE;
1535         }
1536
1537         memset(&dev_start, 0x0, sizeof(IFX_TAPI_DEV_START_CFG_t));
1538         dev_start.nMode = IFX_TAPI_INIT_MODE_VOICE_CODER;
1539
1540         /* Start TAPI */
1541         if (ioctl(dev_ctx.dev_fd, IFX_TAPI_DEV_START, &dev_start)) {
1542                 ast_log(LOG_ERROR, "IFX_TAPI_DEV_START ioctl failed\n");
1543                 return AST_MODULE_LOAD_FAILURE;
1544         }
1545
1546         for (c = 0; c < dev_ctx.channels ; c++) {
1547                 /* tones */
1548 #ifdef TODO_TONES
1549                 memset(&tone, 0, sizeof(IFX_TAPI_TONE_t));
1550                 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_TONE_TABLE_CFG_SET, &tone)) {
1551                         ast_log(LOG_ERROR, "IFX_TAPI_TONE_TABLE_CFG_SET %d failed\n", c);
1552                         return AST_MODULE_LOAD_FAILURE;
1553                 }
1554 #endif
1555                 /* ringing type */
1556                 IFX_TAPI_RING_CFG_t ringingType;
1557                 memset(&ringingType, 0, sizeof(IFX_TAPI_RING_CFG_t));
1558                 ringingType.nMode = IFX_TAPI_RING_CFG_MODE_INTERNAL_BALANCED;
1559                 ringingType.nSubmode = IFX_TAPI_RING_CFG_SUBMODE_DC_RNG_TRIP_FAST;
1560                 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_RING_CFG_SET, (IFX_int32_t) &ringingType)) {
1561                         ast_log(LOG_ERROR, "IFX_TAPI_RING_CFG_SET failed\n");
1562                         return AST_MODULE_LOAD_FAILURE;
1563                 }
1564
1565                 /* ring cadence */
1566                 IFX_char_t data[15] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1567                                                                 0x00, 0x00, 0x00, 0x00, 0x00,     
1568                                                                 0x00, 0x00, 0x00, 0x00, 0x00 };
1569
1570                 IFX_TAPI_RING_CADENCE_t ringCadence;
1571                 memset(&ringCadence, 0, sizeof(IFX_TAPI_RING_CADENCE_t));
1572                 memcpy(&ringCadence.data, data, sizeof(data));
1573                 ringCadence.nr = sizeof(data) * 8;
1574
1575                 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_RING_CADENCE_HR_SET, &ringCadence)) {
1576                         ast_log(LOG_ERROR, "IFX_TAPI_RING_CADENCE_HR_SET failed\n");
1577                         return AST_MODULE_LOAD_FAILURE;
1578                 }
1579
1580                 /* perform mapping */
1581                 memset(&map_data, 0x0, sizeof(IFX_TAPI_MAP_DATA_t));
1582                 map_data.nDstCh = c;
1583                 map_data.nChType = IFX_TAPI_MAP_TYPE_PHONE;
1584
1585                 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_MAP_DATA_ADD, &map_data)) {
1586                         ast_log(LOG_ERROR, "IFX_TAPI_MAP_DATA_ADD %d failed\n", c);
1587                         return AST_MODULE_LOAD_FAILURE;
1588                 }
1589
1590                 /* set line feed */
1591                 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_LINE_FEED_SET, IFX_TAPI_LINE_FEED_STANDBY)) {
1592                         ast_log(LOG_ERROR, "IFX_TAPI_LINE_FEED_SET %d failed\n", c);
1593                         return AST_MODULE_LOAD_FAILURE;
1594                 }
1595
1596                 /* Configure encoder */
1597                 memset(&enc_cfg, 0x0, sizeof(IFX_TAPI_ENC_CFG_t));
1598                 enc_cfg.nFrameLen = IFX_TAPI_COD_LENGTH_20;
1599                 enc_cfg.nEncType = IFX_TAPI_COD_TYPE_MLAW;
1600
1601                 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_ENC_CFG_SET, &enc_cfg)) {
1602                         ast_log(LOG_ERROR, "IFX_TAPI_ENC_CFG_SET %d failed\n", c);
1603                         return AST_MODULE_LOAD_FAILURE;
1604                 }
1605
1606                 /* set volume */
1607                 memset(&line_vol, 0, sizeof(line_vol));
1608                 line_vol.nGainRx = rxgain;
1609                 line_vol.nGainTx = txgain;
1610
1611                 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_PHONE_VOLUME_SET, &line_vol)) {
1612                         ast_log(LOG_ERROR, "IFX_TAPI_PHONE_VOLUME_SET %d failed\n", c);
1613                         return AST_MODULE_LOAD_FAILURE;
1614                 }
1615
1616                 /* Configure line echo canceller */
1617                 memset(&wlec_cfg, 0, sizeof(wlec_cfg));
1618                 wlec_cfg.nType = wlec_type;
1619                 wlec_cfg.bNlp = wlec_nlp;
1620                 wlec_cfg.nNBFEwindow = wlec_nbfe;
1621                 wlec_cfg.nNBNEwindow = wlec_nbne;
1622                 wlec_cfg.nWBNEwindow = wlec_wbne;
1623
1624                 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_WLEC_PHONE_CFG_SET, &wlec_cfg)) {
1625                         ast_log(LOG_ERROR, "IFX_TAPI_WLEC_PHONE_CFG_SET %d failed\n", c);
1626                         return AST_MODULE_LOAD_FAILURE;
1627                 }
1628
1629                 /* Configure jitter buffer */
1630                 memset(&jb_cfg, 0, sizeof(jb_cfg));
1631                 jb_cfg.nJbType = jb_type;
1632                 jb_cfg.nPckAdpt = jb_pckadpt;
1633                 jb_cfg.nLocalAdpt = jb_localadpt;
1634                 jb_cfg.nScaling = jb_scaling;
1635                 jb_cfg.nInitialSize = jb_initialsize;
1636                 jb_cfg.nMinSize = jb_minsize;
1637                 jb_cfg.nMaxSize = jb_maxsize;
1638
1639                 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_JB_CFG_SET, &jb_cfg)) {
1640                         ast_log(LOG_ERROR, "IFX_TAPI_JB_CFG_SET %d failed\n", c);
1641                         return AST_MODULE_LOAD_FAILURE;
1642                 }
1643
1644                 /* Configure Caller ID type */
1645                 memset(&cid_cfg, 0, sizeof(cid_cfg));
1646                 cid_cfg.nStandard = cid_type;
1647
1648                 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_CID_CFG_SET, &cid_cfg)) {
1649                         ast_log(LOG_ERROR, "IIFX_TAPI_CID_CFG_SET %d failed\n", c);
1650                         return AST_MODULE_LOAD_FAILURE;
1651                 }
1652
1653                 /* Configure voice activity detection */
1654                 if (ioctl(dev_ctx.ch_fd[c], IFX_TAPI_ENC_VAD_CFG_SET, vad_type)) {
1655                         ast_log(LOG_ERROR, "IFX_TAPI_ENC_VAD_CFG_SET %d failed\n", c);
1656                         return AST_MODULE_LOAD_FAILURE;
1657                 }
1658
1659                 /* Setup TAPI <-> Asterisk codec type mapping */
1660                 if (lantiq_setup_rtp(c)) {
1661                         return AST_MODULE_LOAD_FAILURE;
1662                 }
1663
1664                 /* Set initial hook status */
1665                 iflist[c].channel_state = lantiq_get_hookstatus(c);
1666                 
1667                 if (iflist[c].channel_state == UNKNOWN) {
1668                         return AST_MODULE_LOAD_FAILURE;
1669                 }
1670         }
1671
1672         /* make sure our device will be closed properly */
1673         ast_register_atexit(lantiq_cleanup);
1674
1675         restart_monitor();
1676         return AST_MODULE_LOAD_SUCCESS;
1677 }
1678
1679 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Lantiq TAPI Telephony API Support");