Reworked BLE according to v0.11 of the KTag Beacon Specification #2
10 changed files with 121 additions and 23 deletions
|
@ -93,6 +93,16 @@ typedef struct
|
||||||
uint8_t unused[13];
|
uint8_t unused[13];
|
||||||
} __attribute__((packed, aligned(1))) BLE_InstigationPacket_T;
|
} __attribute__((packed, aligned(1))) BLE_InstigationPacket_T;
|
||||||
|
|
||||||
|
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.
|
//! Contents of the BLE packet #BLE_PACKET_TYPE_EVENT.
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,7 +38,7 @@ const char *BLE_ADDR_To_Str(const uint8_t bd_addr[6])
|
||||||
// Convert each byte and add separating colons.
|
// Convert each byte and add separating colons.
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
snprintf(&str_addr[i * 3], sizeof(str_addr) - (i * 3), "%02X", bd_addr[i]);
|
snprintf(&str_addr[i * 3], sizeof(str_addr) - (i * 3), "%02X", bd_addr[5-i]);
|
||||||
|
|
||||||
// Add colon separator except after the last byte.
|
// Add colon separator except after the last byte.
|
||||||
if (i < 5)
|
if (i < 5)
|
||||||
|
|
|
@ -79,6 +79,8 @@ typedef enum
|
||||||
KEVENT_AUDIO_COMPLETED = 36,
|
KEVENT_AUDIO_COMPLETED = 36,
|
||||||
KEVENT_GAME_OVER = 37,
|
KEVENT_GAME_OVER = 37,
|
||||||
KEVENT_PLAY_PRESSED_ON_REMOTE = 38,
|
KEVENT_PLAY_PRESSED_ON_REMOTE = 38,
|
||||||
|
//! For #KEVENT_BLE_EVENT_RECEIVED, #KEvent_T::Data contains the BLE_EventID_T of the received event.
|
||||||
|
KEVENT_BLE_EVENT_RECEIVED = 39,
|
||||||
// KEVENT_IS_OUT_OF_RANGE is one more than the last valid event.
|
// KEVENT_IS_OUT_OF_RANGE is one more than the last valid event.
|
||||||
KEVENT_IS_OUT_OF_RANGE
|
KEVENT_IS_OUT_OF_RANGE
|
||||||
} KEvent_ID_T;
|
} KEvent_ID_T;
|
||||||
|
|
|
@ -344,14 +344,7 @@ static void Playing__Interacting_Do(StateMachineContext_T * context)
|
||||||
|
|
||||||
case KEVENT_BLE_PACKET_RECEIVED:
|
case KEVENT_BLE_PACKET_RECEIVED:
|
||||||
#ifdef LOG_INTERACTING_SUBSTATE
|
#ifdef LOG_INTERACTING_SUBSTATE
|
||||||
//KLOG_INFO(KLOG_TAG, "KEVENT_BLE_PACKET_RECEIVED from %02X:%02X:%02X:%02X:%02X:%02X",
|
KLOG_INFO(KLOG_TAG, "KEVENT_BLE_PACKET_RECEIVED from %s", BLE_ADDR_To_Str(((BLE_Packet_T *)Event.Data)->Generic.BD_ADDR));
|
||||||
// ((BLE_Packet_T *)Event.Data)->Generic.BD_ADDR[5],
|
|
||||||
// ((BLE_Packet_T *)Event.Data)->Generic.BD_ADDR[4],
|
|
||||||
// ((BLE_Packet_T *)Event.Data)->Generic.BD_ADDR[3],
|
|
||||||
// ((BLE_Packet_T *)Event.Data)->Generic.BD_ADDR[2],
|
|
||||||
// ((BLE_Packet_T *)Event.Data)->Generic.BD_ADDR[1],
|
|
||||||
// ((BLE_Packet_T *)Event.Data)->Generic.BD_ADDR[0]
|
|
||||||
//);
|
|
||||||
#endif // LOG_INTERACTING_SUBSTATE
|
#endif // LOG_INTERACTING_SUBSTATE
|
||||||
if (((BLE_Packet_T *)Event.Data)->Generic.type == BLE_PACKET_TYPE_STATUS)
|
if (((BLE_Packet_T *)Event.Data)->Generic.type == BLE_PACKET_TYPE_STATUS)
|
||||||
{
|
{
|
||||||
|
@ -361,8 +354,14 @@ static void Playing__Interacting_Do(StateMachineContext_T * context)
|
||||||
{
|
{
|
||||||
HandleBLETagPacket((BLE_TagPacket_T *)Event.Data);
|
HandleBLETagPacket((BLE_TagPacket_T *)Event.Data);
|
||||||
}
|
}
|
||||||
|
else if (((BLE_Packet_T *)Event.Data)->Generic.type == BLE_PACKET_TYPE_EVENT)
|
||||||
BLE_FreePacketBuffer(Event.Data);
|
{
|
||||||
|
HandleBLEEventPacket((BLE_EventPacket_T *)Event.Data, context);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BLE_FreePacketBuffer(Event.Data);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEVENT_ACCESSORY_SWITCH_PRESSED:
|
case KEVENT_ACCESSORY_SWITCH_PRESSED:
|
||||||
|
@ -398,7 +397,7 @@ static void Playing__Interacting_Do(StateMachineContext_T * context)
|
||||||
|
|
||||||
case KEVENT_GAME_OVER:
|
case KEVENT_GAME_OVER:
|
||||||
{
|
{
|
||||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_GAME_OVER, .Data = (void *)0x00};
|
AudioAction_T audio_action = {.ID = AUDIO_PLAY_GAME_OVER, .Play_To_Completion = true};
|
||||||
Perform_Audio_Action(&audio_action);
|
Perform_Audio_Action(&audio_action);
|
||||||
Transition_For_Event(context, STATE_WRAPPING_UP, &Event);
|
Transition_For_Event(context, STATE_WRAPPING_UP, &Event);
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,10 @@ static void Playing__Tagged_Out_Do(StateMachineContext_T * context)
|
||||||
Transition_For_Event(context, STATE_PLAYING__INTERACTING, &Event);
|
Transition_For_Event(context, STATE_PLAYING__INTERACTING, &Event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (((BLE_Packet_T *)Event.Data)->Generic.type == BLE_PACKET_TYPE_EVENT)
|
||||||
|
{
|
||||||
|
HandleBLEEventPacket((BLE_EventPacket_T *)Event.Data, context);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BLE_FreePacketBuffer(Event.Data);
|
BLE_FreePacketBuffer(Event.Data);
|
||||||
|
@ -107,7 +111,7 @@ static void Playing__Tagged_Out_Do(StateMachineContext_T * context)
|
||||||
|
|
||||||
case KEVENT_GAME_OVER:
|
case KEVENT_GAME_OVER:
|
||||||
{
|
{
|
||||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_GAME_OVER, .Data = (void *)0x00};
|
AudioAction_T audio_action = {.ID = AUDIO_PLAY_GAME_OVER, .Play_To_Completion = true};
|
||||||
Perform_Audio_Action(&audio_action);
|
Perform_Audio_Action(&audio_action);
|
||||||
Transition_For_Event(context, STATE_WRAPPING_UP, &Event);
|
Transition_For_Event(context, STATE_WRAPPING_UP, &Event);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@ static void Configuring_Do(StateMachineContext_T *context);
|
||||||
static void Configuring_Exit(StateMachineContext_T *context);
|
static void Configuring_Exit(StateMachineContext_T *context);
|
||||||
|
|
||||||
static void HandleBLEConfigurationPacket(const BLE_ConfigurationPacket_T *const packet);
|
static void HandleBLEConfigurationPacket(const BLE_ConfigurationPacket_T *const packet);
|
||||||
static void HandleBLEEventPacket(const BLE_EventPacket_T *const packet);
|
|
||||||
|
|
||||||
static TimerHandle_t BLEConfigurationResponseTimer = NULL;
|
static TimerHandle_t BLEConfigurationResponseTimer = NULL;
|
||||||
static StaticTimer_t xBLEConfigurationResponseTimerBuffer;
|
static StaticTimer_t xBLEConfigurationResponseTimerBuffer;
|
||||||
|
@ -64,6 +63,12 @@ static void Configuring_Entry(StateMachineContext_T *context)
|
||||||
NeoPixelsAction_T neopixels_action = {.ID = NEOPIXELS_MENU, .Prominence = NEOPIXELS_FOREGROUND, .Data = (void *)0x00};
|
NeoPixelsAction_T neopixels_action = {.ID = NEOPIXELS_MENU, .Prominence = NEOPIXELS_FOREGROUND, .Data = (void *)0x00};
|
||||||
xQueueSend(xQueueNeoPixels, &neopixels_action, 0);
|
xQueueSend(xQueueNeoPixels, &neopixels_action, 0);
|
||||||
|
|
||||||
|
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();
|
BLE_UpdateHelloPacket();
|
||||||
|
|
||||||
if (BLE_ScanAndAdvertise() != SYSTEMK_RESULT_SUCCESS)
|
if (BLE_ScanAndAdvertise() != SYSTEMK_RESULT_SUCCESS)
|
||||||
|
@ -230,10 +235,12 @@ static void Configuring_Do(StateMachineContext_T *context)
|
||||||
}
|
}
|
||||||
else if (((BLE_Packet_T *)Event.Data)->Generic.type == BLE_PACKET_TYPE_EVENT)
|
else if (((BLE_Packet_T *)Event.Data)->Generic.type == BLE_PACKET_TYPE_EVENT)
|
||||||
{
|
{
|
||||||
HandleBLEEventPacket((BLE_EventPacket_T *)Event.Data);
|
HandleBLEEventPacket((BLE_EventPacket_T *)Event.Data, context);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BLE_FreePacketBuffer(Event.Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
BLE_FreePacketBuffer(Event.Data);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -319,7 +326,3 @@ void HandleBLEConfigurationPacket(const BLE_ConfigurationPacket_T *const packet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleBLEEventPacket(const BLE_EventPacket_T *const packet)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
|
@ -128,3 +128,70 @@ void ProcessUnhandledEvent(KEvent_T * Event)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HandleBLEEventPacket(const BLE_EventPacket_T *const packet, StateMachineContext_T *context)
|
||||||
|
{
|
||||||
|
if (BLE_IsBLEPacketForMe(packet->target_BD_ADDR))
|
||||||
|
{
|
||||||
|
if (BLE_IsPacketNew(packet->BD_ADDR, BLE_PACKET_TYPE_EVENT, packet->event_number))
|
||||||
|
{
|
||||||
|
if (packet->event_ID == BLE_EVENT_CONFIGURED)
|
||||||
|
{
|
||||||
|
if (context->States.Current_State == STATE_CONFIGURING)
|
||||||
|
{
|
||||||
|
static KEvent_T Event =
|
||||||
|
{
|
||||||
|
.ID = KEVENT_BLE_EVENT_RECEIVED,
|
||||||
|
.Data = (void *)BLE_EVENT_CONFIGURED
|
||||||
|
};
|
||||||
|
Transition_For_Event(context, STATE_READY, &Event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (packet->event_ID == BLE_EVENT_CONFIGURE)
|
||||||
|
{
|
||||||
|
if (context->States.Current_State == STATE_READY)
|
||||||
|
{
|
||||||
|
static KEvent_T Event =
|
||||||
|
{
|
||||||
|
.ID = KEVENT_BLE_EVENT_RECEIVED,
|
||||||
|
.Data = (void *)BLE_EVENT_CONFIGURE
|
||||||
|
};
|
||||||
|
Transition_For_Event(context, STATE_CONFIGURING, &Event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (packet->event_ID == BLE_EVENT_WRAPUP_COMPLETE)
|
||||||
|
{
|
||||||
|
if (context->States.Current_State == STATE_WRAPPING_UP)
|
||||||
|
{
|
||||||
|
StateID_T next_state = (StateID_T)packet->event_data;
|
||||||
|
|
||||||
|
if (next_state < STATE_IS_OUT_OF_RANGE)
|
||||||
|
{
|
||||||
|
static KEvent_T Event =
|
||||||
|
{
|
||||||
|
.ID = KEVENT_BLE_EVENT_RECEIVED,
|
||||||
|
.Data = (void *)BLE_EVENT_WRAPUP_COMPLETE
|
||||||
|
};
|
||||||
|
Transition_For_Event(context, next_state, &Event);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KLOG_WARN("STATE", "Received a BLE Wrapup Complete event with an invalid Next State!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (packet->event_ID == BLE_EVENT_GAME_OVER)
|
||||||
|
{
|
||||||
|
if ((context->States.Current_State == STATE_PLAYING__INTERACTING) ||
|
||||||
|
(context->States.Current_State == STATE_PLAYING__TAGGED_OUT))
|
||||||
|
{
|
||||||
|
KEvent_T game_over_event = { .ID = KEVENT_GAME_OVER, .Data = (void *)0x00 };
|
||||||
|
Post_KEvent(&game_over_event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BLE_FreePacketBuffer((BLE_GenericPacketType_T *)packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,7 @@ extern TaskHandle_t State_Machine_Task_Handle;
|
||||||
|
|
||||||
void State_Machine_Task(void * pvParameters);
|
void State_Machine_Task(void * pvParameters);
|
||||||
void ProcessUnhandledEvent(KEvent_T * Event);
|
void ProcessUnhandledEvent(KEvent_T * Event);
|
||||||
|
void HandleBLEEventPacket(const BLE_EventPacket_T *const packet, StateMachineContext_T *context);
|
||||||
|
|
||||||
inline void Transition_For_Event(StateMachineContext_T* context, StateID_T next_state, KEvent_T* event)
|
inline void Transition_For_Event(StateMachineContext_T* context, StateID_T next_state, KEvent_T* event)
|
||||||
{
|
{
|
||||||
|
|
|
@ -54,6 +54,8 @@ static void Ready_Entry(StateMachineContext_T * context)
|
||||||
}
|
}
|
||||||
AudioAction_T audio_action = {.ID = AUDIO_PLAY_GAME_ON, .Data = (void *)0x00};
|
AudioAction_T audio_action = {.ID = AUDIO_PLAY_GAME_ON, .Data = (void *)0x00};
|
||||||
Perform_Audio_Action(&audio_action);
|
Perform_Audio_Action(&audio_action);
|
||||||
|
|
||||||
|
Set_Health(MAX_HEALTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Executes the Ready state.
|
//! Executes the Ready state.
|
||||||
|
@ -90,6 +92,10 @@ static void Ready_Do(StateMachineContext_T * context)
|
||||||
{
|
{
|
||||||
Transition_For_Event(context, STATE_STARTING_GAME__RESPONDING, &Event);
|
Transition_For_Event(context, STATE_STARTING_GAME__RESPONDING, &Event);
|
||||||
}
|
}
|
||||||
|
else if (((BLE_Packet_T *)Event.Data)->Generic.type == BLE_PACKET_TYPE_EVENT)
|
||||||
|
{
|
||||||
|
HandleBLEEventPacket((BLE_EventPacket_T *)Event.Data, context);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BLE_FreePacketBuffer(Event.Data);
|
BLE_FreePacketBuffer(Event.Data);
|
||||||
|
|
|
@ -84,8 +84,14 @@ static void Wrapping_Up_Do(StateMachineContext_T * context)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEVENT_BLE_PACKET_RECEIVED:
|
case KEVENT_BLE_PACKET_RECEIVED:
|
||||||
// TODO
|
if (((BLE_Packet_T *)Event.Data)->Generic.type == BLE_PACKET_TYPE_EVENT)
|
||||||
BLE_FreePacketBuffer(Event.Data);
|
{
|
||||||
|
HandleBLEEventPacket((BLE_EventPacket_T *)Event.Data, context);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BLE_FreePacketBuffer(Event.Data);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue