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}"); } } }
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 } }