Skip to content

Commit 2a50b14

Browse files
committed
[VT]: Allow selection of VT client pools based on server version
This change makes it possible for a consumer of the library to choose at runtime which object pool(s) to use based on the version of the VT server.
1 parent 334a21b commit 2a50b14

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

isobus/include/isobus/isobus/isobus_virtual_terminal_client.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,8 @@ namespace isobus
330330
Disconnected, ///< VT is not connected, and is not trying to connect yet
331331
WaitForPartnerVTStatusMessage, ///< VT client is initialized, waiting for a VT server to come online
332332
SendWorkingSetMasterMessage, ///< Client is sending the working state master message
333+
SendGetMemoryInitial, ///< We send an initial get memory message for 0 bytes to get the version of the VT server
334+
WaitForGetMemoryInitialResponse, ///< Client is waiting for a response to the initial
333335
ReadyForObjectPool, ///< Client needs an object pool before connection can continue
334336
SendGetMemory, ///< Client is sending the "get memory" message to see if VT has enough memory available
335337
WaitForGetMemoryResponse, ///< Client is waiting for a response to the "get memory" message
@@ -1234,6 +1236,10 @@ namespace isobus
12341236
const std::vector<std::uint8_t> *pool,
12351237
const std::string &version = "");
12361238

1239+
/// @brief Returns the number of object pools that have been assigned for upload
1240+
/// @returns The number of object pools that have been assigned for upload
1241+
std::size_t get_number_of_object_pools() const;
1242+
12371243
/// @brief Configures an object pool to be automatically scaled to match the target VT server
12381244
/// @param[in] poolIndex The index of the pool you want to auto-scale
12391245
/// @param[in] originalDataMaskDimensions_px The data mask width that your object pool was originally designed for
@@ -1252,6 +1258,15 @@ namespace isobus
12521258
/// @param[in] version An optional version string. The stack will automatically store/load your pool from the VT if this is provided.
12531259
void register_object_pool_data_chunk_callback(std::uint8_t poolIndex, std::uint32_t poolTotalSize, DataChunkCallback value, std::string version = "");
12541260

1261+
/// @brief Sets a callback that will be called when the client is ready for object pool upload. You should call this before initialize if you're planning to use it.
1262+
/// @details This will be called once the VT version of the server is known so that you can select which
1263+
/// object pools you want to upload based on that information. This is optional. If you want to use this mechanism,
1264+
/// simply set your object pools in the callback using set_object_pool or register_object_pool_data_chunk_callback.
1265+
/// If you fail to do this when the callback is called, no object pools will be uploaded until you call set_object_pool, though that
1266+
/// would not be particularly thread safe unless you passed false to the initialize function. You can also just set your object pools before connecting if you want to always upload the same pools.
1267+
/// @param[in] callback The callback to call when ready for object pool upload
1268+
void set_on_ready_for_object_pool_callback(std::function<void(VTVersion)> callback);
1269+
12551270
/// @brief Periodic Update Function (worker thread may call this)
12561271
/// @details This class can spawn a thread, or you can supply your own to run this function.
12571272
/// To configure that behavior, see the initialize function.
@@ -1676,6 +1691,7 @@ namespace isobus
16761691
EventDispatcher<AuxiliaryFunctionEvent> auxiliaryFunctionEventDispatcher; ///< A list of all auxiliary function callbacks
16771692

16781693
// Object Pool info
1694+
std::function<void(VTVersion)> onReadyForObjectPoolCallback;
16791695
DataChunkCallback objectPoolDataCallback = nullptr; ///< The callback to use to get pool data
16801696
std::uint32_t lastObjectPoolIndex = 0; ///< The last object pool index that was processed
16811697
};

isobus/src/isobus_virtual_terminal_client.cpp

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,6 +1264,11 @@ namespace isobus
12641264
}
12651265
}
12661266

1267+
std::size_t VirtualTerminalClient::get_number_of_object_pools() const
1268+
{
1269+
return objectPools.size();
1270+
}
1271+
12671272
void VirtualTerminalClient::set_object_pool_scaling(std::uint8_t poolIndex,
12681273
std::uint32_t originalDataMaskDimensions_px,
12691274
std::uint32_t originalSoftKyeDesignatorHeight_px)
@@ -1303,6 +1308,11 @@ namespace isobus
13031308
}
13041309
}
13051310

1311+
void VirtualTerminalClient::set_on_ready_for_object_pool_callback(std::function<void(VTVersion)> callback)
1312+
{
1313+
onReadyForObjectPoolCallback = callback;
1314+
}
1315+
13061316
void VirtualTerminalClient::update()
13071317
{
13081318
StateMachineState previousStateMachineState = state; // Save state to see if it changes this update
@@ -1337,7 +1347,26 @@ namespace isobus
13371347
{
13381348
if (send_working_set_master())
13391349
{
1340-
set_state(StateMachineState::ReadyForObjectPool);
1350+
set_state(StateMachineState::SendGetMemoryInitial);
1351+
}
1352+
}
1353+
break;
1354+
1355+
case StateMachineState::SendGetMemoryInitial:
1356+
{
1357+
if (send_get_memory(0))
1358+
{
1359+
set_state(StateMachineState::WaitForGetMemoryInitialResponse);
1360+
}
1361+
}
1362+
break;
1363+
1364+
case StateMachineState::WaitForGetMemoryInitialResponse:
1365+
{
1366+
if (SystemTiming::time_expired_ms(lastVTStatusTimestamp_ms, VT_STATUS_TIMEOUT_MS))
1367+
{
1368+
LOG_ERROR("[VT]: VT server has timed out while waiting for initial get memory message. Disconnecting.");
1369+
set_state(StateMachineState::Disconnected);
13411370
}
13421371
}
13431372
break;
@@ -1352,6 +1381,11 @@ namespace isobus
13521381
LOG_ERROR("[VT]: Ready to upload pool, but VT server has timed out. Disconnecting.");
13531382
set_state(StateMachineState::Disconnected);
13541383
}
1384+
else if (onReadyForObjectPoolCallback)
1385+
{
1386+
// Attempt to indicate to the user that we need at least one object pool to proceed.
1387+
onReadyForObjectPoolCallback(get_connected_vt_version());
1388+
}
13551389

13561390
if (!objectPools.empty())
13571391
{
@@ -2774,10 +2808,14 @@ namespace isobus
27742808

27752809
case static_cast<std::uint8_t>(Function::GetMemoryMessage):
27762810
{
2777-
if (StateMachineState::WaitForGetMemoryResponse == parentVT->state)
2811+
if (StateMachineState::WaitForGetMemoryInitialResponse == parentVT->state)
27782812
{
27792813
parentVT->connectedVTVersion = message.get_uint8_at(1);
2780-
2814+
LOG_DEBUG("[VT]: Server version is " + isobus::to_string(static_cast<int>(parentVT->connectedVTVersion)));
2815+
parentVT->set_state(StateMachineState::ReadyForObjectPool);
2816+
}
2817+
else if (StateMachineState::WaitForGetMemoryResponse == parentVT->state)
2818+
{
27812819
if (0 == message.get_uint8_at(2))
27822820
{
27832821
// There IS enough memory

0 commit comments

Comments
 (0)