📄 isdn_lib.c
字号:
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); return 1; case DL_ESTABLISH | REQUEST: { char buf[128]; mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_TARGET | FLG_MSG_DOWN, DL_ESTABLISH | CONFIRM, 0,0, NULL, TIMEOUT_1SEC); } free_msg(msg); return 1; case DL_RELEASE|REQUEST: { char buf[128]; mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_TARGET | FLG_MSG_DOWN, DL_RELEASE| CONFIRM, 0,0, NULL, TIMEOUT_1SEC); } free_msg(msg); return 1; case PH_DEACTIVATE | INDICATION: case DL_RELEASE | INDICATION: cb_log (3, stack->port, "BCHAN: DeACT Ind pid:%d\n",bc->pid); free_msg(msg); return 1; case PH_DEACTIVATE | CONFIRM: case DL_RELEASE | CONFIRM: cb_log(3, stack->port, "BCHAN: DeACT Conf pid:%d\n",bc->pid); free_msg(msg); return 1; case PH_CONTROL|INDICATION: { unsigned int *cont = (unsigned int *) &frm->data.p; cb_log(4, stack->port, "PH_CONTROL: channel:%d oad%d:%s dad%d:%s \n", bc->channel, bc->onumplan,bc->oad, bc->dnumplan,bc->dad); if ((*cont & ~DTMF_TONE_MASK) == DTMF_TONE_VAL) { int dtmf = *cont & DTMF_TONE_MASK; cb_log(4, stack->port, " --> DTMF TONE: %c\n",dtmf); bc->dtmf=dtmf; cb_event(EVENT_DTMF_TONE, bc, glob_mgr->user_data); free_msg(msg); return 1; } if (*cont == BF_REJECT) { cb_log(4, stack->port, " --> BF REJECT\n"); free_msg(msg); return 1; } if (*cont == BF_ACCEPT) { cb_log(4, stack->port, " --> BF ACCEPT\n"); free_msg(msg); return 1; } } break; case PH_DATA|REQUEST: case DL_DATA|REQUEST: cb_log(0, stack->port, "DL_DATA REQUEST \n"); do_tone(bc, 64); free_msg(msg); return 1; case PH_DATA|INDICATION: case DL_DATA|INDICATION: { bc->bframe = (void*)&frm->data.i; bc->bframe_len = frm->len; /** Anyway flip the bufbits **/ if ( misdn_cap_is_speech(bc->capability) ) flip_buf_bits(bc->bframe, bc->bframe_len); if (!bc->bframe_len) { cb_log(2, stack->port, "DL_DATA INDICATION bc->addr:%x frm->addr:%x\n", bc->addr, frm->addr); free_msg(msg); return 1; } if ( (bc->addr&STACK_ID_MASK) != (frm->addr&STACK_ID_MASK) ) { cb_log(2, stack->port, "DL_DATA INDICATION bc->addr:%x frm->addr:%x\n", bc->addr, frm->addr); free_msg(msg); return 1; } #if MISDN_DEBUG cb_log(0, stack->port, "DL_DATA INDICATION Len %d\n", frm->len);#endif if ( (bc->bc_state == BCHAN_ACTIVATED) && frm->len > 0) { int t;#ifdef MISDN_B_DEBUG cb_log(0,bc->port,"do_tone START\n");#endif t=do_tone(bc,frm->len);#ifdef MISDN_B_DEBUG cb_log(0,bc->port,"do_tone STOP (%d)\n",t);#endif if ( !t ) { int i; if ( misdn_cap_is_speech(bc->capability)) { if ( !bc->nojitter ) {#ifdef MISDN_B_DEBUG cb_log(0,bc->port,"tx_jitter START\n");#endif misdn_tx_jitter(bc,frm->len);#ifdef MISDN_B_DEBUG cb_log(0,bc->port,"tx_jitter STOP\n");#endif } }#ifdef MISDN_B_DEBUG cb_log(0,bc->port,"EVENT_B_DATA START\n");#endif i=cb_event( EVENT_BCHAN_DATA, bc, glob_mgr->user_data);#ifdef MISDN_B_DEBUG cb_log(0,bc->port,"EVENT_B_DATA STOP\n");#endif if (i<0) { cb_log(10,stack->port,"cb_event returned <0\n"); /*clean_up_bc(bc);*/ } } } free_msg(msg); return 1; } case PH_CONTROL | CONFIRM: cb_log(4, stack->port, "PH_CONTROL|CNF bc->addr:%x\n", frm->addr); free_msg(msg); return 1; case PH_DATA | CONFIRM: case DL_DATA|CONFIRM:#if MISDN_DEBUG cb_log(0, stack->port, "Data confirmed\n");#endif free_msg(msg); return 1; case DL_DATA|RESPONSE:#if MISDN_DEBUG cb_log(0, stack->port, "Data response\n");#endif break; } return 0;}static int handle_frm_nt(msg_t *msg){ iframe_t *frm= (iframe_t*)msg->data; struct misdn_stack *stack; int err=0; stack=find_stack_by_addr( frm->addr ); if (!stack || !stack->nt) { return 0; } if ((err=stack->nst.l1_l2(&stack->nst,msg))) { if (nt_err_cnt > 0 ) { if (nt_err_cnt < 100) { nt_err_cnt++; cb_log(0, stack->port, "NT Stack sends us error: %d \n", err); } else if (nt_err_cnt < 105){ cb_log(0, stack->port, "NT Stack sends us error: %d over 100 times, so I'll stop this message\n", err); nt_err_cnt = - 1; } } free_msg(msg); return 1; } return 1;}static int handle_frm(msg_t *msg){ iframe_t *frm = (iframe_t*) msg->data; struct misdn_stack *stack=find_stack_by_addr(frm->addr); if (!stack || stack->nt) { return 0; } cb_log(4,stack?stack->port:0,"handle_frm: frm->addr:%x frm->prim:%x\n",frm->addr,frm->prim); { struct misdn_bchannel dummybc; struct misdn_bchannel *bc; int ret=handle_cr(stack, frm); if (ret<0) { cb_log(3,stack?stack->port:0,"handle_frm: handle_cr <0 prim:%x addr:%x\n", frm->prim, frm->addr); } if(ret) { free_msg(msg); return 1; } bc=find_bc_by_l3id(stack, frm->dinfo); if (!bc && (frm->prim==(CC_RESTART|CONFIRM)) ) { make_dummy(&dummybc, stack->port, MISDN_ID_GLOBAL, stack->nt, 0); bc=&dummybc; } if (!bc && (frm->prim==(CC_SETUP|INDICATION)) ) { make_dummy(&dummybc, stack->port, MISDN_ID_GLOBAL, stack->nt, 0); dummybc.port=stack->port; dummybc.l3_id=frm->dinfo; bc=&dummybc; misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); free_msg(msg); return 1; } handle_frm_bc: if (bc ) { int ret; enum event_e event = isdn_msg_get_event(msgs_g, msg, 0); enum event_response_e response=RESPONSE_OK; isdn_msg_parse_event(msgs_g,msg,bc, 0); /** Preprocess some Events **/ ret=handle_event(bc, event, frm); if (ret<0) { cb_log(0,stack->port,"couldn't handle event\n"); free_msg(msg); return 1; } /* shoot up event to App: */ cb_log(5, stack->port, "lib Got Prim: Addr %x prim %x dinfo %x\n",frm->addr, frm->prim, frm->dinfo); if(!isdn_get_info(msgs_g,event,0)) cb_log(0, stack->port, "Unknown Event Ind: Addr:%x prim %x dinfo %x\n",frm->addr, frm->prim, frm->dinfo); else response=cb_event(event, bc, glob_mgr->user_data);#if 1 if (event == EVENT_SETUP) { switch (response) { case RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE: cb_log(0, stack->port, "TOTALY IGNORING SETUP \n"); break; case RESPONSE_IGNORE_SETUP: /* I think we should send CC_RELEASE_CR, but am not sure*/ bc->out_cause=16; case RESPONSE_RELEASE_SETUP: misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); if (bc->channel>0) empty_chan_in_stack(stack, bc->channel); empty_bc(bc); bc_state_change(bc,BCHAN_CLEANED); bc->in_use=0; cb_log(0, stack->port, "GOT IGNORE SETUP\n"); break; case RESPONSE_OK: cb_log(4, stack->port, "GOT SETUP OK\n"); break; default: break; } } if (event == EVENT_RELEASE_COMPLETE) { /* release bchannel only after we've anounced the RELEASE_COMPLETE */ int channel=bc->channel; int tmpcause=bc->cause; int tmp_out_cause=bc->out_cause; empty_bc(bc); bc->cause=tmpcause; bc->out_cause=tmp_out_cause; clean_up_bc(bc); if (tmpcause == 44) { cb_log(0,stack->port,"**** Received CAUSE:44, so not cleaning up channel %d\n", channel); cb_log(0,stack->port,"**** This channel is now no longer available,\nplease try to restart it with 'misdn send restart <port> <channel>'\n"); set_chan_in_stack(stack, channel); bc->channel=channel; misdn_lib_send_restart(stack->port, channel); } else { if (channel>0) empty_chan_in_stack(stack, channel); } bc->in_use=0; } if (event == EVENT_RESTART) { cb_log(0, stack->port, "**** Received RESTART_ACK channel:%d\n", bc->restart_channel); empty_chan_in_stack(stack, bc->restart_channel); } cb_log(5, stack->port, "Freeing Msg on prim:%x \n",frm->prim); free_msg(msg); return 1;#endif } else { struct misdn_bchannel dummybc; cb_log(0, stack->port, " --> Didn't find BC so temporarly creating dummy BC (l3id:%x) on this port.\n", frm->dinfo); memset (&dummybc,0,sizeof(dummybc)); dummybc.port=stack->port; dummybc.l3_id=frm->dinfo; bc=&dummybc; goto handle_frm_bc; } } cb_log(4, stack->port, "TE_FRM_HANDLER: Returning 0 on prim:%x \n",frm->prim); return 0;}static int handle_l1(msg_t *msg){ iframe_t *frm = (iframe_t*) msg->data; struct misdn_stack *stack = find_stack_by_addr(frm->addr); int i ; if (!stack) return 0 ; switch (frm->prim) { case PH_ACTIVATE | CONFIRM: case PH_ACTIVATE | INDICATION: cb_log (3, stack->port, "L1: PH L1Link Up!\n"); stack->l1link=1; if (stack->nt) { if (stack->nst.l1_l2(&stack->nst, msg)) free_msg(msg); if (stack->ptp) misdn_lib_get_l2_up(stack); } else { free_msg(msg); } for (i=0;i<=stack->b_num; i++) { if (stack->bc[i].evq != EVENT_NOTHING) { cb_log(4, stack->port, "Fireing Queued Event %s because L1 got up\n", isdn_get_info(msgs_g, stack->bc[i].evq, 0)); misdn_lib_send_event(&stack->bc[i],stack->bc[i].evq); stack->bc[i].evq=EVENT_NOTHING; } } return 1; case PH_ACTIVATE | REQUEST: free_msg(msg); cb_log(3,stack->port,"L1: PH_ACTIVATE|REQUEST \n"); return 1; case PH_DEACTIVATE | REQUEST: free_msg(msg); cb_log(3,stack->port,"L1: PH_DEACTIVATE|REQUEST \n"); return 1; case PH_DEACTIVATE | CONFIRM: case PH_DEACTIVATE | INDICATION: cb_log (3, stack->port, "L1: PH L1Link Down! \n"); #if 0 for (i=0; i<=stack->b_num; i++) { if (global_state == MISDN_INITIALIZED) { cb_event(EVENT_CLEANUP, &stack->bc[i], glob_mgr->user_data); } }#endif if (stack->nt) { if (stack->nst.l1_l2(&stack->nst, msg)) free_msg(msg); } else { free_msg(msg); } stack->l1link=0; stack->l2link=0; return 1; } return 0;}static int handle_l2(msg_t *msg){ iframe_t *frm = (iframe_t*) msg->data; struct misdn_stack *stack = find_stack_by_addr(frm->addr); if (!stack) { return 0 ; } switch(frm->prim) { case DL_ESTABLISH | REQUEST: cb_log(1,stack->port,"DL_ESTABLISH|REQUEST \n"); return 1; case DL_RELEASE | REQUEST: cb_log(1,stack->port,"DL_RELEASE|REQUEST \n"); return 1; case DL_ESTABLISH | INDICATION: case DL_ESTABLISH | CONFIRM: { cb_log (3, stack->port, "L2: L2Link Up! \n"); if (stack->ptp && stack->l2link) { cb_log (-1, stack->port, "L2: L2Link Up! but it's already UP.. must be faulty, blocking port\n"); cb_event(EVENT_PORT_ALARM, &stack->bc[0], glob_mgr->user_data); } stack->l2link=1; free_msg(msg); return 1; } break; case DL_RELEASE | INDICATION: case DL_RELEASE | CONFIRM: { cb_log (3, stack->port, "L2: L2Link Down! \n"); stack->l2link=0; free_msg(msg); return 1; } break; } return 0;}static int handle_mgmt(msg_t *msg){ struct misdn_stack *stack; iframe_t *frm = (iframe_t*) msg->data; if ( (frm->addr == 0) && (frm->prim == (MGR_DELLAYER|CONFIRM)) ) { cb_log(2, 0, "MGMT: DELLAYER|CONFIRM Addr: 0 !\n") ; free_msg(msg); return 1; } stack=find_stack_by_addr(frm->addr); if (!stack) { if (frm->prim == (MGR_DELLAYER|CONFIRM)) { cb_log(2, 0, "MGMT: DELLAYER|CONFIRM Addr: %x !\n", frm->addr) ; free_msg(msg); return 1; } return 0; } switch(frm->prim) { case MGR_SHORTSTATUS | INDICATION: case MGR_SHORTSTATUS | CONFIRM: cb_log(5, 0, "MGMT: Short status dinfo %x\n",frm->dinfo); switch (frm->dinfo) { case SSTATUS_L1_ACTIVATED: cb_log(3, 0, "MGMT: SSTATUS: L1_ACTIVATED \n"); stack->l1link=1; break; case SSTATUS_L1_DEACTIVATED: cb_log(3, 0, "MGMT: SSTATUS: L1_DEACTIVATED \n"); stack->l1link=0;#if 0 clear_l3(stack);#endif break; case SSTATUS_L2_ESTABLISHED: cb_log(3, stack->port, "MGMT: SSTATUS: L2_ESTABLISH \n"); /*when the L2 goes UP, L1 needs to be UP too*/ stack->l1link=1; stack->l2link=1; break; case SSTATUS_L2_RELEASED: cb_log(3, stack->port, "MGMT: SSTATUS: L2_RELEASED \n"); stack->l2link=0; break; } free_msg(msg); return 1; case MGR_SETSTACK | INDICATION: cb_log(4, stack->port, "MGMT: SETSTACK|IND dinfo %x\n",frm->dinfo); free_msg(msg); return 1; case MGR_DELLAYER | CONFIRM: cb_log(4, stack->port, "MGMT: DELLAYER|CNF dinfo %x\n",frm->dinfo) ; free_msg(msg); return 1; } /* if ( (frm->prim & 0x0f0000) == 0x0f0000) { cb_lo
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -