Пример #1
0
// 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)
}
Пример #2
0
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
}
Пример #3
0
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
}