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 #include <stdio.h>
00030 #include <pthread.h>
00031 #include <string.h>
00032 #include <sys/socket.h>
00033 #include <sys/time.h>
00034 #include <errno.h>
00035 #include <unistd.h>
00036 #include <stdlib.h>
00037 #include <arpa/inet.h>
00038 #include <fcntl.h>
00039 #include <sys/ioctl.h>
00040 #include <sys/file.h>
00041
00042 #include <asterisk/channel.h>
00043 #include <asterisk/config.h>
00044 #include <asterisk/logger.h>
00045 #include <asterisk/module.h>
00046 #include <asterisk/pbx.h>
00047 #include <asterisk/options.h>
00048 #include <asterisk/io.h>
00049 #include <asterisk/frame.h>
00050 #include <asterisk/translate.h>
00051 #include <asterisk/cli.h>
00052 #include <asterisk/musiconhold.h>
00053 #include <asterisk/dsp.h>
00054 #include <asterisk/translate.h>
00055 #include <asterisk/config.h>
00056 #include <asterisk/file.h>
00057 #include <asterisk/callerid.h>
00058 #include <asterisk/indications.h>
00059 #include <asterisk/app.h>
00060 #include <asterisk/features.h>
00061
00062 #include <chan_misdn_config.h>
00063 #include <isdn_lib.h>
00064
00065 char global_tracefile[BUFFERSIZE+1];
00066
00067
00068 struct misdn_jb{
00069 int size;
00070 int upper_threshold;
00071 char *samples, *ok;
00072 int wp,rp;
00073 int state_empty;
00074 int state_full;
00075 int state_buffer;
00076 int bytes_wrote;
00077 ast_mutex_t mutexjb;
00078 };
00079
00080
00081
00082
00083 struct misdn_jb *misdn_jb_init(int size, int upper_threshold);
00084
00085
00086 void misdn_jb_destroy(struct misdn_jb *jb);
00087
00088
00089
00090 int misdn_jb_fill(struct misdn_jb *jb, const char *data, int len);
00091
00092
00093
00094
00095 int misdn_jb_empty(struct misdn_jb *jb, char *data, int len);
00096
00097
00098
00099
00100
00101
00102
00103
00104 enum misdn_chan_state {
00105 MISDN_NOTHING,
00106 MISDN_WAITING4DIGS,
00107 MISDN_EXTCANTMATCH,
00108 MISDN_DIALING,
00109 MISDN_PROGRESS,
00110 MISDN_PROCEEDING,
00111 MISDN_CALLING,
00112 MISDN_CALLING_ACKNOWLEDGE,
00113 MISDN_ALERTING,
00114 MISDN_BUSY,
00115 MISDN_CONNECTED,
00116 MISDN_PRECONNECTED,
00117 MISDN_DISCONNECTED,
00118 MISDN_RELEASED,
00119 MISDN_BRIDGED,
00120 MISDN_CLEANING,
00121 MISDN_HUNGUP_FROM_MISDN,
00122 MISDN_HUNGUP_FROM_AST,
00123
00124 MISDN_HOLDED,
00125 MISDN_HOLD_DISCONNECT
00126
00127 };
00128
00129 #define ORG_AST 1
00130 #define ORG_MISDN 2
00131
00132 struct chan_list {
00133
00134 ast_mutex_t lock;
00135
00136 char allowed_bearers[BUFFERSIZE+1];
00137
00138 enum misdn_chan_state state;
00139 int need_queue_hangup;
00140 int need_hangup;
00141 int need_busy;
00142
00143 int orginator;
00144
00145 int norxtone;
00146 int notxtone;
00147
00148 int toggle_ec;
00149
00150 int incoming_early_audio;
00151
00152 int ignore_dtmf;
00153
00154 int pipe[2];
00155 char ast_rd_buf[4096];
00156 struct ast_frame frame;
00157
00158 int faxdetect;
00159 int faxhandled;
00160
00161 int ast_dsp;
00162
00163 int jb_len;
00164 int jb_upper_threshold;
00165 struct misdn_jb *jb;
00166
00167 struct ast_dsp *dsp;
00168 struct ast_trans_pvt *trans;
00169
00170 struct ast_channel * ast;
00171
00172 int dummy;
00173
00174 struct misdn_bchannel *bc;
00175 struct misdn_bchannel *holded_bc;
00176
00177 unsigned int l3id;
00178 int addr;
00179
00180 char context[BUFFERSIZE];
00181
00182 int zero_read_cnt;
00183 int dropped_frame_cnt;
00184
00185 int far_alerting;
00186 int other_pid;
00187 struct chan_list *other_ch;
00188
00189 const struct tone_zone_sound *ts;
00190
00191 struct chan_list *peer;
00192 struct chan_list *next;
00193 struct chan_list *prev;
00194 struct chan_list *first;
00195 };
00196
00197
00198
00199 void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch);
00200 void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch);
00201
00202 struct robin_list {
00203 char *group;
00204 int port;
00205 int channel;
00206 struct robin_list *next;
00207 struct robin_list *prev;
00208 };
00209 static struct robin_list *robin = NULL;
00210
00211
00212
00213 struct ast_frame *process_ast_dsp(struct chan_list *tmp, struct ast_frame *frame);
00214
00215
00216
00217 static inline void free_robin_list_r (struct robin_list *r)
00218 {
00219 if (r) {
00220 if (r->next) free_robin_list_r(r->next);
00221 if (r->group) free(r->group);
00222 free(r);
00223 }
00224 }
00225
00226 static void free_robin_list ( void )
00227 {
00228 free_robin_list_r(robin);
00229 robin = NULL;
00230 }
00231
00232 static struct robin_list* get_robin_position (char *group)
00233 {
00234 struct robin_list *iter = robin;
00235 for (; iter; iter = iter->next) {
00236 if (!strcasecmp(iter->group, group))
00237 return iter;
00238 }
00239 struct robin_list *new = (struct robin_list *)calloc(1, sizeof(struct robin_list));
00240 new->group = strndup(group, strlen(group));
00241 new->channel = 1;
00242 if (robin) {
00243 new->next = robin;
00244 robin->prev = new;
00245 }
00246 robin = new;
00247 return robin;
00248 }
00249
00250
00251 static void chan_misdn_log(int level, int port, char *tmpl, ...);
00252
00253 static struct ast_channel *misdn_new(struct chan_list *cl, int state, char *exten, char *callerid, int format, int port, int c);
00254 static void send_digit_to_chan(struct chan_list *cl, char digit );
00255
00256
00257 #define AST_CID_P(ast) ast->cid.cid_num
00258 #define AST_BRIDGED_P(ast) ast_bridged_channel(ast)
00259 #define AST_LOAD_CFG ast_config_load
00260 #define AST_DESTROY_CFG ast_config_destroy
00261
00262 #define MISDN_ASTERISK_TECH_PVT(ast) ast->tech_pvt
00263 #define MISDN_ASTERISK_PVT(ast) 1
00264
00265 #include <asterisk/strings.h>
00266
00267
00268
00269 static char *desc = "Channel driver for mISDN Support (Bri/Pri)";
00270 static const char misdn_type[] = "mISDN";
00271
00272 static int tracing = 0 ;
00273
00274 static int usecnt=0;
00275
00276 static char **misdn_key_vector=NULL;
00277 static int misdn_key_vector_size=0;
00278
00279
00280 static int prefformat = AST_FORMAT_ALAW ;
00281
00282 static ast_mutex_t usecnt_lock;
00283
00284 static int *misdn_debug;
00285 static int *misdn_debug_only;
00286 static int max_ports;
00287
00288 struct chan_list dummy_cl;
00289
00290 struct chan_list *cl_te=NULL;
00291 ast_mutex_t cl_te_lock;
00292
00293 static enum event_response_e
00294 cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data);
00295
00296 static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel*bc, struct chan_list *ch);
00297
00298 static void cl_queue_chan(struct chan_list **list, struct chan_list *chan);
00299 static void cl_dequeue_chan(struct chan_list **list, struct chan_list *chan);
00300 static struct chan_list *find_chan_by_bc(struct chan_list *list, struct misdn_bchannel *bc);
00301 static struct chan_list *find_chan_by_pid(struct chan_list *list, int pid);
00302
00303
00304
00305 static int dialtone_indicate(struct chan_list *cl);
00306 static int hanguptone_indicate(struct chan_list *cl);
00307 static int stop_indicate(struct chan_list *cl);
00308
00309 static int start_bc_tones(struct chan_list *cl);
00310 static int stop_bc_tones(struct chan_list *cl);
00311 static void release_chan(struct misdn_bchannel *bc);
00312
00313 static int misdn_set_opt_exec(struct ast_channel *chan, void *data);
00314 static int misdn_facility_exec(struct ast_channel *chan, void *data);
00315
00316 int chan_misdn_jb_empty(struct misdn_bchannel *bc, char *buf, int len);
00317
00318 static int update_ec_config(struct misdn_bchannel *bc);
00319
00320
00321
00322 static struct chan_list * get_chan_by_ast(struct ast_channel *ast)
00323 {
00324 struct chan_list *tmp;
00325
00326 for (tmp=cl_te; tmp; tmp = tmp->next) {
00327 if ( tmp->ast == ast ) return tmp;
00328 }
00329
00330 return NULL;
00331 }
00332
00333 static struct chan_list * get_chan_by_ast_name(char *name)
00334 {
00335 struct chan_list *tmp;
00336
00337 for (tmp=cl_te; tmp; tmp = tmp->next) {
00338 if ( tmp->ast && strcmp(tmp->ast->name,name) == 0) return tmp;
00339 }
00340
00341 return NULL;
00342 }
00343
00344
00345
00346 struct allowed_bearers {
00347 int cap;
00348 int val;
00349 char *name;
00350 };
00351
00352 struct allowed_bearers allowed_bearers_array[]={
00353 {INFO_CAPABILITY_SPEECH,1,"speech"},
00354 {INFO_CAPABILITY_AUDIO_3_1K,2,"3_1khz"},
00355 {INFO_CAPABILITY_DIGITAL_UNRESTRICTED,4,"digital_unrestricted"},
00356 {INFO_CAPABILITY_DIGITAL_RESTRICTED,8,"digital_restriced"},
00357 {INFO_CAPABILITY_VIDEO,16,"video"}
00358 };
00359
00360 static char *bearer2str(int cap) {
00361 static char *bearers[]={
00362 "Speech",
00363 "Audio 3.1k",
00364 "Unres Digital",
00365 "Res Digital",
00366 "Video",
00367 "Unknown Bearer"
00368 };
00369
00370 switch (cap) {
00371 case INFO_CAPABILITY_SPEECH:
00372 return bearers[0];
00373 break;
00374 case INFO_CAPABILITY_AUDIO_3_1K:
00375 return bearers[1];
00376 break;
00377 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
00378 return bearers[2];
00379 break;
00380 case INFO_CAPABILITY_DIGITAL_RESTRICTED:
00381 return bearers[3];
00382 break;
00383 case INFO_CAPABILITY_VIDEO:
00384 return bearers[4];
00385 break;
00386 default:
00387 return bearers[5];
00388 break;
00389 }
00390 }
00391
00392
00393 static void print_facility( struct misdn_bchannel *bc)
00394 {
00395 switch (bc->fac_type) {
00396 case FACILITY_CALLDEFLECT:
00397 chan_misdn_log(2,bc->port," --> calldeflect: %s\n",
00398 bc->fac.calldeflect_nr);
00399 break;
00400 case FACILITY_CENTREX:
00401 chan_misdn_log(2,bc->port," --> centrex: %s\n",
00402 bc->fac.cnip);
00403 break;
00404 default:
00405 chan_misdn_log(2,bc->port," --> unknown\n");
00406
00407 }
00408 }
00409
00410 static void print_bearer(struct misdn_bchannel *bc)
00411 {
00412
00413 chan_misdn_log(2, bc->port, " --> Bearer: %s\n",bearer2str(bc->capability));
00414
00415 switch(bc->law) {
00416 case INFO_CODEC_ALAW:
00417 chan_misdn_log(2, bc->port, " --> Codec: Alaw\n");
00418 break;
00419 case INFO_CODEC_ULAW:
00420 chan_misdn_log(2, bc->port, " --> Codec: Ulaw\n");
00421 break;
00422 }
00423 }
00424
00425
00426 static void send_digit_to_chan(struct chan_list *cl, char digit )
00427 {
00428 static const char* dtmf_tones[] = {
00429 "!941+1336/100,!0/100",
00430 "!697+1209/100,!0/100",
00431 "!697+1336/100,!0/100",
00432 "!697+1477/100,!0/100",
00433 "!770+1209/100,!0/100",
00434 "!770+1336/100,!0/100",
00435 "!770+1477/100,!0/100",
00436 "!852+1209/100,!0/100",
00437 "!852+1336/100,!0/100",
00438 "!852+1477/100,!0/100",
00439 "!697+1633/100,!0/100",
00440 "!770+1633/100,!0/100",
00441 "!852+1633/100,!0/100",
00442 "!941+1633/100,!0/100",
00443 "!941+1209/100,!0/100",
00444 "!941+1477/100,!0/100" };
00445 struct ast_channel *chan=cl->ast;
00446
00447 if (digit >= '0' && digit <='9')
00448 ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0);
00449 else if (digit >= 'A' && digit <= 'D')
00450 ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0);
00451 else if (digit == '*')
00452 ast_playtones_start(chan,0,dtmf_tones[14], 0);
00453 else if (digit == '#')
00454 ast_playtones_start(chan,0,dtmf_tones[15], 0);
00455 else {
00456
00457 ast_log(LOG_DEBUG, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name);
00458
00459
00460 }
00461 }
00462
00463 static int misdn_set_debug(int fd, int argc, char *argv[])
00464 {
00465 if (argc != 4 && argc != 5 && argc != 6 && argc != 7)
00466 return RESULT_SHOWUSAGE;
00467
00468 int level = atoi(argv[3]);
00469
00470 switch (argc) {
00471 case 4:
00472 case 5: {
00473 int only = 0;
00474 if (argc == 5) {
00475 if (strncasecmp(argv[4], "only", strlen(argv[4])))
00476 return RESULT_SHOWUSAGE;
00477 else
00478 only = 1;
00479 }
00480 int i;
00481 for (i=0; i<=max_ports; i++) {
00482 misdn_debug[i] = level;
00483 misdn_debug_only[i] = only;
00484 }
00485 ast_cli(fd, "changing debug level for all ports to %d%s\n",misdn_debug[0], only?" (only)":"");
00486 }
00487 break;
00488 case 6:
00489 case 7: {
00490 if (strncasecmp(argv[4], "port", strlen(argv[4])))
00491 return RESULT_SHOWUSAGE;
00492 int port = atoi(argv[5]);
00493 if (port <= 0 || port > max_ports) {
00494 switch (max_ports) {
00495 case 0:
00496 ast_cli(fd, "port number not valid! no ports available so you won't get lucky with any number here...\n");
00497 break;
00498 case 1:
00499 ast_cli(fd, "port number not valid! only port 1 is availble.\n");
00500 break;
00501 default:
00502 ast_cli(fd, "port number not valid! only ports 1 to %d are available.\n", max_ports);
00503 }
00504 return 0;
00505 }
00506 if (argc == 7) {
00507 if (strncasecmp(argv[6], "only", strlen(argv[6])))
00508 return RESULT_SHOWUSAGE;
00509 else
00510 misdn_debug_only[port] = 1;
00511 } else
00512 misdn_debug_only[port] = 0;
00513 misdn_debug[port] = level;
00514 ast_cli(fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port]?" (only)":"", port);
00515 }
00516 }
00517 return 0;
00518 }
00519
00520 static int misdn_set_crypt_debug(int fd, int argc, char *argv[])
00521 {
00522 if (argc != 5) return RESULT_SHOWUSAGE;
00523
00524 return 0;
00525 }
00526
00527
00528 static int misdn_port_block(int fd, int argc, char *argv[])
00529 {
00530 int port;
00531
00532 if (argc != 4)
00533 return RESULT_SHOWUSAGE;
00534
00535 port = atoi(argv[3]);
00536
00537 misdn_lib_port_block(port);
00538
00539 return 0;
00540 }
00541
00542 static int misdn_port_unblock(int fd, int argc, char *argv[])
00543 {
00544 int port;
00545
00546 if (argc != 4)
00547 return RESULT_SHOWUSAGE;
00548
00549 port = atoi(argv[3]);
00550
00551 misdn_lib_port_unblock(port);
00552
00553 return 0;
00554 }
00555
00556
00557 static int misdn_restart_port (int fd, int argc, char *argv[])
00558 {
00559 int port;
00560
00561 if (argc != 4)
00562 return RESULT_SHOWUSAGE;
00563
00564 port = atoi(argv[3]);
00565
00566 misdn_lib_port_restart(port);
00567
00568 return 0;
00569 }
00570
00571 static int misdn_port_up (int fd, int argc, char *argv[])
00572 {
00573 int port;
00574
00575 if (argc != 4)
00576 return RESULT_SHOWUSAGE;
00577
00578 port = atoi(argv[3]);
00579
00580 misdn_lib_get_port_up(port);
00581
00582 return 0;
00583 }
00584
00585 static int misdn_port_down (int fd, int argc, char *argv[])
00586 {
00587 int port;
00588
00589 if (argc != 4)
00590 return RESULT_SHOWUSAGE;
00591
00592 port = atoi(argv[3]);
00593
00594 misdn_lib_get_port_down(port);
00595
00596 return 0;
00597 }
00598
00599
00600 static int misdn_show_config (int fd, int argc, char *argv[])
00601 {
00602 char buffer[BUFFERSIZE];
00603 enum misdn_cfg_elements elem;
00604 int linebreak;
00605
00606 int onlyport = -1;
00607 if (argc >= 4) {
00608 if (!sscanf(argv[3], "%d", &onlyport) || onlyport < 0) {
00609 ast_cli(fd, "Unknown option: %s\n", argv[3]);
00610 return RESULT_SHOWUSAGE;
00611 }
00612 }
00613
00614 if (argc == 3 || onlyport == 0) {
00615 ast_cli(fd,"Misdn General-Config: \n");
00616 ast_cli(fd," -> Version: chan_misdn-" CHAN_MISDN_VERSION "\n");
00617 for (elem = MISDN_GEN_FIRST + 1, linebreak = 1; elem < MISDN_GEN_LAST; elem++, linebreak++) {
00618 misdn_cfg_get_config_string( 0, elem, buffer, BUFFERSIZE);
00619 ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
00620 }
00621 ast_cli(fd, "\n");
00622 }
00623
00624 if (onlyport < 0) {
00625 int port = misdn_cfg_get_next_port(0);
00626 for (; port > 0; port = misdn_cfg_get_next_port(port)) {
00627 ast_cli(fd, "\n[PORT %d]\n", port);
00628 for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
00629 misdn_cfg_get_config_string( port, elem, buffer, BUFFERSIZE);
00630 ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
00631 }
00632 ast_cli(fd, "\n");
00633 }
00634 }
00635
00636 if (onlyport > 0) {
00637 if (misdn_cfg_is_port_valid(onlyport)) {
00638 ast_cli(fd, "[PORT %d]\n", onlyport);
00639 for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
00640 misdn_cfg_get_config_string( onlyport, elem, buffer, BUFFERSIZE);
00641 ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
00642 }
00643 ast_cli(fd, "\n");
00644 } else {
00645 ast_cli(fd, "Port %d is not active!\n", onlyport);
00646 }
00647 }
00648 return 0;
00649 }
00650
00651 struct state_struct {
00652 enum misdn_chan_state state;
00653 char txt[255] ;
00654 } ;
00655
00656 static struct state_struct state_array[] = {
00657 {MISDN_NOTHING,"NOTHING"},
00658 {MISDN_WAITING4DIGS,"WAITING4DIGS"},
00659 {MISDN_EXTCANTMATCH,"EXTCANTMATCH"},
00660 {MISDN_DIALING,"DIALING"},
00661 {MISDN_PROGRESS,"PROGRESS"},
00662 {MISDN_PROCEEDING,"PROCEEDING"},
00663 {MISDN_CALLING,"CALLING"},
00664 {MISDN_CALLING_ACKNOWLEDGE,"CALLING_ACKNOWLEDGE"},
00665 {MISDN_ALERTING,"ALERTING"},
00666 {MISDN_BUSY,"BUSY"},
00667 {MISDN_CONNECTED,"CONNECTED"},
00668 {MISDN_PRECONNECTED,"PRECONNECTED"},
00669 {MISDN_DISCONNECTED,"DISCONNECTED"},
00670 {MISDN_RELEASED,"RELEASED"},
00671 {MISDN_BRIDGED,"BRIDGED"},
00672 {MISDN_CLEANING,"CLEANING"},
00673 {MISDN_HUNGUP_FROM_MISDN,"HUNGUP_FROM_MISDN"},
00674 {MISDN_HOLDED,"HOLDED"},
00675 {MISDN_HOLD_DISCONNECT,"HOLD_DISCONNECT"},
00676 {MISDN_HUNGUP_FROM_AST,"HUNGUP_FROM_AST"}
00677
00678 };
00679
00680 static char *misdn_get_ch_state(struct chan_list *p)
00681 {
00682 int i;
00683 static char state[8];
00684
00685 if( !p) return NULL;
00686
00687 for (i=0; i< sizeof(state_array)/sizeof(struct state_struct); i++) {
00688 if ( state_array[i].state == p->state) return state_array[i].txt;
00689 }
00690
00691 sprintf(state,"%d",p->state) ;
00692
00693 return state;
00694 }
00695
00696
00697
00698 void reload_config(void)
00699 {
00700 int i, cfg_debug;
00701
00702 free_robin_list();
00703 misdn_cfg_reload();
00704 misdn_cfg_update_ptp();
00705 misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
00706 misdn_cfg_get( 0, MISDN_GEN_DEBUG, &cfg_debug, sizeof(int));
00707
00708 for (i = 0; i <= max_ports; i++) {
00709 misdn_debug[i] = cfg_debug;
00710 misdn_debug_only[i] = 0;
00711 }
00712 }
00713
00714 static int misdn_reload (int fd, int argc, char *argv[])
00715 {
00716 ast_cli(fd, "Reloading mISDN Config\n");
00717 reload_config();
00718 return 0;
00719 }
00720
00721 static void print_bc_info (int fd, struct chan_list* help, struct misdn_bchannel* bc)
00722 {
00723 struct ast_channel *ast=help->ast;
00724 ast_cli(fd,
00725 "* Pid:%d Prt:%d Ch:%d Mode:%s Org:%s dad:%s oad:%s rad:%s ctx:%s state:%s\n",
00726
00727 bc->pid, bc->port, bc->channel,
00728 bc->nt?"NT":"TE",
00729 help->orginator == ORG_AST?"*":"I",
00730 ast?ast->exten:NULL,
00731 ast?AST_CID_P(ast):NULL,
00732 bc->rad,
00733 ast?ast->context:NULL,
00734 misdn_get_ch_state(help)
00735 );
00736 if (misdn_debug[bc->port] > 0)
00737 ast_cli(fd,
00738 " --> astname: %s\n"
00739 " --> ch_l3id: %x\n"
00740 " --> ch_addr: %x\n"
00741 " --> bc_addr: %x\n"
00742 " --> bc_l3id: %x\n"
00743 " --> display: %s\n"
00744 " --> activated: %d\n"
00745 " --> state: %s\n"
00746 " --> capability: %s\n"
00747 " --> echo_cancel: %d\n"
00748 " --> notone : rx %d tx:%d\n"
00749 " --> bc_hold: %d holded_bc :%d\n",
00750 help->ast->name,
00751 help->l3id,
00752 help->addr,
00753 bc->addr,
00754 bc?bc->l3_id:-1,
00755 bc->display,
00756
00757 bc->active,
00758 bc_state2str(bc->bc_state),
00759 bearer2str(bc->capability),
00760 bc->ec_enable,
00761
00762 help->norxtone,help->notxtone,
00763 bc->holded, help->holded_bc?1:0
00764 );
00765
00766 }
00767
00768 static int misdn_show_cls (int fd, int argc, char *argv[])
00769 {
00770 struct chan_list *help=cl_te;
00771
00772 ast_cli(fd,"Chan List: %p\n",cl_te);
00773
00774 for (;help; help=help->next) {
00775 struct misdn_bchannel *bc=help->bc;
00776 struct ast_channel *ast=help->ast;
00777 if (misdn_debug[0] > 2) ast_cli(fd, "Bc:%p Ast:%p\n", bc, ast);
00778 if (bc) {
00779 print_bc_info(fd, help, bc);
00780 } else if ( (bc=help->holded_bc) ) {
00781 chan_misdn_log(0, 0, "ITS A HOLDED BC:\n");
00782 print_bc_info(fd, help, bc);
00783 } else {
00784 ast_cli(fd,"* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, AST_CID_P(ast));
00785 }
00786 }
00787
00788
00789 return 0;
00790 }
00791
00792 static int misdn_show_cl (int fd, int argc, char *argv[])
00793 {
00794 struct chan_list *help=cl_te;
00795
00796 if (argc != 4)
00797 return RESULT_SHOWUSAGE;
00798
00799 for (;help; help=help->next) {
00800 struct misdn_bchannel *bc=help->bc;
00801 struct ast_channel *ast=help->ast;
00802
00803 if (bc && ast) {
00804 if (!strcasecmp(ast->name,argv[3])) {
00805 print_bc_info(fd, help, bc);
00806 break;
00807 }
00808 }
00809 }
00810
00811
00812 return 0;
00813 }
00814
00815 ast_mutex_t lock;
00816 int MAXTICS=8;
00817
00818 static int misdn_set_tics (int fd, int argc, char *argv[])
00819 {
00820 if (argc != 4)
00821 return RESULT_SHOWUSAGE;
00822
00823 MAXTICS=atoi(argv[3]);
00824
00825 return 0;
00826 }
00827
00828 static int misdn_show_stacks (int fd, int argc, char *argv[])
00829 {
00830 int port;
00831
00832 ast_cli(fd, "BEGIN STACK_LIST:\n");
00833
00834 for (port=misdn_cfg_get_next_port(0); port > 0;
00835 port=misdn_cfg_get_next_port(port)) {
00836 char buf[128];
00837 get_show_stack_details(port,buf);
00838 ast_cli(fd," %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port]?"(only)":"");
00839 }
00840
00841
00842 return 0;
00843
00844 }
00845
00846 static int misdn_show_port (int fd, int argc, char *argv[])
00847 {
00848 int port;
00849
00850 if (argc != 4)
00851 return RESULT_SHOWUSAGE;
00852
00853 port = atoi(argv[3]);
00854
00855 ast_cli(fd, "BEGIN STACK_LIST:\n");
00856
00857 char buf[128];
00858 get_show_stack_details(port,buf);
00859 ast_cli(fd," %s Debug:%d%s\n",buf, misdn_debug[port], misdn_debug_only[port]?"(only)":"");
00860
00861
00862 return 0;
00863 }
00864
00865 static int misdn_send_cd (int fd, int argc, char *argv[])
00866 {
00867 char *channame;
00868 char *nr;
00869
00870 if (argc != 5)
00871 return RESULT_SHOWUSAGE;
00872
00873 channame = argv[3];
00874 nr = argv[4];
00875
00876 ast_cli(fd, "Sending Calldeflection (%s) to %s\n",nr, channame);
00877
00878 {
00879 struct chan_list *tmp=get_chan_by_ast_name(channame);
00880
00881 if (!tmp) {
00882 ast_cli(fd, "Sending CD with nr %s to %s failed Channel does not exist\n",nr, channame);
00883 return 0;
00884 } else {
00885
00886 misdn_lib_send_facility(tmp->bc, FACILITY_CALLDEFLECT, nr);
00887 }
00888 }
00889
00890 return 0;
00891 }
00892
00893 static int misdn_send_digit (int fd, int argc, char *argv[])
00894 {
00895 char *channame;
00896 char *msg;
00897
00898 if (argc != 5)
00899 return RESULT_SHOWUSAGE;
00900
00901 channame = argv[3];
00902 msg = argv[4];
00903
00904 ast_cli(fd, "Sending %s to %s\n",msg, channame);
00905
00906 {
00907 struct chan_list *tmp=get_chan_by_ast_name(channame);
00908
00909 if (!tmp) {
00910 ast_cli(fd, "Sending %s to %s failed Channel does not exist\n",msg, channame);
00911 return 0;
00912 } else {
00913 #if 1
00914 int i;
00915 int msglen = strlen(msg);
00916 for (i=0; i<msglen; i++) {
00917 ast_cli(fd, "Sending: %c\n",msg[i]);
00918 send_digit_to_chan(tmp, msg[i]);
00919
00920 usleep(250000);
00921
00922 }
00923 #else
00924 int res;
00925 res = ast_dtmf_stream(tmp->ast,NULL,msg,250);
00926 #endif
00927 }
00928 }
00929
00930 return 0;
00931 }
00932
00933 static int misdn_toggle_echocancel (int fd, int argc, char *argv[])
00934 {
00935 char *channame;
00936
00937 if (argc != 4)
00938 return RESULT_SHOWUSAGE;
00939
00940 channame = argv[3];
00941
00942 ast_cli(fd, "Toggling EchoCancel on %s\n", channame);
00943
00944 {
00945 struct chan_list *tmp=get_chan_by_ast_name(channame);
00946
00947 if (!tmp) {
00948 ast_cli(fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame);
00949 return 0;
00950 } else {
00951
00952 tmp->toggle_ec=tmp->toggle_ec?0:1;
00953
00954 if (tmp->toggle_ec) {
00955 update_ec_config(tmp->bc);
00956 manager_ec_enable(tmp->bc);
00957 } else {
00958 manager_ec_disable(tmp->bc);
00959 }
00960 }
00961 }
00962
00963 return 0;
00964 }
00965
00966 static int misdn_send_display (int fd, int argc, char *argv[])
00967 {
00968 char *channame;
00969 char *msg;
00970
00971 if (argc != 5)
00972 return RESULT_SHOWUSAGE;
00973
00974 channame = argv[3];
00975 msg = argv[4];
00976
00977 ast_cli(fd, "Sending %s to %s\n",msg, channame);
00978 {
00979 struct chan_list *tmp;
00980 tmp=get_chan_by_ast_name(channame);
00981
00982 if (tmp && tmp->bc) {
00983 ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display));
00984 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
00985 } else {
00986 ast_cli(fd,"No such channel %s\n",channame);
00987 return RESULT_FAILURE;
00988 }
00989 }
00990
00991 return RESULT_SUCCESS ;
00992 }
00993
00994 static char *complete_ch_helper(char *line, char *word, int pos, int state, int rpos)
00995 {
00996 struct ast_channel *c;
00997 int which=0;
00998 char *ret;
00999 if (pos != rpos)
01000 return NULL;
01001 c = ast_channel_walk_locked(NULL);
01002 while(c) {
01003 if (!strncasecmp(word, c->name, strlen(word))) {
01004 if (++which > state)
01005 break;
01006 }
01007 ast_mutex_unlock(&c->lock);
01008 c = ast_channel_walk_locked(c);
01009 }
01010 if (c) {
01011 ret = strdup(c->name);
01012 ast_mutex_unlock(&c->lock);
01013 } else
01014 ret = NULL;
01015 return ret;
01016 }
01017
01018 static char *complete_ch(char *line, char *word, int pos, int state)
01019 {
01020 return complete_ch_helper(line, word, pos, state, 3);
01021 }
01022
01023 static char *complete_debug_port (char *line, char *word, int pos, int state)
01024 {
01025 if (state)
01026 return NULL;
01027
01028 switch (pos) {
01029 case 4: if (*word == 'p')
01030 return strdup("port");
01031 else if (*word == 'o')
01032 return strdup("only");
01033 break;
01034 case 6: if (*word == 'o')
01035 return strdup("only");
01036 break;
01037 }
01038 return NULL;
01039 }
01040
01041 static struct ast_cli_entry cli_send_cd =
01042 { {"misdn","send","calldeflect", NULL},
01043 misdn_send_cd,
01044 "Sends CallDeflection to mISDN Channel",
01045 "Usage: misdn send calldeflect <channel> \"<nr>\" \n",
01046 complete_ch
01047 };
01048
01049 static struct ast_cli_entry cli_send_digit =
01050 { {"misdn","send","digit", NULL},
01051 misdn_send_digit,
01052 "Sends DTMF Digit to mISDN Channel",
01053 "Usage: misdn send digit <channel> \"<msg>\" \n"
01054 " Send <digit> to <channel> as DTMF Tone\n"
01055 " when channel is a mISDN channel\n",
01056 complete_ch
01057 };
01058
01059 static struct ast_cli_entry cli_toggle_echocancel =
01060 { {"misdn","toggle","echocancel", NULL},
01061 misdn_toggle_echocancel,
01062 "Toggles EchoCancel on mISDN Channel",
01063 "Usage: misdn toggle echocancel <channel>\n",
01064 complete_ch
01065 };
01066
01067 static struct ast_cli_entry cli_send_display =
01068 { {"misdn","send","display", NULL},
01069 misdn_send_display,
01070 "Sends Text to mISDN Channel",
01071 "Usage: misdn send display <channel> \"<msg>\" \n"
01072 " Send <msg> to <channel> as Display Message\n"
01073 " when channel is a mISDN channel\n",
01074 complete_ch
01075 };
01076
01077 static struct ast_cli_entry cli_show_config =
01078 { {"misdn","show","config", NULL},
01079 misdn_show_config,
01080 "Shows internal mISDN config, read from cfg-file",
01081 "Usage: misdn show config [port | 0]\n use 0 to only print the general config.\n"
01082 };
01083
01084 static struct ast_cli_entry cli_reload =
01085 { {"misdn","reload", NULL},
01086 misdn_reload,
01087 "Reloads internal mISDN config, read from cfg-file",
01088 "Usage: misdn reload\n"
01089 };
01090
01091 static struct ast_cli_entry cli_set_tics =
01092 { {"misdn","set","tics", NULL},
01093 misdn_set_tics,
01094 "",
01095 "\n"
01096 };
01097
01098 static struct ast_cli_entry cli_show_cls =
01099 { {"misdn","show","channels", NULL},
01100 misdn_show_cls,
01101 "Shows internal mISDN chan_list",
01102 "Usage: misdn show channels\n"
01103 };
01104
01105 static struct ast_cli_entry cli_show_cl =
01106 { {"misdn","show","channel", NULL},
01107 misdn_show_cl,
01108 "Shows internal mISDN chan_list",
01109 "Usage: misdn show channels\n",
01110 complete_ch
01111 };
01112
01113 static struct ast_cli_entry cli_port_block=
01114 { {"misdn","port","block", NULL},
01115 misdn_port_block,
01116 "Blocks the given port",
01117 "Usage: misdn port block\n"
01118 };
01119
01120 static struct ast_cli_entry cli_port_unblock=
01121 { {"misdn","port","unblock", NULL},
01122 misdn_port_unblock,
01123 "Unblocks the given port",
01124 "Usage: misdn port unblock\n"
01125 };
01126
01127
01128 static struct ast_cli_entry cli_restart_port =
01129 { {"misdn","restart","port", NULL},
01130 misdn_restart_port,
01131 "Restarts the given port",
01132 "Usage: misdn restart port\n"
01133 };
01134
01135 static struct ast_cli_entry cli_port_up =
01136 { {"misdn","port","up", NULL},
01137 misdn_port_up,
01138 "Tries to establish L1 on the given port",
01139 "Usage: misdn port up <port>\n"
01140 };
01141
01142 static struct ast_cli_entry cli_port_down =
01143 { {"misdn","port","down", NULL},
01144 misdn_port_down,
01145 "Tries to deacivate the L1 on the given port",
01146 "Usage: misdn port down <port>\n"
01147 };
01148
01149
01150
01151 static struct ast_cli_entry cli_show_stacks =
01152 { {"misdn","show","stacks", NULL},
01153 misdn_show_stacks,
01154 "Shows internal mISDN stack_list",
01155 "Usage: misdn show stacks\n"
01156 };
01157
01158 static struct ast_cli_entry cli_show_port =
01159 { {"misdn","show","port", NULL},
01160 misdn_show_port,
01161 "Shows detailed information for given port",
01162 "Usage: misdn show port <port>\n"
01163 };
01164
01165 static struct ast_cli_entry cli_set_debug =
01166 { {"misdn","set","debug", NULL},
01167 misdn_set_debug,
01168 "Sets Debuglevel of chan_misdn",
01169 "Usage: misdn set debug <level> [only] | [port <port> [only]]\n",
01170 complete_debug_port
01171 };
01172
01173 static struct ast_cli_entry cli_set_crypt_debug =
01174 { {"misdn","set","crypt","debug", NULL},
01175 misdn_set_crypt_debug,
01176 "Sets CryptDebuglevel of chan_misdn, at the moment, level={1,2}",
01177 "Usage: misdn set crypt debug <level>\n"
01178 };
01179
01180
01181
01182 static int update_config (struct chan_list *ch, int orig)
01183 {
01184 if (!ch) {
01185 ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
01186 return -1;
01187 }
01188
01189 struct ast_channel *ast=ch->ast;
01190 struct misdn_bchannel *bc=ch->bc;
01191 if (! ast || ! bc ) {
01192 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
01193 return -1;
01194 }
01195
01196 int port=bc->port;
01197
01198 chan_misdn_log(1,port,"update_config: Getting Config\n");
01199
01200
01201 int hdlc=0;
01202 misdn_cfg_get( port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
01203
01204 if (hdlc) {
01205 switch (bc->capability) {
01206 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
01207 case INFO_CAPABILITY_DIGITAL_RESTRICTED:
01208 chan_misdn_log(1,bc->port," --> CONF HDLC\n");
01209 bc->hdlc=1;
01210 break;
01211 }
01212
01213 }
01214
01215
01216 int pres, screen;
01217
01218 misdn_cfg_get( port, MISDN_CFG_PRES, &pres, sizeof(int));
01219 misdn_cfg_get( port, MISDN_CFG_SCREEN, &screen, sizeof(int));
01220 chan_misdn_log(2,port," --> pres: %d screen: %d\n",pres, screen);
01221
01222 if ( (pres + screen) < 0 ) {
01223
01224 chan_misdn_log(2,port," --> pres: %x\n", ast->cid.cid_pres);
01225
01226 switch (ast->cid.cid_pres & 0x60){
01227
01228 case AST_PRES_RESTRICTED:
01229 bc->pres=1;
01230 chan_misdn_log(2, port, " --> PRES: Restricted (0x1)\n");
01231 break;
01232
01233
01234 case AST_PRES_UNAVAILABLE:
01235 bc->pres=2;
01236 chan_misdn_log(2, port, " --> PRES: Unavailable (0x2)\n");
01237 break;
01238
01239 default:
01240 bc->pres=0;
01241 chan_misdn_log(2, port, " --> PRES: Allowed (0x0)\n");
01242 }
01243
01244 switch (ast->cid.cid_pres & 0x3){
01245
01246 case AST_PRES_USER_NUMBER_UNSCREENED:
01247 bc->screen=0;
01248 chan_misdn_log(2, port, " --> SCREEN: Unscreened (0x0)\n");
01249 break;
01250
01251 case AST_PRES_USER_NUMBER_PASSED_SCREEN:
01252 bc->screen=1;
01253 chan_misdn_log(2, port, " --> SCREEN: Passed Screen (0x1)\n");
01254 break;
01255 case AST_PRES_USER_NUMBER_FAILED_SCREEN:
01256 bc->screen=2;
01257 chan_misdn_log(2, port, " --> SCREEN: Failed Screen (0x2)\n");
01258 break;
01259
01260 case AST_PRES_NETWORK_NUMBER:
01261 bc->screen=3;
01262 chan_misdn_log(2, port, " --> SCREEN: Network Nr. (0x3)\n");
01263 break;
01264
01265 default:
01266 bc->screen=0;
01267 chan_misdn_log(2, port, " --> SCREEN: Unscreened (0x0)\n");
01268 }
01269
01270
01271 } else {
01272 bc->screen=screen;
01273 bc->pres=pres;
01274 }
01275
01276 return 0;
01277
01278 }
01279
01280
01281
01282
01283 void config_jitterbuffer(struct chan_list *ch)
01284 {
01285 struct misdn_bchannel *bc=ch->bc;
01286 int len=ch->jb_len, threshold=ch->jb_upper_threshold;
01287
01288 chan_misdn_log(5,bc->port, "config_jb: Called\n");
01289
01290 if ( ! len ) {
01291 chan_misdn_log(1,bc->port, "config_jb: Deactivating Jitterbuffer\n");
01292 bc->nojitter=1;
01293 } else {
01294
01295 if (len <=100 || len > 8000) {
01296 chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer out of Bounds, setting to 1000\n");
01297 len=1000;
01298 }
01299
01300 if ( threshold > len ) {
01301 chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n");
01302 }
01303
01304 if ( ch->jb) {
01305 cb_log(0,bc->port,"config_jb: We've got a Jitterbuffer Already on this port.\n");
01306 misdn_jb_destroy(ch->jb);
01307 ch->jb=NULL;
01308 }
01309
01310 ch->jb=misdn_jb_init(len, threshold);
01311
01312 if (!ch->jb )
01313 bc->nojitter=1;
01314 }
01315 }
01316
01317
01318 void debug_numplan(int port, int numplan, char *type)
01319 {
01320 switch (numplan) {
01321 case NUMPLAN_INTERNATIONAL:
01322 chan_misdn_log(2, port, " --> %s: International\n",type);
01323 break;
01324 case NUMPLAN_NATIONAL:
01325 chan_misdn_log(2, port, " --> %s: National\n",type);
01326 break;
01327 case NUMPLAN_SUBSCRIBER:
01328 chan_misdn_log(2, port, " --> %s: Subscriber\n",type);
01329 break;
01330 case NUMPLAN_UNKNOWN:
01331 chan_misdn_log(2, port, " --> %s: Unknown\n",type);
01332 break;
01333
01334 default:
01335 chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n ");
01336 break;
01337 }
01338 }
01339
01340
01341
01342
01343 static int update_ec_config(struct misdn_bchannel *bc)
01344 {
01345 int ec;
01346 int port=bc->port;
01347
01348 misdn_cfg_get( port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
01349
01350 if (ec == 1 ) {
01351 bc->ec_enable=1;
01352 } else if ( ec > 1 ) {
01353 bc->ec_enable=1;
01354 bc->ec_deftaps=ec;
01355 }
01356
01357 return 0;
01358 }
01359
01360
01361 static int read_config(struct chan_list *ch, int orig) {
01362
01363 if (!ch) {
01364 ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
01365 return -1;
01366 }
01367
01368 struct ast_channel *ast=ch->ast;
01369 struct misdn_bchannel *bc=ch->bc;
01370 if (! ast || ! bc ) {
01371 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
01372 return -1;
01373 }
01374
01375 int port=bc->port;
01376
01377 chan_misdn_log(5,port,"read_config: Getting Config\n");
01378
01379 char lang[BUFFERSIZE+1];
01380
01381 misdn_cfg_get( port, MISDN_CFG_LANGUAGE, lang, BUFFERSIZE);
01382 ast_copy_string(ast->language, lang, sizeof(ast->language));
01383
01384 char musicclass[BUFFERSIZE+1];
01385
01386 misdn_cfg_get( port, MISDN_CFG_MUSICCLASS, musicclass, BUFFERSIZE);
01387 ast_copy_string(ast->musicclass, musicclass, sizeof(ast->musicclass));
01388
01389 misdn_cfg_get( port, MISDN_CFG_TXGAIN, &bc->txgain, sizeof(int));
01390 misdn_cfg_get( port, MISDN_CFG_RXGAIN, &bc->rxgain, sizeof(int));
01391
01392 misdn_cfg_get( port, MISDN_CFG_INCOMING_EARLY_AUDIO, &ch->incoming_early_audio, sizeof(int));
01393
01394 misdn_cfg_get( port, MISDN_CFG_SENDDTMF, &bc->send_dtmf, sizeof(int));
01395
01396 misdn_cfg_get( port, MISDN_CFG_NEED_MORE_INFOS, &bc->need_more_infos, sizeof(int));
01397
01398 misdn_cfg_get( port, MISDN_CFG_FAR_ALERTING, &ch->far_alerting, sizeof(int));
01399
01400 misdn_cfg_get( port, MISDN_CFG_ALLOWED_BEARERS, &ch->allowed_bearers, BUFFERSIZE);
01401
01402
01403 int hdlc=0;
01404 misdn_cfg_get( port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
01405
01406 if (hdlc) {
01407 switch (bc->capability) {
01408 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
01409 case INFO_CAPABILITY_DIGITAL_RESTRICTED:
01410 chan_misdn_log(1,bc->port," --> CONF HDLC\n");
01411 bc->hdlc=1;
01412 break;
01413 }
01414
01415 }
01416
01417 {
01418 misdn_cfg_get( port, MISDN_CFG_JITTERBUFFER, &ch->jb_len, sizeof(int));
01419 misdn_cfg_get( port, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, &ch->jb_upper_threshold, sizeof(int));
01420
01421 config_jitterbuffer(ch);
01422 }
01423
01424 misdn_cfg_get( bc->port, MISDN_CFG_CONTEXT, ch->context, sizeof(ch->context));
01425
01426 ast_copy_string (ast->context,ch->context,sizeof(ast->context));
01427
01428 update_ec_config(bc);
01429
01430 {
01431 int eb3;
01432
01433 misdn_cfg_get( bc->port, MISDN_CFG_EARLY_BCONNECT, &eb3, sizeof(int));
01434 bc->early_bconnect=eb3;
01435 }
01436
01437 port=bc->port;
01438
01439 {
01440 char buf[256];
01441 ast_group_t pg,cg;
01442
01443 misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg));
01444 misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg));
01445
01446 chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n",ast_print_group(buf,sizeof(buf),cg),ast_print_group(buf,sizeof(buf),pg));
01447 ast->pickupgroup=pg;
01448 ast->callgroup=cg;
01449 }
01450
01451 if ( orig == ORG_AST) {
01452 misdn_cfg_get( port, MISDN_CFG_TE_CHOOSE_CHANNEL, &(bc->te_choose_channel), sizeof(int));
01453
01454 {
01455 char callerid[BUFFERSIZE+1];
01456 misdn_cfg_get( port, MISDN_CFG_CALLERID, callerid, BUFFERSIZE);
01457 if ( ! ast_strlen_zero(callerid) ) {
01458 chan_misdn_log(1, port, " --> * Setting Cid to %s\n", callerid);
01459 {
01460 int l = sizeof(bc->oad);
01461 strncpy(bc->oad,callerid, l);
01462 bc->oad[l-1] = 0;
01463 }
01464
01465 }
01466
01467
01468 misdn_cfg_get( port, MISDN_CFG_DIALPLAN, &bc->dnumplan, sizeof(int));
01469 misdn_cfg_get( port, MISDN_CFG_LOCALDIALPLAN, &bc->onumplan, sizeof(int));
01470 misdn_cfg_get( port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int));
01471 debug_numplan(port, bc->dnumplan,"TON");
01472 debug_numplan(port, bc->onumplan,"LTON");
01473 debug_numplan(port, bc->cpnnumplan,"CTON");
01474 }
01475
01476
01477
01478 } else {
01479
01480 misdn_cfg_get( port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int));
01481 debug_numplan(port, bc->cpnnumplan,"CTON");
01482
01483 char prefix[BUFFERSIZE+1]="";
01484 switch( bc->onumplan ) {
01485 case NUMPLAN_INTERNATIONAL:
01486 misdn_cfg_get( bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE);
01487 break;
01488
01489 case NUMPLAN_NATIONAL:
01490 misdn_cfg_get( bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE);
01491 break;
01492 default:
01493 break;
01494 }
01495
01496 {
01497 int l = strlen(prefix) + strlen(bc->oad);
01498 char tmp[l+1];
01499 strcpy(tmp,prefix);
01500 strcat(tmp,bc->oad);
01501 strcpy(bc->oad,tmp);
01502 }
01503
01504 if (!ast_strlen_zero(bc->dad)) {
01505 ast_copy_string(bc->orig_dad,bc->dad, sizeof(bc->orig_dad));
01506 }
01507
01508 if ( ast_strlen_zero(bc->dad) && !ast_strlen_zero(bc->keypad)) {
01509 ast_copy_string(bc->dad,bc->keypad, sizeof(bc->dad));
01510 }
01511
01512 prefix[0] = 0;
01513
01514 switch( bc->dnumplan ) {
01515 case NUMPLAN_INTERNATIONAL:
01516 misdn_cfg_get( bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE);
01517 break;
01518 case NUMPLAN_NATIONAL:
01519 misdn_cfg_get( bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE);
01520 break;
01521 default:
01522 break;
01523 }
01524
01525 {
01526 int l = strlen(prefix) + strlen(bc->dad);
01527 char tmp[l+1];
01528 strcpy(tmp,prefix);
01529 strcat(tmp,bc->dad);
01530 strcpy(bc->dad,tmp);
01531 }
01532
01533 if ( strcmp(bc->dad,ast->exten)) {
01534 ast_copy_string(ast->exten, bc->dad, sizeof(ast->exten));
01535 }
01536
01537 ast_set_callerid(ast, bc->oad, NULL, bc->oad);
01538
01539 if ( !ast_strlen_zero(bc->rad) )
01540 ast->cid.cid_rdnis=strdup(bc->rad);
01541
01542 }
01543
01544 return 0;
01545 }
01546
01547
01548
01549
01550
01551
01552 static int misdn_call(struct ast_channel *ast, char *dest, int timeout)
01553 {
01554 int port=0;
01555 int r;
01556 struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast);
01557 struct misdn_bchannel *newbc;
01558 char *opts=NULL, *ext,*tokb;
01559 char dest_cp[256];
01560
01561 {
01562 strncpy(dest_cp,dest,sizeof(dest_cp)-1);
01563 dest_cp[sizeof(dest_cp)]=0;
01564
01565 ext=strtok_r(dest_cp,"/",&tokb);
01566
01567 if (ext) {
01568 ext=strtok_r(NULL,"/",&tokb);
01569 if (ext) {
01570 opts=strtok_r(NULL,"/",&tokb);
01571 } else {
01572 chan_misdn_log(0,0,"misdn_call: No Extension given!\n");
01573 return -1;
01574 }
01575 }
01576 }
01577
01578 if (!ast) {
01579 ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n");
01580 return -1;
01581 }
01582
01583 if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest ) {
01584 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
01585 ast->hangupcause=41;
01586 ast_setstate(ast, AST_STATE_DOWN);
01587 return -1;
01588 }
01589
01590 if (!ch) {
01591 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
01592 ast->hangupcause=41;
01593 ast_setstate(ast, AST_STATE_DOWN);
01594 return -1;
01595 }
01596
01597 newbc=ch->bc;
01598
01599 if (!newbc) {
01600 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
01601 ast->hangupcause=41;
01602 ast_setstate(ast, AST_STATE_DOWN);
01603 return -1;
01604 }
01605
01606 port=newbc->port;
01607 strncpy(newbc->dad,ext,sizeof( newbc->dad));
01608 strncpy(ast->exten,ext,sizeof(ast->exten));
01609
01610 chan_misdn_log(1, port, "* CALL: %s\n",dest);
01611
01612 chan_misdn_log(1, port, " --> * dad:%s tech:%s ctx:%s\n",ast->exten,ast->name, ast->context);
01613
01614 chan_misdn_log(3, port, " --> * adding2newbc ext %s\n",ast->exten);
01615 if (ast->exten) {
01616 int l = sizeof(newbc->dad);
01617 strncpy(newbc->dad,ast->exten, l);
01618 newbc->dad[l-1] = 0;
01619 }
01620 newbc->rad[0]=0;
01621 chan_misdn_log(3, port, " --> * adding2newbc callerid %s\n",AST_CID_P(ast));
01622 if (ast_strlen_zero(newbc->oad) && AST_CID_P(ast) ) {
01623
01624 if (AST_CID_P(ast)) {
01625 int l = sizeof(newbc->oad);
01626 strncpy(newbc->oad,AST_CID_P(ast), l);
01627 newbc->oad[l-1] = 0;
01628 }
01629 }
01630
01631 {
01632 struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast);
01633 if (!ch) { ast_verbose("No chan_list in misdn_call"); return -1;}
01634
01635 newbc->capability=ast->transfercapability;
01636 pbx_builtin_setvar_helper(ast,"TRANSFERCAPABILITY",ast_transfercapability2str(newbc->capability));
01637 if ( ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) {
01638 chan_misdn_log(2, port, " --> * Call with flag Digital\n");
01639 }
01640
01641
01642
01643 update_config(ch,ORG_AST);
01644
01645
01646 import_ch(ast, newbc, ch);
01647
01648
01649 if (opts)
01650 misdn_set_opt_exec(ast,opts);
01651 else
01652 chan_misdn_log(2,port,"NO OPTS GIVEN\n");
01653
01654 ch->state=MISDN_CALLING;
01655
01656 r=misdn_lib_send_event( newbc, EVENT_SETUP );
01657
01658
01659 ch->l3id=newbc->l3_id;
01660 }
01661
01662 if ( r == -ENOCHAN ) {
01663 chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n");
01664 chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n",newbc?newbc->pid:-1);
01665 ast->hangupcause=34;
01666 ast_setstate(ast, AST_STATE_DOWN);
01667 return -1;
01668 }
01669
01670 chan_misdn_log(1, port, " --> * SEND: State Dialing pid:%d\n",newbc?newbc->pid:1);
01671
01672 ast_setstate(ast, AST_STATE_DIALING);
01673 ast->hangupcause=16;
01674
01675 if (newbc->nt) stop_bc_tones(ch);
01676
01677 return 0;
01678 }
01679
01680
01681 static int misdn_answer(struct ast_channel *ast)
01682 {
01683 struct chan_list *p;
01684
01685
01686 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1;
01687
01688 chan_misdn_log(1, p? (p->bc? p->bc->port : 0) : 0, "* ANSWER:\n");
01689
01690 if (!p) {
01691 ast_log(LOG_WARNING, " --> Channel not connected ??\n");
01692 ast_queue_hangup(ast);
01693 }
01694
01695 if (!p->bc) {
01696 chan_misdn_log(1, 0, " --> Got Answer, but theres no bc obj ??\n");
01697
01698 ast_queue_hangup(ast);
01699 }
01700
01701 {
01702 const char *tmp_key = pbx_builtin_getvar_helper(p->ast, "CRYPT_KEY");
01703
01704 if (tmp_key ) {
01705 chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n");
01706 {
01707 int l = sizeof(p->bc->crypt_key);
01708 strncpy(p->bc->crypt_key,tmp_key, l);
01709 p->bc->crypt_key[l-1] = 0;
01710 }
01711 } else {
01712 chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n");
01713 }
01714
01715 }
01716
01717 {
01718 const char *nodsp=pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS");
01719 if (nodsp) {
01720 chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n");
01721 p->bc->nodsp=1;
01722 p->bc->hdlc=0;
01723 p->bc->nojitter=1;
01724 }
01725 }
01726
01727 p->state = MISDN_CONNECTED;
01728 misdn_lib_echo(p->bc,0);
01729 stop_indicate(p);
01730
01731 if ( ast_strlen_zero(p->bc->cad) ) {
01732 chan_misdn_log(2,p->bc->port," --> empty cad using dad\n");
01733 ast_copy_string(p->bc->cad,p->bc->dad,sizeof(p->bc->cad));
01734 }
01735
01736 misdn_lib_send_event( p->bc, EVENT_CONNECT);
01737 start_bc_tones(p);
01738
01739 return 0;
01740 }
01741
01742 static int misdn_digit(struct ast_channel *ast, char digit )
01743 {
01744 struct chan_list *p;
01745
01746 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) return -1;
01747
01748 struct misdn_bchannel *bc=p->bc;
01749 chan_misdn_log(1, bc?bc->port:0, "* IND : Digit %c\n",digit);
01750
01751 if (!bc) {
01752 ast_log(LOG_WARNING, " --> !! Got Digit Event withut having bchannel Object\n");
01753 return -1;
01754 }
01755
01756 switch (p->state ) {
01757 case MISDN_CALLING:
01758 {
01759
01760 char buf[8];
01761 buf[0]=digit;
01762 buf[1]=0;
01763
01764 int l = sizeof(bc->infos_pending);
01765 strncat(bc->infos_pending,buf,l);
01766 bc->infos_pending[l-1] = 0;
01767 }
01768 break;
01769 case MISDN_CALLING_ACKNOWLEDGE:
01770 {
01771 bc->info_dad[0]=digit;
01772 bc->info_dad[1]=0;
01773
01774 {
01775 int l = sizeof(bc->dad);
01776 strncat(bc->dad,bc->info_dad, l - strlen(bc->dad));
01777 bc->dad[l-1] = 0;
01778 }
01779 {
01780 int l = sizeof(p->ast->exten);
01781 strncpy(p->ast->exten, bc->dad, l);
01782 p->ast->exten[l-1] = 0;
01783 }
01784
01785 misdn_lib_send_event( bc, EVENT_INFORMATION);
01786 }
01787 break;
01788
01789 default:
01790 if ( bc->send_dtmf ) {
01791 send_digit_to_chan(p,digit);
01792 }
01793 break;
01794 }
01795
01796 return 0;
01797 }
01798
01799
01800 static int misdn_fixup(struct ast_channel *oldast, struct ast_channel *ast)
01801 {
01802 struct chan_list *p;
01803
01804 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) )) return -1;
01805
01806 chan_misdn_log(1, p->bc?p->bc->port:0, "* IND: Got Fixup State:%s L3id:%x\n", misdn_get_ch_state(p), p->l3id);
01807
01808 p->ast = ast ;
01809 p->state=MISDN_CONNECTED;
01810
01811 return 0;
01812 }
01813
01814
01815
01816 static int misdn_indication(struct ast_channel *ast, int cond)
01817 {
01818 struct chan_list *p;
01819
01820
01821 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) {
01822 ast_log(LOG_WARNING, "Returnded -1 in misdn_indication\n");
01823 return -1;
01824 }
01825
01826 if (!p->bc ) {
01827 chan_misdn_log(1, 0, "* IND : Indication from %s\n",ast->exten);
01828 ast_log(LOG_WARNING, "Private Pointer but no bc ?\n");
01829 return -1;
01830 }
01831
01832 chan_misdn_log(1, p->bc->port, "* IND : Indication [%d] from %s\n",cond, ast->exten);
01833
01834 switch (cond) {
01835 case AST_CONTROL_BUSY:
01836 chan_misdn_log(1, p->bc->port, "* IND :\tbusy\n");
01837 chan_misdn_log(1, p->bc->port, " --> * SEND: State Busy pid:%d\n",p->bc?p->bc->pid:-1);
01838 ast_setstate(ast,AST_STATE_BUSY);
01839
01840 p->bc->out_cause=17;
01841 if (p->state != MISDN_CONNECTED) {
01842 start_bc_tones(p);
01843 misdn_lib_send_event( p->bc, EVENT_DISCONNECT);
01844 } else {
01845 chan_misdn_log(-1, p->bc->port, " --> !! Got Busy in Connected State !?! ast:%s\n", ast->name);
01846 }
01847 return -1;
01848 break;
01849 case AST_CONTROL_RING:
01850 chan_misdn_log(1, p->bc->port, " --> * IND :\tring pid:%d\n",p->bc?p->bc->pid:-1);
01851 return -1;
01852 break;
01853
01854 case AST_CONTROL_RINGING:
01855 switch (p->state) {
01856 case MISDN_ALERTING:
01857 chan_misdn_log(1, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoreing it\n",p->bc?p->bc->pid:-1);
01858 break;
01859 case MISDN_CONNECTED:
01860 chan_misdn_log(1, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n",p->bc?p->bc->pid:-1);
01861 return -1;
01862 break;
01863 default:
01864 p->state=MISDN_ALERTING;
01865 chan_misdn_log(1, p->bc->port, " --> * IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1);
01866 misdn_lib_send_event( p->bc, EVENT_ALERTING);
01867
01868 if (p->other_ch && p->other_ch->bc) {
01869 if (misdn_inband_avail(p->other_ch->bc)) {
01870 chan_misdn_log(1,p->bc->port, " --> other End is mISDN and has inband info available\n");
01871 break;
01872 }
01873
01874 if (!p->other_ch->bc->nt) {
01875 chan_misdn_log(1,p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n");
01876 break;
01877 }
01878 }
01879
01880 chan_misdn_log(1, p->bc->port, " --> * SEND: State Ring pid:%d\n",p->bc?p->bc->pid:-1);
01881 ast_setstate(ast,AST_STATE_RINGING);
01882
01883 if ( !p->bc->nt && (p->orginator==ORG_MISDN) && !p->incoming_early_audio )
01884 chan_misdn_log(1,p->bc->port, " --> incoming_early_audio off\n");
01885 else
01886 return -1;
01887 }
01888 break;
01889 case AST_CONTROL_ANSWER:
01890 chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n",p->bc?p->bc->pid:-1);
01891 start_bc_tones(p);
01892 break;
01893 case AST_CONTROL_TAKEOFFHOOK:
01894 chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n",p->bc?p->bc->pid:-1);
01895 return -1;
01896 break;
01897 case AST_CONTROL_OFFHOOK:
01898 chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n",p->bc?p->bc->pid:-1);
01899 return -1;
01900 break;
01901 case AST_CONTROL_FLASH:
01902 chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n",p->bc?p->bc->pid:-1);
01903 break;
01904 case AST_CONTROL_PROGRESS:
01905 chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n",p->bc?p->bc->pid:-1);
01906 misdn_lib_send_event( p->bc, EVENT_PROGRESS);
01907 break;
01908 case AST_CONTROL_PROCEEDING:
01909 chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n",p->bc?p->bc->pid:-1);
01910 misdn_lib_send_event( p->bc, EVENT_PROCEEDING);
01911 break;
01912 case AST_CONTROL_CONGESTION:
01913 chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n",p->bc?p->bc->pid:-1);
01914
01915 p->bc->out_cause=42;
01916 if (p->state != MISDN_CONNECTED) {
01917 start_bc_tones(p);
01918 misdn_lib_send_event( p->bc, EVENT_RELEASE);
01919 } else {
01920 misdn_lib_send_event( p->bc, EVENT_DISCONNECT);
01921 }
01922
01923 if (p->bc->nt) {
01924 hanguptone_indicate(p);
01925 }
01926 break;
01927 case -1 :
01928 chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n",p->bc?p->bc->pid:-1);
01929
01930 stop_indicate(p);
01931
01932 if (p->state == MISDN_CONNECTED)
01933 start_bc_tones(p);
01934
01935 break;
01936
01937 case AST_CONTROL_HOLD:
01938 chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n",p->bc?p->bc->pid:-1);
01939 break;
01940 case AST_CONTROL_UNHOLD:
01941 chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n",p->bc?p->bc->pid:-1);
01942 break;
01943 default:
01944 ast_log(LOG_NOTICE, " --> * Unknown Indication:%d pid:%d\n",cond,p->bc?p->bc->pid:-1);
01945 }
01946
01947 return 0;
01948 }
01949
01950 static int misdn_hangup(struct ast_channel *ast)
01951 {
01952 struct chan_list *p;
01953 struct misdn_bchannel *bc=NULL;
01954
01955 ast_log(LOG_DEBUG, "misdn_hangup(%s)\n", ast->name);
01956
01957 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) ) ) return -1;
01958
01959 if (!p) {
01960 chan_misdn_log(3, 0, "misdn_hangup called, without chan_list obj.\n");
01961 return 0 ;
01962 }
01963
01964 bc=p->bc;
01965
01966 if (!bc) {
01967 ast_log(LOG_WARNING,"Hangup with private but no bc ?\n");
01968 return 0;
01969 }
01970
01971
01972 MISDN_ASTERISK_TECH_PVT(ast)=NULL;
01973 p->ast=NULL;
01974
01975 bc=p->bc;
01976
01977 if (ast->_state == AST_STATE_RESERVED) {
01978
01979 ast_log(LOG_DEBUG, "State Reserved => chanIsAvail\n");
01980 MISDN_ASTERISK_TECH_PVT(ast)=NULL;
01981
01982 cl_dequeue_chan(&cl_te, p);
01983
01984 close(p->pipe[0]);
01985 close(p->pipe[1]);
01986
01987 free(p);
01988 if (bc)
01989 misdn_lib_release(bc);
01990
01991 return 0;
01992 }
01993
01994 p->need_hangup=0;
01995 p->need_queue_hangup=0;
01996
01997
01998 if (!p->bc->nt)
01999 stop_bc_tones(p);
02000
02001
02002 {
02003 const char *varcause=NULL;
02004 bc->out_cause=ast->hangupcause?ast->hangupcause:16;
02005
02006 if ( (varcause=pbx_builtin_getvar_helper(ast, "HANGUPCAUSE")) ||
02007 (varcause=pbx_builtin_getvar_helper(ast, "PRI_CAUSE"))) {
02008 int tmpcause=atoi(varcause);
02009 bc->out_cause=tmpcause?tmpcause:16;
02010 }
02011
02012 chan_misdn_log(1, bc->port, "* IND : HANGUP\tpid:%d ctx:%s dad:%s oad:%s State:%s\n",p->bc?p->bc->pid:-1, ast->context, ast->exten, AST_CID_P(ast), misdn_get_ch_state(p));
02013 chan_misdn_log(2, bc->port, " --> l3id:%x\n",p->l3id);
02014 chan_misdn_log(1, bc->port, " --> cause:%d\n",bc->cause);
02015 chan_misdn_log(1, bc->port, " --> out_cause:%d\n",bc->out_cause);
02016 chan_misdn_log(1, bc->port, " --> state:%s\n", misdn_get_ch_state(p));
02017
02018 switch (p->state) {
02019 case MISDN_CALLING:
02020 p->state=MISDN_CLEANING;
02021 misdn_lib_send_event( bc, EVENT_RELEASE_COMPLETE);
02022 break;
02023 case MISDN_HOLDED:
02024 case MISDN_DIALING:
02025 start_bc_tones(p);
02026 hanguptone_indicate(p);
02027
02028 if (bc->need_disconnect)
02029 misdn_lib_send_event( bc, EVENT_DISCONNECT);
02030 break;
02031
02032 case MISDN_CALLING_ACKNOWLEDGE:
02033 start_bc_tones(p);
02034 hanguptone_indicate(p);
02035
02036 if (bc->need_disconnect)
02037 misdn_lib_send_event( bc, EVENT_DISCONNECT);
02038 break;
02039
02040 case MISDN_ALERTING:
02041 case MISDN_PROGRESS:
02042 case MISDN_PROCEEDING:
02043 if (p->orginator != ORG_AST)
02044 hanguptone_indicate(p);
02045
02046
02047 if (bc->need_disconnect)
02048 misdn_lib_send_event( bc, EVENT_DISCONNECT);
02049 break;
02050 case MISDN_CONNECTED:
02051 case MISDN_PRECONNECTED:
02052
02053 if (p->bc->nt) {
02054 start_bc_tones(p);
02055 hanguptone_indicate(p);
02056 p->bc->progress_indicator=8;
02057 }
02058 if (bc->need_disconnect)
02059 misdn_lib_send_event( bc, EVENT_DISCONNECT);
02060
02061
02062 break;
02063 case MISDN_DISCONNECTED:
02064 misdn_lib_send_event( bc, EVENT_RELEASE);
02065 p->state=MISDN_CLEANING;
02066 break;
02067
02068 case MISDN_RELEASED:
02069 case MISDN_CLEANING:
02070 p->state=MISDN_CLEANING;
02071 break;
02072
02073 case MISDN_BUSY:
02074 break;
02075
02076 case MISDN_HOLD_DISCONNECT:
02077
02078 chan_misdn_log(1, bc->port, " --> cause %d\n",bc->cause);
02079 chan_misdn_log(1, bc->port, " --> out_cause %d\n",bc->out_cause);
02080
02081 bc->out_cause=-1;
02082 misdn_lib_send_event(bc,EVENT_RELEASE);
02083 p->state=MISDN_CLEANING;
02084 break;
02085 default:
02086 if (bc->nt) {
02087 bc->out_cause=-1;
02088 misdn_lib_send_event(bc, EVENT_RELEASE);
02089 p->state=MISDN_CLEANING;
02090 } else {
02091 if (bc->need_disconnect)
02092 misdn_lib_send_event(bc, EVENT_DISCONNECT);
02093 }
02094 }
02095
02096 p->state=MISDN_CLEANING;
02097
02098 }
02099
02100
02101 chan_misdn_log(1, bc->port, "Channel: %s hanguped new state:%s\n",ast->name,misdn_get_ch_state(p));
02102
02103 return 0;
02104 }
02105
02106 static struct ast_frame *misdn_read(struct ast_channel *ast)
02107 {
02108 struct chan_list *tmp;
02109 int len;
02110
02111 if (!ast) {
02112 chan_misdn_log(1,0,"misdn_read called without ast\n");
02113 return NULL;
02114 }
02115 if (! (tmp=MISDN_ASTERISK_TECH_PVT(ast)) ) {
02116 chan_misdn_log(1,0,"misdn_read called without ast->pvt\n");
02117 return NULL;
02118 }
02119 if (!tmp->bc) {
02120 chan_misdn_log(1,0,"misdn_read called without bc\n");
02121 return NULL;
02122 }
02123
02124 len=read(tmp->pipe[0],tmp->ast_rd_buf,sizeof(tmp->ast_rd_buf));
02125
02126 if (len<=0) {
02127
02128 chan_misdn_log(2,tmp->bc->port,"misdn_read: Pipe closed, hanging up\n");
02129 return NULL;
02130 }
02131
02132 tmp->frame.frametype = AST_FRAME_VOICE;
02133 tmp->frame.subclass = AST_FORMAT_ALAW;
02134 tmp->frame.datalen = len;
02135 tmp->frame.samples = len ;
02136 tmp->frame.mallocd =0 ;
02137 tmp->frame.offset= 0 ;
02138 tmp->frame.src = NULL;
02139 tmp->frame.data = tmp->ast_rd_buf ;
02140
02141 if (tmp->faxdetect || tmp->ast_dsp ) {
02142 return process_ast_dsp(tmp, &tmp->frame);
02143 }
02144
02145 return &tmp->frame;
02146 }
02147
02148
02149 static int misdn_write(struct ast_channel *ast, struct ast_frame *frame)
02150 {
02151 struct chan_list *ch;
02152 int i = 0;
02153
02154 if (!ast || ! (ch=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1;
02155
02156 if (!ch->bc ) {
02157 ast_log(LOG_WARNING, "private but no bc\n");
02158 return -1;
02159 }
02160
02161 if (ch->state == MISDN_HOLDED) {
02162 chan_misdn_log(8, ch->bc->port, "misdn_write: Returning because holded\n");
02163 return 0;
02164 }
02165
02166 if (ch->notxtone) {
02167 chan_misdn_log(9, ch->bc->port, "misdn_write: Returning because notxone\n");
02168 return 0;
02169 }
02170
02171
02172 if ( !frame->subclass) {
02173 chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n");
02174 return 0;
02175 }
02176
02177 if ( !(frame->subclass & prefformat)) {
02178
02179 chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%d\n", frame->subclass);
02180 return 0;
02181 }
02182
02183
02184 if ( !frame->samples ) {
02185 chan_misdn_log(4, ch->bc->port, "misdn_write: zero write\n");
02186 return 0;
02187 }
02188
02189 if ( ! ch->bc->addr ) {
02190 chan_misdn_log(8, ch->bc->port, "misdn_write: no addr for bc dropping:%d\n", frame->samples);
02191 return 0;
02192 }
02193
02194 #if MISDN_DEBUG
02195 {
02196 int i, max=5>frame->samples?frame->samples:5;
02197
02198 printf("write2mISDN %p %d bytes: ", p, frame->samples);
02199
02200 for (i=0; i< max ; i++) printf("%2.2x ",((char*) frame->data)[i]);
02201 printf ("\n");
02202 }
02203 #endif
02204
02205
02206 switch (ch->bc->bc_state) {
02207 case BCHAN_ACTIVATED:
02208 case BCHAN_BRIDGED:
02209 break;
02210 default:
02211 if (!ch->dropped_frame_cnt)
02212 chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) droping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d\n",frame->samples,ch->bc->addr, ast->exten, ast->cid.cid_num,misdn_get_ch_state( ch), ch->bc->bc_state);
02213
02214 ch->dropped_frame_cnt++;
02215 if (ch->dropped_frame_cnt > 100) {
02216 ch->dropped_frame_cnt=0;
02217 chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) droping: %d frames addr:%x dropped > 100 frames!\n",frame->samples,ch->bc->addr);
02218
02219 }
02220
02221 return 0;
02222 }
02223
02224 chan_misdn_log(9, ch->bc->port, "Sending :%d bytes 2 MISDN\n",frame->samples);
02225
02226 if ( !ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability) ) {
02227
02228 if (misdn_jb_fill(ch->jb,frame->data,frame->samples) < 0) {
02229 if (ch->bc->active)
02230 cb_log(0,ch->bc->port,"Misdn Jitterbuffer Overflow.\n");
02231 }
02232
02233 } else {
02234
02235 i=misdn_lib_tx2misdn_frm(ch->bc, frame->data, frame->samples);
02236 }
02237
02238
02239
02240 return 0;
02241 }
02242
02243
02244
02245
02246 enum ast_bridge_result misdn_bridge (struct ast_channel *c0,
02247 struct ast_channel *c1, int flags,
02248 struct ast_frame **fo,
02249 struct ast_channel **rc,
02250 int timeoutms)
02251
02252 {
02253 struct chan_list *ch1,*ch2;
02254 struct ast_channel *carr[2], *who;
02255 int to=-1;
02256 struct ast_frame *f;
02257
02258 ch1=get_chan_by_ast(c0);
02259 ch2=get_chan_by_ast(c1);
02260
02261 carr[0]=c0;
02262 carr[1]=c1;
02263
02264
02265 if (ch1 && ch2 ) ;
02266 else
02267 return -1;
02268
02269
02270 int bridging;
02271 misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
02272 if (bridging) {
02273 int ec;
02274 misdn_cfg_get( ch1->bc->port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
02275 if ( ec ) {
02276 chan_misdn_log(2, ch1->bc->port, "Disabling Echo Cancellor when Bridged\n");
02277 ch1->bc->ec_enable=0;
02278 manager_ec_disable(ch1->bc);
02279 }
02280 misdn_cfg_get( ch2->bc->port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
02281 if ( ec ) {
02282 chan_misdn_log(2, ch2->bc->port, "Disabling Echo Cancellor when Bridged\n");
02283 ch2->bc->ec_enable=0;
02284 manager_ec_disable(ch2->bc);
02285 }
02286
02287
02288 chan_misdn_log(1, ch1->bc->port, "I SEND: Making conference with Number:%d\n", ch1->bc->pid +1);
02289
02290 misdn_lib_bridge(ch1->bc,ch2->bc);
02291 }
02292
02293 chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between %s and %s\n", ch1->bc->oad, ch2->bc->oad);
02294
02295
02296 if (! (flags&AST_BRIDGE_DTMF_CHANNEL_0) )
02297 ch1->ignore_dtmf=1;
02298
02299 if (! (flags&AST_BRIDGE_DTMF_CHANNEL_1) )
02300 ch2->ignore_dtmf=1;
02301
02302
02303 while(1) {
02304 to=-1;
02305 who = ast_waitfor_n(carr, 2, &to);
02306
02307 if (!who) {
02308 ast_log(LOG_NOTICE,"misdn_bridge: empty read, breaking out\n");
02309 break;
02310 }
02311 f = ast_read(who);
02312
02313 if (!f || f->frametype == AST_FRAME_CONTROL) {
02314
02315
02316 if (!f)
02317 chan_misdn_log(1,ch1->bc->port,"Read Null Frame\n");
02318 else
02319 chan_misdn_log(1,ch1->bc->port,"Read Frame Controll class:%d\n",f->subclass);
02320
02321 *fo=f;
02322 *rc=who;
02323
02324 break;
02325 }
02326
02327 if ( f->frametype == AST_FRAME_DTMF ) {
02328 chan_misdn_log(1,0,"Read DTMF %d from %s\n",f->subclass, who->exten);
02329
02330 *fo=f;
02331 *rc=who;
02332 break;
02333 }
02334
02335
02336 if (who == c0) {
02337 ast_write(c1,f);
02338 }
02339 else {
02340 ast_write(c0,f);
02341 }
02342
02343 }
02344
02345 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1);
02346
02347 misdn_lib_split_bridge(ch1->bc,ch2->bc);
02348
02349
02350 return AST_BRIDGE_COMPLETE;
02351 }
02352
02353
02354
02355 static int dialtone_indicate(struct chan_list *cl)
02356 {
02357 const struct tone_zone_sound *ts= NULL;
02358 struct ast_channel *ast=cl->ast;
02359
02360
02361 int nd=0;
02362 misdn_cfg_get( cl->bc->port, MISDN_CFG_NODIALTONE, &nd, sizeof(nd));
02363
02364 if (nd) {
02365 chan_misdn_log(1,cl->bc->port,"Not sending Dialtone, because config wants it\n");
02366 return 0;
02367 }
02368
02369 chan_misdn_log(3,cl->bc->port," --> Dial\n");
02370 ts=ast_get_indication_tone(ast->zone,"dial");
02371 cl->ts=ts;
02372
02373 if (ts) {
02374 cl->notxtone=0;
02375 cl->norxtone=0;
02376 ast_playtones_start(ast,0, ts->data, 0);
02377 chan_misdn_log(4,cl->bc->port,"Starting Playtones\n");
02378 misdn_lib_tone_generator_start(cl->bc);
02379 }
02380
02381 return 0;
02382 }
02383
02384 static int hanguptone_indicate(struct chan_list *cl)
02385 {
02386 misdn_lib_send_tone(cl->bc,TONE_HANGUP);
02387 return 0;
02388 }
02389
02390 static int stop_indicate(struct chan_list *cl)
02391 {
02392 struct ast_channel *ast=cl->ast;
02393 chan_misdn_log(3,cl->bc->port," --> None\n");
02394 misdn_lib_tone_generator_stop(cl->bc);
02395 ast_playtones_stop(ast);
02396
02397
02398 return 0;
02399 }
02400
02401
02402 static int start_bc_tones(struct chan_list* cl)
02403 {
02404 misdn_lib_tone_generator_stop(cl->bc);
02405 cl->notxtone=0;
02406 cl->norxtone=0;
02407 return 0;
02408 }
02409
02410 static int stop_bc_tones(struct chan_list *cl)
02411 {
02412 if (!cl) return -1;
02413
02414 cl->notxtone=1;
02415 cl->norxtone=1;
02416
02417 return 0;
02418 }
02419
02420
02421 static struct chan_list *init_chan_list(int orig)
02422 {
02423 struct chan_list *cl=malloc(sizeof(struct chan_list));
02424
02425 if (!cl) {
02426 chan_misdn_log(-1, 0, "misdn_request: malloc failed!");
02427 return NULL;
02428 }
02429
02430 memset(cl,0,sizeof(struct chan_list));
02431
02432 cl->orginator=orig;
02433 cl->need_queue_hangup=1;
02434 cl->need_hangup=1;
02435 cl->need_busy=1;
02436
02437 return cl;
02438
02439 }
02440
02441 static struct ast_channel *misdn_request(const char *type, int format, void *data, int *cause)
02442
02443 {
02444 struct ast_channel *tmp = NULL;
02445 char group[BUFFERSIZE+1]="";
02446 char buf[128];
02447 char buf2[128], *ext=NULL, *port_str;
02448 char *tokb=NULL, *p=NULL;
02449 int channel=0, port=0;
02450 struct misdn_bchannel *newbc = NULL;
02451
02452 struct chan_list *cl=init_chan_list(ORG_AST);
02453
02454 sprintf(buf,"%s/%s",misdn_type,(char*)data);
02455 ast_copy_string(buf2,data, 128);
02456
02457 port_str=strtok_r(buf2,"/", &tokb);
02458
02459 ext=strtok_r(NULL,"/", &tokb);
02460
02461 if (port_str) {
02462 if (port_str[0]=='g' && port_str[1]==':' ) {
02463
02464 port_str += 2;
02465 strncpy(group, port_str, BUFFERSIZE);
02466 group[127] = 0;
02467 chan_misdn_log(2, 0, " --> Group Call group: %s\n",group);
02468 }
02469 else if ((p = strchr(port_str, ':'))) {
02470
02471 *p = 0;
02472 channel = atoi(++p);
02473 port = atoi(port_str);
02474 chan_misdn_log(2, port, " --> Call on preselected Channel (%d).\n", channel);
02475 }
02476 else {
02477 port = atoi(port_str);
02478 }
02479
02480
02481 } else {
02482 ast_log(LOG_WARNING, " --> ! IND : CALL dad:%s WITHOUT PORT/Group, check extension.conf\n",ext);
02483 return NULL;
02484 }
02485
02486 if (!ast_strlen_zero(group)) {
02487
02488 char cfg_group[BUFFERSIZE+1];
02489 struct robin_list *rr = NULL;
02490
02491 if (misdn_cfg_is_group_method(group, METHOD_ROUND_ROBIN)) {
02492 chan_misdn_log(4, port, " --> STARTING ROUND ROBIN...");
02493 rr = get_robin_position(group);
02494 }
02495
02496 if (rr) {
02497 int robin_channel = rr->channel;
02498 int port_start;
02499 int next_chan = 1;
02500
02501 do {
02502 port_start = 0;
02503 for (port = misdn_cfg_get_next_port_spin(rr->port); port > 0 && port != port_start;
02504 port = misdn_cfg_get_next_port_spin(port)) {
02505
02506 if (!port_start)
02507 port_start = port;
02508
02509 if (port >= port_start)
02510 next_chan = 1;
02511
02512 if (port <= port_start && next_chan) {
02513 int maxbchans=misdn_lib_get_maxchans(port);
02514 if (++robin_channel >= maxbchans) {
02515 robin_channel = 1;
02516 }
02517 next_chan = 0;
02518 }
02519
02520 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE);
02521
02522 if (!strcasecmp(cfg_group, group)) {
02523 int port_up;
02524 int check;
02525 misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int));
02526 port_up = misdn_lib_port_up(port, check);
02527
02528 if (check && !port_up)
02529 chan_misdn_log(1,port,"L1 is not Up on this Port\n");
02530
02531 if (check && port_up<0) {
02532 ast_log(LOG_WARNING,"This port (%d) is blocked\n", port);
02533 }
02534
02535
02536 if ( port_up>0 ) {
02537 newbc = misdn_lib_get_free_bc(port, robin_channel);
02538 if (newbc) {
02539 chan_misdn_log(4, port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel);
02540 if (port_up)
02541 chan_misdn_log(4, port, "portup:%d\n", port_up);
02542 rr->port = newbc->port;
02543 rr->channel = newbc->channel;
02544 break;
02545 }
02546 }
02547 }
02548 }
02549 } while (!newbc && robin_channel != rr->channel);
02550
02551 if (!newbc)
02552 chan_misdn_log(-1, port, " Failed! No free channel in group %d!", group);
02553 }
02554
02555 else {
02556 for (port=misdn_cfg_get_next_port(0); port > 0;
02557 port=misdn_cfg_get_next_port(port)) {
02558
02559 misdn_cfg_get( port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE);
02560
02561 chan_misdn_log(3,port, "Group [%s] Port [%d]\n", group, port);
02562 if (!strcasecmp(cfg_group, group)) {
02563 int port_up;
02564 int check;
02565 misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int));
02566 port_up = misdn_lib_port_up(port, check);
02567
02568 chan_misdn_log(4, port, "portup:%d\n", port_up);
02569
02570 if ( port_up>0 ) {
02571 newbc = misdn_lib_get_free_bc(port, 0);
02572 if (newbc)
02573 break;
02574 }
02575 }
02576 }
02577 }
02578
02579 } else {
02580 if (channel)
02581 chan_misdn_log(1, port," --> preselected_channel: %d\n",channel);
02582 newbc = misdn_lib_get_free_bc(port, channel);
02583 }
02584
02585 if (!newbc) {
02586 chan_misdn_log(-1, 0, "Could not create channel on port:%d with extensions:%s\n",port,ext);
02587 return NULL;
02588 }
02589
02590
02591 cl->bc=newbc;
02592
02593 tmp = misdn_new(cl, AST_STATE_RESERVED, ext, NULL, format, port, channel);
02594 cl->ast=tmp;
02595
02596
02597 cl_queue_chan(&cl_te, cl) ;
02598
02599
02600 read_config(cl, ORG_AST);
02601
02602
02603 cl->need_hangup=0;
02604
02605 return tmp;
02606 }
02607
02608
02609 int misdn_send_text (struct ast_channel *chan, const char *text)
02610 {
02611 struct chan_list *tmp=chan->tech_pvt;
02612
02613 if (tmp && tmp->bc) {
02614 ast_copy_string(tmp->bc->display,text,sizeof(tmp->bc->display));
02615 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
02616 } else {
02617 ast_log(LOG_WARNING, "No chan_list but send_text request?\n");
02618 return -1;
02619 }
02620
02621 return 0;
02622 }
02623
02624 static struct ast_channel_tech misdn_tech = {
02625 .type="mISDN",
02626 .description="Channel driver for mISDN Support (Bri/Pri)",
02627 .capabilities= AST_FORMAT_ALAW ,
02628 .requester=misdn_request,
02629 .send_digit=misdn_digit,
02630 .call=misdn_call,
02631 .bridge=misdn_bridge,
02632 .hangup=misdn_hangup,
02633 .answer=misdn_answer,
02634 .read=misdn_read,
02635 .write=misdn_write,
02636 .indicate=misdn_indication,
02637 .fixup=misdn_fixup,
02638 .send_text=misdn_send_text,
02639 .properties=0
02640 };
02641
02642 static struct ast_channel_tech misdn_tech_wo_bridge = {
02643 .type="mISDN",
02644 .description="Channel driver for mISDN Support (Bri/Pri)",
02645 .capabilities=AST_FORMAT_ALAW ,
02646 .requester=misdn_request,
02647 .send_digit=misdn_digit,
02648 .call=misdn_call,
02649 .hangup=misdn_hangup,
02650 .answer=misdn_answer,
02651 .read=misdn_read,
02652 .write=misdn_write,
02653 .indicate=misdn_indication,
02654 .fixup=misdn_fixup,
02655 .send_text=misdn_send_text,
02656 .properties=0
02657 };
02658
02659
02660 static unsigned long glob_channel=0;
02661
02662 static struct ast_channel *misdn_new(struct chan_list *chlist, int state, char *exten, char *callerid, int format, int port, int c)
02663 {
02664 struct ast_channel *tmp;
02665
02666 tmp = ast_channel_alloc(1);
02667
02668 if (tmp) {
02669 chan_misdn_log(2, 0, " --> * NEW CHANNEL dad:%s oad:%s\n",exten,callerid);
02670
02671
02672 if (c<=0) {
02673 c=glob_channel++;
02674 snprintf(tmp->name, sizeof(tmp->name), "%s/%d-u%d",
02675 misdn_type, port, c);
02676 } else {
02677 snprintf(tmp->name, sizeof(tmp->name), "%s/%d-%d",
02678 misdn_type, port, c);
02679 }
02680
02681 tmp->type = misdn_type;
02682
02683 tmp->nativeformats = prefformat;
02684
02685 tmp->readformat = format;
02686 tmp->rawreadformat = format;
02687 tmp->writeformat = format;
02688 tmp->rawwriteformat = format;
02689
02690 tmp->tech_pvt = chlist;
02691
02692 int bridging;
02693 misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
02694 if (bridging)
02695 tmp->tech = &misdn_tech;
02696 else
02697 tmp->tech = &misdn_tech_wo_bridge;
02698
02699 tmp->writeformat = format;
02700 tmp->readformat = format;
02701 tmp->priority=1;
02702
02703 if (exten)
02704 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten));
02705 else
02706 chan_misdn_log(1,0,"misdn_new: no exten given.\n");
02707
02708 if (callerid) {
02709 char *cid_name, *cid_num;
02710
02711 ast_callerid_parse(callerid, &cid_name, &cid_num);
02712
02713 if (!ast_strlen_zero(cid_num))
02714 tmp->cid.cid_num = strdup(cid_num);
02715 if (!ast_strlen_zero(cid_name))
02716 tmp->cid.cid_name = strdup(cid_name);
02717 }
02718
02719 {
02720 if (pipe(chlist->pipe)<0)
02721 perror("Pipe failed\n");
02722
02723 tmp->fds[0]=chlist->pipe[0];
02724
02725 }
02726
02727 ast_setstate(tmp, state);
02728 if (state == AST_STATE_RING)
02729 tmp->rings = 1;
02730 else
02731 tmp->rings = 0;
02732
02733
02734 } else {
02735 chan_misdn_log(-1,0,"Unable to allocate channel structure\n");
02736 }
02737
02738 return tmp;
02739 }
02740
02741
02742 struct ast_frame *process_ast_dsp(struct chan_list *tmp, struct ast_frame *frame)
02743 {
02744 struct ast_frame *f,*f2;
02745 if (tmp->trans)
02746 f2=ast_translate(tmp->trans, frame,0);
02747 else {
02748 chan_misdn_log(0, tmp->bc->port, "No T-Path found\n");
02749 return NULL;
02750 }
02751
02752 f = ast_dsp_process(tmp->ast, tmp->dsp, f2);
02753 if (f && (f->frametype == AST_FRAME_DTMF)) {
02754 ast_log(LOG_DEBUG, "Detected inband DTMF digit: %c", f->subclass);
02755 if (f->subclass == 'f' && tmp->faxdetect) {
02756
02757 struct ast_channel *ast = tmp->ast;
02758 if (!tmp->faxhandled) {
02759 tmp->faxhandled++;
02760 if (strcmp(ast->exten, "fax")) {
02761 if (ast_exists_extension(ast, ast_strlen_zero(ast->macrocontext)? ast->context : ast->macrocontext, "fax", 1, AST_CID_P(ast))) {
02762 if (option_verbose > 2)
02763 ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
02764
02765 pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten);
02766 if (ast_async_goto(ast, ast->context, "fax", 1))
02767 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, ast->context);
02768 } else
02769 ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n",ast->context, ast->exten);
02770 } else
02771 ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
02772 } else
02773 ast_log(LOG_DEBUG, "Fax already handled\n");
02774
02775 } else if ( tmp->ast_dsp) {
02776 chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n",f->subclass);
02777 return f;
02778 }
02779 }
02780
02781 frame->frametype = AST_FRAME_NULL;
02782 frame->subclass = 0;
02783 return frame;
02784 }
02785
02786
02787 static struct chan_list *find_chan_by_bc(struct chan_list *list, struct misdn_bchannel *bc)
02788 {
02789 struct chan_list *help=list;
02790 for (;help; help=help->next) {
02791 if (help->bc == bc) return help;
02792 }
02793
02794 chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad);
02795
02796 return NULL;
02797 }
02798
02799 static struct chan_list *find_chan_by_pid(struct chan_list *list, int pid)
02800 {
02801 struct chan_list *help=list;
02802 for (;help; help=help->next) {
02803 if (help->bc->pid == pid) return help;
02804 }
02805
02806 chan_misdn_log(6, 0, "$$$ find_chan: No channel found for pid:%d\n",pid);
02807
02808 return NULL;
02809 }
02810
02811 static struct chan_list *find_holded(struct chan_list *list, struct misdn_bchannel *bc)
02812 {
02813 struct chan_list *help=list;
02814
02815 chan_misdn_log(6, bc->port, "$$$ find_holded: channel:%d oad:%s dad:%s\n",bc->channel, bc->oad,bc->dad);
02816 for (;help; help=help->next) {
02817 chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n",help->bc->holded, help->bc->channel);
02818 if (help->bc->port == bc->port
02819 && help->bc->holded ) return help;
02820 }
02821
02822 chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad);
02823
02824 return NULL;
02825 }
02826
02827 static void cl_queue_chan(struct chan_list **list, struct chan_list *chan)
02828 {
02829 chan_misdn_log(4, chan->bc? chan->bc->port : 0, "* Queuing chan %p\n",chan);
02830
02831 ast_mutex_lock(&cl_te_lock);
02832 if (!*list) {
02833 *list = chan;
02834 } else {
02835 struct chan_list *help=*list;
02836 for (;help->next; help=help->next);
02837 help->next=chan;
02838 }
02839 chan->next=NULL;
02840 ast_mutex_unlock(&cl_te_lock);
02841 }
02842
02843 static void cl_dequeue_chan(struct chan_list **list, struct chan_list *chan)
02844 {
02845 if (chan->dsp)
02846 ast_dsp_free(chan->dsp);
02847 if (chan->trans)
02848 ast_translator_free_path(chan->trans);
02849
02850
02851
02852 ast_mutex_lock(&cl_te_lock);
02853 if (!*list) {
02854 ast_mutex_unlock(&cl_te_lock);
02855 return;
02856 }
02857
02858 if (*list == chan) {
02859 *list=(*list)->next;
02860 ast_mutex_unlock(&cl_te_lock);
02861 return ;
02862 }
02863
02864 {
02865 struct chan_list *help=*list;
02866 for (;help->next; help=help->next) {
02867 if (help->next == chan) {
02868 help->next=help->next->next;
02869 ast_mutex_unlock(&cl_te_lock);
02870 return;
02871 }
02872 }
02873 }
02874
02875 ast_mutex_unlock(&cl_te_lock);
02876 }
02877
02878
02879
02880
02881 int pbx_start_chan(struct chan_list *ch)
02882 {
02883 int ret=ast_pbx_start(ch->ast);
02884
02885 if (ret>=0)
02886 ch->need_hangup=0;
02887 else
02888 ch->need_hangup=1;
02889
02890 return ret;
02891 }
02892
02893 static void hangup_chan(struct chan_list *ch)
02894 {
02895 if (!ch) {
02896 cb_log(1,0,"Cannot hangup chan, no ch\n");
02897 return;
02898 }
02899
02900 cb_log(1,ch->bc?ch->bc->port:0,"hangup_chan\n");
02901
02902 if (ch->need_hangup)
02903 {
02904 cb_log(1,ch->bc->port,"-> hangup\n");
02905 send_cause2ast(ch->ast,ch->bc,ch);
02906 ch->need_hangup=0;
02907 ch->need_queue_hangup=0;
02908 if (ch->ast)
02909 ast_hangup(ch->ast);
02910 return;
02911 }
02912
02913 if (!ch->need_queue_hangup) {
02914 cb_log(1,ch->bc->port,"No need to queue hangup\n");
02915 }
02916
02917 ch->need_queue_hangup=0;
02918 if (ch->ast) {
02919 send_cause2ast(ch->ast,ch->bc,ch);
02920
02921 if (ch->ast)
02922 ast_queue_hangup(ch->ast);
02923 cb_log(1,ch->bc->port,"-> queue_hangup\n");
02924 } else {
02925 cb_log(1,ch->bc->port,"Cannot hangup chan, no ast\n");
02926 }
02927 }
02928
02929
02930 static void release_chan(struct misdn_bchannel *bc) {
02931 struct ast_channel *ast=NULL;
02932 {
02933 struct chan_list *ch=find_chan_by_bc(cl_te, bc);
02934 if (!ch) {
02935 chan_misdn_log(0, bc->port, "release_chan: Ch not found!\n");
02936 return;
02937 }
02938
02939 if (ch->ast) {
02940 ast=ch->ast;
02941 }
02942
02943 chan_misdn_log(1, bc->port, "release_chan: bc with l3id: %x\n",bc->l3_id);
02944
02945
02946 if (ch->jb ) {
02947 misdn_jb_destroy(ch->jb);
02948 ch->jb=NULL;
02949 } else {
02950 if (!bc->nojitter)
02951 chan_misdn_log(5,bc->port,"Jitterbuffer already destroyed.\n");
02952 }
02953
02954 if (ch) {
02955
02956 close(ch->pipe[0]);
02957 close(ch->pipe[1]);
02958
02959
02960 if (ast && MISDN_ASTERISK_TECH_PVT(ast)) {
02961 chan_misdn_log(1, bc->port, "* RELEASING CHANNEL pid:%d ctx:%s dad:%s oad:%s state: %s\n",bc?bc->pid:-1, ast->context, ast->exten,AST_CID_P(ast),misdn_get_ch_state(ch));
02962 chan_misdn_log(3, bc->port, " --> * State Down\n");
02963 MISDN_ASTERISK_TECH_PVT(ast)=NULL;
02964
02965
02966 if (ast->_state != AST_STATE_RESERVED) {
02967 chan_misdn_log(3, bc->port, " --> Setting AST State to down\n");
02968 ast_setstate(ast, AST_STATE_DOWN);
02969 }
02970 }
02971
02972 ch->state=MISDN_CLEANING;
02973 cl_dequeue_chan(&cl_te, ch);
02974
02975 free(ch);
02976 } else {
02977
02978 }
02979 }
02980 }
02981
02982
02983 static void misdn_transfer_bc(struct chan_list *tmp_ch, struct chan_list *holded_chan)
02984 {
02985 chan_misdn_log(4,0,"TRANSFERING %s to %s\n",holded_chan->ast->name, tmp_ch->ast->name);
02986
02987 tmp_ch->state=MISDN_HOLD_DISCONNECT;
02988
02989 ast_moh_stop(AST_BRIDGED_P(holded_chan->ast));
02990
02991 holded_chan->state=MISDN_CONNECTED;
02992 misdn_lib_transfer(holded_chan->bc?holded_chan->bc:holded_chan->holded_bc);
02993 ast_channel_masquerade(holded_chan->ast, AST_BRIDGED_P(tmp_ch->ast));
02994 }
02995
02996
02997 static void do_immediate_setup(struct misdn_bchannel *bc,struct chan_list *ch , struct ast_channel *ast)
02998 {
02999 char predial[256]="";
03000 char *p = predial;
03001
03002 struct ast_frame fr;
03003
03004 strncpy(predial, ast->exten, sizeof(predial) -1 );
03005
03006 ch->state=MISDN_DIALING;
03007
03008 if (bc->nt) {
03009 int ret;
03010 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03011 } else {
03012 int ret;
03013 if ( misdn_lib_is_ptp(bc->port)) {
03014 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03015 } else {
03016 ret = misdn_lib_send_event(bc, EVENT_PROCEEDING );
03017 }
03018 }
03019
03020 if ( !bc->nt && (ch->orginator==ORG_MISDN) && !ch->incoming_early_audio )
03021 chan_misdn_log(1,bc->port, " --> incoming_early_audio off\n");
03022 else
03023 dialtone_indicate(ch);
03024
03025 chan_misdn_log(1, bc->port, "* Starting Ast ctx:%s dad:%s oad:%s with 's' extension\n", ast->context, ast->exten, AST_CID_P(ast));
03026
03027 strncpy(ast->exten,"s", 2);
03028
03029 if (pbx_start_chan(ch)<0) {
03030 ast=NULL;
03031 hangup_chan(ch);
03032 hanguptone_indicate(ch);
03033
03034 if (bc->nt)
03035 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
03036 else
03037 misdn_lib_send_event(bc, EVENT_DISCONNECT );
03038 }
03039
03040
03041 while (!ast_strlen_zero(p) ) {
03042 fr.frametype = AST_FRAME_DTMF;
03043 fr.subclass = *p ;
03044 fr.src=NULL;
03045 fr.data = NULL ;
03046 fr.datalen = 0;
03047 fr.samples = 0 ;
03048 fr.mallocd =0 ;
03049 fr.offset= 0 ;
03050
03051 if (ch->ast && MISDN_ASTERISK_PVT(ch->ast) && MISDN_ASTERISK_TECH_PVT(ch->ast)) {
03052 ast_queue_frame(ch->ast, &fr);
03053 }
03054 p++;
03055 }
03056 }
03057
03058
03059
03060 static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel*bc, struct chan_list *ch) {
03061 if (!ast) {
03062 chan_misdn_log(1,0,"send_cause2ast: No Ast\n");
03063 return;
03064 }
03065 if (!bc) {
03066 chan_misdn_log(1,0,"send_cause2ast: No BC\n");
03067 return;
03068 }
03069 if (!ch) {
03070 chan_misdn_log(1,0,"send_cause2ast: No Ch\n");
03071 return;
03072 }
03073
03074 ast->hangupcause=bc->cause;
03075
03076 switch ( bc->cause) {
03077
03078 case 1:
03079 case 2:
03080 case 3:
03081 case 4:
03082 case 22:
03083 case 27:
03084
03085
03086
03087
03088
03089
03090
03091
03092
03093 break;
03094
03095 case 21:
03096 case 17:
03097
03098 ch->state=MISDN_BUSY;
03099
03100 if (!ch->need_busy) {
03101 chan_misdn_log(1,bc?bc->port:0, "Queued busy already\n");
03102 break;
03103 }
03104
03105 chan_misdn_log(1, bc?bc->port:0, " --> * SEND: Queue Busy pid:%d\n", bc?bc->pid:-1);
03106
03107 ast_queue_control(ast, AST_CONTROL_BUSY);
03108
03109 ch->need_busy=0;
03110
03111 break;
03112 }
03113 }
03114
03115 void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
03116 {
03117 char *tmp;
03118 tmp=pbx_builtin_getvar_helper(chan,"MISDN_PID");
03119 if (tmp) {
03120 ch->other_pid=atoi(tmp);
03121 chan_misdn_log(1,bc->port,"IMPORT_PID: importing pid:%s\n",tmp);
03122
03123 if (ch->other_pid >0) {
03124 ch->other_ch=find_chan_by_pid(cl_te,ch->other_pid);
03125 if (ch->other_ch) ch->other_ch->other_ch=ch;
03126 }
03127 }
03128 }
03129
03130 void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
03131 {
03132 char tmp[32];
03133
03134 chan_misdn_log(1,bc->port,"EXPORT_PID: pid:%d\n",bc->pid);
03135 sprintf(tmp,"%d",bc->pid);
03136 pbx_builtin_setvar_helper(chan,"_MISDN_PID",tmp);
03137 }
03138
03139
03140
03141
03142
03143
03144 static enum event_response_e
03145 cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
03146 {
03147 struct chan_list *ch=find_chan_by_bc(cl_te, bc);
03148
03149 if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) {
03150 int debuglevel=1;
03151
03152 if ( event==EVENT_CLEANUP && !user_data)
03153 debuglevel=5;
03154
03155 chan_misdn_log(debuglevel, bc->port, "I IND :%s oad:%s dad:%s pid:%d state:%s\n", manager_isdn_get_info(event), bc->oad, bc->dad, bc->pid, ch?misdn_get_ch_state(ch):"none");
03156 if (debuglevel==1) {
03157 misdn_lib_log_ies(bc);
03158 chan_misdn_log(4,bc->port," --> bc_state:%s\n",bc_state2str(bc->bc_state));
03159 }
03160 }
03161
03162 if (!ch) {
03163 switch(event) {
03164 case EVENT_SETUP:
03165 case EVENT_DISCONNECT:
03166 case EVENT_PORT_ALARM:
03167 case EVENT_RETRIEVE:
03168 case EVENT_NEW_BC:
03169 break;
03170 case EVENT_RELEASE_COMPLETE:
03171 chan_misdn_log(1, bc->port, " --> no Ch, so we've already released.\n");
03172 break;
03173 case EVENT_CLEANUP:
03174 case EVENT_TONE_GENERATE:
03175 case EVENT_BCHAN_DATA:
03176 return -1;
03177
03178 default:
03179 chan_misdn_log(1,bc->port, "Chan not existing at the moment bc->l3id:%x bc:%p event:%s port:%d channel:%d\n",bc->l3_id, bc, manager_isdn_get_info( event), bc->port,bc->channel);
03180 return -1;
03181 }
03182 }
03183
03184 if (ch ) {
03185 switch (event) {
03186 case EVENT_TONE_GENERATE:
03187 break;
03188 case EVENT_DISCONNECT:
03189 case EVENT_RELEASE:
03190 case EVENT_RELEASE_COMPLETE:
03191 case EVENT_CLEANUP:
03192 case EVENT_TIMEOUT:
03193 if (!ch->ast)
03194 chan_misdn_log(3,bc->port,"ast_hangup already called, so we have no ast ptr anymore in event(%s)\n",manager_isdn_get_info(event));
03195 break;
03196 default:
03197 if ( !ch->ast || !MISDN_ASTERISK_PVT(ch->ast) || !MISDN_ASTERISK_TECH_PVT(ch->ast)) {
03198 if (event!=EVENT_BCHAN_DATA)
03199 ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event));
03200 return -1;
03201 }
03202 }
03203 }
03204
03205
03206 switch (event) {
03207 case EVENT_PORT_ALARM:
03208 {
03209 int boa=0;
03210
03211 misdn_cfg_get( bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(int));
03212 if (boa) {
03213 cb_log(1,bc->port," --> blocking\n");
03214 misdn_lib_port_block(bc->port);
03215 }
03216 }
03217 break;
03218
03219 case EVENT_BCHAN_ACTIVATED:
03220 break;
03221
03222 case EVENT_NEW_L3ID:
03223 ch->l3id=bc->l3_id;
03224 ch->addr=bc->addr;
03225 break;
03226
03227 case EVENT_NEW_BC:
03228 if (!ch) {
03229 ch=find_holded(cl_te,bc);
03230 }
03231
03232 if (!ch) {
03233 ast_log(LOG_WARNING,"NEW_BC without chan_list?\n");
03234 break;
03235 }
03236
03237 if (bc)
03238 ch->bc=(struct misdn_bchannel*)user_data;
03239 break;
03240
03241 case EVENT_DTMF_TONE:
03242 {
03243
03244 struct ast_frame fr;
03245 memset(&fr, 0 , sizeof(fr));
03246 fr.frametype = AST_FRAME_DTMF;
03247 fr.subclass = bc->dtmf ;
03248 fr.src=NULL;
03249 fr.data = NULL ;
03250 fr.datalen = 0;
03251 fr.samples = 0 ;
03252 fr.mallocd =0 ;
03253 fr.offset= 0 ;
03254
03255 if (!ch->ignore_dtmf) {
03256 chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf);
03257 ast_queue_frame(ch->ast, &fr);
03258 } else {
03259 chan_misdn_log(2, bc->port, " --> Ingoring DTMF:%c due to bridge flags\n", bc->dtmf);
03260 }
03261 }
03262 break;
03263 case EVENT_STATUS:
03264 break;
03265
03266 case EVENT_INFORMATION:
03267 {
03268 int stop_tone;
03269 misdn_cfg_get( 0, MISDN_GEN_STOP_TONE, &stop_tone, sizeof(int));
03270 if ( stop_tone ) {
03271 stop_indicate(ch);
03272 }
03273
03274 if (ch->state == MISDN_WAITING4DIGS ) {
03275
03276 {
03277 int l = sizeof(bc->dad);
03278 strncat(bc->dad,bc->info_dad, l);
03279 bc->dad[l-1] = 0;
03280 }
03281
03282
03283 {
03284 int l = sizeof(ch->ast->exten);
03285 strncpy(ch->ast->exten, bc->dad, l);
03286 ch->ast->exten[l-1] = 0;
03287 }
03288
03289
03290
03291 if (!strcmp(ch->ast->exten, ast_pickup_ext())) {
03292 int ret;
03293 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03294 if (ast_pickup_call(ch->ast)) {
03295 hangup_chan(ch);
03296 } else {
03297 struct ast_channel *chan=ch->ast;
03298 ch->state = MISDN_CALLING_ACKNOWLEDGE;
03299 ast_setstate(chan, AST_STATE_DOWN);
03300 hangup_chan(ch);
03301 ch->ast=NULL;
03302 break;
03303 }
03304 }
03305
03306 if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
03307
03308 chan_misdn_log(-1, bc->port, "Extension can never match, so disconnecting\n");
03309 if (bc->nt)
03310 hanguptone_indicate(ch);
03311 ch->state=MISDN_EXTCANTMATCH;
03312 bc->out_cause=1;
03313
03314 misdn_lib_send_event(bc, EVENT_DISCONNECT );
03315
03316 break;
03317 }
03318 if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
03319 ch->state=MISDN_DIALING;
03320
03321 stop_indicate(ch);
03322
03323 if (pbx_start_chan(ch)<0) {
03324 hangup_chan(ch);
03325
03326 chan_misdn_log(-1, bc->port, "ast_pbx_start returned < 0 in INFO\n");
03327 if (bc->nt) hanguptone_indicate(ch);
03328
03329 misdn_lib_send_event(bc, EVENT_DISCONNECT );
03330 }
03331 }
03332
03333 } else {
03334
03335 struct ast_frame fr;
03336 fr.frametype = AST_FRAME_DTMF;
03337 fr.subclass = bc->info_dad[0] ;
03338 fr.src=NULL;
03339 fr.data = NULL ;
03340 fr.datalen = 0;
03341 fr.samples = 0 ;
03342 fr.mallocd =0 ;
03343 fr.offset= 0 ;
03344
03345
03346 int digits;
03347 misdn_cfg_get( 0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(int));
03348 if (ch->state != MISDN_CONNECTED ) {
03349 if (digits) {
03350 int l = sizeof(bc->dad);
03351 strncat(bc->dad,bc->info_dad, l);
03352 bc->dad[l-1] = 0;
03353 l = sizeof(ch->ast->exten);
03354 strncpy(ch->ast->exten, bc->dad, l);
03355 ch->ast->exten[l-1] = 0;
03356
03357 ast_cdr_update(ch->ast);
03358 }
03359
03360 ast_queue_frame(ch->ast, &fr);
03361 }
03362 }
03363 }
03364 break;
03365 case EVENT_SETUP:
03366 {
03367 struct chan_list *ch=find_chan_by_bc(cl_te, bc);
03368 if (ch && ch->state != MISDN_NOTHING ) {
03369 chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n");
03370 return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE;
03371 }
03372 }
03373
03374
03375 int msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad);
03376 if (!bc->nt && ! msn_valid) {
03377 chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n");
03378 return RESPONSE_IGNORE_SETUP;
03379 }
03380
03381 print_bearer(bc);
03382
03383 {
03384 struct chan_list *ch=init_chan_list(ORG_MISDN);
03385 struct ast_channel *chan;
03386
03387 if (!ch) { chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n"); return 0;}
03388
03389 ch->bc = bc;
03390 ch->l3id=bc->l3_id;
03391 ch->addr=bc->addr;
03392 ch->orginator = ORG_MISDN;
03393
03394 chan=misdn_new(ch, AST_STATE_RESERVED,bc->dad, bc->oad, AST_FORMAT_ALAW, bc->port, bc->channel);
03395 ch->ast = chan;
03396
03397 read_config(ch, ORG_MISDN);
03398
03399 export_ch(chan, bc, ch);
03400
03401 ch->ast->rings=1;
03402 ast_setstate(ch->ast, AST_STATE_RINGING);
03403
03404 int pres,screen;
03405
03406 switch (bc->pres) {
03407 case 1:
03408 pres=AST_PRES_RESTRICTED; chan_misdn_log(2,bc->port," --> PRES: Restricted (1)\n");
03409 break;
03410 case 2:
03411 pres=AST_PRES_UNAVAILABLE; chan_misdn_log(2,bc->port," --> PRES: Restricted (2)\n");
03412 break;
03413 default:
03414 pres=AST_PRES_ALLOWED; chan_misdn_log(2,bc->port," --> PRES: Restricted (%d)\n", bc->pres);
03415 }
03416
03417 switch (bc->screen) {
03418 case 0:
03419 screen=AST_PRES_USER_NUMBER_UNSCREENED; chan_misdn_log(2,bc->port," --> SCREEN: Unscreened (0)\n");
03420 break;
03421 case 1:
03422 screen=AST_PRES_USER_NUMBER_PASSED_SCREEN; chan_misdn_log(2,bc->port," --> SCREEN: Passed screen (1)\n");
03423 break;
03424 case 2:
03425 screen=AST_PRES_USER_NUMBER_FAILED_SCREEN; chan_misdn_log(2,bc->port," --> SCREEN: failed screen (2)\n");
03426 break;
03427 case 3:
03428 screen=AST_PRES_NETWORK_NUMBER; chan_misdn_log(2,bc->port," --> SCREEN: Network Number (3)\n");
03429 break;
03430 default:
03431 screen=AST_PRES_USER_NUMBER_UNSCREENED; chan_misdn_log(2,bc->port," --> SCREEN: Unscreened (%d)\n",bc->screen);
03432 }
03433
03434 chan->cid.cid_pres=pres+screen;
03435
03436 pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability));
03437 chan->transfercapability=bc->capability;
03438
03439 switch (bc->capability) {
03440 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
03441 pbx_builtin_setvar_helper(chan,"CALLTYPE","DIGITAL");
03442 break;
03443 default:
03444 pbx_builtin_setvar_helper(chan,"CALLTYPE","SPEECH");
03445 }
03446
03447
03448 cl_queue_chan(&cl_te, ch) ;
03449
03450
03451 if (!strstr(ch->allowed_bearers,"all")) {
03452 int i;
03453 for (i=0; i< sizeof(allowed_bearers_array)/sizeof(struct allowed_bearers); i++) {
03454 if (allowed_bearers_array[i].cap == bc->capability) {
03455 if ( !strstr( ch->allowed_bearers, allowed_bearers_array[i].name)) {
03456 chan_misdn_log(0,bc->port,"Bearer Not allowed\b");
03457 bc->out_cause=88;
03458
03459 ch->state=MISDN_EXTCANTMATCH;
03460 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
03461 return RESPONSE_OK;
03462 }
03463 }
03464
03465 }
03466 }
03467
03468
03469 if (!strcmp(chan->exten, ast_pickup_ext())) {
03470 int ret;
03471 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03472 if (ast_pickup_call(chan)) {
03473 hangup_chan(ch);
03474 } else {
03475 ch->state = MISDN_CALLING_ACKNOWLEDGE;
03476 ast_setstate(chan, AST_STATE_DOWN);
03477 hangup_chan(ch);
03478 ch->ast=NULL;
03479 break;
03480 }
03481 }
03482
03483
03484
03485
03486
03487 {
03488 int ai;
03489 misdn_cfg_get( bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai));
03490 if ( ai ) {
03491 do_immediate_setup(bc, ch , chan);
03492 break;
03493 }
03494
03495
03496
03497 }
03498
03499
03500 {
03501 int im;
03502 misdn_cfg_get( bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im));
03503 if ( im && ast_strlen_zero(bc->dad) ) {
03504 do_immediate_setup(bc, ch , chan);
03505 break;
03506 }
03507 }
03508
03509
03510 chan_misdn_log(5,bc->port,"CONTEXT:%s\n",ch->context);
03511 if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
03512
03513 chan_misdn_log(-1, bc->port, "Extension can never match, so disconnecting\n");
03514
03515 if (bc->nt)
03516 hanguptone_indicate(ch);
03517 ch->state=MISDN_EXTCANTMATCH;
03518 bc->out_cause=1;
03519
03520 if (bc->nt)
03521 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
03522 else
03523 misdn_lib_send_event(bc, EVENT_RELEASE );
03524
03525 break;
03526 }
03527
03528 if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
03529 ch->state=MISDN_DIALING;
03530
03531 if (bc->nt || (bc->need_more_infos && misdn_lib_is_ptp(bc->port)) ) {
03532 int ret;
03533 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03534 } else {
03535 int ret;
03536 ret= misdn_lib_send_event(bc, EVENT_PROCEEDING );
03537 }
03538
03539 if (pbx_start_chan(ch)<0) {
03540 hangup_chan(ch);
03541
03542 chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n");
03543 chan=NULL;
03544
03545 if (bc->nt) {
03546 hanguptone_indicate(ch);
03547 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
03548 } else
03549 misdn_lib_send_event(bc, EVENT_RELEASE);
03550 }
03551 } else {
03552
03553 if (bc->sending_complete) {
03554 ch->state=MISDN_EXTCANTMATCH;
03555 bc->out_cause=1;
03556
03557 if (bc->nt) {
03558 chan_misdn_log(0,bc->port," --> sending_complete so we never match ..\n");
03559 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
03560 } else {
03561 chan_misdn_log(0,bc->port," --> sending_complete so we never match ..\n");
03562 misdn_lib_send_event(bc, EVENT_RELEASE);
03563 }
03564
03565 } else {
03566
03567 int ret= misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03568 if (ret == -ENOCHAN) {
03569 ast_log(LOG_WARNING,"Channel was catched, before we could Acknowledge\n");
03570 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
03571 }
03572
03573
03574
03575
03576 int stop_tone;
03577 misdn_cfg_get( 0, MISDN_GEN_STOP_TONE, &stop_tone, sizeof(int));
03578 if ( (!ast_strlen_zero(bc->dad)) && stop_tone )
03579 stop_indicate(ch);
03580 else {
03581 dialtone_indicate(ch);
03582 }
03583
03584 ch->state=MISDN_WAITING4DIGS;
03585 }
03586 }
03587
03588 }
03589 break;
03590 case EVENT_SETUP_ACKNOWLEDGE:
03591 {
03592 ch->state = MISDN_CALLING_ACKNOWLEDGE;
03593 if (!ast_strlen_zero(bc->infos_pending)) {
03594
03595
03596 {
03597 int l = sizeof(bc->dad);
03598 strncat(bc->dad,bc->infos_pending, l - strlen(bc->dad));
03599 bc->dad[l-1] = 0;
03600 }
03601 {
03602 int l = sizeof(ch->ast->exten);
03603 strncpy(ch->ast->exten, bc->dad, l);
03604 ch->ast->exten[l-1] = 0;
03605 }
03606 {
03607 int l = sizeof(bc->info_dad);
03608 strncpy(bc->info_dad, bc->infos_pending, l);
03609 bc->info_dad[l-1] = 0;
03610 }
03611 strncpy(bc->infos_pending,"", 1);
03612
03613 misdn_lib_send_event(bc, EVENT_INFORMATION);
03614 }
03615 }
03616 break;
03617 case EVENT_PROCEEDING:
03618 {
03619
03620 if ( misdn_cap_is_speech(bc->capability) &&
03621 misdn_inband_avail(bc) ) {
03622 start_bc_tones(ch);
03623 }
03624
03625 ch->state = MISDN_PROCEEDING;
03626
03627 ast_queue_control(ch->ast, AST_CONTROL_PROCEEDING);
03628 }
03629 break;
03630 case EVENT_PROGRESS:
03631 if (!bc->nt ) {
03632 if ( misdn_cap_is_speech(bc->capability) &&
03633 misdn_inband_avail(bc)
03634 ) {
03635 start_bc_tones(ch);
03636 }
03637
03638 ast_queue_control(ch->ast, AST_CONTROL_PROGRESS);
03639
03640 ch->state=MISDN_PROGRESS;
03641 }
03642 break;
03643
03644
03645 case EVENT_ALERTING:
03646 {
03647 ch->state = MISDN_ALERTING;
03648
03649 ast_queue_control(ch->ast, AST_CONTROL_RINGING);
03650 ast_setstate(ch->ast, AST_STATE_RINGING);
03651
03652 cb_log(1,bc->port,"Set State Ringing\n");
03653
03654 if ( misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) {
03655 cb_log(1,bc->port,"Starting Tones, we have inband Data\n");
03656 start_bc_tones(ch);
03657 } else {
03658 cb_log(1,bc->port,"We have no inband Data, the other end must create ringing\n");
03659 if (ch->far_alerting) {
03660 cb_log(1,bc->port,"The other end can not do ringing eh ?.. we must do all ourself..");
03661 start_bc_tones(ch);
03662
03663 }
03664 }
03665 }
03666 break;
03667 case EVENT_CONNECT:
03668 {
03669
03670 misdn_lib_send_event(bc,EVENT_CONNECT_ACKNOWLEDGE);
03671
03672 struct ast_channel *bridged=AST_BRIDGED_P(ch->ast);
03673
03674 misdn_lib_echo(bc,0);
03675 stop_indicate(ch);
03676
03677 if (bridged && !strcasecmp(bridged->tech->type,"mISDN")) {
03678 struct chan_list *bridged_ch=MISDN_ASTERISK_TECH_PVT(bridged);
03679
03680 chan_misdn_log(1,bc->port," --> copying cpndialplan:%d and cad:%s to the A-Channel\n",bc->cpnnumplan,bc->cad);
03681 if (bridged_ch) {
03682 bridged_ch->bc->cpnnumplan=bc->cpnnumplan;
03683 ast_copy_string(bridged_ch->bc->cad,bc->cad,sizeof(bc->cad));
03684 }
03685 }
03686 }
03687
03688
03689
03690
03691 case EVENT_CONNECT_ACKNOWLEDGE:
03692 {
03693 ch->l3id=bc->l3_id;
03694 ch->addr=bc->addr;
03695
03696 start_bc_tones(ch);
03697
03698
03699 ch->state = MISDN_CONNECTED;
03700 ast_queue_control(ch->ast, AST_CONTROL_ANSWER);
03701 }
03702 break;
03703 case EVENT_DISCONNECT:
03704
03705 if (ch) {
03706 struct chan_list *holded_ch=find_holded(cl_te, bc);
03707
03708 chan_misdn_log(3,bc->port," --> org:%d nt:%d, inbandavail:%d state:%d\n", ch->orginator, bc->nt, misdn_inband_avail(bc), ch->state);
03709 if ( ch->orginator==ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) {
03710
03711
03712
03713
03714
03715 chan_misdn_log(1,bc->port, " --> Inband Info Avail, not sending RELEASE\n");
03716
03717 ch->state=MISDN_DISCONNECTED;
03718 start_bc_tones(ch);
03719 break;
03720 }
03721
03722
03723 if (holded_ch && ch->ast ) {
03724 cb_log(1,bc->port," --> found holded ch\n");
03725 if (ch->state == MISDN_CONNECTED ) {
03726 misdn_transfer_bc(ch, holded_ch) ;
03727 }
03728 hangup_chan(ch);
03729 release_chan(bc);
03730 break;
03731 }
03732
03733 stop_bc_tones(ch);
03734 hangup_chan(ch);
03735 }
03736 bc->out_cause=-1;
03737 if (bc->need_release) misdn_lib_send_event(bc,EVENT_RELEASE);
03738 break;
03739
03740 case EVENT_RELEASE:
03741 {
03742 bc->out_cause=16;
03743
03744 hangup_chan(ch);
03745 release_chan(bc);
03746
03747 if (bc->need_release_complete)
03748 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
03749 }
03750 break;
03751 case EVENT_RELEASE_COMPLETE:
03752 {
03753 stop_bc_tones(ch);
03754 hangup_chan(ch);
03755 release_chan(bc);
03756 if(ch)
03757 ch->state=MISDN_CLEANING;
03758 }
03759 break;
03760 case EVENT_CLEANUP:
03761 {
03762 stop_bc_tones(ch);
03763
03764 switch(ch->state) {
03765 case MISDN_CALLING:
03766 bc->cause=27;
03767 break;
03768 default:
03769 break;
03770 }
03771
03772 hangup_chan(ch);
03773 release_chan(bc);
03774 }
03775 break;
03776
03777 case EVENT_TONE_GENERATE:
03778 {
03779 int tone_len=bc->tone_cnt;
03780 struct ast_channel *ast=ch->ast;
03781 void *tmp;
03782 int res;
03783 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
03784
03785 chan_misdn_log(9,bc->port,"TONE_GEN: len:%d\n");
03786
03787 if (!ast) break;
03788
03789 if (!ast->generator) break;
03790
03791
03792
03793 tmp = ast->generatordata;
03794 ast->generatordata = NULL;
03795 generate = ast->generator->generate;
03796
03797 if (tone_len <0 || tone_len > 512 ) {
03798 ast_log(LOG_NOTICE, "TONE_GEN: len was %d, set to 128\n",tone_len);
03799 tone_len=128;
03800 }
03801
03802 res = generate(ast, tmp, tone_len, tone_len);
03803 ast->generatordata = tmp;
03804
03805 if (res) {
03806 ast_log(LOG_WARNING, "Auto-deactivating generator\n");
03807 ast_deactivate_generator(ast);
03808 } else {
03809 bc->tone_cnt=0;
03810 }
03811 }
03812 break;
03813
03814 case EVENT_BCHAN_DATA:
03815 {
03816 if ( !misdn_cap_is_speech(ch->bc->capability) ) {
03817 struct ast_frame frame;
03818
03819 frame.frametype = AST_FRAME_VOICE;
03820 frame.subclass = AST_FORMAT_ALAW;
03821 frame.datalen = bc->bframe_len;
03822 frame.samples = bc->bframe_len ;
03823 frame.mallocd =0 ;
03824 frame.offset= 0 ;
03825 frame.src = NULL;
03826 frame.data = bc->bframe ;
03827
03828 ast_queue_frame(ch->ast,&frame);
03829 } else {
03830 fd_set wrfs;
03831 struct timeval tv;
03832 tv.tv_sec=0;
03833 tv.tv_usec=0;
03834
03835
03836 FD_ZERO(&wrfs);
03837 FD_SET(ch->pipe[1],&wrfs);
03838
03839 int t=select(FD_SETSIZE,NULL,&wrfs,NULL,&tv);
03840
03841 if (!t) {
03842 chan_misdn_log(9, bc->port, "Select Timed out\n");
03843 break;
03844 }
03845
03846 if (t<0) {
03847 chan_misdn_log(-1, bc->port, "Select Error (err=%s)\n",strerror(errno));
03848 break;
03849 }
03850
03851 if (FD_ISSET(ch->pipe[1],&wrfs)) {
03852 chan_misdn_log(9, bc->port, "writing %d bytes 2 asterisk\n",bc->bframe_len);
03853 int ret=write(ch->pipe[1], bc->bframe, bc->bframe_len);
03854
03855 if (ret<=0) {
03856 chan_misdn_log(-1, bc->port, "Write returned <=0 (err=%s)\n",strerror(errno));
03857 }
03858 } else {
03859 chan_misdn_log(1, bc->port, "Wripe Pipe full!\n");
03860 }
03861 }
03862 }
03863 break;
03864 case EVENT_TIMEOUT:
03865 {
03866 if (ch && bc)
03867 chan_misdn_log(1,bc->port,"--> state: %s\n",misdn_get_ch_state(ch));
03868
03869 switch (ch->state) {
03870 case MISDN_CALLING:
03871 case MISDN_DIALING:
03872 case MISDN_PROGRESS:
03873 case MISDN_ALERTING:
03874 case MISDN_PROCEEDING:
03875 case MISDN_CALLING_ACKNOWLEDGE:
03876 if (bc->nt) {
03877 bc->progress_indicator=8;
03878 hanguptone_indicate(ch);
03879 }
03880
03881 bc->out_cause=1;
03882 misdn_lib_send_event(bc,EVENT_DISCONNECT);
03883 break;
03884
03885 case MISDN_WAITING4DIGS:
03886 if (bc->nt) {
03887 bc->progress_indicator=8;
03888 bc->out_cause=1;
03889 hanguptone_indicate(ch);
03890 misdn_lib_send_event(bc,EVENT_DISCONNECT);
03891 } else {
03892 bc->out_cause=16;
03893 misdn_lib_send_event(bc,EVENT_RELEASE);
03894 }
03895
03896 break;
03897
03898
03899 case MISDN_CLEANING:
03900 chan_misdn_log(1,bc->port," --> in state cleaning .. so ingoring, the stack should clean it for us\n");
03901 break;
03902
03903 default:
03904 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
03905 }
03906 }
03907 break;
03908
03909
03910
03911
03912
03913 case EVENT_RETRIEVE:
03914 {
03915 ch=find_holded(cl_te, bc);
03916 if (!ch) {
03917 ast_log(LOG_WARNING, "Found no Holded channel, cannot Retrieve\n");
03918 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
03919 break;
03920 }
03921 struct ast_channel *hold_ast=AST_BRIDGED_P(ch->ast);
03922 ch->state = MISDN_CONNECTED;
03923
03924 if (hold_ast) {
03925 ast_moh_stop(hold_ast);
03926 }
03927
03928 if ( misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0)
03929 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
03930
03931
03932 }
03933 break;
03934
03935 case EVENT_HOLD:
03936 {
03937 int hold_allowed;
03938 misdn_cfg_get( bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(int));
03939
03940 if (!hold_allowed) {
03941
03942 chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n");
03943 misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
03944 break;
03945 }
03946
03947 #if 0
03948 {
03949 struct chan_list *holded_ch=find_holded(cl_te, bc);
03950 if (holded_ch) {
03951 misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
03952
03953 chan_misdn_log(-1, bc->port, "We can't use RETRIEVE at the moment due to mISDN bug!\n");
03954 break;
03955 }
03956 }
03957 #endif
03958 struct ast_channel *bridged=AST_BRIDGED_P(ch->ast);
03959
03960 if (bridged){
03961 struct chan_list *bridged_ch=MISDN_ASTERISK_TECH_PVT(bridged);
03962 ch->state = MISDN_HOLDED;
03963 ch->l3id = bc->l3_id;
03964
03965 bc->holded_bc=bridged_ch->bc;
03966 misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE);
03967
03968 ast_moh_start(bridged, NULL);
03969 } else {
03970 misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
03971 chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n");
03972 }
03973 }
03974 break;
03975
03976 case EVENT_FACILITY:
03977 print_facility(bc);
03978
03979 switch (bc->fac_type) {
03980 case FACILITY_CALLDEFLECT:
03981 {
03982 struct ast_channel *bridged=AST_BRIDGED_P(ch->ast);
03983 struct chan_list *ch;
03984
03985 if (bridged && MISDN_ASTERISK_TECH_PVT(bridged)) {
03986 ch=MISDN_ASTERISK_TECH_PVT(bridged);
03987
03988 if (ch->bc) {
03989
03990 }
03991
03992 }
03993
03994 }
03995
03996 break;
03997 default:
03998 chan_misdn_log(1, bc->port," --> not yet handled\n");
03999 }
04000
04001 break;
04002
04003 case EVENT_RESTART:
04004
04005 stop_bc_tones(ch);
04006 release_chan(bc);
04007
04008 break;
04009
04010 default:
04011 ast_log(LOG_NOTICE, "Got Unknown Event\n");
04012 break;
04013 }
04014
04015 return RESPONSE_OK;
04016 }
04017
04018
04019
04020
04021
04022
04023
04024
04025
04026
04027
04028 static int g_config_initialized=0;
04029
04030 int load_module(void)
04031 {
04032 int i;
04033
04034 char ports[256]="";
04035
04036 max_ports=misdn_lib_maxports_get();
04037
04038 if (max_ports<=0) {
04039 ast_log(LOG_ERROR, "Unable to initialize mISDN\n");
04040 return 0;
04041 }
04042
04043
04044 misdn_cfg_init(max_ports);
04045 g_config_initialized=1;
04046
04047 misdn_debug = (int *)malloc(sizeof(int) * (max_ports+1));
04048 misdn_cfg_get( 0, MISDN_GEN_DEBUG, &misdn_debug[0], sizeof(int));
04049 for (i = 1; i <= max_ports; i++)
04050 misdn_debug[i] = misdn_debug[0];
04051 misdn_debug_only = (int *)calloc(max_ports + 1, sizeof(int));
04052
04053
04054 {
04055 char tempbuf[BUFFERSIZE+1];
04056 misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, tempbuf, BUFFERSIZE);
04057 if (strlen(tempbuf))
04058 tracing = 1;
04059 }
04060
04061 ast_mutex_init(&cl_te_lock);
04062
04063 misdn_cfg_update_ptp();
04064 misdn_cfg_get_ports_string(ports);
04065
04066 if (strlen(ports))
04067 chan_misdn_log(0, 0, "Got: %s from get_ports\n",ports);
04068
04069 {
04070 struct misdn_lib_iface iface = {
04071 .cb_event = cb_events,
04072 .cb_log = chan_misdn_log,
04073 .cb_jb_empty = chan_misdn_jb_empty,
04074 };
04075 if (misdn_lib_init(ports, &iface, NULL))
04076 chan_misdn_log(0, 0, "No te ports initialized\n");
04077
04078 int ntflags=0;
04079 char ntfile[BUFFERSIZE+1];
04080
04081 misdn_cfg_get( 0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(int));
04082 misdn_cfg_get( 0, MISDN_GEN_NTDEBUGFILE, &ntfile, BUFFERSIZE);
04083
04084 misdn_lib_nt_debug_init(ntflags,ntfile);
04085
04086 }
04087
04088
04089 {
04090 if (ast_channel_register(&misdn_tech)) {
04091 ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type);
04092 unload_module();
04093 return -1;
04094 }
04095 }
04096
04097 ast_cli_register(&cli_send_display);
04098 ast_cli_register(&cli_send_cd);
04099 ast_cli_register(&cli_send_digit);
04100 ast_cli_register(&cli_toggle_echocancel);
04101 ast_cli_register(&cli_set_tics);
04102
04103 ast_cli_register(&cli_show_cls);
04104 ast_cli_register(&cli_show_cl);
04105 ast_cli_register(&cli_show_config);
04106 ast_cli_register(&cli_show_port);
04107 ast_cli_register(&cli_show_stacks);
04108
04109 ast_cli_register(&cli_port_block);
04110 ast_cli_register(&cli_port_unblock);
04111 ast_cli_register(&cli_restart_port);
04112 ast_cli_register(&cli_port_up);
04113 ast_cli_register(&cli_port_down);
04114 ast_cli_register(&cli_set_debug);
04115 ast_cli_register(&cli_set_crypt_debug);
04116 ast_cli_register(&cli_reload);
04117
04118
04119 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
04120 "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
04121 "Sets mISDN opts. and optargs\n"
04122 "\n"
04123 "The available options are:\n"
04124 " d - Send display text on called phone, text is the optparam\n"
04125 " n - don't detect dtmf tones on called channel\n"
04126 " h - make digital outgoing call\n"
04127 " c - make crypted outgoing call, param is keyindex\n"
04128 " e - perform echo cancelation on this channel,\n"
04129 " takes taps as arguments (32,64,128,256)\n"
04130 " s - send Non Inband DTMF as inband\n"
04131 " vr - rxgain control\n"
04132 " vt - txgain control\n"
04133 );
04134
04135
04136 ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility",
04137 "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n"
04138 "Sends the Facility Message FACILITY_TYPE with \n"
04139 "the given Arguments to the current ISDN Channel\n"
04140 "Supported Facilities are:\n"
04141 "\n"
04142 "type=calldeflect args=Nr where to deflect\n"
04143 );
04144
04145
04146 misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
04147
04148 chan_misdn_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n");
04149
04150 return 0;
04151 }
04152
04153
04154
04155 int unload_module(void)
04156 {
04157
04158 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
04159
04160 if (!g_config_initialized) return 0;
04161
04162 ast_cli_unregister(&cli_send_display);
04163
04164 ast_cli_unregister(&cli_send_cd);
04165
04166 ast_cli_unregister(&cli_send_digit);
04167 ast_cli_unregister(&cli_toggle_echocancel);
04168 ast_cli_unregister(&cli_set_tics);
04169
04170 ast_cli_unregister(&cli_show_cls);
04171 ast_cli_unregister(&cli_show_cl);
04172 ast_cli_unregister(&cli_show_config);
04173 ast_cli_unregister(&cli_show_port);
04174 ast_cli_unregister(&cli_show_stacks);
04175 ast_cli_unregister(&cli_port_block);
04176 ast_cli_unregister(&cli_port_unblock);
04177 ast_cli_unregister(&cli_restart_port);
04178 ast_cli_unregister(&cli_port_up);
04179 ast_cli_unregister(&cli_port_down);
04180 ast_cli_unregister(&cli_set_debug);
04181 ast_cli_unregister(&cli_set_crypt_debug);
04182 ast_cli_unregister(&cli_reload);
04183
04184 ast_unregister_application("misdn_set_opt");
04185 ast_unregister_application("misdn_facility");
04186
04187 ast_channel_unregister(&misdn_tech);
04188
04189
04190 free_robin_list();
04191 misdn_cfg_destroy();
04192 misdn_lib_destroy();
04193
04194 if (misdn_debug)
04195 free(misdn_debug);
04196 if (misdn_debug_only)
04197 free(misdn_debug_only);
04198
04199 return 0;
04200 }
04201
04202 int reload(void)
04203 {
04204 reload_config();
04205
04206 return 0;
04207 }
04208
04209 int usecount(void)
04210 {
04211 int res;
04212 ast_mutex_lock(&usecnt_lock);
04213 res = usecnt;
04214 ast_mutex_unlock(&usecnt_lock);
04215 return res;
04216 }
04217
04218 char *description(void)
04219 {
04220 return desc;
04221 }
04222
04223 char *key(void)
04224 {
04225 return ASTERISK_GPL_KEY;
04226 }
04227
04228
04229
04230
04231
04232
04233 static int misdn_facility_exec(struct ast_channel *chan, void *data)
04234 {
04235 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
04236 char *tok, *tokb;
04237
04238 chan_misdn_log(0,0,"TYPE: %s\n",chan->tech->type);
04239
04240 if (strcasecmp(chan->tech->type,"mISDN")) {
04241 ast_log(LOG_WARNING, "misdn_facility makes only sense with chan_misdn channels!\n");
04242 return -1;
04243 }
04244
04245 if (ast_strlen_zero((char *)data)) {
04246 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n");
04247 return -1;
04248 }
04249
04250 tok=strtok_r((char*)data,"|", &tokb) ;
04251
04252 if (!tok) {
04253 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n");
04254 return -1;
04255 }
04256
04257 if (!strcasecmp(tok,"calldeflect")) {
04258 tok=strtok_r(NULL,"|", &tokb) ;
04259
04260 if (!tok) {
04261 ast_log(LOG_WARNING, "Facility: Call Defl Requires arguments\n");
04262 }
04263
04264 misdn_lib_send_facility(ch->bc, FACILITY_CALLDEFLECT, tok);
04265
04266 } else {
04267 ast_log(LOG_WARNING, "Unknown Facility: %s\n",tok);
04268 }
04269
04270 return 0;
04271
04272 }
04273
04274
04275 static int misdn_set_opt_exec(struct ast_channel *chan, void *data)
04276 {
04277 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
04278 char *tok,*tokb;
04279 int keyidx=0;
04280 int rxgain=0;
04281 int txgain=0;
04282 int change_jitter=0;
04283
04284 if (strcasecmp(chan->tech->type,"mISDN")) {
04285 ast_log(LOG_WARNING, "misdn_set_opt makes only sense with chan_misdn channels!\n");
04286 return -1;
04287 }
04288
04289 if (ast_strlen_zero((char *)data)) {
04290 ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n");
04291 return -1;
04292 }
04293
04294 for (tok=strtok_r((char*)data, ":",&tokb);
04295 tok;
04296 tok=strtok_r(NULL,":",&tokb) ) {
04297 int neglect=0;
04298
04299 if (tok[0] == '!' ) {
04300 neglect=1;
04301 tok++;
04302 }
04303
04304 switch(tok[0]) {
04305
04306 case 'd' :
04307 ast_copy_string(ch->bc->display,++tok,84);
04308 chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n",ch->bc->display);
04309 break;
04310
04311 case 'n':
04312 chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n");
04313 ch->bc->nodsp=1;
04314 break;
04315
04316 case 'j':
04317 chan_misdn_log(1, ch->bc->port, "SETOPT: jitter\n");
04318 tok++;
04319 change_jitter=1;
04320
04321 switch ( tok[0] ) {
04322 case 'b' :
04323 ch->jb_len=atoi(++tok);
04324 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d\n",ch->jb_len);
04325 break;
04326 case 't' :
04327 ch->jb_upper_threshold=atoi(++tok);
04328 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d\n",ch->jb_upper_threshold);
04329 break;
04330
04331 case 'n':
04332 ch->bc->nojitter=1;
04333 chan_misdn_log(1, ch->bc->port, " --> nojitter\n");
04334 break;
04335
04336 default:
04337 ch->jb_len=4000;
04338 ch->jb_upper_threshold=0;
04339 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d (default)\n",ch->jb_len);
04340 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d (default)\n",ch->jb_upper_threshold);
04341 }
04342
04343 break;
04344
04345 case 'v':
04346 tok++;
04347
04348 switch ( tok[0] ) {
04349 case 'r' :
04350 rxgain=atoi(++tok);
04351 if (rxgain<-8) rxgain=-8;
04352 if (rxgain>8) rxgain=8;
04353 ch->bc->rxgain=rxgain;
04354 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n",rxgain);
04355 break;
04356 case 't':
04357 txgain=atoi(++tok);
04358 if (txgain<-8) txgain=-8;
04359 if (txgain>8) txgain=8;
04360 ch->bc->txgain=txgain;
04361 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n",txgain);
04362 break;
04363 }
04364 break;
04365
04366 case 'c':
04367 keyidx=atoi(++tok);
04368
04369 if (keyidx > misdn_key_vector_size || keyidx < 0 ) {
04370 ast_log(LOG_WARNING, "You entered the keyidx: %d but we have only %d keys\n",keyidx, misdn_key_vector_size );
04371 continue;
04372 }
04373
04374 {
04375 ast_copy_string(ch->bc->crypt_key, misdn_key_vector[keyidx], sizeof(ch->bc->crypt_key));
04376 }
04377
04378 chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n",misdn_key_vector[keyidx]);
04379 break;
04380
04381 case 'e':
04382 chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n");
04383
04384 if (neglect) {
04385 chan_misdn_log(1, ch->bc->port, " --> disabled\n");
04386 ch->bc->ec_enable=0;
04387
04388 } else {
04389 ch->bc->ec_enable=1;
04390 ch->bc->orig=ch->orginator;
04391 tok++;
04392 if (tok) {
04393 ch->bc->ec_deftaps=atoi(tok);
04394 }
04395 }
04396
04397 break;
04398
04399 case 'h':
04400 chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n");
04401
04402 if (strlen(tok) > 1 && tok[1]=='1') {
04403 chan_misdn_log(1, ch->bc->port, "SETOPT: HDLC \n");
04404 ch->bc->hdlc=1;
04405 }
04406 ch->bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
04407 break;
04408
04409 case 's':
04410 chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n");
04411 ch->bc->send_dtmf=1;
04412 break;
04413
04414 case 'f':
04415 chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n");
04416 ch->faxdetect=1;
04417 break;
04418
04419 case 'a':
04420 chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n");
04421 ch->ast_dsp=1;
04422 break;
04423
04424 case 'p':
04425 chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n",&tok[1]);
04426
04427 if (strstr(tok,"allowed") ) {
04428 ch->bc->pres=0;
04429 } else if (strstr(tok,"not_screened")) {
04430 ch->bc->pres=1;
04431 }
04432
04433
04434 break;
04435
04436
04437 default:
04438 break;
04439 }
04440 }
04441
04442 if (change_jitter)
04443 config_jitterbuffer(ch);
04444
04445
04446 if (ch->faxdetect || ch->ast_dsp) {
04447
04448 if (!ch->dsp) ch->dsp = ast_dsp_new();
04449 if (ch->dsp) ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT| DSP_FEATURE_FAX_DETECT);
04450 if (!ch->trans) ch->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW);
04451 }
04452
04453 if (ch->ast_dsp) {
04454 chan_misdn_log(1,ch->bc->port,"SETOPT: with AST_DSP we deactivate mISDN_dsp\n");
04455 ch->bc->nodsp=1;
04456 ch->bc->nojitter=1;
04457 }
04458
04459 return 0;
04460 }
04461
04462
04463 int chan_misdn_jb_empty ( struct misdn_bchannel *bc, char *buf, int len)
04464 {
04465 struct chan_list *ch=find_chan_by_bc(cl_te, bc);
04466
04467 if (ch && ch->jb) {
04468 return misdn_jb_empty(ch->jb, buf, len);
04469 }
04470
04471 return -1;
04472 }
04473
04474
04475
04476
04477
04478
04479
04480
04481
04482 struct misdn_jb *misdn_jb_init(int size, int upper_threshold)
04483 {
04484 int i;
04485 struct misdn_jb *jb = (struct misdn_jb*) malloc(sizeof(struct misdn_jb));
04486 jb->size = size;
04487 jb->upper_threshold = upper_threshold;
04488 jb->wp = 0;
04489 jb->rp = 0;
04490 jb->state_full = 0;
04491 jb->state_empty = 0;
04492 jb->bytes_wrote = 0;
04493 jb->samples = (char *)malloc(size*sizeof(char));
04494
04495 if (!jb->samples) {
04496 chan_misdn_log(-1,0,"No free Mem for jb->samples\n");
04497 return NULL;
04498 }
04499
04500 jb->ok = (char *)malloc(size*sizeof(char));
04501
04502 if (!jb->ok) {
04503 chan_misdn_log(-1,0,"No free Mem for jb->ok\n");
04504 return NULL;
04505 }
04506
04507 for(i=0; i<size; i++)
04508 jb->ok[i]=0;
04509
04510 ast_mutex_init(&jb->mutexjb);
04511
04512 return jb;
04513 }
04514
04515
04516 void misdn_jb_destroy(struct misdn_jb *jb)
04517 {
04518 ast_mutex_destroy(&jb->mutexjb);
04519
04520 free(jb->samples);
04521 free(jb);
04522 }
04523
04524
04525
04526 int misdn_jb_fill(struct misdn_jb *jb, const char *data, int len)
04527 {
04528 int i, j, rp, wp;
04529
04530 if (!jb || ! data) return 0;
04531
04532 ast_mutex_lock (&jb->mutexjb);
04533
04534 wp=jb->wp;
04535 rp=jb->rp;
04536
04537 for(i=0; i<len; i++)
04538 {
04539 jb->samples[wp]=data[i];
04540 jb->ok[wp]=1;
04541 wp = (wp!=jb->size-1 ? wp+1 : 0);
04542
04543 if(wp==jb->rp)
04544 jb->state_full=1;
04545 }
04546
04547 if(wp>=rp)
04548 jb->state_buffer=wp-rp;
04549 else
04550 jb->state_buffer= jb->size-rp+wp;
04551 chan_misdn_log(9,0,"misdn_jb_fill: written:%d | Bufferstatus:%d p:%x\n",len,jb->state_buffer,jb);
04552
04553 if(jb->state_full)
04554 {
04555 jb->wp=wp;
04556
04557 rp=wp;
04558 for(j=0; j<jb->upper_threshold; j++)
04559 rp = (rp!=0 ? rp-1 : jb->size-1);
04560 jb->rp=rp;
04561 jb->state_full=0;
04562 jb->state_empty=1;
04563
04564 ast_mutex_unlock (&jb->mutexjb);
04565
04566 return -1;
04567 }
04568
04569 if(!jb->state_empty)
04570 {
04571 jb->bytes_wrote+=len;
04572 if(jb->bytes_wrote>=jb->upper_threshold)
04573 {
04574 jb->state_empty=1;
04575 jb->bytes_wrote=0;
04576 }
04577 }
04578 jb->wp=wp;
04579
04580 ast_mutex_unlock (&jb->mutexjb);
04581
04582 return 0;
04583 }
04584
04585
04586
04587
04588 int misdn_jb_empty(struct misdn_jb *jb, char *data, int len)
04589 {
04590 int i, wp, rp, read=0;
04591
04592 ast_mutex_lock (&jb->mutexjb);
04593
04594 rp=jb->rp;
04595 wp=jb->wp;
04596
04597 if(jb->state_empty)
04598 {
04599 for(i=0; i<len; i++)
04600 {
04601 if(wp==rp)
04602 {
04603 jb->rp=rp;
04604 jb->state_empty=0;
04605
04606 ast_mutex_unlock (&jb->mutexjb);
04607
04608 return read;
04609 }
04610 else
04611 {
04612 if(jb->ok[rp]==1)
04613 {
04614 data[i]=jb->samples[rp];
04615 jb->ok[rp]=0;
04616 rp=(rp!=jb->size-1 ? rp+1 : 0);
04617 read+=1;
04618 }
04619 }
04620 }
04621
04622 if(wp >= rp)
04623 jb->state_buffer=wp-rp;
04624 else
04625 jb->state_buffer= jb->size-rp+wp;
04626 chan_misdn_log(9,0,"misdn_jb_empty: read:%d | Bufferstatus:%d p:%x\n",len,jb->state_buffer,jb);
04627
04628 jb->rp=rp;
04629 }
04630 else
04631 chan_misdn_log(9,0,"misdn_jb_empty: Wait...requested:%d p:%x\n",len,jb);
04632
04633 ast_mutex_unlock (&jb->mutexjb);
04634
04635 return read;
04636 }
04637
04638
04639
04640
04641
04642
04643
04644
04645
04646
04647
04648 void chan_misdn_log(int level, int port, char *tmpl, ...)
04649 {
04650 if (! ((0 <= port) && (port <= max_ports))) {
04651 ast_log(LOG_WARNING, "cb_log called with out-of-range port number! (%d)\n", port);
04652 port=0;
04653 level=-1;
04654 }
04655
04656 va_list ap;
04657 char buf[1024];
04658 char port_buf[8];
04659 sprintf(port_buf,"P[%2d] ",port);
04660
04661 va_start(ap, tmpl);
04662 vsnprintf( buf, 1023, tmpl, ap );
04663 va_end(ap);
04664
04665 if (level == -1)
04666 ast_log(LOG_WARNING, buf);
04667
04668 else if (misdn_debug_only[port] ?
04669 (level==1 && misdn_debug[port]) || (level==misdn_debug[port])
04670 : level <= misdn_debug[port]) {
04671
04672 ast_console_puts(port_buf);
04673 ast_console_puts(buf);
04674 }
04675
04676 if ((level <= misdn_debug[0]) && !ast_strlen_zero(global_tracefile) ) {
04677 time_t tm = time(NULL);
04678 char *tmp=ctime(&tm),*p;
04679
04680 FILE *fp= fopen(global_tracefile, "a+");
04681
04682 p=strchr(tmp,'\n');
04683 if (p) *p=':';
04684
04685 if (!fp) {
04686 ast_console_puts("Error opening Tracefile: [ ");
04687 ast_console_puts(global_tracefile);
04688 ast_console_puts(" ] ");
04689
04690 ast_console_puts(strerror(errno));
04691 ast_console_puts("\n");
04692 return ;
04693 }
04694
04695 fputs(tmp,fp);
04696 fputs(" ", fp);
04697 fputs(port_buf,fp);
04698 fputs(" ", fp);
04699 fputs(buf, fp);
04700
04701 fclose(fp);
04702 }
04703 }
04704
04705