Skip to content

Commit

Permalink
lorawan: add devicetime request support
Browse files Browse the repository at this point in the history
Add devicetime request support.
Update lorawan sample
Related to Issue #55072

Co-authored-by: Jan Kowalewski <[email protected]>

Signed-off-by: romain pelletant <[email protected]>
Signed-off-by: Jan Kowalewski <[email protected]>
  • Loading branch information
RomainPelletant authored and nashif committed Nov 16, 2024
1 parent 866905f commit ae0c1b7
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 9 deletions.
27 changes: 27 additions & 0 deletions include/zephyr/lorawan/lorawan.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ enum lorawan_message_type {
*/
enum lorawan_dl_flags {
LORAWAN_DATA_PENDING = BIT(0),
LORAWAN_TIME_UPDATED = BIT(1),
};

/**
Expand Down Expand Up @@ -378,6 +379,32 @@ void lorawan_get_payload_sizes(uint8_t *max_next_payload_size,
*/
int lorawan_set_region(enum lorawan_region region);

/**
* @brief Request for time according to DeviceTimeReq MAC cmd
*
* Append MAC DevTimeReq command. It will be processed on next send
* message or force sending empty message to request time immediately.
*
* @param force_request Immediately send an empty message to execute the request
* @return 0 if successful, negative errno otherwise
*/
int lorawan_request_device_time(bool force_request);

/**
* @brief Retrieve the current time from LoRaWAN stack updated by
* DeviceTimeAns on MAC layer.
*
* This function uses the GPS epoch format, as used in all LoRaWAN services.
*
* The GPS epoch started on 1980-01-06T00:00:00Z, but has since diverged
* from UTC, as it does not consider corrections like leap seconds.
*
* @param gps_time Synchronized time in GPS epoch format truncated to 32-bit.
*
* @return 0 if successful, -EAGAIN if the clock is not yet synchronized.
*/
int lorawan_device_time_get(uint32_t *gps_time);

#ifdef CONFIG_LORAWAN_APP_CLOCK_SYNC

/**
Expand Down
9 changes: 4 additions & 5 deletions samples/subsys/lorawan/class_a/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,11 @@ LOG_MODULE_REGISTER(lorawan_class_a);

char data[] = {'h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd'};

static void dl_callback(uint8_t port, uint8_t flags,
int16_t rssi, int8_t snr,
uint8_t len, const uint8_t *hex_data)
static void dl_callback(uint8_t port, uint8_t flags, int16_t rssi, int8_t snr, uint8_t len,
const uint8_t *hex_data)
{
LOG_INF("Port %d, Pending %d, RSSI %ddB, SNR %ddBm",
port, flags & LORAWAN_DATA_PENDING, rssi, snr);
LOG_INF("Port %d, Pending %d, RSSI %ddB, SNR %ddBm, Time %d", port,
flags & LORAWAN_DATA_PENDING, rssi, snr, !!(flags & LORAWAN_TIME_UPDATED));
if (hex_data) {
LOG_HEXDUMP_INF(hex_data, len, "Payload: ");
}
Expand Down
7 changes: 3 additions & 4 deletions samples/subsys/lorawan/fuota/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@ LOG_MODULE_REGISTER(lorawan_fuota, CONFIG_LORAWAN_SERVICES_LOG_LEVEL);

char data[] = {'h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd'};

static void downlink_info(uint8_t port, bool data_pending, int16_t rssi, int8_t snr,
uint8_t len, const uint8_t *data)
static void downlink_info(uint8_t port, uint8_t flags, int16_t rssi, int8_t snr, uint8_t len,
const uint8_t *data)
{
LOG_INF("Received from port %d, pending %d, RSSI %ddB, SNR %ddBm",
port, data_pending, rssi, snr);
LOG_INF("Received from port %d, flags %d, RSSI %ddB, SNR %ddBm", port, flags, rssi, snr);
if (data) {
LOG_HEXDUMP_INF(data, len, "Payload: ");
}
Expand Down
45 changes: 45 additions & 0 deletions subsys/lorawan/lorawan.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ K_MUTEX_DEFINE(lorawan_send_mutex);
static enum lorawan_datarate default_datarate;
static enum lorawan_datarate current_datarate;
static bool lorawan_adr_enable;
static bool lorawan_device_time_updated_once;

static sys_slist_t dl_callbacks;

Expand Down Expand Up @@ -162,9 +163,14 @@ static void mcps_indication_handler(McpsIndication_t *mcps_indication)
if (lorawan_adr_enable) {
datarate_observe(false);
}
/* Save time has been updated at least once */
if (!lorawan_device_time_updated_once && mcps_indication->DeviceTimeAnsReceived) {
lorawan_device_time_updated_once = true;
}

/* IsUplinkTxPending also indicates pending downlinks */
flags |= (mcps_indication->IsUplinkTxPending == 1 ? LORAWAN_DATA_PENDING : 0);
flags |= (mcps_indication->DeviceTimeAnsReceived ? LORAWAN_TIME_UPDATED : 0);

/* Iterate over all registered downlink callbacks */
SYS_SLIST_FOR_EACH_CONTAINER(&dl_callbacks, cb, node) {
Expand Down Expand Up @@ -202,6 +208,9 @@ static void mlme_confirm_handler(MlmeConfirm_t *mlme_confirm)
/* Not implemented */
LOG_INF("Link check not implemented yet!");
break;
case MLME_DEVICE_TIME:
LOG_INF("DevTimeReq done");
break;
default:
break;
}
Expand Down Expand Up @@ -382,6 +391,42 @@ int lorawan_set_region(enum lorawan_region region)
return 0;
}

int lorawan_request_device_time(bool force_request)
{
int ret = 0;
LoRaMacStatus_t status;
MlmeReq_t mlme_req;

mlme_req.Type = MLME_DEVICE_TIME;
status = LoRaMacMlmeRequest(&mlme_req);
if (status != LORAMAC_STATUS_OK) {
LOG_ERR("DeviceTime Req. failed: %s", lorawan_status2str(status));
ret = lorawan_status2errno(status);
return ret;
}

if (force_request) {
ret = lorawan_send(0U, "", 0U, LORAWAN_MSG_UNCONFIRMED);
}

return ret;
}

int lorawan_device_time_get(uint32_t *gps_time)
{
SysTime_t local_time;

__ASSERT(gps_time != NULL, "gps_time parameter is required");

if (lorawan_device_time_updated_once) {
local_time = SysTimeGet();
*gps_time = local_time.Seconds - UNIX_GPS_EPOCH_OFFSET;
return 0;
} else {
return -EAGAIN;
}
}

int lorawan_join(const struct lorawan_join_config *join_cfg)
{
MibRequestConfirm_t mib_req;
Expand Down

0 comments on commit ae0c1b7

Please sign in to comment.