Open frazar opened 5 years ago
MAC commands are processed by the back-end, not the gateway (also not the packet forwarder on the gateway) so I assume your statement is based on back-end code? What code?
Maybe you're right, and the problem lies in the Network Server software. As I mentioned before, I'm not an expert, and I'm still trying to figure stuff out.
I thought it was due to packet_forwarder because of the TODO
s I found skimming the code and the # Invalid gps time reference
messages I was seeing in the logs.
I'll investigate more thoroughly and report back.
I'll report here the results of my research.
First, I tried to understand why the Loraserver was sending a zero payload for the DeviceTimeAns
.
Basically, when the loraserver
software receives a request of the DeviceTimeReq
MAC command, it will answer copying the timestamp of the received packet.
You can see this behaviour in the handleDeviceTimeReq()
function:
here the function reads the TimeSinceGpsEpoch
field of the rxInfo
structure into the timeSinceGPSEpoch
variable, as follows:
timeSinceGPSEpoch, err = ptypes.Duration(rxInfo.TimeSinceGpsEpoch)
here the timeSinceGPSEpoch
variable is used to populate the payload of the DeviceTimeAns
MAC command.
MACCommands: storage.MACCommands{
{
CID: lorawan.DeviceTimeAns,
Payload: &lorawan.DeviceTimeAnsPayload{
TimeSinceGPSEpoch: timeSinceGPSEpoch,
},
},
},
So if the DeviceTimeAns
payload is zero, it's because the rxInfo.TimeSinceGpsEpoch
field is zero.
This field is read from..
The next layer of the network is the Lora-gateway-bridge.
Turns out the TimeSinceGpsEpoch
field is populated using the "tmms" field of the JSON object received by the packet_forwarder
, as seen here
// Time since GPS epoch
if rxpk.Tmms != nil {
d := time.Duration(*rxpk.Tmms) * time.Millisecond
frame.RxInfo.TimeSinceGpsEpoch = ptypes.DurationProto(d)
}
So how is the "tmms" field set?
The lora-gateway-bridge reads the JSON sent by packet_forwarder. It turns out the "tmms" field is always missing from this JSON.
I could only find it mentioned in the PROTOCOL.TXT
of the packet_forwarder from Lora-Net
Probably the easiest solution is patching the lora-gateway-bridge so that it uses the "time" field rather then "tmms" to set RxInfo.TimeSinceGpsEpoch
.
When the gateway is not equipped with a GPS module and is configured with
fake_gps: true
, the time information is not added to the "DeviceTimeAns" MAC command specified in LoRaWAN 1.0.3.Browsing the code I found a couple of TODOs that mention the possibility of using an alternative time source from the GPS module:
A solution could use the
clock_gettime()
function withCLOCK_REALTIME
to get the seconds since the Unix epoch, and then convert to seconds since the GPS epoch (taking into consideration leap seconds..).I see two way of enabling the behaviour of using the local time:
gps_ref_valid
isfalse
.I'm willing to propose a PR, but I'm not an expert in C or the codebase, so I might need a little guidance.