lorawan

package module
v0.0.0-...-b905ab3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 12, 2019 License: MIT Imports: 10 Imported by: 0

README

LoRaWAN (Go)

Build Status GoDoc

Package lorawan provides structures and tools to read and write LoraWAN messages from and to a slice of bytes.

The following structures are implemented (+ fields):

* PHYPayload    (MHDR | MACPayload | MIC)
* MACPayload    (FHDR | FPort | FRMPayload)
* FHDR          (DevAddr | FCtrl | FCnt | FOpts)

The Following message types (MType) are implemented:

* JoinRequest
* JoinAccept
* UnconfirmedDataUp
* UnconfirmedDataDown
* ConfirmedDataUp
* ConfirmedDataDown
* Proprietary (todo: add pluggable function for MIC calculation / validation)

The following MAC commands (and their optional payloads) are implemented:

* LinkCheckReq
* LinkCheckAns
* LinkADRReq
* LinkADRAns
* DutyCycleReq
* DutyCycleAns
* RXParamSetupReq
* RXParamSetupAns
* DevStatusReq
* DevStatusAns
* NewChannelReq
* NewChannelAns
* RXTimingSetupReq
* RXTimingSetupAns
* Proprietary commands (0x80 - 0xFF) can be registered with RegisterProprietaryMACCommand

Support for calculating and setting the MIC is done by calling SetMIC():

err := phyPayload.SetMIC(key)

Validating the MIC is done by calling ValidateMIC():

valid, err := phyPayload.ValidateMIC(key)

Encryption and decryption of the MACPayload (for join-accept) is done by calling EncryptJoinAcceptPayload() and DecryptJoinAcceptPayload(). Note that you need to call SetMIC BEFORE encryption.

err := phyPayload.EncryptJoinAcceptPayload(key)
err := phyPayload.DecryptJoinAcceptPayload(key)

Encryption and decryption of the FRMPayload is done by calling EncryptFRMPayload() and DecryptFRMPayload(). After encryption (and thus before decryption), the bytes are stored in the DataPayload struct.

err := phyPayload.EncryptFRMPayload(key)
err := phyPayload.DecryptFRMPayload(key)

All payloads implement the Payload interface. Based on the MIC value, you should be able to know to which type to cast the Payload value, so you will be able to access its fields.

See the examples section of the documentation for more usage examples of this package.

When using this package, knowledge about the LoRaWAN specification is needed. You can request the LoRaWAN specification here: https://www.lora-alliance.org/For-Developers/LoRaWANDevelopers

ISM band configuration

The LoRaWAN specification defines various region specific defaults and configuration. These can be found in the band sub-package.

Documentation

See https://godoc.org/github.com/brocaar/lorawan. There is also an examples section with usage examples.

License

