public LoRaMessageWrapper(LoRaPayload payload, LoRaMessageType type, byte[] physicalToken, string datr, uint rfch, double freq, long tmst) { LoRaPayloadMessage = payload; PktFwdPayload = new DownlinkPktFwdMessage(Convert.ToBase64String(LoRaPayloadMessage.GetByteMessage()), datr, rfch, freq, tmst); var jsonMsg = JsonConvert.SerializeObject(PktFwdPayload); Logger.Log(ConversionHelper.ByteArrayToString(payload.GetLoRaMessage().DevEUI.ToArray()), $"{((MType)(payload.Mhdr.Span[0])).ToString()} {jsonMsg}", Logger.LoggingLevel.Full); var messageBytes = Encoding.Default.GetBytes(jsonMsg); PhysicalPayload = new PhysicalPayload(physicalToken, PhysicalIdentifier.PULL_RESP, messageBytes); }
/// <summary> /// Case of Downlink message. TODO refactor this /// </summary> /// <param name="input"></param> public LoRaMetada(LoRaGenericPayload payloadMessage, LoRaMessageType messageType) { if (messageType == LoRaMessageType.JoinAccept) { rawB64data = Convert.ToBase64String(((LoRaPayloadJoinAccept)payloadMessage).ToMessage()); } else if (messageType == LoRaMessageType.UnconfirmedDataDown || messageType == LoRaMessageType.ConfirmedDataDown) { rawB64data = Convert.ToBase64String(((LoRaPayloadStandardData)payloadMessage).ToMessage()); } }
/// <summary> /// This contructor is used in case of downlink message /// </summary> /// <param name="inputMessage"></param> /// <param name="type"> /// 0 = Join Request /// 1 = Join Accept /// 2 = Unconfirmed Data up /// 3 = Unconfirmed Data down /// 4 = Confirmed Data up /// 5 = Confirmed Data down /// 6 = Rejoin Request</param> public LoRaMessage(LoRaGenericPayload payload, LoRaMessageType type, byte[] physicalToken) { //construct a Join Accept Message if (type == LoRaMessageType.JoinAccept) { payloadMessage = (LoRaPayloadJoinAccept)payload; loraMetadata = new LoRaMetada(payloadMessage, type); physicalPayload = new PhysicalPayload(physicalToken, 0x03, Encoding.Default.GetBytes(loraMetadata.rawB64data)); physicalPayload.message = ((LoRaPayloadJoinAccept)payload).getFinalMessage(physicalToken); } else if (type == LoRaMessageType.UnconfirmedDataDown) { throw new NotImplementedException(); } else if (type == LoRaMessageType.ConfirmedDataDown) { throw new NotImplementedException(); } }
/// <summary> /// This contructor is used in case of downlink message /// </summary> /// <param name="inputMessage"></param> /// <param name="type"> /// 0 = Join Request /// 1 = Join Accept /// 2 = Unconfirmed Data up /// 3 = Unconfirmed Data down /// 4 = Confirmed Data up /// 5 = Confirmed Data down /// 6 = Rejoin Request</param> public LoRaMessageWrapper(LoRaPayload payload, LoRaMessageType type, byte[] physicalToken) { LoRaPayloadMessage = payload; // construct a Join Accept Message if (type == LoRaMessageType.JoinAccept) { var downlinkmsg = new DownlinkPktFwdMessage(Convert.ToBase64String(payload.GetByteMessage())); PktFwdPayload = downlinkmsg; var jsonMsg = JsonConvert.SerializeObject(downlinkmsg); var messageBytes = Encoding.Default.GetBytes(jsonMsg); PhysicalPayload = new PhysicalPayload(physicalToken, PhysicalIdentifier.PULL_RESP, messageBytes); } else if (type == LoRaMessageType.UnconfirmedDataDown) { throw new NotImplementedException(); } else if (type == LoRaMessageType.ConfirmedDataDown) { throw new NotImplementedException(); } }
public LoRaMessage(LoRaGenericPayload payload, LoRaMessageType type, byte[] physicalToken, string _datr, uint _rfch, double _freq, long _tmst) { //construct a Join Accept Message if (type == LoRaMessageType.JoinAccept) { payloadMessage = (LoRaPayloadJoinAccept)payload; loraMetadata = new LoRaMetada(payloadMessage, type); var downlinkmsg = new DownlinkPktFwdMessage(loraMetadata.rawB64data, _datr, _rfch, _freq, _tmst); var jsonMsg = JsonConvert.SerializeObject(downlinkmsg); Console.WriteLine(jsonMsg); var messageBytes = Encoding.Default.GetBytes(jsonMsg); physicalPayload = new PhysicalPayload(physicalToken, PhysicalIdentifier.PULL_RESP, messageBytes); } else if (type == LoRaMessageType.UnconfirmedDataDown) { payloadMessage = (LoRaPayloadStandardData)payload; loraMetadata = new LoRaMetada(payloadMessage, type); var downlinkmsg = new DownlinkPktFwdMessage(loraMetadata.rawB64data, _datr, _rfch, _freq, _tmst + 1000000); var jsonMsg = JsonConvert.SerializeObject(downlinkmsg); Console.WriteLine(jsonMsg); var messageBytes = Encoding.Default.GetBytes(jsonMsg); physicalPayload = new PhysicalPayload(physicalToken, PhysicalIdentifier.PULL_RESP, messageBytes); } else if (type == LoRaMessageType.ConfirmedDataDown) { payloadMessage = (LoRaPayloadStandardData)payload; loraMetadata = new LoRaMetada(payloadMessage, type); var downlinkmsg = new DownlinkPktFwdMessage(loraMetadata.rawB64data, _datr, _rfch, _freq, _tmst + 1000000); var jsonMsg = JsonConvert.SerializeObject(downlinkmsg); Console.WriteLine(jsonMsg); var messageBytes = Encoding.Default.GetBytes(jsonMsg); physicalPayload = new PhysicalPayload(physicalToken, PhysicalIdentifier.PULL_RESP, messageBytes); } }
/// <summary> /// This contructor is used in case of uplink message, hence we don't know the message type yet /// </summary> /// <param name="inputMessage"></param> public LoRaMessage(byte[] inputMessage) { //packet normally sent by the gateway as heartbeat. TODO find more elegant way to integrate. physicalPayload = new PhysicalPayload(inputMessage); if (physicalPayload.message != null) { loraMetadata = new LoRaMetada(physicalPayload.message); //set up the parts of the raw message //status message if (loraMetadata.rawB64data != null) { byte[] convertedInputMessage = Convert.FromBase64String(loraMetadata.rawB64data); var messageType = convertedInputMessage[0] >> 5; loRaMessageType = (LoRaMessageType)messageType; //Uplink Message if (messageType == (int)LoRaMessageType.UnconfirmedDataUp) { payloadMessage = new LoRaPayloadStandardData(convertedInputMessage); } else if (messageType == (int)LoRaMessageType.ConfirmedDataUp) { payloadMessage = new LoRaPayloadStandardData(convertedInputMessage); } else if (messageType == (int)LoRaMessageType.JoinRequest) { payloadMessage = new LoRaPayloadJoinRequest(convertedInputMessage); } isLoRaMessage = true; } else { isLoRaMessage = false; } } else { isLoRaMessage = false; } }
/// <summary> /// This contructor is used in case of downlink message /// </summary> /// <param name="inputMessage"></param> /// <param name="type"> /// 0 = Join Request /// 1 = Join Accept /// 2 = Unconfirmed Data up /// 3 = Unconfirmed Data down /// 4 = Confirmed Data up /// 5 = Confirmed Data down /// 6 = Rejoin Request</param> public LoRaMessage(LoRaGenericPayload payload, LoRaMessageType type, byte[] physicalToken) { //construct a Join Accept Message if (type == LoRaMessageType.JoinAccept) { payloadMessage = (LoRaPayloadJoinAccept)payload; loraMetadata = new LoRaMetada(payloadMessage, type); var downlinkmsg = new DownlinkPktFwdMessage(loraMetadata.rawB64data); var jsonMsg = JsonConvert.SerializeObject(downlinkmsg); var messageBytes = Encoding.Default.GetBytes(jsonMsg); physicalPayload = new PhysicalPayload(physicalToken, PhysicalIdentifier.PULL_RESP, messageBytes); } else if (type == LoRaMessageType.UnconfirmedDataDown) { throw new NotImplementedException(); } else if (type == LoRaMessageType.ConfirmedDataDown) { throw new NotImplementedException(); } }
/// <summary> /// Case of Downlink message. TODO refactor this /// </summary> /// <param name="input"></param> public LoRaMetada(LoRaGenericPayload payloadMessage, LoRaMessageType tmp) { rawB64data = Convert.ToBase64String(((LoRaPayloadJoinAccept)payloadMessage).ToMessage()); }
public void When_Creating_Rxpk_Recreating_Payload_Should_Match_Source_Values(LoRaMessageType loRaMessageType, string data) { var devAddrText = "00000060"; var appSKeyText = "00000060000000600000006000000060"; var nwkSKeyText = "00000060000000600000006000000060"; ushort fcnt = 12; byte[] devAddr = ConversionHelper.StringToByteArray(devAddrText); Array.Reverse(devAddr); byte[] fCtrl = new byte[] { 0x80 }; var fcntBytes = BitConverter.GetBytes(fcnt); var fopts = new List <MacCommand>(); byte[] fPort = new byte[] { 1 }; byte[] payload = Encoding.UTF8.GetBytes(data); Array.Reverse(payload); // 0 = uplink, 1 = downlink int direction = 0; var devicePayloadData = new LoRaPayloadData(loRaMessageType, devAddr, fCtrl, fcntBytes, fopts, fPort, payload, direction); Assert.Equal(12, devicePayloadData.GetFcnt()); Assert.Equal(0, devicePayloadData.Direction); Assert.Equal(1, devicePayloadData.GetFPort()); var datr = "SF10BW125"; var freq = 868.3; var uplinkMsg = devicePayloadData.SerializeUplink(appSKeyText, nwkSKeyText, datr, freq, 0); // Now try to recreate LoRaPayloadData from rxpk Assert.True(LoRaPayload.TryCreateLoRaPayload(uplinkMsg.Rxpk[0], out LoRaPayload parsedLoRaPayload)); Assert.Equal(loRaMessageType, parsedLoRaPayload.LoRaMessageType); Assert.IsType <LoRaPayloadData>(parsedLoRaPayload); var parsedLoRaPayloadData = (LoRaPayloadData)parsedLoRaPayload; Assert.Equal(12, parsedLoRaPayloadData.GetFcnt()); Assert.Equal(0, parsedLoRaPayloadData.Direction); Assert.Equal(1, parsedLoRaPayloadData.GetFPort()); // Ensure that mic check and getting payload back works Assert.True(parsedLoRaPayloadData.CheckMic(nwkSKeyText)); // does not matter where the check mic happen, should always work! var parsedPayloadBytes = parsedLoRaPayloadData.GetDecryptedPayload(appSKeyText); Assert.Equal(data, Encoding.UTF8.GetString(parsedPayloadBytes)); // checking mic and getting payload should not change the payload properties Assert.Equal(12, parsedLoRaPayloadData.GetFcnt()); Assert.Equal(0, parsedLoRaPayloadData.Direction); Assert.Equal(1, parsedLoRaPayloadData.GetFPort()); // checking mic should not break getting the payload Assert.True(parsedLoRaPayloadData.CheckMic(nwkSKeyText)); // does not matter where the check mic happen, should always work! var parsedPayloadBytes2 = parsedLoRaPayloadData.GetDecryptedPayload(appSKeyText); Assert.Equal(data, Encoding.UTF8.GetString(parsedPayloadBytes2)); // checking mic and getting payload should not change the payload properties Assert.Equal(12, parsedLoRaPayloadData.GetFcnt()); Assert.Equal(0, parsedLoRaPayloadData.Direction); Assert.Equal(1, parsedLoRaPayloadData.GetFPort()); }
/// <summary> /// This contructor is used in case of uplink message, hence we don't know the message type yet /// </summary> /// <param name="inputMessage"></param> public LoRaMessageWrapper(byte[] inputMessage, bool server = false, string AppKey = "") { // packet normally sent by the gateway as heartbeat. TODO find more elegant way to integrate. PhysicalPayload = new PhysicalPayload(inputMessage, server); if (PhysicalPayload.message != null) { var payload = Encoding.Default.GetString(PhysicalPayload.message); // todo ronnie implement a better logging by message type if (!payload.StartsWith("{\"stat")) { Logger.Log($"Physical dataUp {payload}", Logger.LoggingLevel.Full); // Deserialized for uplink messages var payloadObject = JsonConvert.DeserializeObject <UplinkPktFwdMessage>(payload); PktFwdPayload = payloadObject; // set up the parts of the raw message // status message if (PktFwdPayload != null) { // if there is no packet, then it maybe a downlink message if (PktFwdPayload.GetPktFwdMessage().Rxpks.Count > 0) { if (PktFwdPayload.GetPktFwdMessage().Rxpks[0].data != null) { byte[] convertedInputMessage = Convert.FromBase64String(PktFwdPayload.GetPktFwdMessage().Rxpks[0].data); var messageType = convertedInputMessage[0] >> 5; LoRaMessageType = (LoRaMessageType)messageType; // Uplink Message if (messageType == (int)LoRaMessageType.UnconfirmedDataUp) { LoRaPayloadMessage = new LoRaPayloadData(convertedInputMessage); } else if (messageType == (int)LoRaMessageType.ConfirmedDataUp) { LoRaPayloadMessage = new LoRaPayloadData(convertedInputMessage); } else if (messageType == (int)LoRaMessageType.JoinRequest) { LoRaPayloadMessage = new LoRaPayloadJoinRequest(convertedInputMessage); } IsLoRaMessage = true; } } else { // deselrialize for a downlink message var payloadDownObject = JsonConvert.DeserializeObject <DownlinkPktFwdMessage>(payload); if (payloadDownObject != null) { if (payloadDownObject.txpk != null) { // if we have data, it is a downlink message if (payloadDownObject.txpk.data != null) { byte[] convertedInputMessage = Convert.FromBase64String(payloadDownObject.txpk.data); var messageType = convertedInputMessage[0] >> 5; LoRaMessageType = (LoRaMessageType)messageType; if (messageType == (int)LoRaMessageType.JoinAccept) { LoRaPayloadMessage = new LoRaPayloadJoinAccept(convertedInputMessage, AppKey); } IsLoRaMessage = true; } } else { Logger.Log("Error: " + payload, Logger.LoggingLevel.Full); } } } } } else { Logger.Log($"Statistic: {payload}", Logger.LoggingLevel.Full); IsLoRaMessage = false; } } else { IsLoRaMessage = false; } }