예제 #1
0
 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);
             }
         }
     }
 }
예제 #2
0
        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;
                }
            }
        }
예제 #3
0
 public static void GetSupported(ZWaveNode node)
 {
     var message = ZWaveMessage.CreateRequest(node.Id, new byte[] {
         (byte)CommandClass.Security,
         (byte)SecurityCommand.SupportedGet
     });
     SendMessage(node, message);
 }
예제 #4
0
 public static SecurityData GetSecurityData(ZWaveNode node)
 {
     if (!node.Data.ContainsKey("SecurityData"))
     {
         node.Data.Add("SecurityData", new SecurityData(node));
     }
     return (SecurityData)node.Data["SecurityData"];
 }
예제 #5
0
 public static void GetScheme(ZWaveNode node)
 {
     node.SendRequest(new byte[] {
         (byte)CommandClass.Security,
         (byte)SecurityCommand.SchemeGet,
         0
     });
 }
예제 #6
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
         });
     }
 }
예제 #7
0
        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);
        }
예제 #8
0
        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);
                }
            }
        }
예제 #9
0
        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
            }
        }
예제 #10
0
        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);
            }
        }
예제 #11
0
        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
            }
        }
예제 #12
0
        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);
            }
        }
예제 #13
0
        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);
        }
예제 #14
0
        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;
        }
예제 #15
0
 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);
 }
예제 #16
0
        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;
        }
예제 #17
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 });
     }
 }
예제 #18
0
        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);
            }
        }
예제 #19
0
        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);
                }
            }
        }
예제 #20
0
 public static SecurityData GetSecurityData(ZWaveNode node)
 {
     return (SecurityData)node.GetData("SecurityData", new SecurityData(node)).Value;
 }
예제 #21
0
 public SecurityData(ZWaveNode node)
 {
     parentNode = node;
 }
예제 #22
0
        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;
        }
예제 #23
0
        // 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;

        }
예제 #24
0
        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);
            }
        }
예제 #25
0
        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();
        }