isdn_lib.c
来自「一个非常美妙的proxy。功能强大。基于sip的协议。如果还要的话」· C语言 代码 · 共 2,927 行 · 第 1/5 页
C
2,927 行
struct misdn_bchannel *find_bc_by_l3id(struct misdn_stack *stack, unsigned long l3id){ int i; for (i=0; i<stack->b_num; i++) { if (stack->bc[i].l3_id == l3id) return &stack->bc[i] ; } return stack_holder_find(stack,l3id);}struct misdn_bchannel *find_bc_holded(struct misdn_stack *stack){ int i; for (i=0; i<stack->b_num; i++) { if (stack->bc[i].holded ) return &stack->bc[i] ; } return NULL;}struct misdn_bchannel *find_bc_by_addr(unsigned long addr){ int port = addr & IF_CONTRMASK; struct misdn_stack* stack; int i; for (stack=glob_mgr->stack_list; stack; stack=stack->next) { if (stack->port == port) { for (i=0; i< stack->b_num; i++) { if (stack->bc[i].addr==addr) { return &stack->bc[i]; } } } } return NULL;}int handle_event ( struct misdn_bchannel *bc, enum event_e event, iframe_t *frm){ struct misdn_stack *stack=get_stack_by_bc(bc); if (stack->mode == TE_MODE) { switch (event) { case EVENT_CONNECT_ACKNOWLEDGE: manager_bchannel_activate(bc); break; case EVENT_CONNECT: if ( *bc->crypt_key ) { cb_log(4, stack->port, "ENABLING BLOWFISH port:%d channel:%d oad%d:%s dad%d:%s\n", stack->port, bc->channel, bc->onumplan,bc->oad, bc->dnumplan,bc->dad); manager_ph_control_block(bc, BF_ENABLE_KEY, bc->crypt_key, strlen(bc->crypt_key) ); } case EVENT_SETUP: if (bc->channel>0 && bc->channel<255) set_chan_in_stack(stack, bc->channel); break; case EVENT_ALERTING: case EVENT_PROGRESS: case EVENT_PROCEEDING: case EVENT_SETUP_ACKNOWLEDGE: { struct misdn_stack *stack=find_stack_by_port(frm->addr&IF_CONTRMASK); if (!stack) return -1; if (bc->channel == 0xff) { bc->channel=find_free_chan_in_stack(stack, 0); if (!bc->channel) { cb_log(0, stack->port, "Any Channel Requested, but we have no more!!\n"); break; } } if (stack->mode == TE_MODE) { setup_bc(bc); } } default: break; } } else { /** NT MODE **/ } return 0;}int handle_new_process(struct misdn_stack *stack, iframe_t *frm){ struct misdn_bchannel* bc=misdn_lib_get_free_bc(frm->addr&IF_CONTRMASK, 0); if (!bc) { cb_log(0, 0, " --> !! lib: No free channel!\n"); return -1; } cb_log(4, stack->port, " --> new_process: New L3Id: %x\n",frm->dinfo); bc->l3_id=frm->dinfo; if (mypid>5000) mypid=0; bc->pid=mypid++; return 0;}int handle_cr ( iframe_t *frm){ struct misdn_stack *stack=find_stack_by_port(frm->addr&IF_CONTRMASK); if (!stack) return -1; switch (frm->prim) { case CC_NEW_CR|INDICATION: cb_log(4, stack->port, " --> lib: NEW_CR Ind with l3id:%x port:%d\n",frm->dinfo, stack->port); handle_new_process(stack, frm); return 1; case CC_NEW_CR|CONFIRM: return 1; case CC_NEW_CR|REQUEST: return 1; case CC_RELEASE_CR|REQUEST: return 1; case CC_RELEASE_CR|CONFIRM: break; case CC_RELEASE_CR|INDICATION: cb_log(4, stack->port, " --> lib: RELEASE_CR Ind with l3id:%x\n",frm->dinfo); { struct misdn_bchannel *bc=find_bc_by_l3id(stack, frm->dinfo); struct misdn_bchannel dummybc; if (!bc) { cb_log(4, stack->port, " --> Didn't found BC so temporarly creating dummy BC (l3id:%x) on port:%d\n", frm->dinfo, stack->port); memset (&dummybc,0,sizeof(dummybc)); dummybc.port=stack->port; dummybc.l3_id=frm->dinfo; bc=&dummybc; } if (bc) { cb_log(4, stack->port, " --> lib: CLEANING UP l3id: %x\n",frm->dinfo); empty_chan_in_stack(stack,bc->channel); empty_bc(bc); clean_up_bc(bc); dump_chan_list(stack); bc->pid = 0; cb_event(EVENT_CLEANUP, bc, glob_mgr->user_data); if (bc->stack_holder) { cb_log(4,stack->port, "REMOVEING Holder\n"); stack_holder_remove( stack, bc); free(bc); } } else { if (stack->mode == NT_MODE) cb_log(4, stack->port, "BC with dinfo: %x not found.. (prim was %x and addr %x)\n",frm->dinfo, frm->prim, frm->addr); } return 1; } break; } return 0;}/*Emptys bc if it's reserved (no SETUP out yet)*/void misdn_lib_release(struct misdn_bchannel *bc){ struct misdn_stack *stack=get_stack_by_bc(bc); if (!stack) { cb_log(1,0,"misdn_release: No Stack found\n"); return; } if (bc->channel>=0) { empty_chan_in_stack(stack,bc->channel); empty_bc(bc); } clean_up_bc(bc);}int misdn_lib_get_port_up (int port) { /* Pull Up L1 if we have JOLLY */ struct misdn_stack *stack; for (stack=glob_mgr->stack_list; stack; stack=stack->next) { if (stack->port == port) { if (!stack->l1link) misdn_lib_get_l1_up(stack); if (!stack->l2link) misdn_lib_get_l2_up(stack); return 0; } } return 0;}int misdn_lib_send_facility(struct misdn_bchannel *bc, enum facility_type fac, void *data){ bc->facility=fac; strcpy(bc->facility_calldeflect_nr,(char*)data); misdn_lib_send_event(bc,EVENT_FACILITY); return 0;}int misdn_lib_port_up(int port){ struct misdn_stack *stack; for (stack=glob_mgr->stack_list; stack; stack=stack->next) { if (stack->port == port) { if (stack->mode == NT_MODE) { if (stack->l1link) return 1; else return 0; } else { if (stack->l1link) return 1; else return 0; } } } return -1;}inthandle_event_nt(void *dat, void *arg){ manager_t *mgr = (manager_t *)dat; msg_t *msg = (msg_t *)arg;#ifdef MISDNUSER_JOLLY mISDNuser_head_t *hh;#else mISDN_head_t *hh;#endif struct misdn_stack *stack=find_stack_by_mgr(mgr); int port; if (!msg || !mgr) return(-EINVAL);#ifdef MISDNUSER_JOLLY hh=(mISDNuser_head_t*)msg->data;#else hh=(mISDN_head_t*)msg->data;#endif port=hh->dinfo & IF_CONTRMASK; cb_log(4, stack->port, " --> lib: prim %x dinfo %x port: %d\n",hh->prim, hh->dinfo ,stack->port); { switch(hh->prim){ case CC_RETRIEVE|INDICATION: { iframe_t frm; /* fake te frm to add callref to global callreflist */ frm.dinfo = hh->dinfo; frm.addr=stack->upper_id; frm.prim = CC_NEW_CR|INDICATION; if (handle_cr(&frm)< 0) { 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; } struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo); cb_event(EVENT_NEW_BC, bc, glob_mgr->user_data); struct misdn_bchannel *hold_bc=stack_holder_find(stack,bc->l3_id); if (hold_bc) { cb_log(4, stack->port, "REMOVEING Holder\n"); stack_holder_remove(stack, hold_bc); free(hold_bc); } } 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, bc?stack->port:0, " --> lib: Event_ind:SETUP CONFIRM [NT] : new L3ID is %x\n",l3id ); if (!bc) { cb_log(4, 0, "Bc Not found (after SETUP CONFIRM)\n"); return 0; } bc->l3_id=l3id; cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data); } free_msg(msg); return 0; case CC_SETUP|INDICATION: { iframe_t frm; /* fake te frm to add callref to global callreflist */ frm.dinfo = hh->dinfo; frm.addr=stack->upper_id; frm.prim = CC_NEW_CR|INDICATION; if (handle_cr(&frm)< 0) { 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; } } break; case CC_CONNECT|INDICATION: case CC_ALERTING|INDICATION: case CC_PROCEEDING|INDICATION: { 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 port:%d\n",hh->dinfo, stack->port); 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; } setup_bc(bc); } 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) { //repair reject bug int myprocid=bc->l3_id&0x0000ffff; hh->dinfo=(hh->dinfo&0xffff0000)|myprocid; cb_log(4,stack->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: { struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo); cb_log(4, stack->port, " --> RELEASE CONFIRM, sending RELEASE_COMPLETE\n"); if (bc) misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); } hh->prim=CC_RELEASE|INDICATION; 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; 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 port:%d\n", hh->dinfo, stack->port); memset (&dummybc,0,sizeof(dummybc)); dummybc.port=stack->port; dummybc.l3_id=hh->dinfo; bc=&dummybc; } if (bc) {#ifdef MISDNUSER_JOLLY if ( (bc->l3_id & 0xff00) == 0xff00) { cb_log(4, stack->port, " --> Removing Process Id:%x on port:%d\n", bc->l3_id&0xff, stack->port); stack->procids[bc->l3_id&0xff] = 0 ; }#else if ( (bc->l3_id & 0xfff0) == 0xfff0) { cb_log(4, stack->port, " --> Removing Process Id:%x on port:%d\n", bc->l3_id&0xf, stack->port); stack->procids[bc->l3_id&0xf] = 0 ; } #endif } else cb_log(0, stack->port, "Couldnt find BC so I couldnt remove the Process!!!! this is bad Port:%d\n", stack->port ); handle_cr(&frm); 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, 0, " --> In NEW_CR: didn't found bc ??\n"); return -1;};#ifdef MISDNUSER_JOLLY if (((l3id&0xff00)!=0xff00) && ((bc->l3_id&0xff00)==0xff00)) { cb_log(4, stack->port, " --> Removing Process Id:%x on port:%d\n", 0xff&bc->l3_id, stack->port); stack->procids[bc->l3_id&0xff] = 0 ; }#else if (((l3id&0xfff0)!=0xfff0) && ((bc->l3_id&0xfff0)==0xfff0)) { cb_log(4, stack->port, "Removing Process Id:%x on port:%d\n", 0xf&bc->l3_id, stack->port); stack->procids[bc->l3_id&0xf] = 0 ; }#endif 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(4, stack->port, "%% GOT L2 Activate Info port:%d\n",stack->port); stack->l2link = 1; free_msg(msg); return 0; } break; case DL_RELEASE | INDICATION: case DL_RELEASE | CONFIRM: { cb_log(4, stack->port, "%% GOT L2 DeActivate Info port:%d\n",stack->port); stack->l2link = 0; /** Clean the L3 here **/ if (cb_clearl3_true()) clear_l3(stack); 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) on port:%d\n", hh->dinfo, stack->port); memset (&dummybc,0,sizeof(dummybc)); dummybc.port=stack->port; dummybc.l3_id=hh->dinfo; bc=&dummybc; } if (bc ) { isdn_msg_parse_event(msgs_g,msg,bc, 1); 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 { 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;}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->mode != NT_MODE) continue; it = stack->nst.tlist; /* find timer */ for(it=stack->nst.tlist; it; it=it->next) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?