00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "asterisk.h"
00038
00039 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 284478 $")
00040
00041 #include <stdio.h>
00042 #include <pthread.h>
00043 #include <string.h>
00044 #include <sys/socket.h>
00045 #include <sys/time.h>
00046 #include <errno.h>
00047 #include <unistd.h>
00048 #include <stdlib.h>
00049 #include <arpa/inet.h>
00050 #include <fcntl.h>
00051 #include <sys/ioctl.h>
00052 #include <signal.h>
00053 #include <sys/file.h>
00054 #include <semaphore.h>
00055
00056 #include "asterisk/channel.h"
00057 #include "asterisk/config.h"
00058 #include "asterisk/logger.h"
00059 #include "asterisk/module.h"
00060 #include "asterisk/pbx.h"
00061 #include "asterisk/options.h"
00062 #include "asterisk/io.h"
00063 #include "asterisk/frame.h"
00064 #include "asterisk/translate.h"
00065 #include "asterisk/cli.h"
00066 #include "asterisk/musiconhold.h"
00067 #include "asterisk/dsp.h"
00068 #include "asterisk/translate.h"
00069 #include "asterisk/config.h"
00070 #include "asterisk/file.h"
00071 #include "asterisk/callerid.h"
00072 #include "asterisk/indications.h"
00073 #include "asterisk/app.h"
00074 #include "asterisk/features.h"
00075 #include "asterisk/term.h"
00076 #include "asterisk/sched.h"
00077 #include "asterisk/stringfields.h"
00078 #include "asterisk/causes.h"
00079
00080 #include "chan_misdn_config.h"
00081 #include "isdn_lib.h"
00082
00083 char global_tracefile[BUFFERSIZE + 1];
00084
00085 static int g_config_initialized = 0;
00086
00087 struct misdn_jb{
00088 int size;
00089 int upper_threshold;
00090 char *samples, *ok;
00091 int wp,rp;
00092 int state_empty;
00093 int state_full;
00094 int state_buffer;
00095 int bytes_wrote;
00096 ast_mutex_t mutexjb;
00097 };
00098
00099
00100
00101
00102 struct misdn_jb *misdn_jb_init(int size, int upper_threshold);
00103
00104
00105 void misdn_jb_destroy(struct misdn_jb *jb);
00106
00107
00108
00109 int misdn_jb_fill(struct misdn_jb *jb, const char *data, int len);
00110
00111
00112
00113
00114 int misdn_jb_empty(struct misdn_jb *jb, char *data, int len);
00115
00116
00117
00118
00119 ast_mutex_t release_lock;
00120
00121 enum misdn_chan_state {
00122 MISDN_NOTHING=0,
00123 MISDN_WAITING4DIGS,
00124 MISDN_EXTCANTMATCH,
00125 MISDN_INCOMING_SETUP,
00126 MISDN_DIALING,
00127 MISDN_PROGRESS,
00128 MISDN_PROCEEDING,
00129 MISDN_CALLING,
00130 MISDN_CALLING_ACKNOWLEDGE,
00131 MISDN_ALERTING,
00132 MISDN_BUSY,
00133 MISDN_CONNECTED,
00134 MISDN_DISCONNECTED,
00135 MISDN_CLEANING,
00136 };
00137
00138 #define ORG_AST 1
00139 #define ORG_MISDN 2
00140
00141 enum misdn_hold_state {
00142 MISDN_HOLD_IDLE,
00143 MISDN_HOLD_ACTIVE,
00144 MISDN_HOLD_TRANSFER,
00145 MISDN_HOLD_DISCONNECT,
00146 };
00147 struct hold_info {
00148
00149
00150
00151 enum misdn_hold_state state;
00152
00153
00154
00155
00156 int port;
00157
00158
00159
00160
00161
00162 int channel;
00163 };
00164
00165
00166
00167
00168 struct chan_list {
00169
00170
00171
00172 char allowed_bearers[BUFFERSIZE + 1];
00173
00174
00175
00176
00177 enum misdn_chan_state state;
00178
00179
00180
00181
00182
00183 int need_queue_hangup;
00184
00185
00186
00187
00188 int need_hangup;
00189
00190
00191
00192
00193 int need_busy;
00194
00195
00196
00197
00198 int originator;
00199
00200
00201
00202
00203
00204 int noautorespond_on_setup;
00205
00206 int norxtone;
00207
00208
00209
00210
00211 int notxtone;
00212
00213
00214
00215
00216 int toggle_ec;
00217
00218
00219
00220
00221
00222
00223 int incoming_early_audio;
00224
00225
00226
00227
00228
00229 int ignore_dtmf;
00230
00231
00232
00233
00234
00235 int pipe[2];
00236
00237
00238
00239
00240 char ast_rd_buf[4096];
00241
00242
00243
00244
00245 struct ast_frame frame;
00246
00247
00248
00249
00250
00251
00252 int faxdetect;
00253
00254
00255
00256
00257
00258
00259 int faxdetect_timeout;
00260
00261
00262
00263
00264 struct timeval faxdetect_tv;
00265
00266
00267
00268
00269 int faxhandled;
00270
00271
00272
00273
00274
00275 int ast_dsp;
00276
00277
00278
00279
00280
00281 int jb_len;
00282
00283
00284
00285
00286
00287 int jb_upper_threshold;
00288
00289
00290
00291
00292
00293
00294 struct misdn_jb *jb;
00295
00296
00297
00298
00299
00300
00301 struct ast_dsp *dsp;
00302
00303
00304
00305
00306 struct ast_channel * ast;
00307
00308
00309
00310
00311
00312
00313 struct misdn_bchannel *bc;
00314
00315
00316
00317
00318 struct hold_info hold;
00319
00320
00321
00322
00323
00324 unsigned int l3id;
00325
00326
00327
00328
00329
00330 int addr;
00331
00332
00333
00334
00335
00336 char context[AST_MAX_CONTEXT];
00337
00338
00339
00340
00341
00342 char mohinterpret[MAX_MUSICCLASS];
00343
00344
00345
00346
00347
00348
00349 int dropped_frame_cnt;
00350
00351
00352
00353
00354
00355 int far_alerting;
00356
00357
00358
00359
00360
00361 int nttimeout;
00362
00363
00364
00365
00366
00367 int other_pid;
00368
00369
00370
00371
00372
00373
00374 struct chan_list *other_ch;
00375
00376
00377
00378
00379
00380 const struct tone_zone_sound *ts;
00381
00382
00383
00384
00385
00386 int overlap_dial;
00387
00388
00389
00390
00391 int overlap_dial_task;
00392
00393
00394
00395
00396 ast_mutex_t overlap_tv_lock;
00397
00398
00399
00400
00401 struct timeval overlap_tv;
00402
00403
00404
00405
00406
00407
00408 struct chan_list *next;
00409
00410
00411 };
00412
00413
00414
00415 void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch);
00416 void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch);
00417
00418 struct robin_list {
00419 char *group;
00420 int port;
00421 int channel;
00422 struct robin_list *next;
00423 struct robin_list *prev;
00424 };
00425 static struct robin_list *robin = NULL;
00426
00427
00428
00429 static struct ast_frame *process_ast_dsp(struct chan_list *tmp, struct ast_frame *frame);
00430
00431
00432
00433 static void free_robin_list(void)
00434 {
00435 struct robin_list *r;
00436 struct robin_list *next;
00437
00438 for (r = robin, robin = NULL; r; r = next) {
00439 next = r->next;
00440 free(r->group);
00441 free(r);
00442 }
00443 }
00444
00445 static struct robin_list* get_robin_position (char *group)
00446 {
00447 struct robin_list *new;
00448 struct robin_list *iter = robin;
00449 for (; iter; iter = iter->next) {
00450 if (!strcasecmp(iter->group, group)) {
00451 return iter;
00452 }
00453 }
00454 new = calloc(1, sizeof(*new));
00455 if (!new) {
00456 return NULL;
00457 }
00458 new->group = strdup(group);
00459 if (!new->group) {
00460 free(new);
00461 return NULL;
00462 }
00463 new->port = 0;
00464 new->channel = 0;
00465 if (robin) {
00466 new->next = robin;
00467 robin->prev = new;
00468 }
00469 robin = new;
00470 return robin;
00471 }
00472
00473
00474
00475 static struct sched_context *misdn_tasks = NULL;
00476 static pthread_t misdn_tasks_thread;
00477
00478 static int *misdn_ports;
00479
00480 static void chan_misdn_log(int level, int port, char *tmpl, ...)
00481 __attribute__((format(printf, 3, 4)));
00482
00483 static struct ast_channel *misdn_new(struct chan_list *cl, int state, char *exten, char *callerid, int format, int port, int c);
00484 static void send_digit_to_chan(struct chan_list *cl, char digit );
00485
00486 static int pbx_start_chan(struct chan_list *ch);
00487
00488 #define MISDN_ASTERISK_TECH_PVT(ast) ast->tech_pvt
00489 #define MISDN_ASTERISK_PVT(ast) 1
00490
00491 #include "asterisk/strings.h"
00492
00493
00494
00495 static const char misdn_type[] = "mISDN";
00496
00497 static int tracing = 0 ;
00498
00499
00500 static int prefformat = AST_FORMAT_ALAW ;
00501
00502 static int *misdn_debug;
00503 static int *misdn_debug_only;
00504 static int max_ports;
00505
00506 static int *misdn_in_calls;
00507 static int *misdn_out_calls;
00508
00509
00510 struct chan_list dummy_cl;
00511
00512
00513
00514
00515 struct chan_list *cl_te=NULL;
00516 ast_mutex_t cl_te_lock;
00517
00518 static enum event_response_e
00519 cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data);
00520
00521 static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel*bc, struct chan_list *ch);
00522
00523 static void cl_queue_chan(struct chan_list **list, struct chan_list *chan);
00524 static void cl_dequeue_chan(struct chan_list **list, struct chan_list *chan);
00525 static struct chan_list *find_chan_by_bc(struct chan_list *list, struct misdn_bchannel *bc);
00526 static struct chan_list *find_chan_by_pid(struct chan_list *list, int pid);
00527
00528
00529
00530 static int dialtone_indicate(struct chan_list *cl);
00531 static void hanguptone_indicate(struct chan_list *cl);
00532 static int stop_indicate(struct chan_list *cl);
00533
00534 static int start_bc_tones(struct chan_list *cl);
00535 static int stop_bc_tones(struct chan_list *cl);
00536 static void release_chan_early(struct chan_list *ch);
00537 static void release_chan(struct chan_list *ch, struct misdn_bchannel *bc);
00538
00539 static int misdn_check_l2l1(struct ast_channel *chan, void *data);
00540 static int misdn_set_opt_exec(struct ast_channel *chan, void *data);
00541 static int misdn_facility_exec(struct ast_channel *chan, void *data);
00542
00543 int chan_misdn_jb_empty(struct misdn_bchannel *bc, char *buf, int len);
00544
00545
00546 void debug_numplan(int port, int numplan, char *type);
00547
00548
00549 int add_out_calls(int port);
00550 int add_in_calls(int port);
00551
00552
00553 #ifdef MISDN_1_2
00554 static int update_pipeline_config(struct misdn_bchannel *bc);
00555 #else
00556 static int update_ec_config(struct misdn_bchannel *bc);
00557 #endif
00558
00559
00560
00561
00562
00563 static struct chan_list * get_chan_by_ast(struct ast_channel *ast)
00564 {
00565 struct chan_list *tmp;
00566
00567 for (tmp=cl_te; tmp; tmp = tmp->next) {
00568 if ( tmp->ast == ast ) return tmp;
00569 }
00570
00571 return NULL;
00572 }
00573
00574 static struct chan_list * get_chan_by_ast_name(char *name)
00575 {
00576 struct chan_list *tmp;
00577
00578 for (tmp=cl_te; tmp; tmp = tmp->next) {
00579 if ( tmp->ast && strcmp(tmp->ast->name,name) == 0) return tmp;
00580 }
00581
00582 return NULL;
00583 }
00584
00585
00586
00587 struct allowed_bearers {
00588 char *name;
00589 char *display;
00590 int cap;
00591 int deprecated;
00592 };
00593
00594
00595 static const struct allowed_bearers allowed_bearers_array[]= {
00596
00597 { "speech", "Speech", INFO_CAPABILITY_SPEECH, 0 },
00598 { "3_1khz", "3.1KHz Audio", INFO_CAPABILITY_AUDIO_3_1K, 0 },
00599 { "digital_unrestricted", "Unrestricted Digital", INFO_CAPABILITY_DIGITAL_UNRESTRICTED, 0 },
00600 { "digital_restricted", "Restricted Digital", INFO_CAPABILITY_DIGITAL_RESTRICTED, 0 },
00601 { "digital_restriced", "Restricted Digital", INFO_CAPABILITY_DIGITAL_RESTRICTED, 1 },
00602 { "video", "Video", INFO_CAPABILITY_VIDEO, 0 }
00603 };
00604
00605
00606 static const char *bearer2str(int cap)
00607 {
00608 unsigned index;
00609
00610 for (index = 0; index < ARRAY_LEN(allowed_bearers_array); ++index) {
00611 if (allowed_bearers_array[index].cap == cap) {
00612 return allowed_bearers_array[index].display;
00613 }
00614 }
00615
00616 return "Unknown Bearer";
00617 }
00618
00619
00620 static void print_facility(struct FacParm *fac, struct misdn_bchannel *bc)
00621 {
00622 switch (fac->Function) {
00623 case Fac_CD:
00624 chan_misdn_log(1,bc->port," --> calldeflect to: %s, presentable: %s\n", fac->u.CDeflection.DeflectedToNumber,
00625 fac->u.CDeflection.PresentationAllowed ? "yes" : "no");
00626 break;
00627 case Fac_AOCDCurrency:
00628 if (fac->u.AOCDcur.chargeNotAvailable)
00629 chan_misdn_log(1,bc->port," --> AOCD currency: charge not available\n");
00630 else if (fac->u.AOCDcur.freeOfCharge)
00631 chan_misdn_log(1,bc->port," --> AOCD currency: free of charge\n");
00632 else if (fac->u.AOCDchu.billingId >= 0)
00633 chan_misdn_log(1,bc->port," --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s billingId:%d\n",
00634 fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
00635 (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDcur.billingId);
00636 else
00637 chan_misdn_log(1,bc->port," --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s\n",
00638 fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
00639 (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total");
00640 break;
00641 case Fac_AOCDChargingUnit:
00642 if (fac->u.AOCDchu.chargeNotAvailable)
00643 chan_misdn_log(1,bc->port," --> AOCD charging unit: charge not available\n");
00644 else if (fac->u.AOCDchu.freeOfCharge)
00645 chan_misdn_log(1,bc->port," --> AOCD charging unit: free of charge\n");
00646 else if (fac->u.AOCDchu.billingId >= 0)
00647 chan_misdn_log(1,bc->port," --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s billingId:%d\n",
00648 fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDchu.billingId);
00649 else
00650 chan_misdn_log(1,bc->port," --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s\n",
00651 fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total");
00652 break;
00653 default:
00654 chan_misdn_log(1,bc->port," --> unknown facility\n");
00655 break;
00656 }
00657 }
00658
00659 static void print_bearer(struct misdn_bchannel *bc)
00660 {
00661
00662 chan_misdn_log(2, bc->port, " --> Bearer: %s\n",bearer2str(bc->capability));
00663
00664 switch(bc->law) {
00665 case INFO_CODEC_ALAW:
00666 chan_misdn_log(2, bc->port, " --> Codec: Alaw\n");
00667 break;
00668 case INFO_CODEC_ULAW:
00669 chan_misdn_log(2, bc->port, " --> Codec: Ulaw\n");
00670 break;
00671 }
00672 }
00673
00674 static void export_aoc_vars(int originator, struct ast_channel *ast, struct misdn_bchannel *bc)
00675 {
00676 char buf[128];
00677
00678 if (!ast)
00679 return;
00680
00681 if (originator == ORG_AST) {
00682 ast = ast_bridged_channel(ast);
00683 if (!ast)
00684 return;
00685 }
00686
00687 switch (bc->AOCDtype) {
00688 case Fac_AOCDCurrency:
00689 pbx_builtin_setvar_helper(ast, "AOCD_Type", "currency");
00690 if (bc->AOCD.currency.chargeNotAvailable)
00691 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no");
00692 else {
00693 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes");
00694 if (bc->AOCD.currency.freeOfCharge)
00695 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes");
00696 else {
00697 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no");
00698 if (snprintf(buf, sizeof(buf), "%d %s", bc->AOCD.currency.currencyAmount * bc->AOCD.currency.multiplier, bc->AOCD.currency.currency) < sizeof(buf)) {
00699 pbx_builtin_setvar_helper(ast, "AOCD_Amount", buf);
00700 if (bc->AOCD.currency.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.currency.billingId) < sizeof(buf))
00701 pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf);
00702 }
00703 }
00704 }
00705 break;
00706 case Fac_AOCDChargingUnit:
00707 pbx_builtin_setvar_helper(ast, "AOCD_Type", "charging_unit");
00708 if (bc->AOCD.chargingUnit.chargeNotAvailable)
00709 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no");
00710 else {
00711 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes");
00712 if (bc->AOCD.chargingUnit.freeOfCharge)
00713 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes");
00714 else {
00715 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no");
00716 if (snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.recordedUnits) < sizeof(buf)) {
00717 pbx_builtin_setvar_helper(ast, "AOCD_RecordedUnits", buf);
00718 if (bc->AOCD.chargingUnit.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.billingId) < sizeof(buf))
00719 pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf);
00720 }
00721 }
00722 }
00723 break;
00724 default:
00725 break;
00726 }
00727 }
00728
00729
00730
00731 static void sighandler(int sig)
00732 {}
00733
00734 static void* misdn_tasks_thread_func (void *data)
00735 {
00736 int wait;
00737 struct sigaction sa;
00738
00739 sa.sa_handler = sighandler;
00740 sa.sa_flags = SA_NODEFER;
00741 sigemptyset(&sa.sa_mask);
00742 sigaddset(&sa.sa_mask, SIGUSR1);
00743 sigaction(SIGUSR1, &sa, NULL);
00744
00745 sem_post((sem_t *)data);
00746
00747 while (1) {
00748 wait = ast_sched_wait(misdn_tasks);
00749 if (wait < 0)
00750 wait = 8000;
00751 if (poll(NULL, 0, wait) < 0)
00752 chan_misdn_log(4, 0, "Waking up misdn_tasks thread\n");
00753 ast_sched_runq(misdn_tasks);
00754 }
00755 return NULL;
00756 }
00757
00758 static void misdn_tasks_init (void)
00759 {
00760 sem_t blocker;
00761 int i = 5;
00762
00763 if (sem_init(&blocker, 0, 0)) {
00764 perror("chan_misdn: Failed to initialize semaphore!");
00765 exit(1);
00766 }
00767
00768 chan_misdn_log(4, 0, "Starting misdn_tasks thread\n");
00769
00770 misdn_tasks = sched_context_create();
00771 pthread_create(&misdn_tasks_thread, NULL, misdn_tasks_thread_func, &blocker);
00772
00773 while (sem_wait(&blocker) && --i);
00774 sem_destroy(&blocker);
00775 }
00776
00777 static void misdn_tasks_destroy (void)
00778 {
00779 if (misdn_tasks) {
00780 chan_misdn_log(4, 0, "Killing misdn_tasks thread\n");
00781 if ( pthread_cancel(misdn_tasks_thread) == 0 ) {
00782 cb_log(4, 0, "Joining misdn_tasks thread\n");
00783 pthread_join(misdn_tasks_thread, NULL);
00784 }
00785 sched_context_destroy(misdn_tasks);
00786 }
00787 }
00788
00789 static inline void misdn_tasks_wakeup (void)
00790 {
00791 pthread_kill(misdn_tasks_thread, SIGUSR1);
00792 }
00793
00794 static inline int _misdn_tasks_add_variable (int timeout, ast_sched_cb callback, const void *data, int variable)
00795 {
00796 int task_id;
00797
00798 if (!misdn_tasks) {
00799 misdn_tasks_init();
00800 }
00801 task_id = ast_sched_add_variable(misdn_tasks, timeout, callback, data, variable);
00802 misdn_tasks_wakeup();
00803
00804 return task_id;
00805 }
00806
00807 static int misdn_tasks_add (int timeout, ast_sched_cb callback, const void *data)
00808 {
00809 return _misdn_tasks_add_variable(timeout, callback, data, 0);
00810 }
00811
00812 static int misdn_tasks_add_variable (int timeout, ast_sched_cb callback, const void *data)
00813 {
00814 return _misdn_tasks_add_variable(timeout, callback, data, 1);
00815 }
00816
00817 static void misdn_tasks_remove (int task_id)
00818 {
00819 AST_SCHED_DEL(misdn_tasks, task_id);
00820 }
00821
00822 static int misdn_l1_task (const void *data)
00823 {
00824 misdn_lib_isdn_l1watcher(*(int *)data);
00825 chan_misdn_log(5, *(int *)data, "L1watcher timeout\n");
00826 return 1;
00827 }
00828
00829 static int misdn_overlap_dial_task (const void *data)
00830 {
00831 struct timeval tv_end, tv_now;
00832 int diff;
00833 struct chan_list *ch = (struct chan_list *)data;
00834
00835 chan_misdn_log(4, ch->bc->port, "overlap dial task, chan_state: %d\n", ch->state);
00836
00837 if (ch->state != MISDN_WAITING4DIGS) {
00838 ch->overlap_dial_task = -1;
00839 return 0;
00840 }
00841
00842 ast_mutex_lock(&ch->overlap_tv_lock);
00843 tv_end = ch->overlap_tv;
00844 ast_mutex_unlock(&ch->overlap_tv_lock);
00845
00846 tv_end.tv_sec += ch->overlap_dial;
00847 tv_now = ast_tvnow();
00848
00849 diff = ast_tvdiff_ms(tv_end, tv_now);
00850
00851 if (diff <= 100) {
00852 char *dad=ch->bc->dad, sexten[]="s";
00853
00854 stop_indicate(ch);
00855
00856 if (ast_strlen_zero(ch->bc->dad)) {
00857 dad=sexten;
00858 strcpy(ch->ast->exten, sexten);
00859 }
00860
00861 if (ast_exists_extension(ch->ast, ch->context, dad, 1, ch->bc->oad)) {
00862 ch->state=MISDN_DIALING;
00863 if (pbx_start_chan(ch) < 0) {
00864 chan_misdn_log(-1, ch->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n");
00865 goto misdn_overlap_dial_task_disconnect;
00866 }
00867 } else {
00868 misdn_overlap_dial_task_disconnect:
00869 hanguptone_indicate(ch);
00870 ch->bc->out_cause = AST_CAUSE_UNALLOCATED;
00871 ch->state=MISDN_CLEANING;
00872 misdn_lib_send_event(ch->bc, EVENT_DISCONNECT);
00873 }
00874 ch->overlap_dial_task = -1;
00875 return 0;
00876 } else
00877 return diff;
00878 }
00879
00880 static void send_digit_to_chan(struct chan_list *cl, char digit )
00881 {
00882 static const char* dtmf_tones[] = {
00883 "!941+1336/100,!0/100",
00884 "!697+1209/100,!0/100",
00885 "!697+1336/100,!0/100",
00886 "!697+1477/100,!0/100",
00887 "!770+1209/100,!0/100",
00888 "!770+1336/100,!0/100",
00889 "!770+1477/100,!0/100",
00890 "!852+1209/100,!0/100",
00891 "!852+1336/100,!0/100",
00892 "!852+1477/100,!0/100",
00893 "!697+1633/100,!0/100",
00894 "!770+1633/100,!0/100",
00895 "!852+1633/100,!0/100",
00896 "!941+1633/100,!0/100",
00897 "!941+1209/100,!0/100",
00898 "!941+1477/100,!0/100" };
00899 struct ast_channel *chan=cl->ast;
00900
00901 if (digit >= '0' && digit <='9')
00902 ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0);
00903 else if (digit >= 'A' && digit <= 'D')
00904 ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0);
00905 else if (digit == '*')
00906 ast_playtones_start(chan,0,dtmf_tones[14], 0);
00907 else if (digit == '#')
00908 ast_playtones_start(chan,0,dtmf_tones[15], 0);
00909 else {
00910
00911 ast_log(LOG_DEBUG, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name);
00912 }
00913 }
00914
00915
00916 static int misdn_set_debug(int fd, int argc, char *argv[])
00917 {
00918 int level;
00919
00920 if (argc != 4 && argc != 5 && argc != 6 && argc != 7)
00921 return RESULT_SHOWUSAGE;
00922
00923 level = atoi(argv[3]);
00924
00925 switch (argc) {
00926 case 4:
00927 case 5:
00928 {
00929 int i;
00930 int only = 0;
00931 if (argc == 5) {
00932 if (strncasecmp(argv[4], "only", strlen(argv[4])))
00933 return RESULT_SHOWUSAGE;
00934 else
00935 only = 1;
00936 }
00937
00938 for (i = 0; i <= max_ports; i++) {
00939 misdn_debug[i] = level;
00940 misdn_debug_only[i] = only;
00941 }
00942 ast_cli(fd, "changing debug level for all ports to %d%s\n",misdn_debug[0], only?" (only)":"");
00943 }
00944 break;
00945 case 6:
00946 case 7:
00947 {
00948 int port;
00949 if (strncasecmp(argv[4], "port", strlen(argv[4])))
00950 return RESULT_SHOWUSAGE;
00951 port = atoi(argv[5]);
00952 if (port <= 0 || port > max_ports) {
00953 switch (max_ports) {
00954 case 0:
00955 ast_cli(fd, "port number not valid! no ports available so you won't get lucky with any number here...\n");
00956 break;
00957 case 1:
00958 ast_cli(fd, "port number not valid! only port 1 is available.\n");
00959 break;
00960 default:
00961 ast_cli(fd, "port number not valid! only ports 1 to %d are available.\n", max_ports);
00962 }
00963 return 0;
00964 }
00965 if (argc == 7) {
00966 if (strncasecmp(argv[6], "only", strlen(argv[6])))
00967 return RESULT_SHOWUSAGE;
00968 else
00969 misdn_debug_only[port] = 1;
00970 } else
00971 misdn_debug_only[port] = 0;
00972 misdn_debug[port] = level;
00973 ast_cli(fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port]?" (only)":"", port);
00974 }
00975 }
00976 return 0;
00977 }
00978
00979 static int misdn_set_crypt_debug(int fd, int argc, char *argv[])
00980 {
00981 if (argc != 5) return RESULT_SHOWUSAGE;
00982
00983 return 0;
00984 }
00985
00986 static int misdn_port_block(int fd, int argc, char *argv[])
00987 {
00988 int port;
00989
00990 if (argc != 4)
00991 return RESULT_SHOWUSAGE;
00992
00993 port = atoi(argv[3]);
00994
00995 misdn_lib_port_block(port);
00996
00997 return 0;
00998 }
00999
01000 static int misdn_port_unblock(int fd, int argc, char *argv[])
01001 {
01002 int port;
01003
01004 if (argc != 4)
01005 return RESULT_SHOWUSAGE;
01006
01007 port = atoi(argv[3]);
01008
01009 misdn_lib_port_unblock(port);
01010
01011 return 0;
01012 }
01013
01014
01015 static int misdn_restart_port (int fd, int argc, char *argv[])
01016 {
01017 int port;
01018
01019 if (argc != 4)
01020 return RESULT_SHOWUSAGE;
01021
01022 port = atoi(argv[3]);
01023
01024 misdn_lib_port_restart(port);
01025
01026 return 0;
01027 }
01028
01029 static int misdn_restart_pid (int fd, int argc, char *argv[])
01030 {
01031 int pid;
01032
01033 if (argc != 4)
01034 return RESULT_SHOWUSAGE;
01035
01036 pid = atoi(argv[3]);
01037
01038 misdn_lib_pid_restart(pid);
01039
01040 return 0;
01041 }
01042
01043 static int misdn_port_up (int fd, int argc, char *argv[])
01044 {
01045 int port;
01046
01047 if (argc != 4)
01048 return RESULT_SHOWUSAGE;
01049
01050 port = atoi(argv[3]);
01051
01052 misdn_lib_get_port_up(port);
01053
01054 return 0;
01055 }
01056
01057 static int misdn_port_down (int fd, int argc, char *argv[])
01058 {
01059 int port;
01060
01061 if (argc != 4)
01062 return RESULT_SHOWUSAGE;
01063
01064 port = atoi(argv[3]);
01065
01066 misdn_lib_get_port_down(port);
01067
01068 return 0;
01069 }
01070
01071 static inline void show_config_description (int fd, enum misdn_cfg_elements elem)
01072 {
01073 char section[BUFFERSIZE];
01074 char name[BUFFERSIZE];
01075 char desc[BUFFERSIZE];
01076 char def[BUFFERSIZE];
01077 char tmp[BUFFERSIZE];
01078
01079 misdn_cfg_get_name(elem, tmp, sizeof(tmp));
01080 term_color(name, tmp, COLOR_BRWHITE, 0, sizeof(tmp));
01081 misdn_cfg_get_desc(elem, desc, sizeof(desc), def, sizeof(def));
01082
01083 if (elem < MISDN_CFG_LAST)
01084 term_color(section, "PORTS SECTION", COLOR_YELLOW, 0, sizeof(section));
01085 else
01086 term_color(section, "GENERAL SECTION", COLOR_YELLOW, 0, sizeof(section));
01087
01088 if (*def)
01089 ast_cli(fd, "[%s] %s (Default: %s)\n\t%s\n", section, name, def, desc);
01090 else
01091 ast_cli(fd, "[%s] %s\n\t%s\n", section, name, desc);
01092 }
01093
01094 static int misdn_show_config (int fd, int argc, char *argv[])
01095 {
01096 char buffer[BUFFERSIZE];
01097 enum misdn_cfg_elements elem;
01098 int linebreak;
01099 int onlyport = -1;
01100 int ok = 0;
01101
01102 if (argc >= 4) {
01103 if (!strcmp(argv[3], "description")) {
01104 if (argc == 5) {
01105 enum misdn_cfg_elements elem = misdn_cfg_get_elem(argv[4]);
01106 if (elem == MISDN_CFG_FIRST)
01107 ast_cli(fd, "Unknown element: %s\n", argv[4]);
01108 else
01109 show_config_description(fd, elem);
01110 return 0;
01111 }
01112 return RESULT_SHOWUSAGE;
01113 }
01114 if (!strcmp(argv[3], "descriptions")) {
01115 if ((argc == 4) || ((argc == 5) && !strcmp(argv[4], "general"))) {
01116 for (elem = MISDN_GEN_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) {
01117 show_config_description(fd, elem);
01118 ast_cli(fd, "\n");
01119 }
01120 ok = 1;
01121 }
01122 if ((argc == 4) || ((argc == 5) && !strcmp(argv[4], "ports"))) {
01123 for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_CFG_LAST - 1 ; ++elem) {
01124 show_config_description(fd, elem);
01125 ast_cli(fd, "\n");
01126 }
01127 ok = 1;
01128 }
01129 return ok ? 0 : RESULT_SHOWUSAGE;
01130 }
01131 if (!sscanf(argv[3], "%30d", &onlyport) || onlyport < 0) {
01132 ast_cli(fd, "Unknown option: %s\n", argv[3]);
01133 return RESULT_SHOWUSAGE;
01134 }
01135 }
01136
01137 if (argc == 3 || onlyport == 0) {
01138 ast_cli(fd, "Misdn General-Config:\n");
01139 for (elem = MISDN_GEN_FIRST + 1, linebreak = 1; elem < MISDN_GEN_LAST; elem++, linebreak++) {
01140 misdn_cfg_get_config_string(0, elem, buffer, BUFFERSIZE);
01141 ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
01142 }
01143 ast_cli(fd, "\n");
01144 }
01145
01146 if (onlyport < 0) {
01147 int port = misdn_cfg_get_next_port(0);
01148 for (; port > 0; port = misdn_cfg_get_next_port(port)) {
01149 ast_cli(fd, "\n[PORT %d]\n", port);
01150 for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
01151 misdn_cfg_get_config_string(port, elem, buffer, BUFFERSIZE);
01152 ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
01153 }
01154 ast_cli(fd, "\n");
01155 }
01156 }
01157
01158 if (onlyport > 0) {
01159 if (misdn_cfg_is_port_valid(onlyport)) {
01160 ast_cli(fd, "[PORT %d]\n", onlyport);
01161 for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
01162 misdn_cfg_get_config_string(onlyport, elem, buffer, BUFFERSIZE);
01163 ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
01164 }
01165 ast_cli(fd, "\n");
01166 } else {
01167 ast_cli(fd, "Port %d is not active!\n", onlyport);
01168 }
01169 }
01170
01171 return 0;
01172 }
01173
01174 struct state_struct {
01175 enum misdn_chan_state state;
01176 char txt[255];
01177 };
01178
01179 static struct state_struct state_array[] = {
01180 {MISDN_NOTHING,"NOTHING"},
01181 {MISDN_WAITING4DIGS,"WAITING4DIGS"},
01182 {MISDN_EXTCANTMATCH,"EXTCANTMATCH"},
01183 {MISDN_INCOMING_SETUP,"INCOMING SETUP"},
01184 {MISDN_DIALING,"DIALING"},
01185 {MISDN_PROGRESS,"PROGRESS"},
01186 {MISDN_PROCEEDING,"PROCEEDING"},
01187 {MISDN_CALLING,"CALLING"},
01188 {MISDN_CALLING_ACKNOWLEDGE,"CALLING_ACKNOWLEDGE"},
01189 {MISDN_ALERTING,"ALERTING"},
01190 {MISDN_BUSY,"BUSY"},
01191 {MISDN_CONNECTED,"CONNECTED"},
01192 {MISDN_DISCONNECTED,"DISCONNECTED"},
01193 {MISDN_CLEANING,"CLEANING"},
01194 };
01195
01196 static const char *misdn_get_ch_state(struct chan_list *p)
01197 {
01198 int i;
01199 static char state[8];
01200
01201 if( !p) return NULL;
01202
01203 for (i = 0; i < sizeof(state_array) / sizeof(struct state_struct); i++) {
01204 if (state_array[i].state == p->state)
01205 return state_array[i].txt;
01206 }
01207
01208 snprintf(state, sizeof(state), "%d", p->state) ;
01209
01210 return state;
01211 }
01212
01213
01214
01215 static void reload_config(void)
01216 {
01217 int i, cfg_debug;
01218
01219 if (!g_config_initialized) {
01220 ast_log(LOG_WARNING, "chan_misdn is not initialized properly, still reloading ?\n");
01221 return ;
01222 }
01223
01224 free_robin_list();
01225 misdn_cfg_reload();
01226 misdn_cfg_update_ptp();
01227 misdn_cfg_get(0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
01228 misdn_cfg_get(0, MISDN_GEN_DEBUG, &cfg_debug, sizeof(int));
01229
01230 for (i = 0; i <= max_ports; i++) {
01231 misdn_debug[i] = cfg_debug;
01232 misdn_debug_only[i] = 0;
01233 }
01234 }
01235
01236 static int misdn_reload (int fd, int argc, char *argv[])
01237 {
01238 ast_cli(fd, "Reloading mISDN configuration\n");
01239 reload_config();
01240 return 0;
01241 }
01242
01243 static void print_bc_info (int fd, struct chan_list *help, struct misdn_bchannel *bc)
01244 {
01245 struct ast_channel *ast = help->ast;
01246 ast_cli(fd,
01247 "* Pid:%d Prt:%d Ch:%d Mode:%s Org:%s dad:%s oad:%s rad:%s ctx:%s state:%s\n",
01248
01249 bc->pid, bc->port, bc->channel,
01250 bc->nt ? "NT" : "TE",
01251 help->originator == ORG_AST ? "*" : "I",
01252 ast ? ast->exten : NULL,
01253 ast ? ast->cid.cid_num : NULL,
01254 bc->rad,
01255 ast ? ast->context : NULL,
01256 misdn_get_ch_state(help)
01257 );
01258 if (misdn_debug[bc->port] > 0)
01259 ast_cli(fd,
01260 " --> astname: %s\n"
01261 " --> ch_l3id: %x\n"
01262 " --> ch_addr: %x\n"
01263 " --> bc_addr: %x\n"
01264 " --> bc_l3id: %x\n"
01265 " --> display: %s\n"
01266 " --> activated: %d\n"
01267 " --> state: %s\n"
01268 " --> capability: %s\n"
01269 #ifdef MISDN_1_2
01270 " --> pipeline: %s\n"
01271 #else
01272 " --> echo_cancel: %d\n"
01273 #endif
01274 " --> notone : rx %d tx:%d\n"
01275 " --> bc_hold: %d\n",
01276 help->ast->name,
01277 help->l3id,
01278 help->addr,
01279 bc->addr,
01280 bc ? bc->l3_id : -1,
01281 bc->display,
01282
01283 bc->active,
01284 bc_state2str(bc->bc_state),
01285 bearer2str(bc->capability),
01286 #ifdef MISDN_1_2
01287 bc->pipeline,
01288 #else
01289 bc->ec_enable,
01290 #endif
01291
01292 help->norxtone, help->notxtone,
01293 bc->holded
01294 );
01295
01296 }
01297
01298 static int misdn_show_cls (int fd, int argc, char *argv[])
01299 {
01300 struct chan_list *help;
01301
01302 help = cl_te;
01303
01304 ast_cli(fd, "Channel List: %p\n", cl_te);
01305
01306 for (; help; help = help->next) {
01307 struct misdn_bchannel *bc = help->bc;
01308 struct ast_channel *ast = help->ast;
01309 if (!ast) {
01310 if (!bc) {
01311 ast_cli(fd, "chan_list obj. with l3id:%x has no bc and no ast Leg\n", help->l3id);
01312 continue;
01313 }
01314 ast_cli(fd, "bc with pid:%d has no Ast Leg\n", bc->pid);
01315 continue;
01316 }
01317
01318 if (misdn_debug[0] > 2)
01319 ast_cli(fd, "Bc:%p Ast:%p\n", bc, ast);
01320 if (bc) {
01321 print_bc_info(fd, help, bc);
01322 } else {
01323 if (help->hold.state != MISDN_HOLD_IDLE) {
01324 ast_cli(fd, "ITS A HELD CALL BC:\n");
01325 ast_cli(fd, " --> l3_id: %x\n"
01326 " --> dad:%s oad:%s\n"
01327 " --> hold_port: %d\n"
01328 " --> hold_channel: %d\n",
01329 help->l3id,
01330 ast->exten,
01331 ast->cid.cid_num,
01332 help->hold.port,
01333 help->hold.channel
01334 );
01335 } else {
01336 ast_cli(fd, "* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, ast->cid.cid_num);
01337 }
01338 }
01339 }
01340
01341 misdn_dump_chanlist();
01342
01343 return 0;
01344 }
01345
01346 static int misdn_show_cl (int fd, int argc, char *argv[])
01347 {
01348 struct chan_list *help;
01349
01350 if (argc != 4)
01351 return RESULT_SHOWUSAGE;
01352
01353 help = cl_te;
01354
01355 for (; help; help = help->next) {
01356 struct misdn_bchannel *bc = help->bc;
01357 struct ast_channel *ast = help->ast;
01358
01359 if (bc && ast) {
01360 if (!strcasecmp(ast->name,argv[3])) {
01361 print_bc_info(fd, help, bc);
01362 break;
01363 }
01364 }
01365 }
01366
01367 return 0;
01368 }
01369
01370 ast_mutex_t lock;
01371 int MAXTICS = 8;
01372
01373 static int misdn_set_tics (int fd, int argc, char *argv[])
01374 {
01375 if (argc != 4)
01376 return RESULT_SHOWUSAGE;
01377
01378 MAXTICS = atoi(argv[3]);
01379
01380 return 0;
01381 }
01382
01383 static int misdn_show_stacks (int fd, int argc, char *argv[])
01384 {
01385 int port;
01386
01387 ast_cli(fd, "BEGIN STACK_LIST:\n");
01388 for (port = misdn_cfg_get_next_port(0); port > 0;
01389 port = misdn_cfg_get_next_port(port)) {
01390 char buf[128];
01391 get_show_stack_details(port, buf);
01392 ast_cli(fd, " %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : "");
01393 }
01394
01395 return 0;
01396 }
01397
01398 static int misdn_show_ports_stats (int fd, int argc, char *argv[])
01399 {
01400 int port;
01401
01402 ast_cli(fd, "Port\tin_calls\tout_calls\n");
01403 for (port = misdn_cfg_get_next_port(0); port > 0;
01404 port = misdn_cfg_get_next_port(port)) {
01405 ast_cli(fd, "%d\t%d\t\t%d\n", port, misdn_in_calls[port], misdn_out_calls[port]);
01406 }
01407 ast_cli(fd, "\n");
01408
01409 return 0;
01410 }
01411
01412 static int misdn_show_port (int fd, int argc, char *argv[])
01413 {
01414 int port;
01415 char buf[128];
01416
01417 if (argc != 4)
01418 return RESULT_SHOWUSAGE;
01419
01420 port = atoi(argv[3]);
01421
01422 ast_cli(fd, "BEGIN STACK_LIST:\n");
01423 get_show_stack_details(port, buf);
01424 ast_cli(fd, " %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : "");
01425
01426 return 0;
01427 }
01428
01429 static int misdn_send_cd (int fd, int argc, char *argv[])
01430 {
01431 char *channame;
01432 char *nr;
01433 struct chan_list *tmp;
01434
01435 if (argc != 5)
01436 return RESULT_SHOWUSAGE;
01437
01438
01439 {
01440 channame = argv[3];
01441 nr = argv[4];
01442
01443 ast_cli(fd, "Sending Calldeflection (%s) to %s\n", nr, channame);
01444 tmp = get_chan_by_ast_name(channame);
01445 if (!tmp) {
01446 ast_cli(fd, "Sending CD with nr %s to %s failed: Channel does not exist.\n",nr, channame);
01447 return 0;
01448 }
01449
01450 if (strlen(nr) >= 15) {
01451 ast_cli(fd, "Sending CD with nr %s to %s failed: Number too long (up to 15 digits are allowed).\n",nr, channame);
01452 return 0;
01453 }
01454 tmp->bc->fac_out.Function = Fac_CD;
01455 ast_copy_string((char *)tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr, sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber));
01456 misdn_lib_send_event(tmp->bc, EVENT_FACILITY);
01457 }
01458
01459 return 0;
01460 }
01461
01462 static int misdn_send_restart(int fd, int argc, char *argv[])
01463 {
01464 int port;
01465 int channel;
01466
01467 if (argc < 4 || argc > 5)
01468 return RESULT_SHOWUSAGE;
01469
01470 port = atoi(argv[3]);
01471
01472 if (argc == 5) {
01473 channel = atoi(argv[4]);
01474 misdn_lib_send_restart(port, channel);
01475 } else {
01476 misdn_lib_send_restart(port, -1);
01477 }
01478
01479 return 0;
01480 }
01481
01482 static int misdn_send_digit (int fd, int argc, char *argv[])
01483 {
01484 char *channame;
01485 char *msg;
01486 struct chan_list *tmp;
01487 int i, msglen;
01488
01489 if (argc != 5)
01490 return RESULT_SHOWUSAGE;
01491
01492 channame = argv[3];
01493 msg = argv[4];
01494 msglen = strlen(msg);
01495
01496 ast_cli(fd, "Sending %s to %s\n", msg, channame);
01497
01498 tmp = get_chan_by_ast_name(channame);
01499 if (!tmp) {
01500 ast_cli(fd, "Sending %s to %s failed Channel does not exist\n", msg, channame);
01501 return 0;
01502 }
01503 #if 1
01504 for (i = 0; i < msglen; i++) {
01505 ast_cli(fd, "Sending: %c\n", msg[i]);
01506 send_digit_to_chan(tmp, msg[i]);
01507
01508 usleep(250000);
01509
01510 }
01511 #else
01512 ast_dtmf_stream(tmp->ast, NULL, msg, 250);
01513 #endif
01514
01515 return 0;
01516 }
01517
01518 static int misdn_toggle_echocancel (int fd, int argc, char *argv[])
01519 {
01520 char *channame;
01521 struct chan_list *tmp;
01522
01523 if (argc != 4)
01524 return RESULT_SHOWUSAGE;
01525
01526 channame = argv[3];
01527
01528 ast_cli(fd, "Toggling EchoCancel on %s\n", channame);
01529
01530 tmp = get_chan_by_ast_name(channame);
01531 if (!tmp) {
01532 ast_cli(fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame);
01533 return 0;
01534 }
01535
01536 tmp->toggle_ec = tmp->toggle_ec ? 0 : 1;
01537
01538 if (tmp->toggle_ec) {
01539 #ifdef MISDN_1_2
01540 update_pipeline_config(tmp->bc);
01541 #else
01542 update_ec_config(tmp->bc);
01543 #endif
01544 manager_ec_enable(tmp->bc);
01545 } else {
01546 manager_ec_disable(tmp->bc);
01547 }
01548
01549 return 0;
01550 }
01551
01552 static int misdn_send_display (int fd, int argc, char *argv[])
01553 {
01554 char *channame;
01555 char *msg;
01556 struct chan_list *tmp;
01557
01558 if (argc != 5)
01559 return RESULT_SHOWUSAGE;
01560
01561 channame = argv[3];
01562 msg = argv[4];
01563
01564 ast_cli(fd, "Sending %s to %s\n", msg, channame);
01565 tmp = get_chan_by_ast_name(channame);
01566
01567 if (tmp && tmp->bc) {
01568 ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display));
01569 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
01570 } else {
01571 ast_cli(fd, "No such channel %s\n", channame);
01572 return RESULT_FAILURE;
01573 }
01574
01575 return RESULT_SUCCESS;
01576 }
01577
01578 static char *complete_ch_helper(const char *line, const char *word, int pos, int state, int rpos)
01579 {
01580 struct ast_channel *c;
01581 int which=0;
01582 char *ret;
01583 if (pos != rpos)
01584 return NULL;
01585 c = ast_channel_walk_locked(NULL);
01586 while(c) {
01587 if (!strncasecmp(word, c->name, strlen(word))) {
01588 if (++which > state)
01589 break;
01590 }
01591 ast_mutex_unlock(&c->lock);
01592 c = ast_channel_walk_locked(c);
01593 }
01594 if (c) {
01595 ret = strdup(c->name);
01596 ast_mutex_unlock(&c->lock);
01597 } else
01598 ret = NULL;
01599 return ret;
01600 }
01601
01602 static char *complete_ch(const char *line, const char *word, int pos, int state)
01603 {
01604 return complete_ch_helper(line, word, pos, state, 3);
01605 }
01606
01607 static char *complete_debug_port (const char *line, const char *word, int pos, int state)
01608 {
01609 if (state)
01610 return NULL;
01611
01612 switch (pos) {
01613 case 4:
01614 if (*word == 'p')
01615 return strdup("port");
01616 else if (*word == 'o')
01617 return strdup("only");
01618 break;
01619 case 6:
01620 if (*word == 'o')
01621 return strdup("only");
01622 break;
01623 }
01624 return NULL;
01625 }
01626
01627 static char *complete_show_config (const char *line, const char *word, int pos, int state)
01628 {
01629 char buffer[BUFFERSIZE];
01630 enum misdn_cfg_elements elem;
01631 int wordlen = strlen(word);
01632 int which = 0;
01633 int port = 0;
01634
01635 switch (pos) {
01636 case 3:
01637 if ((!strncmp(word, "description", wordlen)) && (++which > state))
01638 return strdup("description");
01639 if ((!strncmp(word, "descriptions", wordlen)) && (++which > state))
01640 return strdup("descriptions");
01641 if ((!strncmp(word, "0", wordlen)) && (++which > state))
01642 return strdup("0");
01643 while ((port = misdn_cfg_get_next_port(port)) != -1) {
01644 snprintf(buffer, sizeof(buffer), "%d", port);
01645 if ((!strncmp(word, buffer, wordlen)) && (++which > state)) {
01646 return strdup(buffer);
01647 }
01648 }
01649 break;
01650 case 4:
01651 if (strstr(line, "description ")) {
01652 for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) {
01653 if ((elem == MISDN_CFG_LAST) || (elem == MISDN_GEN_FIRST))
01654 continue;
01655 misdn_cfg_get_name(elem, buffer, BUFFERSIZE);
01656 if (!wordlen || !strncmp(word, buffer, wordlen)) {
01657 if (++which > state)
01658 return strdup(buffer);
01659 }
01660 }
01661 } else if (strstr(line, "descriptions ")) {
01662 if ((!wordlen || !strncmp(word, "general", wordlen)) && (++which > state))
01663 return strdup("general");
01664 if ((!wordlen || !strncmp(word, "ports", wordlen)) && (++which > state))
01665 return strdup("ports");
01666 }
01667 break;
01668 }
01669 return NULL;
01670 }
01671
01672 static struct ast_cli_entry chan_misdn_clis[] = {
01673 { {"misdn","send","calldeflect", NULL}, misdn_send_cd, "Sends CallDeflection to mISDN Channel",
01674 "Usage: misdn send calldeflect <channel> \"<nr>\" \n", complete_ch },
01675 { {"misdn","send","digit", NULL}, misdn_send_digit, "Sends DTMF Digit to mISDN Channel",
01676 "Usage: misdn send digit <channel> \"<msg>\" \n"
01677 " Send <digit> to <channel> as DTMF Tone\n"
01678 " when channel is a mISDN channel\n", complete_ch },
01679 { {"misdn","toggle","echocancel", NULL}, misdn_toggle_echocancel, "Toggles EchoCancel on mISDN Channel",
01680 "Usage: misdn toggle echocancel <channel>\n", complete_ch },
01681 { {"misdn","send","display", NULL}, misdn_send_display, "Sends Text to mISDN Channel",
01682 "Usage: misdn send display <channel> \"<msg>\" \n"
01683 " Send <msg> to <channel> as Display Message\n"
01684 " when channel is a mISDN channel\n", complete_ch },
01685 { {"misdn","show","config", NULL}, misdn_show_config, "Shows internal mISDN config, read from cfg-file",
01686 "Usage: misdn show config [<port> | description <config element> | descriptions [general|ports]]\n"
01687 " Use 0 for <port> to only print the general config.\n", complete_show_config },
01688 { {"misdn","reload", NULL}, misdn_reload, "Reloads internal mISDN config, read from cfg-file",
01689 "Usage: misdn reload\n" },
01690 { {"misdn","set","tics", NULL}, misdn_set_tics, "",
01691 "\n" },
01692 { {"misdn","show","channels", NULL}, misdn_show_cls, "Shows internal mISDN chan_list",
01693 "Usage: misdn show channels\n" },
01694 { {"misdn","show","channel", NULL}, misdn_show_cl, "Shows internal mISDN chan_list",
01695 "Usage: misdn show channels\n", complete_ch },
01696 { {"misdn","port","block", NULL}, misdn_port_block, "Blocks the given port",
01697 "Usage: misdn port block\n" },
01698 { {"misdn","port","unblock", NULL}, misdn_port_unblock, "Unblocks the given port",
01699 "Usage: misdn port unblock\n" },
01700 { {"misdn","restart","port", NULL}, misdn_restart_port, "Restarts the given port",
01701 "Usage: misdn restart port\n" },
01702 { {"misdn","restart","pid", NULL}, misdn_restart_pid, "Restarts the given pid",
01703 "Usage: misdn restart pid\n" },
01704 { {"misdn","send","restart", NULL}, misdn_send_restart,
01705 "Sends a restart for every bchannel on the given port",
01706 "Usage: misdn send restart <port>\n"},
01707 { {"misdn","port","up", NULL}, misdn_port_up, "Tries to establish L1 on the given port",
01708 "Usage: misdn port up <port>\n" },
01709 { {"misdn","port","down", NULL}, misdn_port_down, "Tries to deactivate the L1 on the given port",
01710 "Usage: misdn port down <port>\n" },
01711 { {"misdn","show","stacks", NULL}, misdn_show_stacks, "Shows internal mISDN stack_list",
01712 "Usage: misdn show stacks\n" },
01713 { {"misdn","show","ports","stats", NULL}, misdn_show_ports_stats, "Shows chan_misdns call statistics per port",
01714 "Usage: misdn show port stats\n" },
01715 { {"misdn","show","port", NULL}, misdn_show_port, "Shows detailed information for given port",
01716 "Usage: misdn show port <port>\n" },
01717 { {"misdn","set","debug", NULL}, misdn_set_debug, "Sets Debuglevel of chan_misdn",
01718 "Usage: misdn set debug <level> [only] | [port <port> [only]]\n", complete_debug_port },
01719 { {"misdn","set","crypt","debug", NULL}, misdn_set_crypt_debug, "Sets CryptDebuglevel of chan_misdn, at the moment, level={1,2}",
01720 "Usage: misdn set crypt debug <level>\n" }
01721 };
01722
01723
01724 static int update_config(struct chan_list *ch, int orig)
01725 {
01726 struct ast_channel *ast;
01727 struct misdn_bchannel *bc;
01728 int port, hdlc = 0;
01729 int pres, screen;
01730
01731 if (!ch) {
01732 ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
01733 return -1;
01734 }
01735
01736 ast = ch->ast;
01737 bc = ch->bc;
01738 if (! ast || ! bc) {
01739 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
01740 return -1;
01741 }
01742
01743 port = bc->port;
01744
01745 chan_misdn_log(7, port, "update_config: Getting Config\n");
01746
01747 misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
01748
01749 if (hdlc) {
01750 switch (bc->capability) {
01751 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
01752 case INFO_CAPABILITY_DIGITAL_RESTRICTED:
01753 chan_misdn_log(1, bc->port, " --> CONF HDLC\n");
01754 bc->hdlc = 1;
01755 break;
01756 }
01757 }
01758
01759
01760 misdn_cfg_get(port, MISDN_CFG_PRES, &pres, sizeof(pres));
01761 misdn_cfg_get(port, MISDN_CFG_SCREEN, &screen, sizeof(screen));
01762 chan_misdn_log(2, port, " --> pres: %d screen: %d\n", pres, screen);
01763
01764 if (pres < 0 || screen < 0) {
01765 chan_misdn_log(2, port, " --> pres: %x\n", ast->cid.cid_pres);
01766
01767 switch (ast->cid.cid_pres & 0x60) {
01768 case AST_PRES_RESTRICTED:
01769 bc->pres = 1;
01770 chan_misdn_log(2, port, " --> PRES: Restricted (1)\n");
01771 break;
01772 case AST_PRES_UNAVAILABLE:
01773 bc->pres = 2;
01774 chan_misdn_log(2, port, " --> PRES: Unavailable (2)\n");
01775 break;
01776 default:
01777 bc->pres = 0;
01778 chan_misdn_log(2, port, " --> PRES: Allowed (0)\n");
01779 break;
01780 }
01781
01782 switch (ast->cid.cid_pres & 0x3) {
01783 default:
01784 case AST_PRES_USER_NUMBER_UNSCREENED:
01785 bc->screen = 0;
01786 chan_misdn_log(2, port, " --> SCREEN: Unscreened (0)\n");
01787 break;
01788 case AST_PRES_USER_NUMBER_PASSED_SCREEN:
01789 bc->screen = 1;
01790 chan_misdn_log(2, port, " --> SCREEN: Passed Screen (1)\n");
01791 break;
01792 case AST_PRES_USER_NUMBER_FAILED_SCREEN:
01793 bc->screen = 2;
01794 chan_misdn_log(2, port, " --> SCREEN: Failed Screen (2)\n");
01795 break;
01796 case AST_PRES_NETWORK_NUMBER:
01797 bc->screen = 3;
01798 chan_misdn_log(2, port, " --> SCREEN: Network Nr. (3)\n");
01799 break;
01800 }
01801 } else {
01802 bc->screen = screen;
01803 bc->pres = pres;
01804 }
01805
01806 return 0;
01807 }
01808
01809
01810 static void config_jitterbuffer(struct chan_list *ch)
01811 {
01812 struct misdn_bchannel *bc = ch->bc;
01813 int len = ch->jb_len, threshold = ch->jb_upper_threshold;
01814
01815 chan_misdn_log(5, bc->port, "config_jb: Called\n");
01816
01817 if (! len) {
01818 chan_misdn_log(1, bc->port, "config_jb: Deactivating Jitterbuffer\n");
01819 bc->nojitter=1;
01820 } else {
01821 if (len <= 100 || len > 8000) {
01822 chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer out of Bounds, setting to 1000\n");
01823 len = 1000;
01824 }
01825
01826 if ( threshold > len ) {
01827 chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n");
01828 }
01829
01830 if ( ch->jb) {
01831 cb_log(0, bc->port, "config_jb: We've got a Jitterbuffer Already on this port.\n");
01832 misdn_jb_destroy(ch->jb);
01833 ch->jb = NULL;
01834 }
01835
01836 ch->jb=misdn_jb_init(len, threshold);
01837
01838 if (!ch->jb )
01839 bc->nojitter = 1;
01840 }
01841 }
01842
01843
01844 void debug_numplan(int port, int numplan, char *type)
01845 {
01846 switch (numplan) {
01847 case NUMPLAN_INTERNATIONAL:
01848 chan_misdn_log(2, port, " --> %s: International\n", type);
01849 break;
01850 case NUMPLAN_NATIONAL:
01851 chan_misdn_log(2, port, " --> %s: National\n", type);
01852 break;
01853 case NUMPLAN_SUBSCRIBER:
01854 chan_misdn_log(2, port, " --> %s: Subscriber\n", type);
01855 break;
01856 case NUMPLAN_UNKNOWN:
01857 chan_misdn_log(2, port, " --> %s: Unknown\n", type);
01858 break;
01859
01860 default:
01861 chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n ");
01862 break;
01863 }
01864 }
01865
01866
01867 #ifdef MISDN_1_2
01868 static int update_pipeline_config(struct misdn_bchannel *bc)
01869 {
01870 int ec;
01871
01872 misdn_cfg_get(bc->port, MISDN_CFG_PIPELINE, bc->pipeline, sizeof(bc->pipeline));
01873
01874 if (*bc->pipeline)
01875 return 0;
01876
01877 misdn_cfg_get(bc->port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
01878 if (ec == 1)
01879 ast_copy_string(bc->pipeline, "mg2ec", sizeof(bc->pipeline));
01880 else if (ec > 1)
01881 snprintf(bc->pipeline, sizeof(bc->pipeline), "mg2ec(deftaps=%d)", ec);
01882
01883 return 0;
01884 }
01885 #else
01886 static int update_ec_config(struct misdn_bchannel *bc)
01887 {
01888 int ec;
01889 int port = bc->port;
01890
01891 misdn_cfg_get(port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
01892
01893 if (ec == 1) {
01894 bc->ec_enable = 1;
01895 } else if (ec > 1) {
01896 bc->ec_enable = 1;
01897 bc->ec_deftaps = ec;
01898 }
01899
01900 return 0;
01901 }
01902 #endif
01903
01904
01905 static int read_config(struct chan_list *ch, int orig)
01906 {
01907 struct ast_channel *ast;
01908 struct misdn_bchannel *bc;
01909 int port;
01910 int hdlc = 0;
01911 char lang[BUFFERSIZE + 1];
01912 char faxdetect[BUFFERSIZE + 1];
01913 char buf[256];
01914 char buf2[256];
01915 ast_group_t pg;
01916 ast_group_t cg;
01917
01918 if (!ch) {
01919 ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
01920 return -1;
01921 }
01922
01923 ast = ch->ast;
01924 bc = ch->bc;
01925 if (! ast || ! bc) {
01926 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
01927 return -1;
01928 }
01929
01930 port = bc->port;
01931 chan_misdn_log(1, port, "read_config: Getting Config\n");
01932
01933 misdn_cfg_get(port, MISDN_CFG_LANGUAGE, lang, BUFFERSIZE);
01934 ast_string_field_set(ast, language, lang);
01935
01936 misdn_cfg_get(port, MISDN_CFG_MUSICCLASS, ch->mohinterpret, sizeof(ch->mohinterpret));
01937
01938 misdn_cfg_get(port, MISDN_CFG_TXGAIN, &bc->txgain, sizeof(int));
01939 misdn_cfg_get(port, MISDN_CFG_RXGAIN, &bc->rxgain, sizeof(int));
01940
01941 misdn_cfg_get(port, MISDN_CFG_INCOMING_EARLY_AUDIO, &ch->incoming_early_audio, sizeof(int));
01942
01943 misdn_cfg_get(port, MISDN_CFG_SENDDTMF, &bc->send_dtmf, sizeof(int));
01944
01945 misdn_cfg_get(port, MISDN_CFG_ASTDTMF, &ch->ast_dsp, sizeof(int));
01946
01947 if (ch->ast_dsp) {
01948 ch->ignore_dtmf = 1;
01949 }
01950
01951 misdn_cfg_get(port, MISDN_CFG_NEED_MORE_INFOS, &bc->need_more_infos, sizeof(int));
01952 misdn_cfg_get(port, MISDN_CFG_NTTIMEOUT, &ch->nttimeout, sizeof(int));
01953
01954 misdn_cfg_get(port, MISDN_CFG_NOAUTORESPOND_ON_SETUP, &ch->noautorespond_on_setup, sizeof(int));
01955
01956 misdn_cfg_get(port, MISDN_CFG_FAR_ALERTING, &ch->far_alerting, sizeof(int));
01957
01958 misdn_cfg_get(port, MISDN_CFG_ALLOWED_BEARERS, &ch->allowed_bearers, BUFFERSIZE);
01959
01960 misdn_cfg_get(port, MISDN_CFG_FAXDETECT, faxdetect, BUFFERSIZE);
01961
01962 misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
01963
01964 if (hdlc) {
01965 switch (bc->capability) {
01966 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
01967 case INFO_CAPABILITY_DIGITAL_RESTRICTED:
01968 chan_misdn_log(1, bc->port, " --> CONF HDLC\n");
01969 bc->hdlc = 1;
01970 break;
01971 }
01972
01973 }
01974
01975 misdn_cfg_get(port, MISDN_CFG_JITTERBUFFER, &ch->jb_len, sizeof(int));
01976 misdn_cfg_get(port, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, &ch->jb_upper_threshold, sizeof(int));
01977
01978 config_jitterbuffer(ch);
01979
01980 misdn_cfg_get(bc->port, MISDN_CFG_CONTEXT, ch->context, sizeof(ch->context));
01981
01982 ast_copy_string(ast->context, ch->context, sizeof(ast->context));
01983
01984 #ifdef MISDN_1_2
01985 update_pipeline_config(bc);
01986 #else
01987 update_ec_config(bc);
01988 #endif
01989
01990 {
01991 int eb3;
01992
01993 misdn_cfg_get( bc->port, MISDN_CFG_EARLY_BCONNECT, &eb3, sizeof(int));
01994 bc->early_bconnect=eb3;
01995 }
01996
01997 misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg));
01998 misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg));
01999
02000 chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n", ast_print_group(buf, sizeof(buf), cg), ast_print_group(buf2, sizeof(buf2), pg));
02001 ast->pickupgroup = pg;
02002 ast->callgroup = cg;
02003
02004 if (orig == ORG_AST) {
02005 char callerid[BUFFERSIZE + 1];
02006
02007
02008
02009 misdn_cfg_get(port, MISDN_CFG_TE_CHOOSE_CHANNEL, &(bc->te_choose_channel), sizeof(int));
02010
02011 if (strstr(faxdetect, "outgoing") || strstr(faxdetect, "both")) {
02012 if (strstr(faxdetect, "nojump"))
02013 ch->faxdetect = 2;
02014 else
02015 ch->faxdetect = 1;
02016 }
02017
02018 misdn_cfg_get(port, MISDN_CFG_CALLERID, callerid, BUFFERSIZE);
02019 if ( ! ast_strlen_zero(callerid) ) {
02020 chan_misdn_log(1, port, " --> * Setting Cid to %s\n", callerid);
02021 ast_copy_string(bc->oad, callerid, sizeof(bc->oad));
02022 }
02023
02024 misdn_cfg_get(port, MISDN_CFG_DIALPLAN, &bc->dnumplan, sizeof(int));
02025 misdn_cfg_get(port, MISDN_CFG_LOCALDIALPLAN, &bc->onumplan, sizeof(int));
02026 misdn_cfg_get(port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int));
02027 debug_numplan(port, bc->dnumplan, "TON");
02028 debug_numplan(port, bc->onumplan, "LTON");
02029 debug_numplan(port, bc->cpnnumplan, "CTON");
02030
02031 ch->overlap_dial = 0;
02032 } else {
02033
02034 char prefix[BUFFERSIZE + 1] = "";
02035
02036 if (strstr(faxdetect, "incoming") || strstr(faxdetect, "both")) {
02037 if (strstr(faxdetect, "nojump"))
02038 ch->faxdetect = 2;
02039 else
02040 ch->faxdetect = 1;
02041 }
02042
02043 misdn_cfg_get(port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int));
02044 debug_numplan(port, bc->cpnnumplan, "CTON");
02045
02046 switch (bc->onumplan) {
02047 case NUMPLAN_INTERNATIONAL:
02048 misdn_cfg_get(bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE);
02049 break;
02050
02051 case NUMPLAN_NATIONAL:
02052 misdn_cfg_get(bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE);
02053 break;
02054 default:
02055 break;
02056 }
02057
02058 ast_copy_string(buf, bc->oad, sizeof(buf));
02059 snprintf(bc->oad, sizeof(bc->oad), "%s%s", prefix, buf);
02060
02061 if (!ast_strlen_zero(bc->dad)) {
02062 ast_copy_string(bc->orig_dad, bc->dad, sizeof(bc->orig_dad));
02063 }
02064
02065 if ( ast_strlen_zero(bc->dad) && !ast_strlen_zero(bc->keypad)) {
02066 ast_copy_string(bc->dad, bc->keypad, sizeof(bc->dad));
02067 }
02068
02069 prefix[0] = 0;
02070
02071 switch (bc->dnumplan) {
02072 case NUMPLAN_INTERNATIONAL:
02073 misdn_cfg_get(bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE);
02074 break;
02075 case NUMPLAN_NATIONAL:
02076 misdn_cfg_get(bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE);
02077 break;
02078 default:
02079 break;
02080 }
02081
02082 ast_copy_string(buf, bc->dad, sizeof(buf));
02083 snprintf(bc->dad, sizeof(bc->dad), "%s%s", prefix, buf);
02084
02085 if (strcmp(bc->dad, ast->exten)) {
02086 ast_copy_string(ast->exten, bc->dad, sizeof(ast->exten));
02087 }
02088
02089 ast_set_callerid(ast, bc->oad, NULL, bc->oad);
02090
02091 if ( !ast_strlen_zero(bc->rad) ) {
02092 if (ast->cid.cid_rdnis)
02093 free(ast->cid.cid_rdnis);
02094 ast->cid.cid_rdnis = strdup(bc->rad);
02095 }
02096
02097 misdn_cfg_get(bc->port, MISDN_CFG_OVERLAP_DIAL, &ch->overlap_dial, sizeof(ch->overlap_dial));
02098 ast_mutex_init(&ch->overlap_tv_lock);
02099 }
02100
02101 ch->overlap_dial_task = -1;
02102
02103 if (ch->faxdetect || ch->ast_dsp) {
02104 misdn_cfg_get(port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout));
02105 if (!ch->dsp)
02106 ch->dsp = ast_dsp_new();
02107 if (ch->dsp) {
02108 if (ch->faxdetect)
02109 ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT | DSP_FEATURE_FAX_DETECT);
02110 else
02111 ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT );
02112 }
02113 }
02114
02115
02116 bc->AOCDtype = Fac_None;
02117
02118 return 0;
02119 }
02120
02121
02122
02123
02124
02125
02126 static int misdn_call(struct ast_channel *ast, char *dest, int timeout)
02127 {
02128 int port = 0;
02129 int r;
02130 int exceed;
02131 int bridging;
02132 struct chan_list *ch;
02133 struct misdn_bchannel *newbc;
02134 char *opts, *ext;
02135 char *dest_cp;
02136
02137 if (!ast) {
02138 ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n");
02139 return -1;
02140 }
02141
02142 if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest ) {
02143 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
02144 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
02145 ast_setstate(ast, AST_STATE_DOWN);
02146 return -1;
02147 }
02148
02149 ch = MISDN_ASTERISK_TECH_PVT(ast);
02150 if (!ch) {
02151 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
02152 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
02153 ast_setstate(ast, AST_STATE_DOWN);
02154 return -1;
02155 }
02156
02157 newbc = ch->bc;
02158 if (!newbc) {
02159 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
02160 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
02161 ast_setstate(ast, AST_STATE_DOWN);
02162 return -1;
02163 }
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173 dest_cp = ast_strdupa(dest);
02174 strsep(&dest_cp, "/");
02175 ext = strsep(&dest_cp, "/");
02176 if (!ext) {
02177 ext = "";
02178 }
02179 opts = dest_cp;
02180
02181 port = newbc->port;
02182
02183 if ((exceed = add_out_calls(port))) {
02184 char tmp[16];
02185 snprintf(tmp, sizeof(tmp), "%d", exceed);
02186 pbx_builtin_setvar_helper(ast, "MAX_OVERFLOW", tmp);
02187 return -1;
02188 }
02189
02190 chan_misdn_log(1, port, "* CALL: %s\n", dest);
02191
02192 chan_misdn_log(2, port, " --> * dad:%s tech:%s ctx:%s\n", ast->exten, ast->name, ast->context);
02193
02194 chan_misdn_log(3, port, " --> * adding2newbc ext %s\n", ast->exten);
02195 if (ast->exten) {
02196 ast_copy_string(ast->exten, ext, sizeof(ast->exten));
02197 ast_copy_string(newbc->dad, ext, sizeof(newbc->dad));
02198 }
02199
02200 ast_copy_string(newbc->rad, S_OR(ast->cid.cid_rdnis, ""), sizeof(newbc->rad));
02201
02202 chan_misdn_log(3, port, " --> * adding2newbc callerid %s\n", ast->cid.cid_num);
02203 if (ast_strlen_zero(newbc->oad) && !ast_strlen_zero(ast->cid.cid_num)) {
02204 ast_copy_string(newbc->oad, ast->cid.cid_num, sizeof(newbc->oad));
02205 }
02206
02207 newbc->capability = ast->transfercapability;
02208 pbx_builtin_setvar_helper(ast, "TRANSFERCAPABILITY", ast_transfercapability2str(newbc->capability));
02209 if ( ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) {
02210 chan_misdn_log(2, port, " --> * Call with flag Digital\n");
02211 }
02212
02213
02214 update_config(ch, ORG_AST);
02215
02216
02217 import_ch(ast, newbc, ch);
02218
02219
02220 if (opts)
02221 misdn_set_opt_exec(ast, opts);
02222 else
02223 chan_misdn_log(2, port, "NO OPTS GIVEN\n");
02224
02225
02226 misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging));
02227 if (bridging && ch->other_ch) {
02228 #ifdef MISDN_1_2
02229 chan_misdn_log(1, port, "Disabling EC (aka Pipeline) on both Sides\n");
02230 *ch->bc->pipeline = 0;
02231 *ch->other_ch->bc->pipeline = 0;
02232 #else
02233 chan_misdn_log(1, port, "Disabling EC on both Sides\n");
02234 ch->bc->ec_enable = 0;
02235 ch->other_ch->bc->ec_enable = 0;
02236 #endif
02237 }
02238
02239 r = misdn_lib_send_event( newbc, EVENT_SETUP );
02240
02241
02242 ch->l3id = newbc->l3_id;
02243
02244 if ( r == -ENOCHAN ) {
02245 chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n");
02246 chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n", newbc ? newbc->pid : -1);
02247 ast->hangupcause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
02248 ast_setstate(ast, AST_STATE_DOWN);
02249 return -1;
02250 }
02251
02252 chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n", newbc ? newbc->pid : 1);
02253
02254 ast_setstate(ast, AST_STATE_DIALING);
02255 ast->hangupcause = AST_CAUSE_NORMAL_CLEARING;
02256
02257 if (newbc->nt)
02258 stop_bc_tones(ch);
02259
02260 ch->state = MISDN_CALLING;
02261
02262 return 0;
02263 }
02264
02265
02266 static int misdn_answer(struct ast_channel *ast)
02267 {
02268 struct chan_list *p;
02269 const char *tmp;
02270
02271 if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) return -1;
02272
02273 chan_misdn_log(1, p ? (p->bc ? p->bc->port : 0) : 0, "* ANSWER:\n");
02274
02275 if (!p) {
02276 ast_log(LOG_WARNING, " --> Channel not connected ??\n");
02277 ast_queue_hangup(ast);
02278 }
02279
02280 if (!p->bc) {
02281 chan_misdn_log(1, 0, " --> Got Answer, but there is no bc obj ??\n");
02282
02283 ast_queue_hangup(ast);
02284 }
02285
02286 tmp = pbx_builtin_getvar_helper(p->ast, "CRYPT_KEY");
02287 if (!ast_strlen_zero(tmp)) {
02288 chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n");
02289 ast_copy_string(p->bc->crypt_key, tmp, sizeof(p->bc->crypt_key));
02290 } else {
02291 chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n");
02292 }
02293
02294 tmp = pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS");
02295 if (!ast_strlen_zero(tmp) && ast_true(tmp)) {
02296 chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n");
02297 p->bc->nodsp = 1;
02298 p->bc->hdlc = 0;
02299 p->bc->nojitter = 1;
02300 }
02301
02302 p->state = MISDN_CONNECTED;
02303 stop_indicate(p);
02304
02305 if ( ast_strlen_zero(p->bc->cad) ) {
02306 chan_misdn_log(2,p->bc->port," --> empty cad using dad\n");
02307 ast_copy_string(p->bc->cad, p->bc->dad, sizeof(p->bc->cad));
02308 }
02309
02310 misdn_lib_send_event( p->bc, EVENT_CONNECT);
02311 start_bc_tones(p);
02312
02313 return 0;
02314 }
02315
02316 static int misdn_digit_begin(struct ast_channel *chan, char digit)
02317 {
02318
02319 return 0;
02320 }
02321
02322 static int misdn_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
02323 {
02324 struct chan_list *p;
02325 struct misdn_bchannel *bc;
02326
02327 if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) return -1;
02328
02329 bc = p->bc;
02330 chan_misdn_log(1, bc ? bc->port : 0, "* IND : Digit %c\n", digit);
02331
02332 if (!bc) {
02333 ast_log(LOG_WARNING, " --> !! Got Digit Event without having bchannel Object\n");
02334 return -1;
02335 }
02336
02337 switch (p->state ) {
02338 case MISDN_CALLING:
02339 {
02340 int l;
02341 char buf[8];
02342 buf[0]=digit;
02343 buf[1]=0;
02344
02345 l = sizeof(bc->infos_pending);
02346 strncat(bc->infos_pending, buf, l - strlen(bc->infos_pending) - 1);
02347 }
02348 break;
02349 case MISDN_CALLING_ACKNOWLEDGE:
02350 {
02351 bc->info_dad[0]=digit;
02352 bc->info_dad[1]=0;
02353
02354 {
02355 int l = sizeof(bc->dad);
02356 strncat(bc->dad, bc->info_dad, l - strlen(bc->dad) - 1);
02357 }
02358 {
02359 int l = sizeof(p->ast->exten);
02360 strncpy(p->ast->exten, bc->dad, l);
02361 p->ast->exten[l-1] = 0;
02362 }
02363
02364 misdn_lib_send_event( bc, EVENT_INFORMATION);
02365 }
02366 break;
02367 default:
02368 if ( bc->send_dtmf )
02369 send_digit_to_chan(p,digit);
02370 break;
02371 }
02372
02373 return 0;
02374 }
02375
02376
02377 static int misdn_fixup(struct ast_channel *oldast, struct ast_channel *ast)
02378 {
02379 struct chan_list *p;
02380
02381 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) )) return -1;
02382
02383 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);
02384
02385 p->ast = ast;
02386
02387 return 0;
02388 }
02389
02390
02391
02392 static int misdn_indication(struct ast_channel *ast, int cond, const void *data, size_t datalen)
02393 {
02394 struct chan_list *p;
02395
02396 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) {
02397 ast_log(LOG_WARNING, "Returned -1 in misdn_indication\n");
02398 return -1;
02399 }
02400
02401 if (!p->bc) {
02402 if (p->hold.state == MISDN_HOLD_IDLE) {
02403 chan_misdn_log(1, 0, "* IND : Indication [%d] ignored on %s\n", cond,
02404 ast->name);
02405 ast_log(LOG_WARNING, "Private Pointer but no bc ?\n");
02406 } else {
02407 chan_misdn_log(1, 0, "* IND : Indication [%d] ignored on hold %s\n",
02408 cond, ast->name);
02409 }
02410 return -1;
02411 }
02412
02413 chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] on %s\n\n", cond, ast->name);
02414
02415 switch (cond) {
02416 case AST_CONTROL_BUSY:
02417 chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n", p->bc ? p->bc->pid : -1);
02418 ast_setstate(ast, AST_STATE_BUSY);
02419
02420 p->bc->out_cause = AST_CAUSE_USER_BUSY;
02421 if (p->state != MISDN_CONNECTED) {
02422 start_bc_tones(p);
02423 misdn_lib_send_event( p->bc, EVENT_DISCONNECT);
02424 }
02425 return -1;
02426 case AST_CONTROL_RING:
02427 chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n", p->bc ? p->bc->pid : -1);
02428 return -1;
02429 case AST_CONTROL_RINGING:
02430 chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n", p->bc ? p->bc->pid : -1);
02431 switch (p->state) {
02432 case MISDN_ALERTING:
02433 chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoring it\n", p->bc ? p->bc->pid : -1);
02434 break;
02435 case MISDN_CONNECTED:
02436 chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n", p->bc ? p->bc->pid : -1);
02437 return -1;
02438 default:
02439 p->state = MISDN_ALERTING;
02440 chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n", p->bc ? p->bc->pid : -1);
02441 misdn_lib_send_event( p->bc, EVENT_ALERTING);
02442
02443 if (p->other_ch && p->other_ch->bc) {
02444 if (misdn_inband_avail(p->other_ch->bc)) {
02445 chan_misdn_log(2, p->bc->port, " --> other End is mISDN and has inband info available\n");
02446 break;
02447 }
02448
02449 if (!p->other_ch->bc->nt) {
02450 chan_misdn_log(2, p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n");
02451 break;
02452 }
02453 }
02454
02455 chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n", p->bc ? p->bc->pid : -1);
02456 ast_setstate(ast, AST_STATE_RING);
02457
02458 if (!p->bc->nt && (p->originator == ORG_MISDN) && !p->incoming_early_audio)
02459 chan_misdn_log(2, p->bc->port, " --> incoming_early_audio off\n");
02460 else
02461 return -1;
02462 }
02463 break;
02464 case AST_CONTROL_ANSWER:
02465 chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n", p->bc ? p->bc->pid : -1);
02466 start_bc_tones(p);
02467 break;
02468 case AST_CONTROL_TAKEOFFHOOK:
02469 chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n", p->bc ? p->bc->pid : -1);
02470 return -1;
02471 case AST_CONTROL_OFFHOOK:
02472 chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n", p->bc ? p->bc->pid : -1);
02473 return -1;
02474 case AST_CONTROL_FLASH:
02475 chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n", p->bc ? p->bc->pid : -1);
02476 break;
02477 case AST_CONTROL_PROGRESS:
02478 chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n", p->bc ? p->bc->pid : -1);
02479 misdn_lib_send_event( p->bc, EVENT_PROGRESS);
02480 break;
02481 case AST_CONTROL_PROCEEDING:
02482 chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n", p->bc ? p->bc->pid : -1);
02483 misdn_lib_send_event( p->bc, EVENT_PROCEEDING);
02484 break;
02485 case AST_CONTROL_CONGESTION:
02486 chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n", p->bc ? p->bc->pid : -1);
02487
02488 p->bc->out_cause = AST_CAUSE_SWITCH_CONGESTION;
02489 start_bc_tones(p);
02490 misdn_lib_send_event( p->bc, EVENT_DISCONNECT);
02491
02492 if (p->bc->nt) {
02493 hanguptone_indicate(p);
02494 }
02495 break;
02496 case -1 :
02497 chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n", p->bc ? p->bc->pid : -1);
02498
02499 stop_indicate(p);
02500
02501 if (p->state == MISDN_CONNECTED)
02502 start_bc_tones(p);
02503 break;
02504 case AST_CONTROL_HOLD:
02505 ast_moh_start(ast, data, p->mohinterpret);
02506 chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n", p->bc ? p->bc->pid : -1);
02507 break;
02508 case AST_CONTROL_UNHOLD:
02509 ast_moh_stop(ast);
02510 chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n", p->bc ? p->bc->pid : -1);
02511 break;
02512 default:
02513 chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n", cond, p->bc ? p->bc->pid : -1);
02514 return -1;
02515 }
02516
02517 return 0;
02518 }
02519
02520 static int misdn_hangup(struct ast_channel *ast)
02521 {
02522 struct chan_list *p;
02523 struct misdn_bchannel *bc;
02524 const char *var;
02525
02526 if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) {
02527 return -1;
02528 }
02529 MISDN_ASTERISK_TECH_PVT(ast) = NULL;
02530
02531 ast_log(LOG_DEBUG, "misdn_hangup(%s)\n", ast->name);
02532
02533 if (p->hold.state == MISDN_HOLD_IDLE) {
02534 bc = p->bc;
02535 } else {
02536 p->hold.state = MISDN_HOLD_DISCONNECT;
02537 bc = misdn_lib_find_held_bc(p->hold.port, p->l3id);
02538 if (!bc) {
02539 chan_misdn_log(4, p->hold.port,
02540 "misdn_hangup: Could not find held bc for (%s)\n", ast->name);
02541 release_chan_early(p);
02542 return 0;
02543 }
02544 }
02545
02546 if (ast->_state == AST_STATE_RESERVED || p->state == MISDN_NOTHING) {
02547
02548 ast_log(LOG_DEBUG, "State Reserved (or nothing) => chanIsAvail\n");
02549 release_chan_early(p);
02550 if (bc) {
02551 misdn_lib_release(bc);
02552 }
02553 return 0;
02554 }
02555 if (!bc) {
02556 ast_log(LOG_WARNING, "Hangup with private but no bc ? state:%s l3id:%x\n",
02557 misdn_get_ch_state(p), p->l3id);
02558 release_chan_early(p);
02559 return 0;
02560 }
02561
02562 p->ast = NULL;
02563 p->need_hangup = 0;
02564 p->need_queue_hangup = 0;
02565 p->need_busy = 0;
02566
02567 if (!bc->nt) {
02568 stop_bc_tones(p);
02569 }
02570
02571 bc->out_cause = ast->hangupcause ? ast->hangupcause : AST_CAUSE_NORMAL_CLEARING;
02572
02573 var = pbx_builtin_getvar_helper(ast, "HANGUPCAUSE");
02574 if (!var) {
02575 var = pbx_builtin_getvar_helper(ast, "PRI_CAUSE");
02576 }
02577 if (var) {
02578 int tmpcause;
02579
02580 tmpcause = atoi(var);
02581 bc->out_cause = tmpcause ? tmpcause : AST_CAUSE_NORMAL_CLEARING;
02582 }
02583
02584 var = pbx_builtin_getvar_helper(ast, "MISDN_USERUSER");
02585 if (var) {
02586 ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", var);
02587 ast_copy_string(bc->uu, var, sizeof(bc->uu));
02588 bc->uulen = strlen(bc->uu);
02589 }
02590
02591 chan_misdn_log(1, bc->port,
02592 "* IND : HANGUP\tpid:%d ctx:%s dad:%s oad:%s State:%s\n",
02593 bc->pid,
02594 ast->context,
02595 ast->exten,
02596 ast->cid.cid_num,
02597 misdn_get_ch_state(p));
02598 chan_misdn_log(3, bc->port, " --> l3id:%x\n", p->l3id);
02599 chan_misdn_log(3, bc->port, " --> cause:%d\n", bc->cause);
02600 chan_misdn_log(2, bc->port, " --> out_cause:%d\n", bc->out_cause);
02601
02602 switch (p->state) {
02603 case MISDN_INCOMING_SETUP:
02604
02605
02606
02607
02608 ast_log(LOG_NOTICE, "release channel, in INCOMING_SETUP state.. no other events happened\n");
02609 release_chan(p, bc);
02610
02611 if (bc->need_release_complete) {
02612 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
02613 }
02614 return 0;
02615 case MISDN_DIALING:
02616 if (p->hold.state == MISDN_HOLD_IDLE) {
02617 start_bc_tones(p);
02618 hanguptone_indicate(p);
02619 }
02620
02621 if (bc->need_disconnect) {
02622 misdn_lib_send_event(bc, EVENT_DISCONNECT);
02623 }
02624 break;
02625 case MISDN_CALLING_ACKNOWLEDGE:
02626 if (p->hold.state == MISDN_HOLD_IDLE) {
02627 start_bc_tones(p);
02628 hanguptone_indicate(p);
02629 }
02630
02631 if (bc->need_disconnect) {
02632 misdn_lib_send_event(bc, EVENT_DISCONNECT);
02633 }
02634 break;
02635
02636 case MISDN_CALLING:
02637 case MISDN_ALERTING:
02638 case MISDN_PROGRESS:
02639 case MISDN_PROCEEDING:
02640 if (p->originator != ORG_AST && p->hold.state == MISDN_HOLD_IDLE) {
02641 hanguptone_indicate(p);
02642 }
02643
02644 if (bc->need_disconnect) {
02645 misdn_lib_send_event(bc, EVENT_DISCONNECT);
02646 }
02647 break;
02648 case MISDN_CONNECTED:
02649
02650 if (bc->nt && p->hold.state == MISDN_HOLD_IDLE) {
02651 start_bc_tones(p);
02652 hanguptone_indicate(p);
02653 bc->progress_indicator = INFO_PI_INBAND_AVAILABLE;
02654 }
02655 if (bc->need_disconnect) {
02656 misdn_lib_send_event(bc, EVENT_DISCONNECT);
02657 }
02658 break;
02659 case MISDN_DISCONNECTED:
02660 if (bc->need_release) {
02661 misdn_lib_send_event(bc, EVENT_RELEASE);
02662 }
02663 break;
02664
02665 case MISDN_CLEANING:
02666 return 0;
02667
02668 case MISDN_BUSY:
02669 break;
02670 default:
02671 if (bc->nt) {
02672 bc->out_cause = -1;
02673 if (bc->need_release) {
02674 misdn_lib_send_event(bc, EVENT_RELEASE);
02675 }
02676 } else {
02677 if (bc->need_disconnect) {
02678 misdn_lib_send_event(bc, EVENT_DISCONNECT);
02679 }
02680 }
02681 break;
02682 }
02683
02684 p->state = MISDN_CLEANING;
02685 chan_misdn_log(3, bc->port, " --> Channel: %s hungup new state:%s\n", ast->name,
02686 misdn_get_ch_state(p));
02687
02688 return 0;
02689 }
02690
02691
02692 static struct ast_frame *process_ast_dsp(struct chan_list *tmp, struct ast_frame *frame)
02693 {
02694 struct ast_frame *f;
02695
02696 if (tmp->dsp) {
02697 f = ast_dsp_process(tmp->ast, tmp->dsp, frame);
02698 } else {
02699 chan_misdn_log(0, tmp->bc->port, "No DSP-Path found\n");
02700 return NULL;
02701 }
02702
02703 if (!f || (f->frametype != AST_FRAME_DTMF)) {
02704 return f;
02705 }
02706
02707 ast_log(LOG_DEBUG, "Detected inband DTMF digit: %c\n", f->subclass);
02708
02709 if (tmp->faxdetect && (f->subclass == 'f')) {
02710
02711 if (!tmp->faxhandled) {
02712 struct ast_channel *ast = tmp->ast;
02713 tmp->faxhandled++;
02714 chan_misdn_log(0, tmp->bc->port, "Fax detected, preparing %s for fax transfer.\n", ast->name);
02715 tmp->bc->rxgain = 0;
02716 isdn_lib_update_rxgain(tmp->bc);
02717 tmp->bc->txgain = 0;
02718 isdn_lib_update_txgain(tmp->bc);
02719 #ifdef MISDN_1_2
02720 *tmp->bc->pipeline = 0;
02721 #else
02722 tmp->bc->ec_enable = 0;
02723 #endif
02724 isdn_lib_update_ec(tmp->bc);
02725 isdn_lib_stop_dtmf(tmp->bc);
02726 switch (tmp->faxdetect) {
02727 case 1:
02728 if (strcmp(ast->exten, "fax")) {
02729 char *context;
02730 char context_tmp[BUFFERSIZE];
02731 misdn_cfg_get(tmp->bc->port, MISDN_CFG_FAXDETECT_CONTEXT, &context_tmp, sizeof(context_tmp));
02732 context = ast_strlen_zero(context_tmp) ? (ast_strlen_zero(ast->macrocontext) ? ast->context : ast->macrocontext) : context_tmp;
02733 if (ast_exists_extension(ast, context, "fax", 1, ast->cid.cid_num)) {
02734 if (option_verbose > 2)
02735 ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension (context:%s)\n", ast->name, context);
02736
02737 pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten);
02738 if (ast_async_goto(ast, context, "fax", 1))
02739 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, context);
02740 } else
02741 ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n", context, ast->exten);
02742 } else {
02743 ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
02744 }
02745 break;
02746 case 2:
02747 ast_verbose(VERBOSE_PREFIX_3 "Not redirecting %s to fax extension, nojump is set.\n", ast->name);
02748 break;
02749 }
02750 } else {
02751 ast_log(LOG_DEBUG, "Fax already handled\n");
02752 }
02753 }
02754
02755 if (tmp->ast_dsp && (f->subclass != 'f')) {
02756 chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n", f->subclass);
02757 }
02758
02759 return f;
02760 }
02761
02762
02763 static struct ast_frame *misdn_read(struct ast_channel *ast)
02764 {
02765 struct chan_list *tmp;
02766 int len, t;
02767 struct pollfd pfd = { .fd = -1, .events = POLLIN };
02768
02769 if (!ast) {
02770 chan_misdn_log(1, 0, "misdn_read called without ast\n");
02771 return NULL;
02772 }
02773 if (!(tmp = MISDN_ASTERISK_TECH_PVT(ast))) {
02774 chan_misdn_log(1, 0, "misdn_read called without ast->pvt\n");
02775 return NULL;
02776 }
02777
02778 if (!tmp->bc && tmp->hold.state == MISDN_HOLD_IDLE) {
02779 chan_misdn_log(1, 0, "misdn_read called without bc\n");
02780 return NULL;
02781 }
02782
02783 pfd.fd = tmp->pipe[0];
02784 t = ast_poll(&pfd, 1, 20);
02785
02786 if (t < 0) {
02787 chan_misdn_log(-1, tmp->bc->port, "poll() error (err=%s)\n", strerror(errno));
02788 return NULL;
02789 }
02790
02791 if (!t) {
02792 chan_misdn_log(3, tmp->bc->port, "poll() timed out\n");
02793 len = 160;
02794 } else if (pfd.revents & POLLIN) {
02795 len = read(tmp->pipe[0], tmp->ast_rd_buf, sizeof(tmp->ast_rd_buf));
02796
02797 if (len <= 0) {
02798
02799 chan_misdn_log(2, tmp->bc->port, "misdn_read: Pipe closed, hanging up\n");
02800 return NULL;
02801 }
02802
02803 } else {
02804 return NULL;
02805 }
02806
02807 tmp->frame.frametype = AST_FRAME_VOICE;
02808 tmp->frame.subclass = AST_FORMAT_ALAW;
02809 tmp->frame.datalen = len;
02810 tmp->frame.samples = len;
02811 tmp->frame.mallocd = 0;
02812 tmp->frame.offset = 0;
02813 tmp->frame.delivery = ast_tv(0,0);
02814 tmp->frame.src = NULL;
02815 tmp->frame.data = tmp->ast_rd_buf;
02816
02817 if (tmp->faxdetect && !tmp->faxhandled) {
02818 if (tmp->faxdetect_timeout) {
02819 if (ast_tvzero(tmp->faxdetect_tv)) {
02820 tmp->faxdetect_tv = ast_tvnow();
02821 chan_misdn_log(2, tmp->bc->port, "faxdetect: starting detection with timeout: %ds ...\n", tmp->faxdetect_timeout);
02822 return process_ast_dsp(tmp, &tmp->frame);
02823 } else {
02824 struct timeval tv_now = ast_tvnow();
02825 int diff = ast_tvdiff_ms(tv_now, tmp->faxdetect_tv);
02826 if (diff <= (tmp->faxdetect_timeout * 1000)) {
02827 chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ...\n");
02828 return process_ast_dsp(tmp, &tmp->frame);
02829 } else {
02830 chan_misdn_log(2, tmp->bc->port, "faxdetect: stopping detection (time ran out) ...\n");
02831 tmp->faxdetect = 0;
02832 return &tmp->frame;
02833 }
02834 }
02835 } else {
02836 chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ... (no timeout)\n");
02837 return process_ast_dsp(tmp, &tmp->frame);
02838 }
02839 } else {
02840 if (tmp->ast_dsp)
02841 return process_ast_dsp(tmp, &tmp->frame);
02842 else
02843 return &tmp->frame;
02844 }
02845 }
02846
02847
02848 static int misdn_write(struct ast_channel *ast, struct ast_frame *frame)
02849 {
02850 struct chan_list *ch;
02851 int i = 0;
02852
02853 if (!ast || ! (ch = MISDN_ASTERISK_TECH_PVT(ast)) ) return -1;
02854
02855 if (ch->hold.state != MISDN_HOLD_IDLE) {
02856 chan_misdn_log(7, 0, "misdn_write: Returning because hold active\n");
02857 return 0;
02858 }
02859
02860 if (!ch->bc ) {
02861 ast_log(LOG_WARNING, "private but no bc\n");
02862 return -1;
02863 }
02864
02865 if (ch->notxtone) {
02866 chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because notxtone\n");
02867 return 0;
02868 }
02869
02870
02871 if (!frame->subclass) {
02872 chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n");
02873 return 0;
02874 }
02875
02876 if (!(frame->subclass & prefformat)) {
02877
02878 chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%d\n", frame->subclass);
02879 return 0;
02880 }
02881
02882
02883 if (!frame->samples ) {
02884 chan_misdn_log(4, ch->bc->port, "misdn_write: zero write\n");
02885
02886 if (!strcmp(frame->src,"ast_prod")) {
02887 chan_misdn_log(1, ch->bc->port, "misdn_write: state (%s) prodded.\n", misdn_get_ch_state(ch));
02888
02889 if (ch->ts) {
02890 chan_misdn_log(4, ch->bc->port, "Starting Playtones\n");
02891 misdn_lib_tone_generator_start(ch->bc);
02892 }
02893 return 0;
02894 }
02895
02896 return -1;
02897 }
02898
02899 if ( ! ch->bc->addr ) {
02900 chan_misdn_log(8, ch->bc->port, "misdn_write: no addr for bc dropping:%d\n", frame->samples);
02901 return 0;
02902 }
02903
02904 #ifdef MISDN_DEBUG
02905 {
02906 int i, max = 5 > frame->samples ? frame->samples : 5;
02907
02908 printf("write2mISDN %p %d bytes: ", p, frame->samples);
02909
02910 for (i = 0; i < max; i++)
02911 printf("%2.2x ", ((char*) frame->data)[i]);
02912 printf ("\n");
02913 }
02914 #endif
02915
02916 switch (ch->bc->bc_state) {
02917 case BCHAN_ACTIVATED:
02918 case BCHAN_BRIDGED:
02919 break;
02920 default:
02921 if (!ch->dropped_frame_cnt)
02922 chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) dropping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d l3id:%x\n", frame->samples, ch->bc->addr, ast->exten, ast->cid.cid_num, misdn_get_ch_state( ch), ch->bc->bc_state, ch->bc->l3_id);
02923
02924 ch->dropped_frame_cnt++;
02925 if (ch->dropped_frame_cnt > 100) {
02926 ch->dropped_frame_cnt = 0;
02927 chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) dropping: %d frames addr:%x dropped > 100 frames!\n", frame->samples, ch->bc->addr);
02928 }
02929
02930 return 0;
02931 }
02932
02933 chan_misdn_log(9, ch->bc->port, "Sending :%d bytes to MISDN\n", frame->samples);
02934 if ( !ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability) ) {
02935
02936 if (misdn_jb_fill(ch->jb, frame->data, frame->samples) < 0) {
02937 if (ch->bc->active)
02938 cb_log(0, ch->bc->port, "Misdn Jitterbuffer Overflow.\n");
02939 }
02940
02941 } else {
02942
02943 i = misdn_lib_tx2misdn_frm(ch->bc, frame->data, frame->samples);
02944 }
02945
02946 return 0;
02947 }
02948
02949
02950
02951
02952 static enum ast_bridge_result misdn_bridge (struct ast_channel *c0,
02953 struct ast_channel *c1, int flags,
02954 struct ast_frame **fo,
02955 struct ast_channel **rc,
02956 int timeoutms)
02957
02958 {
02959 struct chan_list *ch1, *ch2;
02960 struct ast_channel *carr[2], *who;
02961 int to = -1;
02962 struct ast_frame *f;
02963 int p1_b, p2_b;
02964 int bridging;
02965
02966 ch1 = get_chan_by_ast(c0);
02967 ch2 = get_chan_by_ast(c1);
02968
02969 carr[0] = c0;
02970 carr[1] = c1;
02971
02972 if (!(ch1 && ch2))
02973 return -1;
02974
02975 misdn_cfg_get(ch1->bc->port, MISDN_CFG_BRIDGING, &p1_b, sizeof(int));
02976 misdn_cfg_get(ch2->bc->port, MISDN_CFG_BRIDGING, &p2_b, sizeof(int));
02977
02978 if (! p1_b || ! p2_b) {
02979 ast_log(LOG_NOTICE, "Falling back to Asterisk bridging\n");
02980 return AST_BRIDGE_FAILED;
02981 }
02982
02983 misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
02984 if (bridging) {
02985
02986 chan_misdn_log(1, ch1->bc->port, "I SEND: Making conference with Number:%d\n", ch1->bc->pid + 1);
02987 misdn_lib_bridge(ch1->bc, ch2->bc);
02988 }
02989
02990 if (option_verbose > 2)
02991 ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name);
02992
02993 chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between %s and %s\n", ch1->bc->oad, ch2->bc->oad);
02994
02995 if (! (flags & AST_BRIDGE_DTMF_CHANNEL_0) )
02996 ch1->ignore_dtmf = 1;
02997
02998 if (! (flags & AST_BRIDGE_DTMF_CHANNEL_1) )
02999 ch2->ignore_dtmf = 1;
03000
03001 for (;;) {
03002 to = -1;
03003 who = ast_waitfor_n(carr, 2, &to);
03004
03005 if (!who) {
03006 ast_log(LOG_NOTICE, "misdn_bridge: empty read, breaking out\n");
03007 break;
03008 }
03009 f = ast_read(who);
03010
03011 if (!f || f->frametype == AST_FRAME_CONTROL) {
03012
03013
03014 if (!f)
03015 chan_misdn_log(4, ch1->bc->port, "Read Null Frame\n");
03016 else
03017 chan_misdn_log(4, ch1->bc->port, "Read Frame Control class:%d\n", f->subclass);
03018
03019 *fo = f;
03020 *rc = who;
03021 break;
03022 }
03023
03024 if ( f->frametype == AST_FRAME_DTMF ) {
03025 chan_misdn_log(1, 0, "Read DTMF %d from %s\n", f->subclass, who->exten);
03026
03027 *fo = f;
03028 *rc = who;
03029 break;
03030 }
03031
03032 #if 0
03033 if (f->frametype == AST_FRAME_VOICE) {
03034 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1);
03035
03036 continue;
03037 }
03038 #endif
03039
03040 if (who == c0) {
03041 ast_write(c1, f);
03042 }
03043 else {
03044 ast_write(c0, f);
03045 }
03046 }
03047
03048 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid + 1);
03049
03050 misdn_lib_split_bridge(ch1->bc, ch2->bc);
03051
03052 return AST_BRIDGE_COMPLETE;
03053 }
03054
03055
03056
03057 static int dialtone_indicate(struct chan_list *cl)
03058 {
03059 const struct tone_zone_sound *ts = NULL;
03060 struct ast_channel *ast = cl->ast;
03061 int nd = 0;
03062
03063 if (!ast) {
03064 chan_misdn_log(0, cl->bc->port, "No Ast in dialtone_indicate\n");
03065 return -1;
03066 }
03067
03068 misdn_cfg_get(cl->bc->port, MISDN_CFG_NODIALTONE, &nd, sizeof(nd));
03069
03070 if (nd) {
03071 chan_misdn_log(1, cl->bc->port, "Not sending Dialtone, because config wants it\n");
03072 return 0;
03073 }
03074
03075 chan_misdn_log(3, cl->bc->port, " --> Dial\n");
03076 ts = ast_get_indication_tone(ast->zone, "dial");
03077 cl->ts = ts;
03078
03079 if (ts) {
03080 cl->notxtone = 0;
03081 cl->norxtone = 0;
03082
03083 ast_playtones_start(ast, 0, ts->data, 0);
03084 }
03085
03086 return 0;
03087 }
03088
03089 static void hanguptone_indicate(struct chan_list *cl)
03090 {
03091 misdn_lib_send_tone(cl->bc, TONE_HANGUP);
03092 }
03093
03094 static int stop_indicate(struct chan_list *cl)
03095 {
03096 struct ast_channel *ast = cl->ast;
03097
03098 if (!ast) {
03099 chan_misdn_log(0, cl->bc->port, "No Ast in stop_indicate\n");
03100 return -1;
03101 }
03102
03103 chan_misdn_log(3, cl->bc->port, " --> None\n");
03104 misdn_lib_tone_generator_stop(cl->bc);
03105 ast_playtones_stop(ast);
03106
03107 cl->ts = NULL;
03108
03109
03110 return 0;
03111 }
03112
03113
03114 static int start_bc_tones(struct chan_list* cl)
03115 {
03116 misdn_lib_tone_generator_stop(cl->bc);
03117 cl->notxtone = 0;
03118 cl->norxtone = 0;
03119 return 0;
03120 }
03121
03122 static int stop_bc_tones(struct chan_list *cl)
03123 {
03124 if (!cl) return -1;
03125
03126 cl->notxtone = 1;
03127 cl->norxtone = 1;
03128
03129 return 0;
03130 }
03131
03132
03133 static struct chan_list *init_chan_list(int orig)
03134 {
03135 struct chan_list *cl;
03136
03137 cl = calloc(1, sizeof(struct chan_list));
03138 if (!cl) {
03139 chan_misdn_log(-1, 0, "misdn_request: malloc failed!");
03140 return NULL;
03141 }
03142
03143 cl->originator = orig;
03144 cl->need_queue_hangup = 1;
03145 cl->need_hangup = 1;
03146 cl->need_busy = 1;
03147 cl->overlap_dial_task = -1;
03148
03149 return cl;
03150 }
03151
03152 static struct ast_channel *misdn_request(const char *type, int format, void *data, int *cause)
03153 {
03154 struct ast_channel *tmp = NULL;
03155 char group[BUFFERSIZE + 1] = "";
03156 char dial_str[128];
03157 char *buf2 = ast_strdupa(data);
03158 char *ext;
03159 char *port_str;
03160 char *p = NULL;
03161 int channel = 0;
03162 int port = 0;
03163 struct misdn_bchannel *newbc = NULL;
03164 int dec = 0;
03165 struct chan_list *cl;
03166
03167 snprintf(dial_str, sizeof(dial_str), "%s/%s", misdn_type, (char *) data);
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177 port_str = strsep(&buf2, "/");
03178 if (!ast_strlen_zero(port_str)) {
03179 if (port_str[0] == 'g' && port_str[1] == ':' ) {
03180
03181 port_str += 2;
03182 ast_copy_string(group, port_str, sizeof(group));
03183 chan_misdn_log(2, 0, " --> Group Call group: %s\n", group);
03184 } else if ((p = strchr(port_str, ':'))) {
03185
03186 *p = 0;
03187 channel = atoi(++p);
03188 port = atoi(port_str);
03189 chan_misdn_log(2, port, " --> Call on preselected Channel (%d).\n", channel);
03190 } else {
03191 port = atoi(port_str);
03192 }
03193 } else {
03194 ast_log(LOG_WARNING, " --> ! IND : Dial(%s) WITHOUT Port or Group, check extensions.conf\n", dial_str);
03195 return NULL;
03196 }
03197
03198 ext = strsep(&buf2, "/");
03199 if (!ext) {
03200 ext = "";
03201 }
03202
03203 if (misdn_cfg_is_group_method(group, METHOD_STANDARD_DEC)) {
03204 chan_misdn_log(4, port, " --> STARTING STANDARD DEC...\n");
03205 dec = 1;
03206 }
03207
03208 if (!ast_strlen_zero(group)) {
03209 char cfg_group[BUFFERSIZE + 1];
03210 struct robin_list *rr = NULL;
03211
03212
03213
03214 if (misdn_cfg_is_group_method(group, METHOD_ROUND_ROBIN)) {
03215 chan_misdn_log(4, port, " --> STARTING ROUND ROBIN...\n");
03216 rr = get_robin_position(group);
03217 }
03218
03219 if (rr) {
03220 int port_start = 0;
03221 int port_bak = rr->port;
03222 int chan_bak = rr->channel;
03223
03224 if (!rr->port)
03225 rr->port = misdn_cfg_get_next_port_spin(rr->port);
03226
03227 for (; rr->port > 0; rr->port = misdn_cfg_get_next_port_spin(rr->port)) {
03228 int port_up;
03229 int check;
03230 int max_chan;
03231 int last_chance = 0;
03232
03233 misdn_cfg_get(rr->port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE);
03234 if (strcasecmp(cfg_group, group))
03235 continue;
03236
03237 misdn_cfg_get(rr->port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int));
03238 port_up = misdn_lib_port_up(rr->port, check);
03239
03240 if (check && !port_up)
03241 chan_misdn_log(1, rr->port, "L1 is not Up on this Port\n");
03242
03243 if (check && port_up < 0)
03244 ast_log(LOG_WARNING,"This port (%d) is blocked\n", rr->port);
03245
03246 if ((port_start == rr->port) && (port_up <= 0))
03247 break;
03248
03249 if (!port_start)
03250 port_start = rr->port;
03251
03252 if (port_up <= 0)
03253 continue;
03254
03255 max_chan = misdn_lib_get_maxchans(rr->port);
03256
03257 for (++rr->channel; !last_chance && rr->channel <= max_chan; ++rr->channel) {
03258 if (rr->port == port_bak && rr->channel == chan_bak)
03259 last_chance = 1;
03260
03261 chan_misdn_log(1, 0, "trying port:%d channel:%d\n", rr->port, rr->channel);
03262 newbc = misdn_lib_get_free_bc(rr->port, rr->channel, 0, 0);
03263 if (newbc) {
03264 chan_misdn_log(4, rr->port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel);
03265 if (port_up)
03266 chan_misdn_log(4, rr->port, "portup:%d\n", port_up);
03267 port = rr->port;
03268 break;
03269 }
03270 }
03271
03272 if (newbc || last_chance)
03273 break;
03274
03275 rr->channel = 0;
03276 }
03277 if (!newbc) {
03278 rr->port = port_bak;
03279 rr->channel = chan_bak;
03280 }
03281 } else {
03282 for (port = misdn_cfg_get_next_port(0); port > 0;
03283 port = misdn_cfg_get_next_port(port)) {
03284
03285 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE);
03286
03287 chan_misdn_log(3, port, "Group [%s] Port [%d]\n", group, port);
03288 if (!strcasecmp(cfg_group, group)) {
03289 int port_up;
03290 int check;
03291 misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int));
03292 port_up = misdn_lib_port_up(port, check);
03293
03294 chan_misdn_log(4, port, "portup:%d\n", port_up);
03295
03296 if (port_up > 0) {
03297 newbc = misdn_lib_get_free_bc(port, 0, 0, dec);
03298 if (newbc)
03299 break;
03300 }
03301 }
03302 }
03303 }
03304
03305
03306 if (!newbc) {
03307 ast_log(LOG_WARNING,
03308 "Could not Dial out on group '%s'.\n"
03309 "\tEither the L2 and L1 on all of these ports where DOWN (see 'show application misdn_check_l2l1')\n"
03310 "\tOr there was no free channel on none of the ports\n\n"
03311 , group);
03312 return NULL;
03313 }
03314 } else {
03315
03316 if (channel)
03317 chan_misdn_log(1, port, " --> preselected_channel: %d\n", channel);
03318 newbc = misdn_lib_get_free_bc(port, channel, 0, dec);
03319
03320 if (!newbc) {
03321 ast_log(LOG_WARNING, "Could not create channel on port:%d with extensions:%s\n", port, ext);
03322 return NULL;
03323 }
03324 }
03325
03326
03327
03328 cl = init_chan_list(ORG_AST);
03329 if (!cl) {
03330 ast_log(LOG_ERROR, "Could not create call record for Dial(%s)\n", dial_str);
03331 return NULL;
03332 }
03333 cl->bc = newbc;
03334
03335 tmp = misdn_new(cl, AST_STATE_RESERVED, ext, NULL, format, port, channel);
03336 if (!tmp) {
03337 free(cl);
03338 ast_log(LOG_ERROR,"Could not create Asterisk object\n");
03339 return NULL;
03340 }
03341
03342 cl->ast=tmp;
03343
03344
03345 cl_queue_chan(&cl_te, cl) ;
03346
03347
03348 read_config(cl, ORG_AST);
03349
03350
03351 cl->need_hangup = 0;
03352
03353 return tmp;
03354 }
03355
03356
03357 static int misdn_send_text(struct ast_channel *chan, const char *text)
03358 {
03359 struct chan_list *tmp = chan->tech_pvt;
03360
03361 if (tmp && tmp->bc) {
03362 ast_copy_string(tmp->bc->display, text, sizeof(tmp->bc->display));
03363 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
03364 } else {
03365 ast_log(LOG_WARNING, "No chan_list but send_text request?\n");
03366 return -1;
03367 }
03368
03369 return 0;
03370 }
03371
03372 static struct ast_channel_tech misdn_tech = {
03373 .type = "mISDN",
03374 .description = "Channel driver for mISDN Support (Bri/Pri)",
03375 .capabilities = AST_FORMAT_ALAW ,
03376 .requester = misdn_request,
03377 .send_digit_begin = misdn_digit_begin,
03378 .send_digit_end = misdn_digit_end,
03379 .call = misdn_call,
03380 .bridge = misdn_bridge,
03381 .hangup = misdn_hangup,
03382 .answer = misdn_answer,
03383 .read = misdn_read,
03384 .write = misdn_write,
03385 .indicate = misdn_indication,
03386 .fixup = misdn_fixup,
03387 .send_text = misdn_send_text,
03388 .properties = 0
03389 };
03390
03391 static struct ast_channel_tech misdn_tech_wo_bridge = {
03392 .type = "mISDN",
03393 .description = "Channel driver for mISDN Support (Bri/Pri)",
03394 .capabilities = AST_FORMAT_ALAW ,
03395 .requester = misdn_request,
03396 .send_digit_begin = misdn_digit_begin,
03397 .send_digit_end = misdn_digit_end,
03398 .call = misdn_call,
03399 .hangup = misdn_hangup,
03400 .answer = misdn_answer,
03401 .read = misdn_read,
03402 .write = misdn_write,
03403 .indicate = misdn_indication,
03404 .fixup = misdn_fixup,
03405 .send_text = misdn_send_text,
03406 .properties = 0
03407 };
03408
03409
03410 static int glob_channel = 0;
03411
03412 static void update_name(struct ast_channel *tmp, int port, int c)
03413 {
03414 int chan_offset = 0;
03415 int tmp_port = misdn_cfg_get_next_port(0);
03416 for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) {
03417 if (tmp_port == port)
03418 break;
03419 chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2;
03420 }
03421 if (c < 0)
03422 c = 0;
03423
03424 ast_string_field_build(tmp, name, "%s/%d-u%d",
03425 misdn_type, chan_offset + c, glob_channel++);
03426
03427 chan_misdn_log(3, port, " --> updating channel name to [%s]\n", tmp->name);
03428 }
03429
03430 static struct ast_channel *misdn_new(struct chan_list *chlist, int state, char *exten, char *callerid, int format, int port, int c)
03431 {
03432 struct ast_channel *tmp;
03433 char *cid_name = 0, *cid_num = 0;
03434 int chan_offset = 0;
03435 int tmp_port = misdn_cfg_get_next_port(0);
03436 int bridging;
03437
03438 for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) {
03439 if (tmp_port == port)
03440 break;
03441 chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2;
03442 }
03443 if (c < 0)
03444 c = 0;
03445
03446 if (callerid) {
03447 ast_callerid_parse(callerid, &cid_name, &cid_num);
03448 }
03449
03450 tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", 0, "%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++);
03451 if (tmp) {
03452 chan_misdn_log(2, 0, " --> * NEW CHANNEL dad:%s oad:%s\n", exten, callerid);
03453
03454 tmp->nativeformats = prefformat;
03455
03456 tmp->readformat = format;
03457 tmp->rawreadformat = format;
03458 tmp->writeformat = format;
03459 tmp->rawwriteformat = format;
03460
03461 tmp->tech_pvt = chlist;
03462
03463 misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
03464
03465 if (bridging)
03466 tmp->tech = &misdn_tech;
03467 else
03468 tmp->tech = &misdn_tech_wo_bridge;
03469
03470 tmp->writeformat = format;
03471 tmp->readformat = format;
03472 tmp->priority=1;
03473
03474 if (exten)
03475 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten));
03476 else
03477 chan_misdn_log(1, 0, "misdn_new: no exten given.\n");
03478
03479 if (callerid)
03480
03481
03482 tmp->cid.cid_ani = ast_strdup(cid_num);
03483
03484 if (pipe(chlist->pipe) < 0)
03485 perror("Pipe failed\n");
03486 tmp->fds[0] = chlist->pipe[0];
03487
03488 if (state == AST_STATE_RING)
03489 tmp->rings = 1;
03490 else
03491 tmp->rings = 0;
03492
03493 } else {
03494 chan_misdn_log(-1, 0, "Unable to allocate channel structure\n");
03495 }
03496
03497 return tmp;
03498 }
03499
03500 static struct chan_list *find_chan_by_bc(struct chan_list *list, struct misdn_bchannel *bc)
03501 {
03502 struct chan_list *help = list;
03503 for (; help; help = help->next) {
03504 if (help->bc == bc) return help;
03505 }
03506
03507 chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n", bc->oad, bc->dad);
03508
03509 return NULL;
03510 }
03511
03512 static struct chan_list *find_chan_by_pid(struct chan_list *list, int pid)
03513 {
03514 struct chan_list *help = list;
03515 for (; help; help = help->next) {
03516 if ( help->bc && (help->bc->pid == pid) ) return help;
03517 }
03518
03519 chan_misdn_log(6, 0, "$$$ find_chan: No channel found for pid:%d\n", pid);
03520
03521 return NULL;
03522 }
03523
03524 static struct chan_list *find_hold_call(struct chan_list *list, struct misdn_bchannel *bc)
03525 {
03526 struct chan_list *help = list;
03527
03528 if (bc->pri) return NULL;
03529
03530 chan_misdn_log(6, bc->port, "$$$ find_hold_call: channel:%d oad:%s dad:%s\n", bc->channel, bc->oad, bc->dad);
03531 for (;help; help = help->next) {
03532 chan_misdn_log(4, bc->port, "$$$ find_hold_call: --> hold:%d channel:%d\n", help->hold.state, help->hold.channel);
03533 if (help->hold.state == MISDN_HOLD_ACTIVE && help->hold.port == bc->port)
03534 return help;
03535 }
03536 chan_misdn_log(6, bc->port, "$$$ find_hold_call: No channel found for oad:%s dad:%s\n", bc->oad, bc->dad);
03537
03538 return NULL;
03539 }
03540
03541
03542 static struct chan_list *find_hold_call_l3(struct chan_list *list, unsigned long l3_id)
03543 {
03544 struct chan_list *help = list;
03545
03546 for (; help; help = help->next) {
03547 if (help->hold.state != MISDN_HOLD_IDLE && help->l3id == l3_id)
03548 return help;
03549 }
03550
03551 return NULL;
03552 }
03553
03554 #define TRANSFER_ON_HELD_CALL_HANGUP 1
03555 #if defined(TRANSFER_ON_HELD_CALL_HANGUP)
03556
03557
03558
03559
03560
03561
03562
03563
03564
03565
03566
03567
03568
03569
03570 static struct chan_list *find_hold_active_call(struct chan_list *list, struct misdn_bchannel *bc)
03571 {
03572 for (; list; list = list->next) {
03573 if (list->hold.state == MISDN_HOLD_IDLE && list->bc && list->bc->port == bc->port
03574 && list->ast) {
03575 switch (list->state) {
03576 case MISDN_PROCEEDING:
03577 case MISDN_PROGRESS:
03578 case MISDN_ALERTING:
03579 case MISDN_CONNECTED:
03580 return list;
03581 default:
03582 break;
03583 }
03584 }
03585 }
03586 return NULL;
03587 }
03588 #endif
03589
03590 static void cl_queue_chan(struct chan_list **list, struct chan_list *chan)
03591 {
03592 chan_misdn_log(4, chan->bc ? chan->bc->port : 0, "* Queuing chan %p\n", chan);
03593
03594 ast_mutex_lock(&cl_te_lock);
03595 if (!*list) {
03596 *list = chan;
03597 } else {
03598 struct chan_list *help = *list;
03599 for (; help->next; help = help->next);
03600 help->next = chan;
03601 }
03602 chan->next = NULL;
03603 ast_mutex_unlock(&cl_te_lock);
03604 }
03605
03606 static void cl_dequeue_chan(struct chan_list **list, struct chan_list *chan)
03607 {
03608 struct chan_list *help;
03609
03610 if (chan->dsp)
03611 ast_dsp_free(chan->dsp);
03612
03613 ast_mutex_lock(&cl_te_lock);
03614 if (!*list) {
03615 ast_mutex_unlock(&cl_te_lock);
03616 return;
03617 }
03618
03619 if (*list == chan) {
03620 *list = (*list)->next;
03621 ast_mutex_unlock(&cl_te_lock);
03622 return;
03623 }
03624
03625 for (help = *list; help->next; help = help->next) {
03626 if (help->next == chan) {
03627 help->next = help->next->next;
03628 ast_mutex_unlock(&cl_te_lock);
03629 return;
03630 }
03631 }
03632
03633 ast_mutex_unlock(&cl_te_lock);
03634 }
03635
03636
03637
03638
03639 static int pbx_start_chan(struct chan_list *ch)
03640 {
03641 int ret = ast_pbx_start(ch->ast);
03642
03643 if (ret >= 0)
03644 ch->need_hangup = 0;
03645 else
03646 ch->need_hangup = 1;
03647
03648 return ret;
03649 }
03650
03651 static void hangup_chan(struct chan_list *ch, struct misdn_bchannel *bc)
03652 {
03653 int port;
03654
03655 if (!ch) {
03656 cb_log(1, 0, "Cannot hangup chan, no ch\n");
03657 return;
03658 }
03659
03660 port = bc->port;
03661 cb_log(5, port, "hangup_chan called\n");
03662
03663 if (ch->need_hangup) {
03664 cb_log(2, port, " --> hangup\n");
03665 ch->need_hangup = 0;
03666 ch->need_queue_hangup = 0;
03667 if (ch->ast) {
03668 send_cause2ast(ch->ast, bc, ch);
03669 ast_hangup(ch->ast);
03670 }
03671 return;
03672 }
03673
03674 if (!ch->need_queue_hangup) {
03675 cb_log(2, port, " --> No need to queue hangup\n");
03676 }
03677
03678 ch->need_queue_hangup = 0;
03679 if (ch->ast) {
03680 send_cause2ast(ch->ast, bc, ch);
03681 ast_queue_hangup(ch->ast);
03682 cb_log(2, port, " --> queue_hangup\n");
03683 } else {
03684 cb_log(1, port, "Cannot hangup chan, no ast\n");
03685 }
03686 }
03687
03688
03689
03690
03691
03692
03693
03694
03695
03696
03697
03698
03699 static void release_chan(struct chan_list *ch, struct misdn_bchannel *bc)
03700 {
03701 struct ast_channel *ast;
03702
03703 ch->state = MISDN_CLEANING;
03704
03705 ast_mutex_lock(&release_lock);
03706
03707 cl_dequeue_chan(&cl_te, ch);
03708
03709 chan_misdn_log(5, bc->port, "release_chan: bc with pid:%d l3id: %x\n", bc->pid, bc->l3_id);
03710
03711
03712 if (ch->jb) {
03713 misdn_jb_destroy(ch->jb);
03714 ch->jb = NULL;
03715 } else {
03716 if (!bc->nojitter) {
03717 chan_misdn_log(5, bc->port, "Jitterbuffer already destroyed.\n");
03718 }
03719 }
03720
03721 if (ch->overlap_dial) {
03722 if (ch->overlap_dial_task != -1) {
03723 misdn_tasks_remove(ch->overlap_dial_task);
03724 ch->overlap_dial_task = -1;
03725 }
03726 ast_mutex_destroy(&ch->overlap_tv_lock);
03727 }
03728
03729 if (ch->originator == ORG_AST) {
03730 --misdn_out_calls[bc->port];
03731 } else {
03732 --misdn_in_calls[bc->port];
03733 }
03734
03735 close(ch->pipe[0]);
03736 close(ch->pipe[1]);
03737
03738 ast = ch->ast;
03739 if (ast) {
03740 MISDN_ASTERISK_TECH_PVT(ast) = NULL;
03741 chan_misdn_log(1, bc->port,
03742 "* RELEASING CHANNEL pid:%d ctx:%s dad:%s oad:%s\n",
03743 bc->pid,
03744 ast->context,
03745 ast->exten,
03746 ast->cid.cid_num);
03747
03748 if (ast->_state != AST_STATE_RESERVED) {
03749 chan_misdn_log(3, bc->port, " --> Setting AST State to down\n");
03750 ast_setstate(ast, AST_STATE_DOWN);
03751 }
03752 }
03753
03754 free(ch);
03755
03756 ast_mutex_unlock(&release_lock);
03757 }
03758
03759
03760
03761
03762
03763
03764
03765
03766
03767
03768
03769 static void release_chan_early(struct chan_list *ch)
03770 {
03771 struct ast_channel *ast;
03772
03773 ch->state = MISDN_CLEANING;
03774
03775 ast_mutex_lock(&release_lock);
03776
03777 cl_dequeue_chan(&cl_te, ch);
03778
03779
03780 if (ch->jb) {
03781 misdn_jb_destroy(ch->jb);
03782 ch->jb = NULL;
03783 }
03784
03785 if (ch->overlap_dial) {
03786 if (ch->overlap_dial_task != -1) {
03787 misdn_tasks_remove(ch->overlap_dial_task);
03788 ch->overlap_dial_task = -1;
03789 }
03790 ast_mutex_destroy(&ch->overlap_tv_lock);
03791 }
03792
03793 if (ch->hold.state != MISDN_HOLD_IDLE) {
03794 if (ch->originator == ORG_AST) {
03795 --misdn_out_calls[ch->hold.port];
03796 } else {
03797 --misdn_in_calls[ch->hold.port];
03798 }
03799 }
03800
03801 close(ch->pipe[0]);
03802 close(ch->pipe[1]);
03803
03804 ast = ch->ast;
03805 if (ast) {
03806 MISDN_ASTERISK_TECH_PVT(ast) = NULL;
03807 if (ast->_state != AST_STATE_RESERVED) {
03808 ast_setstate(ast, AST_STATE_DOWN);
03809 }
03810 }
03811
03812 free(ch);
03813
03814 ast_mutex_unlock(&release_lock);
03815 }
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827 static int misdn_attempt_transfer(struct chan_list *active_ch, struct chan_list *held_ch)
03828 {
03829 int retval;
03830 struct ast_channel *bridged;
03831
03832 switch (active_ch->state) {
03833 case MISDN_PROCEEDING:
03834 case MISDN_PROGRESS:
03835 case MISDN_ALERTING:
03836 case MISDN_CONNECTED:
03837 break;
03838 default:
03839 return -1;
03840 }
03841
03842 bridged = ast_bridged_channel(held_ch->ast);
03843 if (bridged) {
03844 ast_queue_control(held_ch->ast, AST_CONTROL_UNHOLD);
03845 held_ch->hold.state = MISDN_HOLD_TRANSFER;
03846
03847 chan_misdn_log(1, held_ch->hold.port, "TRANSFERRING %s to %s\n",
03848 held_ch->ast->name, active_ch->ast->name);
03849 retval = ast_channel_masquerade(active_ch->ast, bridged);
03850 } else {
03851
03852
03853
03854
03855 retval = -1;
03856 }
03857
03858 return retval;
03859 }
03860
03861
03862 static void do_immediate_setup(struct misdn_bchannel *bc, struct chan_list *ch, struct ast_channel *ast)
03863 {
03864 char predial[256]="";
03865 char *p = predial;
03866
03867 struct ast_frame fr;
03868
03869 strncpy(predial, ast->exten, sizeof(predial) -1 );
03870
03871 ch->state = MISDN_DIALING;
03872
03873 if (!ch->noautorespond_on_setup) {
03874 if (bc->nt) {
03875 int ret;
03876 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03877 } else {
03878 int ret;
03879 if ( misdn_lib_is_ptp(bc->port)) {
03880 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03881 } else {
03882 ret = misdn_lib_send_event(bc, EVENT_PROCEEDING );
03883 }
03884 }
03885 } else {
03886 ch->state = MISDN_INCOMING_SETUP;
03887 }
03888
03889 chan_misdn_log(1, bc->port, "* Starting Ast ctx:%s dad:%s oad:%s with 's' extension\n", ast->context, ast->exten, ast->cid.cid_num);
03890
03891 strcpy(ast->exten, "s");
03892
03893 if (!ast_canmatch_extension(ast, ast->context, ast->exten, 1, bc->oad) || pbx_start_chan(ch) < 0) {
03894 ast = NULL;
03895 bc->out_cause = AST_CAUSE_UNALLOCATED;
03896 hangup_chan(ch, bc);
03897 hanguptone_indicate(ch);
03898
03899 if (bc->nt)
03900 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
03901 else
03902 misdn_lib_send_event(bc, EVENT_DISCONNECT );
03903 }
03904
03905
03906 while (!ast_strlen_zero(p) ) {
03907 fr.frametype = AST_FRAME_DTMF;
03908 fr.subclass = *p;
03909 fr.src = NULL;
03910 fr.data = NULL;
03911 fr.datalen = 0;
03912 fr.samples = 0;
03913 fr.mallocd = 0;
03914 fr.offset = 0;
03915 fr.delivery = ast_tv(0,0);
03916
03917 if (ch->ast && MISDN_ASTERISK_PVT(ch->ast) && MISDN_ASTERISK_TECH_PVT(ch->ast)) {
03918 ast_queue_frame(ch->ast, &fr);
03919 }
03920 p++;
03921 }
03922 }
03923
03924
03925
03926 static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel *bc, struct chan_list *ch) {
03927 if (!ast) {
03928 chan_misdn_log(1, 0, "send_cause2ast: No Ast\n");
03929 return;
03930 }
03931 if (!bc) {
03932 chan_misdn_log(1, 0, "send_cause2ast: No BC\n");
03933 return;
03934 }
03935 if (!ch) {
03936 chan_misdn_log(1, 0, "send_cause2ast: No Ch\n");
03937 return;
03938 }
03939
03940 ast->hangupcause = bc->cause;
03941
03942 switch (bc->cause) {
03943
03944 case AST_CAUSE_UNALLOCATED:
03945 case AST_CAUSE_NO_ROUTE_TRANSIT_NET:
03946 case AST_CAUSE_NO_ROUTE_DESTINATION:
03947 case 4:
03948 case AST_CAUSE_NUMBER_CHANGED:
03949 case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
03950
03951
03952
03953
03954
03955
03956
03957
03958
03959
03960 break;
03961
03962 case AST_CAUSE_CALL_REJECTED:
03963 case AST_CAUSE_USER_BUSY:
03964 ch->state = MISDN_BUSY;
03965
03966 if (!ch->need_busy) {
03967 chan_misdn_log(1, bc ? bc->port : 0, "Queued busy already\n");
03968 break;
03969 }
03970
03971 chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Busy pid:%d\n", bc ? bc->pid : -1);
03972
03973 ast_queue_control(ast, AST_CONTROL_BUSY);
03974
03975 ch->need_busy = 0;
03976
03977 break;
03978 }
03979 }
03980
03981
03982
03983 void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
03984 {
03985 const char *tmp;
03986
03987 tmp = pbx_builtin_getvar_helper(chan, "MISDN_PID");
03988 if (tmp) {
03989 ch->other_pid = atoi(tmp);
03990 chan_misdn_log(3, bc->port, " --> IMPORT_PID: importing pid:%s\n", tmp);
03991 if (ch->other_pid > 0) {
03992 ch->other_ch = find_chan_by_pid(cl_te, ch->other_pid);
03993 if (ch->other_ch)
03994 ch->other_ch->other_ch = ch;
03995 }
03996 }
03997
03998 tmp = pbx_builtin_getvar_helper(chan, "MISDN_ADDRESS_COMPLETE");
03999 if (tmp && (atoi(tmp) == 1)) {
04000 bc->sending_complete = 1;
04001 }
04002
04003 tmp = pbx_builtin_getvar_helper(chan, "MISDN_USERUSER");
04004 if (tmp) {
04005 ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp);
04006 ast_copy_string(bc->uu, tmp, sizeof(bc->uu));
04007 bc->uulen = strlen(bc->uu);
04008 }
04009
04010 tmp = pbx_builtin_getvar_helper(chan, "MISDN_KEYPAD");
04011 if (tmp) {
04012 ast_copy_string(bc->keypad, tmp, sizeof(bc->keypad));
04013 }
04014 }
04015
04016
04017 void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
04018 {
04019 char tmp[32];
04020 chan_misdn_log(3, bc->port, " --> EXPORT_PID: pid:%d\n", bc->pid);
04021 snprintf(tmp, sizeof(tmp), "%d", bc->pid);
04022 pbx_builtin_setvar_helper(chan, "_MISDN_PID", tmp);
04023
04024 if (bc->sending_complete) {
04025 snprintf(tmp, sizeof(tmp), "%d", bc->sending_complete);
04026 pbx_builtin_setvar_helper(chan, "MISDN_ADDRESS_COMPLETE", tmp);
04027 }
04028
04029 if (bc->urate) {
04030 snprintf(tmp, sizeof(tmp), "%d", bc->urate);
04031 pbx_builtin_setvar_helper(chan, "MISDN_URATE", tmp);
04032 }
04033
04034 if (bc->uulen && (bc->uulen < sizeof(bc->uu))) {
04035 bc->uu[bc->uulen] = 0;
04036 pbx_builtin_setvar_helper(chan, "MISDN_USERUSER", bc->uu);
04037 }
04038
04039 if (!ast_strlen_zero(bc->keypad))
04040 pbx_builtin_setvar_helper(chan, "MISDN_KEYPAD", bc->keypad);
04041 }
04042
04043 int add_in_calls(int port)
04044 {
04045 int max_in_calls;
04046
04047 misdn_cfg_get(port, MISDN_CFG_MAX_IN, &max_in_calls, sizeof(max_in_calls));
04048 misdn_in_calls[port]++;
04049
04050 if (max_in_calls >= 0 && max_in_calls < misdn_in_calls[port]) {
04051 ast_log(LOG_NOTICE, "Marking Incoming Call on port[%d]\n", port);
04052 return misdn_in_calls[port] - max_in_calls;
04053 }
04054
04055 return 0;
04056 }
04057
04058 int add_out_calls(int port)
04059 {
04060 int max_out_calls;
04061
04062 misdn_cfg_get(port, MISDN_CFG_MAX_OUT, &max_out_calls, sizeof(max_out_calls));
04063
04064 if (max_out_calls >= 0 && max_out_calls <= misdn_out_calls[port]) {
04065 ast_log(LOG_NOTICE, "Rejecting Outgoing Call on port[%d]\n", port);
04066 return (misdn_out_calls[port] + 1) - max_out_calls;
04067 }
04068
04069 misdn_out_calls[port]++;
04070
04071 return 0;
04072 }
04073
04074 static void start_pbx(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan) {
04075 if (pbx_start_chan(ch) < 0) {
04076 hangup_chan(ch, bc);
04077 chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n");
04078 if (bc->nt) {
04079 hanguptone_indicate(ch);
04080 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
04081 } else
04082 misdn_lib_send_event(bc, EVENT_RELEASE);
04083 }
04084 }
04085
04086 static void wait_for_digits(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan) {
04087 ch->state=MISDN_WAITING4DIGS;
04088 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
04089 if (bc->nt && !bc->dad[0])
04090 dialtone_indicate(ch);
04091 }
04092
04093
04094
04095
04096
04097 static enum event_response_e
04098 cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
04099 {
04100 int msn_valid;
04101 struct chan_list *held_ch;
04102 struct chan_list *ch = find_chan_by_bc(cl_te, bc);
04103
04104 if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) {
04105 int debuglevel = 1;
04106 if ( event == EVENT_CLEANUP && !user_data)
04107 debuglevel = 5;
04108
04109 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");
04110 if (debuglevel == 1) {
04111 misdn_lib_log_ies(bc);
04112 chan_misdn_log(4, bc->port, " --> bc_state:%s\n", bc_state2str(bc->bc_state));
04113 }
04114 }
04115
04116 if (!ch) {
04117 switch(event) {
04118 case EVENT_SETUP:
04119 case EVENT_DISCONNECT:
04120 case EVENT_RELEASE:
04121 case EVENT_RELEASE_COMPLETE:
04122 case EVENT_PORT_ALARM:
04123 case EVENT_RETRIEVE:
04124 case EVENT_NEW_BC:
04125 case EVENT_FACILITY:
04126 break;
04127 case EVENT_CLEANUP:
04128 case EVENT_TONE_GENERATE:
04129 case EVENT_BCHAN_DATA:
04130 return -1;
04131 default:
04132 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);
04133 return -1;
04134 }
04135 }
04136
04137 if (ch) {
04138 switch (event) {
04139 case EVENT_TONE_GENERATE:
04140 break;
04141 case EVENT_DISCONNECT:
04142 case EVENT_RELEASE:
04143 case EVENT_RELEASE_COMPLETE:
04144 case EVENT_CLEANUP:
04145 case EVENT_TIMEOUT:
04146 if (!ch->ast)
04147 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));
04148 break;
04149 default:
04150 if (!ch->ast || !MISDN_ASTERISK_PVT(ch->ast) || !MISDN_ASTERISK_TECH_PVT(ch->ast)) {
04151 if (event != EVENT_BCHAN_DATA)
04152 ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event));
04153 return -1;
04154 }
04155 }
04156 }
04157
04158
04159 switch (event) {
04160 case EVENT_PORT_ALARM:
04161 {
04162 int boa = 0;
04163 misdn_cfg_get(bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(int));
04164 if (boa) {
04165 cb_log(1, bc->port, " --> blocking\n");
04166 misdn_lib_port_block(bc->port);
04167 }
04168 }
04169 break;
04170 case EVENT_BCHAN_ACTIVATED:
04171 break;
04172
04173 case EVENT_NEW_CHANNEL:
04174 update_name(ch->ast,bc->port,bc->channel);
04175 break;
04176
04177 case EVENT_NEW_L3ID:
04178 ch->l3id=bc->l3_id;
04179 ch->addr=bc->addr;
04180 break;
04181
04182 case EVENT_NEW_BC:
04183 if (!ch) {
04184 ch = find_hold_call(cl_te,bc);
04185 }
04186
04187 if (!ch) {
04188 ast_log(LOG_WARNING, "NEW_BC without chan_list?\n");
04189 break;
04190 }
04191
04192 if (bc)
04193 ch->bc = (struct misdn_bchannel *)user_data;
04194 break;
04195
04196 case EVENT_DTMF_TONE:
04197 {
04198
04199 struct ast_frame fr;
04200
04201 memset(&fr, 0, sizeof(fr));
04202 fr.frametype = AST_FRAME_DTMF;
04203 fr.subclass = bc->dtmf ;
04204 fr.src = NULL;
04205 fr.data = NULL;
04206 fr.datalen = 0;
04207 fr.samples = 0;
04208 fr.mallocd = 0;
04209 fr.offset = 0;
04210 fr.delivery = ast_tv(0,0);
04211
04212 if (!ch->ignore_dtmf) {
04213 chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf);
04214 ast_queue_frame(ch->ast, &fr);
04215 } else {
04216 chan_misdn_log(2, bc->port, " --> Ignoring DTMF:%c due to bridge flags\n", bc->dtmf);
04217 }
04218 }
04219 break;
04220 case EVENT_STATUS:
04221 break;
04222
04223 case EVENT_INFORMATION:
04224 {
04225 if ( ch->state != MISDN_CONNECTED )
04226 stop_indicate(ch);
04227
04228 if (!ch->ast)
04229 break;
04230
04231 if (ch->state == MISDN_WAITING4DIGS ) {
04232
04233 if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) {
04234 chan_misdn_log(1, bc->port, " --> using keypad as info\n");
04235 ast_copy_string(bc->info_dad, bc->keypad, sizeof(bc->info_dad));
04236 }
04237
04238 strncat(bc->dad, bc->info_dad, sizeof(bc->dad) - strlen(bc->dad) - 1);
04239 ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten));
04240
04241
04242 if (!strcmp(ch->ast->exten, ast_pickup_ext())) {
04243 if (ast_pickup_call(ch->ast)) {
04244 hangup_chan(ch, bc);
04245 } else {
04246 struct ast_channel *chan = ch->ast;
04247 ch->state = MISDN_CALLING_ACKNOWLEDGE;
04248 ast_setstate(chan, AST_STATE_DOWN);
04249 hangup_chan(ch, bc);
04250 ch->ast = NULL;
04251 break;
04252 }
04253 }
04254
04255 if (!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
04256 if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) {
04257 ast_log(LOG_WARNING,
04258 "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n",
04259 bc->dad, ch->context, bc->port);
04260 strcpy(ch->ast->exten, "i");
04261
04262 ch->state = MISDN_DIALING;
04263 start_pbx(ch, bc, ch->ast);
04264 break;
04265 }
04266
04267 ast_log(LOG_WARNING,
04268 "Extension '%s@%s' can never match. Disconnecting. port:%d\n"
04269 "\tMaybe you want to add an 'i' extension to catch this case.\n",
04270 bc->dad, ch->context, bc->port);
04271
04272 if (bc->nt)
04273 hanguptone_indicate(ch);
04274 ch->state = MISDN_EXTCANTMATCH;
04275 bc->out_cause = AST_CAUSE_UNALLOCATED;
04276
04277 misdn_lib_send_event(bc, EVENT_DISCONNECT);
04278 break;
04279 }
04280
04281 if (ch->overlap_dial) {
04282 ast_mutex_lock(&ch->overlap_tv_lock);
04283 ch->overlap_tv = ast_tvnow();
04284 ast_mutex_unlock(&ch->overlap_tv_lock);
04285 if (ch->overlap_dial_task == -1) {
04286 ch->overlap_dial_task =
04287 misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch);
04288 }
04289 break;
04290 }
04291
04292 if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
04293
04294 ch->state = MISDN_DIALING;
04295 start_pbx(ch, bc, ch->ast);
04296 }
04297 } else {
04298
04299 struct ast_frame fr;
04300 int digits;
04301
04302 memset(&fr, 0, sizeof(fr));
04303 fr.frametype = AST_FRAME_DTMF;
04304 fr.subclass = bc->info_dad[0] ;
04305 fr.src = NULL;
04306 fr.data = NULL;
04307 fr.datalen = 0;
04308 fr.samples = 0;
04309 fr.mallocd = 0;
04310 fr.offset = 0;
04311 fr.delivery = ast_tv(0,0);
04312
04313 misdn_cfg_get(0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(int));
04314 if (ch->state != MISDN_CONNECTED ) {
04315 if (digits) {
04316 strncat(bc->dad, bc->info_dad, sizeof(bc->dad) - strlen(bc->dad) - 1);
04317 ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten));
04318 ast_cdr_update(ch->ast);
04319 }
04320
04321 ast_queue_frame(ch->ast, &fr);
04322 }
04323 }
04324 }
04325 break;
04326 case EVENT_SETUP:
04327 {
04328 struct chan_list *ch = find_chan_by_bc(cl_te, bc);
04329 struct ast_channel *chan;
04330 int exceed;
04331 int pres, screen;
04332 int ai;
04333 int im;
04334
04335 if (ch) {
04336 switch (ch->state) {
04337 case MISDN_NOTHING:
04338 ch = NULL;
04339 break;
04340 default:
04341 chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n");
04342 return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE;
04343 }
04344 }
04345
04346 msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad);
04347 if (!bc->nt && ! msn_valid) {
04348 chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n");
04349 return RESPONSE_IGNORE_SETUP;
04350 }
04351
04352 if (bc->cw) {
04353 int cause;
04354 chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n");
04355 misdn_cfg_get(bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause));
04356 bc->out_cause = cause ? cause : AST_CAUSE_NORMAL_CLEARING;
04357 return RESPONSE_RELEASE_SETUP;
04358 }
04359
04360 print_bearer(bc);
04361
04362 ch = init_chan_list(ORG_MISDN);
04363
04364 if (!ch) {
04365 chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n");
04366 return 0;
04367 }
04368
04369 ch->bc = bc;
04370 ch->l3id = bc->l3_id;
04371 ch->addr = bc->addr;
04372 ch->originator = ORG_MISDN;
04373
04374 chan = misdn_new(ch, AST_STATE_RESERVED, bc->dad, bc->oad, AST_FORMAT_ALAW, bc->port, bc->channel);
04375 if (!chan) {
04376 free(ch);
04377 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
04378 ast_log(LOG_ERROR, "cb_events: misdn_new failed !\n");
04379 return 0;
04380 }
04381
04382 ch->ast = chan;
04383
04384 if ((exceed = add_in_calls(bc->port))) {
04385 char tmp[16];
04386 snprintf(tmp, sizeof(tmp), "%d", exceed);
04387 pbx_builtin_setvar_helper(chan, "MAX_OVERFLOW", tmp);
04388 }
04389
04390 read_config(ch, ORG_MISDN);
04391
04392 export_ch(chan, bc, ch);
04393
04394 ch->ast->rings = 1;
04395 ast_setstate(ch->ast, AST_STATE_RINGING);
04396
04397 switch (bc->pres) {
04398 case 1:
04399 pres = AST_PRES_RESTRICTED;
04400 chan_misdn_log(2, bc->port, " --> PRES: Restricted (1)\n");
04401 break;
04402 case 2:
04403 pres = AST_PRES_UNAVAILABLE;
04404 chan_misdn_log(2, bc->port, " --> PRES: Unavailable (2)\n");
04405 break;
04406 default:
04407 pres = AST_PRES_ALLOWED;
04408 chan_misdn_log(2, bc->port, " --> PRES: Allowed (%d)\n", bc->pres);
04409 break;
04410 }
04411
04412 switch (bc->screen) {
04413 default:
04414 case 0:
04415 screen = AST_PRES_USER_NUMBER_UNSCREENED;
04416 chan_misdn_log(2, bc->port, " --> SCREEN: Unscreened (%d)\n", bc->screen);
04417 break;
04418 case 1:
04419 screen = AST_PRES_USER_NUMBER_PASSED_SCREEN;
04420 chan_misdn_log(2, bc->port, " --> SCREEN: Passed screen (1)\n");
04421 break;
04422 case 2:
04423 screen = AST_PRES_USER_NUMBER_FAILED_SCREEN;
04424 chan_misdn_log(2, bc->port, " --> SCREEN: failed screen (2)\n");
04425 break;
04426 case 3:
04427 screen = AST_PRES_NETWORK_NUMBER;
04428 chan_misdn_log(2, bc->port, " --> SCREEN: Network Number (3)\n");
04429 break;
04430 }
04431
04432 chan->cid.cid_pres = pres | screen;
04433
04434 pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability));
04435 chan->transfercapability = bc->capability;
04436
04437 switch (bc->capability) {
04438 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
04439 pbx_builtin_setvar_helper(chan, "CALLTYPE", "DIGITAL");
04440 break;
04441 default:
04442 pbx_builtin_setvar_helper(chan, "CALLTYPE", "SPEECH");
04443 }
04444
04445
04446 cl_queue_chan(&cl_te, ch);
04447
04448 if (!strstr(ch->allowed_bearers, "all")) {
04449 int i;
04450
04451 for (i = 0; i < ARRAY_LEN(allowed_bearers_array); ++i) {
04452 if (allowed_bearers_array[i].cap == bc->capability) {
04453 if (strstr(ch->allowed_bearers, allowed_bearers_array[i].name)) {
04454
04455 if (allowed_bearers_array[i].deprecated) {
04456 chan_misdn_log(0, bc->port, "%s in allowed_bearers list is deprecated\n",
04457 allowed_bearers_array[i].name);
04458 }
04459 break;
04460 }
04461 }
04462 }
04463 if (i == ARRAY_LEN(allowed_bearers_array)) {
04464
04465 chan_misdn_log(0, bc->port, "Bearer capability not allowed: %s(%d)\n",
04466 bearer2str(bc->capability), bc->capability);
04467 bc->out_cause = AST_CAUSE_INCOMPATIBLE_DESTINATION;
04468
04469 ch->state = MISDN_EXTCANTMATCH;
04470 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
04471 return RESPONSE_OK;
04472 }
04473 }
04474
04475
04476 if (!strcmp(chan->exten, ast_pickup_ext())) {
04477 if (!ch->noautorespond_on_setup) {
04478 int ret;
04479 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
04480 } else {
04481 ch->state = MISDN_INCOMING_SETUP;
04482 }
04483 if (ast_pickup_call(chan)) {
04484 hangup_chan(ch, bc);
04485 } else {
04486 ch->state = MISDN_CALLING_ACKNOWLEDGE;
04487 ast_setstate(chan, AST_STATE_DOWN);
04488 hangup_chan(ch, bc);
04489 ch->ast = NULL;
04490 break;
04491 }
04492 }
04493
04494
04495
04496
04497
04498 misdn_cfg_get(bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai));
04499 if (ai) {
04500 do_immediate_setup(bc, ch, chan);
04501 break;
04502 }
04503
04504
04505 misdn_cfg_get(bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im));
04506 if (im && ast_strlen_zero(bc->dad)) {
04507 do_immediate_setup(bc, ch, chan);
04508 break;
04509 }
04510
04511 chan_misdn_log(5, bc->port, "CONTEXT:%s\n", ch->context);
04512 if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
04513 if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) {
04514 ast_log(LOG_WARNING,
04515 "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n",
04516 bc->dad, ch->context, bc->port);
04517 strcpy(ch->ast->exten, "i");
04518 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE);
04519 ch->state = MISDN_DIALING;
04520 start_pbx(ch, bc, chan);
04521 break;
04522 }
04523
04524 ast_log(LOG_WARNING,
04525 "Extension '%s@%s' can never match. Disconnecting. port:%d\n"
04526 "\tMaybe you want to add an 'i' extension to catch this case.\n",
04527 bc->dad, ch->context, bc->port);
04528 if (bc->nt)
04529 hanguptone_indicate(ch);
04530
04531 ch->state = MISDN_EXTCANTMATCH;
04532 bc->out_cause = AST_CAUSE_UNALLOCATED;
04533
04534 if (bc->nt)
04535 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
04536 else
04537 misdn_lib_send_event(bc, EVENT_RELEASE );
04538
04539 break;
04540 }
04541
04542
04543
04544
04545 if (bc->sending_complete || (!bc->nt && !misdn_lib_is_ptp(bc->port))) {
04546 if (!ch->noautorespond_on_setup) {
04547 ch->state=MISDN_DIALING;
04548 misdn_lib_send_event(bc, EVENT_PROCEEDING );
04549 } else {
04550 ch->state = MISDN_INCOMING_SETUP;
04551 }
04552 start_pbx(ch, bc, chan);
04553 break;
04554 }
04555
04556
04557
04558
04559
04560
04561
04562 if (ch->overlap_dial && bc->nt && !bc->dad[0] ) {
04563 wait_for_digits(ch, bc, chan);
04564 break;
04565 }
04566
04567
04568
04569
04570
04571 if (ch->overlap_dial) {
04572 ast_mutex_lock(&ch->overlap_tv_lock);
04573 ch->overlap_tv = ast_tvnow();
04574 ast_mutex_unlock(&ch->overlap_tv_lock);
04575
04576 wait_for_digits(ch, bc, chan);
04577 if (ch->overlap_dial_task == -1)
04578 ch->overlap_dial_task =
04579 misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch);
04580
04581 break;
04582 }
04583
04584
04585
04586
04587 if (!ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
04588 wait_for_digits(ch, bc, chan);
04589 break;
04590 }
04591
04592
04593
04594
04595 if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
04596 if (bc->need_more_infos)
04597 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
04598 else
04599 misdn_lib_send_event(bc, EVENT_PROCEEDING);
04600
04601 ch->state = MISDN_DIALING;
04602 start_pbx(ch, bc, chan);
04603 break;
04604 }
04605 }
04606 break;
04607
04608 case EVENT_SETUP_ACKNOWLEDGE:
04609 {
04610 ch->state = MISDN_CALLING_ACKNOWLEDGE;
04611
04612 if (bc->channel)
04613 update_name(ch->ast,bc->port,bc->channel);
04614
04615 if (!ast_strlen_zero(bc->infos_pending)) {
04616
04617 strncat(bc->dad, bc->infos_pending, sizeof(bc->dad) - strlen(bc->dad) - 1);
04618
04619 if (!ch->ast)
04620 break;
04621 ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten));
04622 ast_copy_string(bc->info_dad, bc->infos_pending, sizeof(bc->info_dad));
04623 ast_copy_string(bc->infos_pending, "", sizeof(bc->infos_pending));
04624
04625 misdn_lib_send_event(bc, EVENT_INFORMATION);
04626 }
04627 }
04628 break;
04629 case EVENT_PROCEEDING:
04630 {
04631 if (bc->channel)
04632 update_name(ch->ast, bc->port, bc->channel);
04633
04634 if (misdn_cap_is_speech(bc->capability) &&
04635 misdn_inband_avail(bc) ) {
04636 start_bc_tones(ch);
04637 }
04638
04639 ch->state = MISDN_PROCEEDING;
04640
04641 if (!ch->ast)
04642 break;
04643
04644 ast_queue_control(ch->ast, AST_CONTROL_PROCEEDING);
04645 }
04646 break;
04647 case EVENT_PROGRESS:
04648 if (bc->channel)
04649 update_name(ch->ast, bc->port, bc->channel);
04650
04651 if (!bc->nt ) {
04652 if ( misdn_cap_is_speech(bc->capability) &&
04653 misdn_inband_avail(bc)
04654 ) {
04655 start_bc_tones(ch);
04656 }
04657
04658 ch->state = MISDN_PROGRESS;
04659
04660 if (!ch->ast)
04661 break;
04662 ast_queue_control(ch->ast, AST_CONTROL_PROGRESS);
04663 }
04664 break;
04665
04666
04667 case EVENT_ALERTING:
04668 {
04669 if (bc->channel)
04670 update_name(ch->ast, bc->port, bc->channel);
04671
04672 ch->state = MISDN_ALERTING;
04673
04674 if (!ch->ast)
04675 break;
04676
04677 ast_queue_control(ch->ast, AST_CONTROL_RINGING);
04678 ast_setstate(ch->ast, AST_STATE_RINGING);
04679
04680 cb_log(7, bc->port, " --> Set State Ringing\n");
04681
04682 if (misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) {
04683 cb_log(1, bc->port, "Starting Tones, we have inband Data\n");
04684 start_bc_tones(ch);
04685 } else {
04686 cb_log(3, bc->port, " --> We have no inband Data, the other end must create ringing\n");
04687 if (ch->far_alerting) {
04688 cb_log(1, bc->port, " --> The other end can not do ringing eh ?.. we must do all ourself..");
04689 start_bc_tones(ch);
04690
04691 }
04692 }
04693 }
04694 break;
04695 case EVENT_CONNECT:
04696 {
04697 struct ast_channel *bridged;
04698
04699
04700 misdn_lib_send_event(bc, EVENT_CONNECT_ACKNOWLEDGE);
04701
04702 if (!ch->ast)
04703 break;
04704
04705 bridged = ast_bridged_channel(ch->ast);
04706 stop_indicate(ch);
04707
04708 if (bridged && !strcasecmp(bridged->tech->type, "mISDN")) {
04709 struct chan_list *bridged_ch = MISDN_ASTERISK_TECH_PVT(bridged);
04710
04711 chan_misdn_log(1, bc->port, " --> copying cpndialplan:%d and cad:%s to the A-Channel\n", bc->cpnnumplan, bc->cad);
04712 if (bridged_ch) {
04713 bridged_ch->bc->cpnnumplan = bc->cpnnumplan;
04714 ast_copy_string(bridged_ch->bc->cad, bc->cad, sizeof(bridged_ch->bc->cad));
04715 }
04716 }
04717 }
04718 ch->l3id=bc->l3_id;
04719 ch->addr=bc->addr;
04720
04721 start_bc_tones(ch);
04722
04723 ch->state = MISDN_CONNECTED;
04724
04725 ast_queue_control(ch->ast, AST_CONTROL_ANSWER);
04726 break;
04727 case EVENT_CONNECT_ACKNOWLEDGE:
04728 {
04729 ch->l3id = bc->l3_id;
04730 ch->addr = bc->addr;
04731
04732 start_bc_tones(ch);
04733
04734 ch->state = MISDN_CONNECTED;
04735 }
04736 break;
04737 case EVENT_DISCONNECT:
04738
04739 if (ch) {
04740 chan_misdn_log(3, bc->port, " --> org:%d nt:%d, inbandavail:%d state:%d\n", ch->originator, bc->nt, misdn_inband_avail(bc), ch->state);
04741 if (ch->originator == ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) {
04742
04743
04744
04745
04746
04747 chan_misdn_log(1, bc->port, " --> Inband Info Avail, not sending RELEASE\n");
04748
04749 ch->state = MISDN_DISCONNECTED;
04750 start_bc_tones(ch);
04751
04752 if (ch->ast) {
04753 ch->ast->hangupcause = bc->cause;
04754 if (bc->cause == AST_CAUSE_USER_BUSY)
04755 ast_queue_control(ch->ast, AST_CONTROL_BUSY);
04756 }
04757 ch->need_busy = 0;
04758 break;
04759 }
04760
04761 bc->need_disconnect = 0;
04762 stop_bc_tones(ch);
04763
04764
04765 held_ch = find_hold_call(cl_te, bc);
04766 if (!held_ch || !ch->ast || misdn_attempt_transfer(ch, held_ch)) {
04767 hangup_chan(ch, bc);
04768 }
04769 } else {
04770 held_ch = find_hold_call_l3(cl_te, bc->l3_id);
04771 if (held_ch && held_ch->hold.state == MISDN_HOLD_ACTIVE) {
04772 bc->need_disconnect = 0;
04773
04774 #if defined(TRANSFER_ON_HELD_CALL_HANGUP)
04775
04776
04777
04778
04779
04780 ch = find_hold_active_call(cl_te, bc);
04781 if (!ch || misdn_attempt_transfer(ch, held_ch)) {
04782 held_ch->hold.state = MISDN_HOLD_DISCONNECT;
04783 hangup_chan(held_ch, bc);
04784 }
04785 #else
04786 hangup_chan(held_ch, bc);
04787 #endif
04788 }
04789 }
04790 bc->out_cause = -1;
04791 if (bc->need_release)
04792 misdn_lib_send_event(bc, EVENT_RELEASE);
04793 break;
04794
04795 case EVENT_RELEASE:
04796 if (!ch) {
04797 ch = find_hold_call_l3(cl_te, bc->l3_id);
04798 if (!ch) {
04799 chan_misdn_log(1, bc->port,
04800 " --> no Ch, so we've already released. (%s)\n",
04801 manager_isdn_get_info(event));
04802 return -1;
04803 }
04804 }
04805
04806 bc->need_disconnect = 0;
04807 bc->need_release = 0;
04808
04809 hangup_chan(ch, bc);
04810 release_chan(ch, bc);
04811 break;
04812 case EVENT_RELEASE_COMPLETE:
04813 if (!ch) {
04814 ch = find_hold_call_l3(cl_te, bc->l3_id);
04815 if (!ch) {
04816 chan_misdn_log(1, bc->port,
04817 " --> no Ch, so we've already released. (%s)\n",
04818 manager_isdn_get_info(event));
04819 break;
04820 }
04821 }
04822
04823 bc->need_disconnect = 0;
04824 bc->need_release = 0;
04825 bc->need_release_complete = 0;
04826
04827 stop_bc_tones(ch);
04828 hangup_chan(ch, bc);
04829 release_chan(ch, bc);
04830 break;
04831 case EVENT_BCHAN_ERROR:
04832 case EVENT_CLEANUP:
04833 {
04834 stop_bc_tones(ch);
04835
04836 switch (ch->state) {
04837 case MISDN_CALLING:
04838 bc->cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
04839 break;
04840 default:
04841 break;
04842 }
04843
04844 hangup_chan(ch, bc);
04845 release_chan(ch, bc);
04846 }
04847 break;
04848
04849 case EVENT_TONE_GENERATE:
04850 {
04851 int tone_len = bc->tone_cnt;
04852 struct ast_channel *ast = ch->ast;
04853 void *tmp;
04854 int res;
04855 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
04856
04857 chan_misdn_log(9, bc->port, "TONE_GEN: len:%d\n", tone_len);
04858
04859 if (!ast)
04860 break;
04861
04862 if (!ast->generator)
04863 break;
04864
04865 tmp = ast->generatordata;
04866 ast->generatordata = NULL;
04867 generate = ast->generator->generate;
04868
04869 if (tone_len < 0 || tone_len > 512 ) {
04870 ast_log(LOG_NOTICE, "TONE_GEN: len was %d, set to 128\n", tone_len);
04871 tone_len = 128;
04872 }
04873
04874 res = generate(ast, tmp, tone_len, tone_len);
04875 ast->generatordata = tmp;
04876
04877 if (res) {
04878 ast_log(LOG_WARNING, "Auto-deactivating generator\n");
04879 ast_deactivate_generator(ast);
04880 } else {
04881 bc->tone_cnt = 0;
04882 }
04883 }
04884 break;
04885
04886 case EVENT_BCHAN_DATA:
04887 {
04888 if (!misdn_cap_is_speech(ch->bc->capability)) {
04889 struct ast_frame frame;
04890
04891 memset(&frame, 0, sizeof(frame));
04892 frame.frametype = AST_FRAME_VOICE;
04893 frame.subclass = AST_FORMAT_ALAW;
04894 frame.datalen = bc->bframe_len;
04895 frame.samples = bc->bframe_len;
04896 frame.mallocd = 0;
04897 frame.offset = 0;
04898 frame.delivery = ast_tv(0,0);
04899 frame.src = NULL;
04900 frame.data = bc->bframe;
04901
04902 if (ch->ast)
04903 ast_queue_frame(ch->ast, &frame);
04904 } else {
04905 struct pollfd pfd = { .fd = ch->pipe[1], .events = POLLOUT };
04906 int t;
04907
04908 t = ast_poll(&pfd, 1, 0);
04909
04910 if (t < 0) {
04911 chan_misdn_log(-1, bc->port, "poll() error (err=%s)\n", strerror(errno));
04912 break;
04913 }
04914
04915 if (!t) {
04916 chan_misdn_log(9, bc->port, "poll() timed out\n");
04917 break;
04918 }
04919
04920 if (pfd.revents & POLLOUT) {
04921 chan_misdn_log(9, bc->port, "writing %d bytes to asterisk\n", bc->bframe_len);
04922 if (write(ch->pipe[1], bc->bframe, bc->bframe_len) <= 0) {
04923 chan_misdn_log(0, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n", strerror(errno));
04924
04925 stop_bc_tones(ch);
04926 hangup_chan(ch, bc);
04927 release_chan(ch, bc);
04928 }
04929 } else {
04930 chan_misdn_log(1, bc->port, "Write Pipe full!\n");
04931 }
04932 }
04933 }
04934 break;
04935 case EVENT_TIMEOUT:
04936 {
04937 if (ch && bc)
04938 chan_misdn_log(1, bc->port, "--> state: %s\n", misdn_get_ch_state(ch));
04939
04940 switch (ch->state) {
04941 case MISDN_DIALING:
04942 case MISDN_PROGRESS:
04943 if (bc->nt && !ch->nttimeout)
04944 break;
04945
04946 case MISDN_CALLING:
04947 case MISDN_ALERTING:
04948 case MISDN_PROCEEDING:
04949 case MISDN_CALLING_ACKNOWLEDGE:
04950 if (bc->nt) {
04951 bc->progress_indicator = INFO_PI_INBAND_AVAILABLE;
04952 hanguptone_indicate(ch);
04953 }
04954
04955 bc->out_cause = AST_CAUSE_UNALLOCATED;
04956 misdn_lib_send_event(bc, EVENT_DISCONNECT);
04957 break;
04958
04959 case MISDN_WAITING4DIGS:
04960 if (bc->nt) {
04961 bc->progress_indicator = INFO_PI_INBAND_AVAILABLE;
04962 bc->out_cause = AST_CAUSE_UNALLOCATED;
04963 hanguptone_indicate(ch);
04964 misdn_lib_send_event(bc, EVENT_DISCONNECT);
04965 } else {
04966 bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
04967 misdn_lib_send_event(bc, EVENT_RELEASE);
04968 }
04969
04970 break;
04971
04972 case MISDN_CLEANING:
04973 chan_misdn_log(1,bc->port," --> in state cleaning .. so ignoring, the stack should clean it for us\n");
04974 break;
04975
04976 default:
04977 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
04978 }
04979 }
04980 break;
04981
04982
04983
04984
04985
04986 case EVENT_RETRIEVE:
04987 if (!ch) {
04988 chan_misdn_log(4, bc->port, " --> no CH, searching for held call\n");
04989 ch = find_hold_call_l3(cl_te, bc->l3_id);
04990 if (!ch || ch->hold.state != MISDN_HOLD_ACTIVE) {
04991 ast_log(LOG_WARNING, "No held call found, cannot Retrieve\n");
04992 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
04993 break;
04994 }
04995 }
04996
04997
04998 ch->bc = bc;
04999
05000 ch->hold.state = MISDN_HOLD_IDLE;
05001 ch->hold.port = 0;
05002 ch->hold.channel = 0;
05003
05004 ast_queue_control(ch->ast, AST_CONTROL_UNHOLD);
05005
05006 if (misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0) {
05007 chan_misdn_log(4, bc->port, " --> RETRIEVE_ACK failed\n");
05008 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
05009 }
05010 break;
05011
05012 case EVENT_HOLD:
05013 {
05014 int hold_allowed;
05015 struct ast_channel *bridged;
05016
05017 misdn_cfg_get(bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(int));
05018
05019 if (!hold_allowed) {
05020
05021 chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n");
05022 misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
05023 break;
05024 }
05025
05026 bridged = ast_bridged_channel(ch->ast);
05027 if (bridged) {
05028 chan_misdn_log(2, bc->port, "Bridge Partner is of type: %s\n", bridged->tech->type);
05029 ch->l3id = bc->l3_id;
05030
05031
05032 ch->bc = NULL;
05033 ch->hold.state = MISDN_HOLD_ACTIVE;
05034 ch->hold.port = bc->port;
05035 ch->hold.channel = bc->channel;
05036
05037 ast_queue_control(ch->ast, AST_CONTROL_HOLD);
05038
05039 misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE);
05040 } else {
05041 misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
05042 chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n");
05043 }
05044 }
05045 break;
05046
05047 case EVENT_FACILITY:
05048 if (!ch) {
05049
05050 chan_misdn_log(-1, bc->port, "Got EVENT_FACILITY but we don't have a ch!\n");
05051 break;
05052 }
05053
05054 print_facility(&(bc->fac_in), bc);
05055
05056 switch (bc->fac_in.Function) {
05057 case Fac_CD:
05058 {
05059 struct ast_channel *bridged = ast_bridged_channel(ch->ast);
05060 struct chan_list *ch_br;
05061 if (bridged && MISDN_ASTERISK_TECH_PVT(bridged)) {
05062 ch_br = MISDN_ASTERISK_TECH_PVT(bridged);
05063
05064 if (ch_br->bc) {
05065 if (ast_exists_extension(bridged, ch->context, (char *)bc->fac_in.u.CDeflection.DeflectedToNumber, 1, bc->oad)) {
05066 ch_br->state = MISDN_DIALING;
05067 if (pbx_start_chan(ch_br) < 0) {
05068 chan_misdn_log(-1, ch_br->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n");
05069 }
05070 }
05071 }
05072 }
05073 misdn_lib_send_event(bc, EVENT_DISCONNECT);
05074 }
05075 break;
05076 case Fac_AOCDCurrency:
05077 {
05078 bc->AOCDtype = Fac_AOCDCurrency;
05079 memcpy(&(bc->AOCD.currency), &(bc->fac_in.u.AOCDcur), sizeof(struct FacAOCDCurrency));
05080 export_aoc_vars(ch->originator, ch->ast, bc);
05081 }
05082 break;
05083 case Fac_AOCDChargingUnit:
05084 {
05085 bc->AOCDtype = Fac_AOCDChargingUnit;
05086 memcpy(&(bc->AOCD.chargingUnit), &(bc->fac_in.u.AOCDchu), sizeof(struct FacAOCDChargingUnit));
05087 export_aoc_vars(ch->originator, ch->ast, bc);
05088 }
05089 break;
05090 default:
05091 chan_misdn_log(0, bc->port," --> not yet handled: facility type:%d\n", bc->fac_in.Function);
05092 }
05093
05094 break;
05095
05096 case EVENT_RESTART:
05097
05098 if (!bc->dummy) {
05099 stop_bc_tones(ch);
05100 release_chan(ch, bc);
05101 }
05102 break;
05103
05104 default:
05105 chan_misdn_log(1, 0, "Got Unknown Event\n");
05106 break;
05107 }
05108
05109 return RESPONSE_OK;
05110 }
05111
05112
05113
05114
05115
05116
05117
05118
05119
05120
05121
05122
05123 static int unload_module(void)
05124 {
05125
05126 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
05127
05128 misdn_tasks_destroy();
05129
05130 if (!g_config_initialized)
05131 return 0;
05132
05133 ast_cli_unregister_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry));
05134
05135
05136 ast_unregister_application("misdn_set_opt");
05137 ast_unregister_application("misdn_facility");
05138 ast_unregister_application("misdn_check_l2l1");
05139
05140 ast_channel_unregister(&misdn_tech);
05141
05142 free_robin_list();
05143 misdn_cfg_destroy();
05144 misdn_lib_destroy();
05145
05146 free(misdn_out_calls);
05147 free(misdn_in_calls);
05148 free(misdn_debug_only);
05149 free(misdn_ports);
05150 free(misdn_debug);
05151
05152 return 0;
05153 }
05154
05155 static int load_module(void)
05156 {
05157 int i, port;
05158 int ntflags = 0, ntkc = 0;
05159 char ports[256] = "";
05160 char tempbuf[BUFFERSIZE + 1];
05161 char ntfile[BUFFERSIZE + 1];
05162 struct misdn_lib_iface iface = {
05163 .cb_event = cb_events,
05164 .cb_log = chan_misdn_log,
05165 .cb_jb_empty = chan_misdn_jb_empty,
05166 };
05167
05168 max_ports = misdn_lib_maxports_get();
05169
05170 if (max_ports <= 0) {
05171 ast_log(LOG_ERROR, "Unable to initialize mISDN\n");
05172 return AST_MODULE_LOAD_DECLINE;
05173 }
05174
05175 if (misdn_cfg_init(max_ports)) {
05176 ast_log(LOG_ERROR, "Unable to initialize misdn_config.\n");
05177 return AST_MODULE_LOAD_DECLINE;
05178 }
05179 g_config_initialized = 1;
05180
05181 misdn_debug = (int *) malloc(sizeof(int) * (max_ports + 1));
05182 if (!misdn_debug) {
05183 ast_log(LOG_ERROR, "Out of memory for misdn_debug\n");
05184 return AST_MODULE_LOAD_DECLINE;
05185 }
05186 misdn_ports = (int *) malloc(sizeof(int) * (max_ports + 1));
05187 if (!misdn_ports) {
05188 free(misdn_debug);
05189 ast_log(LOG_ERROR, "Out of memory for misdn_ports\n");
05190 return AST_MODULE_LOAD_DECLINE;
05191 }
05192 misdn_cfg_get(0, MISDN_GEN_DEBUG, &misdn_debug[0], sizeof(int));
05193 for (i = 1; i <= max_ports; i++) {
05194 misdn_debug[i] = misdn_debug[0];
05195 misdn_ports[i] = i;
05196 }
05197 *misdn_ports = 0;
05198 misdn_debug_only = (int *) calloc(max_ports + 1, sizeof(int));
05199 if (!misdn_debug_only) {
05200 free(misdn_ports);
05201 free(misdn_debug);
05202 ast_log(LOG_ERROR, "Out of memory for misdn_debug_only\n");
05203 return AST_MODULE_LOAD_DECLINE;
05204 }
05205
05206 misdn_cfg_get(0, MISDN_GEN_TRACEFILE, tempbuf, BUFFERSIZE);
05207 if (!ast_strlen_zero(tempbuf))
05208 tracing = 1;
05209
05210 misdn_in_calls = (int *) malloc(sizeof(int) * (max_ports + 1));
05211 if (!misdn_in_calls) {
05212 free(misdn_debug_only);
05213 free(misdn_ports);
05214 free(misdn_debug);
05215 ast_log(LOG_ERROR, "Out of memory for misdn_in_calls\n");
05216 return AST_MODULE_LOAD_DECLINE;
05217 }
05218 misdn_out_calls = (int *) malloc(sizeof(int) * (max_ports + 1));
05219 if (!misdn_out_calls) {
05220 free(misdn_in_calls);
05221 free(misdn_debug_only);
05222 free(misdn_ports);
05223 free(misdn_debug);
05224 ast_log(LOG_ERROR, "Out of memory for misdn_out_calls\n");
05225 return AST_MODULE_LOAD_DECLINE;
05226 }
05227
05228 for (i = 1; i <= max_ports; i++) {
05229 misdn_in_calls[i] = 0;
05230 misdn_out_calls[i] = 0;
05231 }
05232
05233 ast_mutex_init(&cl_te_lock);
05234 ast_mutex_init(&release_lock);
05235
05236 misdn_cfg_update_ptp();
05237 misdn_cfg_get_ports_string(ports);
05238
05239 if (!ast_strlen_zero(ports))
05240 chan_misdn_log(0, 0, "Got: %s from get_ports\n", ports);
05241 if (misdn_lib_init(ports, &iface, NULL))
05242 chan_misdn_log(0, 0, "No te ports initialized\n");
05243
05244 misdn_cfg_get(0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(int));
05245 misdn_cfg_get(0, MISDN_GEN_NTDEBUGFILE, &ntfile, BUFFERSIZE);
05246 misdn_lib_nt_debug_init(ntflags, ntfile);
05247
05248 misdn_cfg_get( 0, MISDN_GEN_NTKEEPCALLS, &ntkc, sizeof(int));
05249 misdn_lib_nt_keepcalls(ntkc);
05250
05251 if (ast_channel_register(&misdn_tech)) {
05252 ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type);
05253 unload_module();
05254 return -1;
05255 }
05256
05257 ast_cli_register_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry));
05258
05259 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
05260 "misdn_set_opt(:<opt><optarg>:<opt><optarg>...):\n"
05261 "Sets mISDN opts. and optargs\n"
05262 "\n"
05263 "The available options are:\n"
05264 " a - Have Asterisk detect DTMF tones on called channel\n"
05265 " c - Make crypted outgoing call, optarg is keyindex\n"
05266 " d - Send display text to called phone, text is the optarg\n"
05267 " e - Perform echo cancellation on this channel,\n"
05268 " takes taps as optarg (32,64,128,256)\n"
05269 " e! - Disable echo cancellation on this channel\n"
05270 " f - Enable fax detection\n"
05271 " h - Make digital outgoing call\n"
05272 " h1 - Make HDLC mode digital outgoing call\n"
05273 " i - Ignore detected DTMF tones, don't signal them to Asterisk,\n"
05274 " they will be transported inband.\n"
05275 " jb - Set jitter buffer length, optarg is length\n"
05276 " jt - Set jitter buffer upper threshold, optarg is threshold\n"
05277 " jn - Disable jitter buffer\n"
05278 " n - Disable mISDN DSP on channel.\n"
05279 " Disables: echo cancel, DTMF detection, and volume control.\n"
05280 " p - Caller ID presentation,\n"
05281 " optarg is either 'allowed' or 'restricted'\n"
05282 " s - Send Non-inband DTMF as inband\n"
05283 " vr - Rx gain control, optarg is gain\n"
05284 " vt - Tx gain control, optarg is gain\n"
05285 );
05286
05287
05288 ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility",
05289 "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n"
05290 "Sends the Facility Message FACILITY_TYPE with \n"
05291 "the given Arguments to the current ISDN Channel\n"
05292 "Supported Facilities are:\n"
05293 "\n"
05294 "type=calldeflect args=Nr where to deflect\n"
05295 );
05296
05297
05298 ast_register_application("misdn_check_l2l1", misdn_check_l2l1, "misdn_check_l2l1",
05299 "misdn_check_l2l1(<port>||g:<groupname>,timeout)"
05300 "Checks if the L2 and L1 are up on either the given <port> or\n"
05301 "on the ports in the group with <groupname>\n"
05302 "If the L1/L2 are down, check_l2l1 gets up the L1/L2 and waits\n"
05303 "for <timeout> seconds that this happens. Otherwise, nothing happens\n"
05304 "\n"
05305 "This application, ensures the L1/L2 state of the Ports in a group\n"
05306 "it is intended to make the pmp_l1_check option redundant and to\n"
05307 "fix a buggy switch config from your provider\n"
05308 "\n"
05309 "a sample dialplan would look like:\n\n"
05310 "exten => _X.,1,misdn_check_l2l1(g:out|2)\n"
05311 "exten => _X.,n,dial(mISDN/g:out/${EXTEN})\n"
05312 "\n"
05313 );
05314
05315
05316 misdn_cfg_get(0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
05317
05318
05319
05320 for (port = misdn_cfg_get_next_port(0); port >= 0; port = misdn_cfg_get_next_port(port)) {
05321 int l1timeout;
05322 misdn_cfg_get(port, MISDN_CFG_L1_TIMEOUT, &l1timeout, sizeof(l1timeout));
05323 if (l1timeout) {
05324 chan_misdn_log(4, 0, "Adding L1watcher task: port:%d timeout:%ds\n", port, l1timeout);
05325 misdn_tasks_add(l1timeout * 1000, misdn_l1_task, &misdn_ports[port]);
05326 }
05327 }
05328
05329 chan_misdn_log(0, 0, "-- mISDN Channel Driver Registered --\n");
05330
05331 return 0;
05332 }
05333
05334
05335
05336 static int reload(void)
05337 {
05338 reload_config();
05339
05340 return 0;
05341 }
05342
05343
05344
05345 static int misdn_facility_exec(struct ast_channel *chan, void *data)
05346 {
05347 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
05348 char *tok, *tokb;
05349
05350 chan_misdn_log(0, 0, "TYPE: %s\n", chan->tech->type);
05351
05352 if (strcasecmp(chan->tech->type, "mISDN")) {
05353 ast_log(LOG_WARNING, "misdn_facility makes only sense with chan_misdn channels!\n");
05354 return -1;
05355 }
05356
05357 if (ast_strlen_zero((char *)data)) {
05358 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n");
05359 return -1;
05360 }
05361
05362 tok = strtok_r((char*) data, "|", &tokb) ;
05363
05364 if (!tok) {
05365 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n");
05366 return -1;
05367 }
05368
05369 if (!strcasecmp(tok, "calldeflect")) {
05370 tok = strtok_r(NULL, "|", &tokb) ;
05371
05372 if (!tok) {
05373 ast_log(LOG_WARNING, "Facility: Call Defl Requires arguments\n");
05374 }
05375
05376 if (strlen(tok) >= sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber)) {
05377 ast_log(LOG_WARNING, "Facility: Number argument too long (up to 15 digits are allowed). Ignoring.\n");
05378 return 0;
05379 }
05380 ch->bc->fac_out.Function = Fac_CD;
05381 ast_copy_string((char *)ch->bc->fac_out.u.CDeflection.DeflectedToNumber, tok, sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber));
05382 misdn_lib_send_event(ch->bc, EVENT_FACILITY);
05383 } else {
05384 chan_misdn_log(1, ch->bc->port, "Unknown Facility: %s\n", tok);
05385 }
05386
05387 return 0;
05388 }
05389
05390 static int misdn_check_l2l1(struct ast_channel *chan, void *data)
05391 {
05392 char group[BUFFERSIZE + 1];
05393 char *port_str;
05394 int port = 0;
05395 int timeout;
05396 int dowait = 0;
05397 int port_up;
05398
05399 AST_DECLARE_APP_ARGS(args,
05400 AST_APP_ARG(grouppar);
05401 AST_APP_ARG(timeout);
05402 );
05403
05404 if (ast_strlen_zero((char *)data)) {
05405 ast_log(LOG_WARNING, "misdn_check_l2l1 Requires arguments\n");
05406 return -1;
05407 }
05408
05409 AST_STANDARD_APP_ARGS(args, data);
05410
05411 if (args.argc != 2) {
05412 ast_log(LOG_WARNING, "Wrong argument count\n");
05413 return 0;
05414 }
05415
05416
05417 timeout = atoi(args.timeout);
05418 port_str = args.grouppar;
05419
05420 if (port_str[0] == 'g' && port_str[1] == ':' ) {
05421
05422 port_str += 2;
05423 ast_copy_string(group, port_str, sizeof(group));
05424 chan_misdn_log(2, 0, "Checking Ports in group: %s\n", group);
05425
05426 for ( port = misdn_cfg_get_next_port(port);
05427 port > 0;
05428 port = misdn_cfg_get_next_port(port)) {
05429 char cfg_group[BUFFERSIZE + 1];
05430
05431 chan_misdn_log(2, 0, "trying port %d\n", port);
05432
05433 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE);
05434
05435 if (!strcasecmp(cfg_group, group)) {
05436 port_up = misdn_lib_port_up(port, 1);
05437
05438 if (!port_up) {
05439 chan_misdn_log(2, 0, " --> port '%d'\n", port);
05440 misdn_lib_get_port_up(port);
05441 dowait = 1;
05442 }
05443 }
05444 }
05445
05446 } else {
05447 port = atoi(port_str);
05448 chan_misdn_log(2, 0, "Checking Port: %d\n",port);
05449 port_up = misdn_lib_port_up(port, 1);
05450 if (!port_up) {
05451 misdn_lib_get_port_up(port);
05452 dowait = 1;
05453 }
05454 }
05455
05456 if (dowait) {
05457 chan_misdn_log(2, 0, "Waiting for '%d' seconds\n", timeout);
05458 sleep(timeout);
05459 }
05460
05461 return 0;
05462 }
05463
05464 static int misdn_set_opt_exec(struct ast_channel *chan, void *data)
05465 {
05466 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
05467 char *tok, *tokb;
05468 int keyidx = 0;
05469 int rxgain = 0;
05470 int txgain = 0;
05471 int change_jitter = 0;
05472
05473 if (strcasecmp(chan->tech->type, "mISDN")) {
05474 ast_log(LOG_WARNING, "misdn_set_opt makes only sense with chan_misdn channels!\n");
05475 return -1;
05476 }
05477
05478 if (ast_strlen_zero((char *)data)) {
05479 ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n");
05480 return -1;
05481 }
05482
05483 for (tok = strtok_r((char*) data, ":", &tokb);
05484 tok;
05485 tok = strtok_r(NULL, ":", &tokb) ) {
05486 int neglect = 0;
05487
05488 if (tok[0] == '!' ) {
05489 neglect = 1;
05490 tok++;
05491 }
05492
05493 switch(tok[0]) {
05494
05495 case 'd' :
05496 ast_copy_string(ch->bc->display, ++tok, sizeof(ch->bc->display));
05497 chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n", ch->bc->display);
05498 break;
05499
05500 case 'n':
05501 chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n");
05502 ch->bc->nodsp = 1;
05503 break;
05504
05505 case 'j':
05506 chan_misdn_log(1, ch->bc->port, "SETOPT: jitter\n");
05507 tok++;
05508 change_jitter = 1;
05509
05510 switch ( tok[0] ) {
05511 case 'b':
05512 ch->jb_len = atoi(++tok);
05513 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d\n", ch->jb_len);
05514 break;
05515 case 't' :
05516 ch->jb_upper_threshold = atoi(++tok);
05517 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d\n", ch->jb_upper_threshold);
05518 break;
05519 case 'n':
05520 ch->bc->nojitter = 1;
05521 chan_misdn_log(1, ch->bc->port, " --> nojitter\n");
05522 break;
05523 default:
05524 ch->jb_len = 4000;
05525 ch->jb_upper_threshold = 0;
05526 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d (default)\n", ch->jb_len);
05527 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d (default)\n", ch->jb_upper_threshold);
05528 }
05529 break;
05530 case 'v':
05531 tok++;
05532
05533 switch (tok[0]) {
05534 case 'r' :
05535 rxgain = atoi(++tok);
05536 if (rxgain < -8)
05537 rxgain = -8;
05538 if (rxgain > 8)
05539 rxgain = 8;
05540 ch->bc->rxgain = rxgain;
05541 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", rxgain);
05542 break;
05543 case 't':
05544 txgain = atoi(++tok);
05545 if (txgain < -8)
05546 txgain = -8;
05547 if (txgain > 8)
05548 txgain = 8;
05549 ch->bc->txgain = txgain;
05550 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", txgain);
05551 break;
05552 }
05553 break;
05554
05555 case 'c':
05556 keyidx = atoi(++tok);
05557 {
05558 char keys[4096];
05559 char *key = NULL, *tmp = keys;
05560 int i;
05561 misdn_cfg_get(0, MISDN_GEN_CRYPT_KEYS, keys, sizeof(keys));
05562
05563 for (i = 0; i < keyidx; i++) {
05564 key = strsep(&tmp, ",");
05565 }
05566
05567 if (key) {
05568 ast_copy_string(ch->bc->crypt_key, key, sizeof(ch->bc->crypt_key));
05569 }
05570
05571 chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n", ch->bc->crypt_key);
05572 break;
05573 }
05574 case 'e':
05575 chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n");
05576
05577 if (neglect) {
05578 chan_misdn_log(1, ch->bc->port, " --> disabled\n");
05579 #ifdef MISDN_1_2
05580 *ch->bc->pipeline = 0;
05581 #else
05582 ch->bc->ec_enable = 0;
05583 #endif
05584 } else {
05585 #ifdef MISDN_1_2
05586 update_pipeline_config(ch->bc);
05587 #else
05588 ch->bc->ec_enable = 1;
05589 ch->bc->orig = ch->originator;
05590 tok++;
05591 if (*tok) {
05592 ch->bc->ec_deftaps = atoi(tok);
05593 }
05594 #endif
05595 }
05596
05597 break;
05598 case 'h':
05599 chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n");
05600
05601 if (strlen(tok) > 1 && tok[1] == '1') {
05602 chan_misdn_log(1, ch->bc->port, "SETOPT: HDLC \n");
05603 if (!ch->bc->hdlc) {
05604 ch->bc->hdlc = 1;
05605 }
05606 }
05607 ch->bc->capability = INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
05608 break;
05609
05610 case 's':
05611 chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n");
05612 ch->bc->send_dtmf = 1;
05613 break;
05614
05615 case 'f':
05616 chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n");
05617 ch->faxdetect = 1;
05618 misdn_cfg_get(ch->bc->port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout));
05619 break;
05620
05621 case 'a':
05622 chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n");
05623 ch->ast_dsp = 1;
05624 break;
05625
05626 case 'p':
05627 chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n", &tok[1]);
05628
05629 if (strstr(tok,"allowed")) {
05630 ch->bc->pres = 0;
05631 } else if (strstr(tok, "restricted")) {
05632 ch->bc->pres = 1;
05633 } else if (strstr(tok, "not_screened")) {
05634 chan_misdn_log(0, ch->bc->port, "SETOPT: callerpres: not_screened is deprecated\n");
05635 ch->bc->pres = 1;
05636 }
05637 break;
05638 case 'i' :
05639 chan_misdn_log(1, ch->bc->port, "Ignoring dtmf tones, just use them inband\n");
05640 ch->ignore_dtmf=1;
05641 break;
05642 default:
05643 break;
05644 }
05645 }
05646
05647 if (change_jitter)
05648 config_jitterbuffer(ch);
05649
05650 if (ch->faxdetect || ch->ast_dsp) {
05651 if (!ch->dsp)
05652 ch->dsp = ast_dsp_new();
05653 if (ch->dsp)
05654 ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT| DSP_FEATURE_FAX_DETECT);
05655 }
05656
05657 if (ch->ast_dsp) {
05658 chan_misdn_log(1, ch->bc->port, "SETOPT: with AST_DSP we deactivate mISDN_dsp\n");
05659 ch->bc->nodsp = 1;
05660 }
05661
05662 return 0;
05663 }
05664
05665
05666 int chan_misdn_jb_empty ( struct misdn_bchannel *bc, char *buf, int len)
05667 {
05668 struct chan_list *ch = find_chan_by_bc(cl_te, bc);
05669
05670 if (ch && ch->jb) {
05671 return misdn_jb_empty(ch->jb, buf, len);
05672 }
05673
05674 return -1;
05675 }
05676
05677
05678
05679
05680
05681
05682
05683
05684
05685 struct misdn_jb *misdn_jb_init(int size, int upper_threshold)
05686 {
05687 int i;
05688 struct misdn_jb *jb;
05689
05690 jb = malloc(sizeof(struct misdn_jb));
05691 if (!jb) {
05692 chan_misdn_log(-1, 0, "No free Mem for jb\n");
05693 return NULL;
05694 }
05695 jb->size = size;
05696 jb->upper_threshold = upper_threshold;
05697 jb->wp = 0;
05698 jb->rp = 0;
05699 jb->state_full = 0;
05700 jb->state_empty = 0;
05701 jb->bytes_wrote = 0;
05702 jb->samples = malloc(size * sizeof(char));
05703 if (!jb->samples) {
05704 free(jb);
05705 chan_misdn_log(-1, 0, "No free Mem for jb->samples\n");
05706 return NULL;
05707 }
05708
05709 jb->ok = malloc(size * sizeof(char));
05710 if (!jb->ok) {
05711 free(jb->samples);
05712 free(jb);
05713 chan_misdn_log(-1, 0, "No free Mem for jb->ok\n");
05714 return NULL;
05715 }
05716
05717 for (i = 0; i < size; i++)
05718 jb->ok[i] = 0;
05719
05720 ast_mutex_init(&jb->mutexjb);
05721
05722 return jb;
05723 }
05724
05725
05726 void misdn_jb_destroy(struct misdn_jb *jb)
05727 {
05728 ast_mutex_destroy(&jb->mutexjb);
05729
05730 free(jb->ok);
05731 free(jb->samples);
05732 free(jb);
05733 }
05734
05735
05736
05737 int misdn_jb_fill(struct misdn_jb *jb, const char *data, int len)
05738 {
05739 int i, j, rp, wp;
05740
05741 if (!jb || ! data)
05742 return 0;
05743
05744 ast_mutex_lock(&jb->mutexjb);
05745
05746 wp = jb->wp;
05747 rp = jb->rp;
05748
05749 for (i = 0; i < len; i++) {
05750 jb->samples[wp] = data[i];
05751 jb->ok[wp] = 1;
05752 wp = (wp != jb->size - 1) ? wp + 1 : 0;
05753
05754 if (wp == jb->rp)
05755 jb->state_full = 1;
05756 }
05757
05758 if (wp >= rp)
05759 jb->state_buffer = wp - rp;
05760 else
05761 jb->state_buffer = jb->size - rp + wp;
05762 chan_misdn_log(9, 0, "misdn_jb_fill: written:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb);
05763
05764 if (jb->state_full) {
05765 jb->wp = wp;
05766
05767 rp = wp;
05768 for (j = 0; j < jb->upper_threshold; j++)
05769 rp = (rp != 0) ? rp - 1 : jb->size - 1;
05770 jb->rp = rp;
05771 jb->state_full = 0;
05772 jb->state_empty = 1;
05773
05774 ast_mutex_unlock(&jb->mutexjb);
05775
05776 return -1;
05777 }
05778
05779 if (!jb->state_empty) {
05780 jb->bytes_wrote += len;
05781 if (jb->bytes_wrote >= jb->upper_threshold) {
05782 jb->state_empty = 1;
05783 jb->bytes_wrote = 0;
05784 }
05785 }
05786 jb->wp = wp;
05787
05788 ast_mutex_unlock(&jb->mutexjb);
05789
05790 return 0;
05791 }
05792
05793
05794
05795
05796 int misdn_jb_empty(struct misdn_jb *jb, char *data, int len)
05797 {
05798 int i, wp, rp, read = 0;
05799
05800 ast_mutex_lock(&jb->mutexjb);
05801
05802 rp = jb->rp;
05803 wp = jb->wp;
05804
05805 if (jb->state_empty) {
05806 for (i = 0; i < len; i++) {
05807 if (wp == rp) {
05808 jb->rp = rp;
05809 jb->state_empty = 0;
05810
05811 ast_mutex_unlock(&jb->mutexjb);
05812
05813 return read;
05814 } else {
05815 if (jb->ok[rp] == 1) {
05816 data[i] = jb->samples[rp];
05817 jb->ok[rp] = 0;
05818 rp = (rp != jb->size - 1) ? rp + 1 : 0;
05819 read += 1;
05820 }
05821 }
05822 }
05823
05824 if (wp >= rp)
05825 jb->state_buffer = wp - rp;
05826 else
05827 jb->state_buffer = jb->size - rp + wp;
05828 chan_misdn_log(9, 0, "misdn_jb_empty: read:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb);
05829
05830 jb->rp = rp;
05831 } else
05832 chan_misdn_log(9, 0, "misdn_jb_empty: Wait...requested:%d p:%p\n", len, jb);
05833
05834 ast_mutex_unlock(&jb->mutexjb);
05835
05836 return read;
05837 }
05838
05839
05840
05841
05842
05843
05844
05845
05846
05847
05848
05849 static void chan_misdn_log(int level, int port, char *tmpl, ...)
05850 {
05851 va_list ap;
05852 char buf[1024];
05853 char port_buf[8];
05854
05855 if (! ((0 <= port) && (port <= max_ports))) {
05856 ast_log(LOG_WARNING, "cb_log called with out-of-range port number! (%d)\n", port);
05857 port = 0;
05858 level = -1;
05859 }
05860
05861 snprintf(port_buf, sizeof(port_buf), "P[%2d] ", port);
05862
05863 va_start(ap, tmpl);
05864 vsnprintf(buf, sizeof(buf), tmpl, ap);
05865 va_end(ap);
05866
05867 if (level == -1)
05868 ast_log(LOG_WARNING, "%s", buf);
05869
05870 else if (misdn_debug_only[port] ?
05871 (level == 1 && misdn_debug[port]) || (level == misdn_debug[port])
05872 : level <= misdn_debug[port]) {
05873
05874 ast_console_puts(port_buf);
05875 ast_console_puts(buf);
05876 }
05877
05878 if ((level <= misdn_debug[0]) && !ast_strlen_zero(global_tracefile) ) {
05879 time_t tm = time(NULL);
05880 char *tmp = ctime(&tm), *p;
05881
05882 FILE *fp = fopen(global_tracefile, "a+");
05883
05884 p = strchr(tmp, '\n');
05885 if (p)
05886 *p = ':';
05887
05888 if (!fp) {
05889 ast_console_puts("Error opening Tracefile: [ ");
05890 ast_console_puts(global_tracefile);
05891 ast_console_puts(" ] ");
05892
05893 ast_console_puts(strerror(errno));
05894 ast_console_puts("\n");
05895 return ;
05896 }
05897
05898 fputs(tmp, fp);
05899 fputs(" ", fp);
05900 fputs(port_buf, fp);
05901 fputs(" ", fp);
05902 fputs(buf, fp);
05903
05904 fclose(fp);
05905 }
05906 }
05907
05908 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Channel driver for mISDN Support (BRI/PRI)",
05909 .load = load_module,
05910 .unload = unload_module,
05911 .reload = reload,
05912 );