00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "asterisk.h"
00033
00034 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 284597 $")
00035
00036 #include <ctype.h>
00037 #include <sys/socket.h>
00038 #include <sys/time.h>
00039 #include <arpa/inet.h>
00040 #include <fcntl.h>
00041 #include <sys/ioctl.h>
00042 #include <signal.h>
00043 #ifdef HAVE_LINUX_COMPILER_H
00044 #include <linux/compiler.h>
00045 #endif
00046 #include <linux/telephony.h>
00047
00048 #include <linux/version.h>
00049 #include <linux/ixjuser.h>
00050
00051 #include "asterisk/lock.h"
00052 #include "asterisk/channel.h"
00053 #include "asterisk/config.h"
00054 #include "asterisk/module.h"
00055 #include "asterisk/pbx.h"
00056 #include "asterisk/utils.h"
00057 #include "asterisk/callerid.h"
00058 #include "asterisk/causes.h"
00059 #include "asterisk/stringfields.h"
00060 #include "asterisk/musiconhold.h"
00061
00062 #include "chan_phone.h"
00063
00064 #ifdef QTI_PHONEJACK_TJ_PCI
00065 #define QNDRV_VER 310
00066 #else
00067 #define QNDRV_VER 100
00068 #endif
00069
00070 #if QNDRV_VER > 100
00071 #ifdef __linux__
00072 #define IXJ_PHONE_RING_START(x) ioctl(p->fd, PHONE_RING_START, &x);
00073 #else
00074 #define IXJ_PHONE_RING_START(x) ioctl(p->fd, PHONE_RING_START, x);
00075 #endif
00076 #else
00077 #define IXJ_PHONE_RING_START(x) ioctl(p->fd, PHONE_RING_START, &x);
00078 #endif
00079
00080 #define DEFAULT_CALLER_ID "Unknown"
00081 #define PHONE_MAX_BUF 480
00082 #define DEFAULT_GAIN 0x100
00083
00084 static const char tdesc[] = "Standard Linux Telephony API Driver";
00085 static const char config[] = "phone.conf";
00086
00087
00088 static char context[AST_MAX_EXTENSION] = "default";
00089
00090
00091 static char language[MAX_LANGUAGE] = "";
00092
00093 static int echocancel = AEC_OFF;
00094
00095 static int silencesupression = 0;
00096
00097 static format_t prefformat = AST_FORMAT_G729A | AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW;
00098
00099
00100 AST_MUTEX_DEFINE_STATIC(iflock);
00101
00102
00103
00104 AST_MUTEX_DEFINE_STATIC(monlock);
00105
00106
00107 static unsigned int monitor;
00108
00109
00110
00111 static pthread_t monitor_thread = AST_PTHREADT_NULL;
00112
00113 static int restart_monitor(void);
00114
00115
00116
00117
00118 #define MODE_DIALTONE 1
00119 #define MODE_IMMEDIATE 2
00120 #define MODE_FXO 3
00121 #define MODE_FXS 4
00122 #define MODE_SIGMA 5
00123
00124 static struct phone_pvt {
00125 int fd;
00126 struct ast_channel *owner;
00127 int mode;
00128 format_t lastformat;
00129 format_t lastinput;
00130 int ministate;
00131 char dev[256];
00132 struct phone_pvt *next;
00133 struct ast_frame fr;
00134 char offset[AST_FRIENDLY_OFFSET];
00135 char buf[PHONE_MAX_BUF];
00136 int obuflen;
00137 int dialtone;
00138 int txgain, rxgain;
00139
00140 int cpt;
00141 int silencesupression;
00142 char context[AST_MAX_EXTENSION];
00143 char obuf[PHONE_MAX_BUF * 2];
00144 char ext[AST_MAX_EXTENSION];
00145 char language[MAX_LANGUAGE];
00146 char cid_num[AST_MAX_EXTENSION];
00147 char cid_name[AST_MAX_EXTENSION];
00148 } *iflist = NULL;
00149
00150 static char cid_num[AST_MAX_EXTENSION];
00151 static char cid_name[AST_MAX_EXTENSION];
00152
00153 static struct ast_channel *phone_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
00154 static int phone_digit_begin(struct ast_channel *ast, char digit);
00155 static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
00156 static int phone_call(struct ast_channel *ast, char *dest, int timeout);
00157 static int phone_hangup(struct ast_channel *ast);
00158 static int phone_answer(struct ast_channel *ast);
00159 static struct ast_frame *phone_read(struct ast_channel *ast);
00160 static int phone_write(struct ast_channel *ast, struct ast_frame *frame);
00161 static struct ast_frame *phone_exception(struct ast_channel *ast);
00162 static int phone_send_text(struct ast_channel *ast, const char *text);
00163 static int phone_fixup(struct ast_channel *old, struct ast_channel *new);
00164 static int phone_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
00165
00166 static const struct ast_channel_tech phone_tech = {
00167 .type = "Phone",
00168 .description = tdesc,
00169 .capabilities = AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_G729A,
00170 .requester = phone_request,
00171 .send_digit_begin = phone_digit_begin,
00172 .send_digit_end = phone_digit_end,
00173 .call = phone_call,
00174 .hangup = phone_hangup,
00175 .answer = phone_answer,
00176 .read = phone_read,
00177 .write = phone_write,
00178 .exception = phone_exception,
00179 .indicate = phone_indicate,
00180 .fixup = phone_fixup
00181 };
00182
00183 static struct ast_channel_tech phone_tech_fxs = {
00184 .type = "Phone",
00185 .description = tdesc,
00186 .requester = phone_request,
00187 .send_digit_begin = phone_digit_begin,
00188 .send_digit_end = phone_digit_end,
00189 .call = phone_call,
00190 .hangup = phone_hangup,
00191 .answer = phone_answer,
00192 .read = phone_read,
00193 .write = phone_write,
00194 .exception = phone_exception,
00195 .write_video = phone_write,
00196 .send_text = phone_send_text,
00197 .indicate = phone_indicate,
00198 .fixup = phone_fixup
00199 };
00200
00201 static struct ast_channel_tech *cur_tech;
00202
00203 static int phone_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
00204 {
00205 struct phone_pvt *p = chan->tech_pvt;
00206 int res=-1;
00207 ast_debug(1, "Requested indication %d on channel %s\n", condition, chan->name);
00208 switch(condition) {
00209 case AST_CONTROL_FLASH:
00210 ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_ON_HOOK);
00211 usleep(320000);
00212 ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_OFF_HOOK);
00213 p->lastformat = -1;
00214 res = 0;
00215 break;
00216 case AST_CONTROL_HOLD:
00217 ast_moh_start(chan, data, NULL);
00218 break;
00219 case AST_CONTROL_UNHOLD:
00220 ast_moh_stop(chan);
00221 break;
00222 case AST_CONTROL_SRCUPDATE:
00223 res = 0;
00224 break;
00225 default:
00226 ast_log(LOG_WARNING, "Condition %d is not supported on channel %s\n", condition, chan->name);
00227 }
00228 return res;
00229 }
00230
00231 static int phone_fixup(struct ast_channel *old, struct ast_channel *new)
00232 {
00233 struct phone_pvt *pvt = old->tech_pvt;
00234 if (pvt && pvt->owner == old)
00235 pvt->owner = new;
00236 return 0;
00237 }
00238
00239 static int phone_digit_begin(struct ast_channel *chan, char digit)
00240 {
00241
00242 return 0;
00243 }
00244
00245 static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
00246 {
00247 struct phone_pvt *p;
00248 int outdigit;
00249 p = ast->tech_pvt;
00250 ast_debug(1, "Dialed %c\n", digit);
00251 switch(digit) {
00252 case '0':
00253 case '1':
00254 case '2':
00255 case '3':
00256 case '4':
00257 case '5':
00258 case '6':
00259 case '7':
00260 case '8':
00261 case '9':
00262 outdigit = digit - '0';
00263 break;
00264 case '*':
00265 outdigit = 11;
00266 break;
00267 case '#':
00268 outdigit = 12;
00269 break;
00270 case 'f':
00271 case 'F':
00272 ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_ON_HOOK);
00273 usleep(320000);
00274 ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_OFF_HOOK);
00275 p->lastformat = -1;
00276 return 0;
00277 default:
00278 ast_log(LOG_WARNING, "Unknown digit '%c'\n", digit);
00279 return -1;
00280 }
00281 ast_debug(1, "Dialed %d\n", outdigit);
00282 ioctl(p->fd, PHONE_PLAY_TONE, outdigit);
00283 p->lastformat = -1;
00284 return 0;
00285 }
00286
00287 static int phone_call(struct ast_channel *ast, char *dest, int timeout)
00288 {
00289 struct phone_pvt *p;
00290
00291 PHONE_CID cid;
00292 struct timeval UtcTime = ast_tvnow();
00293 struct ast_tm tm;
00294 int start;
00295
00296 ast_localtime(&UtcTime, &tm, NULL);
00297
00298 memset(&cid, 0, sizeof(PHONE_CID));
00299 if(&tm != NULL) {
00300 snprintf(cid.month, sizeof(cid.month), "%02d",(tm.tm_mon + 1));
00301 snprintf(cid.day, sizeof(cid.day), "%02d", tm.tm_mday);
00302 snprintf(cid.hour, sizeof(cid.hour), "%02d", tm.tm_hour);
00303 snprintf(cid.min, sizeof(cid.min), "%02d", tm.tm_min);
00304 }
00305
00306 if (!ast->connected.id.name.valid
00307 || ast_strlen_zero(ast->connected.id.name.str)) {
00308 strcpy(cid.name, DEFAULT_CALLER_ID);
00309 } else {
00310 ast_copy_string(cid.name, ast->connected.id.name.str, sizeof(cid.name));
00311 }
00312
00313 if (ast->connected.id.number.valid && ast->connected.id.number.str) {
00314 ast_copy_string(cid.number, ast->connected.id.number.str, sizeof(cid.number));
00315 }
00316
00317 p = ast->tech_pvt;
00318
00319 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
00320 ast_log(LOG_WARNING, "phone_call called on %s, neither down nor reserved\n", ast->name);
00321 return -1;
00322 }
00323 ast_debug(1, "Ringing %s on %s (%d)\n", dest, ast->name, ast->fds[0]);
00324
00325 start = IXJ_PHONE_RING_START(cid);
00326 if (start == -1)
00327 return -1;
00328
00329 if (p->mode == MODE_FXS) {
00330 char *digit = strchr(dest, '/');
00331 if (digit)
00332 {
00333 digit++;
00334 while (*digit)
00335 phone_digit_end(ast, *digit++, 0);
00336 }
00337 }
00338
00339 ast_setstate(ast, AST_STATE_RINGING);
00340 ast_queue_control(ast, AST_CONTROL_RINGING);
00341 return 0;
00342 }
00343
00344 static int phone_hangup(struct ast_channel *ast)
00345 {
00346 struct phone_pvt *p;
00347 p = ast->tech_pvt;
00348 ast_debug(1, "phone_hangup(%s)\n", ast->name);
00349 if (!ast->tech_pvt) {
00350 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
00351 return 0;
00352 }
00353
00354 ast_setstate(ast, AST_STATE_DOWN);
00355 if (ioctl(p->fd, PHONE_REC_STOP))
00356 ast_log(LOG_WARNING, "Failed to stop recording\n");
00357 if (ioctl(p->fd, PHONE_PLAY_STOP))
00358 ast_log(LOG_WARNING, "Failed to stop playing\n");
00359 if (ioctl(p->fd, PHONE_RING_STOP))
00360 ast_log(LOG_WARNING, "Failed to stop ringing\n");
00361 if (ioctl(p->fd, PHONE_CPT_STOP))
00362 ast_log(LOG_WARNING, "Failed to stop sounds\n");
00363
00364
00365 if (p->mode == MODE_FXO) {
00366 if (ioctl(p->fd, PHONE_PSTN_SET_STATE, PSTN_ON_HOOK))
00367 ast_debug(1, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n",ast->name, strerror(errno));
00368 }
00369
00370
00371 if (ioctl(p->fd, PHONE_HOOKSTATE)) {
00372 ast_debug(1, "Got hunghup, giving busy signal\n");
00373 ioctl(p->fd, PHONE_BUSY);
00374 p->cpt = 1;
00375 }
00376 p->lastformat = -1;
00377 p->lastinput = -1;
00378 p->ministate = 0;
00379 p->obuflen = 0;
00380 p->dialtone = 0;
00381 memset(p->ext, 0, sizeof(p->ext));
00382 ((struct phone_pvt *)(ast->tech_pvt))->owner = NULL;
00383 ast_module_unref(ast_module_info->self);
00384 ast_verb(3, "Hungup '%s'\n", ast->name);
00385 ast->tech_pvt = NULL;
00386 ast_setstate(ast, AST_STATE_DOWN);
00387 restart_monitor();
00388 return 0;
00389 }
00390
00391 static int phone_setup(struct ast_channel *ast)
00392 {
00393 struct phone_pvt *p;
00394 p = ast->tech_pvt;
00395 ioctl(p->fd, PHONE_CPT_STOP);
00396
00397 if (ast->rawreadformat == AST_FORMAT_G729A) {
00398
00399 ioctl(p->fd, PHONE_REC_STOP);
00400 if (p->lastinput != AST_FORMAT_G729A) {
00401 p->lastinput = AST_FORMAT_G729A;
00402 if (ioctl(p->fd, PHONE_REC_CODEC, G729)) {
00403 ast_log(LOG_WARNING, "Failed to set codec to g729\n");
00404 return -1;
00405 }
00406 }
00407 } else if (ast->rawreadformat == AST_FORMAT_G723_1) {
00408 ioctl(p->fd, PHONE_REC_STOP);
00409 if (p->lastinput != AST_FORMAT_G723_1) {
00410 p->lastinput = AST_FORMAT_G723_1;
00411 if (ioctl(p->fd, PHONE_REC_CODEC, G723_63)) {
00412 ast_log(LOG_WARNING, "Failed to set codec to g723.1\n");
00413 return -1;
00414 }
00415 }
00416 } else if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
00417 ioctl(p->fd, PHONE_REC_STOP);
00418 if (p->lastinput != AST_FORMAT_SLINEAR) {
00419 p->lastinput = AST_FORMAT_SLINEAR;
00420 if (ioctl(p->fd, PHONE_REC_CODEC, LINEAR16)) {
00421 ast_log(LOG_WARNING, "Failed to set codec to signed linear 16\n");
00422 return -1;
00423 }
00424 }
00425 } else if (ast->rawreadformat == AST_FORMAT_ULAW) {
00426 ioctl(p->fd, PHONE_REC_STOP);
00427 if (p->lastinput != AST_FORMAT_ULAW) {
00428 p->lastinput = AST_FORMAT_ULAW;
00429 if (ioctl(p->fd, PHONE_REC_CODEC, ULAW)) {
00430 ast_log(LOG_WARNING, "Failed to set codec to uLaw\n");
00431 return -1;
00432 }
00433 }
00434 } else if (p->mode == MODE_FXS) {
00435 ioctl(p->fd, PHONE_REC_STOP);
00436 if (p->lastinput != ast->rawreadformat) {
00437 p->lastinput = ast->rawreadformat;
00438 if (ioctl(p->fd, PHONE_REC_CODEC, ast->rawreadformat)) {
00439 ast_log(LOG_WARNING, "Failed to set codec to %s\n",
00440 ast_getformatname(ast->rawreadformat));
00441 return -1;
00442 }
00443 }
00444 } else {
00445 ast_log(LOG_WARNING, "Can't do format %s\n", ast_getformatname(ast->rawreadformat));
00446 return -1;
00447 }
00448 if (ioctl(p->fd, PHONE_REC_START)) {
00449 ast_log(LOG_WARNING, "Failed to start recording\n");
00450 return -1;
00451 }
00452
00453 ioctl(p->fd, PHONE_SET_TONE_ON_TIME, 300);
00454 ioctl(p->fd, PHONE_SET_TONE_OFF_TIME, 200);
00455 return 0;
00456 }
00457
00458 static int phone_answer(struct ast_channel *ast)
00459 {
00460 struct phone_pvt *p;
00461 p = ast->tech_pvt;
00462
00463 if (p->mode == MODE_FXO) {
00464 if (ioctl(p->fd, PHONE_PSTN_SET_STATE, PSTN_OFF_HOOK))
00465 ast_debug(1, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n", ast->name, strerror(errno));
00466 else
00467 ast_debug(1, "Took linejack off hook\n");
00468 }
00469 phone_setup(ast);
00470 ast_debug(1, "phone_answer(%s)\n", ast->name);
00471 ast->rings = 0;
00472 ast_setstate(ast, AST_STATE_UP);
00473 return 0;
00474 }
00475
00476 #if 0
00477 static char phone_2digit(char c)
00478 {
00479 if (c == 12)
00480 return '#';
00481 else if (c == 11)
00482 return '*';
00483 else if ((c < 10) && (c >= 0))
00484 return '0' + c - 1;
00485 else
00486 return '?';
00487 }
00488 #endif
00489
00490 static struct ast_frame *phone_exception(struct ast_channel *ast)
00491 {
00492 int res;
00493 union telephony_exception phonee;
00494 struct phone_pvt *p = ast->tech_pvt;
00495 char digit;
00496
00497
00498 p->fr.datalen = 0;
00499 p->fr.samples = 0;
00500 p->fr.data.ptr = NULL;
00501 p->fr.src = "Phone";
00502 p->fr.offset = 0;
00503 p->fr.mallocd=0;
00504 p->fr.delivery = ast_tv(0,0);
00505
00506 phonee.bytes = ioctl(p->fd, PHONE_EXCEPTION);
00507 if (phonee.bits.dtmf_ready) {
00508 ast_debug(1, "phone_exception(): DTMF\n");
00509
00510
00511 digit = ioctl(p->fd, PHONE_GET_DTMF_ASCII);
00512 p->fr.subclass.integer = digit;
00513 p->fr.frametype = AST_FRAME_DTMF;
00514 return &p->fr;
00515 }
00516 if (phonee.bits.hookstate) {
00517 ast_debug(1, "Hookstate changed\n");
00518 res = ioctl(p->fd, PHONE_HOOKSTATE);
00519
00520 ast_debug(1, "New hookstate: %d\n", res);
00521 if (!res && (p->mode != MODE_FXO))
00522 return NULL;
00523 else {
00524 if (ast->_state == AST_STATE_RINGING) {
00525
00526 p->fr.frametype = AST_FRAME_CONTROL;
00527 p->fr.subclass.integer = AST_CONTROL_ANSWER;
00528 phone_setup(ast);
00529 ast_setstate(ast, AST_STATE_UP);
00530 return &p->fr;
00531 } else
00532 ast_log(LOG_WARNING, "Got off hook in weird state %d\n", ast->_state);
00533 }
00534 }
00535 #if 1
00536 if (phonee.bits.pstn_ring)
00537 ast_verbose("Unit is ringing\n");
00538 if (phonee.bits.caller_id) {
00539 ast_verbose("We have caller ID\n");
00540 }
00541 if (phonee.bits.pstn_wink)
00542 ast_verbose("Detected Wink\n");
00543 #endif
00544
00545 p->fr.frametype = AST_FRAME_NULL;
00546 p->fr.subclass.integer = 0;
00547 return &p->fr;
00548 }
00549
00550 static struct ast_frame *phone_read(struct ast_channel *ast)
00551 {
00552 int res;
00553 struct phone_pvt *p = ast->tech_pvt;
00554
00555
00556
00557 p->fr.datalen = 0;
00558 p->fr.samples = 0;
00559 p->fr.data.ptr = NULL;
00560 p->fr.src = "Phone";
00561 p->fr.offset = 0;
00562 p->fr.mallocd=0;
00563 p->fr.delivery = ast_tv(0,0);
00564
00565
00566 CHECK_BLOCKING(ast);
00567 res = read(p->fd, p->buf, PHONE_MAX_BUF);
00568 ast_clear_flag(ast, AST_FLAG_BLOCKING);
00569 if (res < 0) {
00570 #if 0
00571 if (errno == EAGAIN) {
00572 ast_log(LOG_WARNING, "Null frame received\n");
00573 p->fr.frametype = AST_FRAME_NULL;
00574 p->fr.subclass = 0;
00575 return &p->fr;
00576 }
00577 #endif
00578 ast_log(LOG_WARNING, "Error reading: %s\n", strerror(errno));
00579 return NULL;
00580 }
00581 p->fr.data.ptr = p->buf;
00582 if (p->mode != MODE_FXS)
00583 switch(p->buf[0] & 0x3) {
00584 case '0':
00585 case '1':
00586
00587 break;
00588 case '2':
00589 case '3':
00590
00591 res = 4;
00592 break;
00593 }
00594 p->fr.samples = 240;
00595 p->fr.datalen = res;
00596 p->fr.frametype = p->lastinput <= AST_FORMAT_AUDIO_MASK ?
00597 AST_FRAME_VOICE :
00598 p->lastinput <= AST_FORMAT_PNG ? AST_FRAME_IMAGE
00599 : AST_FRAME_VIDEO;
00600 p->fr.subclass.codec = p->lastinput;
00601 p->fr.offset = AST_FRIENDLY_OFFSET;
00602
00603 if (p->fr.subclass.codec == AST_FORMAT_SLINEAR)
00604 ast_frame_byteswap_le(&p->fr);
00605 return &p->fr;
00606 }
00607
00608 static int phone_write_buf(struct phone_pvt *p, const char *buf, int len, int frlen, int swap)
00609 {
00610 int res;
00611
00612 int space = sizeof(p->obuf) - p->obuflen;
00613
00614 if (space < len)
00615 len = space;
00616 if (swap)
00617 ast_swapcopy_samples(p->obuf+p->obuflen, buf, len/2);
00618 else
00619 memcpy(p->obuf + p->obuflen, buf, len);
00620 p->obuflen += len;
00621 while(p->obuflen > frlen) {
00622 res = write(p->fd, p->obuf, frlen);
00623 if (res != frlen) {
00624 if (res < 1) {
00625
00626
00627
00628
00629 return 0;
00630 } else {
00631 ast_log(LOG_WARNING, "Only wrote %d of %d bytes\n", res, frlen);
00632 }
00633 }
00634 p->obuflen -= frlen;
00635
00636 if (p->obuflen)
00637 memmove(p->obuf, p->obuf + frlen, p->obuflen);
00638 }
00639 return len;
00640 }
00641
00642 static int phone_send_text(struct ast_channel *ast, const char *text)
00643 {
00644 int length = strlen(text);
00645 return phone_write_buf(ast->tech_pvt, text, length, length, 0) ==
00646 length ? 0 : -1;
00647 }
00648
00649 static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
00650 {
00651 struct phone_pvt *p = ast->tech_pvt;
00652 int res;
00653 int maxfr=0;
00654 char *pos;
00655 int sofar;
00656 int expected;
00657 int codecset = 0;
00658 char tmpbuf[4];
00659
00660 if (frame->frametype != AST_FRAME_VOICE && p->mode != MODE_FXS) {
00661 if (frame->frametype != AST_FRAME_IMAGE)
00662 ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
00663 return 0;
00664 }
00665 if (!(frame->subclass.codec &
00666 (AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_G729A)) &&
00667 p->mode != MODE_FXS) {
00668 ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(frame->subclass.codec));
00669 return -1;
00670 }
00671 #if 0
00672
00673 if (ast->_state != AST_STATE_UP) {
00674 ast_setstate(ast, AST_STATE_UP);
00675 phone_setup(ast);
00676 }
00677 #else
00678 if (ast->_state != AST_STATE_UP) {
00679
00680 return 0;
00681 }
00682 #endif
00683 if (frame->subclass.codec == AST_FORMAT_G729A) {
00684 if (p->lastformat != AST_FORMAT_G729A) {
00685 ioctl(p->fd, PHONE_PLAY_STOP);
00686 ioctl(p->fd, PHONE_REC_STOP);
00687 if (ioctl(p->fd, PHONE_PLAY_CODEC, G729)) {
00688 ast_log(LOG_WARNING, "Unable to set G729 mode\n");
00689 return -1;
00690 }
00691 if (ioctl(p->fd, PHONE_REC_CODEC, G729)) {
00692 ast_log(LOG_WARNING, "Unable to set G729 mode\n");
00693 return -1;
00694 }
00695 p->lastformat = AST_FORMAT_G729A;
00696 p->lastinput = AST_FORMAT_G729A;
00697
00698 p->obuflen = 0;
00699 codecset = 1;
00700 }
00701 if (frame->datalen > 80) {
00702 ast_log(LOG_WARNING, "Frame size too large for G.729 (%d bytes)\n", frame->datalen);
00703 return -1;
00704 }
00705 maxfr = 80;
00706 } else if (frame->subclass.codec == AST_FORMAT_G723_1) {
00707 if (p->lastformat != AST_FORMAT_G723_1) {
00708 ioctl(p->fd, PHONE_PLAY_STOP);
00709 ioctl(p->fd, PHONE_REC_STOP);
00710 if (ioctl(p->fd, PHONE_PLAY_CODEC, G723_63)) {
00711 ast_log(LOG_WARNING, "Unable to set G723.1 mode\n");
00712 return -1;
00713 }
00714 if (ioctl(p->fd, PHONE_REC_CODEC, G723_63)) {
00715 ast_log(LOG_WARNING, "Unable to set G723.1 mode\n");
00716 return -1;
00717 }
00718 p->lastformat = AST_FORMAT_G723_1;
00719 p->lastinput = AST_FORMAT_G723_1;
00720
00721 p->obuflen = 0;
00722 codecset = 1;
00723 }
00724 if (frame->datalen > 24) {
00725 ast_log(LOG_WARNING, "Frame size too large for G.723.1 (%d bytes)\n", frame->datalen);
00726 return -1;
00727 }
00728 maxfr = 24;
00729 } else if (frame->subclass.codec == AST_FORMAT_SLINEAR) {
00730 if (p->lastformat != AST_FORMAT_SLINEAR) {
00731 ioctl(p->fd, PHONE_PLAY_STOP);
00732 ioctl(p->fd, PHONE_REC_STOP);
00733 if (ioctl(p->fd, PHONE_PLAY_CODEC, LINEAR16)) {
00734 ast_log(LOG_WARNING, "Unable to set 16-bit linear mode\n");
00735 return -1;
00736 }
00737 if (ioctl(p->fd, PHONE_REC_CODEC, LINEAR16)) {
00738 ast_log(LOG_WARNING, "Unable to set 16-bit linear mode\n");
00739 return -1;
00740 }
00741 p->lastformat = AST_FORMAT_SLINEAR;
00742 p->lastinput = AST_FORMAT_SLINEAR;
00743 codecset = 1;
00744
00745 p->obuflen = 0;
00746 }
00747 maxfr = 480;
00748 } else if (frame->subclass.codec == AST_FORMAT_ULAW) {
00749 if (p->lastformat != AST_FORMAT_ULAW) {
00750 ioctl(p->fd, PHONE_PLAY_STOP);
00751 ioctl(p->fd, PHONE_REC_STOP);
00752 if (ioctl(p->fd, PHONE_PLAY_CODEC, ULAW)) {
00753 ast_log(LOG_WARNING, "Unable to set uLaw mode\n");
00754 return -1;
00755 }
00756 if (ioctl(p->fd, PHONE_REC_CODEC, ULAW)) {
00757 ast_log(LOG_WARNING, "Unable to set uLaw mode\n");
00758 return -1;
00759 }
00760 p->lastformat = AST_FORMAT_ULAW;
00761 p->lastinput = AST_FORMAT_ULAW;
00762 codecset = 1;
00763
00764 p->obuflen = 0;
00765 }
00766 maxfr = 240;
00767 } else {
00768 if (p->lastformat != frame->subclass.codec) {
00769 ioctl(p->fd, PHONE_PLAY_STOP);
00770 ioctl(p->fd, PHONE_REC_STOP);
00771 if (ioctl(p->fd, PHONE_PLAY_CODEC, (int) frame->subclass.codec)) {
00772 ast_log(LOG_WARNING, "Unable to set %s mode\n",
00773 ast_getformatname(frame->subclass.codec));
00774 return -1;
00775 }
00776 if (ioctl(p->fd, PHONE_REC_CODEC, (int) frame->subclass.codec)) {
00777 ast_log(LOG_WARNING, "Unable to set %s mode\n",
00778 ast_getformatname(frame->subclass.codec));
00779 return -1;
00780 }
00781 p->lastformat = frame->subclass.codec;
00782 p->lastinput = frame->subclass.codec;
00783 codecset = 1;
00784
00785 p->obuflen = 0;
00786 }
00787 maxfr = 480;
00788 }
00789 if (codecset) {
00790 ioctl(p->fd, PHONE_REC_DEPTH, 3);
00791 ioctl(p->fd, PHONE_PLAY_DEPTH, 3);
00792 if (ioctl(p->fd, PHONE_PLAY_START)) {
00793 ast_log(LOG_WARNING, "Failed to start playback\n");
00794 return -1;
00795 }
00796 if (ioctl(p->fd, PHONE_REC_START)) {
00797 ast_log(LOG_WARNING, "Failed to start recording\n");
00798 return -1;
00799 }
00800 }
00801
00802 sofar = 0;
00803 pos = frame->data.ptr;
00804 while(sofar < frame->datalen) {
00805
00806 expected = frame->datalen - sofar;
00807 if (maxfr < expected)
00808 expected = maxfr;
00809
00810
00811 if (frame->datalen == 4) {
00812 if (p->silencesupression) {
00813 memcpy(tmpbuf, frame->data.ptr, 4);
00814 expected = 24;
00815 res = phone_write_buf(p, tmpbuf, expected, maxfr, 0);
00816 }
00817 res = 4;
00818 expected=4;
00819 } else {
00820 int swap = 0;
00821 #if __BYTE_ORDER == __BIG_ENDIAN
00822 if (frame->subclass.codec == AST_FORMAT_SLINEAR)
00823 swap = 1;
00824 #endif
00825 res = phone_write_buf(p, pos, expected, maxfr, swap);
00826 }
00827 if (res != expected) {
00828 if ((errno != EAGAIN) && (errno != EINTR)) {
00829 if (res < 0)
00830 ast_log(LOG_WARNING, "Write returned error (%s)\n", strerror(errno));
00831
00832
00833
00834
00835 #if 0
00836 else
00837 ast_log(LOG_WARNING, "Only wrote %d of %d bytes\n", res, frame->datalen);
00838 #endif
00839 return -1;
00840 } else
00841 res = expected;
00842 }
00843 sofar += res;
00844 pos += res;
00845 }
00846 return 0;
00847 }
00848
00849 static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *cntx, const char *linkedid)
00850 {
00851 struct ast_channel *tmp;
00852 struct phone_codec_data queried_codec;
00853 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", i->ext, i->context, linkedid, 0, "Phone/%s", i->dev + 5);
00854 if (tmp) {
00855 tmp->tech = cur_tech;
00856 ast_channel_set_fd(tmp, 0, i->fd);
00857
00858 if (i->mode == MODE_FXS &&
00859 ioctl(i->fd, PHONE_QUERY_CODEC, &queried_codec) == 0) {
00860 if (queried_codec.type == LINEAR16)
00861 tmp->nativeformats =
00862 tmp->rawreadformat =
00863 tmp->rawwriteformat =
00864 AST_FORMAT_SLINEAR;
00865 else {
00866 tmp->nativeformats =
00867 tmp->rawreadformat =
00868 tmp->rawwriteformat =
00869 prefformat & ~AST_FORMAT_SLINEAR;
00870 }
00871 }
00872 else {
00873 tmp->nativeformats = prefformat;
00874 tmp->rawreadformat = prefformat;
00875 tmp->rawwriteformat = prefformat;
00876 }
00877
00878 if (state == AST_STATE_RING)
00879 tmp->rings = 1;
00880 tmp->tech_pvt = i;
00881 ast_copy_string(tmp->context, cntx, sizeof(tmp->context));
00882 if (!ast_strlen_zero(i->ext))
00883 ast_copy_string(tmp->exten, i->ext, sizeof(tmp->exten));
00884 else
00885 strcpy(tmp->exten, "s");
00886 if (!ast_strlen_zero(i->language))
00887 ast_string_field_set(tmp, language, i->language);
00888
00889
00890
00891 if (!ast_strlen_zero(i->cid_num)) {
00892 tmp->caller.ani.number.valid = 1;
00893 tmp->caller.ani.number.str = ast_strdup(i->cid_num);
00894 }
00895
00896 i->owner = tmp;
00897 ast_module_ref(ast_module_info->self);
00898 if (state != AST_STATE_DOWN) {
00899 if (state == AST_STATE_RING) {
00900 ioctl(tmp->fds[0], PHONE_RINGBACK);
00901 i->cpt = 1;
00902 }
00903 if (ast_pbx_start(tmp)) {
00904 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
00905 ast_hangup(tmp);
00906 }
00907 }
00908 } else
00909 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
00910 return tmp;
00911 }
00912
00913 static void phone_mini_packet(struct phone_pvt *i)
00914 {
00915 int res;
00916 char buf[1024];
00917
00918 res = read(i->fd, buf, sizeof(buf));
00919 if (res < 1) {
00920 ast_log(LOG_WARNING, "Read returned %d: %s\n", res, strerror(errno));
00921 return;
00922 }
00923 }
00924
00925 static void phone_check_exception(struct phone_pvt *i)
00926 {
00927 int offhook=0;
00928 char digit[2] = {0 , 0};
00929 union telephony_exception phonee;
00930
00931 #if 0
00932 ast_debug(1, "Exception!\n");
00933 #endif
00934 phonee.bytes = ioctl(i->fd, PHONE_EXCEPTION);
00935 if (phonee.bits.dtmf_ready) {
00936 digit[0] = ioctl(i->fd, PHONE_GET_DTMF_ASCII);
00937 if (i->mode == MODE_DIALTONE || i->mode == MODE_FXS || i->mode == MODE_SIGMA) {
00938 ioctl(i->fd, PHONE_PLAY_STOP);
00939 ioctl(i->fd, PHONE_REC_STOP);
00940 ioctl(i->fd, PHONE_CPT_STOP);
00941 i->dialtone = 0;
00942 if (strlen(i->ext) < AST_MAX_EXTENSION - 1)
00943 strncat(i->ext, digit, sizeof(i->ext) - strlen(i->ext) - 1);
00944 if ((i->mode != MODE_FXS ||
00945 !(phonee.bytes = ioctl(i->fd, PHONE_EXCEPTION)) ||
00946 !phonee.bits.dtmf_ready) &&
00947 ast_exists_extension(NULL, i->context, i->ext, 1, i->cid_num)) {
00948
00949 phone_new(i, AST_STATE_RING, i->context, NULL);
00950
00951 } else if (!ast_canmatch_extension(NULL, i->context, i->ext, 1, i->cid_num)) {
00952
00953
00954 if (ast_exists_extension(NULL, "default", i->ext, 1, i->cid_num)) {
00955
00956 phone_new(i, AST_STATE_RING, "default", NULL);
00957
00958 } else if (!ast_canmatch_extension(NULL, "default", i->ext, 1, i->cid_num)) {
00959
00960 ast_debug(1, "%s can't match anything in %s or default\n", i->ext, i->context);
00961 ioctl(i->fd, PHONE_BUSY);
00962 i->cpt = 1;
00963 }
00964 }
00965 #if 0
00966 ast_verbose("Extension is %s\n", i->ext);
00967 #endif
00968 }
00969 }
00970 if (phonee.bits.hookstate) {
00971 offhook = ioctl(i->fd, PHONE_HOOKSTATE);
00972 if (offhook) {
00973 if (i->mode == MODE_IMMEDIATE) {
00974 phone_new(i, AST_STATE_RING, i->context, NULL);
00975 } else if (i->mode == MODE_DIALTONE) {
00976 ast_module_ref(ast_module_info->self);
00977
00978 i->ext[0] = '\0';
00979
00980 i->dialtone++;
00981 ioctl(i->fd, PHONE_PLAY_STOP);
00982 ioctl(i->fd, PHONE_PLAY_CODEC, ULAW);
00983 ioctl(i->fd, PHONE_PLAY_START);
00984 i->lastformat = -1;
00985 } else if (i->mode == MODE_SIGMA) {
00986 ast_module_ref(ast_module_info->self);
00987
00988 i->ext[0] = '\0';
00989
00990 i->dialtone++;
00991 ioctl(i->fd, PHONE_DIALTONE);
00992 }
00993 } else {
00994 if (i->dialtone)
00995 ast_module_unref(ast_module_info->self);
00996 memset(i->ext, 0, sizeof(i->ext));
00997 if (i->cpt)
00998 {
00999 ioctl(i->fd, PHONE_CPT_STOP);
01000 i->cpt = 0;
01001 }
01002 ioctl(i->fd, PHONE_PLAY_STOP);
01003 ioctl(i->fd, PHONE_REC_STOP);
01004 i->dialtone = 0;
01005 i->lastformat = -1;
01006 }
01007 }
01008 if (phonee.bits.pstn_ring) {
01009 ast_verbose("Unit is ringing\n");
01010 phone_new(i, AST_STATE_RING, i->context, NULL);
01011 }
01012 if (phonee.bits.caller_id)
01013 ast_verbose("We have caller ID\n");
01014
01015
01016 }
01017
01018 static void *do_monitor(void *data)
01019 {
01020 struct pollfd *fds = NULL;
01021 int nfds = 0, inuse_fds = 0, res;
01022 struct phone_pvt *i;
01023 int tonepos = 0;
01024
01025 struct timeval tv = { 0, 0 };
01026 int dotone;
01027
01028
01029 while (monitor) {
01030
01031
01032
01033 if (ast_mutex_lock(&iflock)) {
01034 ast_log(LOG_ERROR, "Unable to grab interface lock\n");
01035 return NULL;
01036 }
01037
01038
01039 i = iflist;
01040 dotone = 0;
01041 inuse_fds = 0;
01042 for (i = iflist; i; i = i->next) {
01043 if (!i->owner) {
01044
01045 if (inuse_fds == nfds) {
01046 void *tmp = ast_realloc(fds, (nfds + 1) * sizeof(*fds));
01047 if (!tmp) {
01048
01049 continue;
01050 }
01051 fds = tmp;
01052 nfds++;
01053 }
01054 fds[inuse_fds].fd = i->fd;
01055 fds[inuse_fds].events = POLLIN | POLLERR;
01056 fds[inuse_fds].revents = 0;
01057 inuse_fds++;
01058
01059 if (i->dialtone && i->mode != MODE_SIGMA) {
01060
01061
01062 if (ast_tvzero(tv)) {
01063
01064 if (write(i->fd, DialTone + tonepos, 240) != 240) {
01065 ast_log(LOG_WARNING, "Dial tone write error\n");
01066 }
01067 }
01068 dotone++;
01069 }
01070 }
01071 }
01072
01073 ast_mutex_unlock(&iflock);
01074
01075
01076 if (dotone && i && i->mode != MODE_SIGMA) {
01077
01078 tonepos += 240;
01079 if (tonepos >= sizeof(DialTone)) {
01080 tonepos = 0;
01081 }
01082 if (ast_tvzero(tv)) {
01083 tv = ast_tv(0, 30000);
01084 }
01085 res = ast_poll2(fds, inuse_fds, &tv);
01086 } else {
01087 res = ast_poll(fds, inuse_fds, -1);
01088 tv = ast_tv(0, 0);
01089 tonepos = 0;
01090 }
01091
01092 if (res < 0) {
01093 ast_debug(1, "poll returned %d: %s\n", res, strerror(errno));
01094 continue;
01095 }
01096
01097
01098 if (!res) {
01099 continue;
01100 }
01101
01102
01103 if (ast_mutex_lock(&iflock)) {
01104 ast_log(LOG_WARNING, "Unable to lock the interface list\n");
01105 continue;
01106 }
01107
01108 for (i = iflist; i; i = i->next) {
01109 int j;
01110
01111 for (j = 0; j < inuse_fds; j++) {
01112 if (fds[j].fd == i->fd) {
01113 break;
01114 }
01115 }
01116
01117
01118 if (j == inuse_fds) {
01119 continue;
01120 }
01121
01122 if (fds[j].revents & POLLIN) {
01123 if (i->owner) {
01124 continue;
01125 }
01126 phone_mini_packet(i);
01127 }
01128 if (fds[j].revents & POLLERR) {
01129 if (i->owner) {
01130 continue;
01131 }
01132 phone_check_exception(i);
01133 }
01134 }
01135 ast_mutex_unlock(&iflock);
01136 }
01137 return NULL;
01138 }
01139
01140 static int restart_monitor()
01141 {
01142
01143 if (monitor_thread == AST_PTHREADT_STOP)
01144 return 0;
01145 if (ast_mutex_lock(&monlock)) {
01146 ast_log(LOG_WARNING, "Unable to lock monitor\n");
01147 return -1;
01148 }
01149 if (monitor_thread == pthread_self()) {
01150 ast_mutex_unlock(&monlock);
01151 ast_log(LOG_WARNING, "Cannot kill myself\n");
01152 return -1;
01153 }
01154 if (monitor_thread != AST_PTHREADT_NULL) {
01155 if (ast_mutex_lock(&iflock)) {
01156 ast_mutex_unlock(&monlock);
01157 ast_log(LOG_WARNING, "Unable to lock the interface list\n");
01158 return -1;
01159 }
01160 monitor = 0;
01161 while (pthread_kill(monitor_thread, SIGURG) == 0)
01162 sched_yield();
01163 pthread_join(monitor_thread, NULL);
01164 ast_mutex_unlock(&iflock);
01165 }
01166 monitor = 1;
01167
01168 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
01169 ast_mutex_unlock(&monlock);
01170 ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
01171 return -1;
01172 }
01173 ast_mutex_unlock(&monlock);
01174 return 0;
01175 }
01176
01177 static struct phone_pvt *mkif(const char *iface, int mode, int txgain, int rxgain)
01178 {
01179
01180 struct phone_pvt *tmp;
01181 int flags;
01182
01183 tmp = ast_calloc(1, sizeof(*tmp));
01184 if (tmp) {
01185 tmp->fd = open(iface, O_RDWR);
01186 if (tmp->fd < 0) {
01187 ast_log(LOG_WARNING, "Unable to open '%s'\n", iface);
01188 ast_free(tmp);
01189 return NULL;
01190 }
01191 if (mode == MODE_FXO) {
01192 if (ioctl(tmp->fd, IXJCTL_PORT, PORT_PSTN)) {
01193 ast_debug(1, "Unable to set port to PSTN\n");
01194 }
01195 } else {
01196 if (ioctl(tmp->fd, IXJCTL_PORT, PORT_POTS))
01197 if (mode != MODE_FXS)
01198 ast_debug(1, "Unable to set port to POTS\n");
01199 }
01200 ioctl(tmp->fd, PHONE_PLAY_STOP);
01201 ioctl(tmp->fd, PHONE_REC_STOP);
01202 ioctl(tmp->fd, PHONE_RING_STOP);
01203 ioctl(tmp->fd, PHONE_CPT_STOP);
01204 if (ioctl(tmp->fd, PHONE_PSTN_SET_STATE, PSTN_ON_HOOK))
01205 ast_debug(1, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n",iface, strerror(errno));
01206 if (echocancel != AEC_OFF)
01207 ioctl(tmp->fd, IXJCTL_AEC_START, echocancel);
01208 if (silencesupression)
01209 tmp->silencesupression = 1;
01210 #ifdef PHONE_VAD
01211 ioctl(tmp->fd, PHONE_VAD, tmp->silencesupression);
01212 #endif
01213 tmp->mode = mode;
01214 flags = fcntl(tmp->fd, F_GETFL);
01215 fcntl(tmp->fd, F_SETFL, flags | O_NONBLOCK);
01216 tmp->owner = NULL;
01217 tmp->lastformat = -1;
01218 tmp->lastinput = -1;
01219 tmp->ministate = 0;
01220 memset(tmp->ext, 0, sizeof(tmp->ext));
01221 ast_copy_string(tmp->language, language, sizeof(tmp->language));
01222 ast_copy_string(tmp->dev, iface, sizeof(tmp->dev));
01223 ast_copy_string(tmp->context, context, sizeof(tmp->context));
01224 tmp->next = NULL;
01225 tmp->obuflen = 0;
01226 tmp->dialtone = 0;
01227 tmp->cpt = 0;
01228 ast_copy_string(tmp->cid_num, cid_num, sizeof(tmp->cid_num));
01229 ast_copy_string(tmp->cid_name, cid_name, sizeof(tmp->cid_name));
01230 tmp->txgain = txgain;
01231 ioctl(tmp->fd, PHONE_PLAY_VOLUME, tmp->txgain);
01232 tmp->rxgain = rxgain;
01233 ioctl(tmp->fd, PHONE_REC_VOLUME, tmp->rxgain);
01234 }
01235 return tmp;
01236 }
01237
01238 static struct ast_channel *phone_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
01239 {
01240 format_t oldformat;
01241 struct phone_pvt *p;
01242 struct ast_channel *tmp = NULL;
01243 char *name = data;
01244
01245
01246 if (ast_mutex_lock(&iflock)) {
01247 ast_log(LOG_ERROR, "Unable to lock interface list???\n");
01248 return NULL;
01249 }
01250 p = iflist;
01251 while(p) {
01252 if (p->mode == MODE_FXS ||
01253 format & (AST_FORMAT_G729A | AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW)) {
01254 size_t length = strlen(p->dev + 5);
01255 if (strncmp(name, p->dev + 5, length) == 0 &&
01256 !isalnum(name[length])) {
01257 if (!p->owner) {
01258 tmp = phone_new(p, AST_STATE_DOWN, p->context, requestor ? requestor->linkedid : NULL);
01259 break;
01260 } else
01261 *cause = AST_CAUSE_BUSY;
01262 }
01263 }
01264 p = p->next;
01265 }
01266 ast_mutex_unlock(&iflock);
01267 restart_monitor();
01268 if (tmp == NULL) {
01269 oldformat = format;
01270 format &= (AST_FORMAT_G729A | AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW);
01271 if (!format) {
01272 char buf[256];
01273 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), oldformat));
01274 return NULL;
01275 }
01276 }
01277 return tmp;
01278 }
01279
01280
01281 static int parse_gain_value(const char *gain_type, const char *value)
01282 {
01283 float gain;
01284
01285
01286 if (sscanf(value, "%30f", &gain) != 1)
01287 {
01288 ast_log(LOG_ERROR, "Invalid %s value '%s' in '%s' config\n",
01289 value, gain_type, config);
01290 return DEFAULT_GAIN;
01291 }
01292
01293
01294 gain = gain * (float)DEFAULT_GAIN;
01295
01296
01297 if (value[strlen(value) - 1] == '%')
01298 return (int)(gain / (float)100);
01299
01300 return (int)gain;
01301 }
01302
01303 static int __unload_module(void)
01304 {
01305 struct phone_pvt *p, *pl;
01306
01307 if (cur_tech)
01308 ast_channel_unregister(cur_tech);
01309 if (!ast_mutex_lock(&iflock)) {
01310
01311 p = iflist;
01312 while(p) {
01313 if (p->owner)
01314 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
01315 p = p->next;
01316 }
01317 iflist = NULL;
01318 ast_mutex_unlock(&iflock);
01319 } else {
01320 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
01321 return -1;
01322 }
01323 if (!ast_mutex_lock(&monlock)) {
01324 if (monitor_thread > AST_PTHREADT_NULL) {
01325 monitor = 0;
01326 while (pthread_kill(monitor_thread, SIGURG) == 0)
01327 sched_yield();
01328 pthread_join(monitor_thread, NULL);
01329 }
01330 monitor_thread = AST_PTHREADT_STOP;
01331 ast_mutex_unlock(&monlock);
01332 } else {
01333 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
01334 return -1;
01335 }
01336
01337 if (!ast_mutex_lock(&iflock)) {
01338
01339 p = iflist;
01340 while(p) {
01341
01342 if (p->fd > -1)
01343 close(p->fd);
01344 pl = p;
01345 p = p->next;
01346
01347 ast_free(pl);
01348 }
01349 iflist = NULL;
01350 ast_mutex_unlock(&iflock);
01351 } else {
01352 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
01353 return -1;
01354 }
01355
01356 return 0;
01357 }
01358
01359 static int unload_module(void)
01360 {
01361 return __unload_module();
01362 }
01363
01364 static int load_module(void)
01365 {
01366 struct ast_config *cfg;
01367 struct ast_variable *v;
01368 struct phone_pvt *tmp;
01369 int mode = MODE_IMMEDIATE;
01370 int txgain = DEFAULT_GAIN, rxgain = DEFAULT_GAIN;
01371 struct ast_flags config_flags = { 0 };
01372
01373 if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) {
01374 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config);
01375 return AST_MODULE_LOAD_DECLINE;
01376 }
01377
01378
01379 if (!cfg) {
01380 ast_log(LOG_ERROR, "Unable to load config %s\n", config);
01381 return AST_MODULE_LOAD_DECLINE;
01382 }
01383 if (ast_mutex_lock(&iflock)) {
01384
01385 ast_log(LOG_ERROR, "Unable to lock interface list???\n");
01386 return AST_MODULE_LOAD_FAILURE;
01387 }
01388 v = ast_variable_browse(cfg, "interfaces");
01389 while(v) {
01390
01391 if (!strcasecmp(v->name, "device")) {
01392 tmp = mkif(v->value, mode, txgain, rxgain);
01393 if (tmp) {
01394 tmp->next = iflist;
01395 iflist = tmp;
01396
01397 } else {
01398 ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value);
01399 ast_config_destroy(cfg);
01400 ast_mutex_unlock(&iflock);
01401 __unload_module();
01402 return AST_MODULE_LOAD_FAILURE;
01403 }
01404 } else if (!strcasecmp(v->name, "silencesupression")) {
01405 silencesupression = ast_true(v->value);
01406 } else if (!strcasecmp(v->name, "language")) {
01407 ast_copy_string(language, v->value, sizeof(language));
01408 } else if (!strcasecmp(v->name, "callerid")) {
01409 ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
01410 } else if (!strcasecmp(v->name, "mode")) {
01411 if (!strncasecmp(v->value, "di", 2))
01412 mode = MODE_DIALTONE;
01413 else if (!strncasecmp(v->value, "sig", 3))
01414 mode = MODE_SIGMA;
01415 else if (!strncasecmp(v->value, "im", 2))
01416 mode = MODE_IMMEDIATE;
01417 else if (!strncasecmp(v->value, "fxs", 3)) {
01418 mode = MODE_FXS;
01419 prefformat = 0x01ff0000;
01420 }
01421 else if (!strncasecmp(v->value, "fx", 2))
01422 mode = MODE_FXO;
01423 else
01424 ast_log(LOG_WARNING, "Unknown mode: %s\n", v->value);
01425 } else if (!strcasecmp(v->name, "context")) {
01426 ast_copy_string(context, v->value, sizeof(context));
01427 } else if (!strcasecmp(v->name, "format")) {
01428 if (!strcasecmp(v->value, "g729")) {
01429 prefformat = AST_FORMAT_G729A;
01430 } else if (!strcasecmp(v->value, "g723.1")) {
01431 prefformat = AST_FORMAT_G723_1;
01432 } else if (!strcasecmp(v->value, "slinear")) {
01433 if (mode == MODE_FXS)
01434 prefformat |= AST_FORMAT_SLINEAR;
01435 else prefformat = AST_FORMAT_SLINEAR;
01436 } else if (!strcasecmp(v->value, "ulaw")) {
01437 prefformat = AST_FORMAT_ULAW;
01438 } else
01439 ast_log(LOG_WARNING, "Unknown format '%s'\n", v->value);
01440 } else if (!strcasecmp(v->name, "echocancel")) {
01441 if (!strcasecmp(v->value, "off")) {
01442 echocancel = AEC_OFF;
01443 } else if (!strcasecmp(v->value, "low")) {
01444 echocancel = AEC_LOW;
01445 } else if (!strcasecmp(v->value, "medium")) {
01446 echocancel = AEC_MED;
01447 } else if (!strcasecmp(v->value, "high")) {
01448 echocancel = AEC_HIGH;
01449 } else
01450 ast_log(LOG_WARNING, "Unknown echo cancellation '%s'\n", v->value);
01451 } else if (!strcasecmp(v->name, "txgain")) {
01452 txgain = parse_gain_value(v->name, v->value);
01453 } else if (!strcasecmp(v->name, "rxgain")) {
01454 rxgain = parse_gain_value(v->name, v->value);
01455 }
01456 v = v->next;
01457 }
01458 ast_mutex_unlock(&iflock);
01459
01460 if (mode == MODE_FXS) {
01461 phone_tech_fxs.capabilities = prefformat;
01462 cur_tech = &phone_tech_fxs;
01463 } else
01464 cur_tech = (struct ast_channel_tech *) &phone_tech;
01465
01466
01467
01468 if (ast_channel_register(cur_tech)) {
01469 ast_log(LOG_ERROR, "Unable to register channel class 'Phone'\n");
01470 ast_config_destroy(cfg);
01471 __unload_module();
01472 return AST_MODULE_LOAD_FAILURE;
01473 }
01474 ast_config_destroy(cfg);
01475
01476 restart_monitor();
01477 return AST_MODULE_LOAD_SUCCESS;
01478 }
01479
01480 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Linux Telephony API Support");