[zb4osgi-changeset] [scm] ZigBee 4 OSGi repository change: r463 - /projects/zb4osgi/sandbox/manlio.bacco/org.aaloa.osgi.zigbee.basedriver/src/main/java/it/cnr/isti/zigbee/basedriver/discovery/NetworkBrowserThread.java

scm-notify at zb4osgi.aaloa.org scm-notify at zb4osgi.aaloa.org
Mon Sep 24 17:28:49 CEST 2012


Author: manlio.bacco
Date: Mon Sep 24 17:28:48 2012
New Revision: 463

Log:
new browsing thread methodology using  LQI  request to discover all devices in a network, also acting as a end-device

Modified:
    projects/zb4osgi/sandbox/manlio.bacco/org.aaloa.osgi.zigbee.basedriver/src/main/java/it/cnr/isti/zigbee/basedriver/discovery/NetworkBrowserThread.java

Modified: projects/zb4osgi/sandbox/manlio.bacco/org.aaloa.osgi.zigbee.basedriver/src/main/java/it/cnr/isti/zigbee/basedriver/discovery/NetworkBrowserThread.java
==============================================================================
--- projects/zb4osgi/sandbox/manlio.bacco/org.aaloa.osgi.zigbee.basedriver/src/main/java/it/cnr/isti/zigbee/basedriver/discovery/NetworkBrowserThread.java (original)
+++ projects/zb4osgi/sandbox/manlio.bacco/org.aaloa.osgi.zigbee.basedriver/src/main/java/it/cnr/isti/zigbee/basedriver/discovery/NetworkBrowserThread.java Mon Sep 24 17:28:48 2012
@@ -32,6 +32,7 @@
 import it.cnr.isti.zigbee.dongle.api.SimpleDriver;
 
 import java.util.ArrayList;
+import java.util.List;
 
 import org.aaloa.zb4osgi.api.monitor.ZigBeeDiscoveryMonitor;
 import org.osgi.framework.InvalidSyntaxException;
@@ -42,6 +43,9 @@
 import com.itaca.ztool.api.ZToolAddress16;
 import com.itaca.ztool.api.zdo.ZDO_IEEE_ADDR_REQ;
 import com.itaca.ztool.api.zdo.ZDO_IEEE_ADDR_RSP;