This package is distributed under the MIT license which can be found in LICENSE. LoRaWAN is a trademark of the LoRa Alliance Inc. (https://www.lora-alliance.org/).

Documentation

Overview

Package lorawan provides structures and tools to read and write LoraWAN messages from and to a slice of bytes.

The following structures are implemented (+ fields):

  • PHYPayload (MHDR | MACPayload | MIC)
  • MACPayload (FHDR | FPort | FRMPayload)
  • FHDR (DevAddr | FCtrl | FCnt | FOpts)

The Following message types (MType) are implemented:

  • JoinRequest
  • JoinAccept
  • UnconfirmedDataUp
  • UnconfirmedDataDown
  • ConfirmedDataUp
  • ConfirmedDataDown
  • Proprietary

The following MAC commands (and their optional payloads) are implemented:

  • LinkCheckReq
  • LinkCheckAns
  • LinkADRReq
  • LinkADRAns
  • DutyCycleReq
  • DutyCycleAns
  • RXParamSetupReq
  • RXParamSetupAns
  • DevStatusReq
  • DevStatusAns
  • NewChannelReq
  • NewChannelAns
  • RXTimingSetupReq
  • RXTimingSetupAns
  • Proprietary commands (0x80 - 0xFF) can be registered with RegisterProprietaryMACCommand

Support for calculating and setting the MIC is done by calling SetMIC():

err := phyPayload.SetMIC(key)

Validating the MIC is done by calling ValidateMIC():

valid, err := phyPayload.ValidateMIC(key)

Encryption and decryption of the MACPayload (for join-accept) is done by calling EncryptJoinAcceptPayload() and DecryptJoinAcceptPayload(). Note that you need to call SetMIC BEFORE encryption.

err := phyPayload.EncryptJoinAcceptPayload(key)
err := phyPayload.DecryptJoinAcceptPayload(key)

Encryption and decryption of the FRMPayload is done by calling EncryptFRMPayload() and DecryptFRMPayload(). After encryption (and thus before decryption), the bytes are stored in the DataPayload struct.

err := phyPayload.EncryptFRMPayload(key)
err := phyPayload.DecryptFRMPayload(key)

All payloads implement the Payload interface. Based on the MIC value, you should be able to know to which type to cast the Payload value, so you will be able to access its fields.

See the examples section of the documentation for concrete usage examples of this package.

When using this package, knowledge about the LoRaWAN specification is needed. You can download the LoRaWAN specification here: https://www.lora-alliance.org/For-Developers/LoRaWANDevelopers

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func EncryptFRMPayload

func EncryptFRMPayload(key AES128Key, uplink bool, devAddr DevAddr, fCnt uint32, data []byte) ([]byte, error)

EncryptFRMPayload encrypts the FRMPayload (slice of bytes). Note that EncryptFRMPayload is used for both encryption and decryption.

func RegisterProprietaryMACCommand

func RegisterProprietaryMACCommand(uplink bool, cid CID, payloadSize int) error

RegisterProprietaryMACCommand registers a proprietary MAC command. Note that there is no need to call this when the size of the payload is > 0 bytes.

Types

type AES128Key

type AES128Key [16]byte

AES128Key represents a 128 bit AES key.

func (AES128Key) MarshalText

func (k AES128Key) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

func (*AES128Key) Scan

func (k *AES128Key) Scan(src interface{}) error

Scan implements sql.Scanner.

func (AES128Key) String

func (k AES128Key) String() string

String implements fmt.Stringer.

func (*AES128Key) UnmarshalText

func (k *AES128Key) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler.

type AppNonce

type AppNonce [3]byte

AppNonce represents a 3 byte app-nonce.

func (AppNonce) MarshalText

func (n AppNonce) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

func (AppNonce) String

func (n AppNonce) String() string

String implements fmt.Stringer.

type CFList

type CFList [5]uint32

CFList represents a list of channel frequencies. Each frequency is in Hz and must be multiple of 100, (since the frequency will be divided by 100 on encoding), the max allowed value is 2^24-1 * 100.

func (CFList) MarshalBinary

func (l CFList) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*CFList) UnmarshalBinary

func (l *CFList) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from binary form.

type CID

type CID byte

CID defines the MAC command identifier.

const (
	LinkCheckReq     CID = 0x02
	LinkCheckAns     CID = 0x02
	LinkADRReq       CID = 0x03
	LinkADRAns       CID = 0x03
	DutyCycleReq     CID = 0x04
	DutyCycleAns     CID = 0x04
	RXParamSetupReq  CID = 0x05
	RXParamSetupAns  CID = 0x05
	DevStatusReq     CID = 0x06
	DevStatusAns     CID = 0x06
	NewChannelReq    CID = 0x07
	NewChannelAns    CID = 0x07
	RXTimingSetupReq CID = 0x08
	RXTimingSetupAns CID = 0x08
	TXParamSetupReq  CID = 0x09
	TXParamSetupAns  CID = 0x09
	DLChannelReq     CID = 0x0A
	DLChannelAns     CID = 0x0A
)

MAC commands as specified by the LoRaWAN R1.0 specs. Note that each *Req / *Ans has the same value. Based on the fact if a message is uplink or downlink you should use on or the other.

func (CID) MarshalText

func (c CID) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

func (CID) String

func (i CID) String() string

type ChMask

type ChMask [16]bool

ChMask encodes the channels usable for uplink access. 0 = channel 1, 15 = channel 16.

func (ChMask) MarshalBinary

func (m ChMask) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*ChMask) UnmarshalBinary

func (m *ChMask) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from binary form.

type DLChannelAnsPayload

