private void CheckDeviceHandler(ZWaveNode node, ManufacturerSpecific manufacturerspecs) { //if (node.DeviceHandler == null) { var typeList = GetTypesInNamespace( Assembly.GetExecutingAssembly(), "ZWaveLib.Devices.ProductHandlers." ); for (int i = 0; i < typeList.Count; i++) { //Console.WriteLine(typelist[i].FullName); Type type = Assembly.GetExecutingAssembly().GetType(typeList[i].FullName); // full name - i.e. with namespace (perhaps concatenate) try { IZWaveDeviceHandler deviceHandler = (IZWaveDeviceHandler)Activator.CreateInstance(type); // if (deviceHandler.CanHandleProduct(manufacturerspecs)) { node.DeviceHandler = deviceHandler; node.DeviceHandler.SetNodeHost(node); SaveNodesConfig(); break; } } catch { // TODO: add error logging //Console.WriteLine("ERROR!!!!!!! " + ex.Message + " : " + ex.StackTrace); } } } }
private void CreateDevices(byte[] receivedMessage) { var nodeList = ExtractNodesFromBitMask(receivedMessage); foreach (byte i in nodeList) { var node = devices.Find(n => n.NodeId == i); if (node == null) { //Console.WriteLine("Z-Wave Adding node " + i + " Class[ Basic=" + receivedMessage[7].ToString("X2") + " Generic=" + ((GenericType)receivedMessage[8]).ToString() + " Specific=" + receivedMessage[9].ToString("X2") + " ]"); devices.Add(CreateDevice(i, 0x00)); } else { OnControllerEvent(new ControllerEventArgs(i, ControllerStatus.NodeUpdated)); // Send event } } while (nodeList.Count > 0) { ZWaveNode nextNode = devices.Find(zn => zn.BasicClass == 0x00); if (nextNode != null) { GetNodeCapabilities(nextNode.NodeId); } else { OnControllerEvent(new ControllerEventArgs(0x00, ControllerStatus.DiscoveryEnd)); // Send event break; } } }
public static void GetSupported(ZWaveNode node) { var message = ZWaveMessage.CreateRequest(node.Id, new byte[] { (byte)CommandClass.Security, (byte)SecurityCommand.SupportedGet }); SendMessage(node, message); }
public static SecurityData GetSecurityData(ZWaveNode node) { if (!node.Data.ContainsKey("SecurityData")) { node.Data.Add("SecurityData", new SecurityData(node)); } return (SecurityData)node.Data["SecurityData"]; }
public static void GetScheme(ZWaveNode node) { node.SendRequest(new byte[] { (byte)CommandClass.Security, (byte)SecurityCommand.SchemeGet, 0 }); }
internal virtual void _raiseUpdateParameterEvent(ZWaveNode node, int pid, ParameterType peventtype, object value) { if (UpdateNodeParameter != null) { UpdateNodeParameter(node, new UpdateNodeParameterEventArgs() { NodeId = (int)node.NodeId, ParameterId = pid, ParameterType = peventtype, Value = value }); } }
private void RemoveDevice(byte nodeId) { ZWaveNode node = _devices.Find(n => n.NodeId == nodeId); if (node != null) { node.UpdateNodeParameter -= znode_UpdateNodeParameter; node.ManufacturerSpecificResponse -= znode_ManufacturerSpecificResponse; } _devices.RemoveAll(zn => zn.NodeId == nodeId); }
public void SetDeviceHandler(ZWaveNode node) { // Search handler in nodesConfig first for (int n = 0; n < nodesConfig.Count; n++) { var config = nodesConfig[n]; if (config.NodeId == node.NodeId && config.DeviceHandler != null && !config.DeviceHandler.Contains(".Generic.")) { // set to last known handler SetDeviceHandlerFromName(node, config.DeviceHandler); break; } } // If no specific devicehandler could be found, then set a generic handler if (node.DeviceHandler == null) { IZWaveDeviceHandler deviceHandler = null; switch (node.GenericClass) { case 0x00: // need to query node capabilities //GetNodeCapabilities(node.NodeId); break; case (byte)ZWaveLib.GenericType.SwitchBinary: deviceHandler = new ProductHandlers.Generic.Switch(); break; case (byte)ZWaveLib.GenericType.SwitchMultilevel: // eg. dimmer deviceHandler = new ProductHandlers.Generic.Dimmer(); break; case (byte)ZWaveLib.GenericType.Thermostat: deviceHandler = new ProductHandlers.Generic.Thermostat(); break; // Fallback to generic Sensor driver if type is not directly supported. // The Generic.Sensor handler is currently used as some kind of multi-purpose driver default: deviceHandler = new ProductHandlers.Generic.Sensor(); break; } if (deviceHandler != null) { node.DeviceHandler = deviceHandler; node.DeviceHandler.SetNodeHost(node); } } }
public void SetDeviceHandlerFromName(ZWaveNode node, string fullName) { var type = Assembly.GetExecutingAssembly().GetType(fullName); // full name - i.e. with namespace (perhaps concatenate) try { var deviceHandler = (IZWaveDeviceHandler)Activator.CreateInstance(type); node.DeviceHandler = deviceHandler; node.DeviceHandler.SetNodeHost(node); } catch { // TODO: add error logging } }
public static void SendMessage(ZWaveNode node, byte[] message) { int length = message[5]; Utility.DebugLog(DebugMessageType.Information, "In sendMsg - SecurityHandler"); if (message.Length < 7) { Utility.DebugLog(DebugMessageType.Information, "Message too short"); } if (message[3] != 0x13) { Utility.DebugLog(DebugMessageType.Information, "Invalid Message type"); } if (length > 28) { SecutiryPayload t_payload = new SecutiryPayload(); t_payload.length = 28; t_payload.part = 1; byte[] t_message = new byte[t_payload.length]; System.Array.Copy(message, 6, t_message, 0, t_payload.length); t_payload.message = t_message; QueuePayload(node, t_payload); SecutiryPayload t_payload2 = new SecutiryPayload(); t_payload2.length = length - 28; t_payload2.part = 2; byte[] t_message2 = new byte[t_payload.length]; System.Array.Copy(message, 34, t_message2, 0, t_payload2.length); t_payload2.message = t_message2; QueuePayload(node, t_payload2); } else { SecutiryPayload t_payload = new SecutiryPayload(); t_payload.length = length; t_payload.part = 0; byte[] t_message = new byte[t_payload.length]; System.Array.Copy(message, 6, t_message, 0, t_payload.length); t_payload.message = t_message; QueuePayload(node, t_payload); } }
private void MessageResponseNodeCapabilityHandler(byte[] receivedMessage) { int length = receivedMessage.Length; if (length > 8) { try { var node = devices.Find(n => n.NodeId == currentCommandTargetNode); if (node == null) { //Console.WriteLine("Z-Wave Adding node " + currentCommandTargetNode + " Class[ Basic=" + receivedMessage[7].ToString("X2") + " Generic=" + ((GenericType)receivedMessage[8]).ToString() + " Specific=" + receivedMessage[9].ToString("X2") + " ]"); devices.Add(CreateDevice(currentCommandTargetNode, receivedMessage[8])); } // node.BasicClass = receivedMessage[7]; node.GenericClass = receivedMessage[8]; node.SpecificClass = receivedMessage[9]; node.SetGenericHandler(); // if (node.NodeId != 1) { //Console.WriteLine("Z-Wave Updating node " + node.NodeId + " Class[ Basic=" + receivedMessage[7].ToString("X2") + " Generic=" + ((GenericType)receivedMessage[8]).ToString() + " Specific=" + receivedMessage[9].ToString("X2") + " ]"); } } catch { //Console.WriteLine("Z-Wave ERROR adding node " + node.NodeId + " : " + e.Message + "\n" + e.StackTrace); //System.Diagnostics.Debugger.Break(); } } ZWaveNode nextNode = devices.Find(zn => zn.BasicClass == 0x00); if (nextNode != null) { currentCommandTargetNode = nextNode.NodeId; GetNodeCapabilities(currentCommandTargetNode); } else { OnDiscoveryEvent(new DiscoveryEventArgs(0x00, DISCOVERY_STATUS.DISCOVERY_END)); // Send event } }
private void CreateDevices(byte[] receivedMessage) { List <byte> nodeList = ExtractNodesFromBitMask(receivedMessage); foreach (byte i in nodeList) { ZWaveNode node = _devices.Find(n => n.NodeId == i); if (node == null) { //Console.WriteLine("Z-Wave Adding node " + i + " Class[ Basic=" + receivedMessage[7].ToString("X2") + " Generic=" + ((GenericType)receivedMessage[8]).ToString() + " Specific=" + receivedMessage[9].ToString("X2") + " ]"); _devices.Add(CreateDevice(i, 0x00)); } } Thread.Sleep(500); if (nodeList.Count > 0) { //Console.WriteLine("Z-Wave Querying node capabilities " + currentCommandTargetNode); currentCommandTargetNode = nodeList[0]; GetNodeCapabilities(currentCommandTargetNode); } }
private ZWaveNode CreateDevice(byte nodeId, byte genericClass) { String className = "ZWaveLib.Devices."; switch (genericClass) { case 0x02: className += "Controller"; this.NodeId = nodeId; return((ZWaveNode)this); default: // generic node className += "ZWaveNode"; break; } ZWaveNode znode = (ZWaveNode)Activator.CreateInstance(Type.GetType(className), new object[] { nodeId, zp, genericClass }); znode.UpdateNodeParameter += znode_UpdateNodeParameter; znode.ManufacturerSpecificResponse += znode_ManufacturerSpecificResponse; // znode.ManufacturerSpecific_Get(); return(znode); }
private static bool RequestNonce(ZWaveNode node) { var nodeSecurityData = GetSecurityData(node); Utility.DebugLog(DebugMessageType.Information, "In sendRequestNonce - SecurityHandler"); if (nodeSecurityData.IsWaitingForNonce) return false; Utility.DebugLog(DebugMessageType.Information, "In sendRequestNonce - not waiting for Nonce - SecurityHandler"); nodeSecurityData.IsWaitingForNonce = true; node.SendDataRequest(new byte[] { (byte)CommandClass.Security, (byte)SecurityCommand.NonceGet }); return true; }
private static void SetNetworkKey(ZWaveNode node) { byte[] t_msg = new byte[18]; t_msg[0] = (byte)CommandClass.Security; t_msg[1] = (byte)SecurityCommand.NetworkKeySet; var privateNetworkKey = GetSecurityData(node).GetPrivateNetworkKey(); if (privateNetworkKey == null) { privateNetworkKey = GetSecurityData(node).GeneratePrivateNetworkKey(); } Array.Copy(privateNetworkKey, 0, t_msg, 2, 16); byte[] f_msg = ZWaveMessage.BuildSendDataRequest(node.Id, t_msg); SendMessage(node, f_msg); }
public NodeEvent GetEvent(ZWaveNode node, byte[] message) { byte cmdType = message[1]; byte[] decryptedMessage; NodeEvent nodeEvent = null; int startOffset = 1; switch (cmdType) { case (byte)SecurityCommand.SupportedReport: Utility.DebugLog(DebugMessageType.Information, "Received COMMAND_SUPPORTED_REPORT for node: " + node.Id); /* this is a list of CommandClasses that should be Encrypted. * and it might contain new command classes that were not present in the NodeInfoFrame * so we have to run through, mark existing Command Classes as SetSecured (so SendMsg in the Driver * class will route the unecrypted messages to our SendMsg) and for New Command * Classes, create them, and of course, also do a SetSecured on them. * * This means we must do a SecurityCmd_SupportedGet request ASAP so we dont have * Command Classes created after the Discovery Phase is completed! */ byte[] securedClasses = new byte[message.Length - 3]; Array.Copy(message, 3, securedClasses, 0, message.Length - 3); nodeEvent = new NodeEvent(node, EventParameter.SecurityNodeInformationFrame, securedClasses, 0); break; case (byte)SecurityCommand.SchemeReport: Utility.DebugLog(DebugMessageType.Information, "Received COMMAND_SCHEME_REPORT for node: " + node.Id + ", " + (startOffset + 1)); int schemes = message[startOffset + 1]; SecurityData nodeSecurityData = GetSecurityData(node); if (nodeSecurityData.SchemeAgreed) { break; } else if (schemes == (byte)SecurityScheme.SchemeZero) { SetNetworkKey(node); nodeSecurityData.SchemeAgreed = true; } else { Utility.DebugLog(DebugMessageType.Information, " No common security scheme. The device will continue as an unsecured node."); } break; case (byte)SecurityCommand.NonceGet: Utility.DebugLog(DebugMessageType.Information, "Received COMMAND_NONCE_GET for node: " + node.Id); /* the Device wants to send us a Encrypted Packet, and thus requesting for our latest NONCE */ SendNonceReport(node); break; case (byte)SecurityCommand.MessageEncap: Utility.DebugLog(DebugMessageType.Information, "Received COMMAND_MESSAGE_ENCAP for node: " + node.Id); /* We recieved a Encrypted single packet from the Device. Decrypt it. */ decryptedMessage = DecryptMessage(node, message, startOffset); if (decryptedMessage != null) nodeEvent = new NodeEvent(node, EventParameter.SecurityDecriptedMessage, decryptedMessage, 0); break; case (byte)SecurityCommand.NonceReport: Utility.DebugLog(DebugMessageType.Information, "Received COMMAND_NONCE_REPORT for node: " + node.Id); /* we recieved a NONCE from a device, so assume that there is something in a queue to send out */ ProcessNonceReport(node, message, startOffset); break; case (byte)SecurityCommand.MessageEncapNonceGet: Utility.DebugLog(DebugMessageType.Information, "Received COMMAND_MESSAGE_ENCAP_NONCE_GET for node: " + node.Id); /* we recieved a encrypted packet from the device, and the device is also asking us to send a * new NONCE to it, hence there must be multiple packets.*/ decryptedMessage = DecryptMessage(node, message, startOffset); if (decryptedMessage != null) nodeEvent = new NodeEvent(node, EventParameter.SecurityDecriptedMessage, decryptedMessage, 0); /* Regardless of the success/failure of Decrypting, send a new NONCE */ SendNonceReport(node); break; case (byte)SecurityCommand.NetworkKeySet: Utility.DebugLog(DebugMessageType.Information, "Received COMMAND_NETWORK_KEY_SET for node: " + node.Id + ", " + (startOffset + 1)); /* we shouldn't get a NetworkKeySet from a node if we are the controller * as we send it out to the Devices */ break; case (byte)SecurityCommand.NetworkKeyVerify: Utility.DebugLog(DebugMessageType.Information, "Received COMMAND_NETWORK_KEY_VERIFY for node: " + node.Id + ", " + (startOffset + 1)); /* * if we can decrypt this packet, then we are assured that our NetworkKeySet is successfull * and thus should set the Flag referenced in SecurityCmd_SchemeReport */ GetSupported(node); break; case (byte)SecurityCommand.SchemeInherit: Utility.DebugLog(DebugMessageType.Information, "Received COMMAND_SCHEME_INHERIT for node: " + node.Id); /* only used in a Controller Replication Type enviroment. */ break; } return nodeEvent; }
internal virtual void RaiseUpdateParameterEvent(ZWaveNode node, int pid, ParameterType peventtype, object value) { if (UpdateNodeParameter != null) { UpdateNodeParameter(node, new UpdateNodeParameterEventArgs() { NodeId = (int)node.NodeId, ParameterId = pid, ParameterType = peventtype, Value = value }); } }
private void _zwavemessagereceived(object sender, ZWaveMessageReceivedEventArgs args) { int length = args.Message.Length; // try { ZWaveMessageHeader zh = (ZWaveMessageHeader)args.Message[0]; switch (zh) { case ZWaveMessageHeader.CAN: zp.SendAck(); // RESEND //Console.WriteLine("ZWaveLib: received CAN, resending last message"); // zp.ResendLastMessage(); break; case ZWaveMessageHeader.ACK: zp.SendAck(); break; case ZWaveMessageHeader.SOF: // start of zwave frame // // parse frame headers // int msglength = (int)args.Message[1]; ZWaveMessageType msgtype = (ZWaveMessageType)args.Message[2]; ZWaveCommandClass cmdclass = (args.Message.Length > 3 ? (ZWaveCommandClass)args.Message[3] : 0); // byte sourcenode = 0; // switch (msgtype) { case ZWaveMessageType.REQUEST: zp.SendAck(); if (_devices.Count == 0) { break; } byte callbackid = 0; switch (cmdclass) { case ZWaveCommandClass.CMD_NONE: break; case ZWaveCommandClass.CMD_NODE_ADD: callbackid = args.Message[4]; if (args.Message[5] == 0x03) // ADD_NODE_STATUS_ADDING_SLAVE { // //Console.WriteLine("\n\nADDING NODE SLAVE {0}\n -> ", zp.ByteArrayToString(args.Message)); // // example response from HSM-100 3in1 sensor // 01 15 00 4A 32 03 2E 0E 04 21 01 60 31 70 84 85 80 72 77 86 EF 20 79 // bt gt st c1 c2 c3 c4 c5 c6 c7 c8 c9 -------- // node supported classes (c1, c2.... cn) // _nodeoperationidcheck = args.Message[6]; CreateDevice(_nodeoperationidcheck, 0x00); } else if (args.Message[5] == 0x05) // ADD_NODE_STATUS_PROTOCOL_DONE { if (_nodeoperationidcheck == args.Message[6]) { //Console.WriteLine("\n\nADDING NODE PROTOCOL DONE {0} {1}\n\n", args.Message[6], callbackid); Thread.Sleep(500); GetNodeCapabilities(args.Message[6]); //Discovery(); } } else if (args.Message[5] == 0x07) // ADD_NODE_STATUS_ADDING_FAIL { //Console.WriteLine("\n\nADDING NODE FAIL {0}\n\n", args.Message[6]); } break; case ZWaveCommandClass.CMD_NODE_REMOVE: callbackid = args.Message[4]; if (args.Message[5] == 0x03) // REMOVE_NODE_STATUS_REMOVING_SLAVE { //Console.WriteLine("\n\nREMOVING NODE SLAVE {0}\n\n", args.Message[6]); _nodeoperationidcheck = args.Message[6]; } else if (args.Message[5] == 0x06) // REMOVE_NODE_STATUS_REMOVING_DONE { if (_nodeoperationidcheck == args.Message[6]) { //Console.WriteLine("\n\nREMOVING NODE DONE {0} {1}\n\n", args.Message[6], callbackid); OnDiscoveryEvent(new DiscoveryEventArgs(args.Message[6], DISCOVERY_STATUS.NODE_REMOVED)); // Send event RemoveDevice(args.Message[6]); } } else if (args.Message[5] == 0x07) // REMOVE_NODE_STATUS_REMOVING_FAIL { //Console.WriteLine("\n\nREMOVING NODE FAIL {0}\n\n", args.Message[6]); } break; case ZWaveCommandClass.CMD_APPLICATION_COMMAND: sourcenode = args.Message[5]; ZWaveNode node = _devices.Find(n => n.NodeId == sourcenode); if (node == null) { CreateDevice(sourcenode, 0x00); GetNodeCapabilities(sourcenode); } try { node.MessageRequestHandler(args.Message); } catch (Exception ex) { //Console.WriteLine("# " + ex.Message + "\n" + ex.StackTrace); } break; case ZWaveCommandClass.CMD_SEND_DATA: byte cid = args.Message[4]; if (cid == 0x01) // SEND DATA OK { // TODO: ... what does that mean? } else if (args.Message[5] == 0x00) { // Messaging complete, remove callbackid zp.PendingMessages.RemoveAll(zm => zm.CallbackId == cid); } else if (args.Message[5] == 0x01) { // TODO: callback error??? zp.ResendLastMessage(cid); } break; case ZWaveCommandClass.CMD_NODE_UPDATE_INFO: sourcenode = args.Message[5]; int niflen = (int)args.Message[6]; ZWaveNode znode = _devices.Find(n => n.NodeId == sourcenode); if (znode != null) { byte[] nodeinfo = new byte[niflen - 2]; //Console.WriteLine(ByteArrayToString(args.Message)); Array.Copy(args.Message, 7, nodeinfo, 0, niflen - 2); // _raiseUpdateParameterEvent(znode, 0, ParameterType.PARAMETER_NODE_INFO, zp.ByteArrayToString(nodeinfo)); _raiseUpdateParameterEvent(znode, 0, ParameterType.PARAMETER_WAKEUP_NOTIFY, "1"); } break; default: Console.WriteLine("\nUNHANDLED Z-Wave REQUEST\n " + zp.ByteArrayToString(args.Message) + "\n"); break; } break; case ZWaveMessageType.RESPONSE: switch (cmdclass) { case ZWaveCommandClass.CMD_DISCOVERY_NODES: MessageResponseNodeBitMaskHandler(args.Message); //zp.SendAck(); break; case ZWaveCommandClass.CMD_GET_NODE_PROTOCOL_INFO: MessageResponseNodeCapabilityHandler(args.Message); //zp.SendAck(); break; case ZWaveCommandClass.CMD_REQUEST_NODE_INFO: // Console.WriteLine("\nNODE INFO RESPONSE: " + zp.ByteArrayToString(args.Message) + "\n"); break; case ZWaveCommandClass.CMD_SEND_DATA: this.ReadyToSend = true; break; default: //if (args.Message.Length > 2 && args.Message[3] != 0x13) Console.WriteLine("\nUNHANDLED Z-Wave RESPONSE\n " + zp.ByteArrayToString(args.Message) + "\n"); break; } break; default: Console.WriteLine("\nUNHANDLED Z-Wave message TYPE\n " + zp.ByteArrayToString(args.Message) + "\n"); break; } // break; } } catch (Exception ex) { Console.WriteLine(ex.Message + "\n" + ex.StackTrace); } }
private static void QueuePayload(ZWaveNode node, SecutiryPayload payload) { var nodeSecurityData = GetSecurityData(node); lock (nodeSecurityData.SecurePayload) { nodeSecurityData.SecurePayload.Add(payload); if (nodeSecurityData.DeviceNonceTimer.ElapsedMilliseconds > 10000) nodeSecurityData.IsWaitingForNonce = false; if (!nodeSecurityData.IsWaitingForNonce) { RequestNonce(node); } } }
public static SecurityData GetSecurityData(ZWaveNode node) { return (SecurityData)node.GetData("SecurityData", new SecurityData(node)).Value; }
public SecurityData(ZWaveNode node) { parentNode = node; }
private static byte[] DecryptMessage(ZWaveNode node, byte[] message, int start) { SecurityData nodeSecurityData = GetSecurityData(node); Utility.DebugLog(DebugMessageType.Information, "In DecryptMessage - SecurityHandler"); if (nodeSecurityData.ControllerNonceTimer.ElapsedMilliseconds > 10000) { Utility.DebugLog(DebugMessageType.Information, "Received the nonce too late'" + nodeSecurityData.ControllerNonceTimer.ElapsedMilliseconds + "' > 10000"); return null; } // Utility.DebugLog(DebugMessageType.Information, "Message to be decrypted: " + BitConverter.ToString(message)); // Get IV from inbound packet byte[] iv = new byte[16]; Array.Copy(message, start + 1, iv, 0, 8); byte[] currentNonce = nodeSecurityData.GetControllerCurrentNonce(true); if (currentNonce == null) { Utility.DebugLog(DebugMessageType.Information, "currentNonce null"); return null; } Utility.DebugLog(DebugMessageType.Information, "currentNonce NOT null"); Array.Copy(currentNonce, 0, iv, 8, 8); int _length = message.Length; int encryptedpackagesize = _length - 11 - 8; //19 + 11 + 8 byte[] encryptedpacket = new byte[encryptedpackagesize]; Array.Copy(message, 8 + start + 1, encryptedpacket, 0, encryptedpackagesize); byte[] decryptedpacket = AesWork.EncryptOfbMessage(nodeSecurityData.EncryptionKey, iv, encryptedpacket); Utility.DebugLog(DebugMessageType.Information, "Message " + BitConverter.ToString(message)); Utility.DebugLog(DebugMessageType.Information, "IV " + BitConverter.ToString(iv)); //Utility.DebugLog(DebugMessageType.Information, "Encrypted Packet " + BitConverter.ToString(encryptedpacket)); Utility.DebugLog(DebugMessageType.Information, "Decrypted Packet " + BitConverter.ToString(decryptedpacket)); byte[] mac = GenerateAuthentication(nodeSecurityData.AuthorizationKey, message, start, _length, node.Id, 0x01, iv); byte[] e_mac = new byte[8]; Array.Copy(message, start + 8 + encryptedpackagesize + 2, e_mac, 0, 8); if (!Enumerable.SequenceEqual(mac, e_mac)) { Utility.DebugLog(DebugMessageType.Information, "Computed mac " + BitConverter.ToString(mac) + " does not match the provider mac " + BitConverter.ToString(e_mac) + ". Dropping."); if (nodeSecurityData.SecurePayload.Count > 1) RequestNonce(node); return null; } /* if (decryptedpacket[1] == (byte)CommandClass.Security && 1 == 0) { byte[] msg = new byte[decryptedpacket.Length - 1]; Array.Copy(decryptedpacket, 1, msg, 0, msg.Length); Utility.DebugLog(DebugMessageType.Information, "Processing Internally: " + BitConverter.ToString(msg)); } else { */ byte[] msg = new byte[decryptedpacket.Length - 2 + 8]; Array.Clear(msg, 0, 7); Array.Copy(decryptedpacket, 1, msg, 7, msg.Length - 7); msg[6] = (byte)(msg.Length - 7); Utility.DebugLog(DebugMessageType.Information, "Forwarding: " + BitConverter.ToString(msg)); /* send to the Command Class for Proecssing */ Utility.DebugLog(DebugMessageType.Information, "Received External Command Class: " + BitConverter.ToString(new byte[] { decryptedpacket[1] })); // node.MessageRequestHandler(node.pController, msg); Utility.DebugLog(DebugMessageType.Information, "In DecryptMessage - Finished"); return msg; }
// IN the mesage to be Encrypted // OUT - true - message processed and sent - proceed to next one // - false - we need to wait for the nonce report to come private static bool EncryptMessage(ZWaveNode node, byte[] message) { SecurityData nodeSecurityData = GetSecurityData(node); Utility.DebugLog(DebugMessageType.Information, "In EncryptMessage - secure_payload [" + nodeSecurityData.SecurePayload.Count + "] - " + nodeSecurityData.DeviceNonceTimer.ElapsedMilliseconds); // if we get true we need to wait for the new Nonce // if we get false we need to proceed // if (sendRequestNonce()) // return false; if (nodeSecurityData.DeviceNonceTimer.ElapsedMilliseconds > 10000) return false; SecutiryPayload payload = null; lock (nodeSecurityData.SecurePayload) { if (nodeSecurityData.SecurePayload.Count > 0) { payload = nodeSecurityData.SecurePayload.First(); nodeSecurityData.SecurePayload.Remove(payload); } } if (payload != null) { int len = payload.length + 20; byte[] t_message = new byte[len]; int i = 0; t_message[i] = (byte)CommandClass.Security; i++; t_message[i] = (byte)SecurityCommand.MessageEncap; byte[] initializationVector = new byte[16]; for (int a = 0; a < 8; a++) { initializationVector[a] = (byte)0xAA; i++; t_message[i] = initializationVector[a]; } Array.Copy(nodeSecurityData.DeviceCurrentNonce, 0, initializationVector, 8, 8); int sequence = 0; if (payload.part == 1) { ++nodeSecurityData.SequenceCounter; sequence = nodeSecurityData.SequenceCounter & (byte)0x0f; sequence |= (byte)0x10; } else if (payload.part == 2) { ++nodeSecurityData.SequenceCounter; sequence = nodeSecurityData.SequenceCounter & (byte)0x0f; sequence |= (byte)0x30; } byte[] plaintextmsg = new byte[payload.length + 1]; plaintextmsg[0] = (byte)sequence; for (int a = 0; a < payload.length; a++) { plaintextmsg[a + 1] = payload.message[a]; } byte[] encryptedPayload = new byte[30]; encryptedPayload = AesWork.EncryptOfbMessage(nodeSecurityData.EncryptionKey, initializationVector, plaintextmsg); Utility.DebugLog(DebugMessageType.Information, "authKey " + BitConverter.ToString(nodeSecurityData.AuthorizationKey)); Utility.DebugLog(DebugMessageType.Information, "EncryptKey " + BitConverter.ToString(nodeSecurityData.EncryptionKey)); Utility.DebugLog(DebugMessageType.Information, "Input Packet: " + BitConverter.ToString(plaintextmsg)); Utility.DebugLog(DebugMessageType.Information, "IV " + BitConverter.ToString(initializationVector)); Utility.DebugLog(DebugMessageType.Information, "encryptedPayload " + BitConverter.ToString(encryptedPayload)); for (int a = 0; a < payload.length + 1; ++a) { i++; t_message[i] = encryptedPayload[a]; } i++; t_message[i] = nodeSecurityData.DeviceCurrentNonce[0]; //GenerateAuthentication int start = 1; byte[] mac = GenerateAuthentication(nodeSecurityData.AuthorizationKey, t_message, start, t_message.Length + 2 - start - 1, 0x01, node.Id, initializationVector); for (int a = 0; a < 8; ++a) { i++; t_message[i] = mac[a]; } node.SendDataRequest(t_message); Utility.DebugLog(DebugMessageType.Information, "In EncryptMessage - message sent"); if ((nodeSecurityData.IsNetworkKeySet == false) && payload.message[0] == (byte)CommandClass.Security && payload.message[1] == (byte)SecurityCommand.NetworkKeySet) { nodeSecurityData.IsNetworkKeySet = true; nodeSecurityData.IsAddingNode = false; } return true; } return true; }
private static void ProcessNonceReport(ZWaveNode node, byte[] message, int start) { SecurityData nodeSecurityData = GetSecurityData(node); nodeSecurityData.DeviceNonceTimer.Restart(); if (nodeSecurityData.DeviceCurrentNonce == null) nodeSecurityData.DeviceCurrentNonce = new byte[8]; Array.Copy(message, start + 1, nodeSecurityData.DeviceCurrentNonce, 0, 8); EncryptMessage(node, message); nodeSecurityData.IsWaitingForNonce = false; // if we still have items in the queue request a new nonce if (nodeSecurityData.SecurePayload.Count > 0) { RequestNonce(node); } }
private static void SendNonceReport(ZWaveNode node) { byte[] message = new byte[10]; message[0] = (byte)CommandClass.Security; message[1] = (byte)SecurityCommand.NonceReport; GetSecurityData(node).GenerateControllerCurrentNonce(); Array.Copy(GetSecurityData(node).GetControllerCurrentNonce(), 0, message, 2, 8); node.SendDataRequest(message); GetSecurityData(node).ControllerNonceTimer.Reset(); }