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