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

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Mon Apr 3 12:18:02 MST 2006


Author: crichter
Date: Mon Apr  3 14:17:59 2006
New Revision: 17128

URL: http://svn.digium.com/view/asterisk?rev=17128&view=rev
Log:
* removed unneeded bc->state field
* added statefullness for bchannel activation/deactivation
* fixed a lot PCM bridging issues
* some debugging logs are now on a higher loglevel


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

Modified: trunk/channels/chan_misdn.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_misdn.c?rev=17128&r1=17127&r2=17128&view=diff
==============================================================================
--- trunk/channels/chan_misdn.c (original)
+++ trunk/channels/chan_misdn.c Mon Apr  3 14:17:59 2006
@@ -668,6 +668,7 @@
 			"  --> bc_l3id: %x\n"
 			"  --> display: %s\n"
 			"  --> activated: %d\n"
+			"  --> state: %s\n"
 			"  --> capability: %s\n"
 			"  --> echo_cancel: %d\n"
 			"  --> notone : rx %d tx:%d\n"
@@ -680,6 +681,7 @@
 			bc->display,
 			
 			bc->active,
+			bc_state2str(bc->bc_state),
 			bearer2str(bc->capability),
 			bc->ec_enable,
 			help->norxtone,help->notxtone,
@@ -2032,6 +2034,14 @@
 	
 	len = misdn_ibuf_usedcount(tmp->bc->astbuf);
 
+	if (!len) {
+		chan_misdn_log(4,tmp->bc->port,"misdn_read: ZERO READ\n");
+
+		tmp->frame.frametype = AST_FRAME_NULL;
+		tmp->frame.subclass = 0;
+		return &tmp->frame;
+	}
+
 	/*shrinken len if necessary, we transmit at maximum 4k*/
 	len = len<=sizeof(tmp->ast_rd_buf)?len:sizeof(tmp->ast_rd_buf);
 	
@@ -2080,7 +2090,7 @@
 
 
 	if ( !frame->subclass) {
-		chan_misdn_log(2, ch->bc->port, "misdn_write: * prods us\n");
+		chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n");
 		return 0;
 	}
 	
@@ -2090,6 +2100,16 @@
 		return -1;
 	}
 	
+
+	if ( !frame->samples ) {
+		chan_misdn_log(4, ch->bc->port, "misdn_write: zero write\n");
+		return 0;
+	}
+
+	if ( ! ch->bc->addr ) {
+		chan_misdn_log(4, ch->bc->port, "misdn_write: no addr for bc dropping:%d\n", frame->samples);
+		return 0;
+	}
 	
 #if MISDN_DEBUG
 	{
@@ -2102,9 +2122,13 @@
 	}
 #endif
 
-	
-	if (!ch->bc->active) {
-		chan_misdn_log(5, ch->bc->port, "BC not active droping: %d frames\n",frame->samples);
+
+	switch (ch->bc->bc_state) {
+		case BCHAN_ACTIVATED:
+		case BCHAN_BRIDGED:
+			break;
+		default:
+		chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) droping: %d frames addr:%x\n",frame->samples,ch->bc->addr);
 		return 0;
 	}
 	
@@ -2166,13 +2190,13 @@
 		if ( !ecwb ) {
 			chan_misdn_log(2, ch1->bc->port, "Disabling Echo Cancellor when Bridged\n");
 			ch1->bc->ec_enable=0;
-			manager_ec_disable(ch1->bc);
+		/*	manager_ec_disable(ch1->bc); */
 		}
 		misdn_cfg_get( ch2->bc->port, MISDN_CFG_ECHOCANCELWHENBRIDGED, &ecwb, sizeof(int));
 		if ( !ecwb ) {
 			chan_misdn_log(2, ch2->bc->port, "Disabling Echo Cancellor when Bridged\n");
 			ch2->bc->ec_enable=0;
-			manager_ec_disable(ch2->bc);
+		/*	manager_ec_disable(ch2->bc); */
 		}
 		
 		/* trying to make a mISDN_dsp conference */
@@ -2707,7 +2731,7 @@
 		if (help->l3id == l3id ) return help;
 	}
   
-	chan_misdn_log(4, list? (list->bc? list->bc->port : 0) : 0, "$$$ find_chan: No channel found with l3id:%x\n",l3id);
+	chan_misdn_log(6, list? (list->bc? list->bc->port : 0) : 0, "$$$ find_chan: No channel found with l3id:%x\n",l3id);
   
 	return NULL;
 }
@@ -2719,7 +2743,7 @@
 		if (help->bc == bc) return help;
 	}
   
-	chan_misdn_log(4, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad);
+	chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad);
   
 	return NULL;
 }
@@ -2729,14 +2753,14 @@
 {
 	struct chan_list *help=list;
 	
-	chan_misdn_log(4, bc->port, "$$$ find_holded: channel:%d oad:%s dad:%s\n",bc->channel, bc->oad,bc->dad);
+	chan_misdn_log(6, bc->port, "$$$ find_holded: channel:%d oad:%s dad:%s\n",bc->channel, bc->oad,bc->dad);
 	for (;help; help=help->next) {
 		chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n",help->bc->holded, help->bc->channel);
 		if (help->bc->port == bc->port
 		    && help->bc->holded ) return help;
 	}
 	
-	chan_misdn_log(4, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad);
+	chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad);
   
 	return NULL;
 }
@@ -3068,6 +3092,7 @@
 	if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { /*  Debug Only Non-Bchan */
 		chan_misdn_log(1, bc->port, "I IND :%s oad:%s dad:%s\n", manager_isdn_get_info(event), bc->oad, bc->dad);
 		misdn_lib_log_ies(bc);
+		chan_misdn_log(2,bc->port," --> bc_state:%s\n",bc_state2str(bc->bc_state));
 	}
 	
 	if (event != EVENT_SETUP) {
@@ -3468,8 +3493,6 @@
 		misdn_lib_send_event(bc,EVENT_CONNECT_ACKNOWLEDGE);
 	case EVENT_CONNECT_ACKNOWLEDGE:
 	{
-		bc->state=STATE_CONNECTED;
-		
 		ch->l3id=bc->l3_id;
 		ch->addr=bc->addr;
 		
@@ -3592,8 +3615,7 @@
 		} else {
 			int len=bc->bframe_len;
 			int free=misdn_ibuf_freecount(bc->astbuf);
-			
-			
+		
 			if (bc->bframe_len > free) {
 				ast_log(LOG_DEBUG, "sbuf overflow!\n");
 				len=misdn_ibuf_freecount(bc->astbuf);
@@ -3693,13 +3715,17 @@
 			}
 		}
 #endif
-		
-		if (AST_BRIDGED_P(ch->ast)){
+		struct ast_channel *bridged=AST_BRIDGED_P(ch->ast);
+		
+		if (bridged){
+			struct chan_list *bridged_ch=MISDN_ASTERISK_TECH_PVT(bridged);
 			ch->state = MISDN_HOLDED;
 			ch->l3id = bc->l3_id;
 			
-			ast_moh_start(AST_BRIDGED_P(ch->ast), NULL);
+			bc->holded_bc=bridged_ch->bc;
 			misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE);
+
+			ast_moh_start(bridged, NULL);
 		} else {
 			misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
 			chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n");
@@ -3729,9 +3755,13 @@
 		
 		break;
 		default:
-			chan_misdn_log(1,bc->port," --> not yet handled\n");
-		}
-		
+			chan_misdn_log(1, bc->port," --> not yet handled\n");
+		}
+		
+		break;
+
+
+	case EVENT_RESTART:
 		break;
 				
 	default:

Modified: trunk/channels/misdn/isdn_lib.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/misdn/isdn_lib.c?rev=17128&r1=17127&r2=17128&view=diff
==============================================================================
--- trunk/channels/misdn/isdn_lib.c (original)
+++ trunk/channels/misdn/isdn_lib.c Mon Apr  3 14:17:59 2006
@@ -13,6 +13,11 @@
 
 #include "isdn_lib_intern.h"
 #include <mISDNuser/isdn_debug.h>
+
+
+void misdn_join_conf(struct misdn_bchannel *bc, int conf_id);
+void misdn_split_conf(struct misdn_bchannel *bc, int conf_id);
+
 
 void misdn_free_ibuffer(void *ibuf)
 {
@@ -389,7 +394,7 @@
 	int i;
 
 	for (i=0; i <stack->b_num; i++) {
-		cb_log(5, stack->port, "Idx:%d stack->cchan:%d Chan:%d\n",i,stack->channels[i], i+1);
+		cb_log(8, stack->port, "Idx:%d stack->cchan:%d Chan:%d\n",i,stack->channels[i], i+1);
 	}
 }
 
