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
|
@ -26,6 +26,18 @@ static void Configuring_Entry(StateMachineContext_T *context);
|
|||
static void Configuring_Do(StateMachineContext_T *context);
|
||||
static void Configuring_Exit(StateMachineContext_T *context);
|
||||
|
||||
static void HandleBLEConfigurationPacket(const BLE_ParametersPacket_T *const packet);
|
||||
|
||||
static TimerHandle_t BLEConfigurationResponseTimer = NULL;
|
||||
static StaticTimer_t xBLEConfigurationResponseTimerBuffer;
|
||||
static TickType_t xBLEConfigurationResponseTimerPeriod = 3000 / portTICK_PERIOD_MS;
|
||||
|
||||
static void BLEConfigurationResponseTimerCallback(TimerHandle_t xTimer)
|
||||
{
|
||||
// Don't send HELLO packets once configuration has started.
|
||||
BLE_StopAdvertising();
|
||||
}
|
||||
|
||||
#define MAX_MENU_DEPTH 10
|
||||
static MenuItem_T const *CurrentMenuItem;
|
||||
static uint8_t MenuItemHistoryIndex = 0;
|
||||
|
@ -37,10 +49,11 @@ static const char *KLOG_TAG = "STATE_CONFIGURING";
|
|||
|
||||
//! Activities for the **Configuring** state.
|
||||
const StateActivity_T STATE_CONFIGURING_Activities =
|
||||
{
|
||||
.Entry = Configuring_Entry,
|
||||
.Do = Configuring_Do,
|
||||
.Exit = Configuring_Exit};
|
||||
{
|
||||
.Entry = Configuring_Entry,
|
||||
.Do = Configuring_Do,
|
||||
.Exit = Configuring_Exit
|
||||
};
|
||||
|
||||
//! Sets up the Configuring state.
|
||||
/*!
|
||||
|
@ -52,12 +65,35 @@ 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();
|
||||
if (context->Cause_Of_Transition->ID == KEVENT_BLE_EVENT_RECEIVED)
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_BEEP, .Data = (void *)0x00};
|
||||
Perform_Audio_Action(&audio_action);
|
||||
}
|
||||
|
||||
BLE_UpdateHelloPacket();
|
||||
|
||||
if (BLE_ScanAndAdvertise() != SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
KLOG_ERROR(KLOG_TAG, "Couldn't start BLE!");
|
||||
}
|
||||
|
||||
if (BLEConfigurationResponseTimer == NULL)
|
||||
{
|
||||
BLEConfigurationResponseTimer = xTimerCreateStatic(
|
||||
"BLEConfigResponse",
|
||||
xBLEConfigurationResponseTimerPeriod,
|
||||
pdFALSE,
|
||||
(void *)0,
|
||||
BLEConfigurationResponseTimerCallback,
|
||||
&xBLEConfigurationResponseTimerBuffer);
|
||||
}
|
||||
|
||||
if (BLEConfigurationResponseTimer == NULL)
|
||||
{
|
||||
KLOG_ERROR(KLOG_TAG, "Couldn't create the BLEConfigurationResponseTimer!");
|
||||
}
|
||||
|
||||
// Reset the menu.
|
||||
CurrentMenuItem = RootMenu;
|
||||
MenuItemHistory[MenuItemHistoryIndex] = CurrentMenuItem;
|
||||
|
@ -71,6 +107,13 @@ static void Configuring_Do(StateMachineContext_T *context)
|
|||
{
|
||||
portBASE_TYPE xStatus;
|
||||
static KEvent_T Event;
|
||||
|
||||
// For the first hundred milliseconds, keep updating the Hello packet, since on some platforms (PSoC6), one call is not enough.
|
||||
// TODO: Fix the Hello packet hack on PSoC6.
|
||||
if ((xTaskGetTickCount() - context->Time_At_State_Entry_In_Ticks) < (100 / portTICK_PERIOD_MS))
|
||||
{
|
||||
BLE_UpdateHelloPacket();
|
||||
}
|
||||
|
||||
xStatus = Receive_KEvent(&Event);
|
||||
|
||||
|
@ -150,6 +193,7 @@ static void Configuring_Do(StateMachineContext_T *context)
|
|||
CurrentMenuItem->OnFocus(true);
|
||||
}
|
||||
}
|
||||
BLE_UpdateHelloPacket();
|
||||
break;
|
||||
|
||||
case KEVENT_TRIGGER_SWITCH_RELEASED:
|
||||
|
@ -180,6 +224,8 @@ static void Configuring_Do(StateMachineContext_T *context)
|
|||
{
|
||||
KLOG_WARN(KLOG_TAG, "Failed to increment team!");
|
||||
}
|
||||
|
||||
BLE_UpdateHelloPacket();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -191,6 +237,21 @@ static void Configuring_Do(StateMachineContext_T *context)
|
|||
Transition_For_Event(context, STATE_REPROGRAMMING, &Event);
|
||||
break;
|
||||
|
||||
case KEVENT_BLE_PACKET_RECEIVED:
|
||||
if (((BLE_Packet_T *)Event.Data)->Generic.type == BLE_PACKET_TYPE_PARAMETERS)
|
||||
{
|
||||
HandleBLEConfigurationPacket((BLE_ParametersPacket_T *)Event.Data);
|
||||
}
|
||||
else if (((BLE_Packet_T *)Event.Data)->Generic.type == BLE_PACKET_TYPE_EVENT)
|
||||
{
|
||||
HandleBLEEventPacket((BLE_EventPacket_T *)Event.Data, context);
|
||||
}
|
||||
else
|
||||
{
|
||||
BLE_FreePacketBuffer(Event.Data);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// All other events are ignored in this state.
|
||||
ProcessUnhandledEvent(&Event);
|
||||
|
@ -214,3 +275,151 @@ static void Configuring_Exit(StateMachineContext_T *context)
|
|||
NeoPixelsAction_T neopixels_action = {.ID = NEOPIXELS_ALL_OFF, .Prominence = NEOPIXELS_FOREGROUND, .Data = (void *)0x00};
|
||||
xQueueSend(xQueueNeoPixels, &neopixels_action, 0);
|
||||
}
|
||||
|
||||
static SystemKResult_T HandleParameterChangeRequest(BLE_ParameterKey_T key, uint32_t value)
|
||||
{
|
||||
SystemKResult_T result = SYSTEMK_RESULT_UNSPECIFIED_FAILURE;
|
||||
|
||||
if (key == BLE_PARAMETER_KEY_TEAM_ID)
|
||||
{
|
||||
uint8_t team_ID = (uint8_t)value;
|
||||
if (Is_Valid_Team_ID(team_ID))
|
||||
{
|
||||
result = Set_Team_With_Audio_Feedback(team_ID);
|
||||
}
|
||||
if (result == SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
KLOG_INFO(KLOG_TAG, "Team set to %u over BLE.", team_ID);
|
||||
}
|
||||
}
|
||||
else if (key == BLE_PARAMETER_KEY_PLAYER_ID)
|
||||
{
|
||||
uint8_t player_ID = (uint8_t)value;
|
||||
result = Set_Player_With_Audio_Feedback(player_ID);
|
||||
if (result == SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
KLOG_INFO(KLOG_TAG, "Player set to %u over BLE.", player_ID);
|
||||
}
|
||||
}
|
||||
else if (key == BLE_PARAMETER_KEY_GAME_LENGTH)
|
||||
{
|
||||
result = SETTINGS_set_uint32_t(SYSTEMK_SETTING_T_GAME_LENGTH_in_ms, value);
|
||||
|
||||
if (result == SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_BEEP, .Data = (void *)0x00};
|
||||
Perform_Audio_Action(&audio_action);
|
||||
KLOG_INFO(KLOG_TAG, "Game length set to %lu ms over BLE.", value);
|
||||
}
|
||||
else
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_BONK, .Data = (void *)0x00};
|
||||
Perform_Audio_Action(&audio_action);
|
||||
}
|
||||
}
|
||||
else if (key == BLE_PARAMETER_KEY_MAX_HEALTH)
|
||||
{
|
||||
uint8_t max_health = (uint8_t)value;
|
||||
Set_Max_Health(max_health);
|
||||
result = SETTINGS_set_uint8_t(SYSTEMK_SETTING_MAX_HEALTH, max_health);
|
||||
|
||||
if (result == SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_BEEP, .Data = (void *)0x00};
|
||||
Perform_Audio_Action(&audio_action);
|
||||
KLOG_INFO(KLOG_TAG, "Max health set to %u over BLE.", max_health);
|
||||
}
|
||||
else
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_BONK, .Data = (void *)0x00};
|
||||
Perform_Audio_Action(&audio_action);
|
||||
}
|
||||
}
|
||||
else if (key == BLE_PARAMETER_KEY_SECONDARY_COLOR)
|
||||
{
|
||||
result = SETTINGS_set_uint32_t(SYSTEMK_SETTING_SECONDARY_COLOR, value);
|
||||
|
||||
if (result == SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_BEEP, .Data = (void *)0x00};
|
||||
Perform_Audio_Action(&audio_action);
|
||||
KLOG_INFO(KLOG_TAG, "Secondary color set to %lu over BLE.", value);
|
||||
}
|
||||
else
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_BONK, .Data = (void *)0x00};
|
||||
Perform_Audio_Action(&audio_action);
|
||||
}
|
||||
}
|
||||
else if (key == BLE_PARAMETER_KEY_SPECIAL_WEAPONS_ON_REENTRY)
|
||||
{
|
||||
uint8_t n_weapons_on_reentry = (uint8_t)value;
|
||||
Set_Available_Bombs(n_weapons_on_reentry);
|
||||
result = SETTINGS_set_uint8_t(SYSTEMK_SETTING_N_SPECIAL_WEAPONS_ON_REENTRY, n_weapons_on_reentry);
|
||||
|
||||
if (result == SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_BEEP, .Data = (void *)0x00};
|
||||
Perform_Audio_Action(&audio_action);
|
||||
KLOG_INFO(KLOG_TAG, "Number of special weapons granted on reentry set to %u over BLE.", n_weapons_on_reentry);
|
||||
}
|
||||
else
|
||||
{
|
||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_BONK, .Data = (void *)0x00};
|
||||
Perform_Audio_Action(&audio_action);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void HandleBLEConfigurationPacket(const BLE_ParametersPacket_T *const packet)
|
||||
{
|
||||
if (BLE_IsBLEPacketForMe(packet->target_BD_ADDR))
|
||||
{
|
||||
if (BLE_IsPacketNew(packet->BD_ADDR, BLE_PACKET_TYPE_PARAMETERS, packet->event_number))
|
||||
{
|
||||
if (packet->subtype == BLE_REQUEST_PARAMETER_CHANGE)
|
||||
{
|
||||
SystemKResult_T result = SYSTEMK_RESULT_SUCCESS;
|
||||
|
||||
BLE_ParameterKey_T key_one = BLE_GetValidConfigKey(packet->key_one);
|
||||
if (key_one != BLE_PARAMETER_KEY_NONE)
|
||||
{
|
||||
result = HandleParameterChangeRequest(key_one, packet->value_one);
|
||||
}
|
||||
|
||||
if (result == SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
BLE_ParameterKey_T key_two = BLE_GetValidConfigKey(packet->key_two);
|
||||
if (key_two != BLE_PARAMETER_KEY_NONE)
|
||||
{
|
||||
result = HandleParameterChangeRequest(key_two, packet->value_two);
|
||||
}
|
||||
}
|
||||
|
||||
if (result == SYSTEMK_RESULT_SUCCESS)
|
||||
{
|
||||
BLE_RespondToConfigurationPacket(packet, BLE_ACKNOWLEDGE_PARAMETER_CHANGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
KLOG_ERROR(KLOG_TAG, "Error changing parameter(s)!");
|
||||
BLE_RespondToConfigurationPacket(packet, BLE_ERROR_CHANGING_PARAMETERS);
|
||||
}
|
||||
|
||||
if (xTimerStart(BLEConfigurationResponseTimer, 0) != pdPASS)
|
||||
{
|
||||
KLOG_ERROR(KLOG_TAG, "Couldn't start the BLEConfigurationResponseTimer!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Once configuration has begun, stop advertising the HELLO packet to free up bandwidth.
|
||||
BLE_StopAdvertising();
|
||||
}
|
||||
|
||||
BLE_FreePacketBuffer((BLE_GenericPacketType_T *)packet);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue