📄 isdn_lib.c
字号:
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 ) { 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 int 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 *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); handle_frm_bc: if (bc ) { 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 **/ int 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); 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; } } cb_log(5, stack->port, "Freeing Msg on prim:%x \n",frm->prim); free_msg(msg); return 1;#endif } else { cb_log(0, stack->port, " --> Didn't find BC so temporarly creating dummy BC (l3id:%x) on this port.\n", frm->dinfo); struct misdn_bchannel dummybc; 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"); for (i=0; i<=stack->b_num; i++) { if (global_state == MISDN_INITIALIZED) { cb_event(EVENT_CLEANUP, &stack->bc[i], glob_mgr->user_data); } } 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){ 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; } struct misdn_stack * 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; clear_l3(stack); 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_log(5, 0, "$$$ MGMT FRAME: prim %x addr %x dinfo %x\n",frm->prim, frm->addr, frm->dinfo) ; free_msg(msg); return 1; } */ return 0;}static msg_t *fetch_msg(int midev) { msg_t *msg=alloc_msg(MAX_MSG_SIZE); int r; if (!msg) { cb_log(0, 0, "fetch_msg: alloc msg failed !!"); return NULL; } AGAIN: r=mISDN_read(midev,msg->data,MAX_MSG_SIZE, TIMEOUT_10SEC); msg->len=r; if (r==0) { free_msg(msg); /* danger, cauz usualy freeing in main_loop */ cb_log(6,0,"Got empty Msg..\n"); return NULL; } if (r<0) { if (errno == EAGAIN) { /*we wait for mISDN here*/ cb_log(4,0,"mISDN_read wants us to wait\n"); usleep(5000); goto AGAIN; } cb_log(0,0,"mISDN_read returned :%d error:%s (%d)\n",r,strerror(errno),errno); }#if 0 if (!(frm->prim == (DL_DATA|INDICATION) )|| (frm->prim == (PH_DATA|INDICATION))) cb_log(0,0,"prim: %x dinfo:%x addr:%x msglen:%d frm->len:%d\n",frm->prim, frm->dinfo, frm->addr, msg->len,frm->len );#endif return msg;}void misdn_lib_isdn_l1watcher(int port){ struct misdn_stack *stack; for (stack = glob_mgr->stack_list; stack && (stack->port != port); stack = stack->next) ; if (stack) { cb_log(4, port, "Checking L1 State\n"); if (!stack->l1link) { cb_log(4, port, "L1 State Down, trying to get it up again\n"); misdn_lib_get_short_status(stack); misdn_lib_get_l1_up(stack); misdn_lib_get_l2_up(stack); } }}static void misdn_lib_isdn_event_catcher(void *arg){ struct misdn_lib *mgr = arg; int zero_frm=0 , fff_frm=0 ; int midev= mgr->midev; int port=0; while (1) { msg_t *msg = fetch_msg(midev); iframe_t *frm; if (!msg) continue; frm = (iframe_t*) msg->data; /** When we make a call from NT2Ast we get this frames **/ if (frm->len == 0 && frm->addr == 0 && frm->dinfo == 0 && frm->prim == 0 ) { zero_frm++; free_msg(msg); continue; } else { if (zero_frm) { cb_log(0, port, "*** Alert: %d zero_frms caught\n", zero_frm); zero_frm = 0 ; } } /** I get this sometimes after setup_bc **/ if (frm->len == 0 && frm->dinfo == 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -