func SaveDownlinkFrame(ctx context.Context, frame *DownlinkFrame) error {
	key := GetRedisKey(downlinkFrameKeyTempl, frame.Token)
	b, err := proto.Marshal(frame)
	if err != nil {
		return errors.Wrap(err, "marshal proto error")
	}
	err = RedisClient().Set(ctx, key, b, downlinkFrameTTL).Err()
	if err != nil {
		return errors.Wrap(err, "save downlink-frame error")
	}
	log.WithFields(log.Fields{
		"token":  frame.Token,
		"ctx_id": ctx.Value(logging.ContextIDKey),
	}).Info("storage: downlink-frame saved")
	return nil
}
SaveDownlinkFrame saves the given downlink-frame.
package storage
import (
	"context"
	"time"
	"github.com/go-redis/redis/v8"
	proto "github.com/golang/protobuf/proto"
	"github.com/pkg/errors"
	log "github.com/sirupsen/logrus"
	"github.com/brocaar/chirpstack-network-server/v3/internal/logging"
)
const downlinkFrameTTL = time.Second * 10
const downlinkFrameKeyTempl = "lora:ns:frame:%d"