mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	added select before write to avoid deadlock on full buffer. added some defines for deadlock debugging. added code snippet for generating silence if we don't have data to write.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@32524 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		| @@ -2352,7 +2352,6 @@ static int tone_indicate( struct chan_list *cl, enum tone_e tone) | ||||
| 		break; | ||||
| 	case TONE_FILE: | ||||
| 		break; | ||||
|  | ||||
| 	case TONE_NONE: | ||||
| 		chan_misdn_log(3,cl->bc->port," --> None\n"); | ||||
| 		misdn_lib_tone_generator_stop(cl->bc); | ||||
| @@ -3285,7 +3284,6 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) | ||||
| 				 | ||||
| 				ast_queue_frame(ch->ast, &fr); | ||||
| 			} | ||||
| 			 | ||||
| 		} | ||||
| 	} | ||||
| 	break; | ||||
| @@ -3694,7 +3692,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) | ||||
| 		int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); | ||||
|  | ||||
| 		chan_misdn_log(9,bc->port,"TONE_GEN: len:%d\n"); | ||||
| 		 | ||||
|  | ||||
| 		if (!ast->generator) break; | ||||
| 		 | ||||
| 		tmp = ast->generatordata; | ||||
| @@ -3702,13 +3700,13 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) | ||||
| 		generate = ast->generator->generate; | ||||
| 		res = generate(ast, tmp, tone_len, tone_len); | ||||
| 		ast->generatordata = tmp; | ||||
| 		 | ||||
| 		if (res) { | ||||
| 			ast_log(LOG_WARNING, "Auto-deactivating generator\n"); | ||||
| 			ast_deactivate_generator(ast); | ||||
| 		} else { | ||||
| 			bc->tone_cnt=0; | ||||
| 		} | ||||
| 		 | ||||
| 	} | ||||
| 	break; | ||||
| 		 | ||||
| @@ -3728,10 +3726,35 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) | ||||
| 			 | ||||
| 			ast_queue_frame(ch->ast,&frame); | ||||
| 		} else { | ||||
| 			int ret=write(ch->pipe[1], bc->bframe, bc->bframe_len); | ||||
| 			fd_set wrfs; | ||||
| 			struct timeval tv; | ||||
| 			tv.tv_sec=0; | ||||
| 			tv.tv_usec=0; | ||||
| 			 | ||||
| 			 | ||||
| 			FD_ZERO(&wrfs); | ||||
| 			FD_SET(ch->pipe[1],&wrfs); | ||||
| 			 | ||||
| 			int t=select(FD_SETSIZE,NULL,&wrfs,NULL,&tv); | ||||
|  | ||||
| 			if (ret<=0) { | ||||
| 				chan_misdn_log(1, bc->port, "Write returned <=0 (err=%s)\n",strerror(errno)); | ||||
| 			if (!t) { | ||||
| 				chan_misdn_log(9, bc->port, "Select Timed out\n"); | ||||
| 				break; | ||||
| 			} | ||||
| 			 | ||||
| 			if (t<0) { | ||||
| 				chan_misdn_log(-1, bc->port, "Select Error (err=%s)\n",strerror(errno)); | ||||
| 				break; | ||||
| 			} | ||||
| 			 | ||||
| 			if (FD_ISSET(ch->pipe[1],&wrfs)) { | ||||
| 				int ret=write(ch->pipe[1], bc->bframe, bc->bframe_len); | ||||
| 				 | ||||
| 				if (ret<=0) { | ||||
| 					chan_misdn_log(-1, bc->port, "Write returned <=0 (err=%s)\n",strerror(errno)); | ||||
| 				} | ||||
| 			} else { | ||||
| 				chan_misdn_log(1, bc->port, "Wripe Pipe full!\n"); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -599,7 +599,7 @@ int clean_up_bc(struct misdn_bchannel *bc) | ||||
| 	cb_log(3, stack->port, "$$$ CLEARING STACK\n"); | ||||
| 	 | ||||
| 	ret=mISDN_clear_stack(stack->midev,bc->b_stid); | ||||
| 	if (ret<0) { | ||||
| 	if (ret<0 && errno) { | ||||
| 		cb_log(-1,stack->port,"clear stack failed [%s]\n",strerror(errno)); | ||||
| 	} | ||||
|  | ||||
| @@ -1986,7 +1986,7 @@ static int do_tone(struct misdn_bchannel *bc, int len) | ||||
| 	 | ||||
| 	if (bc->generate_tone) { | ||||
| 		cb_event(EVENT_TONE_GENERATE, bc, glob_mgr->user_data); | ||||
|  | ||||
| 		 | ||||
| 		if ( !bc->nojitter ) { | ||||
| 			misdn_tx_jitter(bc,len); | ||||
| 		} | ||||
| @@ -2002,13 +2002,14 @@ static int do_tone(struct misdn_bchannel *bc, int len) | ||||
| void misdn_tx_jitter(struct misdn_bchannel *bc, int len) | ||||
| { | ||||
| 	char buf[4096 + mISDN_HEADER_LEN]; | ||||
| 	char *data=&buf[mISDN_HEADER_LEN]; | ||||
| 	iframe_t *txfrm= (iframe_t*)buf; | ||||
| 	int jlen, r; | ||||
| 	 | ||||
| 	jlen=cb_jb_empty(bc,&buf[mISDN_HEADER_LEN],len); | ||||
| 	jlen=cb_jb_empty(bc,data,len); | ||||
| 	 | ||||
| 	if (jlen) { | ||||
| 		flip_buf_bits( &buf[mISDN_HEADER_LEN], jlen); | ||||
| 		flip_buf_bits( data, jlen); | ||||
| 		 | ||||
| 		if (jlen < len) { | ||||
| 			cb_log(5,bc->port,"Jitterbuffer Underrun.\n"); | ||||
| @@ -2024,6 +2025,33 @@ void misdn_tx_jitter(struct misdn_bchannel *bc, int len) | ||||
| 		cb_log(9, bc->port, "Transmitting %d samples 2 misdn\n", txfrm->len); | ||||
| 		 | ||||
| 		r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 ); | ||||
| 	} else { | ||||
| #ifdef MISDN_GEN_SILENCE | ||||
| 		int cnt=len/TONE_SILENCE_SIZE; | ||||
| 		int rest=len%TONE_SILENCE_SIZE; | ||||
| 		int i; | ||||
|  | ||||
| 		for (i=0; i<cnt; i++) { | ||||
| 			memcpy(data, tone_silence_flip, TONE_SILENCE_SIZE ); | ||||
| 			data +=TONE_SILENCE_SIZE; | ||||
| 		} | ||||
|  | ||||
| 		if (rest) { | ||||
| 			memcpy(data, tone_silence_flip, rest); | ||||
| 		} | ||||
|  | ||||
| 		txfrm->prim = DL_DATA|REQUEST; | ||||
|  | ||||
| 		txfrm->dinfo = 0; | ||||
|  | ||||
| 		txfrm->addr = bc->addr|FLG_MSG_DOWN; /*  | IF_DOWN; */ | ||||
|  | ||||
| 		txfrm->len =len; | ||||
| 		cb_log(9, bc->port, "Transmitting %d samples 2 misdn\n", txfrm->len); | ||||
|  | ||||
| 		r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 ); | ||||
| #endif | ||||
|  | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -2201,15 +2229,39 @@ int handle_bchan(msg_t *msg) | ||||
| #endif | ||||
| 		 | ||||
| 		if ( (bc->bc_state == BCHAN_ACTIVATED) && frm->len > 0) { | ||||
| 			if (  !do_tone(bc, frm->len)   ) { | ||||
| 			int t; | ||||
|  | ||||
| #ifdef MISDN_B_DEBUG | ||||
| 			cb_log(0,bc->port,"do_tone START\n"); | ||||
| #endif | ||||
| 			t=do_tone(bc,frm->len); | ||||
|  | ||||
| #ifdef MISDN_B_DEBUG | ||||
| 			cb_log(0,bc->port,"do_tone STOP (%d)\n",t); | ||||
| #endif | ||||
| 			if (  !t ) { | ||||
| 				 | ||||
| 				if ( misdn_cap_is_speech(bc->capability)) { | ||||
| 					if ( !bc->nojitter ) { | ||||
| #ifdef MISDN_B_DEBUG | ||||
| 						cb_log(0,bc->port,"tx_jitter START\n"); | ||||
| #endif | ||||
| 						misdn_tx_jitter(bc,frm->len); | ||||
| #ifdef MISDN_B_DEBUG | ||||
| 						cb_log(0,bc->port,"tx_jitter STOP\n"); | ||||
| #endif | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| #ifdef MISDN_B_DEBUG	 | ||||
| 				cb_log(0,bc->port,"EVENT_B_DATA START\n"); | ||||
| #endif | ||||
| 				 | ||||
| 				int i=cb_event( EVENT_BCHAN_DATA, bc, glob_mgr->user_data); | ||||
| #ifdef MISDN_B_DEBUG	 | ||||
| 				cb_log(0,bc->port,"EVENT_B_DATA STOP\n"); | ||||
| #endif | ||||
| 				 | ||||
| 				if (i<0) { | ||||
| 					cb_log(10,stack->port,"cb_event returned <0\n"); | ||||
| 					/*clean_up_bc(bc);*/ | ||||
| @@ -2262,7 +2314,8 @@ int handle_frm_nt(msg_t *msg) | ||||
| 	if (!stack || !stack->nt) { | ||||
| 		return 0; | ||||
| 	} | ||||
|    | ||||
|  | ||||
| 	 | ||||
| 	if ((err=stack->nst.l1_l2(&stack->nst,msg))) { | ||||
|      | ||||
| 		if (nt_err_cnt > 0 ) { | ||||
| @@ -2520,6 +2573,8 @@ int handle_mgmt(msg_t *msg) | ||||
| 		case SSTATUS_L1_DEACTIVATED: | ||||
| 			cb_log(1, 0, "MGMT: SSTATUS: L1_DEACTIVATED \n"); | ||||
| 			stack->l1link=0; | ||||
|  | ||||
| 			clear_l3(stack); | ||||
| 			break; | ||||
|  | ||||
| 		case SSTATUS_L2_ESTABLISHED: | ||||
| @@ -3096,10 +3151,20 @@ int manager_isdn_handler(iframe_t *frm ,msg_t *msg) | ||||
| 	} | ||||
|  | ||||
| 	if ( ((frm->addr | ISDN_PID_BCHANNEL_BIT )>> 28 ) == 0x5) { | ||||
| 		if (handle_bchan(msg))  | ||||
| #ifdef MISDN_HANDLER_DEBUG | ||||
| 		cb_log(0,0,"handle_bchan START\n"); | ||||
| #endif | ||||
| 		if (handle_bchan(msg)) { | ||||
| #ifdef MISDN_HANDLER_DEBUG | ||||
| 			cb_log(0,0,"handle_bchan STOP\n"); | ||||
| #endif | ||||
| 			return 0 ; | ||||
| 		} | ||||
| #ifdef MISDN_HANDLER_DEBUG | ||||
| 		cb_log(0,0,"handle_bchan NOTSTOP\n"); | ||||
| #endif	 | ||||
| 	}	 | ||||
|  | ||||
| 	 | ||||
| 	if (handle_timers(msg))  | ||||
| 		return 0 ; | ||||
| 	 | ||||
| @@ -3112,16 +3177,46 @@ int manager_isdn_handler(iframe_t *frm ,msg_t *msg) | ||||
| 	/* Its important to handle l1 AFTER l2  */ | ||||
| 	if (handle_l1(msg))  | ||||
| 		return 0 ; | ||||
|  | ||||
| 	if (handle_frm_nt(msg))  | ||||
| 	 | ||||
| #ifdef MISDN_HANDLER_DEBUG | ||||
| 	cb_log(0,0,"handle_frm_nt START\n"); | ||||
| #endif | ||||
| 	if (handle_frm_nt(msg)) { | ||||
| #ifdef MISDN_HANDLER_DEBUG | ||||
| 		cb_log(0,0,"handle_frm_nt STOP\n"); | ||||
| #endif | ||||
| 		return 0; | ||||
|  | ||||
| 	if (handle_frm(msg)) | ||||
| 	} | ||||
| #ifdef MISDN_HANDLER_DEBUG | ||||
| 	cb_log(0,0,"handle_frm_nt NOTSTOP\n"); | ||||
| 	 | ||||
| 	cb_log(0,0,"handle_frm START\n"); | ||||
| #endif | ||||
| 	 | ||||
| 	if (handle_frm(msg)) { | ||||
| #ifdef MISDN_HANDLER_DEBUG | ||||
| 		cb_log(0,0,"handle_frm STOP\n"); | ||||
| #endif | ||||
| 		 | ||||
| 		return 0; | ||||
|  | ||||
| 	if (handle_err(msg))  | ||||
| 	} | ||||
| #ifdef MISDN_HANDLER_DEBUG | ||||
| 	cb_log(0,0,"handle_frm NOTSTOP\n");	 | ||||
| 	 | ||||
| 	cb_log(0,0,"handle_err START\n"); | ||||
| #endif | ||||
| 	 | ||||
| 	if (handle_err(msg)) { | ||||
| #ifdef MISDN_HANDLER_DEBUG | ||||
| 		cb_log(0,0,"handle_err STOP\n"); | ||||
| #endif | ||||
| 		return 0 ; | ||||
| 	} | ||||
| #ifdef MISDN_HANDLER_DEBUG | ||||
| 	cb_log(0,0,"handle_err NOTSTOP\n"); | ||||
| #endif | ||||
|  | ||||
| 	 | ||||
| 	cb_log(-1, 0, "Unhandled Message: prim %x len %d from addr %x, dinfo %x on this port.\n",frm->prim, frm->len, frm->addr, frm->dinfo);		 | ||||
| 	free_msg(msg); | ||||
| 	 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user