Esempio n. 1
0
        // Performs join
        public async Task <bool> JoinAsync(SimulatedPacketForwarder packetForwarder, int timeoutInMs = 30 * 1000)
        {
            if (this.IsJoined)
            {
                return(true);
            }

            var token = await RandomTokenGenerator.GetTokenAsync();

            this.LastPayload = new PhysicalPayload(token, PhysicalIdentifier.PUSH_DATA, null);
            var header = this.LastPayload.GetSyncHeader(packetForwarder.MacAddress);

            var joinRequest   = this.CreateJoinRequest();
            var joinCompleted = new SemaphoreSlim(0);

            var joinRequestUplinkMessage = joinRequest.SerializeUplink(this.AppKey);

            packetForwarder.SubscribeOnce((response) =>
            {
                // handle join
                var txpk = Txpk.CreateTxpk(response, this.LoRaDevice.AppKey);
                byte[] convertedInputMessage = Convert.FromBase64String(txpk.Data);

                var joinAccept = new LoRaPayloadJoinAccept(convertedInputMessage, this.AppKey);

                var result = this.HandleJoinAccept(joinAccept); // may need to return bool and only release if true.
                joinCompleted.Release();

                return(result);
            });

            await packetForwarder.SendAsync(header, joinRequest.GetByteMessage());

            TestLogger.Log($"[{this.LoRaDevice.DeviceID}] Join request: {BitConverter.ToString(header).Replace("-", string.Empty)}");

#if DEBUG
            if (System.Diagnostics.Debugger.IsAttached)
            {
                timeoutInMs = 60 * 1000;
            }
#endif

            return(await joinCompleted.WaitAsync(timeoutInMs));
        }
        async Task RunUdpListener()
        {
            while (true)
            {
                UdpReceiveResult receivedResults = await udpClient.ReceiveAsync();

                // Logger.LogAlways($"UDP message received ({receivedResults.Buffer.Length} bytes) from port: {receivedResults.RemoteEndPoint.Port}");

                // If 4, it may mean we received a confirmation
                if (receivedResults.Buffer.Length >= 4)
                {
                    // get the token
                    byte[] token = new byte[2];
                    token[0] = receivedResults.Buffer[1];
                    token[1] = receivedResults.Buffer[2];

                    // identifier
                    var identifier = (PhysicalIdentifier)receivedResults.Buffer[3];

                    // Find the device
                    try
                    {
                        foreach (var dev in this.listDevices)
                        {
                            if (dev.LastPayload != null)
                            {
                                if ((dev.LastPayload.Token[0] == token[0]) && (dev.LastPayload.Token[1] == token[1]))
                                {
                                    string device = dev.LoRaDevice.DevEUI;

                                    // check last operation and answer
                                    // Is is a simple push data?
                                    if (identifier == PhysicalIdentifier.PUSH_ACK)
                                    {
                                        if (dev.LastPayload.Identifier == PhysicalIdentifier.PUSH_DATA)
                                        {
                                            Logger.Log(device, $"PUSH_DATA confirmation receiveced from NetworkServer", LogLevel.Information);
                                        }
                                        else
                                        {
                                            Logger.Log(device, $"PUSH_ACK confirmation receiveced from ", LogLevel.Information);
                                        }
                                    }
                                    else if (identifier == PhysicalIdentifier.PULL_RESP)
                                    {
                                        // we asked something, we get an answer
                                        var txpk = Txpk.CreateTxpk(receivedResults.Buffer, dev.LoRaDevice.AppKey);
                                        LoRaPayload.TryCreateLoRaPayloadForSimulator(txpk, dev.LoRaDevice.AppKey, out LoRaPayload loraMessage);

                                        // Check if the device is not joined, then it is maybe the answer
                                        if ((loraMessage.LoRaMessageType == LoRaMessageType.JoinAccept) && (dev.LoRaDevice.DevAddr == string.Empty))
                                        {
                                            Logger.Log(device, $"Received join accept", LogLevel.Information);

                                            var payload = (LoRaPayloadJoinAccept)loraMessage;

                                            // TODO Need to check if the time is not passed

                                            // Calculate the keys
                                            var netid = payload.NetID.ToArray();
                                            Array.Reverse(netid);
                                            var appNonce = payload.AppNonce.ToArray();
                                            Array.Reverse(appNonce);
                                            var devNonce = dev.LoRaDevice.GetDevNonce();
                                            Array.Reverse(devNonce);
                                            var appSKey = payload.CalculateKey(LoRaPayloadKeyType.AppSKey, appNonce, netid, devNonce, dev.LoRaDevice.GetAppKey());
                                            dev.LoRaDevice.AppSKey = BitConverter.ToString(appSKey).Replace("-", "");
                                            var nwkSKey = payload.CalculateKey(LoRaPayloadKeyType.NwkSkey, appNonce, netid, devNonce, dev.LoRaDevice.GetAppKey());
                                            dev.LoRaDevice.NwkSKey  = BitConverter.ToString(nwkSKey).Replace("-", "");
                                            dev.LoRaDevice.NetId    = BitConverter.ToString(netid).Replace("-", "");
                                            dev.LoRaDevice.AppNonce = BitConverter.ToString(appNonce).Replace("-", "");
                                            var devAdd = payload.DevAddr;

                                            // Array.Reverse(devAdd);
                                            dev.LoRaDevice.DevAddr = BitConverter.ToString(devAdd.ToArray()).Replace("-", "");
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.Log($"Something when wrong: {ex.Message}", LogLevel.Error);
                    }

                    // if (receivedResults.Buffer[3] == (byte)PhysicalIdentifier.PUSH_ACK)
                    // {
                    //    //Bingo
                    //    Logger.LogAlways($"Confirmation receiveced");
                    // }
                }

                // try
                // {
                //    // TODO: process the message not really implemented yet
                //    MessageProcessor messageProcessor = new MessageProcessor();
                //    _ = messageProcessor.processMessage(receivedResults.Buffer);
                // }
                // catch (Exception ex)
                // {
                //    Logger.Log($"Error processing the message {ex.Message}", LogLevel.Error);
                // }
            }
        }