type DLChannelAnsPayload struct {
	UplinkFrequencyExists bool `json:"uplinkFrequencyExists"`
	ChannelFrequencyOK    bool `json:"channelFrequencyOK"`
}

DLChannelAnsPayload represents the DLChannelAns payload.

func (DLChannelAnsPayload) MarshalBinary

func (p DLChannelAnsPayload) MarshalBinary() ([]byte, error)

MarshalBinary encodes the object into bytes.

func (*DLChannelAnsPayload) UnmarshalBinary

func (p *DLChannelAnsPayload) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from bytes.

type DLChannelReqPayload

type DLChannelReqPayload struct {
	ChIndex uint8  `json:"chIndex"`
	Freq    uint32 `json:"freq"`
}

DLChannelReqPayload represents the DLChannelReq payload.

func (DLChannelReqPayload) MarshalBinary

func (p DLChannelReqPayload) MarshalBinary() ([]byte, error)

MarshalBinary encodes the object into bytes.

func (*DLChannelReqPayload) UnmarshalBinary

func (p *DLChannelReqPayload) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from bytes.

type DLSettings

type DLSettings struct {
	RX2DataRate uint8 `json:"rx2DataRate"`
	RX1DROffset uint8 `json:"rx1DROffset"`
}

DLSettings represents the DLSettings fields (downlink settings).

func (DLSettings) MarshalBinary

func (s DLSettings) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*DLSettings) UnmarshalBinary

func (s *DLSettings) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from binary form.

type DataPayload

type DataPayload struct {
	Bytes []byte `json:"bytes"`
}

DataPayload represents a slice of bytes.

func (DataPayload) MarshalBinary

func (p DataPayload) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*DataPayload) UnmarshalBinary

func (p *DataPayload) UnmarshalBinary(uplink bool, data []byte) error

UnmarshalBinary decodes the object from binary form.

type DevAddr

type DevAddr [4]byte

DevAddr represents the device address.

func (DevAddr) MarshalBinary

func (a DevAddr) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (DevAddr) MarshalText

func (a DevAddr) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

func (DevAddr) NwkID

func (a DevAddr) NwkID() byte

NwkID returns the NwkID bits of the DevAddr.

func (*DevAddr) Scan

func (a *DevAddr) Scan(src interface{}) error

Scan implements sql.Scanner.

func (DevAddr) String

func (a DevAddr) String() string

String implements fmt.Stringer.

func (*DevAddr) UnmarshalBinary

func (a *DevAddr) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from binary form.

func (*DevAddr) UnmarshalText

func (a *DevAddr) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler.

type DevNonce

type DevNonce [2]byte

DevNonce represents a 2 byte dev-nonce.

func (DevNonce) MarshalText

func (n DevNonce) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

func (DevNonce) String

func (n DevNonce) String() string

String implements fmt.Stringer.

type DevStatusAnsPayload

type DevStatusAnsPayload struct {
	Battery uint8 `json:"battery"`
	Margin  int8  `json:"margin"`
}

DevStatusAnsPayload represents the DevStatusAns payload.

func (DevStatusAnsPayload) MarshalBinary

func (p DevStatusAnsPayload) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*DevStatusAnsPayload) UnmarshalBinary

func (p *DevStatusAnsPayload) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from binary form.

type DutyCycleReqPayload

type DutyCycleReqPayload struct {
	MaxDCycle uint8 `json:"maxDCycle"`
}

DutyCycleReqPayload represents the DutyCycleReq payload.

func (DutyCycleReqPayload) MarshalBinary

func (p DutyCycleReqPayload) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*DutyCycleReqPayload) UnmarshalBinary

func (p *DutyCycleReqPayload) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from binary form.

type DwellTime

type DwellTime int

DwellTime defines the dwell time type.

const (
	DwellTimeNoLimit DwellTime = iota
	DwellTime400ms
)

Possible dwell time options.

type EUI64

type EUI64 [8]byte

EUI64 data type

func (EUI64) MarshalBinary

func (e EUI64) MarshalBinary() ([]byte, error)

MarshalBinary implements encoding.BinaryMarshaler.

func (EUI64) MarshalText

func (e EUI64) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

func (*EUI64) Scan

func (e *EUI64) Scan(src interface{}) error