@@ -431,15 +436,71 @@
 	return 0;
 }
 
+char *bc_state2str(enum bchannel_state state) {
+	int i;
+	
+	struct bchan_state_s {
+		char *n;
+		enum bchannel_state s;
+	} states[] = {
+		{"BCHAN_CLEANED", BCHAN_CLEANED },
+		{"BCHAN_EMPTY", BCHAN_EMPTY},
+		{"BCHAN_SETUP", BCHAN_SETUP},
+		{"BCHAN_SETUPED", BCHAN_SETUPED},
+		{"BCHAN_ACTIVE", BCHAN_ACTIVE},
+		{"BCHAN_ACTIVATED", BCHAN_ACTIVATED},
+		{"BCHAN_BRIDGE",  BCHAN_BRIDGE},
+		{"BCHAN_BRIDGED", BCHAN_BRIDGED},
+		{"BCHAN_RELEASE", BCHAN_RELEASE},
+		{"BCHAN_RELEASED", BCHAN_RELEASED},
+		{"BCHAN_CLEAN", BCHAN_CLEAN},
+		{"BCHAN_ERROR", BCHAN_ERROR}
+	};
+	
+	for (i=0; i< sizeof(states)/sizeof(struct bchan_state_s); i++)
+		if ( states[i].s == state)
+			return states[i].n;
+
+	return "UNKNOWN";
+}
+
+void bc_state_change(struct misdn_bchannel *bc, enum bchannel_state state)
+{
+	cb_log(3,bc->port,"BC_STATE_CHANGE: from:%s to:%s\n",
+	       bc_state2str(bc->bc_state),
+	       bc_state2str(state) );
+	
+	switch (state) {
+		case BCHAN_ACTIVATED:
+			if (bc->next_bc_state ==  BCHAN_BRIDGED) {
+				misdn_join_conf(bc, bc->conf_id);
+				bc->next_bc_state = BCHAN_EMPTY;
+				return;
+			}
+		default:
+			bc->bc_state=state;
+			break;
+	}
+}
+
+void bc_next_state_change(struct misdn_bchannel *bc, enum bchannel_state state)
+{
+	cb_log(3,bc->port,"BC_NEXT_STATE_CHANGE: from:%s to:%s\n",
+	       bc_state2str(bc->next_bc_state),
+	       bc_state2str(state) );
+
+	bc->next_bc_state=state;
+}
+
 
 void empty_bc(struct misdn_bchannel *bc)
 {
 	bc->bframe_len=0;
-
-	bc->state=STATE_NOTHING;
 	
 	bc->channel = 0;
 	bc->in_use = 0;
+
+	bc->conf_id = 0;
 
 	bc->need_more_infos = 0;
 	
@@ -510,6 +571,11 @@
 	bc->fac_type=FACILITY_NONE;
 	
 	bc->te_choose_channel = 0;
+
+	bc->holded_bc=NULL;
+	
+	bc_state_change(bc,BCHAN_EMPTY);
+	bc_next_state_change(bc,BCHAN_EMPTY);
 }
 
 
@@ -518,43 +584,44 @@
 	int ret=0;
 	unsigned char buff[32];
 	struct misdn_stack * stack;
+
+	cb_log(2, 0, "$$$ CLEANUP CALLED\n");
 	
 	if (!bc  ) return -1;
 	stack=get_stack_by_bc(bc);
+	
 	if (!stack) return -1;
 	
