branch Attitude Adjustment packages
[12.09/packages.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 } *iflist = NULL;
119
120 static struct lantiq_ctx {
121                 int dev_fd;
122                 int channels;
123                 int ch_fd[TAPI_AUDIO_PORT_NUM_MAX];
124 } dev_ctx;
125
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);
137
138 static const struct ast_channel_tech lantiq_tech = {
139         .type = "TAPI",
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
153 };
154
155 /* Protect the interface list (of lantiq_pvt's) */
156 AST_MUTEX_DEFINE_STATIC(iflock);
157
158 /*
159  * Protect the monitoring thread, so only one process can kill or start it, and
160  * not when it's doing something critical.
161  */
162 AST_MUTEX_DEFINE_STATIC(monlock);
163
164 /* Boolean value whether the monitoring thread shall continue. */
165 static unsigned int monitor;
166
167 /* The scheduling thread */
168 struct ast_sched_thread *sched_thread;
169    
170 /*
171  * This is the thread for the monitor which checks for input on the channels
172  * which are not currently in use.
173  */
174 static pthread_t monitor_thread = AST_PTHREADT_NULL;
175
176
177 #define WORDS_BIGENDIAN
178 /* struct taken from some GPLed code by  Mike Borella */
179 typedef struct rtp_header
180 {
181 #if defined(WORDS_BIGENDIAN)
182   uint8_t version:2, padding:1, extension:1, csrc_count:4;
183 #else
184   uint8_t csrc_count:4, extension:1, padding:1, version:2;
185 #endif
186 #if defined(WORDS_BIGENDIAN)
187   uint8_t marker:1, payload_type:7;
188 #else
189   uint8_t payload_type:7, marker:1;
190 #endif
191   uint16_t seqno;
192   uint32_t timestamp;
193   uint32_t ssrc;
194 } rtp_header_t;
195
196 static int lantiq_dev_open(const char *dev_path, const int32_t ch_num)
197 {
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);
202 }
203
204 static void lantiq_ring(int c, int r)
205 {
206         uint8_t status;
207
208         if (r) {
209                 status = (uint8_t) ioctl(dev_ctx.ch_fd[c], IFX_TAPI_RING_START, 0);
210         } else {
211                 status = (uint8_t) ioctl(dev_ctx.ch_fd[c], IFX_TAPI_RING_STOP, 0);
212         }
213
214         if (status) {
215                 ast_log(LOG_ERROR, "%s ioctl failed\n",
216                         (r ? "IFX_TAPI_RING_START" : "IFX_TAPI_RING_STOP"));
217         }
218 }
219
220 static int lantiq_play_tone(int c, int t)
221 {
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);
225         }
226
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");
229                 return -1;
230         }
231
232         return 0;
233 }
234
235 static enum channel_state lantiq_get_hookstatus(int port)
236 {
237         uint8_t status;
238
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");
241                 return UNKNOWN;
242         }
243
244         if (status) {
245                 return OFFHOOK;
246         } else {
247                 return ONHOOK;
248         }
249 }
250
251 static int
252 lantiq_dev_binary_buffer_create(const char *path, uint8_t **ppBuf, uint32_t *pBufSz)
253 {
254         FILE *fd;
255         struct stat file_stat;
256         int32_t status = 0;
257
258         fd = fopen(path, "rb");
259         if (fd == NULL) {
260                 ast_log(LOG_ERROR, "binary file %s open failed\n", path);
261                 return -1;
262         }
263
264         if (stat(path, &file_stat)) {
265                 ast_log(LOG_ERROR, "file %s statistics get failed\n", path);
266                 return -1;
267         }
268
269         *ppBuf = malloc(file_stat.st_size);
270         if (*ppBuf == NULL) {
271                 ast_log(LOG_ERROR, "binary file %s memory allocation failed\n", path);
272                 status = -1;
273                 goto on_exit;
274         }
275
276         if (fread (*ppBuf, sizeof(uint8_t), file_stat.st_size, fd) <= 0) {
277                 ast_log(LOG_ERROR, "file %s read failed\n", path);
278                 status = -1;
279                 goto on_exit;
280         }
281
282         *pBufSz = file_stat.st_size;
283
284 on_exit:
285         if (fd != NULL)
286                 fclose(fd);
287
288         if (*ppBuf != NULL && status)
289                 free(*ppBuf);
290
291         return status;
292 }
293
294 static int32_t lantiq_dev_firmware_download(int32_t fd, const char *path)
295 {
296         uint8_t *firmware = NULL;
297         uint32_t size = 0;
298         VMMC_IO_INIT vmmc_io_init;
299
300         ast_log(LOG_DEBUG, "loading firmware: \"%s\".", path);
301
302         if (lantiq_dev_binary_buffer_create(path, &firmware, &size))
303                 return -1;
304
305         memset(&vmmc_io_init, 0, sizeof(VMMC_IO_INIT));
306         vmmc_io_init.pPRAMfw = firmware;
307         vmmc_io_init.pram_size = size;
308
309         if (ioctl(fd, FIO_FW_DOWNLOAD, &vmmc_io_init)) {
310                 ast_log(LOG_ERROR, "FIO_FW_DOWNLOAD ioctl failed\n");
311                 return -1;
312         }
313
314         if (firmware != NULL)
315                 free(firmware);
316
317         return 0;
318 }
319
320 static const char *state_string(enum channel_state s)
321 {
322         switch (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";
330         }
331 }
332
333 static const char *control_string(int c)
334 {
335         switch (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";
359         }
360 }
361
362 static int ast_lantiq_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
363 {
364         ast_verb(3, "phone indication \"%s\"\n", control_string(condition));
365
366         struct lantiq_pvt *pvt = chan->tech_pvt;
367
368         switch (condition) {
369                 case -1:
370                         {
371                                 lantiq_play_tone(pvt->port_id, TAPI_TONE_LOCALE_NONE);
372                                 return 0;
373                         }
374                 case AST_CONTROL_CONGESTION:
375                 case AST_CONTROL_BUSY:
376                         {
377                                 lantiq_play_tone(pvt->port_id, TAPI_TONE_LOCALE_BUSY_CODE);
378                                 return 0;
379                         }
380                 case AST_CONTROL_RINGING:
381                         {
382                                 lantiq_play_tone(pvt->port_id, TAPI_TONE_LOCALE_RINGING_CODE);
383                                 return 0;
384                         }
385                 default:
386                         {
387                                 /* -1 lets asterisk generate the tone */
388                                 return -1;
389                         }
390         }
391 }
392
393 static int ast_lantiq_fixup(struct ast_channel *old, struct ast_channel *new)
394 {
395         ast_log(LOG_DEBUG, "entering... no code here...\n");
396         return 0;
397 }
398
399 static int ast_digit_begin(struct ast_channel *chan, char digit)
400 {
401         /* TODO: Modify this callback to let Asterisk support controlling the length of DTMF */
402         ast_log(LOG_DEBUG, "entering... no code here...\n");
403         return 0;
404 }
405
406 static int ast_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
407 {
408         ast_log(LOG_DEBUG, "entering... no code here...\n");
409         return 0;
410 }
411
412 static int ast_lantiq_call(struct ast_channel *ast, char *dest, int timeout)
413 {
414         /* lock to prevent simultaneous access with do_monitor thread processing */
415         ast_mutex_lock(&iflock);
416
417         struct lantiq_pvt *pvt = ast->tech_pvt;
418         ast_log(LOG_DEBUG, "state: %s\n", state_string(pvt->channel_state));
419
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;
424
425                 ast_setstate(ast, AST_STATE_RINGING);
426                 ast_queue_control(ast, AST_CONTROL_RINGING);
427         } else {
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);
431         }
432                 
433         ast_mutex_unlock(&iflock);
434
435         return 0;
436 }
437
438 static int ast_lantiq_hangup(struct ast_channel *ast)
439 {
440         /* lock to prevent simultaneous access with do_monitor thread processing */
441         ast_mutex_lock(&iflock);
442
443         struct lantiq_pvt *pvt = ast->tech_pvt;
444         ast_log(LOG_DEBUG, "state: %s\n", state_string(pvt->channel_state));
445         
446         if (ast->_state == AST_STATE_RINGING) {
447                 // FIXME
448                 ast_debug(1, "TAPI: ast_lantiq_hangup(): ast->_state == AST_STATE_RINGING\n");
449         }
450
451         switch (pvt->channel_state) {
452                 case RINGING:
453                 case ONHOOK: 
454                         lantiq_ring(pvt->port_id, 0);
455                         pvt->channel_state = ONHOOK;
456                         break;
457                 default:
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);
461         }
462
463         ast_setstate(ast, AST_STATE_DOWN);
464         ast_module_unref(ast_module_info->self);
465         ast->tech_pvt = NULL;
466         pvt->owner = NULL;
467
468         ast_mutex_unlock(&iflock);
469
470         return 0;
471 }
472
473 static int ast_lantiq_answer(struct ast_channel *ast)
474 {
475         ast_log(LOG_DEBUG, "entering... no code here...\n");
476         return 0;
477 }
478
479 static struct ast_frame * ast_lantiq_read(struct ast_channel *ast)
480 {
481         ast_log(LOG_DEBUG, "entering... no code here...\n");
482         return NULL;
483 }
484
485 static int ast_lantiq_write(struct ast_channel *ast, struct ast_frame *frame)
486 {
487         char buf[2048];
488         struct lantiq_pvt *pvt = ast->tech_pvt;
489         int ret = -1;
490         rtp_header_t *rtp_header = (rtp_header_t *) buf;
491
492         if(frame->frametype != AST_FRAME_VOICE) {
493                 ast_log(LOG_DEBUG, "unhandled frame type\n");
494                 return 0;
495         }
496         
497         if (frame->datalen == 0) {
498                 ast_log(LOG_DEBUG, "we've been prodded\n");
499                 return 0;
500         }
501
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;
512
513         pvt->rtp_timestamp += 160;
514
515         memcpy(buf+RTP_HEADER_LEN, frame->data.ptr, frame->datalen);
516
517         ret = write(dev_ctx.ch_fd[pvt->port_id], buf, frame->datalen+RTP_HEADER_LEN);
518         if (ret <= 0) {
519                 ast_debug(1, "TAPI: ast_lantiq_write(): error writing.\n");
520                 return -1;
521         }
522
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", 
526                          (int)ret,
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);
536 #endif
537
538         return 0;
539 }
540
541 static struct ast_frame * ast_lantiq_exception(struct ast_channel *ast)
542 {
543         ast_log(LOG_DEBUG, "entering... no code here...\n");
544         return NULL;
545 }
546
547 static int lantiq_standby(int c)
548 {
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");
551                 return -1;
552         }
553
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");
556                 return -1;
557         }
558
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");
561                 return -1;
562         }
563
564         return lantiq_play_tone(c, TAPI_TONE_LOCALE_NONE);
565 }
566
567 static int lantiq_end_dialing(int c)
568 {
569         ast_log(LOG_DEBUG, "TODO - DEBUG MSG");
570         struct lantiq_pvt *pvt = &iflist[c];
571
572         if (pvt->dial_timer) {
573                 ast_sched_thread_del(sched_thread, pvt->dial_timer);
574                 pvt->dial_timer = 0;
575         }
576
577         if(pvt->owner) {
578                 ast_hangup(pvt->owner);
579         }
580
581         return 0;
582 }
583
584 static int lantiq_end_call(int c)
585 {
586         ast_log(LOG_DEBUG, "TODO - DEBUG MSG");
587
588         struct lantiq_pvt *pvt = &iflist[c];
589         
590         if(pvt->owner) {
591                 ast_queue_hangup(pvt->owner);
592         }
593
594         return 0;
595 }
596
597 static struct ast_channel * lantiq_channel(int state, int c, char *ext, char *ctx)
598 {
599         ast_log(LOG_DEBUG, "TODO - DEBUG MSG");
600
601         struct ast_channel *chan = NULL;
602
603         struct lantiq_pvt *pvt = &iflist[c];
604
605         chan = ast_channel_alloc(1, state, NULL, NULL, "", ext, ctx, 0, c, "TAPI/%s", "1");
606
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;
612
613         pvt->owner = chan;
614
615         return chan;
616 }
617
618 static struct ast_channel * ast_lantiq_requester(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
619 {
620         ast_mutex_lock(&iflock);
621
622         char buf[BUFSIZ];
623         struct ast_channel *chan = NULL;
624         int port_id = -1;
625
626         ast_debug(1, "Asked to create a TAPI channel with formats: %s\n", ast_getformatname_multiple(buf, sizeof(buf), format));
627
628
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;
633                 return NULL;
634         }
635
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;
641                 return NULL;
642         }
643
644         /* on asterisk user's side, we're using port 1-2.
645          * Here in non normal human's world, we begin
646          * counting at 0.
647          */
648         port_id -= 1;
649
650         chan = lantiq_channel(AST_STATE_DOWN, port_id, NULL, NULL);
651
652         ast_mutex_unlock(&iflock);
653         return chan;
654 }
655
656 static int lantiq_dev_data_handler(int c)
657 {
658         char buf[BUFSIZ];
659         struct ast_frame frame = {0};
660
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);
663         
664         rtp_header_t *rtp = (rtp_header_t*) buf;
665
666         frame.src = "TAPI";
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;
672
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);
679                 }
680         }
681
682         ast_mutex_unlock(&iflock);
683
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", 
686                                  (int)res,
687                                  (int)rtp->version,
688                                  (int)rtp->padding,
689                                  (int)rtp->extension,
690                                  (int)rtp->csrc_count,
691                                  (int)rtp->marker,
692                                  ast_codec2str(rtp->payload_type),
693                                  (int)rtp->seqno,
694                                  (int)rtp->timestamp,
695                                  (int)rtp->ssrc);
696 */
697         return 0;
698 }
699
700 static int accept_call(int c)
701
702         ast_log(LOG_DEBUG, "TODO - DEBUG MSG");
703
704         struct lantiq_pvt *pvt = &iflist[c];
705
706         if (pvt->owner) {
707                 struct ast_channel *chan = pvt->owner;
708
709                 switch (chan->_state) {
710                         case AST_STATE_RINGING:
711                                 ast_queue_control(pvt->owner, AST_CONTROL_ANSWER);
712                                 pvt->channel_state = INCALL;
713                                 break;
714                         default:
715                                 ast_log(LOG_WARNING, "entered unhandled state %s\n", ast_state2str(chan->_state));
716                 }
717         }
718
719         return 0;
720 }
721
722 static int lantiq_dev_event_hook(int c, int state)
723 {
724         ast_mutex_lock(&iflock);
725
726         ast_log(LOG_DEBUG, "on port %i detected event %s hook\n", c, state ? "on" : "off");
727
728         int ret = -1;
729         if (state) {
730                 switch (iflist[c].channel_state) {
731                         case OFFHOOK: 
732                                 ret = lantiq_standby(c);
733                                 break;
734                         case DIALING: 
735                                 ret = lantiq_end_dialing(c);
736                                 break;
737                         case INCALL: 
738                                 ret = lantiq_end_call(c);
739                                 break;
740                         case CALL_ENDED:
741                                 ret = lantiq_standby(c); // TODO: are we sure for this ?
742                                 break;
743                         default:
744                                 break;
745                 }
746                 iflist[c].channel_state = ONHOOK;
747         } else {
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");
750                         goto out;
751                 }
752
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");
755                         goto out;
756                 }
757
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");
760                         goto out;
761                 }
762
763                 switch (iflist[c].channel_state) {
764                         case RINGING: 
765                                 ret = accept_call(c);
766                                 break;
767                         default:
768                                 iflist[c].channel_state = OFFHOOK;
769                                 lantiq_play_tone(c, TAPI_TONE_LOCALE_DIAL_CODE);
770                                 ret = 0;
771                                 break;
772                 }
773
774         }
775
776 out:
777         ast_mutex_unlock(&iflock);
778
779         return ret;
780 }
781
782 static void lantiq_reset_dtmfbuf(struct lantiq_pvt *pvt)
783 {
784         pvt->dtmfbuf[0] = '\0';
785         pvt->dtmfbuf_len = 0;
786         pvt->ext[0] = '\0';
787 }
788
789 static void lantiq_dial(struct lantiq_pvt *pvt)
790 {
791         struct ast_channel *chan = NULL;
792
793         ast_log(LOG_DEBUG, "user want's to dial %s.\n", pvt->dtmfbuf);
794
795         if (ast_exists_extension(NULL, pvt->context, pvt->dtmfbuf, 1, NULL)) {
796                 ast_debug(1, "found extension %s, dialing\n", pvt->dtmfbuf);
797
798                 strcpy(pvt->ext, pvt->dtmfbuf);
799
800                 ast_verbose(VERBOSE_PREFIX_3 " extension exists, starting PBX %s\n", pvt->ext);
801
802                 chan = lantiq_channel(AST_STATE_UP, 1, pvt->ext+1, pvt->context);
803                 chan->tech_pvt = pvt;
804                 pvt->owner = chan;
805
806                 strcpy(chan->exten, pvt->ext);
807                 ast_setstate(chan, AST_STATE_RING);
808                 pvt->channel_state = INCALL;
809
810                 if (ast_pbx_start(chan)) {
811                         ast_log(LOG_WARNING, " unable to start PBX on %s\n", chan->name);
812                         ast_hangup(chan);
813                 }
814         } else {
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;
818         }
819         
820         lantiq_reset_dtmfbuf(pvt);
821 }
822
823 static int lantiq_event_dial_timeout(const void* data)
824 {
825         ast_debug(1, "TAPI: lantiq_event_dial_timeout()\n");
826
827         struct lantiq_pvt *pvt = (struct lantiq_pvt *) data;
828         pvt->dial_timer = 0;
829
830         if (! pvt->channel_state == ONHOOK) {
831                 lantiq_dial(pvt);
832         } else {
833                 ast_debug(1, "TAPI: lantiq_event_dial_timeout(): dial timeout in state ONHOOK.\n");
834         }
835
836         return 0;
837 }
838
839 static int lantiq_send_digit(int c, char digit) 
840 {
841         struct lantiq_pvt *pvt = &iflist[c];
842
843         struct ast_frame f = { .frametype = AST_FRAME_DTMF, .subclass.integer = digit };
844
845         if (pvt->owner) {
846                 ast_log(LOG_DEBUG, "Port %i transmitting digit \"%c\"\n", c, digit);
847                 return ast_queue_frame(pvt->owner, &f);
848         } else {
849                 ast_debug(1, "Warning: lantiq_send_digit() without owner!\n");
850                 return -1;
851         }
852 }
853
854 static void lantiq_dev_event_digit(int c, char digit)
855 {
856         ast_mutex_lock(&iflock);
857
858         ast_log(LOG_DEBUG, "on port %i detected digit \"%c\"\n", c, digit);
859
860         struct lantiq_pvt *pvt = &iflist[c];
861
862         switch (pvt->channel_state) {
863                 case INCALL:
864                         {
865                                 lantiq_send_digit(c, digit);
866                                 break;
867                         }
868                 case OFFHOOK:  
869                         pvt->channel_state = DIALING;
870
871                         lantiq_play_tone(c, TAPI_TONE_LOCALE_NONE);
872
873                         /* fall through */
874                 case DIALING: 
875                         if (digit == '#') {
876                                 if (pvt->dial_timer) {
877                                         ast_sched_thread_del(sched_thread, pvt->dial_timer);
878                                         pvt->dial_timer = 0;
879                                 }
880
881                                 lantiq_dial(pvt);
882                         } else {
883                                 pvt->dtmfbuf[pvt->dtmfbuf_len] = digit;
884                                 pvt->dtmfbuf_len++;
885                                 pvt->dtmfbuf[pvt->dtmfbuf_len] = '\0';
886
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);
891                                 } else {
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);
895                                 }
896                         }
897                         break;
898                 default:
899                         ast_log(LOG_ERROR, "don't know what to do in unhandled state\n");
900                         break;
901         }
902
903         ast_mutex_unlock(&iflock);
904         return;
905 }
906
907 static void lantiq_dev_event_handler(void)
908 {
909         IFX_TAPI_EVENT_t event;
910         unsigned int i;
911
912         for (i = 0; i < dev_ctx.channels ; i++) {
913                 ast_mutex_lock(&iflock);
914
915                 memset (&event, 0, sizeof(event));
916                 event.ch = i;
917                 if (ioctl(dev_ctx.dev_fd, IFX_TAPI_EVENT_GET, &event)) {
918                         ast_mutex_unlock(&iflock);
919                         continue;
920                 }
921                 if (event.id == IFX_TAPI_EVENT_NONE) {
922                         ast_mutex_unlock(&iflock);
923                         continue;
924                 }
925
926                 ast_mutex_unlock(&iflock);
927
928                 switch(event.id) {
929                         case IFX_TAPI_EVENT_FXS_ONHOOK:
930                                 lantiq_dev_event_hook(i, 1);
931                                 break;
932                         case IFX_TAPI_EVENT_FXS_OFFHOOK:
933                                 lantiq_dev_event_hook(i, 0);
934                                 break;
935                         case IFX_TAPI_EVENT_DTMF_DIGIT:
936                                 lantiq_dev_event_digit(i, (char)event.data.dtmf.ascii);
937                                 break;
938                         case IFX_TAPI_EVENT_PULSE_DIGIT:
939                                 if (event.data.pulse.digit == 0xB) {
940                                         lantiq_dev_event_digit(i, '0');
941                                 } else {
942                                         lantiq_dev_event_digit(i, '0' + (char)event.data.pulse.digit);
943                                 }
944                                 break;
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:
948                                 break;
949                         default:
950                                 ast_log(LOG_ERROR, "unknown TAPI event %08X\n", event.id);
951                                 break;
952                 }
953         }
954 }
955
956 static void * lantiq_events_monitor(void *data)
957 {
958         ast_verbose("TAPI thread started\n");
959
960         struct pollfd fds[3];
961
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;
968
969         while (monitor) {
970                 ast_mutex_lock(&monlock);
971
972                 if (poll(fds, dev_ctx.channels + 1, 2000) <= 0) {
973                         ast_mutex_unlock(&monlock);
974                         continue;
975                 }
976
977                 if (fds[0].revents & POLLIN) {
978                         lantiq_dev_event_handler();
979                 }
980
981                 ast_mutex_unlock(&monlock);
982
983                 if ((fds[1].revents & POLLIN) && (lantiq_dev_data_handler(0))) {
984                         ast_log(LOG_ERROR, "data handler 0 failed\n");
985                         break;
986                 }
987
988                 if ((fds[2].revents & POLLIN) && (lantiq_dev_data_handler(1))) {
989                         ast_log(LOG_ERROR, "data handler 1 failed\n");
990                         break;
991                 }
992         }
993
994         return NULL;
995 }
996
997 static int restart_monitor(void)
998 {
999         /* If we're supposed to be stopped -- stay stopped */
1000         if (monitor_thread == AST_PTHREADT_STOP)
1001                 return 0;
1002
1003         ast_mutex_lock(&monlock);
1004
1005         if (monitor_thread == pthread_self()) {
1006                 ast_mutex_unlock(&monlock);
1007                 ast_log(LOG_WARNING, "Cannot kill myself\n");
1008                 return -1;
1009         }
1010
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");
1015                         return -1;
1016                 }
1017                 monitor = 0;
1018                 while (pthread_kill(monitor_thread, SIGURG) == 0)
1019                         sched_yield();
1020                 pthread_join(monitor_thread, NULL);
1021                 ast_mutex_unlock(&iflock);
1022         }
1023
1024         monitor = 1;
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");
1029                 return -1;
1030         }
1031
1032         ast_mutex_unlock(&monlock);
1033
1034         return 0;
1035 }
1036
1037 static void lantiq_cleanup(void)
1038 {
1039         int c;
1040
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");
1044                 }
1045
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");
1048                 }
1049
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");
1052                 }
1053         }
1054
1055         if (ioctl(dev_ctx.dev_fd, IFX_TAPI_DEV_STOP, 0)) {
1056                 ast_log(LOG_WARNING, "IFX_TAPI_DEV_STOP ioctl failed\n");
1057         }
1058
1059         close(dev_ctx.dev_fd);
1060 }
1061
1062 static int unload_module(void)
1063 {
1064         int c;
1065
1066         ast_channel_unregister(&lantiq_tech);
1067
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);
1072                 }
1073                 ast_mutex_unlock(&iflock);
1074         } else {
1075                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
1076                 return -1;
1077         }
1078
1079         if (!ast_mutex_lock(&monlock)) {
1080                 if (monitor_thread > AST_PTHREADT_NULL) {
1081                         monitor = 0;
1082                         while (pthread_kill(monitor_thread, SIGURG) == 0)
1083                                 sched_yield();
1084                         pthread_join(monitor_thread, NULL);
1085                 }
1086                 monitor_thread = AST_PTHREADT_STOP;
1087                 ast_mutex_unlock(&monlock);
1088         } else {
1089                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
1090                 return -1;
1091         }
1092
1093         return 0;
1094 }
1095
1096 static struct lantiq_pvt *lantiq_init_pvt(struct lantiq_pvt *pvt)
1097 {
1098         if (pvt) {
1099                 pvt->owner = NULL;
1100                 pvt->port_id = -1;
1101                 pvt->channel_state = UNKNOWN;
1102                 pvt->context[0] = '\0';
1103                 pvt->ext[0] = '\0';
1104                 pvt->dial_timer = 0;
1105                 pvt->dtmfbuf[0] = '\0';
1106                 pvt->dtmfbuf_len = 0;
1107         } else {
1108                 ast_log(LOG_ERROR, "unable to clear pvt structure\n");
1109         }
1110
1111         return pvt;
1112 }
1113
1114 static int lantiq_create_pvts(void)
1115 {
1116         int i;
1117
1118         iflist = ast_calloc(1, sizeof(struct lantiq_pvt) * dev_ctx.channels);
1119
1120         if (iflist) { 
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);
1127                         } else {
1128                                 snprintf(iflist[i].context, AST_MAX_CONTEXT, "default");
1129                         }
1130                 }
1131                 return 0;
1132         } else {
1133                 ast_log(LOG_ERROR, "unable to allocate memory\n");
1134                 return -1;
1135         }
1136 }
1137
1138 static int lantiq_setup_rtp(int c)
1139 {
1140         /* Configure RTP payload type tables */
1141         IFX_TAPI_PKT_RTP_PT_CFG_t rtpPTConf;
1142
1143         memset((char*)&rtpPTConf, '\0', sizeof(rtpPTConf));
1144
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;
1151
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;
1158
1159         int ret;
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);
1162                 return -1;
1163         }
1164
1165         return 0;
1166 }
1167
1168 static int load_module(void)
1169 {
1170         struct ast_config *cfg;
1171         struct ast_variable *v;
1172         int txgain = 0;
1173         int rxgain = 0;
1174         int wlec_type = 0;
1175         int wlec_nlp = 0;
1176         int wlec_nbfe = 0;
1177         int wlec_nbne = 0;
1178         int wlec_wbne = 0;
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 };
1190         
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;
1194         }
1195
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;
1199         }
1200
1201         /* We *must* have a config file otherwise stop immediately */
1202         if (!cfg) {
1203                 ast_log(LOG_ERROR, "Unable to load config %s\n", config);
1204                 return AST_MODULE_LOAD_DECLINE;
1205         }
1206
1207         if (ast_mutex_lock(&iflock)) {
1208                 ast_log(LOG_ERROR, "Unable to lock interface list.\n");
1209                 return AST_MODULE_LOAD_FAILURE;
1210         }
1211
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;
1219                         }
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;
1231                         } else {
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;
1235                         }
1236                 }
1237         }
1238
1239         for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
1240                 if (!strcasecmp(v->name, "rxgain")) {
1241                         rxgain = atoi(v->value);
1242                         if (!rxgain) {
1243                                 rxgain = 0;
1244                                 ast_log(LOG_WARNING, "Invalid rxgain: %s, using default.\n", v->value);
1245                         }
1246                 } else if (!strcasecmp(v->name, "txgain")) {
1247                         txgain = atoi(v->value);
1248                         if (!txgain) {
1249                                 txgain = 0;
1250                                 ast_log(LOG_WARNING, "Invalid txgain: %s, using default.\n", v->value);
1251                         }
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);
1259                                 }
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);
1268                                 }
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;
1275                         } else {
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;
1280                         }
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;
1286                         } else {
1287                                 ast_log(LOG_ERROR, "Unknown echo cancellation nlp '%s'\n", v->value);
1288                                 ast_config_destroy(cfg);
1289                                 return AST_MODULE_LOAD_DECLINE;
1290                         }
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;
1302                                         }
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);
1311                                 }
1312                         } else {
1313                                 ast_log(LOG_ERROR, "Unknown jitter buffer type '%s'\n", v->value);
1314                                 ast_config_destroy(cfg);
1315                                 return AST_MODULE_LOAD_DECLINE;
1316                         }
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;
1324                         } else {
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;
1328                         }
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;
1344                         } else {
1345                                 ast_log(LOG_ERROR, "Unknown caller id type '%s'\n", v->value);
1346                                 ast_config_destroy(cfg);
1347                                 return AST_MODULE_LOAD_DECLINE;
1348                         }
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;
1358                         } else {
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;
1362                         }
1363                 }
1364         }
1365
1366         lantiq_create_pvts();
1367
1368         ast_mutex_unlock(&iflock);
1369
1370         if (ast_channel_register(&lantiq_tech)) {
1371                 ast_log(LOG_ERROR, "Unable to register channel class 'Phone'\n");
1372                 ast_config_destroy(cfg);
1373                 unload_module();
1374                 return AST_MODULE_LOAD_FAILURE;
1375         }
1376         ast_config_destroy(cfg);
1377         
1378         /* tapi */
1379 #ifdef TODO_TONES
1380         IFX_TAPI_TONE_t tone;
1381 #endif
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;
1389         uint8_t c;
1390
1391         /* open device */
1392         dev_ctx.dev_fd = lantiq_dev_open(base_path, 0);
1393
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;
1397         }
1398
1399         for (c = 0; c < dev_ctx.channels ; c++) {
1400                 dev_ctx.ch_fd[c] = lantiq_dev_open(base_path, c + 1);
1401
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;
1405                 }
1406         }
1407
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;
1411         }
1412
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;
1416         }
1417
1418         memset(&dev_start, 0x0, sizeof(IFX_TAPI_DEV_START_CFG_t));
1419         dev_start.nMode = IFX_TAPI_INIT_MODE_VOICE_CODER;
1420
1421         /* Start TAPI */
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;
1425         }
1426
1427         for (c = 0; c < dev_ctx.channels ; c++) {
1428                 /* tones */
1429 #ifdef TODO_TONES
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;
1434                 }
1435 #endif
1436                 /* ringing type */
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;
1444                 }
1445
1446                 /* ring cadence */
1447                 IFX_char_t data[15] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1448                                                                 0x00, 0x00, 0x00, 0x00, 0x00,     
1449                                                                 0x00, 0x00, 0x00, 0x00, 0x00 };
1450
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;
1455
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;
1459                 }
1460
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;
1465
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;
1469                 }
1470
1471                 /* set line feed */
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;
1475                 }
1476
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;
1481
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;
1485                 }
1486
1487                 /* set volume */
1488                 memset(&line_vol, 0, sizeof(line_vol));
1489                 line_vol.nGainRx = rxgain;
1490                 line_vol.nGainTx = txgain;
1491
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;
1495                 }
1496
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;
1504
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;
1508                 }
1509
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;
1519
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;
1523                 }
1524
1525                 /* Configure Caller ID type */
1526                 memset(&cid_cfg, 0, sizeof(cid_cfg));
1527                 cid_cfg.nStandard = cid_type;
1528
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;
1532                 }
1533
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;
1538                 }
1539
1540                 /* Setup TAPI <-> Asterisk codec type mapping */
1541                 if (lantiq_setup_rtp(c)) {
1542                         return AST_MODULE_LOAD_FAILURE;
1543                 }
1544
1545                 /* Set initial hook status */
1546                 iflist[c].channel_state = lantiq_get_hookstatus(c);
1547                 
1548                 if (iflist[c].channel_state == UNKNOWN) {
1549                         return AST_MODULE_LOAD_FAILURE;
1550                 }
1551         }
1552
1553         /* make sure our device will be closed properly */
1554         ast_register_atexit(lantiq_cleanup);
1555
1556         restart_monitor();
1557         return AST_MODULE_LOAD_SUCCESS;
1558 }
1559
1560 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Lantiq TAPI Telephony API Support");