Sync while working on OT
All checks were successful
Deploy Docs / build-and-deploy (push) Successful in 12s
All checks were successful
Deploy Docs / build-and-deploy (push) Successful in 12s
This commit is contained in:
@@ -3,6 +3,7 @@ menuconfig GAME_MGMT
|
||||
# select BT
|
||||
select OPENTHREAD
|
||||
select OPENTHREAD_COAP
|
||||
select LASERTAG_UTILS
|
||||
help
|
||||
Library for managing game states and logic in the lasertag device.
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ typedef struct __packed
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t start_time; // lower 32 bits of the start time in the open thread timer
|
||||
uint32_t start_time; // lower 32 bits of OpenThread network time in microseconds
|
||||
uint32_t duration; // in seconds, maximum 49 days (2^32 seconds), should be sufficient for any match ;)
|
||||
} start_game;
|
||||
struct
|
||||
|
||||
@@ -9,14 +9,18 @@
|
||||
#include <stdlib.h>
|
||||
#include <thread_mgmt.h>
|
||||
#include <game_mgmt.h>
|
||||
#include <lasertag_utils.h>
|
||||
|
||||
LOG_MODULE_REGISTER(game_mgmt, CONFIG_GAME_MGMT_LOG_LEVEL);
|
||||
|
||||
// Global variables
|
||||
static sys_state_t current_state = SYS_STATE_IDLE;
|
||||
static uint64_t current_game_id = 0;
|
||||
static struct k_work_delayable game_state_work;
|
||||
|
||||
// Forward declarations
|
||||
int game_mgmt_init_coap(void);
|
||||
otInstance *openthread_get_default_instance(void);
|
||||
void game_start_handler(struct k_work *work);
|
||||
|
||||
static otInstance *game_mgmt_get_instance(void)
|
||||
{
|
||||
@@ -59,6 +63,18 @@ static int ot_error_to_errno(otError err)
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t game_mgmt_expand_t32_us(uint32_t t32_us, uint64_t now_us)
|
||||
{
|
||||
uint64_t expanded_us = (now_us & 0xFFFFFFFF00000000ULL) | t32_us;
|
||||
|
||||
if (expanded_us < now_us)
|
||||
{
|
||||
expanded_us += (1ULL << 32);
|
||||
}
|
||||
|
||||
return expanded_us;
|
||||
}
|
||||
|
||||
static int game_mgmt_send_control_to(const otIp6Address *peer_addr, const game_control_payload_t *payload)
|
||||
{
|
||||
otInstance *instance = game_mgmt_get_instance();
|
||||
@@ -129,6 +145,31 @@ static int game_mgmt_send_control_to(const otIp6Address *peer_addr, const game_c
|
||||
return 0;
|
||||
}
|
||||
|
||||
void schedule_game_start(uint64_t startTime_us)
|
||||
{
|
||||
uint64_t now_us;
|
||||
|
||||
now_us = thread_mgmt_get_network_time();
|
||||
if (now_us == 0) {
|
||||
LOG_ERR("Cannot schedule game start: Network time not synchronized");
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t delay_us = (int64_t)(startTime_us - now_us);
|
||||
|
||||
if (delay_us > 0) {
|
||||
k_work_init_delayable(&game_state_work, game_start_handler);
|
||||
|
||||
k_work_reschedule(&game_state_work, K_USEC(delay_us));
|
||||
|
||||
printk("Game scheduled in %lld ms\n", delay_us / 1000);
|
||||
} else {
|
||||
// Start time is in the past -> execute immediately
|
||||
k_work_init_delayable(&game_state_work, game_start_handler);
|
||||
k_work_submit(&game_state_work.work);
|
||||
}
|
||||
}
|
||||
|
||||
int game_mgmt_send_control_multicast(const game_control_payload_t *payload)
|
||||
{
|
||||
otIp6Address multicast_addr;
|
||||
@@ -239,6 +280,10 @@ static void handle_game_control(void *aContext, otMessage *aMessage, const otMes
|
||||
LOG_DBG("Broadcast received: start time 0x%08X, duration %u s",
|
||||
payload.data.start_game.start_time,
|
||||
payload.data.start_game.duration);
|
||||
|
||||
uint64_t now_us = thread_mgmt_get_network_time();
|
||||
uint64_t start_time_us = game_mgmt_expand_t32_us(payload.data.start_game.start_time, now_us);
|
||||
schedule_game_start(start_time_us);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -272,6 +317,12 @@ int game_mgmt_init_coap(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void game_start_handler(struct k_work *work)
|
||||
{
|
||||
ARG_UNUSED(work);
|
||||
LOG_INF(FORMAT_BLUE_BOLD("Game start handler triggered"));
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_GAME_MGMT_SHELL)
|
||||
#include <zephyr/shell/shell.h>
|
||||
|
||||
@@ -298,6 +349,7 @@ static int cmd_game_start(const struct shell *sh, size_t argc, char **argv)
|
||||
}
|
||||
|
||||
shell_print(sh, "Start broadcast sent for T+%u s.", delay_s);
|
||||
schedule_game_start(game_mgmt_expand_t32_us(payload.data.start_game.start_time, now));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user