Beispiel #1
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JObject item             = JObject.Load(reader);
            var     cidPropertyValue = item["cid"].Value <string>();

            if (string.IsNullOrEmpty(cidPropertyValue))
            {
                throw new JsonReaderException("Undefined mac command identifier");
            }

            if (Enum.TryParse <CidEnum>(cidPropertyValue, true, out var macCommandType))
            {
                switch (macCommandType)
                {
                case CidEnum.DevStatusCmd:
                {
                    var cmd = new DevStatusRequest();
                    serializer.Populate(item.CreateReader(), cmd);
                    return(cmd);
                }

                case CidEnum.DutyCycleCmd:
                {
                    var cmd = new DutyCycleRequest();
                    serializer.Populate(item.CreateReader(), cmd);
                    return(cmd);
                }

                case CidEnum.NewChannelCmd:
                {
                    var cmd = new NewChannelRequest();
                    serializer.Populate(item.CreateReader(), cmd);
                    return(cmd);
                }

                case CidEnum.RXParamCmd:
                {
                    var cmd = new RXParamSetupRequest();
                    serializer.Populate(item.CreateReader(), cmd);
                    return(cmd);
                }

                case CidEnum.RXTimingCmd:
                {
                    var cmd = new RXTimingSetupRequest();
                    serializer.Populate(item.CreateReader(), cmd);
                    return(cmd);
                }
                }
            }

            throw new JsonReaderException($"Unkown MAC command identifier: {cidPropertyValue}");
        }
        /// <summary>
        /// Create a List of Mac commands from server based on a sequence of bytes.
        /// </summary>
        public static List <MacCommand> CreateServerMacCommandFromBytes(string deviceId, ReadOnlyMemory <byte> input)
        {
            int pointer     = 0;
            var macCommands = new List <MacCommand>(3);

            while (pointer < input.Length)
            {
                try
                {
                    CidEnum cid = (CidEnum)input.Span[pointer];
                    switch (cid)
                    {
                    case CidEnum.LinkCheckCmd:
                        var linkCheck = new LinkCheckAnswer(input.Span.Slice(pointer));
                        pointer += linkCheck.Length;
                        macCommands.Add(linkCheck);
                        break;

                    case CidEnum.DevStatusCmd:
                        var devStatusRequest = new DevStatusRequest();
                        pointer += devStatusRequest.Length;
                        macCommands.Add(devStatusRequest);
                        break;

                    default:
                        Logger.Log(deviceId, $"a Mac command transmitted from the server, value ${input.Span[pointer]} was not from a supported type. Aborting Mac Command processing", LogLevel.Error);
                        return(null);
                    }

                    MacCommand addedMacCommand = macCommands[macCommands.Count - 1];
                    Logger.Log(deviceId, $"{addedMacCommand.Cid} mac command detected in upstream payload: {addedMacCommand.ToString()}", LogLevel.Debug);
                }
                catch (MacCommandException ex)
                {
                    Logger.Log(deviceId, ex.ToString(), LogLevel.Error);
                }
            }

            return(macCommands);
        }
        /// <summary>
        /// Create a List of Mac commands from client based on a sequence of bytes.
        /// </summary>
        public static List <MacCommand> CreateMacCommandFromBytes(string deviceId, ReadOnlyMemory <byte> input)
        {
            int pointer     = 0;
            var macCommands = new List <MacCommand>(3);

            while (pointer < input.Length)
            {
                try
                {
                    CidEnum cid = (CidEnum)input.Span[pointer];
                    switch (cid)
                    {
                    case CidEnum.LinkCheckCmd:
                        var linkCheck = new LinkCheckRequest();
                        pointer += linkCheck.Length;
                        macCommands.Add(linkCheck);
                        break;

                    case CidEnum.LinkADRCmd:
                        var linkAdrAnswer = new LinkADRAnswer(input.Span.Slice(pointer));
                        pointer += linkAdrAnswer.Length;
                        macCommands.Add(linkAdrAnswer);
                        break;

                    case CidEnum.DutyCycleCmd:
                        var dutyCycle = new DutyCycleAnswer();
                        pointer += dutyCycle.Length;
                        macCommands.Add(dutyCycle);
                        break;

                    case CidEnum.RXParamCmd:
                        var rxParamSetup = new RXParamSetupAnswer(input.Span.Slice(pointer));
                        pointer += rxParamSetup.Length;
                        macCommands.Add(rxParamSetup);
                        break;

                    case CidEnum.DevStatusCmd:
                        // Added this case to enable unit testing
                        if (input.Length == 1)
                        {
                            var devStatusRequest = new DevStatusRequest();
                            pointer += devStatusRequest.Length;
                            macCommands.Add(devStatusRequest);
                        }
                        else
                        {
                            DevStatusAnswer devStatus = new DevStatusAnswer(input.Span.Slice(pointer));
                            pointer += devStatus.Length;
                            macCommands.Add(devStatus);
                        }

                        break;

                    case CidEnum.NewChannelCmd:
                        NewChannelAnswer newChannel = new NewChannelAnswer(input.Span.Slice(pointer));
                        pointer += newChannel.Length;
                        macCommands.Add(newChannel);
                        break;

                    case CidEnum.RXTimingCmd:
                        RXTimingSetupAnswer rxTimingSetup = new RXTimingSetupAnswer();
                        pointer += rxTimingSetup.Length;
                        macCommands.Add(rxTimingSetup);
                        break;

                    default:
                        Logger.Log(deviceId, $"a transmitted Mac Command value ${input.Span[pointer]} was not from a supported type. Aborting Mac Command processing", LogLevel.Error);
                        return(null);
                    }

                    MacCommand addedMacCommand = macCommands[macCommands.Count - 1];
                    Logger.Log(deviceId, $"{addedMacCommand.Cid} mac command detected in upstream payload: {addedMacCommand.ToString()}", LogLevel.Debug);
                }
                catch (MacCommandException ex)
                {
                    Logger.Log(deviceId, ex.ToString(), LogLevel.Error);
                }
            }

            return(macCommands);
        }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (serializer is null)
            {
                throw new ArgumentNullException(nameof(serializer));
            }

            var item             = JObject.Load(reader);
            var cidPropertyValue = item["cid"].Value <string>();

            if (string.IsNullOrEmpty(cidPropertyValue))
            {
                throw new JsonReaderException("Undefined mac command identifier");
            }

            if (Enum.TryParse <Cid>(cidPropertyValue, true, out var macCommandType))
            {
                switch (macCommandType)
                {
                case Cid.DevStatusCmd:
                {
                    var cmd = new DevStatusRequest();
                    serializer.Populate(item.CreateReader(), cmd);
                    return(cmd);
                }

                case Cid.DutyCycleCmd:
                {
                    var cmd = new DutyCycleRequest();
                    serializer.Populate(item.CreateReader(), cmd);
                    return(cmd);
                }

                case Cid.NewChannelCmd:
                {
                    var cmd = new NewChannelRequest();
                    serializer.Populate(item.CreateReader(), cmd);
                    return(cmd);
                }

                case Cid.RXParamCmd:
                {
                    var cmd = new RXParamSetupRequest();
                    serializer.Populate(item.CreateReader(), cmd);
                    return(cmd);
                }

                case Cid.RXTimingCmd:
                {
                    var cmd = new RXTimingSetupRequest();
                    serializer.Populate(item.CreateReader(), cmd);
                    return(cmd);
                }

                case Cid.Zero:
                case Cid.One:
                case Cid.LinkCheckCmd:
                case Cid.LinkADRCmd:
                {
                    GetValue("dataRate", out var datarate);
                    GetValue("txPower", out var txpower);
                    GetValue("chMask", out var chmask);
                    GetValue("chMaskCntl", out var chmaskcntl);
                    GetValue("nbRep", out var nbrep);

                    void GetValue(string propertyName, out JToken value)
                    {
                        if (!item.TryGetValue(propertyName, StringComparison.OrdinalIgnoreCase, out value))
                        {
                            throw new JsonReaderException($"Property '{propertyName}' is missing");
                        }
                    }

                    var cmd = new LinkADRRequest((ushort)datarate, (ushort)txpower, (ushort)chmask, (byte)chmaskcntl, (byte)nbrep);
                    serializer.Populate(item.CreateReader(), cmd);
                    return(cmd);
                }

                case Cid.TxParamSetupCmd:
                default:
                    throw new JsonReaderException($"Unhandled command identifier: {macCommandType}");
                }
            }

            throw new JsonReaderException($"Unknown MAC command identifier: {cidPropertyValue}");
        }