public void SetDao(ZigBeeNodeDao dao) { IeeeAddress = new IeeeAddress(dao.IeeeAddress); NetworkAddress = dao.NetworkAddress; NodeDescriptor = dao.NodeDescriptor; PowerDescriptor = dao.PowerDescriptor; if (dao.BindingTable != null) { BindingTable.AddRange(dao.BindingTable); } foreach (ZigBeeEndpointDao endpointDao in dao.Endpoints) { ZigBeeEndpoint endpoint = new ZigBeeEndpoint(this, endpointDao.EndpointId); endpoint.SetDao(endpointDao); Endpoints[endpoint.EndpointId] = endpoint; } }
/// <summary> /// Updates the node. This will copy data from another node into this node. Updated elements are checked for equality /// and the method will only return true if the node data has been changed. /// /// @param node the {@link ZigBeeNode} that contains the newer node data. /// @return true if there were changes made as a result of the update /// </summary> public bool UpdateNode(ZigBeeNode node) { if (!node.IeeeAddress.Equals(IeeeAddress)) { return(false); } bool updated = false; if (!NetworkAddress.Equals(node.NetworkAddress)) { updated = true; NetworkAddress = node.NetworkAddress; } if (!NodeDescriptor.Equals(node.NodeDescriptor)) { updated = true; NodeDescriptor = node.NodeDescriptor; } if (!PowerDescriptor.Equals(node.PowerDescriptor)) { updated = true; PowerDescriptor = node.PowerDescriptor; } lock (AssociatedDevices) { if (!AssociatedDevices.Equals(node.AssociatedDevices)) { updated = true; AssociatedDevices.Clear(); AssociatedDevices.AddRange(node.AssociatedDevices); } } lock (BindingTable) { if (!BindingTable.Equals(node.BindingTable)) { updated = true; BindingTable.Clear(); BindingTable.AddRange(node.BindingTable); } } lock (Neighbors) { if (!Neighbors.Equals(node.Neighbors)) { updated = true; Neighbors.Clear(); Neighbors.AddRange(node.Neighbors); } } lock (Routes) { if (!Routes.Equals(node.Routes)) { updated = true; Routes.Clear(); Routes.AddRange(node.Routes); } } // TODO: How to deal with endpoints return(updated); }
/// <summary> /// {@inheritDoc} /// </summary> public T ReadZigBeeType <T>(DataType type) { if (index == payload.Length) { return(default(T)); } object[] value = new object[1]; switch (type) { case DataType.BOOLEAN: value[0] = payload[index++] == 0 ? false : true; break; case DataType.OCTET_STRING: int octetSize = payload[index++]; value[0] = new ByteArray(payload, index, index + octetSize); index += octetSize; break; case DataType.CHARACTER_STRING: int stringSize = payload[index++]; if (stringSize == 255) { value[0] = null; break; } byte[] bytes = new byte[stringSize]; int length = stringSize; for (int cnt = 0; cnt < stringSize; cnt++) { bytes[cnt] = (byte)payload[index + cnt]; if (payload[index + cnt] == 0) { length = cnt; break; } } try { int len = length - 0; byte[] dest = new byte[len]; // note i is always from 0 for (int i = 0; i < len; i++) { dest[i] = bytes[0 + i]; // so 0..n = 0+x..n+x } value[0] = Encoding.Default.GetString(dest); } catch (Exception e) { value[0] = null; break; } index += stringSize; break; case DataType.ENDPOINT: case DataType.BITMAP_8_BIT: case DataType.DATA_8_BIT: case DataType.ENUMERATION_8_BIT: value[0] = (byte)((byte)payload[index++] & 0xFF); break; case DataType.EXTENDED_PANID: byte[] panId = new byte[8]; for (int iCnt = 7; iCnt >= 0; iCnt--) { panId[iCnt] = payload[index + iCnt]; } index += 8; value[0] = new ExtendedPanId(panId); break; case DataType.IEEE_ADDRESS: byte[] address = new byte[8]; for (int iCnt = 7; iCnt >= 0; iCnt--) { address[iCnt] = payload[index + iCnt]; } index += 8; value[0] = new IeeeAddress(address); break; case DataType.N_X_ATTRIBUTE_INFORMATION: break; case DataType.N_X_ATTRIBUTE_RECORD: break; case DataType.N_X_ATTRIBUTE_REPORT: break; case DataType.N_X_ATTRIBUTE_REPORTING_CONFIGURATION_RECORD: break; case DataType.N_X_ATTRIBUTE_SELECTOR: break; case DataType.N_X_ATTRIBUTE_STATUS_RECORD: break; case DataType.N_X_EXTENSION_FIELD_SET: break; case DataType.N_X_NEIGHBORS_INFORMATION: break; case DataType.N_X_READ_ATTRIBUTE_STATUS_RECORD: List <ReadAttributeStatusRecord> records = new List <ReadAttributeStatusRecord>(); while (IsEndOfStream() == false) { ReadAttributeStatusRecord statusRecord = new ReadAttributeStatusRecord(); statusRecord.Deserialize(this); records.Add(statusRecord); } value[0] = records; break; case DataType.N_X_UNSIGNED_16_BIT_INTEGER: int cntN16 = (byte)(payload[index++] & 0xFF); List <ushort> arrayN16 = new List <ushort>(cntN16); for (int arrayIndex = 0; arrayIndex < cntN16; arrayIndex++) { arrayN16.Add(BitConverter.ToUInt16(payload, index)); index += 2; } value[0] = arrayN16; break; case DataType.N_X_UNSIGNED_8_BIT_INTEGER: int cntN8 = (byte)(payload[index++] & 0xFF); List <byte> arrayN8 = new List <byte>(cntN8); for (int arrayIndex = 0; arrayIndex < cntN8; arrayIndex++) { arrayN8.Add(payload[index++]); } value[0] = arrayN8; break; case DataType.X_UNSIGNED_8_BIT_INTEGER: int cntX8 = payload.Length - index; List <byte> arrayX8 = new List <byte>(cntX8); for (int arrayIndex = 0; arrayIndex < cntX8; arrayIndex++) { arrayX8.Add((byte)(payload[index++])); } value[0] = arrayX8; break; case DataType.N_X_ATTRIBUTE_IDENTIFIER: int cntX16 = (payload.Length - index) / 2; List <ushort> arrayX16 = new List <ushort>(cntX16); for (int arrayIndex = 0; arrayIndex < cntX16; arrayIndex++) { arrayX16.Add(BitConverter.ToUInt16(payload, index)); index += 2; } value[0] = arrayX16; break; case DataType.UNSIGNED_8_BIT_INTEGER_ARRAY: int cnt8Array = payload.Length - index; byte[] intarray8 = new byte[cnt8Array]; for (int arrayIndex = 0; arrayIndex < cnt8Array; arrayIndex++) { intarray8[arrayIndex] = payload[index++]; } value[0] = intarray8; break; case DataType.N_X_WRITE_ATTRIBUTE_RECORD: break; case DataType.N_X_WRITE_ATTRIBUTE_STATUS_RECORD: break; case DataType.SIGNED_16_BIT_INTEGER: short s = (short)(payload[index++] | (payload[index++] << 8)); value[0] = s; break; case DataType.CLUSTERID: case DataType.NWK_ADDRESS: case DataType.BITMAP_16_BIT: case DataType.ENUMERATION_16_BIT: case DataType.UNSIGNED_16_BIT_INTEGER: ushort us = (ushort)(payload[index++] | (payload[index++] << 8)); value[0] = us; break; case DataType.UNSIGNED_24_BIT_INTEGER: value[0] = payload[index++] + (payload[index++] << 8) | (payload[index++] << 16); break; case DataType.BITMAP_32_BIT: case DataType.SIGNED_32_BIT_INTEGER: case DataType.UNSIGNED_32_BIT_INTEGER: value[0] = payload[index++] + (payload[index++] << 8) | (payload[index++] << 16) + (payload[index++] << 24); break; case DataType.UNSIGNED_48_BIT_INTEGER: value[0] = (payload[index++]) + ((long)(payload[index++]) << 8) | ((long)(payload[index++]) << 16) + ((long)(payload[index++]) << 24) | ((long)(payload[index++]) << 32) + ((long)(payload[index++]) << 40); break; case DataType.SIGNED_8_BIT_INTEGER: value[0] = (sbyte)(payload[index++]); break; case DataType.UNSIGNED_8_BIT_INTEGER: value[0] = (byte)(payload[index++] & 0xFF); break; case DataType.UTCTIME: //TODO: Implement date deserialization break; case DataType.ROUTING_TABLE: RoutingTable routingTable = new RoutingTable(); routingTable.Deserialize(this); value[0] = routingTable; break; case DataType.NEIGHBOR_TABLE: NeighborTable neighborTable = new NeighborTable(); neighborTable.Deserialize(this); value[0] = neighborTable; break; case DataType.NODE_DESCRIPTOR: NodeDescriptor nodeDescriptor = new NodeDescriptor(); nodeDescriptor.Deserialize(this); value[0] = nodeDescriptor; break; case DataType.POWER_DESCRIPTOR: PowerDescriptor powerDescriptor = new PowerDescriptor(); powerDescriptor.Deserialize(this); value[0] = powerDescriptor; break; case DataType.BINDING_TABLE: BindingTable bindingTable = new BindingTable(); bindingTable.Deserialize(this); value[0] = bindingTable; break; case DataType.SIMPLE_DESCRIPTOR: SimpleDescriptor simpleDescriptor = new SimpleDescriptor(); simpleDescriptor.Deserialize(this); value[0] = simpleDescriptor; break; case DataType.ZCL_STATUS: value[0] = (ZclStatus)(payload[index++]); break; case DataType.ZDO_STATUS: value[0] = (ZdoStatus)(payload[index++]); break; case DataType.ZIGBEE_DATA_TYPE: value[0] = ZclDataType.Get(payload[index++]); break; case DataType.BYTE_ARRAY: int cntB8 = (byte)(payload[index++] & 0xFF); byte[] arrayB8 = new byte[cntB8]; for (int arrayIndex = 0; arrayIndex < cntB8; arrayIndex++) { arrayB8[arrayIndex] = (byte)(payload[index++] & 0xff); } value[0] = new ByteArray(arrayB8); break; default: throw new ArgumentException("No reader defined in " + this.GetType().Name + " for " + type.ToString() + " (" + (byte)type + ")"); } return((T)value[0]); }
/// <summary> /// Updates the node. This will copy data from another node into this node. Updated elements are checked for equality /// and the method will only return true if the node data has been changed. /// /// <param name="node">the <see cref="ZigBeeNode"> that contains the newer node data.</param> /// <returns>true if there were changes made as a result of the update</returns> /// </summary> public bool UpdateNode(ZigBeeNode node) { if (!node.IeeeAddress.Equals(IeeeAddress)) { return(false); } bool updated = false; if (!NetworkAddress.Equals(node.NetworkAddress)) { updated = true; NetworkAddress = node.NetworkAddress; } if (!NodeDescriptor.Equals(node.NodeDescriptor)) { updated = true; NodeDescriptor = node.NodeDescriptor; } if (!PowerDescriptor.Equals(node.PowerDescriptor)) { updated = true; PowerDescriptor = node.PowerDescriptor; } lock (AssociatedDevices) { if (!AssociatedDevices.Equals(node.AssociatedDevices)) { updated = true; AssociatedDevices.Clear(); AssociatedDevices.AddRange(node.AssociatedDevices); } } lock (BindingTable) { if (!BindingTable.Equals(node.BindingTable)) { updated = true; BindingTable.Clear(); BindingTable.AddRange(node.BindingTable); } } lock (Neighbors) { if (!Neighbors.Equals(node.Neighbors)) { updated = true; Neighbors.Clear(); Neighbors.AddRange(node.Neighbors); } } lock (Routes) { if (!Routes.Equals(node.Routes)) { updated = true; Routes.Clear(); Routes.AddRange(node.Routes); } } // Endpoints are only copied over if they don't exist in the node // The assumption here is that endpoints are only set once, and not changed. // This should be valid as they are set through the SimpleDescriptor. foreach (var endpoint in node.Endpoints) { if (Endpoints.ContainsKey(endpoint.Key)) { continue; } updated = true; Endpoints[endpoint.Key] = endpoint.Value; } return(updated); }
/// <summary> /// Updates the node. This will copy data from another node into this node. Updated elements are checked for equality /// and the method will only return true if the node data has been changed. /// /// <param name="node">the <see cref="ZigBeeNode"> that contains the newer node data.</param> /// <returns>true if there were changes made as a result of the update</returns> /// </summary> public bool UpdateNode(ZigBeeNode node) { if (!node.IeeeAddress.Equals(IeeeAddress)) { Log.Debug("{IeeeAddress}: Ieee address inconsistent during update <>{NodeIeeeAddress}", IeeeAddress, node.IeeeAddress); return(false); } bool updated = false; if (NetworkAddress != 0 && !NetworkAddress.Equals(node.NetworkAddress)) { Log.Debug("{IeeeAddress}: Network address updated from {NetworkAddress} to {NodeNetworkAddress}", IeeeAddress, NetworkAddress, node.NetworkAddress); updated = true; NetworkAddress = node.NetworkAddress; } if (node.NodeDescriptor != null && (NodeDescriptor == null || !NodeDescriptor.Equals(node.NodeDescriptor))) { Log.Debug("{IeeeAddress}: Node descriptor updated", IeeeAddress); updated = true; NodeDescriptor = node.NodeDescriptor; } if (node.PowerDescriptor != null && (PowerDescriptor == null || !PowerDescriptor.Equals(node.PowerDescriptor))) { Log.Debug("{IeeeAddress}: Power descriptor updated", IeeeAddress); updated = true; PowerDescriptor = node.PowerDescriptor; } lock (AssociatedDevices) { if (!AssociatedDevices.SetEquals(node.AssociatedDevices)) { Log.Debug("{IeeeAddress}: Associated devices updated", IeeeAddress); updated = true; AssociatedDevices.Clear(); AssociatedDevices.UnionWith(node.AssociatedDevices); } } lock (BindingTable) { if (!BindingTable.SetEquals(node.BindingTable)) { Log.Debug("{IeeeAddress}: Binding table updated", IeeeAddress); updated = true; BindingTable.Clear(); BindingTable.UnionWith(node.BindingTable); } } lock (Neighbors) { if (!Neighbors.SetEquals(node.Neighbors)) { Log.Debug("{IeeeAddress}: Neighbors updated", IeeeAddress); updated = true; Neighbors.Clear(); Neighbors.UnionWith(node.Neighbors); } } lock (Routes) { if (!Routes.SetEquals(node.Routes)) { Log.Debug("{IeeeAddress}: Routes updated", IeeeAddress); updated = true; Routes.Clear(); Routes.UnionWith(node.Routes); } } // Endpoints are only copied over if they don't exist in the node // The assumption here is that endpoints are only set once, and not changed. // This should be valid as they are set through the SimpleDescriptor. foreach (var endpoint in node.Endpoints) { if (Endpoints.ContainsKey(endpoint.Key)) { continue; } Log.Debug("{IeeeAddress}: Endpoint {EndpointId} added", IeeeAddress, endpoint.Key); updated = true; Endpoints[endpoint.Key] = endpoint.Value; } return(updated); }