-	if (!bc->upset) {
+	switch (bc->bc_state ) {
+		
+	case BCHAN_CLEANED:
 		cb_log(5, stack->port, "$$$ Already cleaned up bc with stid :%x\n", bc->b_stid);
 		return -1;
-	}
-
-	if (bc->active) {
+		
+	case BCHAN_ACTIVATED:
 		cb_log(2, stack->port, "$$$ bc still active, deactivatiing .. stid :%x\n", bc->b_stid);
 		manager_bchannel_deactivate(bc);
+		break;
+		
+	case BCHAN_BRIDGED:
+		cb_log(2, stack->port, "$$$ bc still bridged\n");
+	default:
+		break;
 	}
 	
 	cb_log(5, stack->port, "$$$ Cleaning up bc with stid :%x\n", bc->b_stid);
-	
 	
 	if ( misdn_cap_is_speech(bc->capability) && bc->ec_enable) {
 		manager_ec_disable(bc);
 	}
 
+	cb_log(2, stack->port, "$$$ CLEARING STACK\n");
+	/*mISDN_clear_stack(stack->midev,bc->b_stid);*/
+	
 	mISDN_write_frame(stack->midev, buff, bc->addr|FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
 	
-
-#ifdef ACK_HDLC	
-	if (bc->ack_hdlc ) {
-		free(bc->ack_hdlc);
-		bc->ack_hdlc=NULL;
-	}
-#endif
-	
-	
 	bc->b_stid = 0;
-	
-	bc->upset=0;
-	
+	bc_state_change(bc, BCHAN_CLEANED);
 	
 	return ret;
 }
@@ -818,14 +885,9 @@
 	int channel=bc->channel-1-(bc->channel>16);
 	int b_stid=stack->b_stids[channel>=0?channel:0];
 
-#if 0
-	if (bc->hdlc) {
-		clean_up_bc(bc);
-	}
-#endif
-	
-	if (bc->upset) {
-		cb_log(4, stack->port, "$$$ bc already upsetted stid :%x\n", b_stid);
+
+	if ( bc->bc_state != BCHAN_CLEANED) {
+		cb_log(4, stack->port, "$$$ bc already upsetted stid :%x (state:%s)\n", b_stid, bc_state2str(bc->bc_state) );
 		return -1;
 	}
 	
@@ -833,7 +895,8 @@
 	
 	if (b_stid <= 0) {
 		cb_log(-1, stack->port," -- Stid <=0 at the moment in channel:%d\n",channel);
-
+		
+		bc_state_change(bc,BCHAN_ERROR);
 		return 1;
 	}
 	
@@ -882,7 +945,8 @@
 		ret = mISDN_new_layer(midev, &li);
 		if (ret ) {
 			cb_log(-1, stack->port,"New Layer Err: %d %s\n",ret,strerror(errno));
-			
+
+			bc_state_change(bc,BCHAN_ERROR);
 			return(-EINVAL);
 		}
 		
@@ -930,25 +994,18 @@
 		cb_log(5, stack->port,"$$$ Set Stack Err: %d %s\n",ret,strerror(errno));
 		
 		mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
+
+		bc_state_change(bc,BCHAN_ERROR);
 		return(-EINVAL);
 	}
 
-#if 0
-	ret = mISDN_get_setstack_ind(midev, bc->layer_id );
-	
-	if (ret){
-		cb_log(5, stack->port,"$$$ Get Set Stack Err: %d %s\n",ret,strerror(errno));
-		
-		mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
-		return(-EINVAL);
-	}
-
-#endif
-
-	
-	bc->upset=1;
-	
-	manager_bchannel_deactivate(bc);
+
+	bc_state_change(bc,BCHAN_SETUP);
+
+	
+	/*manager_bchannel_deactivate(bc);*/
+	
+	
 	return 0;
 }
 
@@ -975,7 +1032,8 @@
 	
 	
 	empty_bc(bc);
-	bc->upset=0;
+	bc_state_change(bc, BCHAN_CLEANED);
+	
 	bc->port=stack->port;
 	bc->nt=stack->nt?1:0;
 	
@@ -1378,7 +1436,7 @@
 		return -1;
 	}
   
-	cb_log(4, stack->port, " --> new_process: New L3Id: %x\n",frm->dinfo);
+	cb_log(7, stack->port, " --> new_process: New L3Id: %x\n",frm->dinfo);
 	bc->l3_id=frm->dinfo;
 	
 	if (mypid>5000) mypid=0;