Scan implements sql.Scanner.

func (EUI64) String

func (e EUI64) String() string

String implement fmt.Stringer.

func (*EUI64) UnmarshalBinary

func (e *EUI64) UnmarshalBinary(data []byte) error

UnmarshalBinary implements encoding.BinaryUnmarshaler.

func (*EUI64) UnmarshalText

func (e *EUI64) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler.

type FCtrl

type FCtrl struct {
	ADR       bool `json:"adr"`
	ADRACKReq bool `json:"adrAckReq"`
	ACK       bool `json:"ack"`
	FPending  bool `json:"fPending"` // only used for downlink messages
	// contains filtered or unexported fields
}

FCtrl represents the FCtrl (frame control) field.

func (FCtrl) MarshalBinary

func (c FCtrl) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*FCtrl) UnmarshalBinary

func (c *FCtrl) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from binary form.

type FHDR

type FHDR struct {
	DevAddr DevAddr      `json:"devAddr"`
	FCtrl   FCtrl        `json:"fCtrl"`
	FCnt    uint32       `json:"fCnt"`  // only the least-significant 16 bits will be marshalled
	FOpts   []MACCommand `json:"fOpts"` // max. number of allowed bytes is 15
}

FHDR represents the frame header.

func (FHDR) MarshalBinary

func (h FHDR) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*FHDR) UnmarshalBinary

func (h *FHDR) UnmarshalBinary(uplink bool, data []byte) error

UnmarshalBinary decodes the object from binary form.

type JoinAcceptPayload

type JoinAcceptPayload struct {
	AppNonce   AppNonce   `json:"appNonce"`
	NetID      NetID      `json:"netID"`
	DevAddr    DevAddr    `json:"devAddr"`
	DLSettings DLSettings `json:"dlSettings"`
	RXDelay    uint8      `json:"rxDelay"` // 0=1s, 1=1s, 2=2s, ... 15=15s
	CFList     *CFList    `json:"cFlist"`
}

JoinAcceptPayload represents the join-accept message payload.

func (JoinAcceptPayload) MarshalBinary

func (p JoinAcceptPayload) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*JoinAcceptPayload) UnmarshalBinary

func (p *JoinAcceptPayload) UnmarshalBinary(uplink bool, data []byte) error

UnmarshalBinary decodes the object from binary form.

type JoinRequestPayload

type JoinRequestPayload struct {
	AppEUI   EUI64    `json:"appEUI"`
	DevEUI   EUI64    `json:"devEUI"`
	DevNonce DevNonce `json:"devNonce"`
}

JoinRequestPayload represents the join-request message payload.

func (JoinRequestPayload) MarshalBinary

func (p JoinRequestPayload) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*JoinRequestPayload) UnmarshalBinary

func (p *JoinRequestPayload) UnmarshalBinary(uplink bool, data []byte) error

UnmarshalBinary decodes the object from binary form.

type LinkADRAnsPayload

type LinkADRAnsPayload struct {
	ChannelMaskACK bool `json:"channelMaskAck"`
	DataRateACK    bool `json:"dataRateAck"`
	PowerACK       bool `json:"powerAck"`
}

LinkADRAnsPayload represents the LinkADRAns payload.

func (LinkADRAnsPayload) MarshalBinary

func (p LinkADRAnsPayload) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*LinkADRAnsPayload) UnmarshalBinary

func (p *LinkADRAnsPayload) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from binary form.

type LinkADRReqPayload

type LinkADRReqPayload struct {
	DataRate   uint8      `json:"dataRate"`
	TXPower    uint8      `json:"txPower"`
	ChMask     ChMask     `json:"chMask"`
	Redundancy Redundancy `json:"redundancy"`
}

LinkADRReqPayload represents the LinkADRReq payload.

func (LinkADRReqPayload) MarshalBinary

func (p LinkADRReqPayload) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*LinkADRReqPayload) UnmarshalBinary

func (p *LinkADRReqPayload) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from binary form.

type LinkCheckAnsPayload

type LinkCheckAnsPayload struct {
	Margin uint8 `json:"margin"`
	GwCnt  uint8 `json:"gwCnt"`
}

LinkCheckAnsPayload represents the LinkCheckAns payload.

