📄 isdn_lib.c
字号:
if (hold_bc) { cb_log(4, stack->port, "REMOVEING Holder\n"); /*swap the backup to our new channel back*/ stack_holder_remove(stack, hold_bc); memcpy(bc,hold_bc,sizeof(struct misdn_bchannel)); free(hold_bc); bc->holded=0; } } break; case CC_SETUP|CONFIRM: { struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo); int l3id = *((int *)(((u_char *)msg->data)+ mISDNUSER_HEAD_SIZE)); cb_log(4, stack->port, " --> lib: Event_ind:SETUP CONFIRM [NT] : new L3ID is %x\n",l3id ); if (!bc) { cb_log(4, stack->port, "Bc Not found (after SETUP CONFIRM)\n"); return 0; } cb_log (2,bc->port,"I IND :CC_SETUP|CONFIRM: old l3id:%x new l3id:%x\n", bc->l3_id, l3id); bc->l3_id=l3id; cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data); } free_msg(msg); return 0; case CC_SETUP|INDICATION: { struct misdn_bchannel* bc=misdn_lib_get_free_bc(stack->port, 0, 1, 0); if (!bc) ERR_NO_CHANNEL: { msg_t *dmsg; cb_log(4, stack->port, "Patch from MEIDANIS:Sending RELEASE_COMPLETE %x (No free Chan for you..)\n", hh->dinfo); dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST,MT_RELEASE_COMPLETE, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1); stack->nst.manager_l3(&stack->nst, dmsg); free_msg(msg); return 0; } cb_log(7, stack->port, " --> new_process: New L3Id: %x\n",hh->dinfo); bc->l3_id=hh->dinfo; } break; case CC_CONNECT_ACKNOWLEDGE|INDICATION:#if 0 { struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo); if (bc) { if ( !misdn_cap_is_speech(bc->capability)) { int ret=setup_bc(bc); if (ret == -EINVAL){ cb_log(0,bc->port,"send_event: setup_bc failed\n"); } } } }#endif break; case CC_ALERTING|INDICATION: case CC_PROCEEDING|INDICATION: case CC_SETUP_ACKNOWLEDGE|INDICATION: if(!stack->ptp) break; case CC_CONNECT|INDICATION: {#if 0 struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo); if (!bc) { msg_t *dmsg; cb_log(0, stack->port,"!!!! We didn't found our bc, dinfo:%x on this port.\n",hh->dinfo); cb_log(0, stack->port, "Releaseing call %x (No free Chan for you..)\n", hh->dinfo); dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST,MT_RELEASE_COMPLETE, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1); stack->nst.manager_l3(&stack->nst, dmsg); free_msg(msg); return 0; } int ret=setup_bc(bc); if (ret == -EINVAL){ cb_log(0,bc->port,"handle_event_nt: setup_bc failed\n"); misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); }#endif } break; case CC_DISCONNECT|INDICATION: { struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo); if (!bc) { bc=find_bc_by_masked_l3id(stack, hh->dinfo, 0xffff0000); if (bc) { int myprocid=bc->l3_id&0x0000ffff; hh->dinfo=(hh->dinfo&0xffff0000)|myprocid; cb_log(3,stack->port,"Reject dinfo: %x cause:%d\n",hh->dinfo,bc->cause); reject=1; } } } break; case CC_FACILITY|INDICATION: { struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo); if (!bc) { bc=find_bc_by_masked_l3id(stack, hh->dinfo, 0xffff0000); if (bc) { int myprocid=bc->l3_id&0x0000ffff; hh->dinfo=(hh->dinfo&0xffff0000)|myprocid; cb_log(4,bc->port,"Repaired reject Bug, new dinfo: %x\n",hh->dinfo); } } } break; case CC_RELEASE_COMPLETE|INDICATION: break; case CC_SUSPEND|INDICATION: { msg_t *dmsg; cb_log(4, stack->port, " --> Got Suspend, sending Reject for now\n"); dmsg = create_l3msg(CC_SUSPEND_REJECT | REQUEST,MT_SUSPEND_REJECT, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1); stack->nst.manager_l3(&stack->nst, dmsg); free_msg(msg); return 0; } break; case CC_RESUME|INDICATION: break; case CC_RELEASE|CONFIRM: break; case CC_RELEASE|INDICATION: break; case CC_RELEASE_CR|INDICATION: { struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo); struct misdn_bchannel dummybc; iframe_t frm; /* fake te frm to remove callref from global callreflist */ frm.dinfo = hh->dinfo; frm.addr=stack->upper_id | FLG_MSG_DOWN; frm.prim = CC_RELEASE_CR|INDICATION; cb_log(4, stack->port, " --> Faking Realease_cr for %x\n",frm.addr); /** removing procid **/ if (!bc) { cb_log(4, stack->port, " --> Didn't found BC so temporarly creating dummy BC (l3id:%x) on this port.\n", hh->dinfo); memset (&dummybc,0,sizeof(dummybc)); dummybc.port=stack->port; dummybc.l3_id=hh->dinfo; dummybc.nt=stack->nt; bc=&dummybc; } if (bc) { if ( (bc->l3_id & 0xff00) == 0xff00) { cb_log(4, stack->port, " --> Removing Process Id:%x on this port.\n", bc->l3_id&0xff); stack->procids[bc->l3_id&0xff] = 0 ; } } else cb_log(0, stack->port, "Couldnt find BC so I couldnt remove the Process!!!! this is a bad port.\n"); if (handle_cr(stack, &frm)<0) { } free_msg(msg); return 0 ; } break; case CC_NEW_CR|INDICATION: /* Got New CR for bchan, for now I handle this one in */ /* connect_ack, Need to be changed */ { struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo); int l3id = *((int *)(((u_char *)msg->data)+ mISDNUSER_HEAD_SIZE)); if (!bc) { cb_log(0, stack->port, " --> In NEW_CR: didn't found bc ??\n"); return -1;}; if (((l3id&0xff00)!=0xff00) && ((bc->l3_id&0xff00)==0xff00)) { cb_log(4, stack->port, " --> Removing Process Id:%x on this port.\n", 0xff&bc->l3_id); stack->procids[bc->l3_id&0xff] = 0 ; } cb_log(4, stack->port, "lib: Event_ind:CC_NEW_CR : very new L3ID is %x\n",l3id ); bc->l3_id =l3id; cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data); free_msg(msg); return 0; } case DL_ESTABLISH | INDICATION: case DL_ESTABLISH | CONFIRM: { cb_log(3, stack->port, "%% GOT L2 Activate Info.\n"); if (stack->ptp && stack->l2link) { cb_log(0, stack->port, "%% GOT L2 Activate Info. but we're activated already.. this l2 is faulty, blocking port\n"); cb_event(EVENT_PORT_ALARM, &stack->bc[0], glob_mgr->user_data); } /* when we get the L2 UP, the L1 is UP definitely too*/ stack->l1link = 1; stack->l2link = 1; stack->l2upcnt=0; free_msg(msg); return 0; } break; case DL_RELEASE | INDICATION: case DL_RELEASE | CONFIRM: { if (stack->ptp) { cb_log(3 , stack->port, "%% GOT L2 DeActivate Info.\n"); if (stack->l2upcnt>3) { cb_log(0 , stack->port, "!!! Could not Get the L2 up after 3 Attemps!!!\n"); } else {#if 0 if (stack->nt) misdn_lib_reinit_nt_stack(stack->port);#endif if (stack->l1link) { misdn_lib_get_l2_up(stack); stack->l2upcnt++; } } } else cb_log(3, stack->port, "%% GOT L2 DeActivate Info.\n"); stack->l2link = 0; free_msg(msg); return 0; } break; } } { /* Parse Events and fire_up to App. */ struct misdn_bchannel *bc; struct misdn_bchannel dummybc; enum event_e event = isdn_msg_get_event(msgs_g, msg, 1); bc=find_bc_by_l3id(stack, hh->dinfo); if (!bc) { cb_log(4, stack->port, " --> Didn't found BC so temporarly creating dummy BC (l3id:%x).\n", hh->dinfo); memset (&dummybc,0,sizeof(dummybc)); dummybc.port=stack->port; dummybc.l3_id=hh->dinfo; dummybc.nt=stack->nt; bc=&dummybc; } if (bc ) { isdn_msg_parse_event(msgs_g,msg,bc, 1); switch (event) { case EVENT_SETUP: if (bc->channel<=0 || bc->channel==0xff) { bc->channel=find_free_chan_in_stack(stack,bc, 0,0); if (bc->channel<=0) goto ERR_NO_CHANNEL; } else if (!stack->ptp) cb_log(3,stack->port," --> PTMP but channel requested\n"); int ret=set_chan_in_stack(stack, bc->channel); if (event==EVENT_SETUP && ret<0){ /* empty bchannel */ bc->channel=0; bc->out_cause=44; goto ERR_NO_CHANNEL; } break; case EVENT_RELEASE: case EVENT_RELEASE_COMPLETE: if (bc->channel>0) empty_chan_in_stack(stack, bc->channel); int tmpcause=bc->cause; empty_bc(bc); bc->cause=tmpcause; clean_up_bc(bc); break; default: break; } if(!isdn_get_info(msgs_g,event,1)) { cb_log(4, stack->port, "Unknown Event Ind: prim %x dinfo %x\n",hh->prim, hh->dinfo); } else { if (reject) { switch(bc->cause){ case 17: cb_log(1, stack->port, "Siemens Busy reject..\n"); break; default: break; } } cb_event(event, bc, glob_mgr->user_data); } } else { cb_log(4, stack->port, "No BC found with l3id: prim %x dinfo %x\n",hh->prim, hh->dinfo); } free_msg(msg); } return 0;}static int handle_timers(msg_t* msg){ iframe_t *frm= (iframe_t*)msg->data; struct misdn_stack *stack; /* Timer Stuff */ switch (frm->prim) { case MGR_INITTIMER | CONFIRM: case MGR_ADDTIMER | CONFIRM: case MGR_DELTIMER | CONFIRM: case MGR_REMOVETIMER | CONFIRM: free_msg(msg); return(1); } if (frm->prim==(MGR_TIMER | INDICATION) ) { for (stack = glob_mgr->stack_list; stack; stack = stack->next) { itimer_t *it; if (!stack->nt) continue; it = stack->nst.tlist; /* find timer */ for(it=stack->nst.tlist; it; it=it->next) { if (it->id == (int)frm->addr) break; } if (it) { int ret; ret = mISDN_write_frame(stack->midev, msg->data, frm->addr, MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC); test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags); ret = it->function(it->data); free_msg(msg); return 1; } } cb_log(0, 0, "Timer Msg without Timer ??\n"); free_msg(msg); return 1; } return 0;}void misdn_lib_tone_generator_start(struct misdn_bchannel *bc){ bc->generate_tone=1;}void misdn_lib_tone_generator_stop(struct misdn_bchannel *bc){ bc->generate_tone=0;}static int do_tone(struct misdn_bchannel *bc, int len){ bc->tone_cnt=len; if (bc->generate_tone) { cb_event(EVENT_TONE_GENERATE, bc, glob_mgr->user_data); if ( !bc->nojitter ) { misdn_tx_jitter(bc,len); } return 1; } return 0;}#ifdef MISDN_SAVE_DATAstatic void misdn_save_data(int id, char *p1, int l1, char *p2, int l2) { char n1[32],n2[32]; sprintf(n1,"/tmp/misdn-rx-%d.raw",id); sprintf(n2,"/tmp/misdn-tx-%d.raw",id); FILE *rx=fopen(n1,"a+"); FILE *tx=fopen(n2,"a+"); if (!rx || !tx) { cb_log(0,0,"Couldn't open files: %s\n",strerror(errno)); return ; } fwrite(p1,1,l1,rx); fwrite(p2,1,l2,tx); fclose(rx); fclose(tx);}#endifvoid misdn_tx_jitter(struct misdn_bchannel *bc, int len){ char buf[4096 + mISDN_HEADER_LEN]; char *data=&buf[mISDN_HEADER_LEN]; iframe_t *txfrm= (iframe_t*)buf; int jlen, r; jlen=cb_jb_empty(bc,data,len); if (jlen) {#ifdef MISDN_SAVE_DATA misdn_save_data((bc->port*100+bc->channel), data, jlen, bc->bframe, bc->bframe_len);#endif flip_buf_bits( data, jlen); if (jlen < len) { cb_log(7,bc->port,"Jitterbuffer Underrun.\n"); } txfrm->prim = DL_DATA|REQUEST; txfrm->dinfo = 0; txfrm->addr = bc->addr|FLG_MSG_DOWN; /* | IF_DOWN; */ txfrm->len =jlen; cb_log(9, bc->port, "Transmitting %d samples 2 misdn\n", txfrm->len); r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 ); } else {#define MISDN_GEN_SILENCE#ifdef MISDN_GEN_SILENCE int cnt=len/TONE_SILENCE_SIZE; int rest=len%TONE_SILENCE_SIZE; int i; for (i=0; i<cnt; i++) { memcpy(data, tone_silence_flip, TONE_SILENCE_SIZE ); data +=TONE_SILENCE_SIZE; } if (rest) { memcpy(data, tone_silence_flip, rest); } txfrm->prim = DL_DATA|REQUEST; txfrm->dinfo = 0; txfrm->addr = bc->addr|FLG_MSG_DOWN; /* | IF_DOWN; */ txfrm->len =len; cb_log(9, bc->port, "Transmitting %d samples 2 misdn\n", txfrm->len); r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 );#endif }}static int handle_bchan(msg_t *msg){ iframe_t *frm= (iframe_t*)msg->data; struct misdn_bchannel *bc=find_bc_by_addr(frm->addr); if (!bc) { cb_log(1,0,"handle_bchan: BC not found for prim:%x with addr:%x dinfo:%x\n", frm->prim, frm->addr, frm->dinfo); return 0 ; } struct misdn_stack *stack=get_stack_by_bc(bc); if (!stack) { cb_log(0, bc->port,"handle_bchan: STACK not found for prim:%x with addr:%x dinfo:%x\n", frm->prim, frm->addr, frm->dinfo); return 0; } switch (frm->prim) { case MGR_SETSTACK| CONFIRM: cb_log(3, stack->port, "BCHAN: MGR_SETSTACK|CONFIRM pid:%d\n",bc->pid); break; case MGR_SETSTACK| INDICATION: cb_log(3, stack->port, "BCHAN: MGR_SETSTACK|IND pid:%d\n",bc->pid); break;#if 0 AGAIN: bc->addr = mISDN_get_layerid(stack->midev, bc->b_stid, bc->layer); if (!bc->addr) { if (errno == EAGAIN) { usleep(1000); goto AGAIN; } cb_log(0,stack->port,"$$$ Get Layer (%d) Id Error: %s\n",bc->layer,strerror(errno)); /* we kill the channel later, when we received some data. */ bc->addr= frm->addr; } else if ( bc->addr < 0) { cb_log(0, stack->port,"$$$ bc->addr <0 Error:%s\n",strerror(errno)); bc->addr=0; } cb_log(4, stack->port," --> Got Adr %x\n", bc->addr); free_msg(msg); switch(bc->bc_state) { case BCHAN_SETUP: bc_state_change(bc,BCHAN_SETUPED); break; case BCHAN_CLEAN_REQUEST: default: cb_log(0, stack->port," --> STATE WASN'T SETUP (but %s) in SETSTACK|IND pid:%d\n",bc_state2str(bc->bc_state), bc->pid); clean_up_bc(bc); } return 1;#endif case MGR_DELLAYER| INDICATION: cb_log(3, stack->port, "BCHAN: MGR_DELLAYER|IND pid:%d\n",bc->pid); break; case MGR_DELLAYER| CONFIRM: cb_log(3, stack->port, "BCHAN: MGR_DELLAYER|CNF pid:%d\n",bc->pid); bc->pid=0; bc->addr=0; free_msg(msg); return 1; case PH_ACTIVATE | INDICATION: case DL_ESTABLISH | INDICATION: cb_log(3, stack->port, "BCHAN: ACT Ind pid:%d\n", bc->pid); free_msg(msg); return 1; case PH_ACTIVATE | CONFIRM: case DL_ESTABLISH | CONFIRM: cb_log(3, stack->port, "BCHAN: bchan ACT Confirm pid:%d\n",bc->pid); free_msg(msg);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -