[zb4osgi-changeset] [scm] ZigBee 4 OSGi repository change: r1093 - in /projects/zb4osgi/trunk/zigbee.basedriver/src/main/java/it/cnr/isti/zigbee/basedriver/api/impl: WaitForClusterResponse.java ZigBeeDeviceImpl.java

scm-notify at zb4osgi.aaloa.org scm-notify at zb4osgi.aaloa.org
Wed Nov 12 15:10:28 CET 2014


Author: stefano.lenzi
Date: Wed Nov 12 15:10:28 2014
New Revision: 1093

Log:
WaitForClusterResponse does not use anymore inversion of control and it is more readable adding and removing it as listener
Avoiding stale reference for WaitForClusterResponse ( refs #273 )


Modified:
    projects/zb4osgi/trunk/zigbee.basedriver/src/main/java/it/cnr/isti/zigbee/basedriver/api/impl/WaitForClusterResponse.java
    projects/zb4osgi/trunk/zigbee.basedriver/src/main/java/it/cnr/isti/zigbee/basedriver/api/impl/ZigBeeDeviceImpl.java

Modified: projects/zb4osgi/trunk/zigbee.basedriver/src/main/java/it/cnr/isti/zigbee/basedriver/api/impl/WaitForClusterResponse.java
==============================================================================
--- projects/zb4osgi/trunk/zigbee.basedriver/src/main/java/it/cnr/isti/zigbee/basedriver/api/impl/WaitForClusterResponse.java	(original)
+++ projects/zb4osgi/trunk/zigbee.basedriver/src/main/java/it/cnr/isti/zigbee/basedriver/api/impl/WaitForClusterResponse.java	Wed Nov 12 15:10:28 2014
@@ -25,6 +25,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.itaca.ztool.api.af.AF_DATA_CONFIRM;
 import com.itaca.ztool.api.af.AF_INCOMING_MSG;
 
 /**
@@ -48,7 +49,6 @@
 	private short clusterId;
 	private long timeout = -1;
 	private AF_INCOMING_MSG response = null;
-	private AFMessageProducer producer;
 
 	private final Thread waiter;
 
@@ -58,12 +58,10 @@
 	 * @param timeout the maximum number of milliseconds to wait for. The value -1 means unlimited waiting time. 
 	 * @since  0.4.0
 	 */
-	public WaitForClusterResponse(final AFMessageProducer producer, final byte transaction, 
+	public WaitForClusterResponse(final byte transaction, 
 			final short id, final long timeout, final Thread thread) {
 		
 		synchronized (this) {
-			this.producer = producer;
-			this.producer.addAFMessageConsumer(this);
 			this.timeout = timeout;
 			this.waiter = thread;
 			response = null;
@@ -77,20 +75,28 @@
 	 * 
 	 * @param timeout the maximum number of milliseconds to wait for. The value -1 means unlimited waiting time. 
 	 */
-	public WaitForClusterResponse(final AFMessageProducer producer, final byte transaction, 
+	public WaitForClusterResponse(final byte transaction, 
 			final short id, final long timeout) {
 		
-		this(producer,transaction, id, timeout, Thread.currentThread());
+		this(transaction, id, timeout, Thread.currentThread());
 	}
 	
 	public boolean consume(AF_INCOMING_MSG msg) {
+		if ( response != null ) {
+			/*
+			 * We already recieved our response so nothing more should be done, someone else is going to consume 
+			 * the AF_INCOMING_MSG
+			 */
+			logger.debug("SKIPPED AF_INCOMING_MSG: the one that we were waiting for has been already recieved");
+			return false;
+		}
 		//THINK  Is the following matching algorithm correct?!?!?		
 		if ( msg.getClusterId() != clusterId ) {
-			logger.debug("Unable to consume AF_INCOMING_MSG, because cluster {} != {}", msg.getClusterId(), clusterId);
+			logger.debug("SKIPPED AF_INCOMING_MSG: the cluster do not matches {} != {}", msg.getClusterId(), clusterId);
 			return false;
 		}
 		if ( msg.getTransId() != transId ) {
-			logger.debug("Unable to consume AF_INCOMING_MSG, because transaction {} != {}", msg.getTransId(), transId);
+			logger.debug("SKIPPED AF_INCOMING_MSG: the transaction do not matches {} != {}", msg.getTransId(), transId);
 			return false;
 		}
 		logger.debug(
@@ -103,8 +109,6 @@
 			response = msg;
 			notify();		
 		}
-		//We wait for a cluster at the time
-		producer.removeAFMessageConsumer(this);
 		return true;
 	}
 	
@@ -118,7 +122,6 @@
 	 */ 	
 	public AF_INCOMING_MSG getResponse(){
 		final long wakeUpTime = System.currentTimeMillis() + timeout;
-		AF_INCOMING_MSG msg = null;
 		
 		synchronized (this) {
 			while(response == null && (timeout > 0 && wakeUpTime > System.currentTimeMillis())){
@@ -127,11 +130,8 @@
 				} catch (InterruptedException ignored) {
 				}
 			}
-			msg = response;
-			response = null;
-			producer.removeAFMessageConsumer(this);
 		}
-		return msg;
+		return response;
 	}
 	
 }

Modified: projects/zb4osgi/trunk/zigbee.basedriver/src/main/java/it/cnr/isti/zigbee/basedriver/api/impl/ZigBeeDeviceImpl.java
==============================================================================
--- projects/zb4osgi/trunk/zigbee.basedriver/src/main/java/it/cnr/isti/zigbee/basedriver/api/impl/ZigBeeDeviceImpl.java	(original)
+++ projects/zb4osgi/trunk/zigbee.basedriver/src/main/java/it/cnr/isti/zigbee/basedriver/api/impl/ZigBeeDeviceImpl.java	Wed Nov 12 15:10:28 2014
@@ -298,49 +298,54 @@
         final AFLayer af = AFLayer.getAFLayer(driver);
         final byte sender = af.getSendingEndpoint(this, input);
         /*
-         * //FIX Removed because transaction is always 0 for the response due to
-         * a bug of CC2480 final byte transaction =
-         * af.getNextTransactionId(sender); the next line is a workaround for
-         * the problem
+         * //FIX Removed because transaction is always 0 for the response due to a bug of CC2480 
+         * 
+         * final byte transaction = af.getNextTransactionId(sender); 
+         * the next line is a workaround for the problem
          */
         final byte transaction = 0;
         final byte[] msg = input.getClusterMsg();
 
         m_addAFMessageListener();
 
-        // Registering the waiter before sending the message, so that they will
-        // be captured
-        WaitForClusterResponse waiter = new WaitForClusterResponse(this,
-                transaction, input.getId(), TIMEOUT);
-
-        // TODO Create radius and options according to the current configuration
-        AF_DATA_CONFIRM response = driver
-                .sendAFDataRequest(new AF_DATA_REQUEST((short) node
-                        .getNetworkAddress(), (byte) endPointAddress, sender,
-                        input.getId(), transaction, (byte) 0 /* options */,
-                        (byte) 0 /* radius */, msg));
-
+        //Registering the waiter before sending the message, so that they will be captured
+        WaitForClusterResponse waiter = new WaitForClusterResponse(transaction, input.getId(), TIMEOUT);
+        addAFMessageConsumer(waiter);
+
+        //TODO Create radius and options according to the current configuration
+        AF_DATA_CONFIRM response = driver.sendAFDataRequest( new AF_DATA_REQUEST(
+				(short) node.getNetworkAddress(), 
+				(byte) endPointAddress, 
+				sender,
+	            input.getId(), 
+	            transaction, 
+	            (byte) 0 /* options */,
+	            (byte) 0 /* radius */, 
+	            msg
+		) );
+        
         if (response == null) {
+        	removeAFMessageConsumer(waiter);
             m_removeAFMessageListener();
             throw new ZigBeeBasedriverException(
-                    "Unable to send cluster on the ZigBee network due to general error - is the device sleeping?");
+            		"Unable to send cluster on the ZigBee network due to general error - is the device sleeping?"
+    		);
         } else if (response.getStatus() != 0) {
+        	removeAFMessageConsumer(waiter);
             m_removeAFMessageListener();
             throw new ZigBeeBasedriverException(
-                    "Unable to send cluster on the ZigBee network:"
-                            + response.getErrorMsg());
+            		"Unable to send cluster on the ZigBee network:" + response.getErrorMsg()
+    		);
         } else {
-            // FIX Can't be singleton because only a the invoke method can be
-            // invoked by multiple-thread
-            // FIX Can't be singleton because the invoke method can be invoked
-            // by multiple-thread
+            //FIX Can't be singleton because only a the invoke method can be invoked by multiple-thread
+            //FIX Can't be singleton because the invoke method can be invoked by multiple-thread
             AF_INCOMING_MSG incoming = waiter.getResponse();
+        	removeAFMessageConsumer(waiter);
             m_removeAFMessageListener();
             if (incoming == null) {
                 throw new ZigBeeBasedriverTimeOutException();
             }
-            Cluster result = new ClusterImpl(incoming.getData(),
-                    incoming.getClusterId());
+            Cluster result = new ClusterImpl(incoming.getData(), incoming.getClusterId());
             return result;
         }
     }




More information about the Commit mailing list