Skip to content

Commit

Permalink
Add RTT calculation for DHCP Time calculation
Browse files Browse the repository at this point in the history
Calculate the RTT of DHCP requests and report in address callback

When receiving DHCP Time vendor data use RTT value to estimate the error
Take RTT into account when setting the time
  • Loading branch information
Mika Tervonen authored and Mika Tervonen committed Jun 14, 2021
1 parent 0b82953 commit d925145
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 3 deletions.
10 changes: 10 additions & 0 deletions nanostack/dhcp_service_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,16 @@ void dhcp_service_set_retry_timers(uint32_t msg_tr_id, uint16_t timeout_init, ui
*/
void dhcp_service_update_server_address(uint32_t msg_tr_id, uint8_t *server_address);

/**
* \brief Get Round Trip time of the request
*
* get the elapsed time of the request from last message sent to server.
*
* \param msg_tr_id The message transaction ID.
*
*/
uint32_t dhcp_service_rtt_get(uint32_t msg_tr_id);

/**
* \brief Stops transactions for a message (retransmissions).
*
Expand Down
9 changes: 8 additions & 1 deletion source/6LoWPAN/ws/ws_bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1010,11 +1010,18 @@ static void ws_bootstrap_dhcp_info_notify_cb(int8_t interface, dhcp_option_notif
int32_t era;
uint32_t offset;
if (net_vendor_option_current_time_read(options->option.vendor_spesific.data, options->option.vendor_spesific.data_length, &era, &offset, NULL)) {
uint32_t estimated_error = 10;
uint64_t current_time;
uint64_t network_time = (era * (uint64_t)(4294967296)) + offset - 2208988800; //Convert to First day of Unix (1 Jan 1970)

tr_debug("Network Time option Era:%"PRId32" Offset:%"PRIu32" rtt: %"PRId32" time: %"PRIu64, era, offset, server_info->rtt, network_time);
if (0 == ns_time_system_time_read(&current_time)) {
uint64_t difference;
// We only adjust clock if time has drifted more than 10 seconds to avoid constant changing of time
// If Round trip time is very high the accuracy is reduced.
uint32_t estimated_error = 10 + server_info->rtt / 10;
// Take into account the round trip time it took the response to arrive from the time server Write the time.
network_time += server_info->rtt / 20;

if (current_time > network_time) {
difference = current_time - network_time;
} else {
Expand Down
1 change: 1 addition & 0 deletions source/DHCPv6_client/dhcpv6_client_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ typedef struct dhcp_server_notify_info {
uint16_t duid_type;
uint16_t duid_length;
uint32_t life_time;
uint32_t rtt; // Round trip time with 100ms tics.
uint8_t *duid;
} dhcp_server_notify_info_t;

Expand Down
9 changes: 7 additions & 2 deletions source/DHCPv6_client/dhcpv6_client_service.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ void dhcpv6_client_send_error_cb(dhcpv6_client_server_data_t *srv_data_ptr)
}


static void dhcp_vendor_information_notify(uint8_t *ptr, uint16_t data_len, dhcp_client_class_t *dhcp_client, dhcpv6_client_server_data_t *srv_data_ptr)
static void dhcp_vendor_information_notify(uint8_t *ptr, uint16_t data_len, dhcp_client_class_t *dhcp_client, dhcpv6_client_server_data_t *srv_data_ptr, uint32_t message_rtt)
{
if (!dhcp_client->option_information_cb) {
return;
Expand All @@ -261,6 +261,8 @@ static void dhcp_vendor_information_notify(uint8_t *ptr, uint16_t data_len, dhcp
server_info.duid = srv_data_ptr->serverDUID.duid + 2; // Skip the type
server_info.duid_type = srv_data_ptr->serverDUID.type;
server_info.duid_length = srv_data_ptr->serverDUID.duid_length - 2;// remove the type
server_info.rtt = message_rtt;


while (data_len >= 4) {
type = common_read_16_bit(ptr);
Expand Down Expand Up @@ -309,6 +311,7 @@ int dhcp_solicit_resp_cb(uint16_t instance_id, void *ptr, uint8_t msg_name, uin
dhcp_duid_options_params_t clientId;
dhcp_duid_options_params_t serverId;
dhcpv6_client_server_data_t *srv_data_ptr = NULL;
uint32_t message_rtt;
(void)instance_id;

//Validate that started TR ID class is still at list
Expand All @@ -327,6 +330,8 @@ int dhcp_solicit_resp_cb(uint16_t instance_id, void *ptr, uint8_t msg_name, uin
}


message_rtt = dhcp_service_rtt_get(srv_data_ptr->transActionId);

//Clear Active Transaction state
srv_data_ptr->transActionId = 0;

Expand Down Expand Up @@ -399,7 +404,7 @@ int dhcp_solicit_resp_cb(uint16_t instance_id, void *ptr, uint8_t msg_name, uin
}

//Optional Options notify from Reply
dhcp_vendor_information_notify(msg_ptr, msg_len, dhcp_client, srv_data_ptr);
dhcp_vendor_information_notify(msg_ptr, msg_len, dhcp_client, srv_data_ptr, message_rtt);

return RET_MSG_ACCEPTED;
error_exit:
Expand Down
13 changes: 13 additions & 0 deletions source/libDHCPv6/dhcp_service_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ typedef struct {
void *client_obj_ptr;
uint32_t msg_tr_id;
uint32_t message_tr_id;
uint32_t transmit_time;
uint32_t first_transmit_time;
uint16_t delayed_tx;
uint16_t timeout;
Expand Down Expand Up @@ -795,6 +796,7 @@ uint32_t dhcp_service_send_req(uint16_t instance_id, uint8_t options, void *ptr,
msg_tr_ptr->recv_resp_cb = receive_resp_cb;
msg_tr_ptr->delayed_tx = delay_tx;
msg_tr_ptr->first_transmit_time = 0;
msg_tr_ptr->transmit_time = 0;
dhcp_tr_set_retry_timers(msg_tr_ptr, msg_tr_ptr->msg_ptr[0]);
common_write_24_bit(msg_tr_ptr->msg_tr_id, &msg_tr_ptr->msg_ptr[1]);

Expand Down Expand Up @@ -826,6 +828,16 @@ void dhcp_service_update_server_address(uint32_t msg_tr_id, uint8_t *server_addr
}
}

uint32_t dhcp_service_rtt_get(uint32_t msg_tr_id)
{
msg_tr_t *msg_tr_ptr = dhcp_tr_find(msg_tr_id);

if (msg_tr_ptr && msg_tr_ptr->transmit_time) {
return protocol_core_monotonic_time - msg_tr_ptr->transmit_time;
}
return 0;
}

void dhcp_service_req_remove(uint32_t msg_tr_id)
{
if (dhcp_service) {
Expand Down Expand Up @@ -927,6 +939,7 @@ void dhcp_service_send_message(msg_tr_t *msg_tr_ptr)
int16_t tc = 0;
socket_setsockopt(msg_tr_ptr->socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_TCLASS, &tc, sizeof(tc));
retval = socket_sendto(msg_tr_ptr->socket, &msg_tr_ptr->addr, msg_tr_ptr->msg_ptr, msg_tr_ptr->msg_len);
msg_tr_ptr->transmit_time = protocol_core_monotonic_time ? protocol_core_monotonic_time : 1;
if (msg_tr_ptr->first_transmit_time == 0 && retval == 0) {
//Mark first pushed message timestamp
msg_tr_ptr->first_transmit_time = protocol_core_monotonic_time ? protocol_core_monotonic_time : 1;
Expand Down
4 changes: 4 additions & 0 deletions test/nanostack/unittest/stub/dhcp_service_api_stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ uint32_t dhcp_service_send_req(uint16_t instance_id, uint8_t options, void *ptr,
void dhcp_service_set_retry_timers(uint32_t msg_tr_id, uint16_t timeout_init, uint16_t timeout_max, uint8_t retrans_max)
{
}
uint32_t dhcp_service_rtt_get(uint32_t msg_tr_id)
{
return 0;
}

void dhcp_service_req_remove(uint32_t msg_tr_id)
{
Expand Down

0 comments on commit d925145

Please sign in to comment.