+import com.itaca.ztool.api.zdo.ZDO_MGMT_LQI_REQ;
+import com.itaca.ztool.api.zdo.ZDO_MGMT_LQI_RSP;
+import com.itaca.ztool.api.zdo.ZDO_MGMT_LQI_RSP.NeighborLqiListItemClass;
 
 
 /**
@@ -57,6 +61,7 @@
 	private static final Logger logger = LoggerFactory.getLogger(NetworkBrowserThread.class);
 
 	private static final short COORDINATOR_NWK_ADDRESS = 0;
+	private static final short LQI_START_INDEX = 0;
 
 	private final ImportingQueue queue;
 	final SimpleDriver driver;
@@ -64,7 +69,9 @@
 
 	final ArrayList<NetworkAddressNodeItem> toInspect = new ArrayList<NetworkAddressNodeItem>();
 	final TShortObjectHashMap<NetworkAddressNodeItem> alreadyInspected = new TShortObjectHashMap<NetworkAddressNodeItem>();
-
+	private List<NetworkAddressNodeItem> connectedNodesFound = new ArrayList<NetworkAddressNodeItem>();
+
+	//private GraphThread gt;
 
 	private class NetworkAddressNodeItem {
 		final NetworkAddressNodeItem parent;
@@ -90,55 +97,177 @@
 		this.driver = driver;        
 	}
 
+	private NetworkAddressNodeItem getIEEEAddress(short nwkAddress){
+
+		NetworkAddressNodeItem node = new NetworkAddressNodeItem(null, nwkAddress);
+		ZDO_IEEE_ADDR_RSP ieee_addr_resp = driver.sendZDOIEEEAddressRequest(
+				new ZDO_IEEE_ADDR_REQ(nwkAddress, ZDO_IEEE_ADDR_REQ.REQ_TYPE.EXTENDED,(byte) 0)						
+				);
+
+		if( ieee_addr_resp == null) {
+			logger.debug("No ZDO_IEEE_ADDR_RSP from #{}", nwkAddress);
+			return null;
+		} 
+		else {
+			logger.debug(
+					"ZDO_IEEE_ADDR_RSP from {} with {} associated", 
+					ieee_addr_resp.getIEEEAddress(), ieee_addr_resp.getAssociatedDeviceCount()
+					);
+
+			node.node = new ZigBeeNodeImpl(node.address, ieee_addr_resp.getIEEEAddress());
+
+			ZToolAddress16 nwk = new ZToolAddress16(
+					Integers.getByteAsInteger(node.address, 1),
+					Integers.getByteAsInteger(node.address, 0)
+					);
+
+			queue.push(nwk, ieee_addr_resp.getIEEEAddress());				
+			announceNode(node);
+
+			return node;
+		}
+	}
+
+	private void announceNodes(List<NetworkAddressNodeItem> nodes){
+
+		if(nodes != null)
+			for(int i = 0; i < nodes.size(); i++)
+				announceNode(nodes.get(i));
+	}
+
+	private void announceNode(NetworkAddressNodeItem node){
+
+		if(node != null){
+			notifyBrowsedNode(node);
+		}
+	}
+
+	private List<NetworkAddressNodeItem> lqiRequestToNode(NetworkAddressNodeItem node, int index){
+
+		if(alreadyInspected.get(node.address) == null){
+
+			if(index == 0)
+				connectedNodesFound.clear();
+
+			short nwk = node.address;
+
+			logger.debug("ZDO_MGMT_LQI_REQ to {} from index {}", node.address, index);
+			ZDO_MGMT_LQI_RSP lqi_resp = driver.sendLQIRequest(new ZDO_MGMT_LQI_REQ(nwk, index));
+
+			if( lqi_resp == null) {
+				logger.debug("No LQI answer from #{}", nwk);
+				return null;
+			}  
+			else {
+				logger.debug(
+						"Found {} neighbors on node {}",
+						lqi_resp.getNeighborLQICount(), node.address);
+
+				NeighborLqiListItemClass[] neighbors = (NeighborLqiListItemClass[]) lqi_resp.getNeighborLqiList();
+
+				if(neighbors != null){
+					for(int i = 0; i < neighbors.length; i++){
+						NeighborLqiListItemClass neighbor = (NeighborLqiListItemClass) neighbors[i];
+
+						logger.info("Node #{} visible from node #{} with LQI value {}", new Object[]{neighbor.NetworkAddress.get16BitValue(), nwk, neighbor.RxLQI});
+
+						NetworkAddressNodeItem result = getIEEEAddress((short)neighbor.NetworkAddress.get16BitValue());
+						NetworkAddressNodeItem newNode;
+						if(result != null){
+							newNode = new NetworkAddressNodeItem(node, result.address);
+							connectedNodesFound.add(newNode);
+						}
+						else{
+							newNode = new NetworkAddressNodeItem(node, (short)neighbor.NetworkAddress.get16BitValue());
+							connectedNodesFound.add(newNode);
+							logger.info("No response to ZDO_IEEE_ADDR_REQ from node {}", neighbor.NetworkAddress.get16BitValue());				
+						}
+
+						//GraphItem n = (gt).new GraphItem(node.address, neighbor.NetworkAddress.get16BitValue(), neighbor.Depth, neighbor.RxLQI);
+						//gt.graph.add(n);	
+					}
+				}
+
+				// NeighborLQICount: neighbors IN THIS RESPONSE
+				// NeighborLQIEntries: all available neighbors 
+				if(lqi_resp.getNeighborLQIEntries() > (lqi_resp.getNeighborLQICount()+index+1)){
+					logger.debug("ZDO_MGMT_LQI_REQ new request to {} because of too many entries for a single request," +
+							" restarting from index {}", node.address, lqi_resp.getNeighborLQICount()+index+1);
+					lqiRequestToNode(node, lqi_resp.getNeighborLQICount()+index+1);
+				}			
+
+				alreadyInspected.put(node.address, node);
+
+				return connectedNodesFound;
+			}
+		}
+		else{
+			logger.debug("Node {} inspected few seconds ago, request delayed", node.address);
+			return null;
+		}
+	}
+
+	private void inspectQueue(ArrayList<NetworkAddressNodeItem> toInspectTemp){
+
+		for(int i = 0; i < toInspect.size(); i++){
+			List<NetworkAddressNodeItem> children = new ArrayList<NetworkAddressNodeItem>();
+			NetworkAddressNodeItem node = toInspect.get(i);
+			if(node != null){
+				children = lqiRequestToNode(node, LQI_START_INDEX);
+				if(children != null){
+					toInspectTemp.addAll(children);
+					announceNodes(children);
+				}
+			}
+		}
+	}
+
 	public void run(){
-		
+
 		final String threadName = Thread.currentThread().getName();
 
 		logger.info("{} STARTED Succesfully", threadName);		
 
-		while(!isEnd()){			
-			long wakeUpTime = System.currentTimeMillis() + Activator.getCurrentConfiguration().getNetworkBrowsingPeriod();
+		while(!isEnd()){
 			cleanUpWalkingTree();
 
-			logger.info("Inspecting ZigBee network for new nodes");             
-			toInspect.add(new NetworkAddressNodeItem(null, COORDINATOR_NWK_ADDRESS) );
+			logger.info("Inspecting ZigBee network for new nodes");
+
 			try{
-				while(toInspect.size() != 0){
-					final NetworkAddressNodeItem inspecting = toInspect.remove( toInspect.size()-1 );
-
-					alreadyInspected.put(inspecting.address, inspecting);
-					logger.info("Inspecting node #{} ({})", inspecting.address, ((int) inspecting.address & 0xFFFF));
-					ZDO_IEEE_ADDR_RSP result = driver.sendZDOIEEEAddressRequest(
-							new ZDO_IEEE_ADDR_REQ(inspecting.address,ZDO_IEEE_ADDR_REQ.REQ_TYPE.EXTENDED,(byte) 0)						
-							);
-
-					if( result == null) {
-						logger.debug("No answer from #{} ({})", inspecting.address, ((int) inspecting.address & 0xFFFF));
-						continue;
-					} else {
-						logger.debug(
-								"Answer from {} with {} associated", 
-								result.getIEEEAddress(), result.getAssociatedDeviceCount()
-								);
-						inspecting.node = new ZigBeeNodeImpl( inspecting.address, result.getIEEEAddress());
-
-						ZToolAddress16 nwk = new ZToolAddress16(
-								Integers.getByteAsInteger(inspecting.address, 1),
-								Integers.getByteAsInteger(inspecting.address, 0)
-								);
-						queue.push(nwk, result.getIEEEAddress());						
-
-						notifyBrowsedNode(inspecting);
+				NetworkAddressNodeItem coordinator = getIEEEAddress(COORDINATOR_NWK_ADDRESS);
+				if(coordinator != null){
+
+					//gt = new GraphThread();
+
+					List<NetworkAddressNodeItem> coordinatorChildren = lqiRequestToNode(coordinator, LQI_START_INDEX);
+					if(coordinatorChildren != null)
+						toInspect.addAll(coordinatorChildren);
+
+					ArrayList<NetworkAddressNodeItem> toInspectTemp = new ArrayList<NetworkAddressNodeItem>();
+
+					while(!toInspect.isEmpty()){
+						inspectQueue(toInspectTemp);
+
+						toInspect.clear();
+						if(!toInspectTemp.isEmpty())
+							for(int i = 0; i < toInspectTemp.size(); i++)
+								toInspect.add(toInspectTemp.get(i));
+						toInspectTemp.clear();
 					}
-					toInspect.addAll( addChildrenNodesToInspectingQueue( inspecting, result ) );
+					toInspect.clear();					
 				}
 
-			}catch(Exception e){
+				long wakeUpTime = System.currentTimeMillis() + Activator.getCurrentConfiguration().getNetworkBrowsingPeriod();
+				ThreadUtils.waitingUntil( wakeUpTime );
+				logger.info("Network browsing completed, waiting until {}", wakeUpTime);
+				//gt.run();
+			}
+			catch(Exception e){
 				e.printStackTrace();
 			}
-			logger.info("Network browsing completed, waiting until {}", wakeUpTime);
-			ThreadUtils.waitingUntil( wakeUpTime );
-		}
+		}
+
+		//gt.end();
 		logger.info("{} TERMINATED Succesfully", threadName);
 	}
 
@@ -146,7 +275,7 @@
 		alreadyInspected.clear();
 		toInspect.clear();
 	}
-
+	/*
 	private ArrayList<NetworkAddressNodeItem> addChildrenNodesToInspectingQueue(NetworkAddressNodeItem inspecting, ZDO_IEEE_ADDR_RSP result) {
 		int start = 0;
 		final ArrayList<NetworkAddressNodeItem> adding = new ArrayList<NetworkAddressNodeItem>();
@@ -190,6 +319,54 @@
 		return adding;
 	}
 
+	private ArrayList<NetworkAddressNodeItem> addChildrenNodesToInspectingQueue(NetworkAddressNodeItem inspecting, ZDO_MGMT_LQI_RSP result) {
+		//int start = 0;
+		final ArrayList<NetworkAddressNodeItem> adding = new ArrayList<NetworkAddressNodeItem>();
+		//do{
+
+		NeighborLqiListItemClass[] list = (NeighborLqiListItemClass[]) result.getNeighborLqiList();
+		List<ZToolAddress16> toAdd = new ArrayList<ZToolAddress16>();
+		for(int i = 0; i < list.length; i++)
+			toAdd.add(list[i].NetworkAddress);
+
+		//List<ZToolAddress16> toAdd = result.getNeighborAddressList();
+		for (int i = 0; i < toAdd.size(); i++) {
+			logger.info("Found node #{} associated to node #{}", toAdd.get(i), inspecting.address);
+			final NetworkAddressNodeItem next = new NetworkAddressNodeItem(inspecting, (short)toAdd.get(i).get16BitValue());
+			final NetworkAddressNodeItem found = alreadyInspected.get((short)toAdd.get(i).get16BitValue());
+			if( found != null ) {
+				//NOTE Logging this wrong behavior but doing nothing
+				logger.error(
+						"BROKEN ZIGBEE UNDERSTANDING (while walking address-tree): " +
+								"found twice the same node with network address {} ", (short)toAdd.get(i).get16BitValue()
+						);
+				logger.debug("Previus node data was {} while current has parent {}", found, inspecting);
+			} else {								
+				adding.add(next);
+			}
+		}
+		//if( toAdd.size() + result.getStartIndex() >= result.getAssociatedDeviceCount() ) {
+		//NOTE No more node connected to inspecting
+		return adding;
+//		}
+//			start += toAdd.length;
+//
+//			logger.info(
+//					"Node #{} as many too many device connected to it received only {} out of {}, " +
+//							"we need to inspect it once more", new Object[]{
+//							inspecting.address, toAdd.length, result.getAssociatedDeviceCount()
+//					});
+//			result = driver.sendZDOIEEEAddressRequest(
+//					new ZDO_IEEE_ADDR_REQ(inspecting.address,ZDO_IEEE_ADDR_REQ.REQ_TYPE.EXTENDED,(byte) start )						
+//					);
+//			if ( result == null ){
+//				logger.error("Faild to further inspect connected device to node #{}", inspecting.address);
+//			}
+//		}while(result != null);
+//
+//		return adding;
+	}
+	 */
 	private void notifyBrowsedNode(NetworkAddressNodeItem item) {
 		ServiceReference[] refs = null;
 		try {
@@ -231,4 +408,4 @@
 	public synchronized void end() {
 		end = true;
 	}
-}
+}




More information about the Commit mailing list