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