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: 366408 $")
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 = ast_channel_tech_pvt(chan);
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 case AST_CONTROL_PVT_CAUSE_CODE:
00226 break;
00227 default:
00228 ast_log(LOG_WARNING, "Condition %d is not supported on channel %s\n", condition, ast_channel_name(chan));
00229 }
00230 return res;
00231 }
00232
00233 static int phone_fixup(struct ast_channel *old, struct ast_channel *new)
00234 {
00235 struct phone_pvt *pvt = ast_channel_tech_pvt(old);
00236 if (pvt && pvt->owner == old)
00237 pvt->owner = new;
00238 return 0;
00239 }
00240
00241 static int phone_digit_begin(struct ast_channel *chan, char digit)
00242 {
00243
00244 return 0;
00245 }
00246
00247 static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
00248 {
00249 struct phone_pvt *p;
00250 int outdigit;
00251 p = ast_channel_tech_pvt(ast);
00252 ast_debug(1, "Dialed %c\n", digit);
00253 switch(digit) {
00254 case '0':
00255 case '1':
00256 case '2':
00257 case '3':
00258 case '4':
00259 case '5':
00260 case '6':
00261 case '7':
00262 case '8':
00263 case '9':
00264 outdigit = digit - '0';
00265 break;
00266 case '*':
00267 outdigit = 11;
00268 break;
00269 case '#':
00270 outdigit = 12;
00271 break;
00272 case 'f':
00273 case 'F':
00274 ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_ON_HOOK);
00275 usleep(320000);
00276 ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_OFF_HOOK);
00277 ast_format_clear(&p->lastformat);
00278 return 0;
00279 default:
00280 ast_log(LOG_WARNING, "Unknown digit '%c'\n", digit);
00281 return -1;
00282 }
00283 ast_debug(1, "Dialed %d\n", outdigit);
00284 ioctl(p->fd, PHONE_PLAY_TONE, outdigit);
00285 ast_format_clear(&p->lastformat);
00286 return 0;
00287 }
00288
00289 static int phone_call(struct ast_channel *ast, const char *dest, int timeout)
00290 {
00291 struct phone_pvt *p;
00292
00293 PHONE_CID cid;
00294 struct timeval UtcTime = ast_tvnow();
00295 struct ast_tm tm;
00296 int start;
00297
00298 ast_localtime(&UtcTime, &tm, NULL);
00299
00300 memset(&cid, 0, sizeof(PHONE_CID));
00301 snprintf(cid.month, sizeof(cid.month), "%02d",(tm.tm_mon + 1));
00302 snprintf(cid.day, sizeof(cid.day), "%02d", tm.tm_mday);
00303 snprintf(cid.hour, sizeof(cid.hour), "%02d", tm.tm_hour);
00304 snprintf(cid.min, sizeof(cid.min), "%02d", tm.tm_min);
00305
00306 if (!ast_channel_connected(ast)->id.name.valid
00307 || ast_strlen_zero(ast_channel_connected(ast)->id.name.str)) {
00308 strcpy(cid.name, DEFAULT_CALLER_ID);
00309 } else {
00310 ast_copy_string(cid.name, ast_channel_connected(ast)->id.name.str, sizeof(cid.name));
00311 }
00312
00313 if (ast_channel_connected(ast)->id.number.valid && ast_channel_connected(ast)->id.number.str) {
00314 ast_copy_string(cid.number, ast_channel_connected(ast)->id.number.str, sizeof(cid.number));
00315 }
00316
00317 p = ast_channel_tech_pvt(ast);
00318
00319 if ((ast_channel_state(ast) != AST_STATE_DOWN) && (ast_channel_state(ast) != AST_STATE_RESERVED)) {
00320 ast_log(LOG_WARNING, "phone_call called on %s, neither down nor reserved\n", ast_channel_name(ast));
00321 return -1;
00322 }
00323 ast_debug(1, "Ringing %s on %s (%d)\n", dest, ast_channel_name(ast), ast_channel_fd(ast, 0));
00324
00325 start = IXJ_PHONE_RING_START(cid);
00326 if (start == -1)
00327 return -1;
00328
00329 if (p->mode == MODE_FXS) {
00330 const 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_channel_tech_pvt(ast);
00348 ast_debug(1, "phone_hangup(%s)\n", ast_channel_name(ast));
00349 if (!ast_channel_tech_pvt(ast)) {
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_channel_name(ast), 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 ast_format_clear(&p->lastformat);
00377 ast_format_clear(&p->lastinput);
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_channel_tech_pvt(ast)))->owner = NULL;
00383 ast_module_unref(ast_module_info->self);
00384 ast_verb(3, "Hungup '%s'\n", ast_channel_name(ast));
00385 ast_channel_tech_pvt_set(ast, 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_channel_tech_pvt(ast);
00395 ioctl(p->fd, PHONE_CPT_STOP);
00396
00397 if (ast_channel_rawreadformat(ast)->id == AST_FORMAT_G729A) {
00398
00399 ioctl(p->fd, PHONE_REC_STOP);
00400 if (p->lastinput.id != AST_FORMAT_G729A) {
00401 ast_format_set(&p->lastinput, AST_FORMAT_G729A, 0);
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_channel_rawreadformat(ast)->id == AST_FORMAT_G723_1) {
00408 ioctl(p->fd, PHONE_REC_STOP);
00409 if (p->lastinput.id != AST_FORMAT_G723_1) {
00410 ast_format_set(&p->lastinput, AST_FORMAT_G723_1, 0);
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_channel_rawreadformat(ast)->id == AST_FORMAT_SLINEAR) {
00417 ioctl(p->fd, PHONE_REC_STOP);
00418 if (p->lastinput.id != AST_FORMAT_SLINEAR) {
00419 ast_format_set(&p->lastinput, AST_FORMAT_SLINEAR, 0);
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_channel_rawreadformat(ast)->id == AST_FORMAT_ULAW) {
00426 ioctl(p->fd, PHONE_REC_STOP);
00427 if (p->lastinput.id != AST_FORMAT_ULAW) {
00428 ast_format_set(&p->lastinput, AST_FORMAT_ULAW, 0);
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 (ast_format_cmp(&p->lastinput, ast_channel_rawreadformat(ast)) == AST_FORMAT_CMP_NOT_EQUAL) {
00437 ast_format_copy(&p->lastinput, ast_channel_rawreadformat(ast));
00438 if (ioctl(p->fd, PHONE_REC_CODEC, ast_channel_rawreadformat(ast))) {
00439 ast_log(LOG_WARNING, "Failed to set codec to %s\n",
00440 ast_getformatname(ast_channel_rawreadformat(ast)));
00441 return -1;
00442 }
00443 }
00444 } else {
00445 ast_log(LOG_WARNING, "Can't do format %s\n", ast_getformatname(ast_channel_rawreadformat(ast)));
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_channel_tech_pvt(ast);
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_channel_name(ast), 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_channel_name(ast));
00471 ast_channel_rings_set(ast, 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_channel_tech_pvt(ast);
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_channel_state(ast) == 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_channel_state(ast));
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_channel_tech_pvt(ast);
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_channel_flags(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 = AST_FORMAT_GET_TYPE(p->lastinput.id) == AST_FORMAT_TYPE_AUDIO ?
00597 AST_FRAME_VOICE : AST_FORMAT_GET_TYPE(p->lastinput.id) == AST_FORMAT_TYPE_IMAGE ?
00598 AST_FRAME_IMAGE : AST_FRAME_VIDEO;
00599 ast_format_copy(&p->fr.subclass.format, &p->lastinput);
00600 p->fr.offset = AST_FRIENDLY_OFFSET;
00601
00602 if (p->fr.subclass.format.id == AST_FORMAT_SLINEAR)
00603 ast_frame_byteswap_le(&p->fr);
00604 return &p->fr;
00605 }
00606
00607 static int phone_write_buf(struct phone_pvt *p, const char *buf, int len, int frlen, int swap)
00608 {
00609 int res;
00610
00611 int space = sizeof(p->obuf) - p->obuflen;
00612
00613 if (space < len)
00614 len = space;
00615 if (swap)
00616 ast_swapcopy_samples(p->obuf+p->obuflen, buf, len/2);
00617 else
00618 memcpy(p->obuf + p->obuflen, buf, len);
00619 p->obuflen += len;
00620 while(p->obuflen > frlen) {
00621 res = write(p->fd, p->obuf, frlen);
00622 if (res != frlen) {
00623 if (res < 1) {
00624
00625
00626
00627
00628 return 0;
00629 } else {
00630 ast_log(LOG_WARNING, "Only wrote %d of %d bytes\n", res, frlen);
00631 }
00632 }
00633 p->obuflen -= frlen;
00634
00635 if (p->obuflen)
00636 memmove(p->obuf, p->obuf + frlen, p->obuflen);
00637 }
00638 return len;
00639 }
00640
00641 static int phone_send_text(struct ast_channel *ast, const char *text)
00642 {
00643 int length = strlen(text);
00644 return phone_write_buf(ast_channel_tech_pvt(ast), text, length, length, 0) ==
00645 length ? 0 : -1;
00646 }
00647
00648 static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
00649 {
00650 struct phone_pvt *p = ast_channel_tech_pvt(ast);
00651 int res;
00652 int maxfr=0;
00653 char *pos;
00654 int sofar;
00655 int expected;
00656 int codecset = 0;
00657 char tmpbuf[4];
00658
00659 if (frame->frametype != AST_FRAME_VOICE && p->mode != MODE_FXS) {
00660 if (frame->frametype != AST_FRAME_IMAGE)
00661 ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
00662 return 0;
00663 }
00664 if (!(frame->subclass.format.id == AST_FORMAT_G723_1 ||
00665 frame->subclass.format.id == AST_FORMAT_SLINEAR ||
00666 frame->subclass.format.id == AST_FORMAT_ULAW ||
00667 frame->subclass.format.id == AST_FORMAT_G729A) &&
00668 p->mode != MODE_FXS) {
00669 ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(&frame->subclass.format));
00670 return -1;
00671 }
00672 #if 0
00673
00674 if (ast->_state != AST_STATE_UP) {
00675 ast_setstate(ast, AST_STATE_UP);
00676 phone_setup(ast);
00677 }
00678 #else
00679 if (ast_channel_state(ast) != AST_STATE_UP) {
00680
00681 return 0;
00682 }
00683 #endif
00684 if (frame->subclass.format.id == AST_FORMAT_G729A) {
00685 if (p->lastformat.id != AST_FORMAT_G729A) {
00686 ioctl(p->fd, PHONE_PLAY_STOP);
00687 ioctl(p->fd, PHONE_REC_STOP);
00688 if (ioctl(p->fd, PHONE_PLAY_CODEC, G729)) {
00689 ast_log(LOG_WARNING, "Unable to set G729 mode\n");
00690 return -1;
00691 }
00692 if (ioctl(p->fd, PHONE_REC_CODEC, G729)) {
00693 ast_log(LOG_WARNING, "Unable to set G729 mode\n");
00694 return -1;
00695 }
00696 ast_format_set(&p->lastformat, AST_FORMAT_G729A, 0);
00697 ast_format_set(&p->lastinput, AST_FORMAT_G729A, 0);
00698
00699 p->obuflen = 0;
00700 codecset = 1;
00701 }
00702 if (frame->datalen > 80) {
00703 ast_log(LOG_WARNING, "Frame size too large for G.729 (%d bytes)\n", frame->datalen);
00704 return -1;
00705 }
00706 maxfr = 80;
00707 } else if (frame->subclass.format.id == AST_FORMAT_G723_1) {
00708 if (p->lastformat.id != AST_FORMAT_G723_1) {
00709 ioctl(p->fd, PHONE_PLAY_STOP);
00710 ioctl(p->fd, PHONE_REC_STOP);
00711 if (ioctl(p->fd, PHONE_PLAY_CODEC, G723_63)) {
00712 ast_log(LOG_WARNING, "Unable to set G723.1 mode\n");
00713 return -1;
00714 }
00715 if (ioctl(p->fd, PHONE_REC_CODEC, G723_63)) {
00716 ast_log(LOG_WARNING, "Unable to set G723.1 mode\n");
00717 return -1;
00718 }
00719 ast_format_set(&p->lastformat, AST_FORMAT_G723_1, 0);
00720 ast_format_set(&p->lastinput, AST_FORMAT_G723_1, 0);
00721
00722 p->obuflen = 0;
00723 codecset = 1;
00724 }
00725 if (frame->datalen > 24) {
00726 ast_log(LOG_WARNING, "Frame size too large for G.723.1 (%d bytes)\n", frame->datalen);
00727 return -1;
00728 }
00729 maxfr = 24;
00730 } else if (frame->subclass.format.id == AST_FORMAT_SLINEAR) {
00731 if (p->lastformat.id != AST_FORMAT_SLINEAR) {
00732 ioctl(p->fd, PHONE_PLAY_STOP);
00733 ioctl(p->fd, PHONE_REC_STOP);
00734 if (ioctl(p->fd, PHONE_PLAY_CODEC, LINEAR16)) {
00735 ast_log(LOG_WARNING, "Unable to set 16-bit linear mode\n");
00736 return -1;
00737 }
00738 if (ioctl(p->fd, PHONE_REC_CODEC, LINEAR16)) {
00739 ast_log(LOG_WARNING, "Unable to set 16-bit linear mode\n");
00740 return -1;
00741 }
00742 ast_format_set(&p->lastformat, AST_FORMAT_SLINEAR, 0);
00743 ast_format_set(&p->lastinput, AST_FORMAT_SLINEAR, 0);
00744 codecset = 1;
00745
00746 p->obuflen = 0;
00747 }
00748 maxfr = 480;
00749 } else if (frame->subclass.format.id == AST_FORMAT_ULAW) {
00750 if (p->lastformat.id != AST_FORMAT_ULAW) {
00751 ioctl(p->fd, PHONE_PLAY_STOP);
00752 ioctl(p->fd, PHONE_REC_STOP);
00753 if (ioctl(p->fd, PHONE_PLAY_CODEC, ULAW)) {
00754 ast_log(LOG_WARNING, "Unable to set uLaw mode\n");
00755 return -1;
00756 }
00757 if (ioctl(p->fd, PHONE_REC_CODEC, ULAW)) {
00758 ast_log(LOG_WARNING, "Unable to set uLaw mode\n");
00759 return -1;
00760 }
00761 ast_format_set(&p->lastformat, AST_FORMAT_ULAW, 0);
00762 ast_format_set(&p->lastinput, AST_FORMAT_ULAW, 0);
00763 codecset = 1;
00764
00765 p->obuflen = 0;
00766 }
00767 maxfr = 240;
00768 } else {
00769 if (ast_format_cmp(&p->lastformat, &frame->subclass.format) != AST_FORMAT_CMP_EQUAL) {
00770 ioctl(p->fd, PHONE_PLAY_STOP);
00771 ioctl(p->fd, PHONE_REC_STOP);
00772 if (ioctl(p->fd, PHONE_PLAY_CODEC, (int) frame->subclass.format.id)) {
00773 ast_log(LOG_WARNING, "Unable to set %s mode\n",
00774 ast_getformatname(&frame->subclass.format));
00775 return -1;
00776 }
00777 if (ioctl(p->fd, PHONE_REC_CODEC, (int) frame->subclass.format.id)) {
00778 ast_log(LOG_WARNING, "Unable to set %s mode\n",
00779 ast_getformatname(&frame->subclass.format));
00780 return -1;
00781 }
00782 ast_format_copy(&p->lastformat, &frame->subclass.format);
00783 ast_format_copy(&p->lastinput, &frame->subclass.format);
00784 codecset = 1;
00785
00786 p->obuflen = 0;
00787 }
00788 maxfr = 480;
00789 }
00790 if (codecset) {
00791 ioctl(p->fd, PHONE_REC_DEPTH, 3);
00792 ioctl(p->fd, PHONE_PLAY_DEPTH, 3);
00793 if (ioctl(p->fd, PHONE_PLAY_START)) {
00794 ast_log(LOG_WARNING, "Failed to start playback\n");
00795 return -1;
00796 }
00797 if (ioctl(p->fd, PHONE_REC_START)) {
00798 ast_log(LOG_WARNING, "Failed to start recording\n");
00799 return -1;
00800 }
00801 }
00802
00803 sofar = 0;
00804 pos = frame->data.ptr;
00805 while(sofar < frame->datalen) {
00806
00807 expected = frame->datalen - sofar;
00808 if (maxfr < expected)
00809 expected = maxfr;
00810
00811
00812 if (frame->datalen == 4) {
00813 if (p->silencesupression) {
00814 memcpy(tmpbuf, frame->data.ptr, 4);
00815 expected = 24;
00816 res = phone_write_buf(p, tmpbuf, expected, maxfr, 0);
00817 }
00818 res = 4;
00819 expected=4;
00820 } else {
00821 int swap = 0;
00822 #if __BYTE_ORDER == __BIG_ENDIAN
00823 if (frame->subclass.format.id == AST_FORMAT_SLINEAR)
00824 swap = 1;
00825 #endif
00826 res = phone_write_buf(p, pos, expected, maxfr, swap);
00827 }
00828 if (res != expected) {
00829 if ((errno != EAGAIN) && (errno != EINTR)) {
00830 if (res < 0)
00831 ast_log(LOG_WARNING, "Write returned error (%s)\n", strerror(errno));
00832
00833
00834
00835
00836 #if 0
00837 else
00838 ast_log(LOG_WARNING, "Only wrote %d of %d bytes\n", res, frame->datalen);
00839 #endif
00840 return -1;
00841 } else
00842 res = expected;
00843 }
00844 sofar += res;
00845 pos += res;
00846 }
00847 return 0;
00848 }
00849
00850 static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *cntx, const char *linkedid)
00851 {
00852 struct ast_channel *tmp;
00853 struct phone_codec_data queried_codec;
00854 struct ast_format tmpfmt;
00855 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", i->ext, i->context, linkedid, 0, "Phone/%s", i->dev + 5);
00856 if (tmp) {
00857 ast_channel_tech_set(tmp, cur_tech);
00858 ast_channel_set_fd(tmp, 0, i->fd);
00859
00860 if (i->mode == MODE_FXS &&
00861 ioctl(i->fd, PHONE_QUERY_CODEC, &queried_codec) == 0) {
00862 if (queried_codec.type == LINEAR16) {
00863 ast_format_cap_add(ast_channel_nativeformats(tmp), ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
00864 ast_format_copy(ast_channel_rawreadformat(tmp), &tmpfmt);
00865 ast_format_copy(ast_channel_rawwriteformat(tmp), &tmpfmt);
00866 } else {
00867 ast_format_cap_remove(prefcap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
00868 }
00869 } else {
00870 ast_format_cap_copy(ast_channel_nativeformats(tmp), prefcap);
00871 ast_best_codec(ast_channel_nativeformats(tmp), &tmpfmt);
00872 ast_format_copy(ast_channel_rawreadformat(tmp), &tmpfmt);
00873 ast_format_copy(ast_channel_rawwriteformat(tmp), &tmpfmt);
00874 }
00875
00876 if (state == AST_STATE_RING)
00877 ast_channel_rings_set(tmp, 1);
00878 ast_channel_tech_pvt_set(tmp, i);
00879 ast_channel_context_set(tmp, cntx);
00880 if (!ast_strlen_zero(i->ext))
00881 ast_channel_exten_set(tmp, i->ext);
00882 else
00883 ast_channel_exten_set(tmp, "s");
00884 if (!ast_strlen_zero(i->language))
00885 ast_channel_language_set(tmp, i->language);
00886
00887
00888
00889 if (!ast_strlen_zero(i->cid_num)) {
00890 ast_channel_caller(tmp)->ani.number.valid = 1;
00891 ast_channel_caller(tmp)->ani.number.str = ast_strdup(i->cid_num);
00892 }
00893
00894 i->owner = tmp;
00895 ast_module_ref(ast_module_info->self);
00896 if (state != AST_STATE_DOWN) {
00897 if (state == AST_STATE_RING) {
00898 ioctl(ast_channel_fd(tmp, 0), PHONE_RINGBACK);
00899 i->cpt = 1;
00900 }
00901 if (ast_pbx_start(tmp)) {
00902 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
00903 ast_hangup(tmp);
00904 }
00905 }
00906 } else
00907 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
00908 return tmp;
00909 }
00910
00911 static void phone_mini_packet(struct phone_pvt *i)
00912 {
00913 int res;
00914 char buf[1024];
00915
00916 res = read(i->fd, buf, sizeof(buf));
00917 if (res < 1) {
00918 ast_log(LOG_WARNING, "Read returned %d: %s\n", res, strerror(errno));
00919 return;
00920 }
00921 }
00922
00923 static void phone_check_exception(struct phone_pvt *i)
00924 {
00925 int offhook=0;
00926 char digit[2] = {0 , 0};
00927 union telephony_exception phonee;
00928
00929 #if 0
00930 ast_debug(1, "Exception!\n");
00931 #endif
00932 phonee.bytes = ioctl(i->fd, PHONE_EXCEPTION);
00933 if (phonee.bits.dtmf_ready) {
00934 digit[0] = ioctl(i->fd, PHONE_GET_DTMF_ASCII);
00935 if (i->mode == MODE_DIALTONE || i->mode == MODE_FXS || i->mode == MODE_SIGMA) {
00936 ioctl(i->fd, PHONE_PLAY_STOP);
00937 ioctl(i->fd, PHONE_REC_STOP);
00938 ioctl(i->fd, PHONE_CPT_STOP);
00939 i->dialtone = 0;
00940 if (strlen(i->ext) < AST_MAX_EXTENSION - 1)
00941 strncat(i->ext, digit, sizeof(i->ext) - strlen(i->ext) - 1);
00942 if ((i->mode != MODE_FXS ||
00943 !(phonee.bytes = ioctl(i->fd, PHONE_EXCEPTION)) ||
00944 !phonee.bits.dtmf_ready) &&
00945 ast_exists_extension(NULL, i->context, i->ext, 1, i->cid_num)) {
00946
00947 phone_new(i, AST_STATE_RING, i->context, NULL);
00948
00949 } else if (!ast_canmatch_extension(NULL, i->context, i->ext, 1, i->cid_num)) {
00950
00951
00952 if (ast_exists_extension(NULL, "default", i->ext, 1, i->cid_num)) {
00953
00954 phone_new(i, AST_STATE_RING, "default", NULL);
00955
00956 } else if (!ast_canmatch_extension(NULL, "default", i->ext, 1, i->cid_num)) {
00957
00958 ast_debug(1, "%s can't match anything in %s or default\n", i->ext, i->context);
00959 ioctl(i->fd, PHONE_BUSY);
00960 i->cpt = 1;
00961 }
00962 }
00963 #if 0
00964 ast_verbose("Extension is %s\n", i->ext);
00965 #endif
00966 }
00967 }
00968 if (phonee.bits.hookstate) {
00969 offhook = ioctl(i->fd, PHONE_HOOKSTATE);
00970 if (offhook) {
00971 if (i->mode == MODE_IMMEDIATE) {
00972 phone_new(i, AST_STATE_RING, i->context, NULL);
00973 } else if (i->mode == MODE_DIALTONE) {
00974 ast_module_ref(ast_module_info->self);
00975
00976 i->ext[0] = '\0';
00977
00978 i->dialtone++;
00979 ioctl(i->fd, PHONE_PLAY_STOP);
00980 ioctl(i->fd, PHONE_PLAY_CODEC, ULAW);
00981 ioctl(i->fd, PHONE_PLAY_START);
00982 ast_format_clear(&i->lastformat);
00983 } else if (i->mode == MODE_SIGMA) {
00984 ast_module_ref(ast_module_info->self);
00985
00986 i->ext[0] = '\0';
00987
00988 i->dialtone++;
00989 ioctl(i->fd, PHONE_DIALTONE);
00990 }
00991 } else {
00992 if (i->dialtone)
00993 ast_module_unref(ast_module_info->self);
00994 memset(i->ext, 0, sizeof(i->ext));
00995 if (i->cpt)
00996 {
00997 ioctl(i->fd, PHONE_CPT_STOP);
00998 i->cpt = 0;
00999 }
01000 ioctl(i->fd, PHONE_PLAY_STOP);
01001 ioctl(i->fd, PHONE_REC_STOP);
01002 i->dialtone = 0;
01003 ast_format_clear(&i->lastformat);
01004 }
01005 }
01006 if (phonee.bits.pstn_ring) {
01007 ast_verbose("Unit is ringing\n");
01008 phone_new(i, AST_STATE_RING, i->context, NULL);
01009 }
01010 if (phonee.bits.caller_id)
01011 ast_verbose("We have caller ID\n");
01012
01013
01014 }
01015
01016 static void *do_monitor(void *data)
01017 {
01018 struct pollfd *fds = NULL;
01019 int nfds = 0, inuse_fds = 0, res;
01020 struct phone_pvt *i;
01021 int tonepos = 0;
01022
01023 struct timeval to = { 0, 0 };
01024 int dotone;
01025
01026
01027 while (monitor) {
01028
01029
01030
01031 if (ast_mutex_lock(&iflock)) {
01032 ast_log(LOG_ERROR, "Unable to grab interface lock\n");
01033 return NULL;
01034 }
01035
01036
01037 i = iflist;
01038 dotone = 0;
01039 inuse_fds = 0;
01040 for (i = iflist; i; i = i->next) {
01041 if (!i->owner) {
01042
01043 if (inuse_fds == nfds) {
01044 void *tmp = ast_realloc(fds, (nfds + 1) * sizeof(*fds));
01045 if (!tmp) {
01046
01047 continue;
01048 }
01049 fds = tmp;
01050 nfds++;
01051 }
01052 fds[inuse_fds].fd = i->fd;
01053 fds[inuse_fds].events = POLLIN | POLLERR;
01054 fds[inuse_fds].revents = 0;
01055 inuse_fds++;
01056
01057 if (i->dialtone && i->mode != MODE_SIGMA) {
01058
01059
01060 if (ast_tvzero(to)) {
01061
01062 if (write(i->fd, DialTone + tonepos, 240) != 240) {
01063 ast_log(LOG_WARNING, "Dial tone write error\n");
01064 }
01065 }
01066 dotone++;
01067 }
01068 }
01069 }
01070
01071 ast_mutex_unlock(&iflock);
01072
01073
01074 if (dotone && i && i->mode != MODE_SIGMA) {
01075
01076 tonepos += 240;
01077 if (tonepos >= sizeof(DialTone)) {
01078 tonepos = 0;
01079 }
01080 if (ast_tvzero(to)) {
01081 to = ast_tv(0, 30000);
01082 }
01083 res = ast_poll2(fds, inuse_fds, &to);
01084 } else {
01085 res = ast_poll(fds, inuse_fds, -1);
01086 to = ast_tv(0, 0);
01087 tonepos = 0;
01088 }
01089
01090 if (res < 0) {
01091 ast_debug(1, "poll returned %d: %s\n", res, strerror(errno));
01092 continue;
01093 }
01094
01095
01096 if (!res) {
01097 continue;
01098 }
01099
01100
01101 if (ast_mutex_lock(&iflock)) {
01102 ast_log(LOG_WARNING, "Unable to lock the interface list\n");
01103 continue;
01104 }
01105
01106 for (i = iflist; i; i = i->next) {
01107 int j;
01108
01109 for (j = 0; j < inuse_fds; j++) {
01110 if (fds[j].fd == i->fd) {
01111 break;
01112 }
01113 }
01114
01115
01116 if (j == inuse_fds) {
01117 continue;
01118 }
01119
01120 if (fds[j].revents & POLLIN) {
01121 if (i->owner) {
01122 continue;
01123 }
01124 phone_mini_packet(i);
01125 }
01126 if (fds[j].revents & POLLERR) {
01127 if (i->owner) {
01128 continue;
01129 }
01130 phone_check_exception(i);
01131 }
01132 }
01133 ast_mutex_unlock(&iflock);
01134 }
01135 return NULL;
01136 }
01137
01138 static int restart_monitor()
01139 {
01140
01141 if (monitor_thread == AST_PTHREADT_STOP)
01142 return 0;
01143 if (ast_mutex_lock(&monlock)) {
01144 ast_log(LOG_WARNING, "Unable to lock monitor\n");
01145 return -1;
01146 }
01147 if (monitor_thread == pthread_self()) {
01148 ast_mutex_unlock(&monlock);
01149 ast_log(LOG_WARNING, "Cannot kill myself\n");
01150 return -1;
01151 }
01152 if (monitor_thread != AST_PTHREADT_NULL) {
01153 if (ast_mutex_lock(&iflock)) {
01154 ast_mutex_unlock(&monlock);
01155 ast_log(LOG_WARNING, "Unable to lock the interface list\n");
01156 return -1;
01157 }
01158 monitor = 0;
01159 while (pthread_kill(monitor_thread, SIGURG) == 0)
01160 sched_yield();
01161 pthread_join(monitor_thread, NULL);
01162 ast_mutex_unlock(&iflock);
01163 }
01164 monitor = 1;
01165
01166 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
01167 ast_mutex_unlock(&monlock);
01168 ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
01169 return -1;
01170 }
01171 ast_mutex_unlock(&monlock);
01172 return 0;
01173 }
01174
01175 static struct phone_pvt *mkif(const char *iface, int mode, int txgain, int rxgain)
01176 {
01177
01178 struct phone_pvt *tmp;
01179 int flags;
01180
01181 tmp = ast_calloc(1, sizeof(*tmp));
01182 if (tmp) {
01183 tmp->fd = open(iface, O_RDWR);
01184 if (tmp->fd < 0) {
01185 ast_log(LOG_WARNING, "Unable to open '%s'\n", iface);
01186 ast_free(tmp);
01187 return NULL;
01188 }
01189 if (mode == MODE_FXO) {
01190 if (ioctl(tmp->fd, IXJCTL_PORT, PORT_PSTN)) {
01191 ast_debug(1, "Unable to set port to PSTN\n");
01192 }
01193 } else {
01194 if (ioctl(tmp->fd, IXJCTL_PORT, PORT_POTS))
01195 if (mode != MODE_FXS)
01196 ast_debug(1, "Unable to set port to POTS\n");
01197 }
01198 ioctl(tmp->fd, PHONE_PLAY_STOP);
01199 ioctl(tmp->fd, PHONE_REC_STOP);
01200 ioctl(tmp->fd, PHONE_RING_STOP);
01201 ioctl(tmp->fd, PHONE_CPT_STOP);
01202 if (ioctl(tmp->fd, PHONE_PSTN_SET_STATE, PSTN_ON_HOOK))
01203 ast_debug(1, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n",iface, strerror(errno));
01204 if (echocancel != AEC_OFF)
01205 ioctl(tmp->fd, IXJCTL_AEC_START, echocancel);
01206 if (silencesupression)
01207 tmp->silencesupression = 1;
01208 #ifdef PHONE_VAD
01209 ioctl(tmp->fd, PHONE_VAD, tmp->silencesupression);
01210 #endif
01211 tmp->mode = mode;
01212 flags = fcntl(tmp->fd, F_GETFL);
01213 fcntl(tmp->fd, F_SETFL, flags | O_NONBLOCK);
01214 tmp->owner = NULL;
01215 ast_format_clear(&tmp->lastformat);
01216 ast_format_clear(&tmp->lastinput);
01217 tmp->ministate = 0;
01218 memset(tmp->ext, 0, sizeof(tmp->ext));
01219 ast_copy_string(tmp->language, language, sizeof(tmp->language));
01220 ast_copy_string(tmp->dev, iface, sizeof(tmp->dev));
01221 ast_copy_string(tmp->context, context, sizeof(tmp->context));
01222 tmp->next = NULL;
01223 tmp->obuflen = 0;
01224 tmp->dialtone = 0;
01225 tmp->cpt = 0;
01226 ast_copy_string(tmp->cid_num, cid_num, sizeof(tmp->cid_num));
01227 ast_copy_string(tmp->cid_name, cid_name, sizeof(tmp->cid_name));
01228 tmp->txgain = txgain;
01229 ioctl(tmp->fd, PHONE_PLAY_VOLUME, tmp->txgain);
01230 tmp->rxgain = rxgain;
01231 ioctl(tmp->fd, PHONE_REC_VOLUME, tmp->rxgain);
01232 }
01233 return tmp;
01234 }
01235
01236 static struct ast_channel *phone_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
01237 {
01238 struct phone_pvt *p;
01239 struct ast_channel *tmp = NULL;
01240 const char *name = data;
01241
01242
01243 if (ast_mutex_lock(&iflock)) {
01244 ast_log(LOG_ERROR, "Unable to lock interface list???\n");
01245 return NULL;
01246 }
01247 p = iflist;
01248 while(p) {
01249 if (p->mode == MODE_FXS || (ast_format_cap_has_joint(cap, phone_tech.capabilities))) {
01250 size_t length = strlen(p->dev + 5);
01251 if (strncmp(name, p->dev + 5, length) == 0 &&
01252 !isalnum(name[length])) {
01253 if (!p->owner) {
01254 tmp = phone_new(p, AST_STATE_DOWN, p->context, requestor ? ast_channel_linkedid(requestor) : NULL);
01255 break;
01256 } else
01257 *cause = AST_CAUSE_BUSY;
01258 }
01259 }
01260 p = p->next;
01261 }
01262 ast_mutex_unlock(&iflock);
01263 restart_monitor();
01264 if (tmp == NULL) {
01265 if (!(ast_format_cap_has_joint(cap, phone_tech.capabilities))) {
01266 char buf[256];
01267 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), cap));
01268 return NULL;
01269 }
01270 }
01271 return tmp;
01272 }
01273
01274
01275 static int parse_gain_value(const char *gain_type, const char *value)
01276 {
01277 float gain;
01278
01279
01280 if (sscanf(value, "%30f", &gain) != 1)
01281 {
01282 ast_log(LOG_ERROR, "Invalid %s value '%s' in '%s' config\n",
01283 value, gain_type, config);
01284 return DEFAULT_GAIN;
01285 }
01286
01287
01288 gain = gain * (float)DEFAULT_GAIN;
01289
01290
01291 if (value[strlen(value) - 1] == '%')
01292 return (int)(gain / (float)100);
01293
01294 return (int)gain;
01295 }
01296
01297 static int __unload_module(void)
01298 {
01299 struct phone_pvt *p, *pl;
01300
01301 if (cur_tech)
01302 ast_channel_unregister(cur_tech);
01303 if (!ast_mutex_lock(&iflock)) {
01304
01305 p = iflist;
01306 while(p) {
01307 if (p->owner)
01308 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
01309 p = p->next;
01310 }
01311 iflist = NULL;
01312 ast_mutex_unlock(&iflock);
01313 } else {
01314 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
01315 return -1;
01316 }
01317 if (!ast_mutex_lock(&monlock)) {
01318 if (monitor_thread > AST_PTHREADT_NULL) {
01319 monitor = 0;
01320 while (pthread_kill(monitor_thread, SIGURG) == 0)
01321 sched_yield();
01322 pthread_join(monitor_thread, NULL);
01323 }
01324 monitor_thread = AST_PTHREADT_STOP;
01325 ast_mutex_unlock(&monlock);
01326 } else {
01327 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
01328 return -1;
01329 }
01330
01331 if (!ast_mutex_lock(&iflock)) {
01332
01333 p = iflist;
01334 while(p) {
01335
01336 if (p->fd > -1)
01337 close(p->fd);
01338 pl = p;
01339 p = p->next;
01340
01341 ast_free(pl);
01342 }
01343 iflist = NULL;
01344 ast_mutex_unlock(&iflock);
01345 } else {
01346 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
01347 return -1;
01348 }
01349
01350 phone_tech.capabilities = ast_format_cap_destroy(phone_tech.capabilities);
01351 phone_tech_fxs.capabilities = ast_format_cap_destroy(phone_tech_fxs.capabilities);
01352 prefcap = ast_format_cap_destroy(prefcap);
01353 return 0;
01354 }
01355
01356 static int unload_module(void)
01357 {
01358 return __unload_module();
01359 }
01360
01361 static int load_module(void)
01362 {
01363 struct ast_config *cfg;
01364 struct ast_variable *v;
01365 struct phone_pvt *tmp;
01366 int mode = MODE_IMMEDIATE;
01367 int txgain = DEFAULT_GAIN, rxgain = DEFAULT_GAIN;
01368 struct ast_flags config_flags = { 0 };
01369 struct ast_format tmpfmt;
01370
01371 if (!(phone_tech.capabilities = ast_format_cap_alloc())) {
01372 return AST_MODULE_LOAD_DECLINE;
01373 }
01374 ast_format_cap_add(phone_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_G723_1, 0));
01375 ast_format_cap_add(phone_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
01376 ast_format_cap_add(phone_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
01377 ast_format_cap_add(phone_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_G729A, 0));
01378
01379 if (!(prefcap = ast_format_cap_alloc())) {
01380 return AST_MODULE_LOAD_DECLINE;
01381 }
01382 ast_format_cap_copy(prefcap, phone_tech.capabilities);
01383 if (!(phone_tech_fxs.capabilities = ast_format_cap_alloc())) {
01384 return AST_MODULE_LOAD_DECLINE;
01385 }
01386
01387 if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) {
01388 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config);
01389 return AST_MODULE_LOAD_DECLINE;
01390 }
01391
01392
01393 if (!cfg) {
01394 ast_log(LOG_ERROR, "Unable to load config %s\n", config);
01395 return AST_MODULE_LOAD_DECLINE;
01396 }
01397 if (ast_mutex_lock(&iflock)) {
01398
01399 ast_log(LOG_ERROR, "Unable to lock interface list???\n");
01400 return AST_MODULE_LOAD_FAILURE;
01401 }
01402 v = ast_variable_browse(cfg, "interfaces");
01403 while(v) {
01404
01405 if (!strcasecmp(v->name, "device")) {
01406 tmp = mkif(v->value, mode, txgain, rxgain);
01407 if (tmp) {
01408 tmp->next = iflist;
01409 iflist = tmp;
01410
01411 } else {
01412 ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value);
01413 ast_config_destroy(cfg);
01414 ast_mutex_unlock(&iflock);
01415 __unload_module();
01416 return AST_MODULE_LOAD_FAILURE;
01417 }
01418 } else if (!strcasecmp(v->name, "silencesupression")) {
01419 silencesupression = ast_true(v->value);
01420 } else if (!strcasecmp(v->name, "language")) {
01421 ast_copy_string(language, v->value, sizeof(language));
01422 } else if (!strcasecmp(v->name, "callerid")) {
01423 ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
01424 } else if (!strcasecmp(v->name, "mode")) {
01425 if (!strncasecmp(v->value, "di", 2))
01426 mode = MODE_DIALTONE;
01427 else if (!strncasecmp(v->value, "sig", 3))
01428 mode = MODE_SIGMA;
01429 else if (!strncasecmp(v->value, "im", 2))
01430 mode = MODE_IMMEDIATE;
01431 else if (!strncasecmp(v->value, "fxs", 3)) {
01432 mode = MODE_FXS;
01433 ast_format_cap_remove_bytype(prefcap, AST_FORMAT_TYPE_AUDIO);
01434 }
01435 else if (!strncasecmp(v->value, "fx", 2))
01436 mode = MODE_FXO;
01437 else
01438 ast_log(LOG_WARNING, "Unknown mode: %s\n", v->value);
01439 } else if (!strcasecmp(v->name, "context")) {
01440 ast_copy_string(context, v->value, sizeof(context));
01441 } else if (!strcasecmp(v->name, "format")) {
01442 if (!strcasecmp(v->value, "g729")) {
01443 ast_format_cap_set(prefcap, ast_format_set(&tmpfmt, AST_FORMAT_G729A, 0));
01444 } else if (!strcasecmp(v->value, "g723.1")) {
01445 ast_format_cap_set(prefcap, ast_format_set(&tmpfmt, AST_FORMAT_G723_1, 0));
01446 } else if (!strcasecmp(v->value, "slinear")) {
01447 ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0);
01448 if (mode == MODE_FXS) {
01449 ast_format_cap_add(prefcap, &tmpfmt);
01450 } else {
01451 ast_format_cap_set(prefcap, &tmpfmt);
01452 }
01453 } else if (!strcasecmp(v->value, "ulaw")) {
01454 ast_format_cap_set(prefcap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
01455 } else
01456 ast_log(LOG_WARNING, "Unknown format '%s'\n", v->value);
01457 } else if (!strcasecmp(v->name, "echocancel")) {
01458 if (!strcasecmp(v->value, "off")) {
01459 echocancel = AEC_OFF;
01460 } else if (!strcasecmp(v->value, "low")) {
01461 echocancel = AEC_LOW;
01462 } else if (!strcasecmp(v->value, "medium")) {
01463 echocancel = AEC_MED;
01464 } else if (!strcasecmp(v->value, "high")) {
01465 echocancel = AEC_HIGH;
01466 } else
01467 ast_log(LOG_WARNING, "Unknown echo cancellation '%s'\n", v->value);
01468 } else if (!strcasecmp(v->name, "txgain")) {
01469 txgain = parse_gain_value(v->name, v->value);
01470 } else if (!strcasecmp(v->name, "rxgain")) {
01471 rxgain = parse_gain_value(v->name, v->value);
01472 }
01473 v = v->next;
01474 }
01475 ast_mutex_unlock(&iflock);
01476
01477 if (mode == MODE_FXS) {
01478 ast_format_cap_copy(phone_tech_fxs.capabilities, prefcap);
01479 cur_tech = &phone_tech_fxs;
01480 } else
01481 cur_tech = (struct ast_channel_tech *) &phone_tech;
01482
01483
01484
01485 if (ast_channel_register(cur_tech)) {
01486 ast_log(LOG_ERROR, "Unable to register channel class 'Phone'\n");
01487 ast_config_destroy(cfg);
01488 __unload_module();
01489 return AST_MODULE_LOAD_FAILURE;
01490 }
01491 ast_config_destroy(cfg);
01492
01493 restart_monitor();
01494 return AST_MODULE_LOAD_SUCCESS;
01495 }
01496
01497 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Linux Telephony API Support");