diff --git a/BLE/BLE_Packets.c b/BLE/BLE_Packets.c index c2cc0a9..14a548c 100644 --- a/BLE/BLE_Packets.c +++ b/BLE/BLE_Packets.c @@ -147,7 +147,7 @@ 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; @@ -190,7 +190,7 @@ void BLE_UpdateStatusPacket() 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[26] = current_state; Advertising_Data.data[27] = 0xFF; Advertising_Data.data[28] = 0xFF; Advertising_Data.data[29] = 0xFF; @@ -237,12 +237,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 +257,74 @@ void BLE_UpdateTagPacket(int16_t damage, color_t color, uint8_t target_BD_ADDR[B } } +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"); + } + size_t len = strlen(device_name); + if (len < sizeof(device_name)) { + memset(device_name + len, 0x00, sizeof(device_name) - len); + } + + 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; diff --git a/BLE/BLE_Packets.h b/BLE/BLE_Packets.h index d1f0a03..d535b46 100644 --- a/BLE/BLE_Packets.h +++ b/BLE/BLE_Packets.h @@ -59,11 +59,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_CONFIGURATION = 6, + BLE_PACKET_TYPE_HELLO = 7, + BLE_LAST_VALID_PACKET_TYPE = BLE_PACKET_TYPE_HELLO, BLE_PACKET_TYPE_UNKNOWN } BLE_PacketType_T; @@ -87,11 +89,10 @@ typedef struct 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. +//! Contents of the BLE packet #BLE_PACKET_TYPE_EVENT. typedef struct { BLE_PacketType_T type; @@ -99,10 +100,11 @@ typedef struct 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 @@ -149,17 +151,61 @@ typedef struct uint16_t maximum_health; color_t primary_color; color_t secondary_color; - uint8_t unused[5]; + uint8_t SystemK_top_level_state; // StateID_T + uint8_t unused[4]; } __attribute__((packed, aligned(1)))BLE_StatusPacket_T; +//! Contents of the BLE packet #BLE_PACKET_TYPE_CONFIGURATION. +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_ConfigurationPacket_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_ConfigurationPacket_T Configuration; + BLE_HelloPacket_T Hello; } BLE_Packet_T; /* Include Files */ @@ -180,8 +226,9 @@ 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); 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_UpdateHelloPacket(); bool BLE_IsBLEPacketForMe(const uint8_t BD_ADDR[BD_ADDR_SIZE]); #ifdef __cplusplus diff --git a/Settings/Settings_Interface.h b/Settings/Settings_Interface.h index 4f80805..5074030 100644 --- a/Settings/Settings_Interface.h +++ b/Settings/Settings_Interface.h @@ -21,6 +21,8 @@ #ifndef SETTINGS_INTERFACE_H #define SETTINGS_INTERFACE_H + +#define SYSTEMK_MAX_CHARS_IN_DEVICE_NAME 15 typedef enum { @@ -29,13 +31,16 @@ typedef enum SYSTEMK_SETTING_TEAMID, SYSTEMK_SETTING_PLAYERID, SYSTEMK_SETTING_WEAPONID, - SYSTEMK_SETTING_T_START_GAME_in_ms + SYSTEMK_SETTING_T_START_GAME_in_ms, + SYSTEMK_SETTING_DEVICE_TYPE, } SystemKSettingID_T; SystemKResult_T SETTINGS_get_uint8_t(SystemKSettingID_T id, uint8_t * value); SystemKResult_T SETTINGS_set_uint8_t(SystemKSettingID_T id, uint8_t value); SystemKResult_T SETTINGS_get_uint32_t(SystemKSettingID_T id, uint32_t * value); SystemKResult_T SETTINGS_set_uint32_t(SystemKSettingID_T id, uint32_t value); +SystemKResult_T SETTINGS_get_device_name(char* name); +SystemKResult_T SETTINGS_set_device_name(char* name); SystemKResult_T SETTINGS_Save(void); #endif // SETTINGS_INTERFACE_H diff --git a/States/Playing/State_Playing.c b/States/Playing/State_Playing.c index 832d2c1..9efedcd 100644 --- a/States/Playing/State_Playing.c +++ b/States/Playing/State_Playing.c @@ -37,7 +37,8 @@ static const int_fast8_t TAG_RSSI_THRESHOLD = -75; static void BLEStatusTimerCallback(TimerHandle_t xTimer) { - BLE_UpdateStatusPacket(); + StateMachineContext_T* context = GetContext(); + BLE_UpdateStatusPacket(context->States.Current_State); } static void GameDurationTimerCallback(TimerHandle_t xTimer) @@ -60,7 +61,7 @@ void Playing_Entry(StateMachineContext_T *context) BLE_RXd_data.neighbors[slot].TimeToLive_in_ms = 0; } - BLE_UpdateStatusPacket(); + BLE_UpdateStatusPacket(context->States.Current_State); if (BLE_ScanAndAdvertise() != SYSTEMK_RESULT_SUCCESS) { KLOG_ERROR(KLOG_TAG, "Couldn't start BLE!"); @@ -92,7 +93,8 @@ void Playing_Entry(StateMachineContext_T *context) } // The timer is only needed for timed games. - if (Get_Time_Remaining_in_Game_in_ms() != UINT32_MAX) + if ((Get_Time_Remaining_in_Game_in_ms() != UINT32_MAX) && + (Get_Time_Remaining_in_Game_in_ms() != 0)) { if (GameDurationTimer == NULL) { @@ -129,7 +131,7 @@ void Playing_Exit(StateMachineContext_T *context) { LOG("Exiting the Playing state."); xTimerStop(BLEStatusTimer, portMAX_DELAY); - BLE_UpdateStatusPacket(); + BLE_UpdateStatusPacket(context->States.Next_State); } void HandleBLEStatusPacket(const BLE_StatusPacket_T *const packet) @@ -202,21 +204,25 @@ void HandleBLETagPacket(const BLE_TagPacket_T *const packet) { if (BLE_IsPacketNew(packet->BD_ADDR, BLE_PACKET_TYPE_TAG, packet->event_number)) { + Health_In_Percent = (int16_t)Get_Health(); + if (packet->damage > 0) { - Reduce_Health(packet->damage); + if (Health_In_Percent > 0) + { + Reduce_Health(packet->damage); - ReceivedTagColor = packet->color; + ReceivedTagColor = packet->color; - AudioAction_T audio_action = {.ID = AUDIO_PLAY_TAG_RECEIVED, .Data = (void *)0x00}; - Perform_Audio_Action(&audio_action); + AudioAction_T audio_action = {.ID = AUDIO_PLAY_TAG_RECEIVED, .Data = (void *)0x00}; + Perform_Audio_Action(&audio_action); - NeoPixelsAction_T neopixels_action = {.ID = NEOPIXELS_TAG_RECEIVED, .Prominence = NEOPIXELS_FOREGROUND, .Data = (void *)&ReceivedTagColor}; - xQueueSend(xQueueNeoPixels, &neopixels_action, 0); + NeoPixelsAction_T neopixels_action = {.ID = NEOPIXELS_TAG_RECEIVED, .Prominence = NEOPIXELS_FOREGROUND, .Data = (void *)&ReceivedTagColor}; + xQueueSend(xQueueNeoPixels, &neopixels_action, 0); + } } else if (packet->damage < 0) { - Health_In_Percent = (uint8_t)Get_Health(); Health_In_Percent -= packet->damage; if (Health_In_Percent > MAX_HEALTH) { @@ -236,4 +242,6 @@ void HandleBLETagPacket(const BLE_TagPacket_T *const packet) } } } + + BLE_FreePacketBuffer(packet); } diff --git a/States/Playing/State_Playing__Tagged_Out.c b/States/Playing/State_Playing__Tagged_Out.c index 87e445a..007d60c 100644 --- a/States/Playing/State_Playing__Tagged_Out.c +++ b/States/Playing/State_Playing__Tagged_Out.c @@ -51,7 +51,7 @@ static void Playing__Tagged_Out_Entry(StateMachineContext_T * context) NeoPixelsAction_T neopixels_action = {.ID = NEOPIXELS_TAGGED_OUT, .Prominence = NEOPIXELS_FOREGROUND, .Data = (void *)0x00}; xQueueSend(xQueueNeoPixels, &neopixels_action, 0); - BLE_UpdateStatusPacket(); + BLE_UpdateStatusPacket(STATE_PLAYING__TAGGED_OUT); Increment_Times_Tagged_Out(); } diff --git a/States/State_Configuring.c b/States/State_Configuring.c index 6c79699..24cf594 100644 --- a/States/State_Configuring.c +++ b/States/State_Configuring.c @@ -52,7 +52,8 @@ static void Configuring_Entry(StateMachineContext_T *context) NeoPixelsAction_T neopixels_action = {.ID = NEOPIXELS_MENU, .Prominence = NEOPIXELS_FOREGROUND, .Data = (void *)0x00}; xQueueSend(xQueueNeoPixels, &neopixels_action, 0); - BLE_UpdateStatusPacket(); + BLE_UpdateHelloPacket(); + if (BLE_ScanAndAdvertise() != SYSTEMK_RESULT_SUCCESS) { KLOG_ERROR(KLOG_TAG, "Couldn't start BLE!"); @@ -150,6 +151,7 @@ static void Configuring_Do(StateMachineContext_T *context) CurrentMenuItem->OnFocus(true); } } + BLE_UpdateHelloPacket(); break; case KEVENT_TRIGGER_SWITCH_RELEASED: @@ -180,6 +182,8 @@ static void Configuring_Do(StateMachineContext_T *context) { KLOG_WARN(KLOG_TAG, "Failed to increment team!"); } + + BLE_UpdateHelloPacket(); } break; diff --git a/States/State_Initializing.c b/States/State_Initializing.c index 2f52060..14a0d09 100644 --- a/States/State_Initializing.c +++ b/States/State_Initializing.c @@ -44,7 +44,8 @@ const StateActivity_T STATE_INITIALIZING_Activities = */ static void Initializing_Entry(StateMachineContext_T * context) { - LOG("Entering the Initializing state."); + KLOG_INFO("SystemK", "Using SystemK version %s.", SYSTEMK_VERSION_STRING); + NeoPixelsAction_T neopixels_action = {.ID = NEOPIXELS_TEST_PATTERN, .Prominence = NEOPIXELS_FOREGROUND, .Data = (void *)0x00}; xQueueSend(xQueueNeoPixels, &neopixels_action, 0); AudioAction_T audio_action = {.ID = AUDIO_PLAY_STARTUP_SOUND, .Play_To_Completion = true, .Data = (void *)0x00}; diff --git a/States/State_Machine.c b/States/State_Machine.c index f3e702b..5f056f9 100644 --- a/States/State_Machine.c +++ b/States/State_Machine.c @@ -22,13 +22,6 @@ /* Include Files */ #include "SystemK.h" -const StateActivity_T STATE_DEFAULT_Activities = -{ - .Entry = NULL, - .Do = NULL, - .Exit = NULL -}; - //! Activities for the top-level state machine. /*! * This array is indexed by #StateID_T (except there is no entry for @@ -37,7 +30,6 @@ const StateActivity_T STATE_DEFAULT_Activities = */ static const StateActivity_T * Activities[] = { - &STATE_DEFAULT_Activities, &STATE_INITIALIZING_Activities, &STATE_REPROGRAMMING_Activities, &STATE_CONFIGURING_Activities, @@ -62,6 +54,11 @@ static StateMachineContext_T Context = .Time_At_State_Entry_In_Ticks = 0, }; +StateMachineContext_T* GetContext() +{ + return &Context; +} + TaskHandle_t State_Machine_Task_Handle; void State_Machine_Task(void * pvParameters) diff --git a/States/State_Machine.h b/States/State_Machine.h index 31d375a..5656daa 100644 --- a/States/State_Machine.h +++ b/States/State_Machine.h @@ -36,22 +36,21 @@ */ typedef enum { - STATE_DEFAULT = 0, - STATE_INITIALIZING = 1, - STATE_REPROGRAMMING = 2, - STATE_CONFIGURING = 3, - STATE_READY = 4, + STATE_INITIALIZING = 0, + STATE_REPROGRAMMING = 1, + STATE_CONFIGURING = 2, + STATE_READY = 3, // Substates of STATE_STARTING_GAME - STATE_STARTING_GAME__INSTIGATING = 5, - STATE_STARTING_GAME__RESPONDING = 6, - STATE_STARTING_GAME__COUNTING_DOWN = 7, + STATE_STARTING_GAME__INSTIGATING = 4, + STATE_STARTING_GAME__RESPONDING = 5, + STATE_STARTING_GAME__COUNTING_DOWN = 6, // Substates of STATE_PLAYING - STATE_PLAYING__INTERACTING = 8, - STATE_PLAYING__TAGGED_OUT = 9, + STATE_PLAYING__INTERACTING = 7, + STATE_PLAYING__TAGGED_OUT = 8, - STATE_WRAPPING_UP = 10, + STATE_WRAPPING_UP = 9, // STATE_IS_OUT_OF_RANGE is one more than the last valid state. STATE_IS_OUT_OF_RANGE, @@ -120,6 +119,8 @@ inline uint32_t GetTimeInState_in_ms(StateMachineContext_T * context) return result; } +StateMachineContext_T* GetContext(); + #include "State_Configuring.h" #include "State_Ready.h" #include "State_Initializing.h" diff --git a/States/State_Ready.c b/States/State_Ready.c index 21b4af4..c58c4bb 100644 --- a/States/State_Ready.c +++ b/States/State_Ready.c @@ -47,7 +47,7 @@ static void Ready_Entry(StateMachineContext_T * context) LOG("Entering the Ready state."); NeoPixelsAction_T neopixels_action = {.ID = NEOPIXELS_IDLE, .Prominence = NEOPIXELS_FOREGROUND, .Data = (void *)0x00}; xQueueSend(xQueueNeoPixels, &neopixels_action, 0); - BLE_UpdateStatusPacket(); + BLE_UpdateStatusPacket(STATE_READY); if (BLE_ScanAndAdvertise() != SYSTEMK_RESULT_SUCCESS) { KLOG_ERROR(KLOG_TAG, "Couldn't start BLE!"); diff --git a/States/State_Wrapping_Up.c b/States/State_Wrapping_Up.c index 1361f93..af0d07c 100644 --- a/States/State_Wrapping_Up.c +++ b/States/State_Wrapping_Up.c @@ -47,7 +47,7 @@ static void Wrapping_Up_Entry(StateMachineContext_T * context) LOG("Entering the Wrapping Up state."); NeoPixelsAction_T neopixels_action = {.ID = NEOPIXELS_IDLE, .Prominence = NEOPIXELS_FOREGROUND, .Data = (void *)0x00}; xQueueSend(xQueueNeoPixels, &neopixels_action, 0); - BLE_UpdateStatusPacket(); + BLE_UpdateStatusPacket(STATE_WRAPPING_UP); if (BLE_ScanAndAdvertise() != SYSTEMK_RESULT_SUCCESS) { KLOG_ERROR(KLOG_TAG, "Couldn't start BLE!"); diff --git a/SystemK.h b/SystemK.h index 289cfb1..aeadecb 100755 --- a/SystemK.h +++ b/SystemK.h @@ -70,6 +70,10 @@ #ifndef SYSTEMK_H #define SYSTEMK_H +#define SYSTEMK_MAJOR_VERSION 0 +#define SYSTEMK_MINOR_VERSION 99 +#define SYSTEMK_VERSION_STRING "00.99" + #ifdef ESP_PLATFORM #include "freertos/FreeRTOS.h" #include "freertos/task.h"