本文整理汇总了Golang中github.com/brocaar/lorawan.PHYPayload类的典型用法代码示例。如果您正苦于以下问题:Golang PHYPayload类的具体用法?Golang PHYPayload怎么用?Golang PHYPayload使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了PHYPayload类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: newReferenceUplink
// newReferenceUplink returns a default uplink message
func newReferenceUplink() *pb.UplinkMessage {
gtwID := "eui-0102030405060708"
phy := lorawan.PHYPayload{
MHDR: lorawan.MHDR{
MType: lorawan.UnconfirmedDataUp,
Major: lorawan.LoRaWANR1,
},
MACPayload: &lorawan.MACPayload{
FHDR: lorawan.FHDR{
DevAddr: lorawan.DevAddr([4]byte{1, 2, 3, 4}),
},
},
}
bytes, _ := phy.MarshalBinary()
up := &pb.UplinkMessage{
Payload: bytes,
ProtocolMetadata: &pb_protocol.RxMetadata{Protocol: &pb_protocol.RxMetadata_Lorawan{Lorawan: &pb_lorawan.Metadata{
CodingRate: "4/5",
DataRate: "SF7BW125",
Modulation: pb_lorawan.Modulation_LORA,
}}},
GatewayMetadata: &pb_gateway.RxMetadata{
GatewayId: gtwID,
Timestamp: 100,
Frequency: 868100000,
Rssi: -25.0,
Snr: 5.0,
},
}
return up
}
示例2: newRXPacketFromRXPK
// newRXPacketFromRXPK transforms a Semtech packet into a models.RXPacket.
func newRXPacketFromRXPK(mac lorawan.EUI64, rxpk RXPK) (models.RXPacket, error) {
var phy lorawan.PHYPayload
if err := phy.UnmarshalText([]byte(rxpk.Data)); err != nil {
return models.RXPacket{}, fmt.Errorf("gateway: could not unmarshal PHYPayload: %s", err)
}
dataRate, err := newDataRateFromDatR(rxpk.DatR)
if err != nil {
return models.RXPacket{}, fmt.Errorf("gateway: could not get DataRate from DatR: %s", err)
}
rxPacket := models.RXPacket{
PHYPayload: phy,
RXInfo: models.RXInfo{
MAC: mac,
Time: time.Time(rxpk.Time),
Timestamp: rxpk.Tmst,
Frequency: int(rxpk.Freq * 1000000),
Channel: int(rxpk.Chan),
RFChain: int(rxpk.RFCh),
CRCStatus: int(rxpk.Stat),
DataRate: dataRate,
CodeRate: rxpk.CodR,
RSSI: int(rxpk.RSSI),
LoRaSNR: rxpk.LSNR,
Size: int(rxpk.Size),
},
}
return rxPacket, nil
}
示例3: msgFromPayload
func msgFromPayload(payload []byte) (*pb_protocol.Message, error) {
var phy lorawan.PHYPayload
if err := phy.UnmarshalBinary(payload); err != nil {
return nil, err
}
msg := pb_lorawan.MessageFromPHYPayload(phy)
return &pb_protocol.Message{Protocol: &pb_protocol.Message_Lorawan{Lorawan: &msg}}, nil
}
示例4: UnmarshalPayload
// UnmarshalPayload unmarshals the Payload into Message if Message is nil
func (m *DeviceActivationResponse) UnmarshalPayload() error {
if m.GetMessage() == nil && m.GetDownlinkOption() != nil && m.DownlinkOption.GetProtocolConfig() != nil && m.DownlinkOption.ProtocolConfig.GetLorawan() != nil {
var phy lorawan.PHYPayload
if err := phy.UnmarshalBinary(m.Payload); err != nil {
return err
}
msg := pb_lorawan.MessageFromPHYPayload(phy)
m.Message = &pb_protocol.Message{Protocol: &pb_protocol.Message_Lorawan{Lorawan: &msg}}
}
return nil
}
示例5: HandleDownlink
func (n *networkServer) HandleDownlink(message *pb_broker.DownlinkMessage) (*pb_broker.DownlinkMessage, error) {
// Get Device
dev, err := n.devices.Get(*message.AppEui, *message.DevEui)
if err != nil {
return nil, err
}
n.status.downlink.Mark(1)
dev.StartUpdate()
if dev.AppID != message.AppId || dev.DevID != message.DevId {
return nil, errors.NewErrInvalidArgument("Downlink", "AppID and DevID do not match AppEUI and DevEUI")
}
// Unmarshal LoRaWAN Payload
var phyPayload lorawan.PHYPayload
err = phyPayload.UnmarshalBinary(message.Payload)
if err != nil {
return nil, err
}
macPayload, ok := phyPayload.MACPayload.(*lorawan.MACPayload)
if !ok {
return nil, errors.NewErrInvalidArgument("Downlink", "does not contain a MAC payload")
}
// Set DevAddr
macPayload.FHDR.DevAddr = lorawan.DevAddr(dev.DevAddr)
// FIRST set and THEN increment FCntDown
// TODO: For confirmed downlink, FCntDown should be incremented AFTER ACK
macPayload.FHDR.FCnt = dev.FCntDown
dev.FCntDown++
err = n.devices.Set(dev)
if err != nil {
return nil, err
}
// Sign MIC
phyPayload.SetMIC(lorawan.AES128Key(dev.NwkSKey))
// Update message
bytes, err := phyPayload.MarshalBinary()
if err != nil {
return nil, err
}
message.Payload = bytes
return message, nil
}
示例6: doTestHandleActivation
func doTestHandleActivation(h *handler, appEUI types.AppEUI, devEUI types.DevEUI, devNonce [2]byte, appKey types.AppKey) (*pb.DeviceActivationResponse, error) {
devAddr := types.DevAddr{1, 2, 3, 4}
requestPHY := lorawan.PHYPayload{
MHDR: lorawan.MHDR{
MType: lorawan.JoinRequest,
Major: lorawan.LoRaWANR1,
},
MACPayload: &lorawan.JoinRequestPayload{
AppEUI: lorawan.EUI64(appEUI),
DevEUI: lorawan.EUI64(devEUI),
DevNonce: devNonce,
},
}
requestPHY.SetMIC(lorawan.AES128Key(appKey))
requestBytes, _ := requestPHY.MarshalBinary()
responsePHY := lorawan.PHYPayload{
MHDR: lorawan.MHDR{
MType: lorawan.JoinAccept,
Major: lorawan.LoRaWANR1,
},
MACPayload: &lorawan.JoinAcceptPayload{},
}
templateBytes, _ := responsePHY.MarshalBinary()
return h.HandleActivation(&pb_broker.DeduplicatedDeviceActivationRequest{
Payload: requestBytes,
AppEui: &appEUI,
AppId: appEUI.String(),
DevEui: &devEUI,
DevId: devEUI.String(),
ActivationMetadata: &pb_protocol.ActivationMetadata{Protocol: &pb_protocol.ActivationMetadata_Lorawan{
Lorawan: &pb_lorawan.ActivationMetadata{
DevAddr: &devAddr,
},
}},
ResponseTemplate: &pb_broker.DeviceActivationResponse{
Payload: templateBytes,
},
})
}
示例7: TestHandleUplink
func TestHandleUplink(t *testing.T) {
a := New(t)
ns := &networkServer{
devices: device.NewRedisDeviceStore(GetRedisClient(), "ns-test-handle-uplink"),
}
ns.InitStatus()
appEUI := types.AppEUI(getEUI(1, 2, 3, 4, 5, 6, 7, 8))
devEUI := types.DevEUI(getEUI(1, 2, 3, 4, 5, 6, 7, 8))
devAddr := getDevAddr(1, 2, 3, 4)
// Device Not Found
message := &pb_broker.DeduplicatedUplinkMessage{
AppEui: &appEUI,
DevEui: &devEUI,
Payload: []byte{},
}
_, err := ns.HandleUplink(message)
a.So(err, ShouldNotBeNil)
ns.devices.Set(&device.Device{
DevAddr: devAddr,
AppEUI: appEUI,
DevEUI: devEUI,
})
defer func() {
ns.devices.Delete(appEUI, devEUI)
}()
// Invalid Payload
message = &pb_broker.DeduplicatedUplinkMessage{
AppEui: &appEUI,
DevEui: &devEUI,
Payload: []byte{},
}
_, err = ns.HandleUplink(message)
a.So(err, ShouldNotBeNil)
phy := lorawan.PHYPayload{
MHDR: lorawan.MHDR{
MType: lorawan.UnconfirmedDataUp,
Major: lorawan.LoRaWANR1,
},
MACPayload: &lorawan.MACPayload{
FHDR: lorawan.FHDR{
DevAddr: lorawan.DevAddr([4]byte{1, 2, 3, 4}),
FCnt: 1,
FCtrl: lorawan.FCtrl{
ADR: true,
ADRACKReq: true,
},
FOpts: []lorawan.MACCommand{
lorawan.MACCommand{CID: lorawan.LinkCheckReq},
},
},
},
}
bytes, _ := phy.MarshalBinary()
// Valid Uplink
message = &pb_broker.DeduplicatedUplinkMessage{
AppEui: &appEUI,
DevEui: &devEUI,
Payload: bytes,
ResponseTemplate: &pb_broker.DownlinkMessage{},
GatewayMetadata: []*pb_gateway.RxMetadata{
&pb_gateway.RxMetadata{},
},
ProtocolMetadata: &pb_protocol.RxMetadata{Protocol: &pb_protocol.RxMetadata_Lorawan{
Lorawan: &pb_lorawan.Metadata{
DataRate: "SF7BW125",
},
}},
}
res, err := ns.HandleUplink(message)
a.So(err, ShouldBeNil)
a.So(res.ResponseTemplate, ShouldNotBeNil)
// LoRaWAN: Unmarshal
var phyPayload lorawan.PHYPayload
phyPayload.UnmarshalBinary(res.ResponseTemplate.Payload)
macPayload, _ := phyPayload.MACPayload.(*lorawan.MACPayload)
// ResponseTemplate DevAddr should match
a.So([4]byte(macPayload.FHDR.DevAddr), ShouldEqual, [4]byte(devAddr))
// ResponseTemplate should ACK the ADRACKReq
a.So(macPayload.FHDR.FCtrl.ACK, ShouldBeTrue)
a.So(macPayload.FHDR.FOpts, ShouldHaveLength, 1)
a.So(macPayload.FHDR.FOpts[0].Payload, ShouldResemble, &lorawan.LinkCheckAnsPayload{GwCnt: 1, Margin: 7})
// Frame Counter should have been updated
dev, _ := ns.devices.Get(appEUI, devEUI)
a.So(dev.FCntUp, ShouldEqual, 1)
a.So(time.Now().Sub(dev.LastSeen), ShouldBeLessThan, 1*time.Second)
}
示例8: HandleActivation
func (b *broker) HandleActivation(activation *pb.DeviceActivationRequest) (res *pb.DeviceActivationResponse, err error) {
ctx := b.Ctx.WithFields(log.Fields{
"GatewayID": activation.GatewayMetadata.GatewayId,
"AppEUI": *activation.AppEui,
"DevEUI": *activation.DevEui,
})
start := time.Now()
defer func() {
if err != nil {
ctx.WithError(err).Warn("Could not handle activation")
} else {
ctx.WithField("Duration", time.Now().Sub(start)).Info("Handled activation")
}
}()
time := time.Now()
b.status.activations.Mark(1)
// De-duplicate uplink messages
duplicates := b.deduplicateActivation(activation)
if len(duplicates) == 0 {
return nil, errDuplicateActivation
}
b.status.activationsUnique.Mark(1)
base := duplicates[0]
// Collect GatewayMetadata and DownlinkOptions
var gatewayMetadata []*gateway.RxMetadata
var downlinkOptions []*pb.DownlinkOption
var deviceActivationResponse *pb.DeviceActivationResponse
for _, duplicate := range duplicates {
gatewayMetadata = append(gatewayMetadata, duplicate.GatewayMetadata)
downlinkOptions = append(downlinkOptions, duplicate.DownlinkOptions...)
}
// Select best DownlinkOption
if len(downlinkOptions) > 0 {
deviceActivationResponse = &pb.DeviceActivationResponse{
DownlinkOption: selectBestDownlink(downlinkOptions),
}
}
// Build Uplink
deduplicatedActivationRequest := &pb.DeduplicatedDeviceActivationRequest{
Payload: base.Payload,
DevEui: base.DevEui,
AppEui: base.AppEui,
ProtocolMetadata: base.ProtocolMetadata,
GatewayMetadata: gatewayMetadata,
ActivationMetadata: base.ActivationMetadata,
ServerTime: time.UnixNano(),
ResponseTemplate: deviceActivationResponse,
}
// Send Activate to NS
deduplicatedActivationRequest, err = b.ns.PrepareActivation(b.Component.GetContext(b.nsToken), deduplicatedActivationRequest)
if err != nil {
return nil, errors.Wrap(errors.FromGRPCError(err), "NetworkServer refused to prepare activation")
}
ctx = ctx.WithFields(log.Fields{
"AppID": deduplicatedActivationRequest.AppId,
"DevID": deduplicatedActivationRequest.DevId,
})
// Find Handler (based on AppEUI)
var announcements []*pb_discovery.Announcement
announcements, err = b.Discovery.GetAllHandlersForAppID(deduplicatedActivationRequest.AppId)
if err != nil {
return nil, err
}
if len(announcements) == 0 {
return nil, errors.NewErrNotFound(fmt.Sprintf("Handler for AppID %s", deduplicatedActivationRequest.AppId))
}
ctx = ctx.WithField("NumHandlers", len(announcements))
// LoRaWAN: Unmarshal and prepare version without MIC
var phyPayload lorawan.PHYPayload
err = phyPayload.UnmarshalBinary(deduplicatedActivationRequest.Payload)
if err != nil {
return nil, err
}
correctMIC := phyPayload.MIC
phyPayload.MIC = [4]byte{0, 0, 0, 0}
phyPayloadWithoutMIC, err := phyPayload.MarshalBinary()
if err != nil {
return nil, err
}
// Build Challenge
challenge := &pb.ActivationChallengeRequest{
Payload: phyPayloadWithoutMIC,
AppId: deduplicatedActivationRequest.AppId,
DevId: deduplicatedActivationRequest.DevId,
AppEui: deduplicatedActivationRequest.AppEui,
DevEui: deduplicatedActivationRequest.DevEui,
//.........这里部分代码省略.........
示例9: HandleUplink
func (b *broker) HandleUplink(uplink *pb.UplinkMessage) (err error) {
ctx := b.Ctx.WithField("GatewayID", uplink.GatewayMetadata.GatewayId)
start := time.Now()
defer func() {
if err != nil {
ctx.WithError(err).Warn("Could not handle uplink")
} else {
ctx.WithField("Duration", time.Now().Sub(start)).Info("Handled uplink")
}
}()
time := time.Now()
b.status.uplink.Mark(1)
// De-duplicate uplink messages
duplicates := b.deduplicateUplink(uplink)
if len(duplicates) == 0 {
return nil
}
b.status.uplinkUnique.Mark(1)
ctx = ctx.WithField("Duplicates", len(duplicates))
base := duplicates[0]
if base.ProtocolMetadata.GetLorawan() == nil {
return errors.NewErrInvalidArgument("Uplink", "does not contain LoRaWAN metadata")
}
// LoRaWAN: Unmarshal
var phyPayload lorawan.PHYPayload
err = phyPayload.UnmarshalBinary(base.Payload)
if err != nil {
return err
}
macPayload, ok := phyPayload.MACPayload.(*lorawan.MACPayload)
if !ok {
return errors.NewErrInvalidArgument("Uplink", "does not contain a MAC payload")
}
// Request devices from NS
devAddr := types.DevAddr(macPayload.FHDR.DevAddr)
ctx = ctx.WithFields(log.Fields{
"DevAddr": devAddr,
"FCnt": macPayload.FHDR.FCnt,
})
var getDevicesResp *networkserver.DevicesResponse
getDevicesResp, err = b.ns.GetDevices(b.Component.GetContext(b.nsToken), &networkserver.DevicesRequest{
DevAddr: &devAddr,
FCnt: macPayload.FHDR.FCnt,
})
if err != nil {
return errors.Wrap(errors.FromGRPCError(err), "NetworkServer did not return devices")
}
b.status.deduplication.Update(int64(len(getDevicesResp.Results)))
if len(getDevicesResp.Results) == 0 {
return errors.NewErrNotFound(fmt.Sprintf("Device with DevAddr %s and FCnt <= %d", devAddr, macPayload.FHDR.FCnt))
}
ctx = ctx.WithField("DevAddrResults", len(getDevicesResp.Results))
// Sort by FCntUp to optimize the number of MIC checks
sort.Sort(ByFCntUp(getDevicesResp.Results))
// Find AppEUI/DevEUI through MIC check
var device *pb_lorawan.Device
var micChecks int
var originalFCnt uint32
for _, candidate := range getDevicesResp.Results {
nwkSKey := lorawan.AES128Key(*candidate.NwkSKey)
// First check with the 16 bit counter
micChecks++
ok, err = phyPayload.ValidateMIC(nwkSKey)
if err != nil {
return err
}
if ok {
device = candidate
break
}
originalFCnt = macPayload.FHDR.FCnt
if candidate.Uses32BitFCnt {
macPayload.FHDR.FCnt = fcnt.GetFull(candidate.FCntUp, uint16(originalFCnt))
// If 32 bit counter has different value, perform another MIC check
if macPayload.FHDR.FCnt != originalFCnt {
micChecks++
ok, err = phyPayload.ValidateMIC(nwkSKey)
if err != nil {
return err
}
if ok {
device = candidate
break
}
}
}
//.........这里部分代码省略.........
示例10: handleDataDownReply
func handleDataDownReply(ctx Context, rxPacket models.RXPacket, ns models.NodeSession) error {
macPL, ok := rxPacket.PHYPayload.MACPayload.(*lorawan.MACPayload)
if !ok {
return fmt.Errorf("expected *lorawan.MACPayload, got: %T", rxPacket.PHYPayload.MACPayload)
}
// the last payload was received by the node
if macPL.FHDR.FCtrl.ACK {
txPayload, err := clearInProcessTXPayload(ctx.RedisPool, ns.DevEUI)
if err != nil {
return err
}
ns.FCntDown++
if err = saveNodeSession(ctx.RedisPool, ns); err != nil {
return err
}
if txPayload != nil {
err = ctx.Application.SendNotification(ns.DevEUI, ns.AppEUI, models.ACKNotificationType, models.ACKNotification{
Reference: txPayload.Reference,
DevEUI: ns.DevEUI,
})
if err != nil {
return err
}
}
}
// check if there are payloads pending in the queue
txPayload, remaining, err := getTXPayloadAndRemainingFromQueue(ctx.RedisPool, ns.DevEUI)
if err != nil {
return err
}
// nothing pending in the queue and no need to ACK RXPacket
if rxPacket.PHYPayload.MHDR.MType != lorawan.ConfirmedDataUp && txPayload == nil {
return nil
}
// get TX DR
uplinkDR, err := Band.GetDataRate(rxPacket.RXInfo.DataRate)
if err != nil {
return err
}
// get TX channel
uplinkChannel, err := Band.GetChannel(rxPacket.RXInfo.Frequency, uplinkDR)
if err != nil {
return err
}
// get RX1 channel
rx1Channel := Band.GetRX1Channel(uplinkChannel)
// get RX1 DR
rx1DR, err := Band.GetRX1DataRateForOffset(uplinkDR, int(ns.RX1DROffset))
if err != nil {
return err
}
// get rx delay
rxDelay := Band.ReceiveDelay1
if ns.RXDelay > 0 {
rxDelay = time.Duration(ns.RXDelay) * time.Second
}
phy := lorawan.PHYPayload{
MHDR: lorawan.MHDR{
MType: lorawan.UnconfirmedDataDown,
Major: lorawan.LoRaWANR1,
},
}
macPL = &lorawan.MACPayload{
FHDR: lorawan.FHDR{
DevAddr: ns.DevAddr,
FCtrl: lorawan.FCtrl{
ACK: rxPacket.PHYPayload.MHDR.MType == lorawan.ConfirmedDataUp, // set ACK to true when received packet needs an ACK
},
FCnt: ns.FCntDown,
},
}
phy.MACPayload = macPL
// add the payload from the queue
if txPayload != nil {
// validate the max payload size
if len(txPayload.Data) > Band.MaxPayloadSize[rx1DR].N {
// remove the payload from the queue regarding confirmed or not
if _, err := clearInProcessTXPayload(ctx.RedisPool, ns.DevEUI); err != nil {
return err
}
log.WithFields(log.Fields{
"dev_eui": ns.DevEUI,
"data_rate": rx1DR,
"frmpayload_size": len(txPayload.Data),
"max_frmpayload_size": Band.MaxPayloadSize[rx1DR].N,
}).Warning("downlink payload max size exceeded")
err = ctx.Application.SendNotification(ns.DevEUI, ns.AppEUI, models.ErrorNotificationType, models.ErrorNotification{
Reference: txPayload.Reference,
DevEUI: ns.DevEUI,
Message: fmt.Sprintf("downlink payload max size exceeded (dr: %d, allowed: %d, got: %d)", rx1DR, Band.MaxPayloadSize[rx1DR].N, len(txPayload.Data)),
})
if err != nil {
return err
//.........这里部分代码省略.........
示例11: handleCollectedJoinRequestPackets
// handleCollectedJoinRequestPackets handles the received join-request.
func handleCollectedJoinRequestPackets(ctx Context, rxPackets RXPackets) error {
if len(rxPackets) == 0 {
return errors.New("packet collector returned 0 packets")
}
rxPacket := rxPackets[0]
var macs []string
for _, p := range rxPackets {
macs = append(macs, p.RXInfo.MAC.String())
}
// MACPayload must be of type *lorawan.JoinRequestPayload
jrPL, ok := rxPacket.PHYPayload.MACPayload.(*lorawan.JoinRequestPayload)
if !ok {
return fmt.Errorf("expected *lorawan.JoinRequestPayload, got: %T", rxPacket.PHYPayload.MACPayload)
}
log.WithFields(log.Fields{
"dev_eui": jrPL.DevEUI,
"gw_count": len(rxPackets),
"gw_macs": strings.Join(macs, ", "),
"mtype": rxPackets[0].PHYPayload.MHDR.MType,
}).Info("packet(s) collected")
// get node information for this DevEUI
node, err := getNode(ctx.DB, jrPL.DevEUI)
if err != nil {
return err
}
// validate the given nonce
if !node.ValidateDevNonce(jrPL.DevNonce) {
return fmt.Errorf("given dev-nonce %x has already been used before for node %s", jrPL.DevNonce, jrPL.DevEUI)
}
// get random (free) DevAddr
devAddr, err := getRandomDevAddr(ctx.RedisPool, ctx.NetID)
if err != nil {
return fmt.Errorf("get random DevAddr error: %s", err)
}
// get app nonce
appNonce, err := getAppNonce()
if err != nil {
return fmt.Errorf("get AppNonce error: %s", err)
}
// get the (optional) CFList
cFList, err := getCFListForNode(ctx.DB, node)
if err != nil {
return fmt.Errorf("get CFList for node error: %s", err)
}
// get keys
nwkSKey, err := getNwkSKey(node.AppKey, ctx.NetID, appNonce, jrPL.DevNonce)
if err != nil {
return fmt.Errorf("get NwkSKey error: %s", err)
}
appSKey, err := getAppSKey(node.AppKey, ctx.NetID, appNonce, jrPL.DevNonce)
if err != nil {
return fmt.Errorf("get AppSKey error: %s", err)
}
ns := models.NodeSession{
DevAddr: devAddr,
DevEUI: jrPL.DevEUI,
AppSKey: appSKey,
NwkSKey: nwkSKey,
FCntUp: 0,
FCntDown: 0,
AppEUI: node.AppEUI,
RXDelay: node.RXDelay,
RX1DROffset: node.RX1DROffset,
}
if err = saveNodeSession(ctx.RedisPool, ns); err != nil {
return fmt.Errorf("save node-session error: %s", err)
}
// update the node (with updated used dev-nonces)
if err = updateNode(ctx.DB, node); err != nil {
return fmt.Errorf("update node error: %s", err)
}
// construct the lorawan packet
phy := lorawan.PHYPayload{
MHDR: lorawan.MHDR{
MType: lorawan.JoinAccept,
Major: lorawan.LoRaWANR1,
},
MACPayload: &lorawan.JoinAcceptPayload{
AppNonce: appNonce,
NetID: ctx.NetID,
DevAddr: ns.DevAddr,
RXDelay: ns.RXDelay,
DLSettings: lorawan.DLSettings{
RX2DataRate: uint8(Band.RX2DataRate),
RX1DROffset: ns.RX1DROffset,
},
//.........这里部分代码省略.........
示例12: HandlePrepareActivation
func (n *networkServer) HandlePrepareActivation(activation *pb_broker.DeduplicatedDeviceActivationRequest) (*pb_broker.DeduplicatedDeviceActivationRequest, error) {
if activation.AppEui == nil || activation.DevEui == nil {
return nil, errors.NewErrInvalidArgument("Activation", "missing AppEUI or DevEUI")
}
dev, err := n.devices.Get(*activation.AppEui, *activation.DevEui)
if err != nil {
return nil, err
}
activation.AppId = dev.AppID
activation.DevId = dev.DevID
// Get activation constraints (for DevAddr prefix selection)
activationConstraints := strings.Split(dev.Options.ActivationConstraints, ",")
if len(activationConstraints) == 1 && activationConstraints[0] == "" {
activationConstraints = []string{}
}
activationConstraints = append(activationConstraints, "otaa")
// Build activation metadata if not present
if meta := activation.GetActivationMetadata(); meta == nil {
activation.ActivationMetadata = &pb_protocol.ActivationMetadata{}
}
// Build lorawan metadata if not present
if lorawan := activation.ActivationMetadata.GetLorawan(); lorawan == nil {
return nil, errors.NewErrInvalidArgument("Activation", "missing LoRaWAN metadata")
}
// Build response template if not present
if pld := activation.GetResponseTemplate(); pld == nil {
return nil, errors.NewErrInvalidArgument("Activation", "missing response template")
}
lorawanMeta := activation.ActivationMetadata.GetLorawan()
// Get a random device address
devAddr, err := n.getDevAddr(activationConstraints...)
if err != nil {
return nil, err
}
// Set the DevAddr in the Activation Metadata
lorawanMeta.DevAddr = &devAddr
// Build JoinAccept Payload
phy := lorawan.PHYPayload{
MHDR: lorawan.MHDR{
MType: lorawan.JoinAccept,
Major: lorawan.LoRaWANR1,
},
MACPayload: &lorawan.JoinAcceptPayload{
NetID: n.netID,
DLSettings: lorawan.DLSettings{RX2DataRate: uint8(lorawanMeta.Rx2Dr), RX1DROffset: uint8(lorawanMeta.Rx1DrOffset)},
RXDelay: uint8(lorawanMeta.RxDelay),
DevAddr: lorawan.DevAddr(devAddr),
},
}
if lorawanMeta.CfList != nil {
var cfList lorawan.CFList
for i, cfListItem := range lorawanMeta.CfList.Freq {
cfList[i] = cfListItem
}
phy.MACPayload.(*lorawan.JoinAcceptPayload).CFList = &cfList
}
// Set the Payload
phyBytes, err := phy.MarshalBinary()
if err != nil {
return nil, err
}
activation.ResponseTemplate.Payload = phyBytes
return activation, nil
}
示例13: ConvertToLoRaWAN
func (h *handler) ConvertToLoRaWAN(ctx log.Interface, appDown *types.DownlinkMessage, ttnDown *pb_broker.DownlinkMessage) error {
// Find Device
dev, err := h.devices.Get(appDown.AppID, appDown.DevID)
if err != nil {
return err
}
// LoRaWAN: Unmarshal Downlink
var phyPayload lorawan.PHYPayload
err = phyPayload.UnmarshalBinary(ttnDown.Payload)
if err != nil {
return err
}
macPayload, ok := phyPayload.MACPayload.(*lorawan.MACPayload)
if !ok {
return errors.NewErrInvalidArgument("Downlink", "does not contain a MAC payload")
}
if ttnDown.DownlinkOption != nil && ttnDown.DownlinkOption.ProtocolConfig.GetLorawan() != nil {
macPayload.FHDR.FCnt = ttnDown.DownlinkOption.ProtocolConfig.GetLorawan().FCnt
}
// Abort when downlink not needed
if len(appDown.PayloadRaw) == 0 && !macPayload.FHDR.FCtrl.ACK && len(macPayload.FHDR.FOpts) == 0 {
return ErrNotNeeded
}
// Set FPort
if appDown.FPort != 0 {
macPayload.FPort = &appDown.FPort
}
// Set Payload
if len(appDown.PayloadRaw) > 0 {
macPayload.FRMPayload = []lorawan.Payload{&lorawan.DataPayload{Bytes: appDown.PayloadRaw}}
if macPayload.FPort == nil || *macPayload.FPort == 0 {
macPayload.FPort = pointer.Uint8(1)
}
} else {
macPayload.FRMPayload = []lorawan.Payload{}
}
// Encrypt
err = phyPayload.EncryptFRMPayload(lorawan.AES128Key(dev.AppSKey))
if err != nil {
return err
}
// Set MIC
err = phyPayload.SetMIC(lorawan.AES128Key(dev.NwkSKey))
if err != nil {
return err
}
// Marshal
phyPayloadBytes, err := phyPayload.MarshalBinary()
if err != nil {
return err
}
ttnDown.Payload = phyPayloadBytes
return nil
}
示例14: ConvertFromLoRaWAN
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
}
示例15: handleDataDownReply
func handleDataDownReply(ctx Context, rxPacket models.RXPacket, ns models.NodeSession) error {
macPL, ok := rxPacket.PHYPayload.MACPayload.(*lorawan.MACPayload)
if !ok {
return fmt.Errorf("expected *lorawan.MACPayload, got: %T", rxPacket.PHYPayload.MACPayload)
}
// get data down properies
properties, err := getDataDownProperties(rxPacket.RXInfo, ns)
if err != nil {
return fmt.Errorf("get data down properties error: %s", err)
}
var frmMACCommands bool
var macPayloads []models.MACPayload
allMACPayloads, err := storage.ReadMACPayloadTXQueue(ctx.RedisPool, ns.DevAddr)
if err != nil {
return fmt.Errorf("read mac-payload tx queue error: %s", err)
}
if len(allMACPayloads) > 0 {
if allMACPayloads[0].FRMPayload {
// the first mac-commands must be sent as FRMPayload, filter the rest
// of the MACPayload items with the same property, respecting the
// max FRMPayload size for the data-rate.
frmMACCommands = true
macPayloads = storage.FilterMACPayloads(allMACPayloads, true, common.Band.MaxPayloadSize[properties.rx1DR].N)
} else {
// the first mac-command must be sent as FOpts, filter the rest of
// the MACPayload items with the same property, respecting the
// max FOpts size of 15.
macPayloads = storage.FilterMACPayloads(allMACPayloads, false, 15)
}
}
// if the MACCommands (if any) are not sent as FRMPayload, check if there
// is a tx-payload in the queue and validate if the FOpts + FRMPayload
// does not exceed the max payload size.
var txPayload *models.TXPayload
if !frmMACCommands {
// check if there are payloads pending in the queue
txPayload, err = getNextValidTXPayloadForDRFromQueue(ctx, ns, properties.rx1DR)
if err != nil {
return fmt.Errorf("get next valid tx-payload error: %s", err)
}
var macByteCount int
for _, mac := range macPayloads {
macByteCount += len(mac.MACCommand)
}
if txPayload != nil && len(txPayload.Data)+macByteCount > common.Band.MaxPayloadSize[properties.rx1DR].N {
log.WithFields(log.Fields{
"data_rate": properties.rx1DR,
"dev_eui": ns.DevEUI,
"reference": txPayload.Reference,
}).Info("scheduling tx-payload for next downlink, mac-commands + payload exceeds max size")
txPayload = nil
}
}
// convert the MACPayload items into MACCommand items
var macCommmands []lorawan.MACCommand
for _, pl := range macPayloads {
var mac lorawan.MACCommand
if err := mac.UnmarshalBinary(false, pl.MACCommand); err != nil {
// in case the mac commands can't be unmarshaled, the payload
// is ignored and an error sent to the network-controller
errStr := fmt.Sprintf("unmarshal mac command error: %s", err)
log.WithFields(log.Fields{
"dev_eui": ns.DevEUI,
"reference": pl.Reference,
}).Warning(errStr)
err = ctx.Controller.SendErrorPayload(ns.AppEUI, ns.DevEUI, models.ErrorPayload{
Reference: pl.Reference,
DevEUI: ns.DevEUI,
Message: errStr,
})
if err != nil {
return fmt.Errorf("send error payload to network-controller error: %s", err)
}
continue
}
macCommmands = append(macCommmands, mac)
}
// uplink was unconfirmed and no downlink data in queue and no mac commands to send
if txPayload == nil && rxPacket.PHYPayload.MHDR.MType == lorawan.UnconfirmedDataUp && len(macCommmands) == 0 {
return nil
}
// get the queue size (the size includes the current payload)
queueSize, err := storage.GetTXPayloadQueueSize(ctx.RedisPool, ns.DevEUI)
if err != nil {
return err
}
if txPayload != nil {
queueSize-- // substract the current tx-payload from the queue-size
}
phy := lorawan.PHYPayload{
//.........这里部分代码省略.........