isdn_lib.c
来自「一个非常美妙的proxy。功能强大。基于sip的协议。如果还要的话」· C语言 代码 · 共 2,927 行 · 第 1/5 页
C
2,927 行
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;}static int do_tone(struct misdn_bchannel *bc, int len){ char buf[4096 + mISDN_HEADER_LEN]; iframe_t *frm= (iframe_t*)buf; int r; struct misdn_stack *stack=get_stack_by_bc(bc); if (bc->tone == TONE_NONE) return 0; frm->prim = DL_DATA|REQUEST; frm->dinfo = 0; frm->addr = bc->addr | IF_DOWN; bc->tone_cnt+=len; if (bc->tone_cnt < TONE_425_SIZE) return 1; switch(bc->tone) { case TONE_DIAL: { frm->len = TONE_425_SIZE; memcpy(&buf[mISDN_HEADER_LEN], tone_425_flip,TONE_425_SIZE); r=mISDN_write(stack->midev, buf, frm->len + mISDN_HEADER_LEN, TIMEOUT_1SEC); if (r<frm->len) { perror("Error written less than told bytes :(\n"); } } break; case TONE_ALERTING: bc->tone_cnt2++; if (bc->tone_cnt2 <= TONE_ALERT_CNT) { frm->len = TONE_425_SIZE; memcpy(&buf[mISDN_HEADER_LEN], tone_425_flip,TONE_425_SIZE); r=mISDN_write(stack->midev, buf, frm->len + mISDN_HEADER_LEN, TIMEOUT_1SEC); if (r<frm->len) { perror("Error written less than told bytes :(\n"); } } else if (bc->tone_cnt2 <= (TONE_ALERT_SILENCE_CNT)) { frm->len = TONE_SILENCE_SIZE; memcpy(&buf[mISDN_HEADER_LEN], tone_silence_flip ,TONE_SILENCE_SIZE); r=mISDN_write(stack->midev, buf, frm->len + mISDN_HEADER_LEN, TIMEOUT_1SEC); } else { bc->tone_cnt2=-1; } break; case TONE_BUSY: bc->tone_cnt2++; if (bc->tone_cnt2 <= TONE_BUSY_CNT) { frm->len = TONE_425_SIZE; memcpy(&buf[mISDN_HEADER_LEN], tone_425_flip,TONE_425_SIZE); r=mISDN_write(stack->midev, buf, frm->len + mISDN_HEADER_LEN, TIMEOUT_1SEC); if (r<frm->len) { perror("Error written less than told bytes :(\n"); } } else if (bc->tone_cnt2 <= (TONE_BUSY_SILENCE_CNT)) { frm->len = TONE_SILENCE_SIZE; memcpy(&buf[mISDN_HEADER_LEN], tone_silence_flip ,TONE_SILENCE_SIZE); r=mISDN_write(stack->midev, buf, frm->len + mISDN_HEADER_LEN, TIMEOUT_1SEC); } else { bc->tone_cnt2=-1; } break; case TONE_FILE: break; case TONE_NONE: return 0; } bc->tone_cnt -= TONE_425_SIZE ; return 1;}int handle_bchan(msg_t *msg){ iframe_t *frm= (iframe_t*)msg->data; struct misdn_bchannel *bc; bc=find_bc_by_addr(frm->addr); if (!bc) return 0 ; struct misdn_stack *stack=get_stack_by_bc(bc); if (!stack) return 0; switch (frm->prim) { case PH_ACTIVATE | INDICATION: case DL_ESTABLISH | INDICATION: cb_log(4, stack->port, "BCHAN: ACT Ind\n"); free_msg(msg); return 1; case PH_ACTIVATE | CONFIRM: case DL_ESTABLISH | CONFIRM: cb_log(4, stack->port, "BCHAN: bchan ACT Confirm\n"); free_msg(msg); return 1; case PH_DEACTIVATE | INDICATION: case DL_RELEASE | INDICATION: cb_log (4, stack->port, "BCHAN: DeACT Ind\n"); free_msg(msg); return 1; case PH_DEACTIVATE | CONFIRM: case DL_RELEASE | CONFIRM: cb_log(4, stack->port, "BCHAN: DeACT Conf\n"); free_msg(msg); return 1; case PH_CONTROL|INDICATION: { unsigned long cont = *((unsigned long *)&frm->data.p); cb_log(4, stack->port, "PH_CONTROL: port:%d channel:%d oad%d:%s dad%d:%s \n", stack->port, 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|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 MISDN_DEBUG cb_log(0, stack->port, "DL_DATA INDICATION Len %d\n", frm->len);#endif if (bc->active && frm->len > 0) { if ( !do_tone(bc, frm->len) ) { if ( misdn_cap_is_speech(bc->capability)) { if ( !bc->nojitter ) { char buf[4096 + mISDN_HEADER_LEN]; iframe_t *txfrm= (iframe_t*)buf; int len, r; len = ibuf_usedcount(bc->misdnbuf); if (len < frm->len) { /** send nothing * till we are synced **/ } else { txfrm->prim = DL_DATA|REQUEST; txfrm->dinfo = 0; txfrm->addr = bc->addr; /* | IF_DOWN; */ txfrm->len = frm->len; ibuf_memcpy_r(&buf[mISDN_HEADER_LEN], bc->misdnbuf,frm->len); cb_log(9, stack->port, "Transmitting %d samples 2 misdn\n", txfrm->len); r=mISDN_write(stack->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 ); } } } cb_event( EVENT_BCHAN_DATA, bc, glob_mgr->user_data); } } 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; break; case DL_DATA|RESPONSE:#if MISDN_DEBUG cb_log(0, stack->port, "Data response\n");#endif break; case DL_DATA | REQUEST: break; } return 0;}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_ADDRMASK ) ); if (!stack || stack->mode != NT_MODE) { 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 port:%d\n", err,stack->port); } else if (nt_err_cnt < 105){ cb_log(0, stack->port, "NT Stack sends us error: %d port:%d over 100 times, so I'll stop this message\n", err,stack->port); nt_err_cnt = - 1; } } free_msg(msg); return 1; } return 1;}int handle_frm(msg_t *msg){ iframe_t *frm = (iframe_t*) msg->data; struct misdn_stack *stack=find_stack_by_addr(frm->addr & IF_ADDRMASK); if (!stack || stack->mode != TE_MODE) { return 0; } { struct misdn_bchannel *bc; if(handle_cr(frm)) { free_msg(msg); return 1; } bc=find_bc_by_l3id(stack, frm->dinfo); 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 **/ handle_event(bc, event, frm); /* 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: port:%d\n", frm->addr&IF_CONTRMASK); break; case RESPONSE_IGNORE_SETUP: /* I think we should send CC_RELEASE_CR, but am not sure*/ empty_chan_in_stack(stack, bc->channel); empty_bc(bc); cb_log(0, stack->port, "GOT IGNORE SETUP: port:%d\n", frm->addr&IF_CONTRMASK); break; case RESPONSE_OK: cb_log(4, stack->port, "GOT SETUP OK: port:%d\n", frm->addr&IF_CONTRMASK); break; default: break; } } cb_log(5, stack->port, "Freeing Msg on prim:%x port:%d\n",frm->prim, frm->addr&IF_CONTRMASK); free_msg(msg); return 1;#endif } else { cb_log(0, stack->port, "NO BC FOR STACK: port:%d\n", frm->addr&IF_CONTRMASK); } } cb_log(4, stack->port, "TE_FRM_HANDLER: Returning 0 on prim:%x port:%d\n",frm->prim, frm->addr&IF_CONTRMASK); return 0;}int handle_l1(msg_t *msg){ iframe_t *frm = (iframe_t*) msg->data; struct misdn_stack *stack = find_stack_by_port(frm->addr & IF_CONTRMASK); int i ; if (!stack) return 0 ; switch (frm->prim) { case PH_ACTIVATE | CONFIRM: case PH_ACTIVATE | INDICATION: cb_log (1, stack->port, "L1: PH L1Link Up! port:%d\n",stack->port); stack->l1link=1; if (stack->mode==NT_MODE) { if (stack->nst.l1_l2(&stack->nst, msg)) free_msg(msg); } 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_DEACTIVATE | CONFIRM: case PH_DEACTIVATE | INDICATION: cb_log (1, stack->port, "L1: PH L1Link Down! port:%d\n",stack->port); 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->mode==NT_MODE) { 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;}int handle_l2(msg_t *msg){ iframe_t *frm = (iframe_t*) msg->data; struct misdn_stack *stack = find_stack_by_addr(frm->addr & IF_ADDRMASK); if (!stack) return 0 ; switch(frm->prim) {#ifdef DL_STATUS case DL_STATUS | INDICATION: case DL_STATUS | CONFIRM: cb_log (3, stack->port, "L2: DL_STATUS! port:%d\n", stack->port); switch (frm->dinfo) { case SDL_ESTAB: cb_log (4, stack->port, " --> SDL_ESTAB port:%d\n", stack->port); stack->l1link=1; goto dl_estab; case SDL_REL: cb_log (4, stack->port, " --> SDL_REL port:%d\n", stack->port); stack->l1link=0; misdn_lib_get_l2_up(stack); goto dl_rel; } break;#endif case DL_ESTABLISH | INDICATION: case DL_ESTABLISH | CONFIRM:#ifdef DL_STATUS dl_estab:#endif { cb_log (3, stack->port, "L2: L2Link Up! port:%d\n", stack->port); stack->l2link=1; free_msg(msg); return 1; } break; case DL_RELEASE | INDICATION: case DL_RELEASE | CONFIRM:#ifdef DL_STATUS dl_rel:#endif { cb_log (3, stack->port, "L2: L2Link Down! port:%d\n", stack->port); stack->l2link=0; free_msg(msg); return 1; } break; } return 0;}int handle_mgmt(msg_t *msg){ iframe_t *frm = (iframe_t*) msg->data; 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;}msg_t *fetch_msg(int midev) { msg_t *msg=alloc_msg(MAX_MSG_SIZE); int r; fd_set rdfs; if (!msg) { cb_log(0, 0, "fetch_msg: alloc msg failed !!"); return NULL; } FD_ZERO(&rdfs); FD_SET(midev,&rdfs); mISDN_select(FD_SETSIZE, &rdfs, NULL, NULL, NULL); if (FD_ISSET(midev, &rdfs)) { r=mISDN_read(midev,msg->data,MAX_MSG_SIZE,0); msg->len=r; if (r==0) { free_msg(msg); /* danger, cauz usualy freeing in main_loop */ printf ("Got empty Msg?\n"); return NULL; } return msg; } else { printf ("Select timeout\n"); } return NULL;}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; //cb_log(5, 0, "In event_catcher thread\n"); while (1) { msg_t *msg = fetch_msg(midev); iframe_t *frm; if (!msg) continue; frm = (iframe_t*) msg->data; port = frm->addr&IF_CONTRMASK; /** 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 && frm->prim == 0xffffffff ) { fff_frm++; free_msg(msg); continue; } else { if (fff_frm) { cb_log(0, port, "*** Alert: %d fff_frms caught\n", fff_frm); fff_frm = 0 ; } } manager_isdn_handler(frm, msg); }}/** App Interface **/int te_lib_init() { char buff[1025]; iframe_t *frm=(iframe_t*)buff; int midev=mISDN_open(); int ret; memset(buff,0,1025); if (midev<=0) return midev; /* create entity for layer 3 TE-mode */ mISDN_write_frame(midev, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC); ret = mISDN_read_frame(midev, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?