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