Commit 9e927eba authored by Bjørn Inge Hanssen's avatar Bjørn Inge Hanssen
Browse files

Fix problem related to control packet state transitions

The statemachine required too many criterias for changing from uninitialized to initialized state. According to the Bluetooth specfication (V4.2 [Vol 4, Part D], 8.X) it is sufficient to to receive a CONFIG_RESPONSE to transition to initialized state.
In addition there were missing mutex unlocks at reception of some control packets when in uninitized state. This would leave the state machine silently waiting for certain packets without responding to the incoming packets, or retransmitting according to what packet was expected.
Also added response to CONFIG packet in active state, as described in specification.
parent a3a0b93b
......@@ -130,27 +130,21 @@ class InitializedExitCriterias : public ExitCriterias
public:
bool syncConfigSent;
bool syncConfigRspReceived;
bool syncConfigReceived;
bool syncConfigRspSent;
InitializedExitCriterias()
: ExitCriterias(),
syncConfigSent(false),
syncConfigRspReceived(false),
syncConfigReceived(false),
syncConfigRspSent(false) {}
syncConfigRspReceived(false) {}
bool isFullfilled() const override
{
return ioResourceError || close || (syncConfigSent && syncConfigRspReceived && syncConfigReceived && syncConfigRspSent);
return ioResourceError || close || (syncConfigSent && syncConfigRspReceived);
}
void reset() override
{
ExitCriterias::reset();
syncConfigSent = false;
syncConfigRspSent = false;
syncConfigReceived = false;
syncConfigRspReceived = false;
};
......
......@@ -69,7 +69,7 @@
// Constants use for state machine states UNINITIALIZED and INITIALIZED
const auto NON_ACTIVE_STATE_TIMEOUT = std::chrono::milliseconds(250); // Duration to wait until resending a packet
const uint8_t PACKET_RETRANSMISSIONS = 4; // Number of times to send reliable packets before giving in
const uint8_t PACKET_RETRANSMISSIONS = 6; // Number of times to send reliable packets before giving in
// Other constants
const auto OPEN_WAIT_TIMEOUT = std::chrono::milliseconds(2000); // Duration to wait for state ACTIVE after open is called
......@@ -316,14 +316,14 @@ void H5Transport::processPacket(std::vector<uint8_t> &packet)
if (isSyncConfigPacket)
{
exit->syncConfigReceived = true;
sendControlPacket(CONTROL_PKT_SYNC_CONFIG_RESPONSE);
exit->syncConfigRspSent = true;
syncWaitCondition.notify_all();
}
if (isSyncPacket) {
if (isSyncPacket)
{
sendControlPacket(CONTROL_PKT_SYNC_RESPONSE);
syncWaitCondition.notify_all();
}
}
else if (currentState == STATE_ACTIVE)
......@@ -335,6 +335,11 @@ void H5Transport::processPacket(std::vector<uint8_t> &packet)
exit->syncReceived = true;
syncWaitCondition.notify_all();
}
if (isSyncConfigPacket)
{
sendControlPacket(CONTROL_PKT_SYNC_CONFIG_RESPONSE);
}
}
}
else if (packet_type == VENDOR_SPECIFIC_PACKET)
......@@ -522,11 +527,12 @@ void H5Transport::setupStateMachine()
uint8_t syncRetransmission = PACKET_RETRANSMISSIONS;
std::unique_lock<std::mutex> syncGuard(syncMutex);
while (!exit->isFullfilled() && syncRetransmission--)
while (!exit->isFullfilled() && syncRetransmission > 0)
{
sendControlPacket(CONTROL_PKT_SYNC);
exit->syncSent = true;
syncWaitCondition.wait_for(syncGuard, NON_ACTIVE_STATE_TIMEOUT);
syncRetransmission--;
}
if (exit->isFullfilled())
......@@ -548,22 +554,16 @@ void H5Transport::setupStateMachine()
std::unique_lock<std::mutex> syncGuard(syncMutex);
// Send a package immediately
sendControlPacket(CONTROL_PKT_SYNC_CONFIG);
exit->syncConfigSent = true;
while (!exit->isFullfilled() && syncRetransmission > 0)
{
auto status = syncWaitCondition.wait_for(syncGuard, NON_ACTIVE_STATE_TIMEOUT);
if (status == std::cv_status::timeout)
{
sendControlPacket(CONTROL_PKT_SYNC_CONFIG);
syncRetransmission--;
}
sendControlPacket(CONTROL_PKT_SYNC_CONFIG);
exit->syncConfigSent = true;
syncWaitCondition.wait_for(syncGuard, NON_ACTIVE_STATE_TIMEOUT);
syncRetransmission--;
}
if (exit->syncConfigSent && exit->syncConfigRspReceived
&& exit->syncConfigReceived && exit->syncConfigRspSent)
if (exit->syncConfigSent && exit->syncConfigRspReceived)
{
return STATE_ACTIVE;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment