isdn_lib.c
来自「一个非常美妙的proxy。功能强大。基于sip的协议。如果还要的话」· C语言 代码 · 共 2,927 行 · 第 1/5 页
C
2,927 行
act.addr = (stack->upper_id & IF_ADDRMASK) | IF_DOWN; act.dinfo = 0; act.len = 0; return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC); } return 0;}int misdn_lib_get_l2_status(struct misdn_stack *stack){ iframe_t act; #ifdef DL_STATUS act.prim = DL_STATUS | REQUEST; #else act.prim = DL_ESTABLISH | REQUEST;#endif act.addr = (stack->upper_id & IF_ADDRMASK) | IF_DOWN; act.dinfo = 0; act.len = 0; return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);}static int create_process (int midev, struct misdn_bchannel *bc) { iframe_t ncr; int l3_id; int i; struct misdn_stack *stack=get_stack_by_bc(bc); int free_chan; if (stack->mode == NT_MODE) { free_chan = find_free_chan_in_stack(stack, bc->channel_preselected?bc->channel:0); if (!free_chan) return -1; bc->channel=free_chan; for (i=0; i <= MAXPROCS; i++) if (stack->procids[i]==0) break; if (i== MAXPROCS) { cb_log(0, stack->port, "Couldnt Create New ProcId Port:%d\n",stack->port); return -1; } stack->procids[i]=1;#ifdef MISDNUSER_JOLLY l3_id = 0xff00 | i;#else l3_id = 0xfff0 | i;#endif ncr.prim = CC_NEW_CR | REQUEST; ncr.addr = (stack->upper_id & IF_ADDRMASK) | IF_DOWN ; ncr.dinfo = l3_id; ncr.len = 0; bc->l3_id = l3_id; if (mypid>5000) mypid=0; bc->pid=mypid++; cb_log(3, stack->port, " --> new_l3id %x\n",l3_id); } else { if (stack->ptp || bc->te_choose_channel) { /* we know exactly which channels are in use */ free_chan = find_free_chan_in_stack(stack, bc->channel_preselected?bc->channel:0); if (!free_chan) return -1; bc->channel=free_chan; } else { /* other phones could have made a call also on this port (ptmp) */ bc->channel=0xff; } /* if we are in te-mode, we need to create a process first */ if (newteid++ > 0xffff) newteid = 0x0001; l3_id = (entity<<16) | newteid; /* preparing message */ ncr.prim = CC_NEW_CR | REQUEST; ncr.addr = (stack->upper_id & IF_ADDRMASK) | IF_DOWN ; ncr.dinfo =l3_id; ncr.len = 0; /* send message */ bc->l3_id = l3_id; if (mypid>5000) mypid=0; bc->pid=mypid++; cb_log(3, stack->port, "--> new_l3id %x\n",l3_id); mISDN_write(midev, &ncr, mISDN_HEADER_LEN+ncr.len, TIMEOUT_1SEC); } return l3_id;}void misdn_lib_setup_bc(struct misdn_bchannel *bc){ setup_bc(bc);}int setup_bc(struct misdn_bchannel *bc){ unsigned char buff[1025]; mISDN_pid_t pid; int ret; struct misdn_stack *stack=get_stack_by_bc(bc); int midev=stack->midev; int channel=bc->channel-1-(bc->channel>16); int b_stid=stack->b_stids[channel>=0?channel:0]; if (bc->nodsp ) clean_up_bc(bc); if ( !misdn_cap_is_speech(bc->capability)) clean_up_bc(bc); if (bc->upset) { cb_log(4, stack->port, "$$$ bc already upsetted stid :%x\n", b_stid); return -1; } cb_log(5, stack->port, "$$$ Setting up bc with stid :%x\n", b_stid); if (b_stid <= 0) { cb_log(0, stack->port," -- Stid <=0 at the moment on port:%d channel:%d\n",stack->port,channel); return 1; } bc->b_stid = b_stid; { layer_info_t li; memset(&li, 0, sizeof(li)); li.object_id = -1; li.extentions = 0; li.st = bc->b_stid; /* given idx */ if ( misdn_cap_is_speech(bc->capability) && !bc->nodsp && bc->async != 1) { cb_log(4, stack->port,"setup_bc: with dsp\n"); { int l = sizeof(li.name); strncpy(li.name, "B L4", l); li.name[l-1] = 0; } li.pid.layermask = ISDN_LAYER((4)); li.pid.protocol[4] = ISDN_PID_L4_B_USER; } else { cb_log(4, stack->port,"setup_bc: without dsp\n"); { int l = sizeof(li.name); strncpy(li.name, "B L3", l); li.name[l-1] = 0; } li.pid.layermask = ISDN_LAYER((3)); li.pid.protocol[3] = ISDN_PID_L3_B_USER; } ret = mISDN_new_layer(midev, &li); if (ret <= 0) { cb_log(0, stack->port,"New Layer Err: %d %s port:%d\n",ret,strerror(errno), stack->port); return(-EINVAL); } bc->layer_id = ret; } memset(&pid, 0, sizeof(pid)); bc->addr = ( bc->layer_id & IF_ADDRMASK) | IF_DOWN; cb_log(4, stack->port," --> Got Adr %x\n", bc->addr); cb_log(4, stack->port," --> Channel is %d\n", bc->channel); if (bc->async == 1 || bc->nodsp) { cb_log(4, stack->port," --> TRANSPARENT Mode (no DSP, no HDLC)\n"); pid.protocol[1] = ISDN_PID_L1_B_64TRANS; pid.protocol[2] = ISDN_PID_L2_B_TRANS; pid.protocol[3] = ISDN_PID_L3_B_USER; pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)); } else if ( misdn_cap_is_speech(bc->capability)) { cb_log(4, stack->port," --> TRANSPARENT Mode\n"); pid.protocol[1] = ISDN_PID_L1_B_64TRANS; pid.protocol[2] = ISDN_PID_L2_B_TRANS; pid.protocol[3] = ISDN_PID_L3_B_DSP; pid.protocol[4] = ISDN_PID_L4_B_USER; pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4)); } else { cb_log(4, stack->port," --> HDLC Mode\n"); pid.protocol[1] = ISDN_PID_L1_B_64HDLC ; pid.protocol[2] = ISDN_PID_L2_B_TRANS ; pid.protocol[3] = ISDN_PID_L3_B_USER; pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) ; } ret = mISDN_set_stack(midev, bc->b_stid, &pid); if (ret){ cb_log(5, stack->port,"$$$ Set Stack Err: %d %s\n",ret,strerror(errno)); mISDN_write_frame(midev, buff, bc->addr, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC); return(-EINVAL); } bc->upset=1; return 0;}/** IFACE **/int init_bc(struct misdn_stack *stack, struct misdn_bchannel *bc, int midev, int port, int bidx, char *msn, int firsttime){ unsigned char buff[1025]; iframe_t *frm = (iframe_t *)buff; int ret; if (!bc) return -1; cb_log(4, port, "Init.BC %d on port:%d\n",bidx, port); memset(bc, 0,sizeof(struct misdn_bchannel)); if (msn) { int l = sizeof(bc->msn); strncpy(bc->msn,msn, l); bc->msn[l-1] = 0; } empty_bc(bc); bc->upset=0; bc->port=stack->port; bc->nt=stack->mode==NT_MODE?1:0; { ibuffer_t* ibuf= init_ibuffer(MISDN_IBUF_SIZE); ibuffer_t* mbuf= init_ibuffer(MISDN_IBUF_SIZE); if (!ibuf) return -1; if (!mbuf) return -1; clear_ibuffer( ibuf); clear_ibuffer( mbuf); ibuf->rsem=malloc(sizeof(sem_t)); mbuf->rsem=malloc(sizeof(sem_t)); bc->astbuf=ibuf; bc->misdnbuf=mbuf; if (sem_init(ibuf->rsem,1,0)<0) sem_init(ibuf->rsem,0,0); if (sem_init(mbuf->rsem,1,0)< 0) sem_init(mbuf->rsem,0,0); } { stack_info_t *stinf; ret = mISDN_get_stack_info(midev, stack->port, buff, sizeof(buff)); if (ret < 0) { cb_log(0, port, "%s: Cannot get stack info for port:%d (ret=%d)\n", __FUNCTION__, port, ret); return -1; } stinf = (stack_info_t *)&frm->data.p; cb_log(4, port, " --> Child %x\n",stinf->child[bidx]); } return 0;}struct misdn_stack * stack_nt_init(struct misdn_stack *stack, int midev, int port){ int ret; layer_info_t li; interface_info_t ii; cb_log(4, port, "Init. Stack on port:%d\n",port); stack->mode = NT_MODE; stack->lower_id = mISDN_get_layerid(midev, stack->d_stid, 1); if (stack->lower_id <= 0) { cb_log(0, port, "%s: Cannot get layer(%d) id of port:%d\n", __FUNCTION__, 1, port); return(NULL); } memset(&li, 0, sizeof(li)); { int l = sizeof(li.name); strncpy(li.name,"net l2", l); li.name[l-1] = 0; } li.object_id = -1; li.extentions = 0; li.pid.protocol[2] = ISDN_PID_L2_LAPD_NET; li.pid.layermask = ISDN_LAYER((2)); li.st = stack->d_stid; stack->upper_id = mISDN_new_layer(midev, &li); if (stack->upper_id <= 0) { cb_log(0, port, "%s: Cannot add layer %d of port:%d\n", __FUNCTION__, 2, port); return(NULL); } cb_log(4, port, "NT Stacks upper_id %x\n",stack->upper_id); memset(&ii, 0, sizeof(ii)); ii.extentions = EXT_IF_EXCLUSIV; ii.owner = stack->upper_id; ii.peer = stack->lower_id; ii.stat = IF_DOWN; ret = mISDN_connect(midev, &ii); if (ret) { cb_log(0, port, "%s: Cannot connect layer %d of port:%d exclusively.\n", __FUNCTION__, 2, port); return(NULL); } /* create nst (nt-mode only) */ { memset(&stack->nst, 0, sizeof(net_stack_t)); memset(&stack->mgr, 0, sizeof(manager_t)); stack->mgr.nst = &stack->nst; stack->nst.manager = &stack->mgr; stack->nst.l3_manager = handle_event_nt; stack->nst.device = midev; stack->nst.cardnr = port; stack->nst.d_stid = stack->d_stid; #ifdef MISDNUSER_JOLLY stack->nst.feature = FEATURE_NET_HOLD; if (stack->ptp) stack->nst.feature |= FEATURE_NET_PTP; if (stack->pri) stack->nst.feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;#endif stack->nst.l1_id = stack->lower_id; stack->nst.l2_id = stack->upper_id; msg_queue_init(&stack->nst.down_queue); Isdnl2Init(&stack->nst); Isdnl3Init(&stack->nst); } misdn_lib_get_l1_up(stack); if (stack->ptp) { misdn_lib_get_l2_up(stack); stack->l2link=0; } return stack;}struct misdn_stack* stack_te_init( int midev, int port, int ptp ){ int ret; unsigned char buff[1025]; iframe_t *frm = (iframe_t *)buff; stack_info_t *stinf; int i; layer_info_t li; interface_info_t ii; struct misdn_stack *stack = malloc(sizeof(struct misdn_stack)); if (!stack ) return NULL; //cb_log(2, "Init. Stack on port:%d\n",port); cb_log(4, port, "Init. Stack on port:%d\n",port); memset(stack,0,sizeof(struct misdn_stack)); for (i=0; i<MAX_BCHANS + 1; i++ ) stack->channels[i]=0; stack->port=port; stack->midev=midev; stack->ptp=ptp; stack->holding=NULL; stack->pri=0; msg_queue_init(&stack->downqueue); /* query port's requirements */ ret = mISDN_get_stack_info(midev, port, buff, sizeof(buff)); if (ret < 0) { cb_log(0, port, "%s: Cannot get stack info for port:%d (ret=%d)\n", __FUNCTION__, port, ret); return(NULL); } stinf = (stack_info_t *)&frm->data.p; stack->d_stid = stinf->id; stack->b_num = stinf->childcnt; for (i=0; i<stinf->childcnt; i++) stack->b_stids[i] = stinf->child[i]; switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK) { case ISDN_PID_L0_TE_S0: //cb_log(2, "TE Stack\n"); stack->mode = TE_MODE; break; case ISDN_PID_L0_NT_S0: cb_log(4, port, "NT Stack\n"); return stack_nt_init(stack,midev,port); break; case ISDN_PID_L0_TE_U: break; case ISDN_PID_L0_NT_U: break; case ISDN_PID_L0_TE_UP2: break; case ISDN_PID_L0_NT_UP2: break; case ISDN_PID_L0_TE_E1: cb_log(4, port, "TE S2M Stack\n"); stack->mode = TE_MODE; stack->pri=1; break; case ISDN_PID_L0_NT_E1: cb_log(4, port, "TE S2M Stack\n"); stack->mode = NT_MODE; stack->pri=1; return stack_nt_init(stack,midev,port); break; default: cb_log(0, port, "unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]); } if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP ) { /* || (nt&&ptp) || pri */ stack->ptp = 1; } else { stack->ptp = 0; } stack->lower_id = mISDN_get_layerid(midev, stack->d_stid, 3); if (stack->lower_id <= 0) { cb_log(0, stack->port, "No lower Id port:%d\n", stack->port); return(NULL); } memset(&li, 0, sizeof(li)); { int l = sizeof(li.name); strncpy(li.name, "user L4", l); li.name[l-1] = 0; } li.object_id = -1; li.extentions = 0; li.pid.protocol[4] = ISDN_PID_L4_CAPI20; li.pid.layermask = ISDN_LAYER((4)); li.st = stack->d_stid; stack->upper_id = mISDN_new_layer(midev, &li); if (stack->upper_id <= 0) { cb_log(0, stack->port, "No Upper ID port:%d\n",stack->port); return(NULL); } memset(&ii, 0, sizeof(ii)); ii.extentions = EXT_IF_EXCLUSIV | EXT_IF_CREATE; ii.owner = stack->upper_id; ii.peer = stack->lower_id; ii.stat = IF_DOWN; ret = mISDN_connect(midev, &ii); if (ret) { cb_log(0, stack->port, "No Connect port:%d\n", stack->port); return NULL; } misdn_lib_get_l1_up(stack); misdn_lib_get_l2_status(stack); /* initially, we assume that the link is NOT up */ stack->l2link = 0; stack->l1link = 0; stack->next=NULL; return stack; }void stack_te_destroy(struct misdn_stack* stack){ char buf[1024]; if (!stack) return; if (stack->lower_id) mISDN_write_frame(stack->midev, buf, stack->lower_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC); if (stack->upper_id) mISDN_write_frame(stack->midev, buf, stack->upper_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);}struct misdn_stack * find_stack_by_addr(int addr){ struct misdn_stack *stack; for (stack=glob_mgr->stack_list; stack; stack=stack->next) { if ( stack->upper_id == addr) return stack; } return NULL;}struct misdn_stack * find_stack_by_port(int port){ struct misdn_stack *stack; for (stack=glob_mgr->stack_list; stack; stack=stack->next) if (stack->port == port) return stack; return NULL;}struct misdn_stack * find_stack_by_mgr(manager_t* mgr_nt){ struct misdn_stack *stack; for (stack=glob_mgr->stack_list; stack; stack=stack->next) if ( &stack->mgr == mgr_nt) return stack; return NULL;}struct misdn_bchannel *find_bc_by_masked_l3id(struct misdn_stack *stack, unsigned long l3id, unsigned long mask){ int i; for (i=0; i<stack->b_num; i++) { if ( (stack->bc[i].l3_id & mask) == (l3id & mask)) return &stack->bc[i] ; } return stack_holder_find(stack,l3id);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?