/* * This program source code file is part of SystemK, a library in the KTag project. * * 🛡️ 🃞 * * Copyright © 2016-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 . */ /** \file * \brief This file defines the Bluetooth Low Energy advertising packets used by KTag. * */ #ifndef BLE_PACKETS_H #define BLE_PACKETS_H #ifdef __cplusplus extern "C" { #endif /* Preprocessor and Type Definitions */ #include #define BLE_MAX_ADVERTISING_BYTES 31 #define BLE_MAX_SCAN_RESPONSE_BYTES 31 #define BD_ADDR_SIZE 6 #define BLE_KTAG_PACKET_TOTAL_SIZE 31 #define BLE_KTAG_PACKET_DATA_SIZE 21 typedef struct { uint8_t data[BLE_MAX_ADVERTISING_BYTES]; uint8_t length; } BLE_AdvertisingData_T; typedef struct { uint8_t data[BLE_MAX_SCAN_RESPONSE_BYTES]; uint8_t length; } BLE_ScanResponseData_T; 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_EVENT = 2, BLE_PACKET_TYPE_TAG = 3, BLE_PACKET_TYPE_CONSOLE = 4, BLE_PACKET_TYPE_STATUS = 5, 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; typedef struct { BLE_PacketType_T type; 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; //! Contents of the BLE packet #BLE_PACKET_TYPE_INSTIGATE_GAME. 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_until_countdown_in_ms; uint8_t unused[13]; } __attribute__((packed, aligned(1))) BLE_InstigationPacket_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; 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 { BLE_PacketType_T type; uint8_t BD_ADDR[BD_ADDR_SIZE]; int8_t RSSI; uint8_t event_number; uint8_t tx_power_level; uint8_t protocol; uint8_t team_ID; uint8_t player_ID; int16_t damage; color_t color; uint8_t target_BD_ADDR[BD_ADDR_SIZE]; uint8_t unused[5]; } __attribute__((packed, aligned(1)))BLE_TagPacket_T; //! Contents of the BLE packet #BLE_PACKET_TYPE_CONSOLE. typedef struct { BLE_PacketType_T type; 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; //! Contents of the BLE packet #BLE_PACKET_TYPE_STATUS. typedef struct { BLE_PacketType_T type; 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; uint8_t player_ID; uint16_t health; uint16_t maximum_health; color_t primary_color; color_t secondary_color; 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_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 */ /* Public Variables */ /* Public Functions */ inline void BLE_FreePacketBuffer(void * buffer) { if (buffer != NULL) { ((BLE_GenericPacketType_T *)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); void BLE_UpdateInstigationPacket(uint32_t Game_Length_in_ms, uint32_t Time_Remaining_Until_Countdown_in_ms); 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 } #endif #endif // BLE_PACKETS_H