From f981ebef9f79acf7487e788e1650a7f3d0e096c7 Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthony.minessale@gmail.com>
Date: Thu, 14 Jun 2007 03:54:02 +0000
Subject: [PATCH] inbound calls milestone

git-svn-id: http://svn.openzap.org/svn/openzap/trunk@255 a93c3328-9c30-0410-af19-c9cd2b2d52af
---
 libs/openzap/mod_openzap/mod_openzap.c |   9 +-
 libs/openzap/src/include/openzap.h     |   3 +-
 libs/openzap/src/include/zap_types.h   |   9 +-
 libs/openzap/src/isdn/Q931api.c        |   9 +-
 libs/openzap/src/isdn/Q931ie.c         |  23 +++--
 libs/openzap/src/priserver.c           |   2 +-
 libs/openzap/src/zap_analog.c          |   3 +
 libs/openzap/src/zap_io.c              |  44 +++++---
 libs/openzap/src/zap_isdn.c            | 137 ++++++++++++++++++-------
 9 files changed, 164 insertions(+), 75 deletions(-)

diff --git a/libs/openzap/mod_openzap/mod_openzap.c b/libs/openzap/mod_openzap/mod_openzap.c
index e4793fe807..639fc18f6f 100644
--- a/libs/openzap/mod_openzap/mod_openzap.c
+++ b/libs/openzap/mod_openzap/mod_openzap.c
@@ -319,6 +319,7 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
 	case ZAP_CHAN_TYPE_B:
 		{
 			if (tech_pvt->zchan->state != ZAP_CHANNEL_STATE_DOWN) {
+				tech_pvt->zchan->caller_data.hangup_cause = switch_channel_get_cause(channel);
 				zap_set_state_locked(tech_pvt->zchan, ZAP_CHANNEL_STATE_HANGUP);
 			}
 		}
@@ -638,7 +639,7 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
 	}
 }
 
