Fixing DevTimeAns handling

As per discussion with Nicolas Sornin, any device time synchronization
value must be handled as is (monotonically increasing GPS epoch time guaranteed to be monotonic with granularity 1 second).

Once we receive a response to DevTimeReq (i.e., DevTimeAns is received)
we immediately set our local gps time stamp and take a snapshot of our
local monotonic (ticker or equivalent) clock. This is achieved by
calling 'set_gps_time(...)' API in the LoRaWANTimer module.
After that an event is generated to let the application know that a
device time has been synched.
feature-lorawan-1-1
Hasnain Virk 2019-03-25 16:00:40 +02:00 committed by Antti Kauppila
parent 6654a595d6
commit d7a57fb0f3
6 changed files with 11 additions and 17 deletions

View File

@ -471,8 +471,9 @@ lorawan_status_t LoRaWANStack::set_link_check_request()
return LORAWAN_STATUS_OK; return LORAWAN_STATUS_OK;
} }
void LoRaWANStack::send_device_time_sync_event() void LoRaWANStack::handle_device_time_sync_event(lorawan_time_t gps_time)
{ {
_lora_time.set_gps_time(gps_time);
send_event_to_application(DEVICE_TIME_SYNCHED); send_event_to_application(DEVICE_TIME_SYNCHED);
} }
@ -486,7 +487,7 @@ lorawan_status_t LoRaWANStack::set_device_time_request()
return LORAWAN_STATUS_NO_NETWORK_JOINED; return LORAWAN_STATUS_NO_NETWORK_JOINED;
} }
return _loramac.setup_device_time_request(callback(this, &LoRaWANStack::send_device_time_sync_event)); return _loramac.setup_device_time_request(callback(this, &LoRaWANStack::handle_device_time_sync_event));
} }
void LoRaWANStack::set_reset_indication() void LoRaWANStack::set_reset_indication()

View File

@ -576,7 +576,7 @@ private:
void forced_timer_expiry(); void forced_timer_expiry();
void process_rejoin_type0(); void process_rejoin_type0();
void send_device_time_sync_event(); void handle_device_time_sync_event(lorawan_time_t gps_time);
private: private:
LoRaMac _loramac; LoRaMac _loramac;

View File

@ -1623,7 +1623,7 @@ void LoRaMac::setup_link_check_request()
_mac_commands.add_link_check_req(); _mac_commands.add_link_check_req();
} }
lorawan_status_t LoRaMac::setup_device_time_request(mbed::Callback<void(void)> notify) lorawan_status_t LoRaMac::setup_device_time_request(mbed::Callback<void(lorawan_time_t)> notify)
{ {
return _mac_commands.add_device_time_req(notify); return _mac_commands.add_device_time_req(notify);
} }

View File

@ -333,7 +333,7 @@ public:
* @brief setup_device_time_request Adds device time request command * @brief setup_device_time_request Adds device time request command
* to be put on next outgoing message (when it fits) * to be put on next outgoing message (when it fits)
*/ */
lorawan_status_t setup_device_time_request(mbed::Callback<void(void)> notify); lorawan_status_t setup_device_time_request(mbed::Callback<void(lorawan_time_t)> notify);
/** /**
* @brief setup_reset_indication Adds reset indication command * @brief setup_reset_indication Adds reset indication command

View File

@ -332,22 +332,15 @@ lorawan_status_t LoRaMacCommand::process_mac_commands(const uint8_t *payload, ui
secs |= (uint32_t) payload[mac_index++] << 8; secs |= (uint32_t) payload[mac_index++] << 8;
secs |= (uint32_t) payload[mac_index++] << 16; secs |= (uint32_t) payload[mac_index++] << 16;
secs |= (uint32_t) payload[mac_index++] << 24; secs |= (uint32_t) payload[mac_index++] << 24;
uint32_t millis = ((uint32_t) payload[mac_index++] * 1000) >> 8;
// round milliseconds to closest second // round milliseconds to closest second
if (millis > 499) { if (payload[mac_index++] >= 0x80) {
secs++; secs++;
} }
// adjust for Unix to GPS epoch diff
secs += UNIX_GPS_EPOCH_DIFF;
// adjust for leap seconds since GPS epoch origin
secs += (MBED_CONF_LORA_CURRENT_TAI_MINUS_UTC - MBED_CONF_LORA_GPS_EPOCH_TAI_MINUS_UTC);
set_time(secs);
// notify the stack controller // notify the stack controller
if (_time_sync_cb) { if (_time_sync_cb) {
_time_sync_cb(); _time_sync_cb(secs);
} }
} }
break; break;
@ -457,7 +450,7 @@ lorawan_status_t LoRaMacCommand::add_device_mode_indication(uint8_t classType)
return ret; return ret;
} }
lorawan_status_t LoRaMacCommand::add_device_time_req(mbed::Callback<void(void)> notify) lorawan_status_t LoRaMacCommand::add_device_time_req(mbed::Callback<void(lorawan_time_t)> notify)
{ {
//App developer must know if the server version is 1.0.3 (or greater) //App developer must know if the server version is 1.0.3 (or greater)
//1.0.2 does not support this MAC command and our stack does not support pre 1.0.2 versions //1.0.2 does not support this MAC command and our stack does not support pre 1.0.2 versions

View File

@ -164,7 +164,7 @@ public:
* @return status Function status: LORAWAN_STATUS_OK: OK, * @return status Function status: LORAWAN_STATUS_OK: OK,
* LORAWAN_STATUS_LENGTH_ERROR: Buffer full * LORAWAN_STATUS_LENGTH_ERROR: Buffer full
*/ */
lorawan_status_t add_device_time_req(mbed::Callback<void(void)> notify); lorawan_status_t add_device_time_req(mbed::Callback<void(lorawan_time_t)> notify);
/** /**
* @brief Set battery level query callback method * @brief Set battery level query callback method
@ -298,7 +298,7 @@ private:
uint8_t mac_cmd_buffer_to_repeat[LORA_MAC_COMMAND_MAX_LENGTH]; uint8_t mac_cmd_buffer_to_repeat[LORA_MAC_COMMAND_MAX_LENGTH];
mbed::Callback<uint8_t(void)> _battery_level_cb; mbed::Callback<uint8_t(void)> _battery_level_cb;
mbed::Callback<void(void)> _time_sync_cb; mbed::Callback<void(lorawan_time_t)> _time_sync_cb;
}; };
#endif //__LORAMACCOMMAND_H__ #endif //__LORAMACCOMMAND_H__