/* * 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_JOIN_NOW = 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_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 random_time_after_countdown_in_ms_x100; uint8_t unused[12]; } __attribute__((packed, aligned(1))) BLE_InstigationPacket_T; //! Contents of the BLE packet #BLE_PACKET_TYPE_JOIN_NOW. 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; //! 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 unused[5]; } __attribute__((packed, aligned(1)))BLE_StatusPacket_T; typedef union { BLE_GenericPacketType_T Generic; BLE_InstigationPacket_T Instigation; BLE_JoinNowPacket_T JoinNow; BLE_TagPacket_T Tag; BLE_ConsolePacket_T Console; BLE_StatusPacket_T Status; } 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(); void BLE_UpdateTagPacket(int16_t damage, color_t color, uint8_t target_BD_ADDR[BD_ADDR_SIZE]); bool BLE_IsBLEPacketForMe(const uint8_t BD_ADDR[BD_ADDR_SIZE]); #ifdef __cplusplus } #endif #endif // BLE_PACKETS_H