// PublishUplink publishes an uplink message to the MQTT broker func (c *DefaultClient) PublishUplink(dataUp types.UplinkMessage) Token { topic := DeviceTopic{dataUp.AppID, dataUp.DevID, DeviceUplink, ""} dataUp.AppID = "" dataUp.DevID = "" msg, err := json.Marshal(dataUp) if err != nil { return &simpleToken{fmt.Errorf("Unable to marshal the message payload")} } return c.publish(topic.String(), msg) }
// ConvertFieldsUp converts the payload to fields using payload functions func (h *handler) ConvertFieldsUp(ctx log.Interface, ttnUp *pb_broker.DeduplicatedUplinkMessage, appUp *types.UplinkMessage) error { // Find Application app, err := h.applications.Get(ttnUp.AppId) if err != nil { return nil // Do not process if application not found } functions := &UplinkFunctions{ Decoder: app.Decoder, Converter: app.Converter, Validator: app.Validator, Logger: functions.Ignore, } fields, valid, err := functions.Process(appUp.PayloadRaw, appUp.FPort) if err != nil { return nil // Do not set fields if processing failed } if !valid { return errors.NewErrInvalidArgument("Payload", "payload validator function returned false") } appUp.PayloadFields = fields return nil }
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 }