2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 2012, Luka Perkov
5 * Copyright (C) 2012, John Crispin
6 * Copyright (C) 2012, Andrej Vlašić
7 * Copyright (C) 2012, Kaspar Schleiser for T-Labs
8 * (Deutsche Telekom Innovation Laboratories)
9 * Copyright (C) 2012, Mirko Vogt for T-Labs
10 * (Deutsche Telekom Innovation Laboratories)
12 * Luka Perkov <openwrt@lukaperkov.net>
13 * John Crispin <blogic@openwrt.org>
14 * Andrej Vlašić <andrej.vlasic0@gmail.com>
15 * Kaspar Schleiser <kaspar@schleiser.de>
16 * Mirko Vogt <mirko@openwrt.org>
18 * See http://www.asterisk.org for more information about
19 * the Asterisk project. Please do not directly contact
20 * any of the maintainers of this project for assistance;
21 * the project provides a web site, mailing lists and IRC
22 * channels for your use.
24 * This program is free software, distributed under the terms of
25 * the GNU General Public License Version 2. See the LICENSE file
26 * at the top of the source tree.
31 * \brief Asterisk channel line driver for Lantiq based TAPI boards
33 * \author Luka Perkov <openwrt@lukaperkov.net>
34 * \author John Crispin <blogic@openwrt.org>
35 * \author Andrej Vlašić <andrej.vlasic0@gmail.com>
36 * \author Kaspar Schleiser <kaspar@schleiser.de>
37 * \author Mirko Vogt <mirko@openwrt.org>
39 * \ingroup channel_drivers
44 ASTERISK_FILE_VERSION(__FILE__
, "$Revision: xxx $")
47 #include <sys/socket.h>
49 #include <arpa/inet.h>
51 #include <sys/ioctl.h>
54 #ifdef HAVE_LINUX_COMPILER_H
55 #include <linux/compiler.h>
57 #include <linux/telephony.h>
59 #include <asterisk/lock.h>
60 #include <asterisk/channel.h>
61 #include <asterisk/config.h>
62 #include <asterisk/module.h>
63 #include <asterisk/pbx.h>
64 #include <asterisk/utils.h>
65 #include <asterisk/callerid.h>
66 #include <asterisk/causes.h>
67 #include <asterisk/stringfields.h>
68 #include <asterisk/musiconhold.h>
69 #include <asterisk/sched.h>
71 /* Lantiq TAPI includes */
72 #include <drv_tapi/drv_tapi_io.h>
73 #include <drv_vmmc/vmmc_io.h>
75 #define RTP_HEADER_LEN 12
77 #define TAPI_AUDIO_PORT_NUM_MAX 2
78 #define TAPI_TONE_LOCALE_NONE 0
79 #define TAPI_TONE_LOCALE_RINGING_CODE 26
80 #define TAPI_TONE_LOCALE_BUSY_CODE 27
81 #define TAPI_TONE_LOCALE_CONGESTION_CODE 27
82 #define TAPI_TONE_LOCALE_DIAL_CODE 25
83 #define TAPI_TONE_LOCALE_WAITING_CODE 37
85 #define LANTIQ_CONTEXT_PREFIX "lantiq"
87 static const char config
[] = "lantiq.conf";
89 static char firmware_filename
[PATH_MAX
] = "/lib/firmware/ifx_firmware.bin";
90 static char bbd_filename
[PATH_MAX
] = "/lib/firmware/ifx_bbd_fxs.bin";
91 static char base_path
[PATH_MAX
] = "/dev/vmmc";
92 static int per_channel_context
= 0;
95 * The private structures of the Phone Jack channels are linked for selecting
108 static struct lantiq_pvt
{
109 struct ast_channel
*owner
; /* Channel we belong to, possibly NULL */
110 int port_id
; /* Port number of this object, 0..n */
112 char context
[AST_MAX_CONTEXT
]; /* this port's dialplan context */
113 char ext
[AST_MAX_EXTENSION
+1]; /* the extension this port is connecting */
114 int dial_timer
; /* timer handle for autodial timeout */
115 char dtmfbuf
[AST_MAX_EXTENSION
+1]; /* buffer holding dialed digits */
116 int dtmfbuf_len
; /* lenght of dtmfbuf */
117 int rtp_timestamp
; /* timestamp for RTP packets */
118 uint16_t rtp_seqno
; /* Sequence nr for RTP packets */
119 uint32_t call_setup_start
; /* Start of dialling in ms */
120 uint32_t call_setup_delay
; /* time between ^ and 1st ring in ms */
121 uint16_t jb_size
; /* Jitter buffer size */
122 uint32_t jb_underflow
; /* Jitter buffer injected samples */
123 uint32_t jb_overflow
; /* Jitter buffer dropped samples */
124 uint16_t jb_delay
; /* Jitter buffer: playout delay */
125 uint16_t jb_invalid
; /* Jitter buffer: Nr. of invalid packets */
129 static struct lantiq_ctx
{
132 int ch_fd
[TAPI_AUDIO_PORT_NUM_MAX
];
135 static int ast_digit_begin(struct ast_channel
*ast
, char digit
);
136 static int ast_digit_end(struct ast_channel
*ast
, char digit
, unsigned int duration
);
137 static int ast_lantiq_call(struct ast_channel
*ast
, char *dest
, int timeout
);
138 static int ast_lantiq_hangup(struct ast_channel
*ast
);
139 static int ast_lantiq_answer(struct ast_channel
*ast
);
140 static struct ast_frame
*ast_lantiq_read(struct ast_channel
*ast
);
141 static int ast_lantiq_write(struct ast_channel
*ast
, struct ast_frame
*frame
);
142 static struct ast_frame
*ast_lantiq_exception(struct ast_channel
*ast
);
143 static int ast_lantiq_indicate(struct ast_channel
*chan
, int condition
, const void *data
, size_t datalen
);
144 static int ast_lantiq_fixup(struct ast_channel
*old
, struct ast_channel
*new);
145 static struct ast_channel
*ast_lantiq_requester(const char *type
, format_t format
, const struct ast_channel
*requestor
, void *data
, int *cause
);
146 static int acf_channel_read(struct ast_channel
*chan
, const char *funcname
, char *args
, char *buf
, size_t buflen
);
147 static void lantiq_jb_get_stats(int c
);
149 static const struct ast_channel_tech lantiq_tech
= {
151 .description
= "Lantiq TAPI Telephony API Driver",
152 .capabilities
= AST_FORMAT_G723_1
| AST_FORMAT_SLINEAR
| AST_FORMAT_ULAW
| AST_FORMAT_G729A
,
153 .send_digit_begin
= ast_digit_begin
,
154 .send_digit_end
= ast_digit_end
,
155 .call
= ast_lantiq_call
,
156 .hangup
= ast_lantiq_hangup
,
157 .answer
= ast_lantiq_answer
,
158 .read
= ast_lantiq_read
,
159 .write
= ast_lantiq_write
,
160 .exception
= ast_lantiq_exception
,
161 .indicate
= ast_lantiq_indicate
,
162 .fixup
= ast_lantiq_fixup
,
163 .requester
= ast_lantiq_requester
,
164 .func_channel_read
= acf_channel_read
167 /* Protect the interface list (of lantiq_pvt's) */
168 AST_MUTEX_DEFINE_STATIC(iflock
);
171 * Protect the monitoring thread, so only one process can kill or start it, and
172 * not when it's doing something critical.
174 AST_MUTEX_DEFINE_STATIC(monlock
);
176 /* Boolean value whether the monitoring thread shall continue. */
177 static unsigned int monitor
;
179 /* The scheduling thread */
180 struct ast_sched_thread
*sched_thread
;
183 * This is the thread for the monitor which checks for input on the channels
184 * which are not currently in use.
186 static pthread_t monitor_thread
= AST_PTHREADT_NULL
;
189 #define WORDS_BIGENDIAN
190 /* struct taken from some GPLed code by Mike Borella */
191 typedef struct rtp_header
193 #if defined(WORDS_BIGENDIAN)
194 uint8_t version
:2, padding
:1, extension
:1, csrc_count
:4;
196 uint8_t csrc_count
:4, extension
:1, padding
:1, version
:2;
198 #if defined(WORDS_BIGENDIAN)
199 uint8_t marker
:1, payload_type
:7;
201 uint8_t payload_type
:7, marker
:1;
208 static uint32_t now(void) {
210 clock_gettime(CLOCK_MONOTONIC
, &ts
);
212 uint64_t tmp
= ts
.tv_sec
*1000 + (ts
.tv_nsec
/1000000);
213 return (uint32_t) tmp
;
216 static int lantiq_dev_open(const char *dev_path
, const int32_t ch_num
)
218 char dev_name
[PATH_MAX
];
219 memset(dev_name
, 0, sizeof(dev_name
));
220 snprintf(dev_name
, PATH_MAX
, "%s%u%u", dev_path
, 1, ch_num
);
221 return open((const char*)dev_name
, O_RDWR
, 0644);
224 static void lantiq_ring(int c
, int r
, const char *cid
)
230 status
= (uint8_t) ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_RING_START
, 0);
232 IFX_TAPI_CID_MSG_t msg
;
233 IFX_TAPI_CID_MSG_STRING_t cid_el
;
235 memset(&msg
, 0, sizeof(msg
));
236 memset(&cid_el
, 0, sizeof(cid_el
));
238 cid_el
.elementType
= IFX_TAPI_CID_ST_CLI
;
239 cid_el
.len
= strlen(cid
);
240 strncpy((char*)cid_el
.element
, cid
, (size_t)cid_el
.len
);
242 msg
.txMode
= IFX_TAPI_CID_HM_ONHOOK
;
243 msg
.messageType
= IFX_TAPI_CID_MT_CSUP
;
244 msg
.message
= (IFX_TAPI_CID_MSG_ELEMENT_t
*)&cid_el
;
245 msg
.nMsgElements
= 1;
247 status
= (uint8_t) ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_CID_TX_SEQ_START
, (IFX_int32_t
) &msg
);
250 status
= (uint8_t) ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_RING_STOP
, 0);
254 ast_log(LOG_ERROR
, "%s ioctl failed\n",
255 (r
? "IFX_TAPI_RING_START" : "IFX_TAPI_RING_STOP"));
259 static int lantiq_play_tone(int c
, int t
)
261 /* stop currently playing tone before starting new one */
262 if (t
!= TAPI_TONE_LOCALE_NONE
) {
263 ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_TONE_LOCAL_PLAY
, TAPI_TONE_LOCALE_NONE
);
266 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_TONE_LOCAL_PLAY
, t
)) {
267 ast_log(LOG_ERROR
, "IFX_TAPI_TONE_LOCAL_PLAY ioctl failed\n");
274 static enum channel_state
lantiq_get_hookstatus(int port
)
278 if (ioctl(dev_ctx
.ch_fd
[port
], IFX_TAPI_LINE_HOOK_STATUS_GET
, &status
)) {
279 ast_log(LOG_ERROR
, "IFX_TAPI_LINE_HOOK_STATUS_GET ioctl failed\n");
291 lantiq_dev_binary_buffer_create(const char *path
, uint8_t **ppBuf
, uint32_t *pBufSz
)
294 struct stat file_stat
;
297 fd
= fopen(path
, "rb");
299 ast_log(LOG_ERROR
, "binary file %s open failed\n", path
);
303 if (stat(path
, &file_stat
)) {
304 ast_log(LOG_ERROR
, "file %s statistics get failed\n", path
);
308 *ppBuf
= malloc(file_stat
.st_size
);
309 if (*ppBuf
== NULL
) {
310 ast_log(LOG_ERROR
, "binary file %s memory allocation failed\n", path
);
315 if (fread (*ppBuf
, sizeof(uint8_t), file_stat
.st_size
, fd
) <= 0) {
316 ast_log(LOG_ERROR
, "file %s read failed\n", path
);
321 *pBufSz
= file_stat
.st_size
;
327 if (*ppBuf
!= NULL
&& status
)
333 static int32_t lantiq_dev_firmware_download(int32_t fd
, const char *path
)
335 uint8_t *firmware
= NULL
;
337 VMMC_IO_INIT vmmc_io_init
;
339 ast_log(LOG_DEBUG
, "loading firmware: \"%s\".", path
);
341 if (lantiq_dev_binary_buffer_create(path
, &firmware
, &size
))
344 memset(&vmmc_io_init
, 0, sizeof(VMMC_IO_INIT
));
345 vmmc_io_init
.pPRAMfw
= firmware
;
346 vmmc_io_init
.pram_size
= size
;
348 if (ioctl(fd
, FIO_FW_DOWNLOAD
, &vmmc_io_init
)) {
349 ast_log(LOG_ERROR
, "FIO_FW_DOWNLOAD ioctl failed\n");
353 if (firmware
!= NULL
)
359 static const char *state_string(enum channel_state s
)
362 case ONHOOK
: return "ONHOOK";
363 case OFFHOOK
: return "OFFHOOK";
364 case DIALING
: return "DIALING";
365 case INCALL
: return "INCALL";
366 case CALL_ENDED
: return "CALL_ENDED";
367 case RINGING
: return "RINGING";
368 default: return "UNKNOWN";
372 static const char *control_string(int c
)
375 case AST_CONTROL_HANGUP
: return "Other end has hungup";
376 case AST_CONTROL_RING
: return "Local ring";
377 case AST_CONTROL_RINGING
: return "Remote end is ringing";
378 case AST_CONTROL_ANSWER
: return "Remote end has answered";
379 case AST_CONTROL_BUSY
: return "Remote end is busy";
380 case AST_CONTROL_TAKEOFFHOOK
: return "Make it go off hook";
381 case AST_CONTROL_OFFHOOK
: return "Line is off hook";
382 case AST_CONTROL_CONGESTION
: return "Congestion (circuits busy)";
383 case AST_CONTROL_FLASH
: return "Flash hook";
384 case AST_CONTROL_WINK
: return "Wink";
385 case AST_CONTROL_OPTION
: return "Set a low-level option";
386 case AST_CONTROL_RADIO_KEY
: return "Key Radio";
387 case AST_CONTROL_RADIO_UNKEY
: return "Un-Key Radio";
388 case AST_CONTROL_PROGRESS
: return "Remote end is making Progress";
389 case AST_CONTROL_PROCEEDING
: return "Remote end is proceeding";
390 case AST_CONTROL_HOLD
: return "Hold";
391 case AST_CONTROL_UNHOLD
: return "Unhold";
392 case AST_CONTROL_SRCUPDATE
: return "Media Source Update";
393 case AST_CONTROL_CONNECTED_LINE
: return "Connected Line";
394 case AST_CONTROL_REDIRECTING
: return "Redirecting";
395 case AST_CONTROL_INCOMPLETE
: return "Incomplete";
396 case -1: return "Stop tone";
397 default: return "Unknown";
401 static int ast_lantiq_indicate(struct ast_channel
*chan
, int condition
, const void *data
, size_t datalen
)
403 ast_verb(3, "phone indication \"%s\"\n", control_string(condition
));
405 struct lantiq_pvt
*pvt
= chan
->tech_pvt
;
410 lantiq_play_tone(pvt
->port_id
, TAPI_TONE_LOCALE_NONE
);
413 case AST_CONTROL_CONGESTION
:
414 case AST_CONTROL_BUSY
:
416 lantiq_play_tone(pvt
->port_id
, TAPI_TONE_LOCALE_BUSY_CODE
);
419 case AST_CONTROL_RINGING
:
421 pvt
->call_setup_delay
= now() - pvt
->call_setup_start
;
422 lantiq_play_tone(pvt
->port_id
, TAPI_TONE_LOCALE_RINGING_CODE
);
427 /* -1 lets asterisk generate the tone */
433 static int ast_lantiq_fixup(struct ast_channel
*old
, struct ast_channel
*new)
435 ast_log(LOG_DEBUG
, "entering... no code here...\n");
439 static int ast_digit_begin(struct ast_channel
*chan
, char digit
)
441 /* TODO: Modify this callback to let Asterisk support controlling the length of DTMF */
442 ast_log(LOG_DEBUG
, "entering... no code here...\n");
446 static int ast_digit_end(struct ast_channel
*ast
, char digit
, unsigned int duration
)
448 ast_log(LOG_DEBUG
, "entering... no code here...\n");
452 static int ast_lantiq_call(struct ast_channel
*ast
, char *dest
, int timeout
)
454 /* lock to prevent simultaneous access with do_monitor thread processing */
455 ast_mutex_lock(&iflock
);
457 struct lantiq_pvt
*pvt
= ast
->tech_pvt
;
458 ast_log(LOG_DEBUG
, "state: %s\n", state_string(pvt
->channel_state
));
460 if (pvt
->channel_state
== ONHOOK
) {
461 ast_log(LOG_DEBUG
, "port %i is ringing\n", pvt
->port_id
);
463 char *cid
= ast
->connected
.id
.number
.valid
? ast
->connected
.id
.number
.str
: NULL
;
464 ast_log(LOG_DEBUG
, "port %i CID: %s\n", pvt
->port_id
, cid
? cid
: "none");
466 lantiq_ring(pvt
->port_id
, 1, cid
);
467 pvt
->channel_state
= RINGING
;
469 ast_setstate(ast
, AST_STATE_RINGING
);
470 ast_queue_control(ast
, AST_CONTROL_RINGING
);
472 ast_log(LOG_DEBUG
, "port %i is busy\n", pvt
->port_id
);
473 ast_setstate(ast
, AST_STATE_BUSY
);
474 ast_queue_control(ast
, AST_CONTROL_BUSY
);
477 ast_mutex_unlock(&iflock
);
482 static int ast_lantiq_hangup(struct ast_channel
*ast
)
484 /* lock to prevent simultaneous access with do_monitor thread processing */
485 ast_mutex_lock(&iflock
);
487 struct lantiq_pvt
*pvt
= ast
->tech_pvt
;
488 ast_log(LOG_DEBUG
, "state: %s\n", state_string(pvt
->channel_state
));
490 if (ast
->_state
== AST_STATE_RINGING
) {
492 ast_debug(1, "TAPI: ast_lantiq_hangup(): ast->_state == AST_STATE_RINGING\n");
495 switch (pvt
->channel_state
) {
498 lantiq_ring(pvt
->port_id
, 0, NULL
);
499 pvt
->channel_state
= ONHOOK
;
502 ast_log(LOG_DEBUG
, "we were hung up, play busy tone\n");
503 pvt
->channel_state
= CALL_ENDED
;
504 lantiq_play_tone(pvt
->port_id
, TAPI_TONE_LOCALE_BUSY_CODE
);
507 lantiq_jb_get_stats(pvt
->port_id
);
509 ast_setstate(ast
, AST_STATE_DOWN
);
510 ast_module_unref(ast_module_info
->self
);
511 ast
->tech_pvt
= NULL
;
514 ast_mutex_unlock(&iflock
);
519 static int ast_lantiq_answer(struct ast_channel
*ast
)
521 ast_log(LOG_DEBUG
, "entering... no code here...\n");
525 static struct ast_frame
* ast_lantiq_read(struct ast_channel
*ast
)
527 ast_log(LOG_DEBUG
, "entering... no code here...\n");
531 static int ast_lantiq_write(struct ast_channel
*ast
, struct ast_frame
*frame
)
534 struct lantiq_pvt
*pvt
= ast
->tech_pvt
;
536 rtp_header_t
*rtp_header
= (rtp_header_t
*) buf
;
538 if(frame
->frametype
!= AST_FRAME_VOICE
) {
539 ast_log(LOG_DEBUG
, "unhandled frame type\n");
543 if (frame
->datalen
== 0) {
544 ast_log(LOG_DEBUG
, "we've been prodded\n");
548 memset(buf
, 0, sizeof(rtp_header_t
));
549 rtp_header
->version
= 2;
550 rtp_header
->padding
= 0;
551 rtp_header
->extension
= 0;
552 rtp_header
->csrc_count
= 0;
553 rtp_header
->marker
= 0;
554 rtp_header
->timestamp
= pvt
->rtp_timestamp
;
555 rtp_header
->seqno
= pvt
->rtp_seqno
++;
556 rtp_header
->ssrc
= 0;
557 rtp_header
->payload_type
= (uint8_t) frame
->subclass
.codec
;
559 pvt
->rtp_timestamp
+= 160;
561 memcpy(buf
+RTP_HEADER_LEN
, frame
->data
.ptr
, frame
->datalen
);
563 ret
= write(dev_ctx
.ch_fd
[pvt
->port_id
], buf
, frame
->datalen
+RTP_HEADER_LEN
);
565 ast_debug(1, "TAPI: ast_lantiq_write(): error writing.\n");
569 #ifdef TODO_DEVEL_INFO
570 ast_debug(1, "ast_lantiq_write(): size: %i version: %i padding: %i extension: %i csrc_count: %i\n"
571 "marker: %i payload_type: %s seqno: %i timestamp: %i ssrc: %i\n",
573 (int)rtp_header
->version
,
574 (int)rtp_header
->padding
,
575 (int)rtp_header
->extension
,
576 (int)rtp_header
->csrc_count
,
577 (int)rtp_header
->marker
,
578 ast_codec2str(rtp_header
->payload_type
),
579 (int)rtp_header
->seqno
,
580 (int)rtp_header
->timestamp
,
581 (int)rtp_header
->ssrc
);
587 static int acf_channel_read(struct ast_channel
*chan
, const char *funcname
, char *args
, char *buf
, size_t buflen
)
589 struct lantiq_pvt
*pvt
;
592 if (!chan
|| chan
->tech
!= &lantiq_tech
) {
593 ast_log(LOG_ERROR
, "This function requires a valid Lantiq TAPI channel\n");
597 ast_mutex_lock(&iflock
);
599 pvt
= (struct lantiq_pvt
*) chan
->tech_pvt
;
601 if (!strcasecmp(args
, "csd")) {
602 snprintf(buf
, buflen
, "%lu", (unsigned long int) pvt
->call_setup_delay
);
603 } else if (!strcasecmp(args
, "jitter_stats")){
604 lantiq_jb_get_stats(pvt
->port_id
);
605 snprintf(buf
, buflen
, "jbBufSize=%u,jbUnderflow=%u,jbOverflow=%u,jbDelay=%u,jbInvalid=%u",
606 (uint32_t) pvt
->jb_size
,
607 (uint32_t) pvt
->jb_underflow
,
608 (uint32_t) pvt
->jb_overflow
,
609 (uint32_t) pvt
->jb_delay
,
610 (uint32_t) pvt
->jb_invalid
);
615 ast_mutex_unlock(&iflock
);
621 static struct ast_frame
* ast_lantiq_exception(struct ast_channel
*ast
)
623 ast_log(LOG_DEBUG
, "entering... no code here...\n");
627 static void lantiq_jb_get_stats(int c
) {
628 struct lantiq_pvt
*pvt
= &iflist
[c
];
630 IFX_TAPI_JB_STATISTICS_t param
;
631 memset (¶m
, 0, sizeof (param
));
632 if (ioctl (dev_ctx
.ch_fd
[c
], IFX_TAPI_JB_STATISTICS_GET
, (IFX_int32_t
) ¶m
) != IFX_SUCCESS
) {
633 ast_debug(1, "Error getting jitter buffer stats.\n");
635 #if !defined (TAPI_VERSION3) && defined (TAPI_VERSION4)
636 ast_debug(1, "Jitter buffer stats: dev=%u, ch=%u, nType=%u, nBufSize=%u, nIsUnderflow=%u, nDsOverflow=%u, nPODelay=%u, nInvalid=%u",
637 (uint32_t) param
.dev
,
640 ast_debug(1, "Jitter buffer stats: nType=%u, nBufSize=%u, nIsUnderflow=%u, nDsOverflow=%u, nPODelay=%u, nInvalid=%u",
642 (uint32_t) param
.nType
,
643 (uint32_t) param
.nBufSize
,
644 (uint32_t) param
.nIsUnderflow
,
645 (uint32_t) param
.nDsOverflow
,
646 (uint32_t) param
.nPODelay
,
647 (uint32_t) param
.nInvalid
);
649 pvt
->jb_size
= param
.nBufSize
;
650 pvt
->jb_underflow
= param
.nIsUnderflow
;
651 pvt
->jb_overflow
= param
.nDsOverflow
;
652 pvt
->jb_invalid
= param
.nInvalid
;
653 pvt
->jb_delay
= param
.nPODelay
;
658 static int lantiq_standby(int c
)
660 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_LINE_FEED_SET
, IFX_TAPI_LINE_FEED_STANDBY
)) {
661 ast_log(LOG_ERROR
, "IFX_TAPI_LINE_FEED_SET ioctl failed\n");
665 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_ENC_STOP
, 0)) {
666 ast_log(LOG_ERROR
, "IFX_TAPI_ENC_STOP ioctl failed\n");
670 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_DEC_STOP
, 0)) {
671 ast_log(LOG_ERROR
, "IFX_TAPI_DEC_STOP ioctl failed\n");
675 return lantiq_play_tone(c
, TAPI_TONE_LOCALE_NONE
);
678 static int lantiq_end_dialing(int c
)
680 ast_log(LOG_DEBUG
, "TODO - DEBUG MSG\n");
681 struct lantiq_pvt
*pvt
= &iflist
[c
];
683 if (pvt
->dial_timer
) {
684 ast_sched_thread_del(sched_thread
, pvt
->dial_timer
);
689 ast_hangup(pvt
->owner
);
695 static int lantiq_end_call(int c
)
697 ast_log(LOG_DEBUG
, "TODO - DEBUG MSG\n");
699 struct lantiq_pvt
*pvt
= &iflist
[c
];
702 lantiq_jb_get_stats(c
);
703 ast_queue_hangup(pvt
->owner
);
709 static struct ast_channel
* lantiq_channel(int state
, int c
, char *ext
, char *ctx
)
711 ast_log(LOG_DEBUG
, "TODO - DEBUG MSG\n");
713 struct ast_channel
*chan
= NULL
;
715 struct lantiq_pvt
*pvt
= &iflist
[c
];
717 chan
= ast_channel_alloc(1, state
, NULL
, NULL
, "", ext
, ctx
, 0, c
, "TAPI/%s", "1");
719 chan
->tech
= &lantiq_tech
;
720 chan
->nativeformats
= AST_FORMAT_ULAW
;
721 chan
->readformat
= AST_FORMAT_ULAW
;
722 chan
->writeformat
= AST_FORMAT_ULAW
;
723 chan
->tech_pvt
= pvt
;
730 static struct ast_channel
* ast_lantiq_requester(const char *type
, format_t format
, const struct ast_channel
*requestor
, void *data
, int *cause
)
732 ast_mutex_lock(&iflock
);
735 struct ast_channel
*chan
= NULL
;
738 ast_debug(1, "Asked to create a TAPI channel with formats: %s\n", ast_getformatname_multiple(buf
, sizeof(buf
), format
));
741 /* check for correct data argument */
742 if (ast_strlen_zero(data
)) {
743 ast_log(LOG_ERROR
, "Unable to create channel with empty destination.\n");
744 *cause
= AST_CAUSE_CHANNEL_UNACCEPTABLE
;
748 /* get our port number */
749 port_id
= atoi((char*) data
);
750 if (port_id
< 1 || port_id
> dev_ctx
.channels
) {
751 ast_log(LOG_ERROR
, "Unknown channel ID: \"%s\"\n", (char*) data
);
752 *cause
= AST_CAUSE_CHANNEL_UNACCEPTABLE
;
756 /* on asterisk user's side, we're using port 1-2.
757 * Here in non normal human's world, we begin
762 chan
= lantiq_channel(AST_STATE_DOWN
, port_id
, NULL
, NULL
);
764 ast_mutex_unlock(&iflock
);
768 static int lantiq_dev_data_handler(int c
)
771 struct ast_frame frame
= {0};
773 int res
= read(dev_ctx
.ch_fd
[c
], buf
, sizeof(buf
));
774 if (res
<= 0) ast_log(LOG_ERROR
, "we got read error %i\n", res
);
776 rtp_header_t
*rtp
= (rtp_header_t
*) buf
;
779 frame
.frametype
= AST_FRAME_VOICE
;
780 frame
.subclass
.codec
= rtp
->payload_type
;
781 frame
.samples
= res
- RTP_HEADER_LEN
;
782 frame
.datalen
= res
- RTP_HEADER_LEN
;
783 frame
.data
.ptr
= buf
+ RTP_HEADER_LEN
;
785 struct lantiq_pvt
*pvt
= (struct lantiq_pvt
*) &iflist
[c
];
786 if (pvt
->owner
&& (pvt
->owner
->_state
== AST_STATE_UP
)) {
787 if(!ast_channel_trylock(pvt
->owner
)) {
788 ast_queue_frame(pvt
->owner
, &frame
);
789 ast_channel_unlock(pvt
->owner
);
793 /* ast_debug(1, "lantiq_dev_data_handler(): size: %i version: %i padding: %i extension: %i csrc_count: %i \n"
794 "marker: %i payload_type: %s seqno: %i timestamp: %i ssrc: %i\n",
799 (int)rtp->csrc_count,
801 ast_codec2str(rtp->payload_type),
809 static int accept_call(int c
)
811 ast_log(LOG_DEBUG
, "TODO - DEBUG MSG\n");
813 struct lantiq_pvt
*pvt
= &iflist
[c
];
816 struct ast_channel
*chan
= pvt
->owner
;
818 switch (chan
->_state
) {
819 case AST_STATE_RINGING
:
820 lantiq_play_tone(c
, TAPI_TONE_LOCALE_NONE
);
821 ast_queue_control(pvt
->owner
, AST_CONTROL_ANSWER
);
822 pvt
->channel_state
= INCALL
;
825 ast_log(LOG_WARNING
, "entered unhandled state %s\n", ast_state2str(chan
->_state
));
832 static int lantiq_dev_event_hook(int c
, int state
)
834 ast_mutex_lock(&iflock
);
836 ast_log(LOG_DEBUG
, "on port %i detected event %s hook\n", c
, state
? "on" : "off");
839 if (state
) { /* going onhook */
840 switch (iflist
[c
].channel_state
) {
842 ret
= lantiq_standby(c
);
845 ret
= lantiq_end_dialing(c
);
848 ret
= lantiq_end_call(c
);
851 ret
= lantiq_standby(c
); // TODO: are we sure for this ?
856 iflist
[c
].channel_state
= ONHOOK
;
857 } else { /* going offhook */
858 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_LINE_FEED_SET
, IFX_TAPI_LINE_FEED_ACTIVE
)) {
859 ast_log(LOG_ERROR
, "IFX_TAPI_LINE_FEED_SET ioctl failed\n");
863 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_ENC_START
, 0)) {
864 ast_log(LOG_ERROR
, "IFX_TAPI_ENC_START ioctl failed\n");
868 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_DEC_START
, 0)) {
869 ast_log(LOG_ERROR
, "IFX_TAPI_DEC_START ioctl failed\n");
873 switch (iflist
[c
].channel_state
) {
875 ret
= accept_call(c
);
878 iflist
[c
].channel_state
= OFFHOOK
;
879 lantiq_play_tone(c
, TAPI_TONE_LOCALE_DIAL_CODE
);
887 ast_mutex_unlock(&iflock
);
892 static void lantiq_reset_dtmfbuf(struct lantiq_pvt
*pvt
)
894 pvt
->dtmfbuf
[0] = '\0';
895 pvt
->dtmfbuf_len
= 0;
899 static void lantiq_dial(struct lantiq_pvt
*pvt
)
901 struct ast_channel
*chan
= NULL
;
903 ast_log(LOG_DEBUG
, "user want's to dial %s.\n", pvt
->dtmfbuf
);
905 if (ast_exists_extension(NULL
, pvt
->context
, pvt
->dtmfbuf
, 1, NULL
)) {
906 ast_debug(1, "found extension %s, dialing\n", pvt
->dtmfbuf
);
908 strcpy(pvt
->ext
, pvt
->dtmfbuf
);
910 ast_verbose(VERBOSE_PREFIX_3
" extension exists, starting PBX %s\n", pvt
->ext
);
912 chan
= lantiq_channel(AST_STATE_UP
, pvt
->port_id
, pvt
->ext
+1, pvt
->context
);
913 chan
->tech_pvt
= pvt
;
916 strcpy(chan
->exten
, pvt
->ext
);
917 ast_setstate(chan
, AST_STATE_RING
);
918 pvt
->channel_state
= INCALL
;
920 pvt
->call_setup_start
= now();
922 if (ast_pbx_start(chan
)) {
923 ast_log(LOG_WARNING
, " unable to start PBX on %s\n", chan
->name
);
927 ast_log(LOG_DEBUG
, "no extension found\n");
928 lantiq_play_tone(pvt
->port_id
, TAPI_TONE_LOCALE_BUSY_CODE
);
929 pvt
->channel_state
= CALL_ENDED
;
932 lantiq_reset_dtmfbuf(pvt
);
935 static int lantiq_event_dial_timeout(const void* data
)
937 ast_debug(1, "TAPI: lantiq_event_dial_timeout()\n");
939 struct lantiq_pvt
*pvt
= (struct lantiq_pvt
*) data
;
942 if (! pvt
->channel_state
== ONHOOK
) {
945 ast_debug(1, "TAPI: lantiq_event_dial_timeout(): dial timeout in state ONHOOK.\n");
951 static int lantiq_send_digit(int c
, char digit
)
953 struct lantiq_pvt
*pvt
= &iflist
[c
];
955 struct ast_frame f
= { .frametype
= AST_FRAME_DTMF
, .subclass
.integer
= digit
};
958 ast_log(LOG_DEBUG
, "Port %i transmitting digit \"%c\"\n", c
, digit
);
959 return ast_queue_frame(pvt
->owner
, &f
);
961 ast_debug(1, "Warning: lantiq_send_digit() without owner!\n");
966 static void lantiq_dev_event_digit(int c
, char digit
)
968 ast_mutex_lock(&iflock
);
970 ast_log(LOG_DEBUG
, "on port %i detected digit \"%c\"\n", c
, digit
);
972 struct lantiq_pvt
*pvt
= &iflist
[c
];
974 switch (pvt
->channel_state
) {
977 lantiq_send_digit(c
, digit
);
981 pvt
->channel_state
= DIALING
;
983 lantiq_play_tone(c
, TAPI_TONE_LOCALE_NONE
);
988 if (pvt
->dial_timer
) {
989 ast_sched_thread_del(sched_thread
, pvt
->dial_timer
);
995 pvt
->dtmfbuf
[pvt
->dtmfbuf_len
] = digit
;
997 pvt
->dtmfbuf
[pvt
->dtmfbuf_len
] = '\0';
999 /* setup autodial timer */
1000 if (!pvt
->dial_timer
) {
1001 ast_log(LOG_DEBUG
, "setting new timer\n");
1002 pvt
->dial_timer
= ast_sched_thread_add(sched_thread
, 2000, lantiq_event_dial_timeout
, (const void*) pvt
);
1004 ast_log(LOG_DEBUG
, "replacing timer\n");
1005 struct sched_context
*sched
= ast_sched_thread_get_context(sched_thread
);
1006 AST_SCHED_REPLACE(pvt
->dial_timer
, sched
, 2000, lantiq_event_dial_timeout
, (const void*) pvt
);
1011 ast_log(LOG_ERROR
, "don't know what to do in unhandled state\n");
1015 ast_mutex_unlock(&iflock
);
1019 static void lantiq_dev_event_handler(void)
1021 IFX_TAPI_EVENT_t event
;
1024 for (i
= 0; i
< dev_ctx
.channels
; i
++) {
1025 ast_mutex_lock(&iflock
);
1027 memset (&event
, 0, sizeof(event
));
1029 if (ioctl(dev_ctx
.dev_fd
, IFX_TAPI_EVENT_GET
, &event
)) {
1030 ast_mutex_unlock(&iflock
);
1033 if (event
.id
== IFX_TAPI_EVENT_NONE
) {
1034 ast_mutex_unlock(&iflock
);
1038 ast_mutex_unlock(&iflock
);
1041 case IFX_TAPI_EVENT_FXS_ONHOOK
:
1042 lantiq_dev_event_hook(i
, 1);
1044 case IFX_TAPI_EVENT_FXS_OFFHOOK
:
1045 lantiq_dev_event_hook(i
, 0);
1047 case IFX_TAPI_EVENT_DTMF_DIGIT
:
1048 lantiq_dev_event_digit(i
, (char)event
.data
.dtmf
.ascii
);
1050 case IFX_TAPI_EVENT_PULSE_DIGIT
:
1051 if (event
.data
.pulse
.digit
== 0xB) {
1052 lantiq_dev_event_digit(i
, '0');
1054 lantiq_dev_event_digit(i
, '0' + (char)event
.data
.pulse
.digit
);
1057 case IFX_TAPI_EVENT_COD_DEC_CHG
:
1058 case IFX_TAPI_EVENT_TONE_GEN_END
:
1059 case IFX_TAPI_EVENT_CID_TX_SEQ_END
:
1062 ast_log(LOG_ERROR
, "unknown TAPI event %08X\n", event
.id
);
1068 static void * lantiq_events_monitor(void *data
)
1070 ast_verbose("TAPI thread started\n");
1072 struct pollfd fds
[3];
1074 fds
[0].fd
= dev_ctx
.dev_fd
;
1075 fds
[0].events
= POLLIN
;
1076 fds
[1].fd
= dev_ctx
.ch_fd
[0];
1077 fds
[1].events
= POLLIN
;
1078 fds
[2].fd
= dev_ctx
.ch_fd
[1];
1079 fds
[2].events
= POLLIN
;
1082 ast_mutex_lock(&monlock
);
1084 if (poll(fds
, dev_ctx
.channels
+ 1, 2000) <= 0) {
1085 ast_mutex_unlock(&monlock
);
1089 if (fds
[0].revents
& POLLIN
) {
1090 lantiq_dev_event_handler();
1093 ast_mutex_unlock(&monlock
);
1095 if ((fds
[1].revents
& POLLIN
) && (lantiq_dev_data_handler(0))) {
1096 ast_log(LOG_ERROR
, "data handler 0 failed\n");
1100 if ((fds
[2].revents
& POLLIN
) && (lantiq_dev_data_handler(1))) {
1101 ast_log(LOG_ERROR
, "data handler 1 failed\n");
1109 static int restart_monitor(void)
1111 /* If we're supposed to be stopped -- stay stopped */
1112 if (monitor_thread
== AST_PTHREADT_STOP
)
1115 ast_mutex_lock(&monlock
);
1117 if (monitor_thread
== pthread_self()) {
1118 ast_mutex_unlock(&monlock
);
1119 ast_log(LOG_WARNING
, "Cannot kill myself\n");
1123 if (monitor_thread
!= AST_PTHREADT_NULL
) {
1124 if (ast_mutex_lock(&iflock
)) {
1125 ast_mutex_unlock(&monlock
);
1126 ast_log(LOG_WARNING
, "Unable to lock the interface list\n");
1130 while (pthread_kill(monitor_thread
, SIGURG
) == 0)
1132 pthread_join(monitor_thread
, NULL
);
1133 ast_mutex_unlock(&iflock
);
1137 /* Start a new monitor */
1138 if (ast_pthread_create_background(&monitor_thread
, NULL
, lantiq_events_monitor
, NULL
) < 0) {
1139 ast_mutex_unlock(&monlock
);
1140 ast_log(LOG_ERROR
, "Unable to start monitor thread.\n");
1144 ast_mutex_unlock(&monlock
);
1149 static void lantiq_cleanup(void)
1153 for (c
= 0; c
< dev_ctx
.channels
; c
++) {
1154 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_LINE_FEED_SET
, IFX_TAPI_LINE_FEED_STANDBY
)) {
1155 ast_log(LOG_WARNING
, "IFX_TAPI_LINE_FEED_SET ioctl failed\n");
1158 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_ENC_STOP
, 0)) {
1159 ast_log(LOG_WARNING
, "IFX_TAPI_ENC_STOP ioctl failed\n");
1162 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_DEC_STOP
, 0)) {
1163 ast_log(LOG_WARNING
, "IFX_TAPI_DEC_STOP ioctl failed\n");
1167 if (ioctl(dev_ctx
.dev_fd
, IFX_TAPI_DEV_STOP
, 0)) {
1168 ast_log(LOG_WARNING
, "IFX_TAPI_DEV_STOP ioctl failed\n");
1171 close(dev_ctx
.dev_fd
);
1174 static int unload_module(void)
1178 ast_channel_unregister(&lantiq_tech
);
1180 if (!ast_mutex_lock(&iflock
)) {
1181 for (c
= 0; c
< dev_ctx
.channels
; c
++) {
1182 if (iflist
[c
].owner
)
1183 ast_softhangup(iflist
[c
].owner
, AST_SOFTHANGUP_APPUNLOAD
);
1185 ast_mutex_unlock(&iflock
);
1187 ast_log(LOG_WARNING
, "Unable to lock the monitor\n");
1191 if (!ast_mutex_lock(&monlock
)) {
1192 if (monitor_thread
> AST_PTHREADT_NULL
) {
1194 while (pthread_kill(monitor_thread
, SIGURG
) == 0)
1196 pthread_join(monitor_thread
, NULL
);
1198 monitor_thread
= AST_PTHREADT_STOP
;
1199 ast_mutex_unlock(&monlock
);
1201 ast_log(LOG_WARNING
, "Unable to lock the monitor\n");
1208 static struct lantiq_pvt
*lantiq_init_pvt(struct lantiq_pvt
*pvt
)
1213 pvt
->channel_state
= UNKNOWN
;
1214 pvt
->context
[0] = '\0';
1216 pvt
->dial_timer
= 0;
1217 pvt
->dtmfbuf
[0] = '\0';
1218 pvt
->dtmfbuf_len
= 0;
1219 pvt
->call_setup_start
= 0;
1220 pvt
->call_setup_delay
= 0;
1222 pvt
->jb_underflow
= 0;
1223 pvt
->jb_overflow
= 0;
1225 pvt
->jb_invalid
= 0;
1227 ast_log(LOG_ERROR
, "unable to clear pvt structure\n");
1233 static int lantiq_create_pvts(void)
1237 iflist
= ast_calloc(1, sizeof(struct lantiq_pvt
) * dev_ctx
.channels
);
1240 for (i
=0 ; i
<dev_ctx
.channels
; i
++) {
1241 lantiq_init_pvt(&iflist
[i
]);
1242 iflist
[i
].port_id
= i
;
1243 if (per_channel_context
) {
1244 snprintf(iflist
[i
].context
, AST_MAX_CONTEXT
, "%s%i", LANTIQ_CONTEXT_PREFIX
, i
+1);
1245 ast_debug(1, "Context for channel %i: %s\n", i
, iflist
[i
].context
);
1247 snprintf(iflist
[i
].context
, AST_MAX_CONTEXT
, "default");
1252 ast_log(LOG_ERROR
, "unable to allocate memory\n");
1257 static int lantiq_setup_rtp(int c
)
1259 /* Configure RTP payload type tables */
1260 IFX_TAPI_PKT_RTP_PT_CFG_t rtpPTConf
;
1262 memset((char*)&rtpPTConf
, '\0', sizeof(rtpPTConf
));
1264 rtpPTConf
.nPTup
[IFX_TAPI_COD_TYPE_MLAW
] = AST_FORMAT_ULAW
;
1265 rtpPTConf
.nPTup
[IFX_TAPI_COD_TYPE_ALAW
] = AST_FORMAT_ALAW
;
1266 // rtpPTConf.nPTup[IFX_TAPI_COD_TYPE_G723_63] = AST_FORMAT_G723_1;
1267 // rtpPTConf.nPTup[IFX_TAPI_COD_TYPE_G723_53] = 4;
1268 // rtpPTConf.nPTup[IFX_TAPI_COD_TYPE_G729] = AST_FORMAT_G729A;
1269 // rtpPTConf.nPTup[IFX_TAPI_COD_TYPE_G722_64] = AST_FORMAT_G722;
1271 rtpPTConf
.nPTdown
[IFX_TAPI_COD_TYPE_MLAW
] = AST_FORMAT_ULAW
;
1272 rtpPTConf
.nPTdown
[IFX_TAPI_COD_TYPE_ALAW
] = AST_FORMAT_ALAW
;
1273 // rtpPTConf.nPTdown[IFX_TAPI_COD_TYPE_G723_63] = AST_FORMAT_G723_1;
1274 // rtpPTConf.nPTdown[IFX_TAPI_COD_TYPE_G723_53] = AST_FORMAT_G723_1;
1275 // rtpPTConf.nPTdown[IFX_TAPI_COD_TYPE_G729] = AST_FORMAT_G729A;
1276 // rtpPTConf.nPTdown[IFX_TAPI_COD_TYPE_G722_64] = AST_FORMAT_G722;
1279 if ((ret
= ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_PKT_RTP_PT_CFG_SET
, (IFX_int32_t
) &rtpPTConf
))) {
1280 ast_log(LOG_ERROR
, "IFX_TAPI_PKT_RTP_PT_CFG_SET failed: ret=%i\n", ret
);
1287 static int load_module(void)
1289 struct ast_config
*cfg
;
1290 struct ast_variable
*v
;
1298 int jb_type
= IFX_TAPI_JB_TYPE_ADAPTIVE
;
1299 int jb_pckadpt
= IFX_TAPI_JB_PKT_ADAPT_VOICE
;
1300 int jb_localadpt
= IFX_TAPI_JB_LOCAL_ADAPT_DEFAULT
;
1301 int jb_scaling
= 0x10;
1302 int jb_initialsize
= 0x2d0;
1303 int jb_minsize
= 0x50;
1304 int jb_maxsize
= 0x5a0;
1305 int cid_type
= IFX_TAPI_CID_STD_TELCORDIA
;
1306 int vad_type
= IFX_TAPI_ENC_VAD_NOVAD
;
1307 dev_ctx
.channels
= TAPI_AUDIO_PORT_NUM_MAX
;
1308 struct ast_flags config_flags
= { 0 };
1310 if (!(sched_thread
= ast_sched_thread_create())) {
1311 ast_log(LOG_ERROR
, "Unable to create scheduler thread\n");
1312 return AST_MODULE_LOAD_FAILURE
;
1315 if ((cfg
= ast_config_load(config
, config_flags
)) == CONFIG_STATUS_FILEINVALID
) {
1316 ast_log(LOG_ERROR
, "Config file %s is in an invalid format. Aborting.\n", config
);
1317 return AST_MODULE_LOAD_DECLINE
;
1320 /* We *must* have a config file otherwise stop immediately */
1322 ast_log(LOG_ERROR
, "Unable to load config %s\n", config
);
1323 return AST_MODULE_LOAD_DECLINE
;
1326 if (ast_mutex_lock(&iflock
)) {
1327 ast_log(LOG_ERROR
, "Unable to lock interface list.\n");
1328 return AST_MODULE_LOAD_FAILURE
;
1331 for (v
= ast_variable_browse(cfg
, "interfaces"); v
; v
= v
->next
) {
1332 if (!strcasecmp(v
->name
, "channels")) {
1333 dev_ctx
.channels
= atoi(v
->value
);
1334 if (!dev_ctx
.channels
) {
1335 ast_log(LOG_ERROR
, "Invalid value for channels in config %s\n", config
);
1336 ast_config_destroy(cfg
);
1337 return AST_MODULE_LOAD_DECLINE
;
1339 } else if (!strcasecmp(v
->name
, "firmwarefilename")) {
1340 ast_copy_string(firmware_filename
, v
->value
, sizeof(firmware_filename
));
1341 } else if (!strcasecmp(v
->name
, "bbdfilename")) {
1342 ast_copy_string(bbd_filename
, v
->value
, sizeof(bbd_filename
));
1343 } else if (!strcasecmp(v
->name
, "basepath")) {
1344 ast_copy_string(base_path
, v
->value
, sizeof(base_path
));
1345 } else if (!strcasecmp(v
->name
, "per_channel_context")) {
1346 if (!strcasecmp(v
->value
, "on")) {
1347 per_channel_context
= 1;
1348 } else if (!strcasecmp(v
->value
, "off")) {
1349 per_channel_context
= 0;
1351 ast_log(LOG_ERROR
, "Unknown per_channel_context value '%s'. Try 'on' or 'off'.\n", v
->value
);
1352 ast_config_destroy(cfg
);
1353 return AST_MODULE_LOAD_DECLINE
;
1358 for (v
= ast_variable_browse(cfg
, "general"); v
; v
= v
->next
) {
1359 if (!strcasecmp(v
->name
, "rxgain")) {
1360 rxgain
= atoi(v
->value
);
1363 ast_log(LOG_WARNING
, "Invalid rxgain: %s, using default.\n", v
->value
);
1365 } else if (!strcasecmp(v
->name
, "txgain")) {
1366 txgain
= atoi(v
->value
);
1369 ast_log(LOG_WARNING
, "Invalid txgain: %s, using default.\n", v
->value
);
1371 } else if (!strcasecmp(v
->name
, "echocancel")) {
1372 if (!strcasecmp(v
->value
, "off")) {
1373 wlec_type
= IFX_TAPI_WLEC_TYPE_OFF
;
1374 } else if (!strcasecmp(v
->value
, "nlec")) {
1375 wlec_type
= IFX_TAPI_WLEC_TYPE_NE
;
1376 if (!strcasecmp(v
->name
, "echocancelfixedwindowsize")) {
1377 wlec_nbne
= atoi(v
->value
);
1379 } else if (!strcasecmp(v
->value
, "wlec")) {
1380 wlec_type
= IFX_TAPI_WLEC_TYPE_NFE
;
1381 if (!strcasecmp(v
->name
, "echocancelnfemovingwindowsize")) {
1382 wlec_nbfe
= atoi(v
->value
);
1383 } else if (!strcasecmp(v
->name
, "echocancelfixedwindowsize")) {
1384 wlec_nbne
= atoi(v
->value
);
1385 } else if (!strcasecmp(v
->name
, "echocancelwidefixedwindowsize")) {
1386 wlec_wbne
= atoi(v
->value
);
1388 } else if (!strcasecmp(v
->value
, "nees")) {
1389 wlec_type
= IFX_TAPI_WLEC_TYPE_NE_ES
;
1390 } else if (!strcasecmp(v
->value
, "nfees")) {
1391 wlec_type
= IFX_TAPI_WLEC_TYPE_NFE_ES
;
1392 } else if (!strcasecmp(v
->value
, "es")) {
1393 wlec_type
= IFX_TAPI_WLEC_TYPE_ES
;
1395 wlec_type
= IFX_TAPI_WLEC_TYPE_OFF
;
1396 ast_log(LOG_ERROR
, "Unknown echo cancellation type '%s'\n", v
->value
);
1397 ast_config_destroy(cfg
);
1398 return AST_MODULE_LOAD_DECLINE
;
1400 } else if (!strcasecmp(v
->name
, "echocancelnlp")) {
1401 if (!strcasecmp(v
->value
, "on")) {
1402 wlec_nlp
= IFX_TAPI_WLEC_NLP_ON
;
1403 } else if (!strcasecmp(v
->value
, "off")) {
1404 wlec_nlp
= IFX_TAPI_WLEC_NLP_OFF
;
1406 ast_log(LOG_ERROR
, "Unknown echo cancellation nlp '%s'\n", v
->value
);
1407 ast_config_destroy(cfg
);
1408 return AST_MODULE_LOAD_DECLINE
;
1410 } else if (!strcasecmp(v
->name
, "jitterbuffertype")) {
1411 if (!strcasecmp(v
->value
, "fixed")) {
1412 jb_type
= IFX_TAPI_JB_TYPE_FIXED
;
1413 } else if (!strcasecmp(v
->value
, "adaptive")) {
1414 jb_type
= IFX_TAPI_JB_TYPE_ADAPTIVE
;
1415 jb_localadpt
= IFX_TAPI_JB_LOCAL_ADAPT_DEFAULT
;
1416 if (!strcasecmp(v
->name
, "jitterbufferadaptation")) {
1417 if (!strcasecmp(v
->value
, "on")) {
1418 jb_localadpt
= IFX_TAPI_JB_LOCAL_ADAPT_ON
;
1419 } else if (!strcasecmp(v
->value
, "off")) {
1420 jb_localadpt
= IFX_TAPI_JB_LOCAL_ADAPT_OFF
;
1422 } else if (!strcasecmp(v
->name
, "jitterbufferscalling")) {
1423 jb_scaling
= atoi(v
->value
);
1424 } else if (!strcasecmp(v
->name
, "jitterbufferinitialsize")) {
1425 jb_initialsize
= atoi(v
->value
);
1426 } else if (!strcasecmp(v
->name
, "jitterbufferminsize")) {
1427 jb_minsize
= atoi(v
->value
);
1428 } else if (!strcasecmp(v
->name
, "jitterbuffermaxsize")) {
1429 jb_maxsize
= atoi(v
->value
);
1432 ast_log(LOG_ERROR
, "Unknown jitter buffer type '%s'\n", v
->value
);
1433 ast_config_destroy(cfg
);
1434 return AST_MODULE_LOAD_DECLINE
;
1436 } else if (!strcasecmp(v
->name
, "jitterbufferpackettype")) {
1437 if (!strcasecmp(v
->value
, "voice")) {
1438 jb_pckadpt
= IFX_TAPI_JB_PKT_ADAPT_VOICE
;
1439 } else if (!strcasecmp(v
->value
, "data")) {
1440 jb_pckadpt
= IFX_TAPI_JB_PKT_ADAPT_DATA
;
1441 } else if (!strcasecmp(v
->value
, "datanorep")) {
1442 jb_pckadpt
= IFX_TAPI_JB_PKT_ADAPT_DATA_NO_REP
;
1444 ast_log(LOG_ERROR
, "Unknown jitter buffer packet adaptation type '%s'\n", v
->value
);
1445 ast_config_destroy(cfg
);
1446 return AST_MODULE_LOAD_DECLINE
;
1448 } else if (!strcasecmp(v
->name
, "calleridtype")) {
1449 ast_log(LOG_DEBUG
, "Setting CID type to %s.\n", v
->value
);
1450 if (!strcasecmp(v
->value
, "telecordia")) {
1451 cid_type
= IFX_TAPI_CID_STD_TELCORDIA
;
1452 } else if (!strcasecmp(v
->value
, "etsifsk")) {
1453 cid_type
= IFX_TAPI_CID_STD_ETSI_FSK
;
1454 } else if (!strcasecmp(v
->value
, "etsidtmf")) {
1455 cid_type
= IFX_TAPI_CID_STD_ETSI_DTMF
;
1456 } else if (!strcasecmp(v
->value
, "sin")) {
1457 cid_type
= IFX_TAPI_CID_STD_SIN
;
1458 } else if (!strcasecmp(v
->value
, "ntt")) {
1459 cid_type
= IFX_TAPI_CID_STD_NTT
;
1460 } else if (!strcasecmp(v
->value
, "kpndtmf")) {
1461 cid_type
= IFX_TAPI_CID_STD_KPN_DTMF
;
1462 } else if (!strcasecmp(v
->value
, "kpndtmffsk")) {
1463 cid_type
= IFX_TAPI_CID_STD_KPN_DTMF_FSK
;
1465 ast_log(LOG_ERROR
, "Unknown caller id type '%s'\n", v
->value
);
1466 ast_config_destroy(cfg
);
1467 return AST_MODULE_LOAD_DECLINE
;
1469 } else if (!strcasecmp(v
->name
, "voiceactivitydetection")) {
1470 if (!strcasecmp(v
->value
, "on")) {
1471 vad_type
= IFX_TAPI_ENC_VAD_ON
;
1472 } else if (!strcasecmp(v
->value
, "g711")) {
1473 vad_type
= IFX_TAPI_ENC_VAD_G711
;
1474 } else if (!strcasecmp(v
->value
, "cng")) {
1475 vad_type
= IFX_TAPI_ENC_VAD_CNG_ONLY
;
1476 } else if (!strcasecmp(v
->value
, "sc")) {
1477 vad_type
= IFX_TAPI_ENC_VAD_SC_ONLY
;
1479 ast_log(LOG_ERROR
, "Unknown voice activity detection value '%s'\n", v
->value
);
1480 ast_config_destroy(cfg
);
1481 return AST_MODULE_LOAD_DECLINE
;
1486 lantiq_create_pvts();
1488 ast_mutex_unlock(&iflock
);
1490 if (ast_channel_register(&lantiq_tech
)) {
1491 ast_log(LOG_ERROR
, "Unable to register channel class 'Phone'\n");
1492 ast_config_destroy(cfg
);
1494 return AST_MODULE_LOAD_FAILURE
;
1496 ast_config_destroy(cfg
);
1500 IFX_TAPI_TONE_t tone
;
1502 IFX_TAPI_DEV_START_CFG_t dev_start
;
1503 IFX_TAPI_MAP_DATA_t map_data
;
1504 IFX_TAPI_ENC_CFG_t enc_cfg
;
1505 IFX_TAPI_LINE_VOLUME_t line_vol
;
1506 IFX_TAPI_WLEC_CFG_t wlec_cfg
;
1507 IFX_TAPI_JB_CFG_t jb_cfg
;
1508 IFX_TAPI_CID_CFG_t cid_cfg
;
1512 dev_ctx
.dev_fd
= lantiq_dev_open(base_path
, 0);
1514 if (dev_ctx
.dev_fd
< 0) {
1515 ast_log(LOG_ERROR
, "lantiq tapi device open function failed\n");
1516 return AST_MODULE_LOAD_FAILURE
;
1519 for (c
= 0; c
< dev_ctx
.channels
; c
++) {
1520 dev_ctx
.ch_fd
[c
] = lantiq_dev_open(base_path
, c
+ 1);
1522 if (dev_ctx
.ch_fd
[c
] < 0) {
1523 ast_log(LOG_ERROR
, "lantiq tapi channel %d open function failed\n", c
);
1524 return AST_MODULE_LOAD_FAILURE
;
1528 if (lantiq_dev_firmware_download(dev_ctx
.dev_fd
, firmware_filename
)) {
1529 ast_log(LOG_ERROR
, "voice firmware download failed\n");
1530 return AST_MODULE_LOAD_FAILURE
;
1533 if (ioctl(dev_ctx
.dev_fd
, IFX_TAPI_DEV_STOP
, 0)) {
1534 ast_log(LOG_ERROR
, "IFX_TAPI_DEV_STOP ioctl failed\n");
1535 return AST_MODULE_LOAD_FAILURE
;
1538 memset(&dev_start
, 0x0, sizeof(IFX_TAPI_DEV_START_CFG_t
));
1539 dev_start
.nMode
= IFX_TAPI_INIT_MODE_VOICE_CODER
;
1542 if (ioctl(dev_ctx
.dev_fd
, IFX_TAPI_DEV_START
, &dev_start
)) {
1543 ast_log(LOG_ERROR
, "IFX_TAPI_DEV_START ioctl failed\n");
1544 return AST_MODULE_LOAD_FAILURE
;
1547 for (c
= 0; c
< dev_ctx
.channels
; c
++) {
1550 memset(&tone
, 0, sizeof(IFX_TAPI_TONE_t
));
1551 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_TONE_TABLE_CFG_SET
, &tone
)) {
1552 ast_log(LOG_ERROR
, "IFX_TAPI_TONE_TABLE_CFG_SET %d failed\n", c
);
1553 return AST_MODULE_LOAD_FAILURE
;
1557 IFX_TAPI_RING_CFG_t ringingType
;
1558 memset(&ringingType
, 0, sizeof(IFX_TAPI_RING_CFG_t
));
1559 ringingType
.nMode
= IFX_TAPI_RING_CFG_MODE_INTERNAL_BALANCED
;
1560 ringingType
.nSubmode
= IFX_TAPI_RING_CFG_SUBMODE_DC_RNG_TRIP_FAST
;
1561 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_RING_CFG_SET
, (IFX_int32_t
) &ringingType
)) {
1562 ast_log(LOG_ERROR
, "IFX_TAPI_RING_CFG_SET failed\n");
1563 return AST_MODULE_LOAD_FAILURE
;
1567 IFX_char_t data
[15] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1568 0x00, 0x00, 0x00, 0x00, 0x00,
1569 0x00, 0x00, 0x00, 0x00, 0x00 };
1571 IFX_TAPI_RING_CADENCE_t ringCadence
;
1572 memset(&ringCadence
, 0, sizeof(IFX_TAPI_RING_CADENCE_t
));
1573 memcpy(&ringCadence
.data
, data
, sizeof(data
));
1574 ringCadence
.nr
= sizeof(data
) * 8;
1576 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_RING_CADENCE_HR_SET
, &ringCadence
)) {
1577 ast_log(LOG_ERROR
, "IFX_TAPI_RING_CADENCE_HR_SET failed\n");
1578 return AST_MODULE_LOAD_FAILURE
;
1581 /* perform mapping */
1582 memset(&map_data
, 0x0, sizeof(IFX_TAPI_MAP_DATA_t
));
1583 map_data
.nDstCh
= c
;
1584 map_data
.nChType
= IFX_TAPI_MAP_TYPE_PHONE
;
1586 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_MAP_DATA_ADD
, &map_data
)) {
1587 ast_log(LOG_ERROR
, "IFX_TAPI_MAP_DATA_ADD %d failed\n", c
);
1588 return AST_MODULE_LOAD_FAILURE
;
1592 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_LINE_FEED_SET
, IFX_TAPI_LINE_FEED_STANDBY
)) {
1593 ast_log(LOG_ERROR
, "IFX_TAPI_LINE_FEED_SET %d failed\n", c
);
1594 return AST_MODULE_LOAD_FAILURE
;
1597 /* Configure encoder */
1598 memset(&enc_cfg
, 0x0, sizeof(IFX_TAPI_ENC_CFG_t
));
1599 enc_cfg
.nFrameLen
= IFX_TAPI_COD_LENGTH_20
;
1600 enc_cfg
.nEncType
= IFX_TAPI_COD_TYPE_MLAW
;
1602 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_ENC_CFG_SET
, &enc_cfg
)) {
1603 ast_log(LOG_ERROR
, "IFX_TAPI_ENC_CFG_SET %d failed\n", c
);
1604 return AST_MODULE_LOAD_FAILURE
;
1608 memset(&line_vol
, 0, sizeof(line_vol
));
1609 line_vol
.nGainRx
= rxgain
;
1610 line_vol
.nGainTx
= txgain
;
1612 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_PHONE_VOLUME_SET
, &line_vol
)) {
1613 ast_log(LOG_ERROR
, "IFX_TAPI_PHONE_VOLUME_SET %d failed\n", c
);
1614 return AST_MODULE_LOAD_FAILURE
;
1617 /* Configure line echo canceller */
1618 memset(&wlec_cfg
, 0, sizeof(wlec_cfg
));
1619 wlec_cfg
.nType
= wlec_type
;
1620 wlec_cfg
.bNlp
= wlec_nlp
;
1621 wlec_cfg
.nNBFEwindow
= wlec_nbfe
;
1622 wlec_cfg
.nNBNEwindow
= wlec_nbne
;
1623 wlec_cfg
.nWBNEwindow
= wlec_wbne
;
1625 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_WLEC_PHONE_CFG_SET
, &wlec_cfg
)) {
1626 ast_log(LOG_ERROR
, "IFX_TAPI_WLEC_PHONE_CFG_SET %d failed\n", c
);
1627 return AST_MODULE_LOAD_FAILURE
;
1630 /* Configure jitter buffer */
1631 memset(&jb_cfg
, 0, sizeof(jb_cfg
));
1632 jb_cfg
.nJbType
= jb_type
;
1633 jb_cfg
.nPckAdpt
= jb_pckadpt
;
1634 jb_cfg
.nLocalAdpt
= jb_localadpt
;
1635 jb_cfg
.nScaling
= jb_scaling
;
1636 jb_cfg
.nInitialSize
= jb_initialsize
;
1637 jb_cfg
.nMinSize
= jb_minsize
;
1638 jb_cfg
.nMaxSize
= jb_maxsize
;
1640 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_JB_CFG_SET
, &jb_cfg
)) {
1641 ast_log(LOG_ERROR
, "IFX_TAPI_JB_CFG_SET %d failed\n", c
);
1642 return AST_MODULE_LOAD_FAILURE
;
1645 /* Configure Caller ID type */
1646 memset(&cid_cfg
, 0, sizeof(cid_cfg
));
1647 cid_cfg
.nStandard
= cid_type
;
1649 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_CID_CFG_SET
, &cid_cfg
)) {
1650 ast_log(LOG_ERROR
, "IIFX_TAPI_CID_CFG_SET %d failed\n", c
);
1651 return AST_MODULE_LOAD_FAILURE
;
1654 /* Configure voice activity detection */
1655 if (ioctl(dev_ctx
.ch_fd
[c
], IFX_TAPI_ENC_VAD_CFG_SET
, vad_type
)) {
1656 ast_log(LOG_ERROR
, "IFX_TAPI_ENC_VAD_CFG_SET %d failed\n", c
);
1657 return AST_MODULE_LOAD_FAILURE
;
1660 /* Setup TAPI <-> Asterisk codec type mapping */
1661 if (lantiq_setup_rtp(c
)) {
1662 return AST_MODULE_LOAD_FAILURE
;
1665 /* Set initial hook status */
1666 iflist
[c
].channel_state
= lantiq_get_hookstatus(c
);
1668 if (iflist
[c
].channel_state
== UNKNOWN
) {
1669 return AST_MODULE_LOAD_FAILURE
;
1673 /* make sure our device will be closed properly */
1674 ast_register_atexit(lantiq_cleanup
);
1677 return AST_MODULE_LOAD_SUCCESS
;
1680 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY
, "Lantiq TAPI Telephony API Support");