diff --git a/hal/src/main/native/athena/FRCDriverStation.cpp b/hal/src/main/native/athena/FRCDriverStation.cpp index 08eab3ad5b..1784ef8a7a 100644 --- a/hal/src/main/native/athena/FRCDriverStation.cpp +++ b/hal/src/main/native/athena/FRCDriverStation.cpp @@ -230,6 +230,67 @@ double HAL_GetMatchTime(int32_t* status) { return matchTime; } +int HAL_GetMatchInfo(HAL_MatchInfo* info) { + uint16_t gameSpecificMessageSize = 0; + int status = FRC_NetworkCommunication_getMatchInfo( + nullptr, nullptr, nullptr, nullptr, nullptr, &gameSpecificMessageSize); + if (status < 0) { + info->eventName = nullptr; + info->gameSpecificMessage = nullptr; + return status; + } + info->eventName = static_cast(std::malloc(256)); + gameSpecificMessageSize = ((gameSpecificMessageSize + 1023) / 1024) * 1024; + uint16_t originalGameSpecificSize = gameSpecificMessageSize; + uint8_t* gameSpecificMessage = + static_cast(std::malloc(gameSpecificMessageSize)); + MatchType_t matchType = MatchType_t::kMatchType_none; + uint16_t matchNumber = 0; + uint8_t replayNumber = 0; + status = FRC_NetworkCommunication_getMatchInfo( + info->eventName, &matchType, &matchNumber, &replayNumber, + gameSpecificMessage, &gameSpecificMessageSize); + if (status < 0) { + std::free(info->eventName); + std::free(gameSpecificMessage); + info->eventName = nullptr; + info->gameSpecificMessage = nullptr; + return status; + } + if (gameSpecificMessageSize >= originalGameSpecificSize) { + // Data has updated between size and read calls. Retry. + // Unless large lag, this call will be right. + std::free(gameSpecificMessage); + gameSpecificMessageSize = ((gameSpecificMessageSize + 1023) / 1024) * 1024; + gameSpecificMessage = + static_cast(std::malloc(gameSpecificMessageSize)); + int status = FRC_NetworkCommunication_getMatchInfo( + nullptr, nullptr, nullptr, nullptr, gameSpecificMessage, + &gameSpecificMessageSize); + if (status < 0) { + std::free(info->eventName); + std::free(gameSpecificMessage); + info->eventName = nullptr; + info->gameSpecificMessage = nullptr; + return status; + } + } + info->eventName[255] = '\0'; + info->matchType = static_cast(matchType); + info->matchNumber = matchNumber; + info->replayNumber = replayNumber; + info->gameSpecificMessage = reinterpret_cast(gameSpecificMessage); + info->gameSpecificMessage[gameSpecificMessageSize] = '\0'; + return status; +} + +void HAL_FreeMatchInfo(HAL_MatchInfo* info) { + std::free(info->eventName); + std::free(info->gameSpecificMessage); + info->eventName = nullptr; + info->gameSpecificMessage = nullptr; +} + void HAL_ObserveUserProgramStarting(void) { FRC_NetworkCommunication_observeUserProgramStarting(); } diff --git a/hal/src/main/native/include/HAL/DriverStation.h b/hal/src/main/native/include/HAL/DriverStation.h index 5707544202..8049ece882 100644 --- a/hal/src/main/native/include/HAL/DriverStation.h +++ b/hal/src/main/native/include/HAL/DriverStation.h @@ -47,6 +47,13 @@ enum HAL_AllianceStationID : int32_t { HAL_AllianceStationID_kBlue3, }; +enum HAL_MatchType { + HAL_kMatchType_none, + HAL_kMatchType_practice, + HAL_kMatchType_qualification, + HAL_kMatchType_elimination, +}; + /* The maximum number of axes that will be stored in a single HALJoystickAxes * struct. This is used for allocating buffers, not bounds checking, since * there are usually less axes in practice. @@ -79,9 +86,18 @@ struct HAL_JoystickDescriptor { uint8_t povCount; }; +struct HAL_MatchInfo { + char* eventName; + HAL_MatchType matchType; + uint16_t matchNumber; + uint8_t replayNumber; + char* gameSpecificMessage; +}; + #ifdef __cplusplus extern "C" { #endif + int32_t HAL_SetErrorData(const char* errors, int32_t errorsLength, int32_t waitMs); int32_t HAL_SendError(HAL_Bool isError, int32_t errorCode, HAL_Bool isLVCode, @@ -105,6 +121,9 @@ int32_t HAL_SetJoystickOutputs(int32_t joystickNum, int64_t outputs, int32_t leftRumble, int32_t rightRumble); double HAL_GetMatchTime(int32_t* status); +int HAL_GetMatchInfo(HAL_MatchInfo* info); +void HAL_FreeMatchInfo(HAL_MatchInfo* info); + #ifndef HAL_USE_LABVIEW void HAL_ReleaseDSMutex(void); diff --git a/hal/src/main/native/sim/DriverStation.cpp b/hal/src/main/native/sim/DriverStation.cpp index fd452559a4..3aafca204b 100644 --- a/hal/src/main/native/sim/DriverStation.cpp +++ b/hal/src/main/native/sim/DriverStation.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -153,6 +154,23 @@ double HAL_GetMatchTime(int32_t* status) { return SimDriverStationData.GetMatchTime(); } +int HAL_GetMatchInfo(HAL_MatchInfo* info) { + info->eventName = static_cast(std::malloc(1)); + info->eventName[0] = '\0'; + info->matchNumber = 0; + info->replayNumber = 0; + info->gameSpecificMessage = static_cast(std::malloc(1)); + info->gameSpecificMessage[0] = '\0'; + return 0; +} + +void HAL_FreeMatchInfo(HAL_MatchInfo* info) { + std::free(info->eventName); + std::free(info->gameSpecificMessage); + info->eventName = nullptr; + info->gameSpecificMessage = nullptr; +} + void HAL_ObserveUserProgramStarting(void) { HALSIM_SetProgramStarted(); } void HAL_ObserveUserProgramDisabled(void) {