[asterisk-commits] trunk r23443 - in /trunk/channels: ./ misdn/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Sat Apr 29 15:56:01 MST 2006


Author: crichter
Date: Sat Apr 29 17:56:00 2006
New Revision: 23443

URL: http://svn.digium.com/view/asterisk?rev=23443&view=rev
Log:
added an up-queue message mechanism to avoid buffer fillups in the kernel, also changed some strdups to ast_strdupa

Modified:
    trunk/channels/chan_misdn.c
    trunk/channels/misdn/isdn_lib.c
    trunk/channels/misdn/isdn_lib_intern.h

Modified: trunk/channels/chan_misdn.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_misdn.c?rev=23443&r1=23442&r2=23443&view=diff
==============================================================================
--- trunk/channels/chan_misdn.c (original)
+++ trunk/channels/chan_misdn.c Sat Apr 29 17:56:00 2006
@@ -182,6 +182,9 @@
 	int addr;
 
 	char context[BUFFERSIZE];
+
+	int zero_read_cnt;
+	int dropped_frame_cnt;
 
 	const struct tone_zone_sound *ts;
 	
@@ -749,7 +752,7 @@
 static int misdn_show_stacks (int fd, int argc, char *argv[])
 {
 	int port;
-	
+
 	ast_cli(fd, "BEGIN STACK_LIST:\n");
 
 	for (port=misdn_cfg_get_next_port(0); port > 0;
@@ -927,7 +930,7 @@
 		c = ast_channel_walk_locked(c);
 	}
 	if (c) {
-		ret = strdup(c->name);
+		ret = ast_strdupa(c->name);
 		ast_mutex_unlock(&c->lock);
 	} else
 		ret = NULL;
@@ -946,12 +949,12 @@
 
 	switch (pos) {
 	case 4: if (*word == 'p')
-				return strdup("port");
+				return ast_strdupa("port");
 			else if (*word == 'o')
-				return strdup("only");
+				return ast_strdupa("only");
 			break;
 	case 6: if (*word == 'o')
-				return strdup("only");
+				return ast_strdupa("only");
 			break;
 	}
 	return NULL;
@@ -1504,17 +1507,13 @@
 		if ( strcmp(bc->dad,ast->exten)) {
 			ast_copy_string(ast->exten, bc->dad, sizeof(ast->exten));
 		}
-		if ( ast->cid.cid_num && strcmp(ast->cid.cid_num, bc->oad)) {
-			free(ast->cid.cid_num);
-			ast->cid.cid_num=NULL;
-			
-		}
+		
 		if ( !ast->cid.cid_num) {
-			ast->cid.cid_num=strdup(bc->oad);
+			ast_set_callerid(ast, bc->oad, NULL, bc->oad);
 		}
 		
 		if ( !ast_strlen_zero(bc->rad) ) 
-			ast->cid.cid_rdnis=strdup(bc->rad);
+			ast->cid.cid_rdnis=ast_strdupa(bc->rad);
 	}
 	return 0;
 }
@@ -2062,10 +2061,20 @@
 	len = misdn_ibuf_usedcount(tmp->bc->astbuf);
 
 	if (!len) {
-		chan_misdn_log(4,tmp->bc->port,"misdn_read: ZERO READ\n");
+		struct ast_frame *frame;
+		if(!tmp->zero_read_cnt)
+			chan_misdn_log(4,tmp->bc->port,"misdn_read: ZERO READ\n");
+		tmp->zero_read_cnt++;
+
+		if (tmp->zero_read_cnt > 5000) {
+			chan_misdn_log(4,tmp->bc->port,"misdn_read: ZERO READ counted > 5000 times\n");
+			tmp->zero_read_cnt=0;
+
+		}
 		tmp->frame.frametype = AST_FRAME_NULL;
 		tmp->frame.subclass = 0;
-		return &tmp->frame;
+		frame=ast_frisolate(&tmp->frame);
+		return frame;
 	}
 
 	/*shrinken len if necessary, we transmit at maximum 4k*/
@@ -2154,7 +2163,16 @@
 		case BCHAN_BRIDGED:
 			break;
 		default:
-		chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) droping: %d frames addr:%x exten:%s cid:%s ch->state:%s\n",frame->samples,ch->bc->addr, ast->exten, ast->cid.cid_num,misdn_get_ch_state( ch));
+		if (!ch->dropped_frame_cnt)
+			chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) droping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d\n",frame->samples,ch->bc->addr, ast->exten, ast->cid.cid_num,misdn_get_ch_state( ch), ch->bc->bc_state);
+		
+		ch->dropped_frame_cnt++;
+		if (ch->dropped_frame_cnt > 100) {
+			ch->dropped_frame_cnt=0;
+			chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) droping: %d frames addr:%x  dropped > 100 frames!\n",frame->samples,ch->bc->addr);
+
+		}
+
 		return 0;
 	}
 	
