Skip to content

Commit 1062b1d

Browse files
authored
Basic Station timesync request/response support. (#181)
Closes #179.
1 parent 0beeaae commit 1062b1d

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed

internal/backend/basicstation/backend.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/brocaar/chirpstack-gateway-bridge/internal/config"
2929
"github.com/brocaar/lorawan"
3030
"github.com/brocaar/lorawan/band"
31+
"github.com/brocaar/lorawan/gps"
3132
)
3233

3334
// websocket upgrade parameters
@@ -559,6 +560,18 @@ func (b *Backend) handleGateway(r *http.Request, c *websocket.Conn) {
559560
continue
560561
}
561562
b.handleDownlinkTransmittedMessage(gatewayID, pl)
563+
case structs.TimeSyncMessage:
564+
// handle time sync request
565+
var pl structs.TimeSyncRequest
566+
if err := json.Unmarshal(msg, &pl); err != nil {
567+
log.WithError(err).WithFields(log.Fields{
568+
"message_type": msgType,
569+
"gateway_id": gatewayID,
570+
"payload": string(msg),
571+
}).Error("backend/basicstation: unmarshal json message error")
572+
continue
573+
}
574+
b.handleTimeSync(gatewayID, pl)
562575
default:
563576
b.handleRawPacketForwarderEvent(gatewayID, msg)
564577
}
@@ -716,6 +729,24 @@ func (b *Backend) handleRawPacketForwarderEvent(gatewayID lorawan.EUI64, pl []by
716729
b.rawPacketForwarderEventChan <- rawEvent
717730
}
718731

732+
func (b *Backend) handleTimeSync(gatewayID lorawan.EUI64, v structs.TimeSyncRequest) {
733+
resp := structs.TimeSyncResponse{
734+
MessageType: structs.TimeSyncMessage,
735+
TxTime: v.TxTime,
736+
GPSTime: int64(gps.Time(time.Now()).TimeSinceGPSEpoch() / time.Microsecond),
737+
}
738+
if err := b.sendToGateway(gatewayID, &resp); err != nil {
739+
log.WithError(err).Error("backend/basicstation: send to gateway error")
740+
return
741+
}
742+
743+
log.WithFields(log.Fields{
744+
"gateway_id": gatewayID,
745+
"txtime": resp.TxTime,
746+
"gpstime": resp.GPSTime,
747+
}).Info("backend/basicstation: timesync message sent to gateway")
748+
}
749+
719750
func (b *Backend) sendToGateway(gatewayID lorawan.EUI64, v interface{}) error {
720751
gw, err := b.gateways.get(gatewayID)
721752
if err != nil {

internal/backend/basicstation/backend_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/brocaar/chirpstack-gateway-bridge/internal/backend/events"
1919
"github.com/brocaar/chirpstack-gateway-bridge/internal/config"
2020
"github.com/brocaar/lorawan"
21+
"github.com/brocaar/lorawan/gps"
2122
)
2223

2324
type BackendTestSuite struct {
@@ -472,6 +473,27 @@ func (ts *BackendTestSuite) TestRawPacketForwarderEvent() {
472473
})
473474
}
474475

476+
func (ts *BackendTestSuite) TestTimeSync() {
477+
assert := require.New(ts.T())
478+
479+
startGPS := int64(gps.Time(time.Now()).TimeSinceGPSEpoch() / time.Microsecond)
480+
tsync := structs.TimeSyncRequest{
481+
MessageType: structs.TimeSyncMessage,
482+
TxTime: 112233445566,
483+
}
484+
485+
assert.NoError(ts.wsClient.WriteJSON(&tsync))
486+
487+
var tsresp structs.TimeSyncResponse
488+
assert.NoError(ts.wsClient.ReadJSON(&tsresp))
489+
490+
assert.Equal(tsync.MessageType, tsresp.MessageType)
491+
assert.Equal(tsync.TxTime, tsresp.TxTime)
492+
493+
endGPS := int64(gps.Time(time.Now()).TimeSinceGPSEpoch() / time.Microsecond)
494+
assert.True(tsresp.GPSTime >= startGPS && tsresp.GPSTime <= endGPS)
495+
}
496+
475497
func TestBackend(t *testing.T) {
476498
suite.Run(t, new(BackendTestSuite))
477499
}

internal/backend/basicstation/structs/msg_type.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const (
1818
ProprietaryDataFrameMessage MessageType = "propdf"
1919
DownlinkMessage MessageType = "dnmsg"
2020
DownlinkTransmittedMessage MessageType = "dntxed"
21+
TimeSyncMessage MessageType = "timesync"
2122
)
2223

2324
type messageTypePayload struct {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package structs
2+
3+
// TimeSyncRequest implements the router-info request.
4+
type TimeSyncRequest struct {
5+
MessageType MessageType `json:"msgtype"`
6+
TxTime int64 `json:"txtime"`
7+
}
8+
9+
// TimeSyncResponse implements the router-info response.
10+
type TimeSyncResponse struct {
11+
MessageType MessageType `json:"msgtype"`
12+
TxTime int64 `json:"txtime"`
13+
GPSTime int64 `json:"gpstime"`
14+
}

0 commit comments

Comments
 (0)