private static CommandMetadata ReadCommandInfo(BinaryReader reader)
 {
     return new CommandMetadata()
     {
         Intent = reader.ReadUInt16(),
         Name = reader.ReadUtfString(),
         Parameters = ReadParameterList(reader)
     };
 }
        private static JToken ReadParameterValue(BinaryReader reader, ParameterMetadata parameterMetadata)
        {
            switch (parameterMetadata.DataType)
            {
                case DataType.Null:
                    return null;

                case DataType.Byte:
                    return (int) reader.ReadByte();
                
                case DataType.Word:
                    return reader.ReadUInt16();

                case DataType.Dword:
                    return reader.ReadUInt32();

                case DataType.Qword:
                    return reader.ReadUInt64();

                case DataType.SignedByte:
                    return reader.ReadSByte();

                case DataType.SignedWord:
                    return reader.ReadInt16();

                case DataType.SignedDword:
                    return reader.ReadInt32();
                
                case DataType.SignedQword:
                    return reader.ReadInt64();

                case DataType.Single:
                    return reader.ReadSingle();

                case DataType.Double:
                    return reader.ReadDouble();

                case DataType.Boolean:
                    return reader.ReadByte() != 0;

                case DataType.Guid:
                    return reader.ReadGuid();

                case DataType.UtfString:
                    return reader.ReadUtfString();

                case DataType.Binary:
                    return reader.ReadBinary();

                case DataType.Array:
                    return new JArray(reader
                        .ReadArray(r => ReadParameterValue(r, parameterMetadata.Children[0]))
                        .Cast<object>()
                        .ToArray());

                case DataType.Object:
                    return new JObject(parameterMetadata.Children
                        .Select(p => new JProperty(p.Name, ReadParameterValue(reader, p)))
                        .Cast<object>()
                        .ToArray());

                default:
                    throw new NotSupportedException(parameterMetadata.DataType + " is not supported for parameters");
            }
        }
 private static NotificationMetadata ReadNotificationInfo(BinaryReader reader)
 {
     return new NotificationMetadata()
     {
         Intent = reader.ReadUInt16(),
         Name = reader.ReadUtfString(),
         Parameters = ReadParameterList(reader)
     };
 }
 private static EquipmentInfo ReadEquipmentInfo(BinaryReader reader)
 {
     return new EquipmentInfo()
     {
         Name = reader.ReadUtfString(),
         Code = reader.ReadUtfString(),
         TypeName = reader.ReadUtfString()
     };
 }
        private void NotifyCommandResult(byte[] data)
        {
            int commandId;
            string status;
            string result;

            using (var stream = new MemoryStream(data))
            using (var reader = new BinaryReader(stream))
            {
                commandId = reader.ReadInt32();
                status = reader.ReadUtfString();
                result = reader.ReadUtfString();
            }

            NotifyCommandResult(commandId, status, result);
        }
        private void RegisterDevice2(byte[] data)
        {
            JObject jsonData;

            using (var stream = new MemoryStream(data))
            using (var reader = new BinaryReader(stream))
                jsonData = JObject.Parse(reader.ReadUtfString());

            var registrationInfo = new DeviceRegistrationInfo();
            registrationInfo.Id = (Guid) jsonData["id"];
            registrationInfo.Key = (string) jsonData["key"];
            registrationInfo.Name = (string) jsonData["name"];

            var deviceClassJson = (JObject) jsonData["deviceClass"];
            registrationInfo.ClassName = (string) deviceClassJson["name"];
            registrationInfo.ClassVersion = (string) deviceClassJson["version"];

            var equipmentJson = (JArray) jsonData["equipment"];
            if (equipmentJson == null || equipmentJson.Count == 0)
            {
                registrationInfo.Equipment = new EquipmentInfo[0];
            }
            else
            {
                registrationInfo.Equipment = equipmentJson
                    .Select(e => new EquipmentInfo()
                    {
                        Code = (string) e["code"],
                        Name = (string) e["name"],
                        TypeName = (string) e["type"]
                    })
                    .ToArray();
            }

            var commandsJson = (JArray) jsonData["commands"];
            if (commandsJson == null || commandsJson.Count == 0)
            {
                registrationInfo.Commands = new CommandMetadata[0];
            }
            else
            {
                registrationInfo.Commands = commandsJson
                    .Select(c => new CommandMetadata()
                    {
                        Intent = (ushort) c["intent"],
                        Name = (string) c["name"],
                        Parameters = ParseParameterMetadata(null, c["params"])
                    })
                    .ToArray();
            }

            var notificationsJson = (JArray)jsonData["notifications"];
            if (notificationsJson == null || notificationsJson.Count == 0)
            {
                registrationInfo.Notifications = new NotificationMetadata[0];
            }
            else
            {
                registrationInfo.Notifications = notificationsJson
                    .Select(c => new NotificationMetadata()
                    {
                        Intent = (ushort) c["intent"],
                        Name = (string) c["name"],
                        Parameters = ParseParameterMetadata(null, c["params"])
                    })
                    .ToArray();
            }

            RegisterDeviceCore(registrationInfo);
        }
        private void RegisterDevice(byte[] data)
        {
            var registrationInfo = new DeviceRegistrationInfo();

            using (var stream = new MemoryStream(data))
            using (var reader = new BinaryReader(stream))
            {
                registrationInfo.Id = reader.ReadGuid();
                registrationInfo.Key = reader.ReadUtfString();
                registrationInfo.Name = reader.ReadUtfString();
                registrationInfo.ClassName = reader.ReadUtfString();
                registrationInfo.ClassVersion = reader.ReadUtfString();
                registrationInfo.Equipment = reader.ReadArray(ReadEquipmentInfo);
                registrationInfo.Notifications = reader.ReadArray(ReadNotificationInfo);
                registrationInfo.Commands = reader.ReadArray(ReadCommandInfo);
            }

            RegisterDeviceCore(registrationInfo);
        }