@@ -1392,7 +1450,7 @@
   
 	switch (frm->prim) {
 	case CC_NEW_CR|INDICATION:
-		cb_log(4, stack->port, " --> lib: NEW_CR Ind with l3id:%x on this port.\n",frm->dinfo);
+		cb_log(7, stack->port, " --> lib: NEW_CR Ind with l3id:%x on this port.\n",frm->dinfo);
 		handle_new_process(stack, frm); 
 		return 1;
 	case CC_NEW_CR|CONFIRM:
@@ -1721,16 +1779,8 @@
 			break;
 
 		case CC_RELEASE|CONFIRM:
-		{
-			/*struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
-			  cb_log(3, stack->port, " --> RELEASE CONFIRM, doing nothin\n");
-			  cb_event(EVENT_CLEANUP, bc, glob_mgr->user_data);
-			  empty_chan_in_stack(stack,bc->channel);
-			  empty_bc(bc);
-			  free_msg(msg);
-			  return 0;*/
-		}
-		break;  
+			break;
+			
 		case CC_RELEASE|INDICATION:
 			break;
 
@@ -1991,9 +2041,13 @@
 	}
 	
 	switch (frm->prim) {
+
+	case MGR_SETSTACK| CONFIRM:
+		cb_log(2, stack->port, "BCHAN: MGR_SETSTACK|CONFIRM \n");
+		break;
+		
 	case MGR_SETSTACK| INDICATION:
 		cb_log(2, stack->port, "BCHAN: MGR_SETSTACK|IND \n");
-		
 		
 		bc->addr = mISDN_get_layerid(stack->midev, bc->b_stid, bc->layer);
 		if (!bc->addr) {
@@ -2005,16 +2059,28 @@
 		}
 		
 		cb_log(4, stack->port," --> Got Adr %x\n", bc->addr);
-		
-		bc->upset=2;
-		
+
 		free_msg(msg);
+		
+		if (bc->bc_state !=  BCHAN_SETUP) {
+			cb_log(4, stack->port," --> STATE WASN'T SETUP in SETSTACK|IND\n");
+		}
+		
+		bc_state_change(bc,BCHAN_SETUPED);
+		
 		
 		manager_bchannel_activate(bc);
 				
 		return 1;
+
+	case MGR_DELLAYER| INDICATION:
+		cb_log(2, stack->port, "BCHAN: MGR_DELLAYER|IND\n");
+		break;
+		
 	case MGR_DELLAYER| CONFIRM:
 		cb_log(2, stack->port, "BCHAN: MGR_DELLAYER|CNF \n");
+		
+		bc_state_change(bc,BCHAN_CLEANED);
 		
 		free_msg(msg);
 		return 1;
@@ -2022,11 +2088,17 @@
 	case PH_ACTIVATE | INDICATION:
 	case DL_ESTABLISH | INDICATION:
 		cb_log(4, stack->port, "BCHAN: ACT Ind\n");
+
+		bc_state_change(bc,BCHAN_ACTIVATED);
+		
 		free_msg(msg);
 		return 1;    
 
 	case PH_ACTIVATE | CONFIRM:
 	case DL_ESTABLISH | CONFIRM:
+		
+		bc_state_change(bc,BCHAN_ACTIVATED);
+		
 		cb_log(4, stack->port, "BCHAN: bchan ACT Confirm\n");
 		free_msg(msg);
 		
@@ -2035,12 +2107,16 @@
 	case PH_DEACTIVATE | INDICATION:
 	case DL_RELEASE | INDICATION:
 		cb_log (4, stack->port, "BCHAN: DeACT Ind\n");
+		
+		bc_state_change(bc,BCHAN_RELEASED);
 		free_msg(msg);
 		return 1;
     
 	case PH_DEACTIVATE | CONFIRM:
 	case DL_RELEASE | CONFIRM:
 		cb_log(4, stack->port, "BCHAN: DeACT Conf\n");
+		
+		bc_state_change(bc,BCHAN_RELEASED);
 		free_msg(msg);
 		return 1;
     
@@ -2089,14 +2165,26 @@
 		/** Anyway flip the bufbits **/
 		if ( misdn_cap_is_speech(bc->capability) ) 
 			flip_buf_bits(bc->bframe, bc->bframe_len);
-		
+	
+
+		if (!bc->bframe_len) {
+			cb_log(2, stack->port, "DL_DATA INDICATION bc->addr:%x frm->addr:%x\n", bc->addr, frm->addr);
+			free_msg(msg);
+			return 1;
+		}
+
+		if ( (bc->addr&STACK_ID_MASK) != (frm->addr&STACK_ID_MASK) ) {
+			cb_log(2, stack->port, "DL_DATA INDICATION bc->addr:%x frm->addr:%x\n", bc->addr, frm->addr);
+			free_msg(msg);
+			return 1;
+		}
 		
 #if MISDN_DEBUG
 		cb_log(-1, stack->port, "DL_DATA INDICATION Len %d\n", frm->len);
 
 #endif
 		
-		if (bc->active && frm->len > 0) {
+		if ( (bc->bc_state == BCHAN_ACTIVATED) && frm->len > 0) {
 			if (  !do_tone(bc, frm->len)   ) {
 				
 				if ( misdn_cap_is_speech(bc->capability)) {
@@ -2107,7 +2195,7 @@
 				
 				int i=cb_event( EVENT_BCHAN_DATA, bc, glob_mgr->user_data);
 				if (i<0) {
-					cb_log(5,stack->port,"cb_event returned <0\n");
+					cb_log(10,stack->port,"cb_event returned <0\n");
 					/*clean_up_bc(bc);*/
 				}
 			}
@@ -2115,6 +2203,12 @@
 		free_msg(msg);
 		return 1;
 	}
+
+
+	case PH_CONTROL | CONFIRM:
+		cb_log(2, stack->port, "PH_CONTROL|CNF bc->addr:%x\n", frm->addr);
+		free_msg(msg);
+		return 1;
 
 	case PH_DATA | CONFIRM:
 	case DL_DATA|CONFIRM:
@@ -2124,13 +2218,7 @@
 
 #endif
 		free_msg(msg);
-
-#ifdef ACK_HDLC
-		if (bc->hdlc) {
-			cb_log(4,stack->port,"Acknowledge Packet\n");
-			sem_post( (sem_t*)bc->ack_hdlc);
-		}
-#endif
+		
 		return 1;
 	case DL_DATA|RESPONSE:
 #if MISDN_DEBUG
@@ -2385,6 +2473,13 @@
 	struct misdn_stack * stack=find_stack_by_addr(frm->addr);
 	
 	if (!stack) {
+		if (frm->prim == (MGR_DELLAYER|CONFIRM)) {
+			cb_log(2, 0, "MGMT: DELLAYER|CONFIRM Addr: %x !\n",
+					frm->addr) ;
+			free(msg);
+			return 1;
+		}
+		
 		return 0;
 	}
 	
@@ -2707,6 +2802,7 @@
 	}
 	
 	cb_log(1, stack->port, "I SEND:%s oad:%s dad:%s \n", isdn_get_info(msgs_g, event, 0), bc->oad, bc->dad);
+	cb_log(1, stack->port, " --> bc_state:%s\n",bc_state2str(bc->bc_state));
 	misdn_lib_log_ies(bc);
 	
 	switch (event) {
@@ -2782,14 +2878,22 @@
 		stack_holder_add(stack,holded_bc);
 		
 		if (stack->nt) {
+			if (bc->bc_state == BCHAN_BRIDGED) {
+				misdn_split_conf(bc,bc->conf_id);
+				misdn_split_conf(bc->holded_bc,bc->holded_bc->conf_id);
+				/*bc_state_change(bc,BCHAN_SETUPED);
+				manager_bchannel_activate(bc);*/
+			}
+
 			empty_chan_in_stack(stack,bc->channel);
 			empty_bc(bc);
 			clean_up_bc(bc);
 		}
 		
 		/** we set it up later at RETRIEVE_ACK again.**/
-		holded_bc->upset=0;
-		holded_bc->active=0;
+		/*holded_bc->upset=0;
+		  holded_bc->active=0;*/
+		bc_state_change(holded_bc,BCHAN_CLEANED);
 		
 		cb_event( EVENT_NEW_BC, holded_bc, glob_mgr->user_data);
 	}
@@ -2866,7 +2970,7 @@
 	
 	if (handle_frm(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);
@@ -3227,20 +3331,27 @@
 		return ;
 	}
 
-	if (bc->upset != 2 ) {
-		cb_log(1, stack->port, "bchannel_activate: BC Not properly upsetted addr:%x\n", bc->addr);
+
+	switch (bc->bc_state) {
+
+	case BCHAN_SETUPED:
+		break;
+		
+	default:
+		cb_log(1, stack->port, "bchannel_activate: BC Not properly upsetted (state:%s) addr:%x\n", bc_state2str(bc->bc_state), bc->addr);
+
+		
 		return;
 	}
 	
+
 	
 	frm=(iframe_t*)msg->data;
 	/* we must activate if we are deactivated */
 	clear_ibuffer(bc->astbuf);
 	
-	if (bc->active) return;
-  
 	cb_log(5, stack->port, "$$$ Bchan Activated addr %x\n", bc->addr);
-
+	
 	/* activate bchannel */
 	frm->prim = DL_ESTABLISH | REQUEST;
 	frm->addr = bc->addr | FLG_MSG_DOWN ;
@@ -3249,9 +3360,9 @@
 	
 	msg_queue_tail(&glob_mgr->activatequeue, msg);
 	sem_post(&glob_mgr->new_msg);
-
-	bc->active=1;
-  
+	
+	bc_state_change(bc, BCHAN_ACTIVE);
+	
 	return ;
   
 }
@@ -3262,20 +3373,33 @@
 	iframe_t dact;
 
 	struct misdn_stack *stack=get_stack_by_bc(bc);
-	if (!bc->active) return;
-  
+
+
+	switch (bc->bc_state) {
+		case BCHAN_ACTIVATED:
+			break;
+		case BCHAN_BRIDGED:
+			misdn_split_conf(bc,bc->conf_id);
+			break;
+		default:
+			cb_log( 4, bc->port,"bchan_deactivate: called but not activated\n");
+			return ;
+
+	}
+	
 	cb_log(5, stack->port, "$$$ Bchan deActivated addr %x\n", bc->addr);
-  
+	
 	bc->generate_tone=0;
 	
 	dact.prim = DL_RELEASE | REQUEST;
 	dact.addr = bc->addr | FLG_MSG_DOWN;
 	dact.dinfo = 0;
 	dact.len = 0;
-  
+	
 	mISDN_write(stack->midev, &dact, mISDN_HEADER_LEN+dact.len, TIMEOUT_1SEC);
 	clear_ibuffer(bc->astbuf);
-	bc->active=0;
+	
+	bc_state_change(bc,BCHAN_RELEASE);
   
 	return;
 }
@@ -3284,7 +3408,15 @@
 int misdn_lib_tx2misdn_frm(struct misdn_bchannel *bc, void *data, int len)
 {
 	struct misdn_stack *stack=get_stack_by_bc(bc);
-	if (!bc->active) return -1;   
+
+	switch (bc->bc_state) {
+		case BCHAN_ACTIVATED:
+		case BCHAN_BRIDGED:
+			break;
+		default:
+			cb_log(3, bc->port, "BC not yet activated (state:%s)\n",bc_state2str(bc->bc_state));
+			return -1;
+	}
 	
 	char buf[4096 + mISDN_HEADER_LEN];
 	iframe_t *frm= (iframe_t*)buf;
@@ -3359,9 +3491,6 @@
 {
 	struct misdn_stack *stack=get_stack_by_bc(bc);
 	
-	if (bc->state == STATE_CONNECTED)
-		misdn_lib_send_event(bc,EVENT_DISCONNECT);
-
 	empty_chan_in_stack(stack, bc->channel);
 	empty_bc(bc);
   
@@ -3491,21 +3620,72 @@
 
 
 
+void misdn_join_conf(struct misdn_bchannel *bc, int conf_id)
+{
+	bc_state_change(bc,BCHAN_BRIDGED);
+	manager_ph_control(bc, CMX_RECEIVE_OFF, 0);
+	manager_ph_control(bc, CMX_CONF_JOIN, conf_id);
+
+	cb_log(1,bc->port, "Joining bc:%x in conf:%d\n",bc->addr,conf_id);
+
+	char data[16];
+	int len=15;
+
+	memset(data,0,15);
+	
+	misdn_lib_tx2misdn_frm(bc, data, len);
+
+}
+
+
+void misdn_split_conf(struct misdn_bchannel *bc, int conf_id)
+{
+	bc_state_change(bc,BCHAN_ACTIVATED);
+	manager_ph_control(bc, CMX_RECEIVE_ON, 0);
+	manager_ph_control(bc, CMX_CONF_SPLIT, conf_id);
+
+	cb_log(1,bc->port, "Splitting bc:%x in conf:%d\n",bc->addr,conf_id);
+}
+
 void misdn_lib_bridge( struct misdn_bchannel * bc1, struct misdn_bchannel *bc2) {
-	manager_ph_control(bc1, CMX_RECEIVE_OFF, 0);
-	manager_ph_control(bc2, CMX_RECEIVE_OFF, 0);
-	
-	manager_ph_control(bc1, CMX_CONF_JOIN, (bc1->pid<<1) +1);
-	manager_ph_control(bc2, CMX_CONF_JOIN, (bc1->pid<<1) +1);
+	int conf_id=(bc1->pid<<1) +1;
+
+	cb_log(1, bc1->port, "I Send: BRIDGE from:%d to:%d\n",bc1->port,bc2->port);
+	
+	struct misdn_bchannel *bc_list[]={
+		bc1,bc2,NULL
+	};
+	struct misdn_bchannel **bc;
+		
+	for (bc=bc_list; *bc;  *bc++) { 
+		(*bc)->conf_id=conf_id;
+		cb_log(1, (*bc)->port, " --> bc_addr:%x\n",(*bc)->addr);
+	
+		switch((*bc)->bc_state) {
+			case BCHAN_ACTIVATED:
+				misdn_join_conf(*bc,conf_id);
+				break;
+			default:
+				bc_next_state_change(*bc,BCHAN_BRIDGED);
+				break;
+		}
+	}
 }
 
 void misdn_lib_split_bridge( struct misdn_bchannel * bc1, struct misdn_bchannel *bc2)
 {
-	
-	manager_ph_control(bc1, CMX_RECEIVE_ON, 0) ;
-	manager_ph_control(bc2, CMX_RECEIVE_ON, 0);
-	
-	manager_ph_control(bc1, CMX_CONF_SPLIT, (bc1->pid<<1) +1);
-	manager_ph_control(bc2, CMX_CONF_SPLIT, (bc1->pid<<1) +1);
-	
-}
+
+	struct misdn_bchannel *bc_list[]={
+		bc1,bc2,NULL
+	};
+	struct misdn_bchannel **bc;
+		
+	for (bc=bc_list; *bc;  *bc++) { 
+		if ( (*bc)->bc_state == BCHAN_BRIDGED){
+			misdn_split_conf( *bc, (*bc)->conf_id);
+		} else {
+			cb_log( 2, (*bc)->port, "BC not bridged (state:%s) so not splitting it\n",bc_state2str((*bc)->bc_state));
+		}
+	}
+	
+}

Modified: trunk/channels/misdn/isdn_lib.h
URL: http://svn.digium.com/view/asterisk/trunk/channels/misdn/isdn_lib.h?rev=17128&r1=17127&r2=17128&view=diff
==============================================================================
--- trunk/channels/misdn/isdn_lib.h (original)
+++ trunk/channels/misdn/isdn_lib.h Mon Apr  3 14:17:59 2006
@@ -23,18 +23,25 @@
 
 #define MAX_BCHANS 30
 
-enum bc_state_e {
-	STATE_NOTHING=0,
-	STATE_NULL,
-	STATE_CALL_INIT,
-	STATE_CONNECTED,
-	STATE_HOLD_ACKNOWLEDGE
-};
+enum bchannel_state {
+	BCHAN_CLEANED=0,
+	BCHAN_EMPTY,
+	BCHAN_SETUP,
+	BCHAN_SETUPED,
+	BCHAN_ACTIVE,
+	BCHAN_ACTIVATED,
+	BCHAN_BRIDGE,
+	BCHAN_BRIDGED,
+	BCHAN_RELEASE,
+	BCHAN_RELEASED,
+	BCHAN_CLEAN,
+	BCHAN_ERROR
+};
+
 
 enum misdn_err_e {
 	ENOCHAN=1
 };
-
 
 
 enum mISDN_NUMBER_PLAN {
@@ -52,7 +59,6 @@
 	RESPONSE_ERR,
 	RESPONSE_OK
 };
-
 
 
 enum event_e {
@@ -243,11 +249,16 @@
 
 	int generate_tone;
 	int tone_cnt;
-  
-	enum bc_state_e state;
-
+ 
+	enum bchannel_state bc_state;
+	enum bchannel_state next_bc_state;
+
+	int conf_id;
+	
 	int holded;
 	int stack_holder;
+
+	struct misdn_bchannel *holded_bc;
 	
 	int pres;
 	int screen;
@@ -390,4 +401,11 @@
 #define PRI_TRANS_CAP_3_1K_AUDIO                                0x10
 #define PRI_TRANS_CAP_7K_AUDIO                                  0x11
 
+
+
+char *bc_state2str(enum bchannel_state state);
+void bc_state_change(struct misdn_bchannel *bc, enum bchannel_state state);
+
+
+
 #endif



More information about the asterisk-commits mailing list