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:
parent
4fe072f2d3
commit
bfcdf4c354
26 changed files with 917 additions and 128 deletions
|
@ -25,5 +25,6 @@
|
|||
SystemKResult_T BLE_GetMyAddress(uint8_t * BD_ADDR);
|
||||
SystemKResult_T BLE_ScanAndAdvertise(void);
|
||||
SystemKResult_T BLE_SetAdvertisingData(BLE_AdvertisingData_T * data);
|
||||
SystemKResult_T BLE_StopAdvertising(void);
|
||||
|
||||
#endif // BLE_HW_INTERFACE_H
|
||||
|
|
|
@ -49,11 +49,14 @@ static PacketTracker_T Tracker =
|
|||
.head = 0,
|
||||
};
|
||||
|
||||
// A packet is _new_ if the combination of BLE adress, type, and event number have not been seen recently.
|
||||
// A packet is _new_ if the combination of BLE address, type, and event number have not been seen recently.
|
||||
bool BLE_IsPacketNew(const uint8_t *sender_BD_ADDR,
|
||||
BLE_PacketType_T packet_type,
|
||||
uint8_t event_number)
|
||||
{
|
||||
//esp_log_level_set("BLE", ESP_LOG_DEBUG);
|
||||
//KLOG_DEBUG("BLE", "Packet from %s", BLE_ADDR_To_Str(sender_BD_ADDR));
|
||||
|
||||
// Check if the packet already exists in the tracker.
|
||||
for (int i = 0; i < Tracker.count; i++)
|
||||
{
|
||||
|
|
|
@ -147,17 +147,19 @@ void BLE_UpdateInstigationPacket(uint32_t Game_Length_in_ms, uint32_t Time_Remai
|
|||
}
|
||||
}
|
||||
|
||||
void BLE_UpdateStatusPacket()
|
||||
void BLE_UpdateStatusPacket(uint8_t current_state)
|
||||
{
|
||||
static uint8_t EventNumber = 0;
|
||||
|
||||
uint8_t team_ID;
|
||||
uint8_t player_ID;
|
||||
uint8_t weapon_ID;
|
||||
uint32_t secondary_color;
|
||||
Protocol_T protocol;
|
||||
(void) SETTINGS_get_uint8_t(SYSTEMK_SETTING_TEAMID, &team_ID);
|
||||
(void) SETTINGS_get_uint8_t(SYSTEMK_SETTING_PLAYERID, &player_ID);
|
||||
(void) SETTINGS_get_uint8_t(SYSTEMK_SETTING_WEAPONID, &weapon_ID);
|
||||
(void) SETTINGS_get_uint32_t(SYSTEMK_SETTING_SECONDARY_COLOR, &secondary_color);
|
||||
protocol = GetWeaponFromID(weapon_ID).Protocol;
|
||||
uint32_t Team_Color = (uint32_t)PROTOCOLS_GetColor(protocol, team_ID, player_ID);
|
||||
|
||||
|
@ -180,17 +182,17 @@ void BLE_UpdateStatusPacket()
|
|||
Advertising_Data.data[13] = player_ID;
|
||||
Advertising_Data.data[14] = Get_Health();
|
||||
Advertising_Data.data[15] = 0x00;
|
||||
Advertising_Data.data[16] = MAX_HEALTH;
|
||||
Advertising_Data.data[16] = Get_Max_Health();
|
||||
Advertising_Data.data[17] = 0x00;
|
||||
Advertising_Data.data[18] = (Team_Color >> 0) & 0xFF;
|
||||
Advertising_Data.data[19] = (Team_Color >> 8) & 0xFF;
|
||||
Advertising_Data.data[20] = (Team_Color >> 16) & 0xFF;
|
||||
Advertising_Data.data[21] = (Team_Color >> 24) & 0xFF;
|
||||
Advertising_Data.data[22] = (Team_Color >> 0) & 0xFF; // Secondary Color
|
||||
Advertising_Data.data[23] = (Team_Color >> 8) & 0xFF; // Secondary Color
|
||||
Advertising_Data.data[24] = (Team_Color >> 16) & 0xFF; // Secondary Color
|
||||
Advertising_Data.data[25] = (Team_Color >> 24) & 0xFF; // Secondary Color
|
||||
Advertising_Data.data[26] = 0xFF;
|
||||
Advertising_Data.data[22] = (secondary_color >> 0) & 0xFF;
|
||||
Advertising_Data.data[23] = (secondary_color >> 8) & 0xFF;
|
||||
Advertising_Data.data[24] = (secondary_color >> 16) & 0xFF;
|
||||
Advertising_Data.data[25] = (secondary_color >> 24) & 0xFF;
|
||||
Advertising_Data.data[26] = current_state;
|
||||
Advertising_Data.data[27] = 0xFF;
|
||||
Advertising_Data.data[28] = 0xFF;
|
||||
Advertising_Data.data[29] = 0xFF;
|
||||
|
@ -237,12 +239,12 @@ void BLE_UpdateTagPacket(int16_t damage, color_t color, uint8_t target_BD_ADDR[B
|
|||
Advertising_Data.data[17] = (color >> 8) & 0xFF;
|
||||
Advertising_Data.data[18] = (color >> 16) & 0xFF;
|
||||
Advertising_Data.data[19] = (color >> 24) & 0xFF;
|
||||
Advertising_Data.data[20] = target_BD_ADDR[0],
|
||||
Advertising_Data.data[21] = target_BD_ADDR[1],
|
||||
Advertising_Data.data[22] = target_BD_ADDR[2],
|
||||
Advertising_Data.data[23] = target_BD_ADDR[3],
|
||||
Advertising_Data.data[24] = target_BD_ADDR[4],
|
||||
Advertising_Data.data[25] = target_BD_ADDR[5],
|
||||
Advertising_Data.data[20] = target_BD_ADDR[0];
|
||||
Advertising_Data.data[21] = target_BD_ADDR[1];
|
||||
Advertising_Data.data[22] = target_BD_ADDR[2];
|
||||
Advertising_Data.data[23] = target_BD_ADDR[3];
|
||||
Advertising_Data.data[24] = target_BD_ADDR[4];
|
||||
Advertising_Data.data[25] = target_BD_ADDR[5];
|
||||
Advertising_Data.data[26] = 0xFF;
|
||||
Advertising_Data.data[27] = 0xFF;
|
||||
Advertising_Data.data[28] = 0xFF;
|
||||
|
@ -257,6 +259,168 @@ void BLE_UpdateTagPacket(int16_t damage, color_t color, uint8_t target_BD_ADDR[B
|
|||
}
|
||||
}
|
||||
|
||||
//! Event number used for all BLE_PACKET_TYPE_PARAMETERS packets.
|
||||
static uint8_t ParametersEventNumber = 0;
|
||||
|
||||
void BLE_RespondToConfigurationPacket(const BLE_ParametersPacket_T *const packet, BLE_ConfigurationSubtype_T response)
|
||||
{
|
||||
Advertising_Data.length = BLE_KTAG_PACKET_TOTAL_SIZE;
|
||||
|
||||
// Manufacturer Specific Data
|
||||
Advertising_Data.data[0] = 0x1E;
|
||||
Advertising_Data.data[1] = 0xFF;
|
||||
Advertising_Data.data[2] = 0xFF;
|
||||
Advertising_Data.data[3] = 0xFF;
|
||||
Advertising_Data.data[4] = 'K';
|
||||
Advertising_Data.data[5] = 'T';
|
||||
Advertising_Data.data[6] = 'a';
|
||||
Advertising_Data.data[7] = 'g';
|
||||
Advertising_Data.data[8] = BLE_PACKET_TYPE_PARAMETERS;
|
||||
Advertising_Data.data[9] = ParametersEventNumber++;
|
||||
Advertising_Data.data[10] = packet->BD_ADDR[0];
|
||||
Advertising_Data.data[11] = packet->BD_ADDR[1];
|
||||
Advertising_Data.data[12] = packet->BD_ADDR[2];
|
||||
Advertising_Data.data[13] = packet->BD_ADDR[3];
|
||||
Advertising_Data.data[14] = packet->BD_ADDR[4];
|
||||
Advertising_Data.data[15] = packet->BD_ADDR[5];
|
||||
Advertising_Data.data[16] = (uint8_t)response;
|
||||
Advertising_Data.data[17] = (uint8_t)((packet->key_one >> 0) & 0xFF);
|
||||
Advertising_Data.data[18] = (uint8_t)((packet->key_one >> 8) & 0xFF);
|
||||
Advertising_Data.data[19] = (uint8_t)((packet->value_one >> 0) & 0xFF);
|
||||
Advertising_Data.data[20] = (uint8_t)((packet->value_one >> 8) & 0xFF);
|
||||
Advertising_Data.data[21] = (uint8_t)((packet->value_one >> 16) & 0xFF);
|
||||
Advertising_Data.data[22] = (uint8_t)((packet->value_one >> 24) & 0xFF);
|
||||
Advertising_Data.data[23] = (uint8_t)((packet->key_two >> 0) & 0xFF);
|
||||
Advertising_Data.data[24] = (uint8_t)((packet->key_two >> 8) & 0xFF);
|
||||
Advertising_Data.data[25] = (uint8_t)((packet->value_two >> 0) & 0xFF);
|
||||
Advertising_Data.data[26] = (uint8_t)((packet->value_two >> 8) & 0xFF);
|
||||
Advertising_Data.data[27] = (uint8_t)((packet->value_two >> 16) & 0xFF);
|
||||
Advertising_Data.data[28] = (uint8_t)((packet->value_two >> 24) & 0xFF);
|
||||
Advertising_Data.data[29] = 0xFF;
|
||||
Advertising_Data.data[30] = 0xFF;
|
||||
|
||||
SystemKResult_T result = BLE_SetAdvertisingData(&Advertising_Data);
|
||||
|
||||
if (result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
KLOG_ERROR(KLOG_TAG, "Error responding to configuration packet!");
|
||||
}
|
||||
|
||||
if (BLE_ScanAndAdvertise() != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
KLOG_ERROR(KLOG_TAG, "Couldn't scan and advertise!");
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
Advertising_Data.length = BLE_KTAG_PACKET_TOTAL_SIZE;
|
||||
|
||||
// Manufacturer Specific Data
|
||||
Advertising_Data.data[0] = 0x1E;
|
||||
Advertising_Data.data[1] = 0xFF;
|
||||
Advertising_Data.data[2] = 0xFF;
|
||||
Advertising_Data.data[3] = 0xFF;
|
||||
Advertising_Data.data[4] = 'K';
|
||||
Advertising_Data.data[5] = 'T';
|
||||
Advertising_Data.data[6] = 'a';
|
||||
Advertising_Data.data[7] = 'g';
|
||||
Advertising_Data.data[8] = BLE_PACKET_TYPE_PARAMETERS;
|
||||
Advertising_Data.data[9] = ParametersEventNumber++;
|
||||
Advertising_Data.data[10] = BLE_BROADCAST_ADDRESS[0];
|
||||
Advertising_Data.data[11] = BLE_BROADCAST_ADDRESS[1];
|
||||
Advertising_Data.data[12] = BLE_BROADCAST_ADDRESS[2];
|
||||
Advertising_Data.data[13] = BLE_BROADCAST_ADDRESS[3];
|
||||
Advertising_Data.data[14] = BLE_BROADCAST_ADDRESS[4];
|
||||
Advertising_Data.data[15] = BLE_BROADCAST_ADDRESS[5];
|
||||
Advertising_Data.data[16] = BLE_CURRENT_PARAMETER_INFORMATION;
|
||||
Advertising_Data.data[17] = (uint8_t)((key_one >> 0) & 0xFF);
|
||||
Advertising_Data.data[18] = (uint8_t)((key_one >> 8) & 0xFF);
|
||||
Advertising_Data.data[19] = (uint8_t)((value_one >> 0) & 0xFF);
|
||||
Advertising_Data.data[20] = (uint8_t)((value_one >> 8) & 0xFF);
|
||||
Advertising_Data.data[21] = (uint8_t)((value_one >> 16) & 0xFF);
|
||||
Advertising_Data.data[22] = (uint8_t)((value_one >> 24) & 0xFF);
|
||||
Advertising_Data.data[23] = (uint8_t)((key_two >> 0) & 0xFF);
|
||||
Advertising_Data.data[24] = (uint8_t)((key_two >> 8) & 0xFF);
|
||||
Advertising_Data.data[25] = (uint8_t)((value_two >> 0) & 0xFF);
|
||||
Advertising_Data.data[26] = (uint8_t)((value_two >> 8) & 0xFF);
|
||||
Advertising_Data.data[27] = (uint8_t)((value_two >> 16) & 0xFF);
|
||||
Advertising_Data.data[28] = (uint8_t)((value_two >> 24) & 0xFF);
|
||||
Advertising_Data.data[29] = 0xFF;
|
||||
Advertising_Data.data[30] = 0xFF;
|
||||
|
||||
SystemKResult_T result = BLE_SetAdvertisingData(&Advertising_Data);
|
||||
|
||||
if (result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
KLOG_ERROR(KLOG_TAG, "Error responding to configuration packet!");
|
||||
}
|
||||
}
|
||||
|
||||
void BLE_UpdateHelloPacket()
|
||||
{
|
||||
static uint8_t EventNumber = 0;
|
||||
|
||||
uint32_t device_type32;
|
||||
uint16_t device_type = BLE_DEVICE_TYPE_UNKNOWN;
|
||||
if (SETTINGS_get_uint32_t(SYSTEMK_SETTING_DEVICE_TYPE, &device_type32) == SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
device_type = (uint16_t)device_type32;
|
||||
}
|
||||
|
||||
uint8_t team_ID;
|
||||
(void) SETTINGS_get_uint8_t(SYSTEMK_SETTING_TEAMID, &team_ID);
|
||||
|
||||
char device_name[SYSTEMK_MAX_CHARS_IN_DEVICE_NAME + 1];
|
||||
SystemKResult_T result = SETTINGS_get_device_name(&device_name[0]);
|
||||
if (result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
strcpy(device_name, "Anonymous");
|
||||
}
|
||||
|
||||
Advertising_Data.length = BLE_KTAG_PACKET_TOTAL_SIZE;
|
||||
|
||||
// Manufacturer Specific Data
|
||||
Advertising_Data.data[0] = 0x1E;
|
||||
Advertising_Data.data[1] = 0xFF;
|
||||
Advertising_Data.data[2] = 0xFF;
|
||||
Advertising_Data.data[3] = 0xFF;
|
||||
Advertising_Data.data[4] = 'K';
|
||||
Advertising_Data.data[5] = 'T';
|
||||
Advertising_Data.data[6] = 'a';
|
||||
Advertising_Data.data[7] = 'g';
|
||||
Advertising_Data.data[8] = BLE_PACKET_TYPE_HELLO;
|
||||
Advertising_Data.data[9] = EventNumber++;
|
||||
Advertising_Data.data[10] = SYSTEMK_MAJOR_VERSION;
|
||||
Advertising_Data.data[11] = SYSTEMK_MINOR_VERSION;
|
||||
Advertising_Data.data[12] = (device_type >> 0) & 0xFF;
|
||||
Advertising_Data.data[13] = (device_type >> 8) & 0xFF;
|
||||
Advertising_Data.data[14] = team_ID;
|
||||
Advertising_Data.data[15] = device_name[0];
|
||||
Advertising_Data.data[16] = device_name[1];
|
||||
Advertising_Data.data[17] = device_name[2];
|
||||
Advertising_Data.data[18] = device_name[3];
|
||||
Advertising_Data.data[19] = device_name[4];
|
||||
Advertising_Data.data[20] = device_name[5];
|
||||
Advertising_Data.data[21] = device_name[6];
|
||||
Advertising_Data.data[22] = device_name[7];
|
||||
Advertising_Data.data[23] = device_name[8];
|
||||
Advertising_Data.data[24] = device_name[9];
|
||||
Advertising_Data.data[25] = device_name[10];
|
||||
Advertising_Data.data[26] = device_name[11];
|
||||
Advertising_Data.data[27] = device_name[12];
|
||||
Advertising_Data.data[28] = device_name[13];
|
||||
Advertising_Data.data[29] = device_name[14];
|
||||
Advertising_Data.data[30] = device_name[15];
|
||||
|
||||
result = BLE_SetAdvertisingData(&Advertising_Data);
|
||||
|
||||
if (result != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
KLOG_ERROR(KLOG_TAG, "Error updating hello packet!");
|
||||
}
|
||||
}
|
||||
|
||||
bool BLE_IsBLEPacketForMe(const uint8_t BD_ADDR[6])
|
||||
{
|
||||
bool for_me = false;
|
||||
|
@ -286,12 +450,12 @@ bool BLE_IsBLEPacketForMe(const uint8_t BD_ADDR[6])
|
|||
}
|
||||
|
||||
// Is this the broadcast address?
|
||||
if ((BD_ADDR[0] == 0xFF) &&
|
||||
(BD_ADDR[1] == 0xFF) &&
|
||||
(BD_ADDR[2] == 0xFF) &&
|
||||
(BD_ADDR[3] == 0xFF) &&
|
||||
(BD_ADDR[4] == 0xFF) &&
|
||||
(BD_ADDR[5] == 0xFF))
|
||||
if ((BD_ADDR[0] == BLE_BROADCAST_ADDRESS[0]) &&
|
||||
(BD_ADDR[1] == BLE_BROADCAST_ADDRESS[1]) &&
|
||||
(BD_ADDR[2] == BLE_BROADCAST_ADDRESS[2]) &&
|
||||
(BD_ADDR[3] == BLE_BROADCAST_ADDRESS[3]) &&
|
||||
(BD_ADDR[4] == BLE_BROADCAST_ADDRESS[4]) &&
|
||||
(BD_ADDR[5] == BLE_BROADCAST_ADDRESS[5]))
|
||||
{
|
||||
for_me = true;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
54
BLE/BLE_Utils.c
Normal file
54
BLE/BLE_Utils.c
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* This program source code file is part of SystemK, a library in the KTag project.
|
||||
*
|
||||
* 🛡️ <https://ktag.clubk.club> 🃞
|
||||
*
|
||||
* Copyright © 2025 Joseph P. Kearney and the KTag developers.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* There should be a copy of the GNU Affero General Public License in the LICENSE
|
||||
* file in the root of this repository. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
const uint8_t BLE_BROADCAST_ADDRESS[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
|
||||
//! Converts a 6-byte Bluetooth Low Energy address to a human-readable string (for logging).
|
||||
/*!
|
||||
* \param bd_addr The Bluetooth address as a 6-byte array
|
||||
* \return Pointer to a static string containing the formatted address
|
||||
*
|
||||
* Output format: "XX:XX:XX:XX:XX:XX" where XX are uppercase hexadecimal values
|
||||
* \note This function is not reentrant as it uses a static buffer!
|
||||
*/
|
||||
const char *BLE_ADDR_To_Str(const uint8_t bd_addr[6])
|
||||
{
|
||||
static char str_addr[18]; // 17 characters + null terminator
|
||||
|
||||
// Convert each byte and add separating colons.
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
snprintf(&str_addr[i * 3], sizeof(str_addr) - (i * 3), "%02X", bd_addr[5-i]);
|
||||
|
||||
// Add colon separator except after the last byte.
|
||||
if (i < 5)
|
||||
{
|
||||
str_addr[(i * 3) + 2] = ':';
|
||||
}
|
||||
}
|
||||
|
||||
str_addr[17] = '\0'; // Ensure null termination.
|
||||
return str_addr;
|
||||
}
|
24
BLE/BLE_Utils.h
Normal file
24
BLE/BLE_Utils.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* This program source code file is part of SystemK, a library in the KTag project.
|
||||
*
|
||||
* 🛡️ <https://ktag.clubk.club> 🃞
|
||||
*
|
||||
* Copyright © 2025 Joseph P. Kearney and the KTag developers.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* There should be a copy of the GNU Affero General Public License in the LICENSE
|
||||
* file in the root of this repository. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
extern const uint8_t BLE_BROADCAST_ADDRESS[6];
|
||||
|
||||
const char* BLE_ADDR_To_Str(const uint8_t bd_addr[6]);
|
Loading…
Add table
Add a link
Reference in a new issue