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 + -
显示快捷键?