Reworked BLE according to v0.11 of the KTag Beacon Specification (#2)

This was done to support the new KTag Konfigurator app, which Jack created for his Senior Design project.

Co-authored-by: Joe Kearney <joe@clubk.club>
Reviewed-on: #2
This commit is contained in:
Joe Kearney 2025-06-08 21:52:29 +00:00
parent 4fe072f2d3
commit bfcdf4c354
26 changed files with 917 additions and 128 deletions

View file

@ -29,7 +29,8 @@
#define BLE_PACKETS_H
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
/* Preprocessor and Type Definitions */
@ -59,11 +60,13 @@ typedef enum
BLE_PACKET_TYPE_BUFFER_FREE = 0,
BLE_PACKET_TYPE_INSTIGATE_GAME = 1,
BLE_FIRST_VALID_PACKET_TYPE = BLE_PACKET_TYPE_INSTIGATE_GAME,
BLE_PACKET_TYPE_JOIN_NOW = 2,
BLE_PACKET_TYPE_EVENT = 2,
BLE_PACKET_TYPE_TAG = 3,
BLE_PACKET_TYPE_CONSOLE = 4,
BLE_PACKET_TYPE_STATUS = 5,
BLE_LAST_VALID_PACKET_TYPE = BLE_PACKET_TYPE_STATUS,
BLE_PACKET_TYPE_PARAMETERS = 6,
BLE_PACKET_TYPE_HELLO = 7,
BLE_LAST_VALID_PACKET_TYPE = BLE_PACKET_TYPE_HELLO,
BLE_PACKET_TYPE_UNKNOWN
} BLE_PacketType_T;
@ -73,7 +76,7 @@ typedef struct
uint8_t BD_ADDR[BD_ADDR_SIZE];
int8_t RSSI;
uint8_t event_number;
uint8_t data[BLE_KTAG_PACKET_DATA_SIZE];
} __attribute__((packed, aligned(1))) BLE_GenericPacketType_T;
@ -84,25 +87,35 @@ typedef struct
uint8_t BD_ADDR[BD_ADDR_SIZE];
int8_t RSSI;
uint8_t event_number;
uint32_t game_length_in_ms;
uint32_t time_remaining_until_countdown_in_ms;
uint8_t random_time_after_countdown_in_ms_x100;
uint8_t unused[12];
uint8_t unused[13];
} __attribute__((packed, aligned(1))) BLE_InstigationPacket_T;
//! Contents of the BLE packet #BLE_PACKET_TYPE_JOIN_NOW.
typedef enum
{
BLE_EVENT_NO_EVENT = 0,
BLE_EVENT_CONFIGURE = 1,
BLE_EVENT_CONFIGURED = 2,
BLE_EVENT_WRAPUP_COMPLETE = 3,
BLE_EVENT_GAME_OVER = 4,
BLE_EVENT_UNUSED = 0xFFFFFFFF
} BLE_EventID_T;
//! Contents of the BLE packet #BLE_PACKET_TYPE_EVENT.
typedef struct
{
BLE_PacketType_T type;
uint8_t BD_ADDR[BD_ADDR_SIZE];
int8_t RSSI;
uint8_t event_number;
uint32_t game_length_in_ms;
uint32_t time_remaining_in_game_in_ms;
uint8_t unused[13];
} __attribute__((packed, aligned(1))) BLE_JoinNowPacket_T;
uint8_t target_BD_ADDR[BD_ADDR_SIZE];
uint32_t event_ID;
uint32_t event_data;
uint8_t unused[7];
} __attribute__((packed, aligned(1))) BLE_EventPacket_T;
//! Contents of the BLE packet #BLE_PACKET_TYPE_TAG.
typedef struct
@ -120,7 +133,7 @@ typedef struct
color_t color;
uint8_t target_BD_ADDR[BD_ADDR_SIZE];
uint8_t unused[5];
} __attribute__((packed, aligned(1)))BLE_TagPacket_T;
} __attribute__((packed, aligned(1))) BLE_TagPacket_T;
//! Contents of the BLE packet #BLE_PACKET_TYPE_CONSOLE.
typedef struct
@ -129,9 +142,9 @@ typedef struct
uint8_t BD_ADDR[BD_ADDR_SIZE];
int8_t RSSI;
uint8_t event_number;
uint8_t console_data[BLE_KTAG_PACKET_DATA_SIZE];
} __attribute__((packed, aligned(1)))BLE_ConsolePacket_T;
} __attribute__((packed, aligned(1))) BLE_ConsolePacket_T;
//! Contents of the BLE packet #BLE_PACKET_TYPE_STATUS.
typedef struct
@ -140,7 +153,7 @@ typedef struct
uint8_t BD_ADDR[BD_ADDR_SIZE];
int8_t RSSI;
uint8_t event_number;
int8_t tx_power_level;
uint8_t protocol;
uint8_t team_ID;
@ -149,17 +162,116 @@ typedef struct
uint16_t maximum_health;
color_t primary_color;
color_t secondary_color;
uint8_t unused[5];
} __attribute__((packed, aligned(1)))BLE_StatusPacket_T;
uint8_t SystemK_top_level_state; // StateID_T
uint8_t unused[4];
} __attribute__((packed, aligned(1))) BLE_StatusPacket_T;
typedef enum
{
BLE_REQUEST_CURRENT_PARAMETER_INFORMATION = 0x00,
BLE_CURRENT_PARAMETER_INFORMATION = 0x01,
BLE_REQUEST_PARAMETER_CHANGE = 0x02,
BLE_ACKNOWLEDGE_PARAMETER_CHANGE = 0x03,
BLE_ERROR_CHANGING_PARAMETERS = 0x04,
BLE_ERROR_RESPONDING_TO_REQUEST = 0xFF
} BLE_ConfigurationSubtype_T;
typedef enum
{
BLE_PARAMETER_KEY_NONE = 0,
BLE_PARAMETER_KEY_TEAM_ID = 1,
BLE_PARAMETER_KEY_PLAYER_ID = 2,
BLE_PARAMETER_KEY_GAME_LENGTH = 3,
BLE_PARAMETER_KEY_MAX_HEALTH = 4,
BLE_PARAMETER_KEY_SECONDARY_COLOR = 5,
BLE_PARAMETER_KEY_SPECIAL_WEAPONS_ON_REENTRY = 6,
BLE_FIRST_VALID_CONFIGURATION_KEY = BLE_PARAMETER_KEY_TEAM_ID,
BLE_LAST_VALID_CONFIGURATION_KEY = BLE_PARAMETER_KEY_SPECIAL_WEAPONS_ON_REENTRY,
BLE_PARAMETER_KEY_SHOTS_FIRED_THIS_GAME = 10001,
BLE_PARAMETER_KEY_TAGS_RECEIVED_THIS_GAME = 10002,
BLE_PARAMETER_KEY_TIMES_TAGGED_OUT_THIS_GAME = 10003,
BLE_FIRST_VALID_GAME_RESULT_KEY = BLE_PARAMETER_KEY_SHOTS_FIRED_THIS_GAME,
BLE_LAST_VALID_GAME_RESULT_KEY = BLE_PARAMETER_KEY_TIMES_TAGGED_OUT_THIS_GAME,
BLE_PARAMETER_KEY_UNUSED = 65535
} BLE_ParameterKey_T;
inline BLE_ParameterKey_T BLE_GetValidConfigKey(uint16_t key)
{
BLE_ParameterKey_T result = BLE_PARAMETER_KEY_NONE;
if ((key >= BLE_FIRST_VALID_CONFIGURATION_KEY) &&
(key <= BLE_LAST_VALID_CONFIGURATION_KEY))
{
result = (BLE_ParameterKey_T)key;
}
return result;
}
inline BLE_ParameterKey_T BLE_GetValidGameResultKey(uint16_t key)
{
BLE_ParameterKey_T result = BLE_PARAMETER_KEY_NONE;
if ((key >= BLE_FIRST_VALID_GAME_RESULT_KEY) &&
(key <= BLE_LAST_VALID_GAME_RESULT_KEY))
{
result = (BLE_ParameterKey_T)key;
}
return result;
}
//! Contents of the BLE packet #BLE_PACKET_TYPE_PARAMETERS.
typedef struct
{
BLE_PacketType_T type;
uint8_t BD_ADDR[BD_ADDR_SIZE];
int8_t RSSI;
uint8_t event_number;
uint8_t target_BD_ADDR[BD_ADDR_SIZE];
uint8_t subtype;
uint16_t key_one;
uint32_t value_one;
uint16_t key_two;
uint32_t value_two;
uint8_t unused[2];
} __attribute__((packed, aligned(1))) BLE_ParametersPacket_T;
typedef enum
{
BLE_DEVICE_TYPE_LITTLE_BOY_BLUE = 0x0000,
BLE_DEVICE_TYPE_2020TPC = 0x0001,
BLE_DEVICE_TYPE_MOBILE_APP = 0x0002,
BLE_DEVICE_TYPE_32ESPECIAL = 0x0003,
BLE_DEVICE_TYPE_UNKNOWN = 0xFFFF
} BLE_DeviceType_T;
//! Contents of the BLE packet #BLE_PACKET_TYPE_HELLO.
typedef struct
{
BLE_PacketType_T type;
uint8_t BD_ADDR[BD_ADDR_SIZE];
int8_t RSSI;
uint8_t event_number;
uint8_t SystemK_major_version;
uint8_t SystemK_minor_version;
uint16_t device_type;
uint8_t team_ID;
uint8_t device_name[SYSTEMK_MAX_CHARS_IN_DEVICE_NAME];
} __attribute__((packed, aligned(1))) BLE_HelloPacket_T;
typedef union
{
BLE_GenericPacketType_T Generic;
BLE_InstigationPacket_T Instigation;
BLE_JoinNowPacket_T JoinNow;
BLE_EventPacket_T Event;
BLE_TagPacket_T Tag;
BLE_ConsolePacket_T Console;
BLE_StatusPacket_T Status;
BLE_ParametersPacket_T Configuration;
BLE_HelloPacket_T Hello;
} BLE_Packet_T;
/* Include Files */
@ -168,20 +280,23 @@ typedef union
/* Public Functions */
inline void BLE_FreePacketBuffer(void * buffer)
inline void BLE_FreePacketBuffer(BLE_GenericPacketType_T *buffer)
{
if (buffer != NULL)
{
((BLE_GenericPacketType_T *)buffer)->type = BLE_PACKET_TYPE_BUFFER_FREE;
buffer->type = BLE_PACKET_TYPE_BUFFER_FREE;
}
}
void BLE_InitPacketBuffers(void);
BLE_Packet_T * BLE_DecodeKTagPacket(const uint8_t * received_data, uint8_t received_data_length, uint8_t peer_BD_ADDR[BD_ADDR_SIZE], int8_t rssi_in_dBm);
BLE_Packet_T *BLE_DecodeKTagPacket(const uint8_t *received_data, uint8_t received_data_length, uint8_t peer_BD_ADDR[BD_ADDR_SIZE], int8_t rssi_in_dBm);
void BLE_UpdateInstigationPacket(uint32_t Game_Length_in_ms, uint32_t Time_Remaining_Until_Countdown_in_ms);
void BLE_UpdateStatusPacket();
void BLE_UpdateStatusPacket(uint8_t current_state);
void BLE_UpdateTagPacket(int16_t damage, color_t color, uint8_t target_BD_ADDR[BD_ADDR_SIZE]);
void BLE_RespondToConfigurationPacket(const BLE_ParametersPacket_T *const packet, BLE_ConfigurationSubtype_T response);
void BLE_BroadcastCurrentParameterInfoPacket(const BLE_ParameterKey_T key_one, const uint32_t value_one, const BLE_ParameterKey_T key_two, const uint32_t value_two);
void BLE_UpdateHelloPacket();
bool BLE_IsBLEPacketForMe(const uint8_t BD_ADDR[BD_ADDR_SIZE]);
#ifdef __cplusplus