@@ -52,10 +52,11 @@ type Backend struct {
5252 scheme string
5353 isClosed bool
5454
55- statsInterval time.Duration
56- pingInterval time.Duration
57- readTimeout time.Duration
58- writeTimeout time.Duration
55+ statsInterval time.Duration
56+ pingInterval time.Duration
57+ timesyncInterval time.Duration
58+ readTimeout time.Duration
59+ writeTimeout time.Duration
5960
6061 gateways gateways
6162
@@ -89,10 +90,11 @@ func NewBackend(conf config.Config) (*Backend, error) {
8990 tlsCert : conf .Backend .BasicStation .TLSCert ,
9091 tlsKey : conf .Backend .BasicStation .TLSKey ,
9192
92- statsInterval : conf .Backend .BasicStation .StatsInterval ,
93- pingInterval : conf .Backend .BasicStation .PingInterval ,
94- readTimeout : conf .Backend .BasicStation .ReadTimeout ,
95- writeTimeout : conf .Backend .BasicStation .WriteTimeout ,
93+ statsInterval : conf .Backend .BasicStation .StatsInterval ,
94+ pingInterval : conf .Backend .BasicStation .PingInterval ,
95+ timesyncInterval : conf .Backend .BasicStation .TimesyncInterval ,
96+ readTimeout : conf .Backend .BasicStation .ReadTimeout ,
97+ writeTimeout : conf .Backend .BasicStation .WriteTimeout ,
9698
9799 region : band .Name (conf .Backend .BasicStation .Region ),
98100 frequencyMin : conf .Backend .BasicStation .FrequencyMin ,
@@ -504,6 +506,7 @@ func (b *Backend) handleGateway(r *http.Request, conn *connection) {
504506 continue
505507 }
506508 b .handleUplinkDataFrame (gatewayID , pl )
509+ b .sendTimesyncRequest (gatewayID , pl .RadioMetaData .UpInfo )
507510 case structs .JoinRequestMessage :
508511 // handle join-request
509512 var pl structs.JoinRequest
@@ -516,6 +519,7 @@ func (b *Backend) handleGateway(r *http.Request, conn *connection) {
516519 continue
517520 }
518521 b .handleJoinRequest (gatewayID , pl )
522+ b .sendTimesyncRequest (gatewayID , pl .RadioMetaData .UpInfo )
519523 case structs .ProprietaryDataFrameMessage :
520524 // handle proprietary uplink
521525 var pl structs.UplinkProprietaryFrame
@@ -528,6 +532,7 @@ func (b *Backend) handleGateway(r *http.Request, conn *connection) {
528532 continue
529533 }
530534 b .handleProprietaryDataFrame (gatewayID , pl )
535+ b .sendTimesyncRequest (gatewayID , pl .RadioMetaData .UpInfo )
531536 case structs .DownlinkTransmittedMessage :
532537 // handle downlink transmitted
533538 var pl structs.DownlinkTransmitted
@@ -752,7 +757,7 @@ func (b *Backend) handleTimeSync(gatewayID lorawan.EUI64, v structs.TimeSyncRequ
752757 "gateway_id" : gatewayID ,
753758 "txtime" : resp .TxTime ,
754759 "gpstime" : resp .GPSTime ,
755- }).Info ("backend/basicstation: timesync message sent to gateway" )
760+ }).Info ("backend/basicstation: timesync response sent to gateway" )
756761}
757762
758763func (b * Backend ) sendToGateway (gatewayID lorawan.EUI64 , v interface {}) error {
@@ -843,3 +848,48 @@ func (b *Backend) websocketWrap(handler func(*http.Request, *connection), w http
843848 handler (r , & c )
844849 done <- struct {}{}
845850}
851+
852+ func (b * Backend ) sendTimesyncRequest (gatewayID lorawan.EUI64 , upInfo structs.RadioMetaDataUpInfo ) {
853+ // Nothing to do
854+ if b .timesyncInterval == 0 {
855+ return
856+ }
857+
858+ lastTimesync , err := b .gateways .getLastTimesync (gatewayID )
859+ if err != nil {
860+ log .WithError (err ).WithFields (log.Fields {
861+ "gateway_id" : gatewayID ,
862+ }).Error ("backend/basicstation: get last timesync timestamp error" )
863+ return
864+ }
865+
866+ // Interval has not been reached yet
867+ if lastTimesync .Add (b .timesyncInterval ).After (time .Now ()) {
868+ return
869+ }
870+
871+ // Set last timesync
872+ if err := b .gateways .setLastTimesync (gatewayID , time .Now ()); err != nil {
873+ log .WithError (err ).WithFields (log.Fields {
874+ "gateway_id" : gatewayID ,
875+ }).Error ("backend/basicstation: set last timesync timestamp error" )
876+ return
877+ }
878+
879+ timesync := structs.TimeSyncGPSTimeTransfer {
880+ MessageType : structs .TimeSyncMessage ,
881+ XTime : upInfo .XTime ,
882+ GPSTime : int64 (gps .Time (time .Now ()).TimeSinceGPSEpoch () / time .Microsecond ),
883+ }
884+
885+ if err := b .sendToGateway (gatewayID , & timesync ); err != nil {
886+ log .WithError (err ).Error ("backend/basicstation: send to gateway error" )
887+ return
888+ }
889+
890+ log .WithFields (log.Fields {
891+ "gateway_id" : gatewayID ,
892+ "xtime" : timesync .XTime ,
893+ "gpstime" : timesync .GPSTime ,
894+ }).Info ("backend/basicstation: timesync request sent to gateway" )
895+ }
0 commit comments