2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2005, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
21 * \brief Generic Linux Telephony Interface driver
23 * \author Mark Spencer <markster@digium.com>
25 * \ingroup channel_drivers
29 <depend>ixjuser</depend>
34 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
37 #include <sys/socket.h>
39 #include <arpa/inet.h>
41 #include <sys/ioctl.h>
43 #ifdef HAVE_LINUX_COMPILER_H
44 #include <linux/compiler.h>
46 #include <linux/telephony.h>
47 /* Still use some IXJ specific stuff */
48 #include <linux/version.h>
49 #include <linux/ixjuser.h>
51 #include "asterisk/lock.h"
52 #include "asterisk/channel.h"
53 #include "asterisk/config.h"
54 #include "asterisk/module.h"
55 #include "asterisk/pbx.h"
56 #include "asterisk/utils.h"
57 #include "asterisk/callerid.h"
58 #include "asterisk/causes.h"
59 #include "asterisk/stringfields.h"
60 #include "asterisk/musiconhold.h"
62 #include "chan_phone.h"
64 #ifdef QTI_PHONEJACK_TJ_PCI /* check for the newer quicknet driver v.3.1.0 which has this symbol */
72 #define IXJ_PHONE_RING_START(x) ioctl(p->fd, PHONE_RING_START, &x);
73 #else /* FreeBSD and others */
74 #define IXJ_PHONE_RING_START(x) ioctl(p->fd, PHONE_RING_START, x);
75 #endif /* __linux__ */
76 #else /* older driver */
77 #define IXJ_PHONE_RING_START(x) ioctl(p->fd, PHONE_RING_START, &x);
80 #define DEFAULT_CALLER_ID "Unknown"
81 #define PHONE_MAX_BUF 480
82 #define DEFAULT_GAIN 0x100
84 static const char tdesc
[] = "Standard Linux Telephony API Driver";
85 static const char config
[] = "phone.conf";
87 /* Default context for dialtone mode */
88 static char context
[AST_MAX_EXTENSION
] = "default";
90 /* Default language */
91 static char language
[MAX_LANGUAGE
] = "";
93 static int echocancel
= AEC_OFF
;
95 static int silencesupression
= 0;
97 static int prefformat
= AST_FORMAT_G729A
| AST_FORMAT_G723_1
| AST_FORMAT_SLINEAR
| AST_FORMAT_ULAW
;
99 /* Protect the interface list (of phone_pvt's) */
100 AST_MUTEX_DEFINE_STATIC(iflock
);
102 /* Protect the monitoring thread, so only one process can kill or start it, and not
103 when it's doing something critical. */
104 AST_MUTEX_DEFINE_STATIC(monlock
);
106 /* Boolean value whether the monitoring thread shall continue. */
107 static unsigned int monitor
;
109 /* This is the thread for the monitor which checks for input on the channels
110 which are not currently in use. */
111 static pthread_t monitor_thread
= AST_PTHREADT_NULL
;
113 static int restart_monitor(void);
115 /* The private structures of the Phone Jack channels are linked for
116 selecting outgoing channels */
118 #define MODE_DIALTONE 1
119 #define MODE_IMMEDIATE 2
124 static struct phone_pvt
{
125 int fd
; /* Raw file descriptor for this device */
126 struct ast_channel
*owner
; /* Channel we belong to, possibly NULL */
127 int mode
; /* Is this in the */
128 int lastformat
; /* Last output format */
129 int lastinput
; /* Last input format */
130 int ministate
; /* Miniature state, for dialtone mode */
131 char dev
[256]; /* Device name */
132 struct phone_pvt
*next
; /* Next channel in list */
133 struct ast_frame fr
; /* Frame */
134 char offset
[AST_FRIENDLY_OFFSET
];
135 char buf
[PHONE_MAX_BUF
]; /* Static buffer for reading frames */
138 int txgain
, rxgain
; /* gain control for playing, recording */
139 /* 0x100 - 1.0, 0x200 - 2.0, 0x80 - 0.5 */
140 int cpt
; /* Call Progress Tone playing? */
141 int silencesupression
;
142 char context
[AST_MAX_EXTENSION
];
143 char obuf
[PHONE_MAX_BUF
* 2];
144 char ext
[AST_MAX_EXTENSION
];
145 char language
[MAX_LANGUAGE
];
146 char cid_num
[AST_MAX_EXTENSION
];
147 char cid_name
[AST_MAX_EXTENSION
];
150 static char cid_num
[AST_MAX_EXTENSION
];
151 static char cid_name
[AST_MAX_EXTENSION
];
153 static struct ast_channel
*phone_request(const char *type
, int format
, void *data
, int *cause
);
154 static int phone_digit_begin(struct ast_channel
*ast
, char digit
);
155 static int phone_digit_end(struct ast_channel
*ast
, char digit
, unsigned int duration
);
156 static int phone_call(struct ast_channel
*ast
, char *dest
, int timeout
);
157 static int phone_hangup(struct ast_channel
*ast
);
158 static int phone_answer(struct ast_channel
*ast
);
159 static struct ast_frame
*phone_read(struct ast_channel
*ast
);
160 static int phone_write(struct ast_channel
*ast
, struct ast_frame
*frame
);
161 static struct ast_frame
*phone_exception(struct ast_channel
*ast
);
162 static int phone_send_text(struct ast_channel
*ast
, const char *text
);
163 static int phone_fixup(struct ast_channel
*old
, struct ast_channel
*new);
164 static int phone_indicate(struct ast_channel
*chan
, int condition
, const void *data
, size_t datalen
);
166 static const struct ast_channel_tech phone_tech
= {
168 .description
= tdesc
,
169 .capabilities
= AST_FORMAT_G723_1
| AST_FORMAT_SLINEAR
| AST_FORMAT_ULAW
| AST_FORMAT_G729A
,
170 .requester
= phone_request
,
171 .send_digit_begin
= phone_digit_begin
,
172 .send_digit_end
= phone_digit_end
,
174 .hangup
= phone_hangup
,
175 .answer
= phone_answer
,
177 .write
= phone_write
,
178 .exception
= phone_exception
,
179 .indicate
= phone_indicate
,
183 static struct ast_channel_tech phone_tech_fxs
= {
185 .description
= tdesc
,
186 .requester
= phone_request
,
187 .send_digit_begin
= phone_digit_begin
,
188 .send_digit_end
= phone_digit_end
,
190 .hangup
= phone_hangup
,
191 .answer
= phone_answer
,
193 .write
= phone_write
,
194 .exception
= phone_exception
,
195 .write_video
= phone_write
,
196 .send_text
= phone_send_text
,
197 .indicate
= phone_indicate
,
201 static struct ast_channel_tech
*cur_tech
;
203 static int phone_indicate(struct ast_channel
*chan
, int condition
, const void *data
, size_t datalen
)
205 struct phone_pvt
*p
= chan
->tech_pvt
;
207 ast_debug(1, "Requested indication %d on channel %s\n", condition
, chan
->name
);
209 case AST_CONTROL_FLASH
:
210 ioctl(p
->fd
, IXJCTL_PSTN_SET_STATE
, PSTN_ON_HOOK
);
212 ioctl(p
->fd
, IXJCTL_PSTN_SET_STATE
, PSTN_OFF_HOOK
);
216 case AST_CONTROL_HOLD
:
217 ast_moh_start(chan
, data
, NULL
);
219 case AST_CONTROL_UNHOLD
:
222 case AST_CONTROL_SRCUPDATE
:
226 ast_log(LOG_WARNING
, "Condition %d is not supported on channel %s\n", condition
, chan
->name
);
231 static int phone_fixup(struct ast_channel
*old
, struct ast_channel
*new)
233 struct phone_pvt
*pvt
= old
->tech_pvt
;
234 if (pvt
&& pvt
->owner
== old
)
239 static int phone_digit_begin(struct ast_channel
*chan
, char digit
)
241 /* XXX Modify this callback to let Asterisk support controlling the length of DTMF */
245 static int phone_digit_end(struct ast_channel
*ast
, char digit
, unsigned int duration
)
250 ast_debug(1, "Dialed %c\n", digit
);
262 outdigit
= digit
- '0';
272 ioctl(p
->fd
, IXJCTL_PSTN_SET_STATE
, PSTN_ON_HOOK
);
274 ioctl(p
->fd
, IXJCTL_PSTN_SET_STATE
, PSTN_OFF_HOOK
);
278 ast_log(LOG_WARNING
, "Unknown digit '%c'\n", digit
);
281 ast_debug(1, "Dialed %d\n", outdigit
);
282 ioctl(p
->fd
, PHONE_PLAY_TONE
, outdigit
);
287 static int phone_call(struct ast_channel
*ast
, char *dest
, int timeout
)
292 struct timeval UtcTime
= ast_tvnow();
296 ast_localtime(&UtcTime
, &tm
, NULL
);
298 memset(&cid
, 0, sizeof(PHONE_CID
));
300 snprintf(cid
.month
, sizeof(cid
.month
), "%02d",(tm
.tm_mon
+ 1));
301 snprintf(cid
.day
, sizeof(cid
.day
), "%02d", tm
.tm_mday
);
302 snprintf(cid
.hour
, sizeof(cid
.hour
), "%02d", tm
.tm_hour
);
303 snprintf(cid
.min
, sizeof(cid
.min
), "%02d", tm
.tm_min
);
305 /* the standard format of ast->callerid is: "name" <number>, but not always complete */
306 if (ast_strlen_zero(ast
->cid
.cid_name
))
307 strcpy(cid
.name
, DEFAULT_CALLER_ID
);
309 ast_copy_string(cid
.name
, ast
->cid
.cid_name
, sizeof(cid
.name
));
311 if (ast
->cid
.cid_num
)
312 ast_copy_string(cid
.number
, ast
->cid
.cid_num
, sizeof(cid
.number
));
316 if ((ast
->_state
!= AST_STATE_DOWN
) && (ast
->_state
!= AST_STATE_RESERVED
)) {
317 ast_log(LOG_WARNING
, "phone_call called on %s, neither down nor reserved\n", ast
->name
);
320 ast_debug(1, "Ringing %s on %s (%d)\n", dest
, ast
->name
, ast
->fds
[0]);
322 start
= IXJ_PHONE_RING_START(cid
);
326 if (p
->mode
== MODE_FXS
) {
327 char *digit
= strchr(dest
, '/');
332 phone_digit_end(ast
, *digit
++, 0);
336 ast_setstate(ast
, AST_STATE_RINGING
);
337 ast_queue_control(ast
, AST_CONTROL_RINGING
);
341 static int phone_hangup(struct ast_channel
*ast
)
345 ast_debug(1, "phone_hangup(%s)\n", ast
->name
);
346 if (!ast
->tech_pvt
) {
347 ast_log(LOG_WARNING
, "Asked to hangup channel not connected\n");
350 /* XXX Is there anything we can do to really hang up except stop recording? */
351 ast_setstate(ast
, AST_STATE_DOWN
);
352 if (ioctl(p
->fd
, PHONE_REC_STOP
))
353 ast_log(LOG_WARNING
, "Failed to stop recording\n");
354 if (ioctl(p
->fd
, PHONE_PLAY_STOP
))
355 ast_log(LOG_WARNING
, "Failed to stop playing\n");
356 if (ioctl(p
->fd
, PHONE_RING_STOP
))
357 ast_log(LOG_WARNING
, "Failed to stop ringing\n");
358 if (ioctl(p
->fd
, PHONE_CPT_STOP
))
359 ast_log(LOG_WARNING
, "Failed to stop sounds\n");
361 /* If it's an FXO, hang them up */
362 if (p
->mode
== MODE_FXO
) {
363 if (ioctl(p
->fd
, PHONE_PSTN_SET_STATE
, PSTN_ON_HOOK
))
364 ast_debug(1, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n",ast
->name
, strerror(errno
));
367 /* If they're off hook, give a busy signal */
368 if (ioctl(p
->fd
, PHONE_HOOKSTATE
)) {
369 ast_debug(1, "Got hunghup, giving busy signal\n");
370 ioctl(p
->fd
, PHONE_BUSY
);
378 memset(p
->ext
, 0, sizeof(p
->ext
));
379 ((struct phone_pvt
*)(ast
->tech_pvt
))->owner
= NULL
;
380 ast_module_unref(ast_module_info
->self
);
381 ast_verb(3, "Hungup '%s'\n", ast
->name
);
382 ast
->tech_pvt
= NULL
;
383 ast_setstate(ast
, AST_STATE_DOWN
);
388 static int phone_setup(struct ast_channel
*ast
)
392 ioctl(p
->fd
, PHONE_CPT_STOP
);
393 /* Nothing to answering really, just start recording */
394 if (ast
->rawreadformat
== AST_FORMAT_G729A
) {
396 ioctl(p
->fd
, PHONE_REC_STOP
);
397 if (p
->lastinput
!= AST_FORMAT_G729A
) {
398 p
->lastinput
= AST_FORMAT_G729A
;
399 if (ioctl(p
->fd
, PHONE_REC_CODEC
, G729
)) {
400 ast_log(LOG_WARNING
, "Failed to set codec to g729\n");
404 } else if (ast
->rawreadformat
== AST_FORMAT_G723_1
) {
405 ioctl(p
->fd
, PHONE_REC_STOP
);
406 if (p
->lastinput
!= AST_FORMAT_G723_1
) {
407 p
->lastinput
= AST_FORMAT_G723_1
;
408 if (ioctl(p
->fd
, PHONE_REC_CODEC
, G723_63
)) {
409 ast_log(LOG_WARNING
, "Failed to set codec to g723.1\n");
413 } else if (ast
->rawreadformat
== AST_FORMAT_SLINEAR
) {
414 ioctl(p
->fd
, PHONE_REC_STOP
);
415 if (p
->lastinput
!= AST_FORMAT_SLINEAR
) {
416 p
->lastinput
= AST_FORMAT_SLINEAR
;
417 if (ioctl(p
->fd
, PHONE_REC_CODEC
, LINEAR16
)) {
418 ast_log(LOG_WARNING
, "Failed to set codec to signed linear 16\n");
422 } else if (ast
->rawreadformat
== AST_FORMAT_ULAW
) {
423 ioctl(p
->fd
, PHONE_REC_STOP
);
424 if (p
->lastinput
!= AST_FORMAT_ULAW
) {
425 p
->lastinput
= AST_FORMAT_ULAW
;
426 if (ioctl(p
->fd
, PHONE_REC_CODEC
, ULAW
)) {
427 ast_log(LOG_WARNING
, "Failed to set codec to uLaw\n");
431 } else if (p
->mode
== MODE_FXS
) {
432 ioctl(p
->fd
, PHONE_REC_STOP
);
433 if (p
->lastinput
!= ast
->rawreadformat
) {
434 p
->lastinput
= ast
->rawreadformat
;
435 if (ioctl(p
->fd
, PHONE_REC_CODEC
, ast
->rawreadformat
)) {
436 ast_log(LOG_WARNING
, "Failed to set codec to %d\n",
442 ast_log(LOG_WARNING
, "Can't do format %s\n", ast_getformatname(ast
->rawreadformat
));
445 if (ioctl(p
->fd
, PHONE_REC_START
)) {
446 ast_log(LOG_WARNING
, "Failed to start recording\n");
449 /* set the DTMF times (the default is too short) */
450 ioctl(p
->fd
, PHONE_SET_TONE_ON_TIME
, 300);
451 ioctl(p
->fd
, PHONE_SET_TONE_OFF_TIME
, 200);
455 static int phone_answer(struct ast_channel
*ast
)
459 /* In case it's a LineJack, take it off hook */
460 if (p
->mode
== MODE_FXO
) {
461 if (ioctl(p
->fd
, PHONE_PSTN_SET_STATE
, PSTN_OFF_HOOK
))
462 ast_debug(1, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n", ast
->name
, strerror(errno
));
464 ast_debug(1, "Took linejack off hook\n");
467 ast_debug(1, "phone_answer(%s)\n", ast
->name
);
469 ast_setstate(ast
, AST_STATE_UP
);
474 static char phone_2digit(char c
)
480 else if ((c
< 10) && (c
>= 0))
487 static struct ast_frame
*phone_exception(struct ast_channel
*ast
)
490 union telephony_exception phonee
;
491 struct phone_pvt
*p
= ast
->tech_pvt
;
494 /* Some nice norms */
497 p
->fr
.data
.ptr
= NULL
;
501 p
->fr
.delivery
= ast_tv(0,0);
503 phonee
.bytes
= ioctl(p
->fd
, PHONE_EXCEPTION
);
504 if (phonee
.bits
.dtmf_ready
) {
505 ast_debug(1, "phone_exception(): DTMF\n");
507 /* We've got a digit -- Just handle this nicely and easily */
508 digit
= ioctl(p
->fd
, PHONE_GET_DTMF_ASCII
);
509 p
->fr
.subclass
= digit
;
510 p
->fr
.frametype
= AST_FRAME_DTMF
;
513 if (phonee
.bits
.hookstate
) {
514 ast_debug(1, "Hookstate changed\n");
515 res
= ioctl(p
->fd
, PHONE_HOOKSTATE
);
516 /* See if we've gone on hook, if so, notify by returning NULL */
517 ast_debug(1, "New hookstate: %d\n", res
);
518 if (!res
&& (p
->mode
!= MODE_FXO
))
521 if (ast
->_state
== AST_STATE_RINGING
) {
522 /* They've picked up the phone */
523 p
->fr
.frametype
= AST_FRAME_CONTROL
;
524 p
->fr
.subclass
= AST_CONTROL_ANSWER
;
526 ast_setstate(ast
, AST_STATE_UP
);
529 ast_log(LOG_WARNING
, "Got off hook in weird state %d\n", ast
->_state
);
533 if (phonee
.bits
.pstn_ring
)
534 ast_verbose("Unit is ringing\n");
535 if (phonee
.bits
.caller_id
) {
536 ast_verbose("We have caller ID\n");
538 if (phonee
.bits
.pstn_wink
)
539 ast_verbose("Detected Wink\n");
541 /* Strange -- nothing there.. */
542 p
->fr
.frametype
= AST_FRAME_NULL
;
547 static struct ast_frame
*phone_read(struct ast_channel
*ast
)
550 struct phone_pvt
*p
= ast
->tech_pvt
;
553 /* Some nice norms */
556 p
->fr
.data
.ptr
= NULL
;
560 p
->fr
.delivery
= ast_tv(0,0);
562 /* Try to read some data... */
564 res
= read(p
->fd
, p
->buf
, PHONE_MAX_BUF
);
565 ast_clear_flag(ast
, AST_FLAG_BLOCKING
);
568 if (errno
== EAGAIN
) {
569 ast_log(LOG_WARNING
, "Null frame received\n");
570 p
->fr
.frametype
= AST_FRAME_NULL
;
575 ast_log(LOG_WARNING
, "Error reading: %s\n", strerror(errno
));
578 p
->fr
.data
.ptr
= p
->buf
;
579 if (p
->mode
!= MODE_FXS
)
580 switch(p
->buf
[0] & 0x3) {
587 /* VAD/CNG, only send two words */
593 p
->fr
.frametype
= p
->lastinput
<= AST_FORMAT_AUDIO_MASK
?
595 p
->lastinput
<= AST_FORMAT_PNG
? AST_FRAME_IMAGE
597 p
->fr
.subclass
= p
->lastinput
;
598 p
->fr
.offset
= AST_FRIENDLY_OFFSET
;
599 /* Byteswap from little-endian to native-endian */
600 if (p
->fr
.subclass
== AST_FORMAT_SLINEAR
)
601 ast_frame_byteswap_le(&p
->fr
);
605 static int phone_write_buf(struct phone_pvt
*p
, const char *buf
, int len
, int frlen
, int swap
)
608 /* Store as much of the buffer as we can, then write fixed frames */
609 int space
= sizeof(p
->obuf
) - p
->obuflen
;
610 /* Make sure we have enough buffer space to store the frame */
614 ast_swapcopy_samples(p
->obuf
+p
->obuflen
, buf
, len
/2);
616 memcpy(p
->obuf
+ p
->obuflen
, buf
, len
);
618 while(p
->obuflen
> frlen
) {
619 res
= write(p
->fd
, p
->obuf
, frlen
);
623 * Card is in non-blocking mode now and it works well now, but there are
624 * lot of messages like this. So, this message is temporarily disabled.
628 ast_log(LOG_WARNING
, "Only wrote %d of %d bytes\n", res
, frlen
);
632 /* Move memory if necessary */
634 memmove(p
->obuf
, p
->obuf
+ frlen
, p
->obuflen
);
639 static int phone_send_text(struct ast_channel
*ast
, const char *text
)
641 int length
= strlen(text
);
642 return phone_write_buf(ast
->tech_pvt
, text
, length
, length
, 0) ==
646 static int phone_write(struct ast_channel
*ast
, struct ast_frame
*frame
)
648 struct phone_pvt
*p
= ast
->tech_pvt
;
656 /* Write a frame of (presumably voice) data */
657 if (frame
->frametype
!= AST_FRAME_VOICE
&& p
->mode
!= MODE_FXS
) {
658 if (frame
->frametype
!= AST_FRAME_IMAGE
)
659 ast_log(LOG_WARNING
, "Don't know what to do with frame type '%d'\n", frame
->frametype
);
662 if (!(frame
->subclass
&
663 (AST_FORMAT_G723_1
| AST_FORMAT_SLINEAR
| AST_FORMAT_ULAW
| AST_FORMAT_G729A
)) &&
664 p
->mode
!= MODE_FXS
) {
665 ast_log(LOG_WARNING
, "Cannot handle frames in %d format\n", frame
->subclass
);
669 /* If we're not in up mode, go into up mode now */
670 if (ast
->_state
!= AST_STATE_UP
) {
671 ast_setstate(ast
, AST_STATE_UP
);
675 if (ast
->_state
!= AST_STATE_UP
) {
676 /* Don't try tos end audio on-hook */
680 if (frame
->subclass
== AST_FORMAT_G729A
) {
681 if (p
->lastformat
!= AST_FORMAT_G729A
) {
682 ioctl(p
->fd
, PHONE_PLAY_STOP
);
683 ioctl(p
->fd
, PHONE_REC_STOP
);
684 if (ioctl(p
->fd
, PHONE_PLAY_CODEC
, G729
)) {
685 ast_log(LOG_WARNING
, "Unable to set G729 mode\n");
688 if (ioctl(p
->fd
, PHONE_REC_CODEC
, G729
)) {
689 ast_log(LOG_WARNING
, "Unable to set G729 mode\n");
692 p
->lastformat
= AST_FORMAT_G729A
;
693 p
->lastinput
= AST_FORMAT_G729A
;
694 /* Reset output buffer */
698 if (frame
->datalen
> 80) {
699 ast_log(LOG_WARNING
, "Frame size too large for G.729 (%d bytes)\n", frame
->datalen
);
703 } else if (frame
->subclass
== AST_FORMAT_G723_1
) {
704 if (p
->lastformat
!= AST_FORMAT_G723_1
) {
705 ioctl(p
->fd
, PHONE_PLAY_STOP
);
706 ioctl(p
->fd
, PHONE_REC_STOP
);
707 if (ioctl(p
->fd
, PHONE_PLAY_CODEC
, G723_63
)) {
708 ast_log(LOG_WARNING
, "Unable to set G723.1 mode\n");
711 if (ioctl(p
->fd
, PHONE_REC_CODEC
, G723_63
)) {
712 ast_log(LOG_WARNING
, "Unable to set G723.1 mode\n");
715 p
->lastformat
= AST_FORMAT_G723_1
;
716 p
->lastinput
= AST_FORMAT_G723_1
;
717 /* Reset output buffer */
721 if (frame
->datalen
> 24) {
722 ast_log(LOG_WARNING
, "Frame size too large for G.723.1 (%d bytes)\n", frame
->datalen
);
726 } else if (frame
->subclass
== AST_FORMAT_SLINEAR
) {
727 if (p
->lastformat
!= AST_FORMAT_SLINEAR
) {
728 ioctl(p
->fd
, PHONE_PLAY_STOP
);
729 ioctl(p
->fd
, PHONE_REC_STOP
);
730 if (ioctl(p
->fd
, PHONE_PLAY_CODEC
, LINEAR16
)) {
731 ast_log(LOG_WARNING
, "Unable to set 16-bit linear mode\n");
734 if (ioctl(p
->fd
, PHONE_REC_CODEC
, LINEAR16
)) {
735 ast_log(LOG_WARNING
, "Unable to set 16-bit linear mode\n");
738 p
->lastformat
= AST_FORMAT_SLINEAR
;
739 p
->lastinput
= AST_FORMAT_SLINEAR
;
741 /* Reset output buffer */
745 } else if (frame
->subclass
== AST_FORMAT_ULAW
) {
746 if (p
->lastformat
!= AST_FORMAT_ULAW
) {
747 ioctl(p
->fd
, PHONE_PLAY_STOP
);
748 ioctl(p
->fd
, PHONE_REC_STOP
);
749 if (ioctl(p
->fd
, PHONE_PLAY_CODEC
, ULAW
)) {
750 ast_log(LOG_WARNING
, "Unable to set uLaw mode\n");
753 if (ioctl(p
->fd
, PHONE_REC_CODEC
, ULAW
)) {
754 ast_log(LOG_WARNING
, "Unable to set uLaw mode\n");
757 p
->lastformat
= AST_FORMAT_ULAW
;
758 p
->lastinput
= AST_FORMAT_ULAW
;
760 /* Reset output buffer */
765 if (p
->lastformat
!= frame
->subclass
) {
766 ioctl(p
->fd
, PHONE_PLAY_STOP
);
767 ioctl(p
->fd
, PHONE_REC_STOP
);
768 if (ioctl(p
->fd
, PHONE_PLAY_CODEC
, frame
->subclass
)) {
769 ast_log(LOG_WARNING
, "Unable to set %d mode\n",
773 if (ioctl(p
->fd
, PHONE_REC_CODEC
, frame
->subclass
)) {
774 ast_log(LOG_WARNING
, "Unable to set %d mode\n",
778 p
->lastformat
= frame
->subclass
;
779 p
->lastinput
= frame
->subclass
;
781 /* Reset output buffer */
787 ioctl(p
->fd
, PHONE_REC_DEPTH
, 3);
788 ioctl(p
->fd
, PHONE_PLAY_DEPTH
, 3);
789 if (ioctl(p
->fd
, PHONE_PLAY_START
)) {
790 ast_log(LOG_WARNING
, "Failed to start playback\n");
793 if (ioctl(p
->fd
, PHONE_REC_START
)) {
794 ast_log(LOG_WARNING
, "Failed to start recording\n");
798 /* If we get here, we have a frame of Appropriate data */
800 pos
= frame
->data
.ptr
;
801 while(sofar
< frame
->datalen
) {
802 /* Write in no more than maxfr sized frames */
803 expected
= frame
->datalen
- sofar
;
804 if (maxfr
< expected
)
806 /* XXX Internet Phone Jack does not handle the 4-byte VAD frame properly! XXX
807 we have to pad it to 24 bytes still. */
808 if (frame
->datalen
== 4) {
809 if (p
->silencesupression
) {
810 memset(tmpbuf
+ 4, 0, sizeof(tmpbuf
) - 4);
811 memcpy(tmpbuf
, frame
->data
.ptr
, 4);
813 res
= phone_write_buf(p
, tmpbuf
, expected
, maxfr
, 0);
819 #if __BYTE_ORDER == __BIG_ENDIAN
820 if (frame
->subclass
== AST_FORMAT_SLINEAR
)
821 swap
= 1; /* Swap big-endian samples to little-endian as we copy */
823 res
= phone_write_buf(p
, pos
, expected
, maxfr
, swap
);
825 if (res
!= expected
) {
826 if ((errno
!= EAGAIN
) && (errno
!= EINTR
)) {
828 ast_log(LOG_WARNING
, "Write returned error (%s)\n", strerror(errno
));
830 * Card is in non-blocking mode now and it works well now, but there are
831 * lot of messages like this. So, this message is temporarily disabled.
835 ast_log(LOG_WARNING
, "Only wrote %d of %d bytes\n", res
, frame
->datalen
);
838 } else /* Pretend it worked */
847 static struct ast_channel
*phone_new(struct phone_pvt
*i
, int state
, char *cntx
)
849 struct ast_channel
*tmp
;
850 struct phone_codec_data queried_codec
;
851 tmp
= ast_channel_alloc(1, state
, i
->cid_num
, i
->cid_name
, "", i
->ext
, i
->context
, 0, "Phone/%s", i
->dev
+ 5);
853 tmp
->tech
= cur_tech
;
854 ast_channel_set_fd(tmp
, 0, i
->fd
);
855 /* XXX Switching formats silently causes kernel panics XXX */
856 if (i
->mode
== MODE_FXS
&&
857 ioctl(i
->fd
, PHONE_QUERY_CODEC
, &queried_codec
) == 0) {
858 if (queried_codec
.type
== LINEAR16
)
861 tmp
->rawwriteformat
=
866 tmp
->rawwriteformat
=
867 prefformat
& ~AST_FORMAT_SLINEAR
;
871 tmp
->nativeformats
= prefformat
;
872 tmp
->rawreadformat
= prefformat
;
873 tmp
->rawwriteformat
= prefformat
;
875 /* no need to call ast_setstate: the channel_alloc already did its job */
876 if (state
== AST_STATE_RING
)
879 ast_copy_string(tmp
->context
, cntx
, sizeof(tmp
->context
));
880 if (!ast_strlen_zero(i
->ext
))
881 ast_copy_string(tmp
->exten
, i
->ext
, sizeof(tmp
->exten
));
883 strcpy(tmp
->exten
, "s");
884 if (!ast_strlen_zero(i
->language
))
885 ast_string_field_set(tmp
, language
, i
->language
);
887 /* Don't use ast_set_callerid() here because it will
888 * generate a NewCallerID event before the NewChannel event */
889 tmp
->cid
.cid_ani
= ast_strdup(i
->cid_num
);
892 ast_module_ref(ast_module_info
->self
);
893 if (state
!= AST_STATE_DOWN
) {
894 if (state
== AST_STATE_RING
) {
895 ioctl(tmp
->fds
[0], PHONE_RINGBACK
);
898 if (ast_pbx_start(tmp
)) {
899 ast_log(LOG_WARNING
, "Unable to start PBX on %s\n", tmp
->name
);
904 ast_log(LOG_WARNING
, "Unable to allocate channel structure\n");
908 static void phone_mini_packet(struct phone_pvt
*i
)
912 /* Ignore stuff we read... */
913 res
= read(i
->fd
, buf
, sizeof(buf
));
915 ast_log(LOG_WARNING
, "Read returned %d: %s\n", res
, strerror(errno
));
920 static void phone_check_exception(struct phone_pvt
*i
)
923 char digit
[2] = {0 , 0};
924 union telephony_exception phonee
;
925 /* XXX Do something XXX */
927 ast_debug(1, "Exception!\n");
929 phonee
.bytes
= ioctl(i
->fd
, PHONE_EXCEPTION
);
930 if (phonee
.bits
.dtmf_ready
) {
931 digit
[0] = ioctl(i
->fd
, PHONE_GET_DTMF_ASCII
);
932 if (i
->mode
== MODE_DIALTONE
|| i
->mode
== MODE_FXS
|| i
->mode
== MODE_SIGMA
) {
933 ioctl(i
->fd
, PHONE_PLAY_STOP
);
934 ioctl(i
->fd
, PHONE_REC_STOP
);
935 ioctl(i
->fd
, PHONE_CPT_STOP
);
937 if (strlen(i
->ext
) < AST_MAX_EXTENSION
- 1)
938 strncat(i
->ext
, digit
, sizeof(i
->ext
) - strlen(i
->ext
) - 1);
939 if ((i
->mode
!= MODE_FXS
||
940 !(phonee
.bytes
= ioctl(i
->fd
, PHONE_EXCEPTION
)) ||
941 !phonee
.bits
.dtmf_ready
) &&
942 ast_exists_extension(NULL
, i
->context
, i
->ext
, 1, i
->cid_num
)) {
943 /* It's a valid extension in its context, get moving! */
944 phone_new(i
, AST_STATE_RING
, i
->context
);
945 /* No need to restart monitor, we are the monitor */
946 } else if (!ast_canmatch_extension(NULL
, i
->context
, i
->ext
, 1, i
->cid_num
)) {
947 /* There is nothing in the specified extension that can match anymore.
949 if (ast_exists_extension(NULL
, "default", i
->ext
, 1, i
->cid_num
)) {
950 /* Check the default, too... */
951 phone_new(i
, AST_STATE_RING
, "default");
952 /* XXX This should probably be justified better XXX */
953 } else if (!ast_canmatch_extension(NULL
, "default", i
->ext
, 1, i
->cid_num
)) {
954 /* It's not a valid extension, give a busy signal */
955 ast_debug(1, "%s can't match anything in %s or default\n", i
->ext
, i
->context
);
956 ioctl(i
->fd
, PHONE_BUSY
);
961 ast_verbose("Extension is %s\n", i
->ext
);
965 if (phonee
.bits
.hookstate
) {
966 offhook
= ioctl(i
->fd
, PHONE_HOOKSTATE
);
968 if (i
->mode
== MODE_IMMEDIATE
) {
969 phone_new(i
, AST_STATE_RING
, i
->context
);
970 } else if (i
->mode
== MODE_DIALTONE
) {
971 ast_module_ref(ast_module_info
->self
);
972 /* Reset the extension */
974 /* Play the dialtone */
976 ioctl(i
->fd
, PHONE_PLAY_STOP
);
977 ioctl(i
->fd
, PHONE_PLAY_CODEC
, ULAW
);
978 ioctl(i
->fd
, PHONE_PLAY_START
);
980 } else if (i
->mode
== MODE_SIGMA
) {
981 ast_module_ref(ast_module_info
->self
);
982 /* Reset the extension */
984 /* Play the dialtone */
986 ioctl(i
->fd
, PHONE_DIALTONE
);
990 ast_module_unref(ast_module_info
->self
);
991 memset(i
->ext
, 0, sizeof(i
->ext
));
994 ioctl(i
->fd
, PHONE_CPT_STOP
);
997 ioctl(i
->fd
, PHONE_PLAY_STOP
);
998 ioctl(i
->fd
, PHONE_REC_STOP
);
1003 if (phonee
.bits
.pstn_ring
) {
1004 ast_verbose("Unit is ringing\n");
1005 phone_new(i
, AST_STATE_RING
, i
->context
);
1007 if (phonee
.bits
.caller_id
)
1008 ast_verbose("We have caller ID\n");
1013 static void *do_monitor(void *data
)
1017 struct phone_pvt
*i
;
1019 /* The tone we're playing this round */
1020 struct timeval wait
= {0,0};
1022 /* This thread monitors all the frame relay interfaces which are not yet in use
1023 (and thus do not have a separate thread) indefinitely */
1025 /* Don't let anybody kill us right away. Nobody should lock the interface list
1026 and wait for the monitor list, but the other way around is okay. */
1027 /* Lock the interface list */
1028 if (ast_mutex_lock(&iflock
)) {
1029 ast_log(LOG_ERROR
, "Unable to grab interface lock\n");
1032 /* Build the stuff we're going to select on, that is the socket of every
1033 phone_pvt that does not have an associated owner channel */
1040 if (FD_ISSET(i
->fd
, &rfds
))
1041 ast_log(LOG_WARNING
, "Descriptor %d appears twice (%s)?\n", i
->fd
, i
->dev
);
1043 /* This needs to be watched, as it lacks an owner */
1044 FD_SET(i
->fd
, &rfds
);
1045 FD_SET(i
->fd
, &efds
);
1048 if (i
->dialtone
&& i
->mode
!= MODE_SIGMA
) {
1049 /* Remember we're going to have to come back and play
1051 if (ast_tvzero(wait
)) {
1052 /* If we're due for a dialtone, play one */
1053 if (write(i
->fd
, DialTone
+ tonepos
, 240) != 240)
1054 ast_log(LOG_WARNING
, "Dial tone write error\n");
1062 /* Okay, now that we know what to do, release the interface lock */
1063 ast_mutex_unlock(&iflock
);
1065 /* Wait indefinitely for something to happen */
1066 if (dotone
&& i
&& i
->mode
!= MODE_SIGMA
) {
1067 /* If we're ready to recycle the time, set it to 30 ms */
1069 if (tonepos
>= sizeof(DialTone
))
1071 if (ast_tvzero(wait
)) {
1072 wait
= ast_tv(30000, 0);
1074 res
= ast_select(n
+ 1, &rfds
, NULL
, &efds
, &wait
);
1076 res
= ast_select(n
+ 1, &rfds
, NULL
, &efds
, NULL
);
1080 /* Okay, select has finished. Let's see what happened. */
1082 ast_debug(1, "select return %d: %s\n", res
, strerror(errno
));
1085 /* If there are no fd's changed, just continue, it's probably time
1086 to play some more dialtones */
1089 /* Alright, lock the interface list again, and let's look and see what has
1091 if (ast_mutex_lock(&iflock
)) {
1092 ast_log(LOG_WARNING
, "Unable to lock the interface list\n");
1097 for(; i
; i
=i
->next
) {
1098 if (FD_ISSET(i
->fd
, &rfds
)) {
1102 phone_mini_packet(i
);
1104 if (FD_ISSET(i
->fd
, &efds
)) {
1108 phone_check_exception(i
);
1111 ast_mutex_unlock(&iflock
);
1117 static int restart_monitor()
1119 /* If we're supposed to be stopped -- stay stopped */
1120 if (monitor_thread
== AST_PTHREADT_STOP
)
1122 if (ast_mutex_lock(&monlock
)) {
1123 ast_log(LOG_WARNING
, "Unable to lock monitor\n");
1126 if (monitor_thread
== pthread_self()) {
1127 ast_mutex_unlock(&monlock
);
1128 ast_log(LOG_WARNING
, "Cannot kill myself\n");
1131 if (monitor_thread
!= AST_PTHREADT_NULL
) {
1132 if (ast_mutex_lock(&iflock
)) {
1133 ast_mutex_unlock(&monlock
);
1134 ast_log(LOG_WARNING
, "Unable to lock the interface list\n");
1138 while (pthread_kill(monitor_thread
, SIGURG
) == 0)
1140 pthread_join(monitor_thread
, NULL
);
1141 ast_mutex_unlock(&iflock
);
1144 /* Start a new monitor */
1145 if (ast_pthread_create_background(&monitor_thread
, NULL
, do_monitor
, NULL
) < 0) {
1146 ast_mutex_unlock(&monlock
);
1147 ast_log(LOG_ERROR
, "Unable to start monitor thread.\n");
1150 ast_mutex_unlock(&monlock
);
1154 static struct phone_pvt
*mkif(const char *iface
, int mode
, int txgain
, int rxgain
)
1156 /* Make a phone_pvt structure for this interface */
1157 struct phone_pvt
*tmp
;
1160 tmp
= ast_calloc(1, sizeof(*tmp
));
1162 tmp
->fd
= open(iface
, O_RDWR
);
1164 ast_log(LOG_WARNING
, "Unable to open '%s'\n", iface
);
1168 if (mode
== MODE_FXO
) {
1169 if (ioctl(tmp
->fd
, IXJCTL_PORT
, PORT_PSTN
)) {
1170 ast_debug(1, "Unable to set port to PSTN\n");
1173 if (ioctl(tmp
->fd
, IXJCTL_PORT
, PORT_POTS
))
1174 if (mode
!= MODE_FXS
)
1175 ast_debug(1, "Unable to set port to POTS\n");
1177 ioctl(tmp
->fd
, PHONE_PLAY_STOP
);
1178 ioctl(tmp
->fd
, PHONE_REC_STOP
);
1179 ioctl(tmp
->fd
, PHONE_RING_STOP
);
1180 ioctl(tmp
->fd
, PHONE_CPT_STOP
);
1181 if (ioctl(tmp
->fd
, PHONE_PSTN_SET_STATE
, PSTN_ON_HOOK
))
1182 ast_debug(1, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n",iface
, strerror(errno
));
1183 if (echocancel
!= AEC_OFF
)
1184 ioctl(tmp
->fd
, IXJCTL_AEC_START
, echocancel
);
1185 if (silencesupression
)
1186 tmp
->silencesupression
= 1;
1188 ioctl(tmp
->fd
, PHONE_VAD
, tmp
->silencesupression
);
1191 flags
= fcntl(tmp
->fd
, F_GETFL
);
1192 fcntl(tmp
->fd
, F_SETFL
, flags
| O_NONBLOCK
);
1194 tmp
->lastformat
= -1;
1195 tmp
->lastinput
= -1;
1197 memset(tmp
->ext
, 0, sizeof(tmp
->ext
));
1198 ast_copy_string(tmp
->language
, language
, sizeof(tmp
->language
));
1199 ast_copy_string(tmp
->dev
, iface
, sizeof(tmp
->dev
));
1200 ast_copy_string(tmp
->context
, context
, sizeof(tmp
->context
));
1205 ast_copy_string(tmp
->cid_num
, cid_num
, sizeof(tmp
->cid_num
));
1206 ast_copy_string(tmp
->cid_name
, cid_name
, sizeof(tmp
->cid_name
));
1207 tmp
->txgain
= txgain
;
1208 ioctl(tmp
->fd
, PHONE_PLAY_VOLUME
, tmp
->txgain
);
1209 tmp
->rxgain
= rxgain
;
1210 ioctl(tmp
->fd
, PHONE_REC_VOLUME
, tmp
->rxgain
);
1215 static struct ast_channel
*phone_request(const char *type
, int format
, void *data
, int *cause
)
1218 struct phone_pvt
*p
;
1219 struct ast_channel
*tmp
= NULL
;
1222 /* Search for an unowned channel */
1223 if (ast_mutex_lock(&iflock
)) {
1224 ast_log(LOG_ERROR
, "Unable to lock interface list???\n");
1229 if (p
->mode
== MODE_FXS
||
1230 format
& (AST_FORMAT_G729A
| AST_FORMAT_G723_1
| AST_FORMAT_SLINEAR
| AST_FORMAT_ULAW
)) {
1231 size_t length
= strlen(p
->dev
+ 5);
1232 if (strncmp(name
, p
->dev
+ 5, length
) == 0 &&
1233 !isalnum(name
[length
])) {
1235 tmp
= phone_new(p
, AST_STATE_DOWN
, p
->context
);
1238 *cause
= AST_CAUSE_BUSY
;
1243 ast_mutex_unlock(&iflock
);
1247 format
&= (AST_FORMAT_G729A
| AST_FORMAT_G723_1
| AST_FORMAT_SLINEAR
| AST_FORMAT_ULAW
);
1249 ast_log(LOG_NOTICE
, "Asked to get a channel of unsupported format '%d'\n", oldformat
);
1256 /* parse gain value from config file */
1257 static int parse_gain_value(const char *gain_type
, const char *value
)
1261 /* try to scan number */
1262 if (sscanf(value
, "%f", &gain
) != 1)
1264 ast_log(LOG_ERROR
, "Invalid %s value '%s' in '%s' config\n",
1265 value
, gain_type
, config
);
1266 return DEFAULT_GAIN
;
1269 /* multiplicate gain by 1.0 gain value */
1270 gain
= gain
* (float)DEFAULT_GAIN
;
1273 if (value
[strlen(value
) - 1] == '%')
1274 return (int)(gain
/ (float)100);
1279 static int __unload_module(void)
1281 struct phone_pvt
*p
, *pl
;
1282 /* First, take us out of the channel loop */
1284 ast_channel_unregister(cur_tech
);
1285 if (!ast_mutex_lock(&iflock
)) {
1286 /* Hangup all interfaces if they have an owner */
1290 ast_softhangup(p
->owner
, AST_SOFTHANGUP_APPUNLOAD
);
1294 ast_mutex_unlock(&iflock
);
1296 ast_log(LOG_WARNING
, "Unable to lock the monitor\n");
1299 if (!ast_mutex_lock(&monlock
)) {
1300 if (monitor_thread
> AST_PTHREADT_NULL
) {
1302 while (pthread_kill(monitor_thread
, SIGURG
) == 0)
1304 pthread_join(monitor_thread
, NULL
);
1306 monitor_thread
= AST_PTHREADT_STOP
;
1307 ast_mutex_unlock(&monlock
);
1309 ast_log(LOG_WARNING
, "Unable to lock the monitor\n");
1313 if (!ast_mutex_lock(&iflock
)) {
1314 /* Destroy all the interfaces and free their memory */
1317 /* Close the socket, assuming it's real */
1322 /* Free associated memory */
1326 ast_mutex_unlock(&iflock
);
1328 ast_log(LOG_WARNING
, "Unable to lock the monitor\n");
1335 static int unload_module(void)
1337 return __unload_module();
1340 static int load_module(void)
1342 struct ast_config
*cfg
;
1343 struct ast_variable
*v
;
1344 struct phone_pvt
*tmp
;
1345 int mode
= MODE_IMMEDIATE
;
1346 int txgain
= DEFAULT_GAIN
, rxgain
= DEFAULT_GAIN
; /* default gain 1.0 */
1347 struct ast_flags config_flags
= { 0 };
1349 cfg
= ast_config_load(config
, config_flags
);
1351 /* We *must* have a config file otherwise stop immediately */
1353 ast_log(LOG_ERROR
, "Unable to load config %s\n", config
);
1354 return AST_MODULE_LOAD_DECLINE
;
1356 if (ast_mutex_lock(&iflock
)) {
1357 /* It's a little silly to lock it, but we mind as well just to be sure */
1358 ast_log(LOG_ERROR
, "Unable to lock interface list???\n");
1359 return AST_MODULE_LOAD_FAILURE
;
1361 v
= ast_variable_browse(cfg
, "interfaces");
1363 /* Create the interface list */
1364 if (!strcasecmp(v
->name
, "device")) {
1365 tmp
= mkif(v
->value
, mode
, txgain
, rxgain
);
1371 ast_log(LOG_ERROR
, "Unable to register channel '%s'\n", v
->value
);
1372 ast_config_destroy(cfg
);
1373 ast_mutex_unlock(&iflock
);
1375 return AST_MODULE_LOAD_FAILURE
;
1377 } else if (!strcasecmp(v
->name
, "silencesupression")) {
1378 silencesupression
= ast_true(v
->value
);
1379 } else if (!strcasecmp(v
->name
, "language")) {
1380 ast_copy_string(language
, v
->value
, sizeof(language
));
1381 } else if (!strcasecmp(v
->name
, "callerid")) {
1382 ast_callerid_split(v
->value
, cid_name
, sizeof(cid_name
), cid_num
, sizeof(cid_num
));
1383 } else if (!strcasecmp(v
->name
, "mode")) {
1384 if (!strncasecmp(v
->value
, "di", 2))
1385 mode
= MODE_DIALTONE
;
1386 else if (!strncasecmp(v
->value
, "sig", 3))
1388 else if (!strncasecmp(v
->value
, "im", 2))
1389 mode
= MODE_IMMEDIATE
;
1390 else if (!strncasecmp(v
->value
, "fxs", 3)) {
1392 prefformat
= 0x01ff0000; /* All non-voice */
1394 else if (!strncasecmp(v
->value
, "fx", 2))
1397 ast_log(LOG_WARNING
, "Unknown mode: %s\n", v
->value
);
1398 } else if (!strcasecmp(v
->name
, "context")) {
1399 ast_copy_string(context
, v
->value
, sizeof(context
));
1400 } else if (!strcasecmp(v
->name
, "format")) {
1401 if (!strcasecmp(v
->value
, "g729")) {
1402 prefformat
= AST_FORMAT_G729A
;
1403 } else if (!strcasecmp(v
->value
, "g723.1")) {
1404 prefformat
= AST_FORMAT_G723_1
;
1405 } else if (!strcasecmp(v
->value
, "slinear")) {
1406 if (mode
== MODE_FXS
)
1407 prefformat
|= AST_FORMAT_SLINEAR
;
1408 else prefformat
= AST_FORMAT_SLINEAR
;
1409 } else if (!strcasecmp(v
->value
, "ulaw")) {
1410 prefformat
= AST_FORMAT_ULAW
;
1412 ast_log(LOG_WARNING
, "Unknown format '%s'\n", v
->value
);
1413 } else if (!strcasecmp(v
->name
, "echocancel")) {
1414 if (!strcasecmp(v
->value
, "off")) {
1415 echocancel
= AEC_OFF
;
1416 } else if (!strcasecmp(v
->value
, "low")) {
1417 echocancel
= AEC_LOW
;
1418 } else if (!strcasecmp(v
->value
, "medium")) {
1419 echocancel
= AEC_MED
;
1420 } else if (!strcasecmp(v
->value
, "high")) {
1421 echocancel
= AEC_HIGH
;
1423 ast_log(LOG_WARNING
, "Unknown echo cancellation '%s'\n", v
->value
);
1424 } else if (!strcasecmp(v
->name
, "txgain")) {
1425 txgain
= parse_gain_value(v
->name
, v
->value
);
1426 } else if (!strcasecmp(v
->name
, "rxgain")) {
1427 rxgain
= parse_gain_value(v
->name
, v
->value
);
1431 ast_mutex_unlock(&iflock
);
1433 if (mode
== MODE_FXS
) {
1434 phone_tech_fxs
.capabilities
= prefformat
;
1435 cur_tech
= &phone_tech_fxs
;
1437 cur_tech
= (struct ast_channel_tech
*) &phone_tech
;
1439 /* Make sure we can register our Adtranphone channel type */
1441 if (ast_channel_register(cur_tech
)) {
1442 ast_log(LOG_ERROR
, "Unable to register channel class 'Phone'\n");
1443 ast_config_destroy(cfg
);
1445 return AST_MODULE_LOAD_FAILURE
;
1447 ast_config_destroy(cfg
);
1448 /* And start the monitor for the first time */
1450 return AST_MODULE_LOAD_SUCCESS
;
1453 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY
, "Linux Telephony API Support");