-static const switch_state_handler_table_t channel_event_handlers = {
+static switch_state_handler_table_t channel_event_handlers = {
 	/*.on_init */ channel_on_init,
 	/*.on_ring */ channel_on_ring,
 	/*.on_execute */ channel_on_execute,
@@ -647,7 +648,7 @@ static const switch_state_handler_table_t channel_event_handlers = {
 	/*.on_transmit */ channel_on_transmit
 };
 
-static const switch_io_routines_t channel_io_routines = {
+static switch_io_routines_t channel_io_routines = {
 	/*.outgoing_channel */ channel_outgoing_channel,
 	/*.read_frame */ channel_read_frame,
 	/*.write_frame */ channel_write_frame,
@@ -658,7 +659,7 @@ static const switch_io_routines_t channel_io_routines = {
 	/*.receive_message*/ channel_receive_message
 };
 
-static const switch_endpoint_interface_t channel_endpoint_interface = {
+static switch_endpoint_interface_t channel_endpoint_interface = {
 	/*.interface_name */ "openzap",
 	/*.io_routines */ &channel_io_routines,
 	/*.event_handlers */ &channel_event_handlers,
@@ -666,7 +667,7 @@ static const switch_endpoint_interface_t channel_endpoint_interface = {
 	/*.next */ NULL
 };
 
-static const switch_loadable_module_interface_t channel_module_interface = {
+static switch_loadable_module_interface_t channel_module_interface = {
 	/*.module_name */ modname,
 	/*.endpoint_interface */ &channel_endpoint_interface,
 	/*.timer_interface */ NULL,
diff --git a/libs/openzap/src/include/openzap.h b/libs/openzap/src/include/openzap.h
index a13ae80814..316b4d3af4 100644
--- a/libs/openzap/src/include/openzap.h
+++ b/libs/openzap/src/include/openzap.h
@@ -195,7 +195,7 @@
 
 #define zap_set_state_locked(obj, s) if ( obj->state == s ) {			\
 		zap_log(ZAP_LOG_WARNING, "Why bother changing state from %s to %s\n", zap_channel_state2str(obj->state), zap_channel_state2str(s)); \
-	} else {															\
+	} else if (zap_test_flag(obj, ZAP_CHANNEL_READY)) {									\
 		int st = obj->state;											\
 		zap_channel_set_state(obj, s);									\
 		if (obj->state == s) zap_log(ZAP_LOG_DEBUG, "Changing state from %s to %s\n", zap_channel_state2str(st), zap_channel_state2str(s)); \
@@ -297,6 +297,7 @@ struct zap_caller_data {
 	char dnis[25];
 	char rdnis[25];
 	int CRV;
+	int hangup_cause;	
 	uint8_t raw_data[1024];
 	uint32_t raw_data_len;
 };
diff --git a/libs/openzap/src/include/zap_types.h b/libs/openzap/src/include/zap_types.h
index c6ae837986..b81f5338c1 100644
--- a/libs/openzap/src/include/zap_types.h
+++ b/libs/openzap/src/include/zap_types.h
@@ -224,7 +224,8 @@ typedef enum {
 
 typedef enum {
 	ZAP_SPAN_CONFIGURED = (1 << 0),
-	ZAP_SPAN_READY = (1 << 1)
+	ZAP_SPAN_READY = (1 << 1),
+	ZAP_SPAN_STATE_CHANGE = (1 << 2)
 } zap_span_flag_t;
 
 typedef enum {
@@ -258,10 +259,13 @@ typedef enum {
 	ZAP_CHANNEL_STATE_DIALING,
 	ZAP_CHANNEL_STATE_GET_CALLERID,
 	ZAP_CHANNEL_STATE_CALLWAITING,
+	ZAP_CHANNEL_STATE_TERMINATING,
+	ZAP_CHANNEL_STATE_RESTART,
 	ZAP_CHANNEL_STATE_INVALID
 } zap_channel_state_t;
 #define CHANNEL_STATE_STRINGS "DOWN", "UP", "HANGUP", "HOLD", "DIALTONE", "COLLECT", \
-		"RING", "BUSY", "ATTN", "IDLE", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", "INVALID"
+		"RING", "BUSY", "ATTN", "IDLE", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", \
+		"TERMINATING", "RESTART", "INVALID"
 ZAP_STR2ENUM_P(zap_str2zap_channel_state, zap_channel_state2str, zap_channel_state_t)
 
 typedef enum {
@@ -285,7 +289,6 @@ typedef enum {
 	ZAP_CHANNEL_CALLERID_DETECT = (1 << 17)
 } zap_channel_flag_t;
 
-
 typedef struct zap_channel zap_channel_t;
 typedef struct zap_event zap_event_t;
 typedef struct zap_sigmsg zap_sigmsg_t;
diff --git a/libs/openzap/src/isdn/Q931api.c b/libs/openzap/src/isdn/Q931api.c
index 1ac2a56b96..2e4e0063a6 100644
--- a/libs/openzap/src/isdn/Q931api.c
+++ b/libs/openzap/src/isdn/Q931api.c
@@ -518,8 +518,8 @@ L3INT Q931Disconnect(Q931_TrunkInfo_t *pTrunk, L3INT iTo, L3INT iCRV, L3INT iCau
 L3INT Q931ReleaseComplete(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf)
 {
     Q931mes_Header *ptr = (Q931mes_Header*)&buf[Q931L4HeaderSpace];
-	ptr->MesType = Q931mes_RESTART_ACKNOWLEDGE;
-
+	ptr->MesType = Q931mes_RELEASE_COMPLETE;
+	ptr->CRVFlag = !(ptr->CRVFlag);
 	return Q931Tx32(pTrunk,buf,ptr->Size);
 }
 
@@ -528,7 +528,10 @@ L3INT Q931AckRestart(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf)
 	L3INT RetCode;
 
     Q931mes_Header *ptr = (Q931mes_Header*)&buf[Q931L4HeaderSpace];
-	ptr->MesType = Q931mes_RELEASE_COMPLETE;
+	ptr->MesType = Q931mes_RESTART_ACKNOWLEDGE;
+	if (ptr->CRV) {
+		ptr->CRVFlag = !(ptr->CRVFlag);
+	}
 
 	RetCode = Q931Proc[pTrunk->Dialect][ptr->MesType](pTrunk, buf, 4);
 
diff --git a/libs/openzap/src/isdn/Q931ie.c b/libs/openzap/src/isdn/Q931ie.c
index 9e2f687206..0ea4251dbf 100644
--- a/libs/openzap/src/isdn/Q931ie.c
+++ b/libs/openzap/src/isdn/Q931ie.c
@@ -715,19 +715,22 @@ L3INT Q931Uie_CalledNum(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR
     pie->TypNum = (IBuf[Octet+Off] >> 4) & 0x07;
     pie->NumPlanID = IBuf[Octet+Off] & 0x0f;
     Octet ++;
-    
+
     /* Octet 4*/
-    for (x = 0; x < IESize - 1; x++)
-    {
+    x=0;
+    do{
         pie->Digit[x] = IBuf[Octet+Off] & 0x7f;
         Off++;
-    }
+        x++;
+    } while((IBuf[Octet+Off]&0x80) == 0 && Q931MoreIE());
+
+	pie->Digit[x] = '\0';
 
     Q931SetIE(*pIE, *OOff);
 
 	*IOff = (*IOff) + Octet + Off;
-    *OOff = (*OOff) + sizeof(Q931ie_CalledNum) + x - 1;
-    pie->Size = (L3UCHAR)(sizeof(Q931ie_CalledNum) + x - 1);
+    *OOff = (*OOff) + sizeof(Q931ie_CalledNum) + x;
+    pie->Size = (L3UCHAR)(sizeof(Q931ie_CalledNum) + x);
 
     return Q931E_NO_ERROR;
 }
@@ -824,15 +827,17 @@ L3INT Q931Uie_CallingNum(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHA
         pie->Digit[x] = IBuf[Octet+Off] & 0x7f;
         Off++;
         x++;
-    }while((IBuf[Octet+Off]&0x80) == 0 && Q931MoreIE());
+    } while((IBuf[Octet+Off]&0x80) == 0 && Q931MoreIE());
+
+	pie->Digit[x] = '\0';
 
     Q931IESizeTest(Q931E_CALLINGNUM);
 
     Q931SetIE(*pIE, *OOff);
 
     *IOff = (*IOff) + Octet + Off;
-    *OOff = (*OOff) + sizeof(Q931ie_CallingNum) + x - 1;
-    pie->Size = (L3UCHAR)(sizeof(Q931ie_CallingNum) + x - 1);
+    *OOff = (*OOff) + sizeof(Q931ie_CallingNum) + x;
+    pie->Size = (L3UCHAR)(sizeof(Q931ie_CallingNum) + x);
 
     return Q931E_NO_ERROR;
 }
diff --git a/libs/openzap/src/priserver.c b/libs/openzap/src/priserver.c
index 57c29146c2..6bb5e02965 100644
--- a/libs/openzap/src/priserver.c
+++ b/libs/openzap/src/priserver.c
@@ -180,7 +180,7 @@ static void launch_channel(struct sangoma_pri *spri, int channo)
 	close(file);
 	//close(ifd);
 
-
+	pri_hangup(spri->pri, channo, 16);
 	if (zap_channel_close(&chan) != ZAP_SUCCESS) {
 		printf("Critical Error: Failed to close channel [%s]\n", chan->last_error);
 	}
diff --git a/libs/openzap/src/zap_analog.c b/libs/openzap/src/zap_analog.c
index 7bca77d10a..0ad28c92bd 100644
--- a/libs/openzap/src/zap_analog.c
+++ b/libs/openzap/src/zap_analog.c
@@ -307,6 +307,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
 					if (done) {
 						zap_set_state_locked(chan, ZAP_CHANNEL_STATE_UP);
 						zap_clear_flag_locked(chan, ZAP_CHANNEL_STATE_CHANGE);
+						zap_clear_flag_locked(chan->span, ZAP_SPAN_STATE_CHANGE);
 						chan->detected_tones[ZAP_TONEMAP_CALLWAITING_ACK] = 0;
 					}
 				}
@@ -328,6 +329,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
 			}
 		} else {
 			zap_clear_flag_locked(chan, ZAP_CHANNEL_STATE_CHANGE);
+			zap_clear_flag_locked(chan->span, ZAP_SPAN_STATE_CHANGE);
 			indicate = 0;
 			state_counter = 0;
 			zap_log(ZAP_LOG_DEBUG, "Executing state handler for %s\n", zap_channel_state2str(chan->state));
@@ -631,6 +633,7 @@ static zap_status_t process_event(zap_span_t *span, zap_event_t *event)
 			if (event->channel->state == ZAP_CHANNEL_STATE_CALLWAITING) {
 				zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_UP);
 				zap_clear_flag_locked(event->channel, ZAP_CHANNEL_STATE_CHANGE);
+				zap_clear_flag_locked(event->channel->span, ZAP_SPAN_STATE_CHANGE);
 				event->channel->detected_tones[ZAP_TONEMAP_CALLWAITING_ACK] = 0;
 			} 
 
diff --git a/libs/openzap/src/zap_io.c b/libs/openzap/src/zap_io.c
index 82d6706134..8f5e0d08f6 100644
--- a/libs/openzap/src/zap_io.c
+++ b/libs/openzap/src/zap_io.c
@@ -511,26 +511,35 @@ zap_status_t zap_channel_set_state(zap_channel_t *zchan, zap_channel_state_t sta
 	
 	zap_mutex_lock(zchan->mutex);
 
-	if (zchan->state == ZAP_CHANNEL_STATE_DOWN) {
-
-		switch(state) {
-		case ZAP_CHANNEL_STATE_BUSY:
-			ok = 0;
-			break;
-		default:
-			break;
-		}
+	if (!zap_test_flag(zchan, ZAP_CHANNEL_READY)) {
+		return ZAP_FAIL;
 	}
 
-	if (zchan->state == ZAP_CHANNEL_STATE_BUSY) {
-
-		switch(state) {
-		case ZAP_CHANNEL_STATE_UP:
-			ok = 0;
-			break;
-		default:
-			break;
+	switch(zchan->state) {
+	case ZAP_CHANNEL_STATE_DOWN:
+		{
+			switch(state) {
+			case ZAP_CHANNEL_STATE_BUSY:
+			case ZAP_CHANNEL_STATE_HANGUP:
+			case ZAP_CHANNEL_STATE_TERMINATING:
+				ok = 0;
+				break;
+			default:
+				break;
+			}
 		}
+	case ZAP_CHANNEL_STATE_BUSY:
+		{
+			switch(state) {
+			case ZAP_CHANNEL_STATE_UP:
+				ok = 0;
+				break;
+			default:
+				break;
+			}
+		}
+	default:
+		break;
 	}
 
 	if (state == zchan->state) {
@@ -539,6 +548,7 @@ zap_status_t zap_channel_set_state(zap_channel_t *zchan, zap_channel_state_t sta
 
 	if (ok) {
 		zap_set_flag(zchan, ZAP_CHANNEL_STATE_CHANGE);	
+		zap_set_flag(zchan->span, ZAP_SPAN_STATE_CHANGE);
 		zchan->last_state = zchan->state; 
 		zchan->state = state;
 	}
diff --git a/libs/openzap/src/zap_isdn.c b/libs/openzap/src/zap_isdn.c
index 35b828c387..d114be55d0 100644
--- a/libs/openzap/src/zap_isdn.c
+++ b/libs/openzap/src/zap_isdn.c
@@ -66,52 +66,74 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen)
 	zap_span_t *span = (zap_span_t *) pvt;
 	zap_isdn_data_t *data = span->isdn_data;
 	Q931mes_Generic *gen = (Q931mes_Generic *) msg;
-
+	Q931ie_ChanID *chanid = Q931GetIEPtr(gen->ChanID, gen->buf);
+	int chan_id = chanid->ChanSlot;
+	zap_channel_t *zchan = NULL;
+	
 	assert(span != NULL);
 	assert(data != NULL);
+	
+	if (chan_id) {
+		zchan = &span->channels[chan_id];
+	}
 
-	zap_log(ZAP_LOG_DEBUG, "Yay I got an event! Type:[%d] Size:[%d]\n", gen->MesType, gen->Size);
+	zap_log(ZAP_LOG_DEBUG, "Yay I got an event! Type:[%02x] Size:[%d]\n", gen->MesType, gen->Size);
 	switch(gen->MesType) {
+	case Q931mes_RESTART:
+		{
+			if (zchan) {
+				zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RESTART);
+			} else {
+				uint32_t i;
+				for (i = 0; i < span->chan_count; i++) {
+					zap_set_state_locked((&span->channels[i]), ZAP_CHANNEL_STATE_RESTART);
+				}
+			}
+		}
+		break;
+	case Q931mes_RELEASE_COMPLETE:
+		{
+			zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN);
+		}
+		break;
+	case Q931mes_DISCONNECT:
+		{
+			zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_TERMINATING);
+		}
+		break;
 	case Q931mes_SETUP:
 		{
-			Q931ie_ChanID *chanid = Q931GetIEPtr(gen->ChanID, gen->buf);
+
 			Q931ie_CallingNum *callingnum = Q931GetIEPtr(gen->CallingNum, gen->buf);
 			Q931ie_CalledNum *callednum = Q931GetIEPtr(gen->CalledNum, gen->buf);
-			int chan_id = chanid->ChanSlot;
-			zap_channel_t *zchan;
 			zap_status_t status;
-			zap_sigmsg_t sig;
-			zap_isdn_data_t *data;
 			int fail = 1;
 			uint32_t cplen = mlen;
 
+
 			if ((status = zap_channel_open(span->span_id, chan_id, &zchan) == ZAP_SUCCESS)) {
-				zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RING);
-				sig.chan_id = zchan->chan_id;
-				sig.span_id = zchan->span_id;
-				sig.channel = zchan;
-				sig.event_id = ZAP_SIGEVENT_START;
-				data = zchan->span->isdn_data;
-				
-				memset(&zchan->caller_data, 0, sizeof(zchan->caller_data));
+				if (zchan->state == ZAP_CHANNEL_STATE_DOWN) {
+					memset(&zchan->caller_data, 0, sizeof(zchan->caller_data));
 
-				zap_copy_string(zchan->caller_data.cid_num, (char *)callingnum->Digit, callingnum->Size - 3);
-				zap_copy_string(zchan->caller_data.cid_name, (char *)callingnum->Digit, callingnum->Size - 3);
-				zap_copy_string(zchan->caller_data.ani, (char *)callingnum->Digit, callingnum->Size - 3);
-				zap_copy_string(zchan->caller_data.dnis, (char *)callednum->Digit, callednum->Size - 3);
+					zap_set_string(zchan->caller_data.cid_num, callingnum->Digit);
+					zap_set_string(zchan->caller_data.cid_name, callingnum->Digit);
+					zap_set_string(zchan->caller_data.ani, callingnum->Digit);
+					zap_set_string(zchan->caller_data.dnis, callednum->Digit);
 
-				zchan->caller_data.CRV = gen->CRV;
-				if (cplen > sizeof(zchan->caller_data.raw_data)) {
-					cplen = sizeof(zchan->caller_data.raw_data);
-				}
-				memcpy(zchan->caller_data.raw_data, msg, cplen);
-				zchan->caller_data.raw_data_len = cplen;
-				if ((status = data->sig_cb(&sig) == ZAP_SUCCESS)) {
+					zchan->caller_data.CRV = gen->CRV;
+					if (cplen > sizeof(zchan->caller_data.raw_data)) {
+						cplen = sizeof(zchan->caller_data.raw_data);
+					}
+					gen->CRVFlag = !(gen->CRVFlag);
+					memcpy(zchan->caller_data.raw_data, msg, cplen);
+					zchan->caller_data.raw_data_len = cplen;
+					zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RING);
 					fail = 0;
-				}
+				} 
 			} 
 
 			if (fail) {
+				zap_log(ZAP_LOG_CRIT, "FIX ME!\n");
 				// add me 
 			}
 			
@@ -147,39 +169,80 @@ static int zap_isdn_921_21(void *pvt, L2UCHAR *msg, L2INT mlen)
 	return zap_channel_write(span->isdn_data->dchan, msg, len, &len) == ZAP_SUCCESS ? 0 : -1;
 }
 
-static void state_advance(zap_channel_t *zchan)
+static __inline__ void state_advance(zap_channel_t *zchan)
 {
 	Q931mes_Generic *gen = (Q931mes_Generic *) zchan->caller_data.raw_data;
 	zap_isdn_data_t *data = zchan->span->isdn_data;
+	zap_sigmsg_t sig;
+	zap_status_t status;
 
 	zap_log(ZAP_LOG_ERROR, "%d:%d STATE [%s]\n", 
 			zchan->span_id, zchan->chan_id, zap_channel_state2str(zchan->state));
 
+	memset(&sig, 0, sizeof(sig));
+	sig.chan_id = zchan->chan_id;
+	sig.span_id = zchan->span_id;
+	sig.channel = zchan;
 
 	switch (zchan->state) {
+	case ZAP_CHANNEL_STATE_RING:
+		{
+			sig.event_id = ZAP_SIGEVENT_START;
+			if ((status = data->sig_cb(&sig) != ZAP_SUCCESS)) {
+				zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_HANGUP);
+			}
+
+		}
+		break;
+	case ZAP_CHANNEL_STATE_RESTART:
+		{
+			zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN);
+			zap_channel_close(&zchan);
+		}
+		break;
 	case ZAP_CHANNEL_STATE_UP:
 		{
-			printf("XXXXXXXXXXXXXXXX answer %d\n", zchan->caller_data.raw_data_len);
 			gen->MesType = Q931mes_CONNECT;
 			gen->BearerCap = 0;
-			gen->CRVFlag = 1;//!(gen->CRVFlag);
 			Q931Rx43(&data->q931, (void *)gen, zchan->caller_data.raw_data_len);
 		}
 		break;
+	case ZAP_CHANNEL_STATE_HANGUP:
+		{
+			Q931ie_Cause cause;
+			gen->MesType = Q931mes_DISCONNECT;
+			cause.IEId = Q931ie_CAUSE;
+			cause.Size = sizeof(Q931ie_Cause);
+			cause.CodStand  = 0;
+			cause.Location = 1;
+			cause.Recom = 1;
+			cause.Value = zchan->caller_data.hangup_cause;
+			*cause.Diag = '\0';
+			gen->Cause = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &cause);
+			Q931Rx43(&data->q931, (L3UCHAR *) gen, gen->Size);
+		}
+		break;
+	case ZAP_CHANNEL_STATE_TERMINATING:
+		{
+			gen->MesType = Q931mes_RELEASE;
+			Q931Rx43(&data->q931, (void *)gen, gen->Size);
+		}
 	default:
 		break;
 	}
 }
 
-static void check_state(zap_span_t *span)
+static __inline__ void check_state(zap_span_t *span)
 {
-	uint32_t j;
-	
-	for(j = 1; j <= span->chan_count; j++) {
-		if (zap_test_flag((&span->channels[j]), ZAP_CHANNEL_STATE_CHANGE)) {
-			state_advance(&span->channels[j]);
-			zap_clear_flag_locked((&span->channels[j]), ZAP_CHANNEL_STATE_CHANGE);
+	if (zap_test_flag(span, ZAP_SPAN_STATE_CHANGE)) {
+		uint32_t j;
+		for(j = 1; j <= span->chan_count; j++) {
+			if (zap_test_flag((&span->channels[j]), ZAP_CHANNEL_STATE_CHANGE)) {
+				state_advance(&span->channels[j]);
+				zap_clear_flag_locked((&span->channels[j]), ZAP_CHANNEL_STATE_CHANGE);
+			}
 		}
+		zap_clear_flag_locked(span, ZAP_SPAN_STATE_CHANGE);
 	}
 }