lihua
5 years ago
4 changed files with 362 additions and 422 deletions
@ -1,107 +0,0 @@ |
|||
package model |
|||
|
|||
import ( |
|||
"github.com/lxn/walk" |
|||
"sort" |
|||
) |
|||
|
|||
type DTUDown struct { |
|||
Index int |
|||
DevEUI string |
|||
MType string |
|||
DevAddr string |
|||
GatewayID string |
|||
FCnt uint32 |
|||
FPort uint8 |
|||
HexData string |
|||
AsciiData string |
|||
Time string |
|||
checked bool |
|||
OrigData string |
|||
} |
|||
|
|||
type DTUDownModel struct { |
|||
walk.TableModelBase |
|||
walk.SorterBase |
|||
SortColumn int |
|||
SortOrder walk.SortOrder |
|||
Items []*DTUDown |
|||
} |
|||
|
|||
func (m *DTUDownModel) RowCount() int { |
|||
return len(m.Items) |
|||
} |
|||
|
|||
func (m *DTUDownModel) Value(row, col int) interface{} { |
|||
item := m.Items[row] |
|||
|
|||
switch col { |
|||
case 0: |
|||
return item.Index |
|||
case 1: |
|||
return item.DevEUI |
|||
case 2: |
|||
return item.MType |
|||
case 3: |
|||
return item.DevAddr |
|||
case 4: |
|||
return item.GatewayID |
|||
case 5: |
|||
return item.FCnt |
|||
case 6: |
|||
return item.FPort |
|||
case 7: |
|||
return item.HexData |
|||
case 8: |
|||
return item.AsciiData |
|||
case 9: |
|||
return item.Time |
|||
} |
|||
panic("unexpected col") |
|||
} |
|||
|
|||
func (m *DTUDownModel) Checked(row int) bool { |
|||
return m.Items[row].checked |
|||
} |
|||
|
|||
func (m *DTUDownModel) SetChecked(row int, checked bool) error { |
|||
m.Items[row].checked = checked |
|||
return nil |
|||
} |
|||
|
|||
func (m *DTUDownModel) Sort(col int, order walk.SortOrder) error { |
|||
m.SortColumn, m.SortOrder = col, order |
|||
sort.Stable(m) |
|||
return m.SorterBase.Sort(col, order) |
|||
} |
|||
|
|||
func (m *DTUDownModel) Len() int { |
|||
return len(m.Items) |
|||
} |
|||
|
|||
func (m *DTUDownModel) Less(i, j int) bool { |
|||
a, b := m.Items[i], m.Items[j] |
|||
c := func(ls bool) bool { |
|||
if m.SortOrder == walk.SortAscending { |
|||
return ls |
|||
} |
|||
return !ls |
|||
} |
|||
|
|||
switch m.SortColumn { |
|||
case 0: |
|||
return c(a.Index < b.Index) |
|||
case 2: |
|||
return c(a.DevEUI < b.DevEUI) |
|||
default: |
|||
return false |
|||
} |
|||
} |
|||
|
|||
func (m *DTUDownModel) Swap(i, j int) { |
|||
m.Items[i], m.Items[j] = m.Items[j], m.Items[i] |
|||
} |
|||
|
|||
func NewDTUDownModel() *DTUDownModel { |
|||
return new(DTUDownModel) |
|||
} |
@ -0,0 +1,261 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"LoRaDTUMock/packets" |
|||
"crypto/aes" |
|||
"crypto/tls" |
|||
"crypto/x509" |
|||
"fmt" |
|||
"github.com/brocaar/lorawan" |
|||
"github.com/pkg/errors" |
|||
"io/ioutil" |
|||
"math/rand" |
|||
"syscall" |
|||
"time" |
|||
) |
|||
|
|||
func BytesToString(b []byte) string { |
|||
_,err := syscall.UTF16FromString(string(b)) |
|||
if err == nil { |
|||
return string(b) |
|||
} |
|||
return "" |
|||
} |
|||
|
|||
func newTLSConfig(cafile, certFile, certKeyFile string) (*tls.Config, error) { |
|||
if cafile == "" && certFile == "" && certKeyFile == "" { |
|||
return nil, nil |
|||
} |
|||
|
|||
tlsConfig := &tls.Config{} |
|||
|
|||
// Import trusted certificates from CAfile.pem.
|
|||
if cafile != "" { |
|||
cacert, err := ioutil.ReadFile(cafile) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
certpool := x509.NewCertPool() |
|||
certpool.AppendCertsFromPEM(cacert) |
|||
|
|||
tlsConfig.RootCAs = certpool // RootCAs = certs used to verify server cert.
|
|||
} |
|||
|
|||
// Import certificate and the key
|
|||
if certFile != "" && certKeyFile != "" { |
|||
kp, err := tls.LoadX509KeyPair(certFile, certKeyFile) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
tlsConfig.Certificates = []tls.Certificate{kp} |
|||
} |
|||
|
|||
return tlsConfig, nil |
|||
} |
|||
|
|||
func BuildUpData(gatewayId,devAddr,nwkSKey string, |
|||
fCnt uint32,fPort,dr,ch uint8,freq,lsnr float64, |
|||
mType lorawan.MType,fCtrl lorawan.FCtrl,rssi int16, |
|||
userData []byte) (*packets.PushDataPacket,*lorawan.PHYPayload,error) { |
|||
var gatewayMac lorawan.EUI64 |
|||
if err := gatewayMac.UnmarshalText([]byte(gatewayId)); err != nil { |
|||
return nil,nil,err |
|||
} |
|||
now := time.Now().Round(time.Second) |
|||
compactTS := packets.CompactTime(now) |
|||
tmms := int64(time.Second / time.Millisecond) |
|||
|
|||
var phy lorawan.PHYPayload |
|||
phy.MHDR.MType = mType |
|||
phy.MHDR.Major = lorawan.LoRaWANR1 |
|||
var mac lorawan.MACPayload |
|||
if err := mac.FHDR.DevAddr.UnmarshalText([]byte(devAddr)); err != nil { |
|||
return nil,nil,err |
|||
} |
|||
mac.FHDR.FCtrl = fCtrl |
|||
mac.FHDR.FCnt = fCnt |
|||
mac.FPort = &fPort |
|||
var dataPayload lorawan.DataPayload |
|||
if err := dataPayload.UnmarshalBinary(true, userData); err != nil { |
|||
return nil,nil,err |
|||
} |
|||
mac.FRMPayload = []lorawan.Payload{&dataPayload} |
|||
phy.MACPayload = &mac |
|||
var aseKey lorawan.AES128Key |
|||
if err := aseKey.UnmarshalText([]byte(nwkSKey));err != nil { |
|||
return nil,nil,err |
|||
} |
|||
if err := phy.EncryptFRMPayload(aseKey);err != nil { |
|||
return nil,nil,err |
|||
} |
|||
sf :=[...]string{"SF12","SF11","SF10","SF9","SF8","SF7"} |
|||
if err := phy.SetUplinkDataMIC(lorawan.LoRaWAN1_0, 0, dr, ch, aseKey, aseKey);err != nil { |
|||
return nil,nil,err |
|||
} |
|||
data,err := phy.MarshalBinary(); |
|||
if err != nil { |
|||
return nil,nil,err |
|||
} |
|||
|
|||
return &packets.PushDataPacket{ |
|||
ProtocolVersion: packets.ProtocolVersion2, |
|||
RandomToken: uint16(rand.Uint32()), |
|||
GatewayMAC: gatewayMac, |
|||
Payload: packets.PushDataPayload{ |
|||
RXPK: []packets.RXPK{ |
|||
{ |
|||
Time: &compactTS, |
|||
Tmst: 708016819, |
|||
Tmms: &tmms, |
|||
Freq: freq, |
|||
Chan: ch, |
|||
RFCh: 1, |
|||
Stat: 1, |
|||
Modu: "LORA", |
|||
DatR: packets.DatR{LoRa: sf[dr]+"BW125"}, |
|||
CodR: "4/5", |
|||
RSSI: rssi, |
|||
LSNR: lsnr, |
|||
Size: uint16(len(data)), |
|||
Data: data, |
|||
}, |
|||
}, |
|||
}, |
|||
},&phy,nil |
|||
} |
|||
|
|||
|
|||
func BuildJoin(gatewayId,appEui,devEui,appKey string,dr,ch uint8, |
|||
freq,lsnr float64,rssi int16,devNonce lorawan.DevNonce) (*packets.PushDataPacket,*lorawan.PHYPayload,error) { |
|||
if dr > 5 || dr < 0 { |
|||
return nil,nil,errors.New("dr exceed limit") |
|||
} |
|||
var gatewayMac lorawan.EUI64 |
|||
if err := gatewayMac.UnmarshalText([]byte(gatewayId));err != nil{ |
|||
return nil,nil,err |
|||
} |
|||
now := time.Now().Round(time.Second) |
|||
compactTS := packets.CompactTime(now) |
|||
tmms := int64(time.Second / time.Millisecond) |
|||
|
|||
var phy lorawan.PHYPayload |
|||
phy.MHDR.MType = lorawan.JoinRequest |
|||
phy.MHDR.Major = lorawan.LoRaWANR1 |
|||
var DevEUI lorawan.EUI64 |
|||
if err := DevEUI.UnmarshalText([]byte(devEui));err != nil{ |
|||
return nil,nil,err |
|||
} |
|||
var joinEUI lorawan.EUI64 |
|||
if err := joinEUI.UnmarshalText([]byte(appEui));err != nil{ |
|||
return nil,nil,err |
|||
} |
|||
phy.MACPayload = &lorawan.JoinRequestPayload{ |
|||
DevEUI: DevEUI, |
|||
JoinEUI: joinEUI, |
|||
DevNonce: devNonce, |
|||
} |
|||
var aseKey lorawan.AES128Key |
|||
if err := aseKey.UnmarshalText([]byte(appKey));err != nil{ |
|||
return nil,nil,err |
|||
} |
|||
sf :=[...]string{"SF12","SF11","SF10","SF9","SF8","SF7"} |
|||
if err := phy.SetUplinkJoinMIC(aseKey);err != nil{ |
|||
return nil,nil,err |
|||
} |
|||
data,err := phy.MarshalBinary() |
|||
if err != nil { |
|||
return nil,nil,err |
|||
} |
|||
return &packets.PushDataPacket{ |
|||
ProtocolVersion: packets.ProtocolVersion2, |
|||
RandomToken: uint16(rand.Uint32()), |
|||
GatewayMAC: gatewayMac, |
|||
Payload: packets.PushDataPayload{ |
|||
RXPK: []packets.RXPK{ |
|||
{ |
|||
Time: &compactTS, |
|||
Tmst: 708016819, |
|||
Tmms: &tmms, |
|||
Freq: freq, |
|||
Chan: ch, |
|||
RFCh: 1, |
|||
Stat: 1, |
|||
Modu: "LORA", |
|||
DatR: packets.DatR{LoRa: sf[dr]+"BW125"}, |
|||
CodR: "4/5", |
|||
RSSI: rssi, |
|||
LSNR: lsnr, |
|||
Size: uint16(len(data)), |
|||
Data: data, |
|||
}, |
|||
}, |
|||
}, |
|||
},&phy,nil |
|||
} |
|||
|
|||
// getNwkSKey returns the network session key.
|
|||
func getNwkSKey(appkey lorawan.AES128Key, netID lorawan.NetID, joinNonce lorawan.JoinNonce, devNonce lorawan.DevNonce) (lorawan.AES128Key, error) { |
|||
return getSKey(0x01, appkey, netID, joinNonce, devNonce) |
|||
} |
|||
|
|||
// getAppSKey returns the application session key.
|
|||
func getAppSKey(appkey lorawan.AES128Key, netID lorawan.NetID, joinNonce lorawan.JoinNonce, devNonce lorawan.DevNonce) (lorawan.AES128Key, error) { |
|||
return getSKey(0x02, appkey, netID, joinNonce, devNonce) |
|||
} |
|||
|
|||
func getSKey(typ byte, nwkKey lorawan.AES128Key, netID lorawan.NetID,joinNonce lorawan.JoinNonce, devNonce lorawan.DevNonce) (lorawan.AES128Key, error) { |
|||
var key lorawan.AES128Key |
|||
b := make([]byte, 16) |
|||
b[0] = typ |
|||
|
|||
netIDB, err := netID.MarshalBinary() |
|||
if err != nil { |
|||
return key, errors.Wrap(err, "marshal binary error") |
|||
} |
|||
|
|||
joinNonceB, err := joinNonce.MarshalBinary() |
|||
if err != nil { |
|||
return key, errors.Wrap(err, "marshal binary error") |
|||
} |
|||
|
|||
devNonceB, err := devNonce.MarshalBinary() |
|||
if err != nil { |
|||
return key, errors.Wrap(err, "marshal binary error") |
|||
} |
|||
|
|||
copy(b[1:4], joinNonceB) |
|||
copy(b[4:7], netIDB) |
|||
copy(b[7:9], devNonceB) |
|||
|
|||
block, err := aes.NewCipher(nwkKey[:]) |
|||
if err != nil { |
|||
return key, err |
|||
} |
|||
if block.BlockSize() != len(b) { |
|||
return key, fmt.Errorf("block-size of %d bytes is expected", len(b)) |
|||
} |
|||
block.Encrypt(key[:], b) |
|||
|
|||
return key, nil |
|||
} |
|||
|
|||
func MarshalFRMPayload(p *lorawan.MACPayload) ([]byte, error) { |
|||
var out []byte |
|||
var b []byte |
|||
var err error |
|||
for _, fp := range p.FRMPayload { |
|||
if mac, ok := fp.(*lorawan.MACCommand); ok { |
|||
if p.FPort == nil || (p.FPort != nil && *p.FPort != 0) { |
|||
return []byte{}, errors.New("lorawan: a MAC command is only allowed when FPort=0") |
|||
} |
|||
b, err = mac.MarshalBinary() |
|||
} else { |
|||
b, err = fp.MarshalBinary() |
|||
} |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
out = append(out, b...) |
|||
} |
|||
return out, nil |
|||
} |
Loading…
Reference in new issue