func (LinkCheckAnsPayload) MarshalBinary

func (p LinkCheckAnsPayload) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*LinkCheckAnsPayload) UnmarshalBinary

func (p *LinkCheckAnsPayload) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from binary form.

type MACCommand

type MACCommand struct {
	CID     CID               `json:"cid"`
	Payload MACCommandPayload `json:"payload"`
}

MACCommand represents a MAC command with optional payload.

func (MACCommand) MarshalBinary

func (m MACCommand) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*MACCommand) UnmarshalBinary

func (m *MACCommand) UnmarshalBinary(uplink bool, data []byte) error

UnmarshalBinary decodes the object from binary form.

type MACCommandPayload

type MACCommandPayload interface {
	MarshalBinary() (data []byte, err error)
	UnmarshalBinary(data []byte) error
}

MACCommandPayload is the interface that every MACCommand payload must implement.

func GetMACPayloadAndSize

func GetMACPayloadAndSize(uplink bool, c CID) (MACCommandPayload, int, error)

GetMACPayloadAndSize returns a new MACCommandPayload instance and it's size.

type MACPayload

type MACPayload struct {
	FHDR       FHDR      `json:"fhdr"`
	FPort      *uint8    `json:"fPort"` // optional, but must be set when FRMPayload is set
	FRMPayload []Payload `json:"frmPayload"`
}

MACPayload represents the MAC payload. Use NewMACPayload for creating a new MACPayload.

func (MACPayload) MarshalBinary

func (p MACPayload) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*MACPayload) UnmarshalBinary

func (p *MACPayload) UnmarshalBinary(uplink bool, data []byte) error

UnmarshalBinary decodes the object from binary form.

type MHDR

type MHDR struct {
	MType MType `json:"mType"`
	Major Major `json:"major"`
}

MHDR represents the MAC header.

func (MHDR) MarshalBinary

func (h MHDR) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*MHDR) UnmarshalBinary

func (h *MHDR) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from binary form.

type MIC

type MIC [4]byte

MIC represents the message integrity code.

func (MIC) MarshalText

func (m MIC) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

func (MIC) String

func (m MIC) String() string

String implements fmt.Stringer.

type MType

type MType byte

MType represents the message type.

const (
	JoinRequest MType = iota
	JoinAccept
	UnconfirmedDataUp
	UnconfirmedDataDown
	ConfirmedDataUp
	ConfirmedDataDown
	RFU
	Proprietary
)

Supported message types (MType)

func (MType) MarshalText

func (m MType) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

func (MType) String

func (i MType) String() string

type Major

type Major byte

Major defines the major version of data message.

const (
	LoRaWANR1 Major = 0
)

Supported major versions

func (Major) MarshalText

func (m Major) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

func (Major) String

func (i Major) String() string

type NetID

type NetID [3]byte

NetID represents the NetID.

func (NetID) MarshalText

func (n NetID) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

func (NetID) NwkID

func (n NetID) NwkID() byte

NwkID returns the NwkID bits of the NetID.

func (NetID) String

func (n NetID) String() string

String implements fmt.Stringer.

func (*NetID) UnmarshalText

func (n *NetID) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler.

type NewChannelAnsPayload

type NewChannelAnsPayload struct {
	ChannelFrequencyOK bool `json:"channelFrequencyOK"`
	DataRateRangeOK    bool `json:"dataRateRangeOK"`
}

NewChannelAnsPayload represents the NewChannelAns payload.

func (NewChannelAnsPayload) MarshalBinary

func (p NewChannelAnsPayload) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*NewChannelAnsPayload) UnmarshalBinary

func (p *NewChannelAnsPayload) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from binary form.

type NewChannelReqPayload

type NewChannelReqPayload struct {
	ChIndex uint8  `json:"chIndex"`
	Freq    uint32 `json:"freq"`
	MaxDR   uint8  `json:"maxDR"`
	MinDR   uint8  `json:"minDR"`
}

NewChannelReqPayload represents the NewChannelReq payload.

func (NewChannelReqPayload) MarshalBinary

func (p NewChannelReqPayload) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*NewChannelReqPayload) UnmarshalBinary

func (p *NewChannelReqPayload) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from binary form.

type PHYPayload

