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