// 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) }
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 }