type PHYPayload struct {
	MHDR       MHDR    `json:"mhdr"`
	MACPayload Payload `json:"macPayload"`
	MIC        MIC     `json:"mic"`
}

PHYPayload represents the physical payload.

Example (Decode)
nwkSKey := [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
appSKey := [16]byte{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}

var phy PHYPayload
// use use UnmarshalBinary when decoding a byte-slice
if err := phy.UnmarshalText([]byte("gAQDAgEAAAAK4mTU97VqDnU=")); err != nil {
	panic(err)
}

ok, err := phy.ValidateMIC(nwkSKey)
if err != nil {
	panic(err)
}
if !ok {
	panic("invalid mic")
}

phyJSON, err := phy.MarshalJSON()
if err != nil {
	panic(err)
}

if err := phy.DecryptFRMPayload(appSKey); err != nil {
	panic(err)
}
macPL, ok := phy.MACPayload.(*MACPayload)
if !ok {
	panic("*MACPayload expected")
}

pl, ok := macPL.FRMPayload[0].(*DataPayload)
if !ok {
	panic("*DataPayload expected")
}

fmt.Println(string(phyJSON))
fmt.Println(pl.Bytes)
Output:

{"mhdr":{"mType":"ConfirmedDataUp","major":"LoRaWANR1"},"macPayload":{"fhdr":{"devAddr":"01020304","fCtrl":{"adr":false,"adrAckReq":false,"ack":false,"fPending":false},"fCnt":0,"fOpts":null},"fPort":10,"frmPayload":[{"bytes":"4mTU9w=="}]},"mic":"b56a0e75"}
[1 2 3 4]
Example (Encode)
nwkSKey := [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
appSKey := [16]byte{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}
fPort := uint8(10)

phy := PHYPayload{
	MHDR: MHDR{
		MType: ConfirmedDataUp,
		Major: LoRaWANR1,
	},
	MACPayload: &MACPayload{
		FHDR: FHDR{
			DevAddr: DevAddr([4]byte{1, 2, 3, 4}),
			FCtrl: FCtrl{
				ADR:       false,
				ADRACKReq: false,
				ACK:       false,
			},
			FCnt:  0,
			FOpts: []MACCommand{}, // you can leave this out when there is no MAC command to send
		},
		FPort:      &fPort,
		FRMPayload: []Payload{&DataPayload{Bytes: []byte{1, 2, 3, 4}}},
	},
}

if err := phy.EncryptFRMPayload(appSKey); err != nil {
	panic(err)
}

if err := phy.SetMIC(nwkSKey); err != nil {
	panic(err)
}

str, err := phy.MarshalText()
if err != nil {
	panic(err)
}

bytes, err := phy.MarshalBinary()
if err != nil {
	panic(err)
}

phyJSON, err := phy.MarshalJSON()
if err != nil {
	panic(err)
}

fmt.Println(string(str))
fmt.Println(bytes)
fmt.Println(string(phyJSON))
Output:

gAQDAgEAAAAK4mTU97VqDnU=
[128 4 3 2 1 0 0 0 10 226 100 212 247 181 106 14 117]
{"mhdr":{"mType":"ConfirmedDataUp","major":"LoRaWANR1"},"macPayload":{"fhdr":{"devAddr":"01020304","fCtrl":{"adr":false,"adrAckReq":false,"ack":false,"fPending":false},"fCnt":0,"fOpts":[]},"fPort":10,"frmPayload":[{"bytes":"4mTU9w=="}]},"mic":"b56a0e75"}
Example (JoinAcceptSend)
appKey := [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}

phy := PHYPayload{
	MHDR: MHDR{
		MType: JoinAccept,
		Major: LoRaWANR1,
	},
	MACPayload: &JoinAcceptPayload{
		AppNonce:   [3]byte{1, 1, 1},
		NetID:      [3]byte{2, 2, 2},
		DevAddr:    DevAddr([4]byte{1, 2, 3, 4}),
		DLSettings: DLSettings{RX2DataRate: 0, RX1DROffset: 0},
		RXDelay:    0,
	},
}

// set the MIC before encryption
if err := phy.SetMIC(appKey); err != nil {
	panic(err)
}
if err := phy.EncryptJoinAcceptPayload(appKey); err != nil {
	panic(err)
}

str, err := phy.MarshalText()
if err != nil {
	panic(err)
}

bytes, err := phy.MarshalBinary()
if err != nil {
	panic(err)
}

fmt.Println(string(str))
fmt.Println(bytes)
Output:

ICPPM1SJquMYPAvguqje5fM=
[32 35 207 51 84 137 170 227 24 60 11 224 186 168 222 229 243]
Example (JoinRequest)
appKey := [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}

phy := PHYPayload{
	MHDR: MHDR{
		MType: JoinRequest,
		Major: LoRaWANR1,
	},
	MACPayload: &JoinRequestPayload{
		AppEUI:   [8]byte{1, 1, 1, 1, 1, 1, 1, 1},
		DevEUI:   [8]byte{2, 2, 2, 2, 2, 2, 2, 2},
		DevNonce: [2]byte{3, 3},
	},
}

if err := phy.SetMIC(appKey); err != nil {
	panic(err)
}

str, err := phy.MarshalText()
if err != nil {
	panic(err)
}

bytes, err := phy.MarshalBinary()
if err != nil {
	panic(err)
}

fmt.Println(string(str))
fmt.Println(bytes)
Output:

AAEBAQEBAQEBAgICAgICAgIDAwm5ezI=
[0 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 9 185 123 50]
Example (ReadJoinRequest)
var phy PHYPayload
if err := phy.UnmarshalText([]byte("AAQDAgEEAwIBBQQDAgUEAwItEGqZDhI=")); err != nil {
	panic(err)
}

jrPL, ok := phy.MACPayload.(*JoinRequestPayload)
if !ok {
	panic("MACPayload must be a *JoinRequestPayload")
}

fmt.Println(phy.MHDR.MType)
fmt.Println(jrPL.AppEUI)
fmt.Println(jrPL.DevEUI)
fmt.Println(jrPL.DevNonce)
Output:

JoinRequest
0102030401020304
0203040502030405
102d

func (*PHYPayload) DecodeFRMPayloadToMACCommands

func (p *PHYPayload) DecodeFRMPayloadToMACCommands() error

DecodeFRMPayloadToMACCommands decodes the (decrypted) FRMPayload bytes into MAC commands. Note that after calling DecryptFRMPayload, this method is called automatically when FPort=0. Use this method when unmarshaling a decrypted FRMPayload from a slice of bytes and this when DecryptFRMPayload is not called.

func (*PHYPayload) DecryptFRMPayload

func (p *PHYPayload) DecryptFRMPayload(key AES128Key) error

DecryptFRMPayload decrypts the FRMPayload with the given key.

func (*PHYPayload) DecryptJoinAcceptPayload

func (p *PHYPayload) DecryptJoinAcceptPayload(appKey AES128Key) error

DecryptJoinAcceptPayload decrypts the join-accept payload with the given AppKey. Note that you need to decrypte before you can validate the MIC.

func (*PHYPayload) EncryptFRMPayload

func (p *PHYPayload) EncryptFRMPayload(key AES128Key) error

EncryptFRMPayload encrypts the FRMPayload with the given key.

func (*PHYPayload) EncryptJoinAcceptPayload

func (p *PHYPayload) EncryptJoinAcceptPayload(appKey AES128Key) error

EncryptJoinAcceptPayload encrypts the join-accept payload with the given AppKey. Note that encrypted must be performed after calling SetMIC (sicne the MIC is part of the encrypted payload).

func (PHYPayload) MarshalBinary

func (p PHYPayload) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (PHYPayload) MarshalJSON

func (p PHYPayload) MarshalJSON() ([]byte, error)

MarshalJSON encodes the PHYPayload into JSON.

func (PHYPayload) MarshalText

func (p PHYPayload) MarshalText() ([]byte, error)

MarshalText encodes the PHYPayload into base64.

func (*PHYPayload) SetMIC

func (p *PHYPayload) SetMIC(key AES128Key) error

SetMIC calculates and sets the MIC field.

func (*PHYPayload) UnmarshalBinary

func (p *PHYPayload) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from binary form.

func (*PHYPayload) UnmarshalText

func (p *PHYPayload) UnmarshalText(text []byte) error

UnmarshalText decodes the PHYPayload from base64.

func (PHYPayload) ValidateMIC

func (p PHYPayload) ValidateMIC(key AES128Key) (bool, error)

ValidateMIC returns if the MIC is valid. When using 32 bit frame counters, only the least-signification 16 bits are sent / received. In order to validate the MIC, the receiver needs to set the FCnt to the full 32 bit value (based on the observation of the traffic). See section '4.3.1.5 Frame counter (FCnt)' of the LoRaWAN 1.0 specification for more details.

type Payload

type Payload interface {
	MarshalBinary() (data []byte, err error)
	UnmarshalBinary(uplink bool, data []byte) error
}

Payload is the interface that every payload needs to implement. Since it might be a MACPayload, an indication must be given if the direction is uplink or downlink (it has different payloads for the same CID, based on direction).

type ProprietaryMACCommandPayload

type ProprietaryMACCommandPayload struct {
	Bytes []byte `json:"bytes"`
}

ProprietaryMACCommandPayload represents a proprietary payload.

func (ProprietaryMACCommandPayload) MarshalBinary

func (p ProprietaryMACCommandPayload) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object into a slice of bytes.

func (*ProprietaryMACCommandPayload) UnmarshalBinary

func (p *ProprietaryMACCommandPayload) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from a slice of bytes.

type RX2SetupAnsPayload

type RX2SetupAnsPayload struct {
	ChannelACK     bool `json:"channelAck"`
	RX2DataRateACK bool `json:"rx2DataRateAck"`
	RX1DROffsetACK bool `json:"rx1DROffsetAck"`
}

RX2SetupAnsPayload represents the RX2SetupAns payload.

func (RX2SetupAnsPayload) MarshalBinary

func (p RX2SetupAnsPayload) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*RX2SetupAnsPayload) UnmarshalBinary

func (p *RX2SetupAnsPayload) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from binary form.

type RX2SetupReqPayload

type RX2SetupReqPayload struct {
	Frequency  uint32     `json:"frequency"`
	DLSettings DLSettings `json:"dlSettings"`
}

RX2SetupReqPayload represents the RX2SetupReq payload.

func (RX2SetupReqPayload) MarshalBinary

func (p RX2SetupReqPayload) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*RX2SetupReqPayload) UnmarshalBinary

