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