@@ -2262,10 +2280,6 @@
 			ast_write(c0,f);
 		}
     
-	}
-  
-	if (bridging) {
-		misdn_lib_split_bridge(ch1->bc,ch2->bc);
 	}
   
 	return 0;
@@ -2612,10 +2626,9 @@
 			char *cid_name, *cid_num;
       
 			ast_callerid_parse(callerid, &cid_name, &cid_num);
-			if (cid_name)
-				tmp->cid.cid_name=strdup(cid_name);
-			if (cid_num)
-				tmp->cid.cid_num=strdup(cid_num);
+			ast_set_callerid(tmp, cid_num,cid_name,cid_num);
+		} else {
+			ast_set_callerid(tmp, NULL,NULL,NULL);
 		}
 
 		{

Modified: trunk/channels/misdn/isdn_lib.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/misdn/isdn_lib.c?rev=23443&r1=23442&r2=23443&view=diff
==============================================================================
--- trunk/channels/misdn/isdn_lib.c (original)
+++ trunk/channels/misdn/isdn_lib.c Sat Apr 29 17:56:00 2006
@@ -802,6 +802,8 @@
 		free_chan = find_free_chan_in_stack(stack, bc->channel_preselected?bc->channel:0);
 		if (!free_chan) return -1;
 		bc->channel=free_chan;
+		
+		cb_log(0,stack->port, " -->  found channel: %d\n",free_chan);
     
 		for (i=0; i <= MAXPROCS; i++)
 			if (stack->procids[i]==0) break;
@@ -833,6 +835,7 @@
 			free_chan = find_free_chan_in_stack(stack, bc->channel_preselected?bc->channel:0);
 			if (!free_chan) return -1;
 			bc->channel=free_chan;
+			cb_log(0,stack->port, " -->  found channel: %d\n",free_chan);
 		} else {
 			/* other phones could have made a call also on this port (ptmp) */
 			bc->channel=0xff;
@@ -1107,6 +1110,7 @@
 	stack->pri=0;
   
 	msg_queue_init(&stack->downqueue);
+	msg_queue_init(&stack->upqueue);
   
 	/* query port's requirements */
 	ret = mISDN_get_stack_info(midev, port, buff, sizeof(buff));
@@ -2072,11 +2076,18 @@
 		
 	case MGR_SETSTACK| INDICATION:
 		cb_log(2, stack->port, "BCHAN: MGR_SETSTACK|IND \n");
-		
+
+	AGAIN:
 		bc->addr = mISDN_get_layerid(stack->midev, bc->b_stid, bc->layer);
 		if (!bc->addr) {
+
+			if (errno == EAGAIN) {
+				usleep(1000);
+				goto AGAIN;
+			}
+			
 			cb_log(0,stack->port,"$$$ Get Layer (%d) Id Error: %s\n",bc->layer,strerror(errno));
-
+			
 			/* we kill the channel later, when we received some
 			   data. */
 			bc->addr= frm->addr;
@@ -2587,16 +2598,29 @@
 	FD_SET(midev,&rdfs);
   
 	mISDN_select(FD_SETSIZE, &rdfs, NULL, NULL, NULL);
+	//select(FD_SETSIZE, &rdfs, NULL, NULL, NULL);
   
 	if (FD_ISSET(midev, &rdfs)) {
-    
-		r=mISDN_read(midev,msg->data,MAX_MSG_SIZE,0);
+
+	AGAIN:
+		r=mISDN_read(midev,msg->data,MAX_MSG_SIZE, 5000);
 		msg->len=r;
     
 		if (r==0) {
 			free_msg(msg); /* danger, cauz usualy freeing in main_loop */
 			printf ("Got empty Msg?\n");
 			return NULL;
+		}
+
+		if (r<0) {
+			if (errno == EAGAIN) {
+				/*we wait for mISDN here*/
+				cb_log(-1,0,"mISDN_read wants us to wait\n");
+				usleep(5000);
+				goto AGAIN;
+			}
+			
+			cb_log(-1,0,"mISDN_read returned :%d error:%s (%d)\n",r,strerror(errno),errno); 
 		}
 
 		return msg;
@@ -2976,6 +3000,22 @@
 int handle_err(msg_t *msg)
 {
 	iframe_t *frm = (iframe_t*) msg->data;
+
+
+	if (!frm->addr) {
+		static int cnt=0;
+		if (!cnt)
+			cb_log(0,0,"mISDN Msg without Address pr:%x dinfo:%x\n",frm->prim,frm->dinfo);
+		cnt++;
+		if (cnt>100) {
+			cb_log(0,0,"mISDN Msg without Address pr:%x dinfo:%x (already more than 100 of them)\n",frm->prim,frm->dinfo);
+			cnt=0;
+		}
+		
+		free_msg(msg);
+		return 1;
+		
+	}
 	
 	switch (frm->prim) {
 		case DL_DATA|INDICATION:
@@ -2983,7 +3023,13 @@
 			int port=(frm->addr&MASTER_ID_MASK) >> 8;
 			int channel=(frm->addr&CHILD_ID_MASK) >> 16;
 
-			cb_log(3,0,"BCHAN DATA without BC: addr:%x port:%d channel:%d\n",frm->addr, port,channel);
+			/*we flush the read buffer here*/
+			
+			cb_log(9,0,"BCHAN DATA without BC: addr:%x port:%d channel:%d\n",frm->addr, port,channel);
+			
+			free_msg(msg) ; 
+			return 1;
+			
 			
 			struct misdn_bchannel *bc=find_bc_by_channel( port , channel);
 
@@ -3015,11 +3061,28 @@
 }
 
 
+int queue_l2l3(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 (!stack) {
+		return 0;
+	}
+
+	msg_queue_tail(&stack->upqueue, msg);
+	sem_post(&glob_mgr->new_msg);
+	return 1;
+}
+
 int manager_isdn_handler(iframe_t *frm ,msg_t *msg)
 {  
 
 	if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM)) {
-		printf("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
+		cb_log(0,0,"SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
 	}
 
 	if ( ((frm->addr | ISDN_PID_BCHANNEL_BIT )>> 28 ) == 0x5) {
@@ -3039,21 +3102,17 @@
 	/* Its important to handle l1 AFTER l2  */
 	if (handle_l1(msg)) 
 		return 0 ;
-	
-	
-	/** Handle L2/3 Signalling after bchans **/ 
-	if (handle_frm_nt(msg)) 
-		return 0 ;
-	
-	if (handle_frm(msg)) 
-		return 0 ;
+
+	/* The L2/L3 will be queued */
+	if (queue_l2l3(msg))
+		return 0;
 
 	if (handle_err(msg)) 
 		return 0 ;
-	
+
 	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);
+	
 
 	return 0;
 }
@@ -3200,6 +3259,24 @@
 		for (stack=glob_mgr->stack_list;
 		     stack;
 		     stack=stack->next ) { 
+
+			while ( (msg=msg_dequeue(&stack->upqueue)) ) {
+				int res=0;
+				/** Handle L2/3 Signalling after bchans **/ 
+				if (!handle_frm_nt(msg)) {
+					/* Maybe it's TE */
+					if (!handle_frm(msg)) {
+						/* wow none! */
+						cb_log(-1,stack->port,"Wow we've got a strange issue while dequeueing a Frame\n");
+					}
+				}
+			}
+
+			/* Here we should check if we really want to 
+				send all the messages we've queued, lets 
+				assume we've queued a Disconnect, but 
+				received it already from the other side!*/
+		     
 			while ( (msg=msg_dequeue(&stack->downqueue)) ) {
 				if (stack->nt ) {
 					if (stack->nst.manager_l3(&stack->nst, msg))
@@ -3208,6 +3285,7 @@
 				} else {
 					iframe_t *frm = (iframe_t *)msg->data;
 					struct misdn_bchannel *bc = find_bc_by_l3id(stack, frm->dinfo);
+					cb_log(0,stack->port,"Sending msg, prim:%x addr:%x dinfo:%x\n",frm->prim,frm->addr,frm->dinfo);
 					if (bc) send_msg(glob_mgr->midev, bc, msg);
 				}
 			}

Modified: trunk/channels/misdn/isdn_lib_intern.h
URL: http://svn.digium.com/view/asterisk/trunk/channels/misdn/isdn_lib_intern.h?rev=23443&r1=23442&r2=23443&view=diff
==============================================================================
--- trunk/channels/misdn/isdn_lib_intern.h (original)
+++ trunk/channels/misdn/isdn_lib_intern.h Sat Apr 29 17:56:00 2006
@@ -74,6 +74,7 @@
 	int procids[0x100+1];
 
 	msg_queue_t downqueue;
+	msg_queue_t upqueue;
 	int busy;
   
 	int port;



More information about the asterisk-commits mailing list