Skip to content

Commit 93ccd76

Browse files
committed
Add MuxTime to downlink messages.
The MuxTime is an alternative way to time-sync Basics Station gateways, instead of using the timesync messages. This is documented here: https://lora-developers.semtech.com/build/software/lora-basics/lora-basics-for-gateways/?url=time.html
1 parent 6b1e593 commit 93ccd76

File tree

5 files changed

+33
-15
lines changed

5 files changed

+33
-15
lines changed

internal/backend/basicstation/backend_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,9 @@ func (ts *BackendTestSuite) TestSendDownlinkFrame() {
564564
rCtx := uint64(3)
565565
xTime := uint64(4)
566566

567+
assert.NotNil(df.MuxTime)
568+
df.MuxTime = nil
569+
567570
assert.Equal(structs.DownlinkFrame{
568571
MessageType: structs.DownlinkMessage,
569572
DevEui: "01-01-01-01-01-01-01-01",

internal/backend/basicstation/structs/downlink_message.go

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,22 @@ import (
1515
type DownlinkFrame struct {
1616
MessageType MessageType `json:"msgtype"`
1717

18-
DevEui string `json:"DevEui"`
19-
DC int `json:"dC"`
20-
DIID uint32 `json:"diid"`
21-
PDU string `json:"pdu"`
22-
Priority int `json:"priority"`
23-
RxDelay *int `json:"RxDelay,omitempty"`
24-
RX1DR *int `json:"RX1DR,omitempty"`
25-
RX1Freq *uint32 `json:"RX1Freq,omitempty"`
26-
RX2DR *int `json:"RX2DR,omitempty"`
27-
RX2Freq *uint32 `json:"RX2Freq,omitempty"`
28-
DR *int `json:"DR,omitempty"`
29-
Freq *uint32 `json:"Freq,omitempty"`
30-
GPSTime *uint64 `json:"gpstime,omitempty"`
31-
XTime *uint64 `json:"xtime,omitempty"`
32-
RCtx *uint64 `json:"rctx,omitempty"`
18+
DevEui string `json:"DevEui"`
19+
DC int `json:"dC"`
20+
DIID uint32 `json:"diid"`
21+
PDU string `json:"pdu"`
22+
Priority int `json:"priority"`
23+
RxDelay *int `json:"RxDelay,omitempty"`
24+
RX1DR *int `json:"RX1DR,omitempty"`
25+
RX1Freq *uint32 `json:"RX1Freq,omitempty"`
26+
RX2DR *int `json:"RX2DR,omitempty"`
27+
RX2Freq *uint32 `json:"RX2Freq,omitempty"`
28+
DR *int `json:"DR,omitempty"`
29+
Freq *uint32 `json:"Freq,omitempty"`
30+
GPSTime *uint64 `json:"gpstime,omitempty"`
31+
XTime *uint64 `json:"xtime,omitempty"`
32+
RCtx *uint64 `json:"rctx,omitempty"`
33+
MuxTime *float64 `json:"MuxTime,omitempty"`
3334
}
3435

3536
// DownlinkFrameFromProto convers the given protobuf message to a DownlinkFrame.
@@ -38,6 +39,9 @@ func DownlinkFrameFromProto(loraBand band.Band, pb *gw.DownlinkFrame) (DownlinkF
3839
return DownlinkFrame{}, errors.New("items must contain at least one item")
3940
}
4041

42+
// MuxTime
43+
muxTime := float64(time.Now().UnixMicro()) / 1000000
44+
4145
// We assume this is for RX1
4246
item := pb.Items[0]
4347

@@ -47,6 +51,7 @@ func DownlinkFrameFromProto(loraBand band.Band, pb *gw.DownlinkFrame) (DownlinkF
4751
DevEui: "01-01-01-01-01-01-01-01", // set to fake DevEUI (setting it to 0 causes the BasicStation to not send acks, see https://github.com/lorabasics/basicstation/issues/71).
4852
DIID: pb.DownlinkId,
4953
PDU: hex.EncodeToString(item.PhyPayload),
54+
MuxTime: &muxTime,
5055
}
5156

5257
// context

internal/backend/basicstation/structs/downlink_message_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,8 @@ func TestDownlinkFrameFromProto(t *testing.T) {
251251
if err != nil {
252252
return
253253
}
254+
assert.NotNil(out.MuxTime)
255+
out.MuxTime = nil
254256
assert.Equal(tst.Out, out)
255257
})
256258
}

internal/backend/basicstation/structs/router_config.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package structs
33
import (
44
"encoding/binary"
55
"fmt"
6+
"time"
67

78
"github.com/brocaar/chirpstack-gateway-bridge/internal/config"
89
"github.com/brocaar/chirpstack-gateway-bridge/internal/config/sx1301v1"
@@ -35,6 +36,7 @@ type RouterConfig struct {
3536
FreqRange []uint32 `json:"freq_range"`
3637
DRs [][]int `json:"DRs"`
3738
SX1301Conf []SX1301Conf `json:"sx1301_conf"`
39+
MuxTime *float64 `json:"MuxTime,omitempty"`
3840
}
3941

4042
// SX1301Conf implements a single SX1301 configuration.
@@ -84,12 +86,16 @@ type SX1301ConfChanMultiSF struct {
8486
func GetRouterConfig(region band.Name, netIDs []lorawan.NetID, joinEUIs [][2]lorawan.EUI64, freqMin, freqMax uint32, concentrators []config.BasicStationConcentrator) (RouterConfig, error) {
8587
concentratorCount := len(concentrators)
8688

89+
// MuxTime
90+
muxTime := float64(time.Now().UnixMicro()) / 1000000
91+
8792
c := RouterConfig{
8893
MessageType: RouterConfigMessage,
8994
Region: regionNameMapping[region],
9095
HWSpec: fmt.Sprintf("sx1301/%d", concentratorCount),
9196
FreqRange: []uint32{freqMin, freqMax},
9297
SX1301Conf: make([]SX1301Conf, concentratorCount),
98+
MuxTime: &muxTime,
9399
}
94100

95101
// set NetID filter

internal/backend/basicstation/structs/router_config_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,8 @@ func TestRouterConfig(t *testing.T) {
321321
if err != nil {
322322
return
323323
}
324+
assert.NotNil(rc.MuxTime)
325+
rc.MuxTime = nil
324326
assert.Equal(tst.ExpectedRouterConfig, rc)
325327
})
326328
}

0 commit comments

Comments
 (0)