private void ReceiveMessage(byte[] message) { ZWaveMessageHeader header = (ZWaveMessageHeader)((int)message[0]); // if (header == ZWaveMessageHeader.ACK) { ZWaveMessageReceived( this, new ZWaveMessageReceivedEventArgs(new byte[] { (byte)ZWaveMessageHeader.ACK }) ); if (message.Length > 1) { byte[] msg = new byte[message.Length - 1]; Array.Copy(message, 1, msg, 0, msg.Length); ReceiveMessage(msg); } return; } // int msgLength = 0; byte[] nextMessage = null; if (message.Length > 1) { msgLength = (int)message[1]; if (message.Length > msgLength + 3) { nextMessage = new byte[message.Length - msgLength - 2]; Array.Copy(message, msgLength + 2, nextMessage, 0, nextMessage.Length); byte[] tmpmsg = new byte[msgLength + 2]; Array.Copy(message, 0, tmpmsg, 0, msgLength + 2); message = tmpmsg; } } // //Console.WriteLine("=== > " + ByteArrayToString(message)); // if (header == ZWaveMessageHeader.SOF) { // found SOF // byte[] cmdAck = new byte[] { 0x01, 0x04, 0x01, 0x13, 0x01, 0xE8 }; if (message.SequenceEqual(cmdAck)) { //_ackwait.Set(); } else if (VerifyChecksum(message)) { ZWaveMessageReceived(this, new ZWaveMessageReceivedEventArgs(message)); } else { Console.WriteLine("\nZWaveLib: bad checksum message " + ByteArrayToString(message) + "\n"); } } else if (header == ZWaveMessageHeader.CAN) { // RESEND ResendLastMessage(); // ZWaveMessageReceived( this, new ZWaveMessageReceivedEventArgs(new byte[] { (byte)ZWaveMessageHeader.CAN }) ); } else { Console.WriteLine("ZWaveLib: unhandled message " + ByteArrayToString(message)); // ZWaveMessageReceived(this, new ZWaveMessageReceivedEventArgs(new byte[] { (byte)ZWaveMessageHeader.NAK })); } if (nextMessage != null) { ReceiveMessage(nextMessage); } }
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 void ZwaveMessageReceived(object sender, ZWaveMessageReceivedEventArgs args) { // discard repeated messages within last 2 seconds time range bool repeated = false; if (lastMessage != null) { var elapsed = (DateTime.UtcNow - lastMessageTimestamp); if (elapsed.TotalSeconds <= 2 && lastMessage.SequenceEqual(args.Message)) { repeated = true; } } lastMessageTimestamp = DateTime.UtcNow; lastMessage = new byte[args.Message.Length]; Buffer.BlockCopy(args.Message, 0, lastMessage, 0, args.Message.Length * sizeof(byte)); if (repeated) { zwavePort.SendAck(); Console.WriteLine("ZWaveLib: repeated message discarded."); return; } // int length = args.Message.Length; try { ZWaveMessageHeader zwaveHeader = (ZWaveMessageHeader)args.Message[0]; switch (zwaveHeader) { case ZWaveMessageHeader.CAN: zwavePort.SendAck(); // RESEND //Console.WriteLine("ZWaveLib: received CAN, resending last message"); //zp.ResendLastMessage(); break; case ZWaveMessageHeader.ACK: zwavePort.SendAck(); break; case ZWaveMessageHeader.SOF: // start of zwave frame // // parse frame headers // //int msgLength = (int)args.Message[1]; var msgType = (ZWaveMessageType)args.Message[2]; var cmdClass = (args.Message.Length > 3 ? (Command)args.Message[3] : 0); byte sourceNodeId = 0; // switch (msgType) { case ZWaveMessageType.REQUEST: zwavePort.SendAck(); if (devices.Count == 0) { break; } switch (cmdClass) { case Command.CMD_NONE: break; case Command.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]); } OnControllerEvent(new ControllerEventArgs( 0x00, ControllerStatus.DISCOVERY_END )); // Send event } 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 Command.CMD_NODE_REMOVE: 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); RemoveDevice(args.Message[6]); } OnControllerEvent(new ControllerEventArgs( 0x00, ControllerStatus.DISCOVERY_END )); // Send event } 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 Command.CMD_APPLICATION_COMMAND: sourceNodeId = args.Message[5]; var node = devices.Find(n => n.NodeId == sourceNodeId); if (node == null) { CreateDevice(sourceNodeId, 0x00); GetNodeCapabilities(sourceNodeId); } try { node.MessageRequestHandler(args.Message); } catch (Exception ex) { Console.WriteLine("# " + ex.Message + "\n" + ex.StackTrace); } break; case Command.CMD_SEND_DATA: byte commandId = args.Message[4]; if (commandId == 0x01) // SEND DATA OK { // TODO: ... what does that mean? } else if (args.Message[5] == 0x00) { // Messaging complete, remove callbackid zwavePort.PendingMessages.RemoveAll(zm => zm.CallbackId == commandId); } else if (args.Message[5] == 0x01) { byte nodeID = zwavePort.ResendLastMessage(commandId); if (nodeID != 0) { // Resend timed out OnControllerEvent(new ControllerEventArgs(nodeID, ControllerStatus.NODE_ERROR)); } } break; case Command.CMD_NODE_UPDATE_INFO: sourceNodeId = args.Message[5]; int nifLength = (int)args.Message[6]; var znode = devices.Find(n => n.NodeId == sourceNodeId); if (znode != null) { byte[] nodeInfo = new byte[nifLength - 2]; //Console.WriteLine(ByteArrayToString(args.Message)); Array.Copy(args.Message, 7, nodeInfo, 0, nifLength - 2); // RaiseUpdateParameterEvent( znode, 0, ParameterType.PARAMETER_NODE_INFO, zwavePort.ByteArrayToString(nodeInfo) ); RaiseUpdateParameterEvent( znode, 0, ParameterType.PARAMETER_WAKEUP_NOTIFY, "1" ); } break; default: Console.WriteLine("\nUNHANDLED Z-Wave REQUEST\n " + zwavePort.ByteArrayToString(args.Message) + "\n"); break; } break; case ZWaveMessageType.RESPONSE: switch (cmdClass) { case Command.CMD_DISCOVERY_NODES: MessageResponseNodeBitMaskHandler(args.Message); break; case Command.CMD_GET_NODE_PROTOCOL_INFO: MessageResponseNodeCapabilityHandler(args.Message); break; case Command.CMD_REQUEST_NODE_INFO: // TODO: shall we do something here? break; case Command.CMD_SEND_DATA: // TODO: shall we do something here? break; default: Console.WriteLine("\nUNHANDLED Z-Wave RESPONSE\n " + zwavePort.ByteArrayToString(args.Message) + "\n"); break; } break; default: Console.WriteLine("\nUNHANDLED Z-Wave message TYPE\n " + zwavePort.ByteArrayToString(args.Message) + "\n"); break; } break; } } catch (Exception ex) { Console.WriteLine(ex.Message + "\n" + ex.StackTrace); } }