00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <syslog.h>
00022 #include <sys/time.h>
00023 #include <mISDNuser/isdn_debug.h>
00024
00025 #include "isdn_lib_intern.h"
00026 #include "isdn_lib.h"
00027
00028
00029
00030
00031
00032 #define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
00033
00034 #include "asterisk/causes.h"
00035
00036 void misdn_join_conf(struct misdn_bchannel *bc, int conf_id);
00037 void misdn_split_conf(struct misdn_bchannel *bc, int conf_id);
00038
00039 int queue_cleanup_bc(struct misdn_bchannel *bc) ;
00040
00041 int misdn_lib_get_l2_up(struct misdn_stack *stack);
00042
00043 struct misdn_stack* get_misdn_stack( void );
00044
00045 static int set_chan_in_stack(struct misdn_stack *stack, int channel);
00046
00047 int release_cr(struct misdn_stack *stack, mISDNuser_head_t *hh);
00048
00049 int misdn_lib_port_is_pri(int port)
00050 {
00051 struct misdn_stack *stack=get_misdn_stack();
00052 for ( ; stack; stack=stack->next) {
00053 if (stack->port == port) {
00054 return stack->pri;
00055 }
00056 }
00057
00058 return -1;
00059 }
00060
00061 static void misdn_make_dummy(struct misdn_bchannel *dummybc, int port, int l3id, int nt, int channel)
00062 {
00063 memset (dummybc,0,sizeof(struct misdn_bchannel));
00064 dummybc->port=port;
00065 dummybc->l3_id=l3id;
00066 dummybc->nt=nt;
00067 dummybc->dummy=1;
00068 dummybc->channel=channel;
00069 }
00070
00071 int misdn_lib_port_block(int port)
00072 {
00073 struct misdn_stack *stack=get_misdn_stack();
00074 for ( ; stack; stack=stack->next) {
00075 if (stack->port == port) {
00076 stack->blocked=1;
00077 return 0;
00078 }
00079 }
00080 return -1;
00081
00082 }
00083
00084 int misdn_lib_port_unblock(int port)
00085 {
00086 struct misdn_stack *stack=get_misdn_stack();
00087 for ( ; stack; stack=stack->next) {
00088 if (stack->port == port) {
00089 stack->blocked=0;
00090 return 0;
00091 }
00092 }
00093 return -1;
00094
00095 }
00096
00097 int misdn_lib_is_port_blocked(int port)
00098 {
00099 struct misdn_stack *stack=get_misdn_stack();
00100 for ( ; stack; stack=stack->next) {
00101 if (stack->port == port) {
00102 return stack->blocked;
00103 }
00104 }
00105 return -1;
00106 }
00107
00108 int misdn_lib_is_ptp(int port)
00109 {
00110 struct misdn_stack *stack=get_misdn_stack();
00111 for ( ; stack; stack=stack->next) {
00112 if (stack->port == port) return stack->ptp;
00113 }
00114 return -1;
00115 }
00116
00117 int misdn_lib_get_maxchans(int port)
00118 {
00119 struct misdn_stack *stack=get_misdn_stack();
00120 for ( ; stack; stack=stack->next) {
00121 if (stack->port == port) {
00122 if (stack->pri)
00123 return 30;
00124 else
00125 return 2;
00126 }
00127 }
00128 return -1;
00129 }
00130
00131
00132 struct misdn_stack *get_stack_by_bc(struct misdn_bchannel *bc)
00133 {
00134 struct misdn_stack *stack = get_misdn_stack();
00135
00136 if (!bc)
00137 return NULL;
00138
00139 for ( ; stack; stack = stack->next) {
00140 if (bc->port == stack->port)
00141 return stack;
00142 }
00143
00144 return NULL;
00145 }
00146
00147
00148 void get_show_stack_details(int port, char *buf)
00149 {
00150 struct misdn_stack *stack=get_misdn_stack();
00151
00152 for ( ; stack; stack=stack->next) {
00153 if (stack->port == port) break;
00154 }
00155
00156 if (stack) {
00157 sprintf(buf, "* Port %d Type %s Prot. %s L2Link %s L1Link:%s Blocked:%d",
00158 stack->port, stack->nt ? "NT" : "TE", stack->ptp ? "PTP" : "PMP",
00159 stack->l2link ? "UP" : "DOWN", stack->l1link ? "UP" : "DOWN",
00160 stack->blocked);
00161 } else {
00162 buf[0]=0;
00163 }
00164 }
00165
00166
00167 static int nt_err_cnt =0 ;
00168
00169 enum global_states {
00170 MISDN_INITIALIZING,
00171 MISDN_INITIALIZED
00172 } ;
00173
00174 static enum global_states global_state=MISDN_INITIALIZING;
00175
00176
00177 #include <mISDNuser/net_l2.h>
00178 #include <mISDNuser/tone.h>
00179 #include <unistd.h>
00180 #include <semaphore.h>
00181 #include <pthread.h>
00182 #include <signal.h>
00183
00184 #include "isdn_lib.h"
00185
00186
00187 struct misdn_lib {
00188
00189 int midev;
00190 int midev_nt;
00191
00192 pthread_t event_thread;
00193 pthread_t event_handler_thread;
00194
00195 void *user_data;
00196
00197 msg_queue_t upqueue;
00198 msg_queue_t activatequeue;
00199
00200 sem_t new_msg;
00201
00202 struct misdn_stack *stack_list;
00203 } ;
00204
00205 #ifndef ECHOCAN_ON
00206 #define ECHOCAN_ON 123
00207 #define ECHOCAN_OFF 124
00208 #endif
00209
00210 #define MISDN_DEBUG 0
00211
00212 void misdn_tx_jitter(struct misdn_bchannel *bc, int len);
00213
00214 struct misdn_bchannel *find_bc_by_l3id(struct misdn_stack *stack, unsigned long l3id);
00215
00216 struct misdn_bchannel *find_bc_by_confid(unsigned long confid);
00217
00218 struct misdn_bchannel *stack_holder_find_bychan(struct misdn_stack *stack, int chan);
00219
00220 int setup_bc(struct misdn_bchannel *bc);
00221
00222 int manager_isdn_handler(iframe_t *frm ,msg_t *msg);
00223
00224 int misdn_lib_port_restart(int port);
00225 int misdn_lib_pid_restart(int pid);
00226
00227 extern struct isdn_msg msgs_g[];
00228
00229 #define ISDN_PID_L3_B_USER 0x430000ff
00230 #define ISDN_PID_L4_B_USER 0x440000ff
00231
00232
00233 #define MISDN_IBUF_SIZE 512
00234
00235
00236 #define TONE_ALERT_CNT 41
00237 #define TONE_ALERT_SILENCE_CNT 200
00238
00239 #define TONE_BUSY_CNT 20
00240 #define TONE_BUSY_SILENCE_CNT 48
00241
00242 static int entity;
00243
00244 static struct misdn_lib *glob_mgr;
00245
00246 char tone_425_flip[TONE_425_SIZE];
00247 char tone_silence_flip[TONE_SILENCE_SIZE];
00248
00249 static void misdn_lib_isdn_event_catcher(void *arg);
00250 static int handle_event_nt(void *dat, void *arg);
00251
00252
00253 void stack_holder_add(struct misdn_stack *stack, struct misdn_bchannel *holder);
00254 void stack_holder_remove(struct misdn_stack *stack, struct misdn_bchannel *holder);
00255 struct misdn_bchannel *stack_holder_find(struct misdn_stack *stack, unsigned long l3id);
00256
00257
00258
00259 int te_lib_init( void ) ;
00260 void te_lib_destroy(int midev) ;
00261 struct misdn_bchannel *manager_find_bc_by_pid(int pid);
00262 struct misdn_bchannel *manager_find_bc_holded(struct misdn_bchannel* bc);
00263 void manager_ph_control_block(struct misdn_bchannel *bc, int c1, void *c2, int c2_len);
00264 void manager_clean_bc(struct misdn_bchannel *bc );
00265 void manager_bchannel_setup (struct misdn_bchannel *bc);
00266 void manager_bchannel_cleanup (struct misdn_bchannel *bc);
00267
00268 void ec_chunk( struct misdn_bchannel *bc, unsigned char *rxchunk, unsigned char *txchunk, int chunk_size);
00269
00270 int bchdev_echocancel_activate(struct misdn_bchannel* dev);
00271 void bchdev_echocancel_deactivate(struct misdn_bchannel* dev);
00272
00273
00274
00275 static char *bearer2str(int cap) {
00276 static char *bearers[]={
00277 "Speech",
00278 "Audio 3.1k",
00279 "Unres Digital",
00280 "Res Digital",
00281 "Unknown Bearer"
00282 };
00283
00284 switch (cap) {
00285 case INFO_CAPABILITY_SPEECH:
00286 return bearers[0];
00287 break;
00288 case INFO_CAPABILITY_AUDIO_3_1K:
00289 return bearers[1];
00290 break;
00291 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
00292 return bearers[2];
00293 break;
00294 case INFO_CAPABILITY_DIGITAL_RESTRICTED:
00295 return bearers[3];
00296 break;
00297 default:
00298 return bearers[4];
00299 break;
00300 }
00301 }
00302
00303
00304 static char flip_table[256];
00305
00306 static void init_flip_bits(void)
00307 {
00308 int i,k;
00309
00310 for (i = 0 ; i < 256 ; i++) {
00311 unsigned char sample = 0 ;
00312 for (k = 0; k<8; k++) {
00313 if ( i & 1 << k ) sample |= 0x80 >> k;
00314 }
00315 flip_table[i] = sample;
00316 }
00317 }
00318
00319 static char * flip_buf_bits ( char * buf , int len)
00320 {
00321 int i;
00322 char * start = buf;
00323
00324 for (i = 0 ; i < len; i++) {
00325 buf[i] = flip_table[(unsigned char)buf[i]];
00326 }
00327
00328 return start;
00329 }
00330
00331
00332
00333
00334 static msg_t *create_l2msg(int prim, int dinfo, int size)
00335 {
00336 int i = 0;
00337 msg_t *dmsg;
00338
00339 while(i < 10)
00340 {
00341 dmsg = prep_l3data_msg(prim, dinfo, size, 256, NULL);
00342 if (dmsg)
00343 return(dmsg);
00344
00345 if (!i)
00346 printf("cannot allocate memory, trying again...\n");
00347 i++;
00348 usleep(300000);
00349 }
00350 printf("cannot allocate memory, system overloaded.\n");
00351 exit(-1);
00352 }
00353
00354
00355
00356 msg_t *create_l3msg(int prim, int mt, int dinfo, int size, int ntmode)
00357 {
00358 int i = 0;
00359 msg_t *dmsg;
00360 Q931_info_t *qi;
00361 iframe_t *frm;
00362
00363 if (!ntmode)
00364 size = sizeof(Q931_info_t)+2;
00365
00366 while(i < 10) {
00367 if (ntmode) {
00368 dmsg = prep_l3data_msg(prim, dinfo, size, 256, NULL);
00369 if (dmsg) {
00370 return(dmsg);
00371 }
00372 } else {
00373 dmsg = alloc_msg(size+256+mISDN_HEADER_LEN+DEFAULT_HEADROOM);
00374 if (dmsg)
00375 {
00376 memset(msg_put(dmsg,size+mISDN_HEADER_LEN), 0, size+mISDN_HEADER_LEN);
00377 frm = (iframe_t *)dmsg->data;
00378 frm->prim = prim;
00379 frm->dinfo = dinfo;
00380 qi = (Q931_info_t *)(dmsg->data + mISDN_HEADER_LEN);
00381 qi->type = mt;
00382 return(dmsg);
00383 }
00384 }
00385
00386 if (!i) printf("cannot allocate memory, trying again...\n");
00387 i++;
00388 usleep(300000);
00389 }
00390 printf("cannot allocate memory, system overloaded.\n");
00391 exit(-1);
00392 }
00393
00394
00395 static int send_msg (int midev, struct misdn_bchannel *bc, msg_t *dmsg)
00396 {
00397 iframe_t *frm = (iframe_t *)dmsg->data;
00398 struct misdn_stack *stack=get_stack_by_bc(bc);
00399
00400 if (!stack) {
00401 cb_log(0,bc->port,"send_msg: IEK!! no stack\n ");
00402 return -1;
00403 }
00404
00405 frm->addr = (stack->upper_id | FLG_MSG_DOWN);
00406 frm->dinfo = bc->l3_id;
00407 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
00408
00409 cb_log(4,stack->port,"Sending msg, prim:%x addr:%x dinfo:%x\n",frm->prim,frm->addr,frm->dinfo);
00410
00411 mISDN_write(midev, dmsg->data, dmsg->len, TIMEOUT_1SEC);
00412 free_msg(dmsg);
00413
00414 return 0;
00415 }
00416
00417
00418 static int mypid=1;
00419
00420
00421 int misdn_cap_is_speech(int cap)
00422
00423 {
00424 if ( (cap != INFO_CAPABILITY_DIGITAL_UNRESTRICTED) &&
00425 (cap != INFO_CAPABILITY_DIGITAL_RESTRICTED) ) return 1;
00426 return 0;
00427 }
00428
00429 int misdn_inband_avail(struct misdn_bchannel *bc)
00430 {
00431
00432 if (!bc->early_bconnect) {
00433
00434 return 0;
00435 }
00436
00437 switch (bc->progress_indicator) {
00438 case INFO_PI_INBAND_AVAILABLE:
00439 case INFO_PI_CALL_NOT_E2E_ISDN:
00440 case INFO_PI_CALLED_NOT_ISDN:
00441 return 1;
00442 default:
00443 return 0;
00444 }
00445 return 0;
00446 }
00447
00448
00449 static void dump_chan_list(struct misdn_stack *stack)
00450 {
00451 int i;
00452
00453 for (i=0; i <= stack->b_num; i++) {
00454 cb_log(6, stack->port, "Idx:%d stack->cchan:%d in_use:%d Chan:%d\n",i,stack->channels[i], stack->bc[i].in_use, i+1);
00455 }
00456 }
00457
00458
00459 void misdn_dump_chanlist()
00460 {
00461 struct misdn_stack *stack=get_misdn_stack();
00462 for ( ; stack; stack=stack->next) {
00463 dump_chan_list(stack);
00464 }
00465
00466 }
00467
00468 int set_chan_in_stack(struct misdn_stack *stack, int channel)
00469 {
00470
00471 cb_log(4,stack->port,"set_chan_in_stack: %d\n",channel);
00472 dump_chan_list(stack);
00473 if (channel >=1 && channel <= MAX_BCHANS) {
00474 if (!stack->channels[channel-1])
00475 stack->channels[channel-1] = 1;
00476 else {
00477 cb_log(4,stack->port,"channel already in use:%d\n", channel );
00478 return -1;
00479 }
00480 } else {
00481 cb_log(0,stack->port,"couldn't set channel %d in\n", channel );
00482 return -1;
00483 }
00484
00485 return 0;
00486 }
00487
00488
00489
00490 static int find_free_chan_in_stack(struct misdn_stack *stack, struct misdn_bchannel *bc, int channel, int dec)
00491 {
00492 int i;
00493 int chan=0;
00494 int bnums = stack->pri ? stack->b_num : stack->b_num - 1;
00495
00496 if (bc->channel_found)
00497 return 0;
00498
00499 bc->channel_found=1;
00500
00501 cb_log(5,stack->port,"find_free_chan: req_chan:%d\n",channel);
00502
00503 if (channel < 0 || channel > MAX_BCHANS) {
00504 cb_log(0, stack->port, " !! out of bound call to find_free_chan_in_stack! (ch:%d)\n", channel);
00505 return 0;
00506 }
00507
00508 channel--;
00509
00510 if (dec) {
00511 for (i = bnums; i >=0; i--) {
00512 if (i != 15 && (channel < 0 || i == channel)) {
00513 if (!stack->channels[i]) {
00514 cb_log (3, stack->port, " --> found chan%s: %d\n", channel>=0?" (preselected)":"", i+1);
00515 chan=i+1;
00516 break;
00517 }
00518 }
00519 }
00520 } else {
00521 for (i = 0; i <= bnums; i++) {
00522 if (i != 15 && (channel < 0 || i == channel)) {
00523 if (!stack->channels[i]) {
00524 cb_log (3, stack->port, " --> found chan%s: %d\n", channel>=0?" (preselected)":"", i+1);
00525 chan=i+1;
00526 break;
00527 }
00528 }
00529 }
00530 }
00531
00532 if (!chan) {
00533 cb_log (1, stack->port, " !! NO FREE CHAN IN STACK\n");
00534 dump_chan_list(stack);
00535 bc->out_cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
00536 return -1;
00537 }
00538
00539 if (set_chan_in_stack(stack, chan)<0) {
00540 cb_log (0, stack->port, "Channel Already in use:%d\n", chan);
00541 bc->out_cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
00542 return -1;
00543 }
00544
00545 bc->channel=chan;
00546 return 0;
00547 }
00548
00549 static int empty_chan_in_stack(struct misdn_stack *stack, int channel)
00550 {
00551 if (channel<=0 || channel>MAX_BCHANS) {
00552 cb_log(0,stack?stack->port:0, "empty_chan_in_stack: cannot empty channel %d\n",channel);
00553 return -1;
00554 }
00555
00556 cb_log (4, stack?stack->port:0, "empty_chan_in_stack: %d\n",channel);
00557 stack->channels[channel-1] = 0;
00558 dump_chan_list(stack);
00559 return 0;
00560 }
00561
00562 char *bc_state2str(enum bchannel_state state) {
00563 int i;
00564
00565 struct bchan_state_s {
00566 char *n;
00567 enum bchannel_state s;
00568 } states[] = {
00569 {"BCHAN_CLEANED", BCHAN_CLEANED },
00570 {"BCHAN_EMPTY", BCHAN_EMPTY},
00571 {"BCHAN_SETUP", BCHAN_SETUP},
00572 {"BCHAN_SETUPED", BCHAN_SETUPED},
00573 {"BCHAN_ACTIVE", BCHAN_ACTIVE},
00574 {"BCHAN_ACTIVATED", BCHAN_ACTIVATED},
00575 {"BCHAN_BRIDGE", BCHAN_BRIDGE},
00576 {"BCHAN_BRIDGED", BCHAN_BRIDGED},
00577 {"BCHAN_RELEASE", BCHAN_RELEASE},
00578 {"BCHAN_RELEASED", BCHAN_RELEASED},
00579 {"BCHAN_CLEAN", BCHAN_CLEAN},
00580 {"BCHAN_CLEAN_REQUEST", BCHAN_CLEAN_REQUEST},
00581 {"BCHAN_ERROR", BCHAN_ERROR}
00582 };
00583
00584 for (i=0; i< sizeof(states)/sizeof(struct bchan_state_s); i++)
00585 if ( states[i].s == state)
00586 return states[i].n;
00587
00588 return "UNKNOWN";
00589 }
00590
00591 void bc_state_change(struct misdn_bchannel *bc, enum bchannel_state state)
00592 {
00593 cb_log(5,bc->port,"BC_STATE_CHANGE: l3id:%x from:%s to:%s\n",
00594 bc->l3_id,
00595 bc_state2str(bc->bc_state),
00596 bc_state2str(state) );
00597
00598 switch (state) {
00599 case BCHAN_ACTIVATED:
00600 if (bc->next_bc_state == BCHAN_BRIDGED) {
00601 misdn_join_conf(bc, bc->conf_id);
00602 bc->next_bc_state = BCHAN_EMPTY;
00603 return;
00604 }
00605 default:
00606 bc->bc_state=state;
00607 break;
00608 }
00609 }
00610
00611 static void bc_next_state_change(struct misdn_bchannel *bc, enum bchannel_state state)
00612 {
00613 cb_log(5,bc->port,"BC_NEXT_STATE_CHANGE: from:%s to:%s\n",
00614 bc_state2str(bc->next_bc_state),
00615 bc_state2str(state) );
00616
00617 bc->next_bc_state=state;
00618 }
00619
00620
00621 static void empty_bc(struct misdn_bchannel *bc)
00622 {
00623 bc->dummy=0;
00624
00625 bc->bframe_len=0;
00626
00627 bc->cw= 0;
00628
00629 bc->dec=0;
00630 bc->channel = 0;
00631
00632 bc->sending_complete = 0;
00633
00634 bc->restart_channel=0;
00635
00636 bc->conf_id = 0;
00637
00638 bc->need_more_infos = 0;
00639
00640 bc->send_dtmf=0;
00641 bc->nodsp=0;
00642 bc->nojitter=0;
00643
00644 bc->time_usec=0;
00645
00646 bc->rxgain=0;
00647 bc->txgain=0;
00648
00649 bc->crypt=0;
00650 bc->curptx=0; bc->curprx=0;
00651
00652 bc->crypt_key[0] = 0;
00653
00654 bc->generate_tone=0;
00655 bc->tone_cnt=0;
00656
00657 bc->dnumplan=NUMPLAN_UNKNOWN;
00658 bc->onumplan=NUMPLAN_UNKNOWN;
00659 bc->rnumplan=NUMPLAN_UNKNOWN;
00660 bc->cpnnumplan=NUMPLAN_UNKNOWN;
00661
00662
00663 bc->active = 0;
00664
00665 bc->early_bconnect = 1;
00666
00667 #ifdef MISDN_1_2
00668 *bc->pipeline = 0;
00669 #else
00670 bc->ec_enable = 0;
00671 bc->ec_deftaps = 128;
00672 #endif
00673
00674 bc->orig=0;
00675
00676 bc->cause = AST_CAUSE_NORMAL_CLEARING;
00677 bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
00678 bc->pres = 0;
00679
00680 bc->evq=EVENT_NOTHING;
00681
00682 bc->progress_coding=0;
00683 bc->progress_location=0;
00684 bc->progress_indicator=0;
00685
00686
00687 bc->capability=INFO_CAPABILITY_SPEECH;
00688 bc->law=INFO_CODEC_ALAW;
00689 bc->mode=0;
00690 bc->rate=0x10;
00691 bc->user1=0;
00692 bc->urate=0;
00693
00694 bc->hdlc=0;
00695
00696
00697 bc->info_dad[0] = 0;
00698 bc->display[0] = 0;
00699 bc->infos_pending[0] = 0;
00700 bc->cad[0] = 0;
00701 bc->oad[0] = 0;
00702 bc->dad[0] = 0;
00703 bc->rad[0] = 0;
00704 bc->orig_dad[0] = 0;
00705 bc->uu[0]=0;
00706 bc->uulen=0;
00707
00708 bc->fac_in.Function = Fac_None;
00709 bc->fac_out.Function = Fac_None;
00710
00711 bc->te_choose_channel = 0;
00712 bc->channel_found= 0;
00713
00714 gettimeofday(&bc->last_used, NULL);
00715 }
00716
00717
00718 static int clean_up_bc(struct misdn_bchannel *bc)
00719 {
00720 int ret=0;
00721 unsigned char buff[32];
00722 struct misdn_stack * stack;
00723
00724 cb_log(3, bc?bc->port:0, "$$$ CLEANUP CALLED pid:%d\n", bc?bc->pid:-1);
00725
00726 if (!bc ) return -1;
00727 stack=get_stack_by_bc(bc);
00728
00729 if (!stack) return -1;
00730
00731 switch (bc->bc_state ) {
00732 case BCHAN_CLEANED:
00733 cb_log(5, stack->port, "$$$ Already cleaned up bc with stid :%x\n", bc->b_stid);
00734 return -1;
00735
00736 default:
00737 break;
00738 }
00739
00740 cb_log(2, stack->port, "$$$ Cleaning up bc with stid :%x pid:%d\n", bc->b_stid, bc->pid);
00741
00742 manager_ec_disable(bc);
00743
00744 manager_bchannel_deactivate(bc);
00745
00746 mISDN_write_frame(stack->midev, buff, bc->layer_id|FLG_MSG_TARGET|FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
00747
00748 bc->b_stid = 0;
00749 bc_state_change(bc, BCHAN_CLEANED);
00750
00751 return ret;
00752 }
00753
00754
00755
00756 static void clear_l3(struct misdn_stack *stack)
00757 {
00758 int i;
00759
00760 for (i=0; i<=stack->b_num; i++) {
00761 if (global_state == MISDN_INITIALIZED) {
00762 cb_event(EVENT_CLEANUP, &stack->bc[i], NULL);
00763 empty_chan_in_stack(stack,i+1);
00764 empty_bc(&stack->bc[i]);
00765 clean_up_bc(&stack->bc[i]);
00766 stack->bc[i].in_use = 0;
00767 }
00768
00769 }
00770 }
00771
00772 static int newteid=0;
00773
00774 #define MAXPROCS 0x100
00775
00776 static int misdn_lib_get_l1_down(struct misdn_stack *stack)
00777 {
00778
00779 iframe_t act;
00780 act.prim = PH_DEACTIVATE | REQUEST;
00781 act.addr = stack->lower_id|FLG_MSG_DOWN;
00782 act.dinfo = 0;
00783 act.len = 0;
00784
00785 cb_log(1, stack->port, "SENDING PH_DEACTIVATE | REQ\n");
00786 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
00787 }
00788
00789
00790 static int misdn_lib_get_l2_down(struct misdn_stack *stack)
00791 {
00792
00793 if (stack->ptp && (stack->nt) ) {
00794 msg_t *dmsg;
00795
00796 dmsg = create_l2msg(DL_RELEASE| REQUEST, 0, 0);
00797
00798 if (stack->nst.manager_l3(&stack->nst, dmsg))
00799 free_msg(dmsg);
00800
00801 } else {
00802 iframe_t act;
00803
00804 act.prim = DL_RELEASE| REQUEST;
00805 act.addr = (stack->upper_id |FLG_MSG_DOWN) ;
00806
00807 act.dinfo = 0;
00808 act.len = 0;
00809 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
00810 }
00811
00812 return 0;
00813 }
00814
00815
00816 static int misdn_lib_get_l1_up(struct misdn_stack *stack)
00817 {
00818
00819 iframe_t act;
00820 act.prim = PH_ACTIVATE | REQUEST;
00821 act.addr = (stack->upper_id | FLG_MSG_DOWN) ;
00822
00823
00824 act.dinfo = 0;
00825 act.len = 0;
00826
00827 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
00828
00829 }
00830
00831 int misdn_lib_get_l2_up(struct misdn_stack *stack)
00832 {
00833
00834 if (stack->ptp && (stack->nt) ) {
00835 msg_t *dmsg;
00836
00837 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
00838
00839 if (stack->nst.manager_l3(&stack->nst, dmsg))
00840 free_msg(dmsg);
00841
00842 } else {
00843 iframe_t act;
00844
00845 act.prim = DL_ESTABLISH | REQUEST;
00846 act.addr = (stack->upper_id |FLG_MSG_DOWN) ;
00847
00848 act.dinfo = 0;
00849 act.len = 0;
00850 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
00851 }
00852
00853 return 0;
00854 }
00855
00856 #if 0
00857 static int misdn_lib_get_l2_te_ptp_up(struct misdn_stack *stack)
00858 {
00859 iframe_t act;
00860
00861 act.prim = DL_ESTABLISH | REQUEST;
00862 act.addr = (stack->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
00863
00864 act.dinfo = 0;
00865 act.len = 0;
00866 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
00867 return 0;
00868 }
00869 #endif
00870
00871 static int misdn_lib_get_short_status(struct misdn_stack *stack)
00872 {
00873 iframe_t act;
00874
00875
00876 act.prim = MGR_SHORTSTATUS | REQUEST;
00877
00878 act.addr = (stack->upper_id | MSG_BROADCAST) ;
00879
00880 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
00881
00882 act.len = 0;
00883 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
00884 }
00885
00886
00887
00888 static int create_process (int midev, struct misdn_bchannel *bc) {
00889 iframe_t ncr;
00890 int l3_id;
00891 int i;
00892 struct misdn_stack *stack=get_stack_by_bc(bc);
00893
00894 if (stack->nt) {
00895 if (find_free_chan_in_stack(stack, bc, bc->channel_preselected?bc->channel:0, 0)<0) return -1;
00896 cb_log(4,stack->port, " --> found channel: %d\n",bc->channel);
00897
00898 for (i=0; i <= MAXPROCS; i++)
00899 if (stack->procids[i]==0) break;
00900
00901 if (i== MAXPROCS) {
00902 cb_log(0, stack->port, "Couldn't Create New ProcId.\n");
00903 return -1;
00904 }
00905 stack->procids[i]=1;
00906
00907 l3_id = 0xff00 | i;
00908
00909 ncr.prim = CC_NEW_CR | REQUEST;
00910
00911 ncr.addr = (stack->upper_id | FLG_MSG_DOWN) ;
00912
00913 ncr.dinfo = l3_id;
00914 ncr.len = 0;
00915
00916 bc->l3_id = l3_id;
00917 cb_log(3, stack->port, " --> new_l3id %x\n",l3_id);
00918
00919 } else {
00920 if (stack->ptp || bc->te_choose_channel) {
00921
00922 if (find_free_chan_in_stack(stack, bc, bc->channel_preselected?bc->channel:0, bc->dec)<0) return -1;
00923 cb_log(2,stack->port, " --> found channel: %d\n",bc->channel);
00924 } else {
00925
00926 bc->channel=0xff;
00927 }
00928
00929
00930
00931 if (newteid++ > 0xffff)
00932 newteid = 0x0001;
00933
00934 l3_id = (entity<<16) | newteid;
00935
00936 ncr.prim = CC_NEW_CR | REQUEST;
00937
00938 ncr.addr = (stack->upper_id | FLG_MSG_DOWN) ;
00939
00940 ncr.dinfo =l3_id;
00941 ncr.len = 0;
00942
00943
00944 bc->l3_id = l3_id;
00945 cb_log(3, stack->port, "--> new_l3id %x\n",l3_id);
00946
00947 mISDN_write(midev, &ncr, mISDN_HEADER_LEN+ncr.len, TIMEOUT_1SEC);
00948 }
00949
00950 return l3_id;
00951 }
00952
00953
00954 void misdn_lib_setup_bc(struct misdn_bchannel *bc)
00955 {
00956 clean_up_bc(bc);
00957 setup_bc(bc);
00958 }
00959
00960
00961 int setup_bc(struct misdn_bchannel *bc)
00962 {
00963 unsigned char buff[1025];
00964 int midev;
00965 int channel;
00966 int b_stid;
00967 int i;
00968 mISDN_pid_t pid;
00969 int ret;
00970
00971 struct misdn_stack *stack=get_stack_by_bc(bc);
00972
00973 if (!stack) {
00974 cb_log(0, bc->port, "setup_bc: NO STACK FOUND!!\n");
00975 return -1;
00976 }
00977
00978 midev = stack->midev;
00979 channel = bc->channel - 1 - (bc->channel > 16);
00980 b_stid = stack->b_stids[channel >= 0 ? channel : 0];
00981
00982 switch (bc->bc_state) {
00983 case BCHAN_CLEANED:
00984 break;
00985 default:
00986 cb_log(4, stack->port, "$$$ bc already setup stid :%x (state:%s)\n", b_stid, bc_state2str(bc->bc_state) );
00987 return -1;
00988 }
00989
00990 cb_log(5, stack->port, "$$$ Setting up bc with stid :%x\n", b_stid);
00991
00992
00993 for (i=0; i <= stack->b_num; i++) {
00994 if (stack->bc[i].b_stid == b_stid) {
00995 cb_log(0, bc->port, "setup_bc: b_stid:%x already in use !!!\n", b_stid);
00996 return -1;
00997 }
00998 }
00999
01000 if (b_stid <= 0) {
01001 cb_log(0, stack->port," -- Stid <=0 at the moment in channel:%d\n",channel);
01002
01003 bc_state_change(bc,BCHAN_ERROR);
01004 return 1;
01005 }
01006
01007 bc->b_stid = b_stid;
01008
01009 {
01010 layer_info_t li;
01011 memset(&li, 0, sizeof(li));
01012
01013 li.object_id = -1;
01014 li.extentions = 0;
01015
01016 li.st = bc->b_stid;
01017
01018
01019 #define MISDN_DSP
01020 #ifndef MISDN_DSP
01021 bc->nodsp=1;
01022 #endif
01023 if ( bc->hdlc || bc->nodsp) {
01024 cb_log(4, stack->port,"setup_bc: without dsp\n");
01025 {
01026 int l = sizeof(li.name);
01027 strncpy(li.name, "B L3", l);
01028 li.name[l-1] = 0;
01029 }
01030 li.pid.layermask = ISDN_LAYER((3));
01031 li.pid.protocol[3] = ISDN_PID_L3_B_USER;
01032
01033 bc->layer=3;
01034 } else {
01035 cb_log(4, stack->port,"setup_bc: with dsp\n");
01036 {
01037 int l = sizeof(li.name);
01038 strncpy(li.name, "B L4", l);
01039 li.name[l-1] = 0;
01040 }
01041 li.pid.layermask = ISDN_LAYER((4));
01042 li.pid.protocol[4] = ISDN_PID_L4_B_USER;
01043
01044 bc->layer=4;
01045 }
01046
01047 ret = mISDN_new_layer(midev, &li);
01048 if (ret ) {
01049 cb_log(0, stack->port,"New Layer Err: %d %s\n",ret,strerror(errno));
01050
01051 bc_state_change(bc,BCHAN_ERROR);
01052 return(-EINVAL);
01053 }
01054
01055 bc->layer_id = li.id;
01056 }
01057
01058 memset(&pid, 0, sizeof(pid));
01059
01060
01061
01062 cb_log(4, stack->port," --> Channel is %d\n", bc->channel);
01063
01064 if (bc->nodsp) {
01065 cb_log(2, stack->port," --> TRANSPARENT Mode (no DSP, no HDLC)\n");
01066 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
01067 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
01068 pid.protocol[3] = ISDN_PID_L3_B_USER;
01069 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3));
01070
01071 } else if ( bc->hdlc ) {
01072 cb_log(2, stack->port," --> HDLC Mode\n");
01073 pid.protocol[1] = ISDN_PID_L1_B_64HDLC ;
01074 pid.protocol[2] = ISDN_PID_L2_B_TRANS ;
01075 pid.protocol[3] = ISDN_PID_L3_B_USER;
01076 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) ;
01077 } else {
01078 cb_log(2, stack->port," --> TRANSPARENT Mode\n");
01079 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
01080 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
01081 pid.protocol[3] = ISDN_PID_L3_B_DSP;
01082 pid.protocol[4] =