Skip to content

Commit

Permalink
v3 test compatibility. Remove unnecessary message, rx and dr structs.
Browse files Browse the repository at this point in the history
  • Loading branch information
iegomez committed May 15, 2019
1 parent b1fabf4 commit 6ca28d8
Show file tree
Hide file tree
Showing 11 changed files with 653 additions and 144 deletions.
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
## Loraserver device simulator

This is an utility program to simulate devices for the [loraserver](https://loraserver.io) project. Basically, it acts as a `lora-gateway-bridge` middleman, publishing and receiving messages through MQTT.
It supports all bands and configurations LoRaWAN versions 1.0 and 1.1.
It supports all bands and configurations LoRaWAN versions 1.0 and 1.1 and is compatible with newest version of `loraserver` modules (v3 test).

It has a simple but complete GUI built with [imgui-go](https://github.com/inkyblackness/imgui-go) and OpenGL 3.2, that allows to configure everything that's needed, such as MQTT broker and credentials, device keys, LoRaWAN version, message marshaling method, data payload, etc.

**Important**: This is a work in progress: the `cli` mode needs to be rewritten (it doesn't work right now) and there may be bugs in the `gui` version. Please report any by filing and issue.
Please report any bug or request new features by filing and issue.

![](images/new-gui.png?raw=true)

Expand All @@ -25,6 +25,10 @@ log_level = "info"
server = "tcp://localhost:1883"
user = "username"
password = "password"
# Uplink topic. %s will be replaced with the gateway mac.
uplink_topic="gateway/%s/event/up"
# Downlink topic. %s will be replaced with the gateway mac.
downlink_topic="gateway/%s/command/down"

[gateway]
mac = "b827ebfffe9448d0"
Expand Down Expand Up @@ -99,6 +103,10 @@ log_level = "info"
addr = "localhost:6379"
password = ""
db = 10

[window]
width = 1200
height = 1000
```
You may also import files located at `working-dir/confs` and save to the same directory.

Expand Down
2 changes: 1 addition & 1 deletion data.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func beginScript() {
imgui.OpenPopup("JS encoder")
openScript = false
}
imgui.SetNextWindowPos(imgui.Vec2{X: (float32(windowWidth) / 2) - 370.0, Y: (float32(windowHeight) / 2) - 200.0})
imgui.SetNextWindowPos(imgui.Vec2{X: (float32(config.Window.Width) / 2) - 370.0, Y: (float32(config.Window.Height) / 2) - 200.0})
imgui.SetNextWindowSize(imgui.Vec2{X: 740, Y: 600})
if imgui.BeginPopupModal("JS encoder") {
imgui.Text(`If "Use encoder" is checked, you may write a function that accepts a JS object`)
Expand Down
119 changes: 63 additions & 56 deletions device.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import (
"fmt"
"time"

"strconv"

lwBand "github.com/brocaar/lorawan/band"

"github.com/brocaar/loraserver/api/gw"
"github.com/brocaar/lorawan"
"github.com/golang/protobuf/ptypes"
"github.com/iegomez/lds/lds"
"github.com/inkyblackness/imgui-go"
log "github.com/sirupsen/logrus"
"strconv"
)

var ulFcntEdit int
Expand Down Expand Up @@ -60,6 +63,7 @@ func beginDeviceForm() {
for _, marshaler := range marshalers {
if imgui.SelectableV(marshaler, marshaler == config.Device.Marshaler, 0, imgui.Vec2{}) {
config.Device.Marshaler = marshaler
cDevice.SetMarshaler(config.Device.Marshaler)
}
}
imgui.EndCombo()
Expand Down Expand Up @@ -230,7 +234,7 @@ func beginReset() {
imgui.OpenPopup("Reset device")
resetDevice = false
}
imgui.SetNextWindowPos(imgui.Vec2{X: float32(windowWidth-190) / 2, Y: float32(windowHeight-90) / 2})
imgui.SetNextWindowPos(imgui.Vec2{X: float32(config.Window.Width-190) / 2, Y: float32(config.Window.Height-90) / 2})
imgui.SetNextWindowSize(imgui.Vec2{X: 380, Y: 180})
imgui.PushItemWidth(250.0)
if imgui.BeginPopupModal("Reset device") {
Expand Down Expand Up @@ -267,7 +271,7 @@ func beginRedisValues() {
imgui.OpenPopup("Set counters and nonces")
setRedisValues = false
}
imgui.SetNextWindowPos(imgui.Vec2{X: float32(windowWidth-170) / 2, Y: float32(windowHeight-70) / 2})
imgui.SetNextWindowPos(imgui.Vec2{X: float32(config.Window.Width-170) / 2, Y: float32(config.Window.Height-70) / 2})
imgui.SetNextWindowSize(imgui.Vec2{X: 420, Y: 220})
imgui.PushItemWidth(250.0)
if imgui.BeginPopupModal("Set counters and nonces") {
Expand Down Expand Up @@ -309,34 +313,48 @@ func join() {
//Always set device to get any changes to the configuration.
setDevice()

dataRate := &lds.DataRate{
Bandwidth: config.DR.Bandwith,
Modulation: "LORA",
SpreadFactor: config.DR.SpreadFactor,
BitRate: config.DR.BitRate,
}

rxInfo := &lds.RxInfo{
Channel: config.RXInfo.Channel,
CodeRate: config.RXInfo.CodeRate,
CrcStatus: config.RXInfo.CrcStatus,
DataRate: dataRate,
Frequency: config.RXInfo.Frequency,
LoRaSNR: float32(config.RXInfo.LoRaSNR),
Mac: config.GW.MAC,
RfChain: config.RXInfo.RfChain,
Rssi: config.RXInfo.Rssi,
Time: time.Now().Format(time.RFC3339),
Timestamp: int32(time.Now().UnixNano() / 1000000000),
}

gwID, err := lds.MACToGatewayID(config.GW.MAC)
if err != nil {
log.Errorf("gw mac error: %s", err)
return
}

err = cDevice.Join(mqttClient, string(gwID), *rxInfo)
now := time.Now()
rxTime := ptypes.TimestampNow()
tsge := ptypes.DurationProto(now.Sub(time.Time{}))

urx := gw.UplinkRXInfo{
GatewayId: gwID,
Rssi: int32(config.RXInfo.Rssi),
LoraSnr: float64(config.RXInfo.LoRaSNR),
Channel: uint32(config.RXInfo.Channel),
RfChain: uint32(config.RXInfo.RfChain),
TimeSinceGpsEpoch: tsge,
Time: rxTime,
Board: 0,
Antenna: 0,
Location: nil,
FineTimestamp: nil,
FineTimestampType: gw.FineTimestampType_NONE,
Context: make([]byte, 4),
}

lmi := &gw.LoRaModulationInfo{
Bandwidth: uint32(config.DR.Bandwidth),
SpreadingFactor: uint32(config.DR.SpreadFactor),
CodeRate: config.RXInfo.CodeRate,
}

umi := &gw.UplinkTXInfo_LoraModulationInfo{
LoraModulationInfo: lmi,
}

utx := gw.UplinkTXInfo{
Frequency: uint32(config.RXInfo.Frequency),
ModulationInfo: umi,
}

err = cDevice.Join(mqttClient, config.MQTT.UplinkTopic, config.GW.MAC, &urx, &utx)

if err != nil {
log.Errorf("join error: %s", err)
Expand All @@ -359,11 +377,19 @@ func run() {

setDevice()

dataRate := &lds.DataRate{
Bandwidth: config.DR.Bandwith,
/*dataRate := &lds.DataRate{
Bandwidth: config.DR.Bandwidth,
Modulation: "LORA",
SpreadFactor: config.DR.SpreadFactor,
BitRate: config.DR.BitRate,
}*/

//Get DR index from a dr.
dataRate := lwBand.DataRate{
Modulation: lwBand.Modulation("LORA"),
SpreadFactor: config.DR.SpreadFactor,
Bandwidth: config.DR.Bandwidth,
BitRate: config.DR.BitRate,
}

running = true
Expand Down Expand Up @@ -403,25 +429,6 @@ func run() {
}
}

//Construct DataRate RxInfo with proper values according to your band (example is for US 915).

rxInfo := &lds.RxInfo{
Channel: config.RXInfo.Channel,
CodeRate: config.RXInfo.CodeRate,
CrcStatus: config.RXInfo.CrcStatus,
DataRate: dataRate,
Frequency: config.RXInfo.Frequency,
LoRaSNR: float32(config.RXInfo.LoRaSNR),
Mac: config.GW.MAC,
RfChain: config.RXInfo.RfChain,
Rssi: config.RXInfo.Rssi,
Size: len(payload),
Time: time.Now().Format(time.RFC3339),
Timestamp: int32(time.Now().UnixNano() / 1000000000),
}

//////

gwID, err := lds.MACToGatewayID(config.GW.MAC)
if err != nil {
log.Errorf("gw mac error: %s", err)
Expand All @@ -434,32 +441,32 @@ func run() {

urx := gw.UplinkRXInfo{
GatewayId: gwID,
Rssi: int32(rxInfo.Rssi),
LoraSnr: float64(rxInfo.LoRaSNR),
Channel: uint32(rxInfo.Channel),
RfChain: uint32(rxInfo.RfChain),
Rssi: int32(config.RXInfo.Rssi),
LoraSnr: float64(config.RXInfo.LoRaSNR),
Channel: uint32(config.RXInfo.Channel),
RfChain: uint32(config.RXInfo.RfChain),
TimeSinceGpsEpoch: tsge,
Time: rxTime,
Timestamp: uint32(rxTime.GetSeconds()),
Board: 0,
Antenna: 0,
Location: nil,
FineTimestamp: nil,
FineTimestampType: gw.FineTimestampType_NONE,
Context: make([]byte, 4),
}

lmi := &gw.LoRaModulationInfo{
Bandwidth: uint32(rxInfo.DataRate.Bandwidth),
SpreadingFactor: uint32(rxInfo.DataRate.SpreadFactor),
CodeRate: rxInfo.CodeRate,
Bandwidth: uint32(config.DR.Bandwidth),
SpreadingFactor: uint32(config.DR.SpreadFactor),
CodeRate: config.RXInfo.CodeRate,
}

umi := &gw.UplinkTXInfo_LoraModulationInfo{
LoraModulationInfo: lmi,
}

utx := gw.UplinkTXInfo{
Frequency: uint32(rxInfo.Frequency),
Frequency: uint32(config.RXInfo.Frequency),
ModulationInfo: umi,
}

Expand All @@ -471,7 +478,7 @@ func run() {
}

//Now send an uplink
ulfc, err := cDevice.Uplink(mqttClient, config.Device.MType, uint8(config.RawPayload.FPort), &urx, &utx, payload, config.GW.MAC, config.Band.Name, *dataRate, fOpts, fCtrl)
ulfc, err := cDevice.Uplink(mqttClient, config.MQTT.UplinkTopic, config.Device.MType, uint8(config.RawPayload.FPort), &urx, &utx, payload, config.GW.MAC, config.Band.Name, dataRate, fOpts, fCtrl)
if err != nil {
log.Errorf("couldn't send uplink: %s", err)
} else {
Expand Down
12 changes: 10 additions & 2 deletions example_conf.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ log_level = "info"
server = "tcp://localhost:1883"
user = "username"
password = "password"
# Uplink topic. %s will be replaced with the gateway mac.
uplink_topic="gateway/%s/event/up"
# Downlink topic. %s will be replaced with the gateway mac.
downlink_topic="gateway/%s/command/down"

[gateway]
mac = "b827ebfffe9448d0"

[band]
name = "AU_915_928"

[Device]
[device]
eui="0000000000000000"
address="000f6e3b"
network_session_encription_key="dc5351f56794ed3ac17c382927192858"
Expand Down Expand Up @@ -77,4 +81,8 @@ skip_fcnt_check=true
[redis]
addr = "localhost:6379"
password = ""
db = 10
db = 10

[window]
width = 1200
height = 1000
18 changes: 9 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@ require (
github.com/BurntSushi/toml v0.3.1
github.com/andlabs/ui v0.0.0-20180902183112-867a9e5a498d
github.com/atotto/clipboard v0.1.2
github.com/brocaar/loraserver v2.3.0+incompatible
github.com/brocaar/lorawan v0.0.0-20181103141609-18588db1582c
github.com/eclipse/paho.mqtt.golang v1.1.1
github.com/brocaar/loraserver v0.0.0-20190429071653-f428e15194fb
github.com/brocaar/lorawan v0.0.0-20190308082318-5ed881e0a2d7
github.com/eclipse/paho.mqtt.golang v1.2.0
github.com/go-gl/gl v0.0.0-20181026044259-55b76b7df9d2
github.com/go-gl/glfw v0.0.0-20190217072633-93b30450e032
github.com/go-redis/redis v6.15.2+incompatible
github.com/golang/protobuf v1.2.0
github.com/golang/protobuf v1.3.1
github.com/inkyblackness/imgui-go v1.7.0
github.com/jacobsa/crypto v0.0.0-20180924003735-d95898ceee07
github.com/konsorten/go-windows-terminal-sequences v1.0.1
github.com/konsorten/go-windows-terminal-sequences v1.0.2
github.com/pkg/errors v0.8.1
github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d
github.com/sirupsen/logrus v1.2.0
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a
golang.org/x/sys v0.0.0-20181121002834-0cf1ed9e522b
github.com/sirupsen/logrus v1.3.0
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
golang.org/x/net v0.0.0-20190322120337-addf6b3196f6
golang.org/x/sys v0.0.0-20190308023053-584f3b12f43e
gopkg.in/sourcemap.v1 v1.0.5 // indirect
)
Loading

0 comments on commit 6ca28d8

Please sign in to comment.