func (h *handler) ConvertFromLoRaWAN(ctx log.Interface, ttnUp *pb_broker.DeduplicatedUplinkMessage, appUp *types.UplinkMessage) error { // Find Device dev, err := h.devices.Get(ttnUp.AppId, ttnUp.DevId) if err != nil { return err } // Check for LoRaWAN if lorawan := ttnUp.ProtocolMetadata.GetLorawan(); lorawan == nil { return errors.NewErrInvalidArgument("Activation", "does not contain LoRaWAN metadata") } // LoRaWAN: Unmarshal Uplink var phyPayload lorawan.PHYPayload err = phyPayload.UnmarshalBinary(ttnUp.Payload) if err != nil { return err } macPayload, ok := phyPayload.MACPayload.(*lorawan.MACPayload) if !ok { return errors.NewErrInvalidArgument("Uplink", "does not contain a MAC payload") } macPayload.FHDR.FCnt = ttnUp.ProtocolMetadata.GetLorawan().FCnt appUp.FCnt = macPayload.FHDR.FCnt ctx = ctx.WithField("FCnt", appUp.FCnt) // LoRaWAN: Validate MIC ok, err = phyPayload.ValidateMIC(lorawan.AES128Key(dev.NwkSKey)) if err != nil { return err } if !ok { return errors.NewErrNotFound("device that validates MIC") } // LoRaWAN: Decrypt if macPayload.FPort != nil && *macPayload.FPort != 0 && len(macPayload.FRMPayload) == 1 { appUp.FPort = *macPayload.FPort ctx = ctx.WithField("FCnt", appUp.FPort) if err := phyPayload.DecryptFRMPayload(lorawan.AES128Key(dev.AppSKey)); err != nil { return errors.NewErrInternal("Could not decrypt payload") } if len(macPayload.FRMPayload) == 1 { payload, ok := macPayload.FRMPayload[0].(*lorawan.DataPayload) if !ok { return errors.NewErrInvalidArgument("Uplink FRMPayload", "must be of type *lorawan.DataPayload") } appUp.PayloadRaw = payload.Bytes } } // LoRaWAN: Publish ACKs as events if macPayload.FHDR.FCtrl.ACK { h.mqttEvent <- &types.DeviceEvent{ AppID: appUp.AppID, DevID: appUp.DevID, Event: types.DownlinkAckEvent, } } return nil }