Beispiel #1
0
        async Task RunUdpListener()
        {
            IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, PORT);

            udpClient = new UdpClient(endPoint);

            Console.WriteLine($"LoRaWAN server started on port {PORT}");


            while (true)
            {
                UdpReceiveResult receivedResults = await udpClient.ReceiveAsync();

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


                //Todo check that is an ack only, we could do a better check in a future verstion
                if (receivedResults.Buffer.Length == 12)
                {
                    remoteLoRaAggregatorIp   = receivedResults.RemoteEndPoint.Address;
                    remoteLoRaAggregatorPort = receivedResults.RemoteEndPoint.Port;
                }



                try
                {
                    MessageProcessor messageProcessor = new MessageProcessor();
                    _ = messageProcessor.processMessage(receivedResults.Buffer);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error processing the message {ex.Message}");
                }
            }
        }
Beispiel #2
0
        async Task RunUdpListener()
        {
            IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, PORT);

            udpClient = new UdpClient(endPoint);

            Logger.Log($"LoRaWAN server started on port {PORT}", Logger.LoggingLevel.Always);


            while (true)
            {
                UdpReceiveResult receivedResults = await udpClient.ReceiveAsync();

                //Logger.Log($"UDP message received ({receivedResults.Buffer[3]}) from port: {receivedResults.RemoteEndPoint.Port} and IP: {receivedResults.RemoteEndPoint.Address.ToString()}",LoggingLevel.Always);


                switch (PhysicalPayload.GetIdentifierFromPayload(receivedResults.Buffer))
                {
                //In this case we have a keep-alive PULL_DATA packet we don't need to start the engine and can return immediately a response to the challenge
                case PhysicalIdentifier.PULL_DATA:
                    if (pullAckRemoteLoRaAggregatorPort == 0)
                    {
                        pullAckRemoteLoRaAggregatorPort = receivedResults.RemoteEndPoint.Port;
                    }
                    SendAcknowledgementMessage(receivedResults, (int)PhysicalIdentifier.PULL_ACK, receivedResults.RemoteEndPoint);
                    break;

                //This is a PUSH_DATA (upstream message).
                case PhysicalIdentifier.PUSH_DATA:
                    SendAcknowledgementMessage(receivedResults, (int)PhysicalIdentifier.PUSH_ACK, receivedResults.RemoteEndPoint);

                    // Message processing runs in the background
                    MessageProcessor messageProcessor = new MessageProcessor(this.configuration, this.loraDeviceInfoManager);

                    // do not wait for it to return
                    _ = Task.Run(async() => {
                        try
                        {
                            var resultMessage = await messageProcessor.ProcessMessageAsync(receivedResults.Buffer);
                            if (resultMessage != null && resultMessage.Length > 0)
                            {
                                var port = pullAckRemoteLoRaAggregatorPort;
                                if (port <= 0)
                                {
                                    port = receivedResults.RemoteEndPoint.Port;
                                }
                                await this.UdpSendMessage(resultMessage, receivedResults.RemoteEndPoint.Address.ToString(), port);
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.Log($"Error processing the message {ex.Message}, {ex.StackTrace}", Logger.LoggingLevel.Error);
                        }
                    });

                    break;

                //This is a ack to a transmission we did previously
                case PhysicalIdentifier.TX_ACK:
                    if (receivedResults.Buffer.Length == 12)
                    {
                        Logger.Log(String.Format("Packet with id {0} successfully transmitted by the aggregator",
                                                 ConversionHelper.ByteArrayToString(receivedResults.Buffer.RangeSubset(1, 2)))
                                   , LoggingLevel.Full);
                    }
                    else
                    {
                        Logger.Log(String.Format("Packet with id {0} had a problem to be transmitted over the air :{1}",
                                                 receivedResults.Buffer.Length > 2 ? ConversionHelper.ByteArrayToString(receivedResults.Buffer.RangeSubset(1, 2)) : "",
                                                 receivedResults.Buffer.Length > 12 ? Encoding.UTF8.GetString(receivedResults.Buffer.RangeSubset(12, receivedResults.Buffer.Length - 12)) : "")
                                   , LoggingLevel.Error);
                    }
                    break;

                default:
                    Logger.Log("Unknown packet type or length being received", LoggingLevel.Error);
                    break;
                }
#pragma warning restore CS4014
            }
        }