// PublishDownlink publishes a downlink message func (c *DefaultClient) PublishDownlink(dataDown types.DownlinkMessage) Token { topic := DeviceTopic{dataDown.AppID, dataDown.DevID, DeviceDownlink, ""} dataDown.AppID = "" dataDown.DevID = "" msg, err := json.Marshal(dataDown) if err != nil { return &simpleToken{fmt.Errorf("Unable to marshal the message payload")} } return c.publish(topic.String(), msg) }
// ConvertFieldsDown converts the fields into a payload func (h *handler) ConvertFieldsDown(ctx log.Interface, appDown *types.DownlinkMessage, ttnDown *pb_broker.DownlinkMessage) error { if appDown.PayloadFields == nil || len(appDown.PayloadFields) == 0 { return nil } if appDown.PayloadRaw != nil { return errors.NewErrInvalidArgument("Downlink", "Both Fields and Payload provided") } app, err := h.applications.Get(appDown.AppID) if err != nil { return nil } functions := &DownlinkFunctions{ Encoder: app.Encoder, Logger: functions.Ignore, } message, _, err := functions.Process(appDown.PayloadFields, appDown.FPort) if err != nil { return err } appDown.PayloadRaw = message return nil }
func (h *handler) EnqueueDownlink(appDownlink *types.DownlinkMessage) (err error) { appID, devID := appDownlink.AppID, appDownlink.DevID ctx := h.Ctx.WithFields(log.Fields{ "AppID": appID, "DevID": devID, }) start := time.Now() defer func() { if err != nil { ctx.WithError(err).Warn("Could not enqueue downlink") } else { ctx.WithField("Duration", time.Now().Sub(start)).Debug("Enqueued downlink") } }() dev, err := h.devices.Get(appID, devID) if err != nil { return err } // Clear redundant fields appDownlink.AppID = "" appDownlink.DevID = "" dev.StartUpdate() dev.NextDownlink = appDownlink err = h.devices.Set(dev) if err != nil { return err } h.mqttEvent <- &types.DeviceEvent{ AppID: appID, DevID: devID, Event: types.DownlinkScheduledEvent, } return nil }
func (h *handler) HandleUplink(uplink *pb_broker.DeduplicatedUplinkMessage) (err error) { appID, devID := uplink.AppId, uplink.DevId ctx := h.Ctx.WithFields(log.Fields{ "AppID": appID, "DevID": devID, }) start := time.Now() defer func() { if err != nil { h.mqttEvent <- &types.DeviceEvent{ AppID: appID, DevID: devID, Event: types.UplinkErrorEvent, Data: types.ErrorEventData{Error: err.Error()}, } ctx.WithError(err).Warn("Could not handle uplink") } else { ctx.WithField("Duration", time.Now().Sub(start)).Info("Handled uplink") } }() h.status.uplink.Mark(1) // Build AppUplink appUplink := &types.UplinkMessage{ AppID: appID, DevID: devID, } // Get Uplink Processors processors := []UplinkProcessor{ h.ConvertFromLoRaWAN, h.ConvertMetadata, h.ConvertFieldsUp, } ctx.WithField("NumProcessors", len(processors)).Debug("Running Uplink Processors") // Run Uplink Processors for _, processor := range processors { err = processor(ctx, uplink, appUplink) if err == ErrNotNeeded { err = nil return nil } else if err != nil { return err } } // Publish Uplink h.mqttUp <- appUplink if h.amqpEnabled { h.amqpUp <- appUplink } <-time.After(ResponseDeadline) // Find Device and scheduled downlink var appDownlink types.DownlinkMessage dev, err := h.devices.Get(uplink.AppId, uplink.DevId) if err != nil { return err } if dev.NextDownlink != nil { appDownlink = *dev.NextDownlink } if uplink.ResponseTemplate == nil { ctx.Debug("No Downlink Available") return nil } // Prepare Downlink downlink := uplink.ResponseTemplate appDownlink.AppID = uplink.AppId appDownlink.DevID = uplink.DevId // Handle Downlink err = h.HandleDownlink(&appDownlink, downlink) if err != nil { return err } // Clear Downlink dev.StartUpdate() dev.NextDownlink = nil err = h.devices.Set(dev) if err != nil { return err } return nil }
jsonflag, err := cmd.Flags().GetBool("json") if err != nil { ctx.WithError(err).Fatal("Failed to read json flag") } fPort, err := cmd.Flags().GetInt("fport") if err != nil { ctx.WithError(err).Fatal("Failed to read fport flag") } message := types.DownlinkMessage{ AppID: appID, DevID: devID, FPort: uint8(fPort), } if args[1] == "" { ctx.Info("Invalid command") cmd.UsageFunc()(cmd) return } if jsonflag { // Valid payload provided + json flag _, err := types.ParseHEX(args[1], len(args[1])/2) if err == nil { ctx.WithError(err).Fatal("You are providing a valid HEX payload while sending payload in JSON.") }