func (p *RX2SetupReqPayload) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from binary form.

type RXTimingSetupReqPayload

type RXTimingSetupReqPayload struct {
	Delay uint8 `json:"delay"` // 0=1s, 1=1s, 2=2s, ... 15=15s
}

RXTimingSetupReqPayload represents the RXTimingSetupReq payload.

func (RXTimingSetupReqPayload) MarshalBinary

func (p RXTimingSetupReqPayload) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*RXTimingSetupReqPayload) UnmarshalBinary

func (p *RXTimingSetupReqPayload) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from binary form.

type Redundancy

type Redundancy struct {
	ChMaskCntl uint8 `json:"chMaskCntl"`
	NbRep      uint8 `json:"nbRep"`
}

Redundancy represents the redundancy field.

func (Redundancy) MarshalBinary

func (r Redundancy) MarshalBinary() ([]byte, error)

MarshalBinary marshals the object in binary form.

func (*Redundancy) UnmarshalBinary

func (r *Redundancy) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from binary form.

type TXParamSetupReqPayload

type TXParamSetupReqPayload struct {
	DownlinkDwelltime DwellTime `json:"downlinkDwellTime"`
	UplinkDwellTime   DwellTime `json:"uplinkDwellTime"`
	MaxEIRP           uint8     `json:"maxEIRP"`
}

TXParamSetupReqPayload represents the TXParamSetupReq payload.

func (TXParamSetupReqPayload) MarshalBinary

func (p TXParamSetupReqPayload) MarshalBinary() ([]byte, error)

MarshalBinary encodes the object into a bytes.

func (*TXParamSetupReqPayload) UnmarshalBinary

func (p *TXParamSetupReqPayload) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the object from bytes.

Directories

Path Synopsis
Package band provides band specific defaults and configuration for downlink communication with end-nodes.
Package band provides band specific defaults and configuration for downlink communication with end-nodes.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL