aboutsummaryrefslogtreecommitdiffstats
path: root/trial/direct_bt
diff options
context:
space:
mode:
Diffstat (limited to 'trial/direct_bt')
-rw-r--r--trial/direct_bt/dbt_client01.hpp166
-rw-r--r--trial/direct_bt/dbt_client_server1x.hpp160
-rw-r--r--trial/direct_bt/dbt_server01.hpp34
-rw-r--r--trial/direct_bt/test_provoke_client_server_i470.cpp53
4 files changed, 222 insertions, 191 deletions
diff --git a/trial/direct_bt/dbt_client01.hpp b/trial/direct_bt/dbt_client01.hpp
index 8d8c78db..2f86976d 100644
--- a/trial/direct_bt/dbt_client01.hpp
+++ b/trial/direct_bt/dbt_client01.hpp
@@ -67,17 +67,16 @@ class DBTClient01 : public DBTClientTest {
jau::sc_atomic_int disconnectCount = 0;
jau::sc_atomic_int notificationsReceived = 0;
jau::sc_atomic_int indicationsReceived = 0;
- jau::sc_atomic_int completedGATTCommands = 0;
jau::sc_atomic_int completedMeasurementsTotal = 0;
jau::sc_atomic_int completedMeasurementsSuccess = 0;
jau::sc_atomic_int measurementsLeft = 0;
+ bool do_disconnect = false;
+
private:
const uint64_t timestamp_t0 = getCurrentMilliseconds();
// const fraction_i64 timestamp_t0 = jau::getMonotonicMicroseconds();
- const uint8_t cmd_arg = 0x44;
-
class MyAdapterStatusListener : public AdapterStatusListener {
public:
DBTClient01& parent;
@@ -197,6 +196,19 @@ class DBTClient01 : public DBTClientTest {
}
}
+ void disconnectDevice(BTDeviceRef device) {
+ // sleep range: 100 - 1500 ms
+ // sleep range: 100 - 1500 ms
+ static const int sleep_min = 100;
+ static const int sleep_max = 1500;
+ static std::random_device rng_hw;;
+ static std::uniform_int_distribution<int> rng_dist(sleep_min, sleep_max);
+ const int64_t sleep_dur = rng_dist(rng_hw);
+ jau::sleep_for( sleep_dur * 1_ms );
+ fprintf_td(stderr, "****** Client i470 disconnectDevice(delayed %d ms): client %s\n", sleep_dur, device->toString().c_str());
+ device->disconnect();
+ }
+
void deviceReady(BTDeviceRef device, const uint64_t timestamp) override {
(void)timestamp;
{
@@ -207,6 +219,11 @@ class DBTClient01 : public DBTClientTest {
std::thread dc(&DBTClient01::processReadyDevice, &parent, device);
dc.detach();
// processReadyDevice(device); // AdapterStatusListener::deviceReady() explicitly allows prolonged and complex code execution!
+
+ if( parent.do_disconnect ) {
+ std::thread disconnectThread(&MyAdapterStatusListener::disconnectDevice, this, device);
+ disconnectThread.detach();
+ }
}
}
@@ -272,10 +289,11 @@ class DBTClient01 : public DBTClientTest {
std::shared_ptr<AdapterStatusListener> myAdapterStatusListener = std::make_shared<MyAdapterStatusListener>(*this);
public:
- DBTClient01(const std::string& adapterName_, const EUI48 useAdapter_, const BTMode btMode_) {
+ DBTClient01(const std::string& adapterName_, const EUI48 useAdapter_, const BTMode btMode_, const bool do_disconnect_) {
this->adapterName = adapterName_;
this->useAdapter = useAdapter_;
this->btMode = btMode_;
+ this->do_disconnect = do_disconnect_;
}
std::string getName() override { return adapterName; }
@@ -314,7 +332,6 @@ class DBTClient01 : public DBTClientTest {
private:
void resetLastProcessingStats() {
- completedGATTCommands = 0;
notificationsReceived = 0;
indicationsReceived = 0;
}
@@ -421,97 +438,63 @@ class DBTClient01 : public DBTClientTest {
td13, td12, td23, td35);
}
- {
- BTGattCmd cmd = BTGattCmd(*device, "TestCmd", DBTConstants::CommandUUID, DBTConstants::ResponseUUID, 256);
- cmd.setVerbose(true);
- const bool cmd_resolved = cmd.isResolved();
- fprintf_td(stderr, "Command test: %s, resolved %d\n", cmd.toString().c_str(), cmd_resolved);
- POctets cmd_data(1, endian::little);
- cmd_data.put_uint8_nc(0, cmd_arg);
- const HCIStatusCode cmd_res = cmd.send(true /* prefNoAck */, cmd_data, 3_s);
- if( HCIStatusCode::SUCCESS == cmd_res ) {
- const jau::TROOctets& resp = cmd.getResponse();
- if( 1 == resp.size() && resp.get_uint8_nc(0) == cmd_arg ) {
- fprintf_td(stderr, "Client Success: %s -> %s (echo response)\n", cmd.toString().c_str(), resp.toString().c_str());
- completedGATTCommands++;
- } else {
- fprintf_td(stderr, "Client Failure: %s -> %s (different response)\n", cmd.toString().c_str(), resp.toString().c_str());
- }
- } else {
- fprintf_td(stderr, "Client Failure: %s -> %s\n", cmd.toString().c_str(), to_string(cmd_res).c_str());
- }
- // cmd.close(); // done via dtor
- }
-
- for(size_t i=0; i<primServices.size(); i++) {
- BTGattService & primService = *primServices.at(i);
- if( GATT_VERBOSE ) {
- fprintf_td(stderr, " [%2.2d] Service UUID %s (%s)\n", i,
- primService.type->toUUID128String().c_str(),
- primService.type->getTypeSizeString().c_str());
- fprintf_td(stderr, " [%2.2d] %s\n", i, primService.toString().c_str());
- }
- jau::darray<BTGattCharRef> & serviceCharacteristics = primService.characteristicList;
- for(size_t j=0; j<serviceCharacteristics.size(); j++) {
- BTGattCharRef & serviceChar = serviceCharacteristics.at(j);
+ do {
+ for(size_t i=0; i<primServices.size(); i++) {
+ BTGattService & primService = *primServices.at(i);
if( GATT_VERBOSE ) {
- fprintf_td(stderr, " [%2.2d.%2.2d] Characteristic: UUID %s (%s)\n", i, j,
- serviceChar->value_type->toUUID128String().c_str(),
- serviceChar->value_type->getTypeSizeString().c_str());
- fprintf_td(stderr, " [%2.2d.%2.2d] %s\n", i, j, serviceChar->toString().c_str());
+ fprintf_td(stderr, " [%2.2d] Service UUID %s (%s)\n", i,
+ primService.type->toUUID128String().c_str(),
+ primService.type->getTypeSizeString().c_str());
+ fprintf_td(stderr, " [%2.2d] %s\n", i, primService.toString().c_str());
}
- if( serviceChar->hasProperties(BTGattChar::PropertyBitVal::Read) ) {
- POctets value(BTGattHandler::number(BTGattHandler::Defaults::MAX_ATT_MTU), 0, jau::endian::little);
- if( serviceChar->readValue(value) ) {
- std::string sval = dfa_utf8_decode(value.get_ptr(), value.size());
+ jau::darray<BTGattCharRef> & serviceCharacteristics = primService.characteristicList;
+ for(size_t j=0; j<serviceCharacteristics.size(); j++) {
+ BTGattCharRef & serviceChar = serviceCharacteristics.at(j);
+ if( GATT_VERBOSE ) {
+ fprintf_td(stderr, " [%2.2d.%2.2d] Characteristic: UUID %s (%s)\n", i, j,
+ serviceChar->value_type->toUUID128String().c_str(),
+ serviceChar->value_type->getTypeSizeString().c_str());
+ fprintf_td(stderr, " [%2.2d.%2.2d] %s\n", i, j, serviceChar->toString().c_str());
+ }
+ if( serviceChar->hasProperties(BTGattChar::PropertyBitVal::Read) ) {
+ POctets value(BTGattHandler::number(BTGattHandler::Defaults::MAX_ATT_MTU), 0, jau::endian::little);
+ if( serviceChar->readValue(value) ) {
+ std::string sval = dfa_utf8_decode(value.get_ptr(), value.size());
+ if( GATT_VERBOSE ) {
+ fprintf_td(stderr, " [%2.2d.%2.2d] value: %s ('%s')\n", (int)i, (int)j, value.toString().c_str(), sval.c_str());
+ }
+ }
+ }
+ jau::darray<BTGattDescRef> & charDescList = serviceChar->descriptorList;
+ for(size_t k=0; k<charDescList.size(); k++) {
+ BTGattDesc & charDesc = *charDescList.at(k);
if( GATT_VERBOSE ) {
- fprintf_td(stderr, " [%2.2d.%2.2d] value: %s ('%s')\n", (int)i, (int)j, value.toString().c_str(), sval.c_str());
+ fprintf_td(stderr, " [%2.2d.%2.2d.%2.2d] Descriptor: UUID %s (%s)\n", i, j, k,
+ charDesc.type->toUUID128String().c_str(),
+ charDesc.type->getTypeSizeString().c_str());
+ fprintf_td(stderr, " [%2.2d.%2.2d.%2.2d] %s\n", i, j, k, charDesc.toString().c_str());
}
}
- }
- jau::darray<BTGattDescRef> & charDescList = serviceChar->descriptorList;
- for(size_t k=0; k<charDescList.size(); k++) {
- BTGattDesc & charDesc = *charDescList.at(k);
- if( GATT_VERBOSE ) {
- fprintf_td(stderr, " [%2.2d.%2.2d.%2.2d] Descriptor: UUID %s (%s)\n", i, j, k,
- charDesc.type->toUUID128String().c_str(),
- charDesc.type->getTypeSizeString().c_str());
- fprintf_td(stderr, " [%2.2d.%2.2d.%2.2d] %s\n", i, j, k, charDesc.toString().c_str());
+ bool cccdEnableResult[2];
+ if( serviceChar->enableNotificationOrIndication( cccdEnableResult ) ) {
+ // ClientCharConfigDescriptor (CCD) is available
+ std::shared_ptr<BTGattChar::Listener> cl = std::make_shared<MyGATTEventListener>(*this, i, j);
+ bool clAdded = serviceChar->addCharListener( cl );
+ if( GATT_VERBOSE ) {
+ fprintf_td(stderr, " [%2.2d.%2.2d] Characteristic-Listener: Notification(%d), Indication(%d): Added %d\n",
+ (int)i, (int)j, cccdEnableResult[0], cccdEnableResult[1], clAdded);
+ fprintf_td(stderr, "\n");
+ }
}
}
- bool cccdEnableResult[2];
- if( serviceChar->enableNotificationOrIndication( cccdEnableResult ) ) {
- // ClientCharConfigDescriptor (CCD) is available
- std::shared_ptr<BTGattChar::Listener> cl = std::make_shared<MyGATTEventListener>(*this, i, j);
- bool clAdded = serviceChar->addCharListener( cl );
- if( GATT_VERBOSE ) {
- fprintf_td(stderr, " [%2.2d.%2.2d] Characteristic-Listener: Notification(%d), Indication(%d): Added %d\n",
- (int)i, (int)j, cccdEnableResult[0], cccdEnableResult[1], clAdded);
- fprintf_td(stderr, "\n");
- }
+ if( GATT_VERBOSE ) {
+ fprintf_td(stderr, "\n");
}
}
- if( GATT_VERBOSE ) {
- fprintf_td(stderr, "\n");
- }
- }
+ success = notificationsReceived >= 2 || indicationsReceived >= 2;
+ } while( !success && device->getConnected() );
- {
- const fraction_timespec t0 = getMonotonicTime();
- bool timeout = false;
- do {
- success = completedGATTCommands >= 1 && ( notificationsReceived >= 2 || indicationsReceived >= 2 );
- if( !success ) {
- const fraction_i64 td = ( getMonotonicTime() - t0 ).to_fraction_i64();
- timeout = 3_s < td;
- if( !timeout ) {
- jau::sleep_for( 17_ms );
- }
- }
- } while( !success && !timeout );
- }
-
- {
+ if( device->getConnected() ) {
// Tell server we have successfully completed the test.
BTGattCmd cmd = BTGattCmd(*device, "FinalHandshake", DBTConstants::CommandUUID, DBTConstants::ResponseUUID, 256);
cmd.setVerbose(true);
@@ -568,16 +551,15 @@ class DBTClient01 : public DBTClientTest {
completedMeasurementsTotal++;
if( success ) {
completedMeasurementsSuccess++;
- }
- if( 0 < measurementsLeft ) {
- measurementsLeft--;
+ if( 0 < measurementsLeft ) {
+ measurementsLeft--;
+ }
}
fprintf_td(stderr, "****** Client Processing Ready Device: Success %d; Measurements completed %d"
- ", left %d; Received notitifications %d, indications %d"
- "; Completed GATT commands %d: %s\n",
+ ", left %d; Received notitifications %d, indications %d: %s\n",
success, completedMeasurementsSuccess.load(),
measurementsLeft.load(), notificationsReceived.load(), indicationsReceived.load(),
- completedGATTCommands.load(), device->getAddressAndType().toString().c_str());
+ device->getAddressAndType().toString().c_str());
}
void removeDevice(BTDeviceRef device) {
diff --git a/trial/direct_bt/dbt_client_server1x.hpp b/trial/direct_bt/dbt_client_server1x.hpp
index 4ed2a0cc..9952042a 100644
--- a/trial/direct_bt/dbt_client_server1x.hpp
+++ b/trial/direct_bt/dbt_client_server1x.hpp
@@ -46,6 +46,9 @@ using namespace direct_bt;
*/
class DBTClientServer1x {
private:
+ // timeout check: timeout_value < test_duration + timeout_preempt_diff; // let's timeout here before our timeout timer
+ static constexpr const fraction_i64 timeout_preempt_diff = 500_ms;
+
std::mutex mtx_sync;
BTDeviceRef lastCompletedDevice = nullptr;
PairingMode lastCompletedDevicePairingMode = PairingMode::NONE;
@@ -59,12 +62,16 @@ class DBTClientServer1x {
{
std::shared_ptr<DBTServer00> server = std::make_shared<DBTServer00>("S-"+suffix, EUI48::ALL_DEVICE, BTMode::DUAL, serverSC, secLevelServer);
std::shared_ptr<DBTClient00> client = std::make_shared<DBTClient00>("C-"+suffix, EUI48::ALL_DEVICE, BTMode::DUAL);
- test8x_fullCycle(suffix, protocolSessionCount, server_client_order,
+ test8x_fullCycle(suffix,
+ protocolSessionCount, DBTConstants::max_connections_per_session, true /* expSuccess */,
+ server_client_order,
server, secLevelServer, serverExpPairing,
client, secLevelClient, clientExpPairing);
}
- void test8x_fullCycle(const std::string& suffix, const int protocolSessionCount, const bool server_client_order,
+ void test8x_fullCycle(const std::string& suffix,
+ const int protocolSessionCount, const int max_connections_per_session, const bool expSuccess,
+ const bool server_client_order,
std::shared_ptr<DBTServerTest> server, const BTSecurityLevel secLevelServer, const ExpectedPairing serverExpPairing,
std::shared_ptr<DBTClientTest> client, const BTSecurityLevel secLevelClient, const ExpectedPairing clientExpPairing)
{
@@ -155,9 +162,9 @@ class DBTClientServer1x {
nullptr == lastCompletedDevice ||
lastCompletedDevice->getConnected() );
}
- max_connections_hit = ( protocolSessionCount * DBTConstants::max_connections_per_session ) <= server->getDisconnectCount();
+ max_connections_hit = ( protocolSessionCount * max_connections_per_session ) <= server->getDisconnectCount();
test_duration = ( jau::getMonotonicTime() - t0 ).to_fraction_i64();
- timeout = 0_s < timeout_value && timeout_value <= test_duration + 500_ms; // let's timeout here before our timeout timer
+ timeout = 0_s < timeout_value && timeout_value <= test_duration + timeout_preempt_diff; // let's timeout here before our timeout timer
if( !done && !max_connections_hit && !timeout ) {
jau::sleep_for( 88_ms );
}
@@ -169,100 +176,105 @@ class DBTClientServer1x {
test_duration.to_ms(), timeout, timeout_value.to_string(true).c_str(), max_connections_hit);
fprintf_td(stderr, " Server ProtocolSessions[success %d/%d total, requested %d], disconnects %d of %d max\n",
server->getProtocolSessionsDoneSuccess(), server->getProtocolSessionsDoneTotal(), protocolSessionCount,
- server->getDisconnectCount(), ( protocolSessionCount * DBTConstants::max_connections_per_session ));
+ server->getDisconnectCount(), ( protocolSessionCount * max_connections_per_session ));
fprintf_td(stderr, " Client ProtocolSessions[success %d/%d total, requested %d], disconnects %d of %d max\n",
client->getProtocolSessionsDoneSuccess(), client->getProtocolSessionsDoneTotal(), protocolSessionCount,
- client->getDisconnectCount(), ( protocolSessionCount * DBTConstants::max_connections_per_session ));
+ client->getDisconnectCount(), ( protocolSessionCount * max_connections_per_session ));
fprintf_td(stderr, "\n\n");
- REQUIRE( false == max_connections_hit );
- REQUIRE( false == timeout );
- {
- const std::lock_guard<std::mutex> lock(mtx_sync); // RAII-style acquire and relinquish via destructor
- REQUIRE( protocolSessionCount <= server->getProtocolSessionsDoneTotal() );
- REQUIRE( protocolSessionCount == server->getProtocolSessionsDoneSuccess() );
- REQUIRE( protocolSessionCount <= client->getProtocolSessionsDoneTotal() );
- REQUIRE( protocolSessionCount == client->getProtocolSessionsDoneSuccess() );
- REQUIRE( nullptr != lastCompletedDevice );
- REQUIRE( EIRDataType::NONE != lastCompletedDeviceEIR.getEIRDataMask() );
- REQUIRE( false == lastCompletedDevice->getConnected() );
- REQUIRE( ( protocolSessionCount * DBTConstants::max_connections_per_session ) > server->getDisconnectCount() );
+ if( expSuccess ) {
+ REQUIRE( false == max_connections_hit );
+ REQUIRE( false == timeout );
+ {
+ const std::lock_guard<std::mutex> lock(mtx_sync); // RAII-style acquire and relinquish via destructor
+ REQUIRE( protocolSessionCount <= server->getProtocolSessionsDoneTotal() );
+ REQUIRE( protocolSessionCount == server->getProtocolSessionsDoneSuccess() );
+ REQUIRE( protocolSessionCount <= client->getProtocolSessionsDoneTotal() );
+ REQUIRE( protocolSessionCount == client->getProtocolSessionsDoneSuccess() );
+ REQUIRE( nullptr != lastCompletedDevice );
+ REQUIRE( EIRDataType::NONE != lastCompletedDeviceEIR.getEIRDataMask() );
+ REQUIRE( false == lastCompletedDevice->getConnected() );
+ REQUIRE( ( protocolSessionCount * max_connections_per_session ) > server->getDisconnectCount() );
+ }
}
//
// Client stop
//
- DBTClientTest::stopDiscovery(client, true /* current_exp_discovering_state */, "test"+suffix+"_stopDiscovery");
+ const bool current_exp_discovering_state = expSuccess ? true : client->getAdapter()->isDiscovering();
+ DBTClientTest::stopDiscovery(client, current_exp_discovering_state, "test"+suffix+"_stopDiscovery");
client->close("test"+suffix+"_close");
//
// Server stop
//
- DBTServerTest::stop(server, false /* current_exp_advertising_state */, "test"+suffix+"_stopAdvertising");
+ const bool current_exp_advertising_state = expSuccess ? false : server->getAdapter()->isAdvertising();
+ DBTServerTest::stop(server, current_exp_advertising_state, "test"+suffix+"_stopAdvertising");
server->close("test"+suffix+"_close");
- //
- // Validating Security Mode
- //
- SMPKeyBin clientKeys = SMPKeyBin::read(DBTConstants::CLIENT_KEY_PATH, *lastCompletedDevice, true /* verbose */);
- REQUIRE( true == clientKeys.isValid() );
- const BTSecurityLevel clientKeysSecLevel = clientKeys.getSecLevel();
- REQUIRE( secLevelClient == clientKeysSecLevel);
- {
- if( ExpectedPairing::PREPAIRED == clientExpPairing && BTSecurityLevel::NONE < secLevelClient ) {
- // Using encryption: pre-paired
- REQUIRE( PairingMode::PRE_PAIRED == lastCompletedDevicePairingMode );
- REQUIRE( BTSecurityLevel::ENC_ONLY == lastCompletedDeviceSecurityLevel ); // pre-paired fixed level, no auth
- } else if( ExpectedPairing::NEW_PAIRING == clientExpPairing && BTSecurityLevel::NONE < secLevelClient ) {
- // Using encryption: Newly paired
- REQUIRE( PairingMode::PRE_PAIRED != lastCompletedDevicePairingMode );
- REQUIRE_MSG( "PairingMode client "+to_string(lastCompletedDevicePairingMode)+" not > NONE", PairingMode::NONE < lastCompletedDevicePairingMode );
- REQUIRE_MSG( "SecurityLevel client "+to_string(lastCompletedDeviceSecurityLevel)+" not >= "+to_string(secLevelClient), secLevelClient <= lastCompletedDeviceSecurityLevel );
- } else if( ExpectedPairing::DONT_CARE == clientExpPairing && BTSecurityLevel::NONE < secLevelClient ) {
- // Any encryption, any pairing
- REQUIRE_MSG( "PairingMode client "+to_string(lastCompletedDevicePairingMode)+" not > NONE", PairingMode::NONE < lastCompletedDevicePairingMode );
- REQUIRE_MSG( "SecurityLevel client "+to_string(lastCompletedDeviceSecurityLevel)+" not >= "+to_string(secLevelClient), secLevelClient <= lastCompletedDeviceSecurityLevel );
- } else {
- // No encryption: No pairing
- REQUIRE( PairingMode::NONE == lastCompletedDevicePairingMode );
- REQUIRE( BTSecurityLevel::NONE == lastCompletedDeviceSecurityLevel );
+ if( expSuccess ) {
+ //
+ // Validating Security Mode
+ //
+ SMPKeyBin clientKeys = SMPKeyBin::read(DBTConstants::CLIENT_KEY_PATH, *lastCompletedDevice, true /* verbose */);
+ REQUIRE( true == clientKeys.isValid() );
+ const BTSecurityLevel clientKeysSecLevel = clientKeys.getSecLevel();
+ REQUIRE( secLevelClient == clientKeysSecLevel);
+ {
+ if( ExpectedPairing::PREPAIRED == clientExpPairing && BTSecurityLevel::NONE < secLevelClient ) {
+ // Using encryption: pre-paired
+ REQUIRE( PairingMode::PRE_PAIRED == lastCompletedDevicePairingMode );
+ REQUIRE( BTSecurityLevel::ENC_ONLY == lastCompletedDeviceSecurityLevel ); // pre-paired fixed level, no auth
+ } else if( ExpectedPairing::NEW_PAIRING == clientExpPairing && BTSecurityLevel::NONE < secLevelClient ) {
+ // Using encryption: Newly paired
+ REQUIRE( PairingMode::PRE_PAIRED != lastCompletedDevicePairingMode );
+ REQUIRE_MSG( "PairingMode client "+to_string(lastCompletedDevicePairingMode)+" not > NONE", PairingMode::NONE < lastCompletedDevicePairingMode );
+ REQUIRE_MSG( "SecurityLevel client "+to_string(lastCompletedDeviceSecurityLevel)+" not >= "+to_string(secLevelClient), secLevelClient <= lastCompletedDeviceSecurityLevel );
+ } else if( ExpectedPairing::DONT_CARE == clientExpPairing && BTSecurityLevel::NONE < secLevelClient ) {
+ // Any encryption, any pairing
+ REQUIRE_MSG( "PairingMode client "+to_string(lastCompletedDevicePairingMode)+" not > NONE", PairingMode::NONE < lastCompletedDevicePairingMode );
+ REQUIRE_MSG( "SecurityLevel client "+to_string(lastCompletedDeviceSecurityLevel)+" not >= "+to_string(secLevelClient), secLevelClient <= lastCompletedDeviceSecurityLevel );
+ } else {
+ // No encryption: No pairing
+ REQUIRE( PairingMode::NONE == lastCompletedDevicePairingMode );
+ REQUIRE( BTSecurityLevel::NONE == lastCompletedDeviceSecurityLevel );
+ }
}
- }
- //
- // Validating EIR
- //
- {
- const std::lock_guard<std::mutex> lock(mtx_sync); // RAII-style acquire and relinquish via destructor
- fprintf_td(stderr, "lastCompletedDevice.connectedEIR: %s\n", lastCompletedDeviceEIR.toString().c_str());
- REQUIRE( EIRDataType::NONE != lastCompletedDeviceEIR.getEIRDataMask() );
- REQUIRE( true == lastCompletedDeviceEIR.isSet(EIRDataType::FLAGS) );
- REQUIRE( true == lastCompletedDeviceEIR.isSet(EIRDataType::SERVICE_UUID) );
- REQUIRE( true == lastCompletedDeviceEIR.isSet(EIRDataType::NAME) );
- REQUIRE( true == lastCompletedDeviceEIR.isSet(EIRDataType::CONN_IVAL) );
- REQUIRE( serverName == lastCompletedDeviceEIR.getName() );
+ //
+ // Validating EIR
+ //
{
- const EInfoReport eir = *lastCompletedDevice->getEIR();
- fprintf_td(stderr, "lastCompletedDevice.currentEIR: %s\n", eir.toString().c_str());
- REQUIRE( EIRDataType::NONE == eir.getEIRDataMask() );
- REQUIRE( 0 == eir.getName().length());
+ const std::lock_guard<std::mutex> lock(mtx_sync); // RAII-style acquire and relinquish via destructor
+ fprintf_td(stderr, "lastCompletedDevice.connectedEIR: %s\n", lastCompletedDeviceEIR.toString().c_str());
+ REQUIRE( EIRDataType::NONE != lastCompletedDeviceEIR.getEIRDataMask() );
+ REQUIRE( true == lastCompletedDeviceEIR.isSet(EIRDataType::FLAGS) );
+ REQUIRE( true == lastCompletedDeviceEIR.isSet(EIRDataType::SERVICE_UUID) );
+ REQUIRE( true == lastCompletedDeviceEIR.isSet(EIRDataType::NAME) );
+ REQUIRE( true == lastCompletedDeviceEIR.isSet(EIRDataType::CONN_IVAL) );
+ REQUIRE( serverName == lastCompletedDeviceEIR.getName() );
+ {
+ const EInfoReport eir = *lastCompletedDevice->getEIR();
+ fprintf_td(stderr, "lastCompletedDevice.currentEIR: %s\n", eir.toString().c_str());
+ REQUIRE( EIRDataType::NONE == eir.getEIRDataMask() );
+ REQUIRE( 0 == eir.getName().length());
+ }
}
- }
- //
- // Now reuse adapter for client mode -> Start discovery + Stop Discovery
- //
- {
- const BTAdapterRef adapter = server->getAdapter();
- { // if( false ) {
- adapter->removeAllStatusListener();
- }
+ //
+ // Now reuse adapter for client mode -> Start discovery + Stop Discovery
+ //
+ {
+ const BTAdapterRef adapter = server->getAdapter();
+ { // if( false ) {
+ adapter->removeAllStatusListener();
+ }
- DBTEndpoint::startDiscovery(adapter, false /* current_exp_discovering_state */);
+ DBTEndpoint::startDiscovery(adapter, false /* current_exp_discovering_state */);
- DBTEndpoint::stopDiscovery(adapter, true /* current_exp_discovering_state */);
+ DBTEndpoint::stopDiscovery(adapter, true /* current_exp_discovering_state */);
+ }
}
-
const int count = manager.removeChangedAdapterSetCallback(myChangedAdapterSetFunc);
fprintf_td(stderr, "****** EOL Removed ChangedAdapterSetCallback %d\n", count);
}
diff --git a/trial/direct_bt/dbt_server01.hpp b/trial/direct_bt/dbt_server01.hpp
index 9bcbe984..7dfe07ed 100644
--- a/trial/direct_bt/dbt_server01.hpp
+++ b/trial/direct_bt/dbt_server01.hpp
@@ -25,6 +25,8 @@
#ifndef DBT_SERVER01_HPP_
#define DBT_SERVER01_HPP_
+#include <random>
+
#include "dbt_constants.hpp"
#include "dbt_server_test.hpp"
@@ -75,6 +77,8 @@ class DBTServer01 : public DBTServerTest {
jau::sc_atomic_int servedProtocolSessionsSuccess = 0;
jau::sc_atomic_int servingProtocolSessionsLeft = 1;
+ bool do_disconnect = false;
+
DBGattServerRef dbGattServer = std::make_shared<DBGattServer>(
/* services: */
jau::make_darray( // DBGattService
@@ -381,14 +385,17 @@ class DBTServer01 : public DBTServerTest {
}
}
- bool onceDisconnect = true;
-
void disconnectDevice() {
- jau::sleep_for( 300_ms );
+ // sleep range: 100 - 1500 ms
+ // sleep range: 100 - 1500 ms
+ static const int sleep_min = 100;
+ static const int sleep_max = 1500;
+ static std::random_device rng_hw;;
+ static std::uniform_int_distribution<int> rng_dist(sleep_min, sleep_max);
+ const int64_t sleep_dur = rng_dist(rng_hw);
+ jau::sleep_for( sleep_dur * 1_ms );
BTDeviceRef connectedDevice_ = parent.getDevice();
- fprintf_td(stderr, "****** Server GATT::disconnectDevice(sessions [%d ok / %d total], left %d): client %s\n",
- parent.servedProtocolSessionsSuccess.load(), parent.servedProtocolSessionsTotal.load(), parent.servingProtocolSessionsLeft.load(),
- connectedDevice_->toString().c_str());
+ fprintf_td(stderr, "****** Server i470 disconnectDevice(delayed %d ms): client %s\n", sleep_dur, connectedDevice_->toString().c_str());
connectedDevice_->disconnect();
}
@@ -452,8 +459,7 @@ class DBTServer01 : public DBTServerTest {
fprintf_td(stderr, "****** Server GATT::mtuChanged(match %d, served %zu, left %zu): %d -> %d, %s\n",
match, parent.servedProtocolSessionsTotal.load(), parent.servingProtocolSessionsLeft.load(),
match ? (int)usedMTU_old : 0, (int)mtu, device->toString().c_str());
- if( onceDisconnect ) {
- onceDisconnect = false;
+ if( parent.do_disconnect ) {
std::thread disconnectThread(&MyGATTServerListener::disconnectDevice, this);
disconnectThread.detach();
}
@@ -574,22 +580,18 @@ class DBTServer01 : public DBTServerTest {
public:
- DBTServer01(const std::string& adapterName_, const jau::EUI48& useAdapter_, const BTMode btMode_, const bool use_SC_, const BTSecurityLevel adapterSecurityLevel_) {
+ DBTServer01(const std::string& adapterName_, const jau::EUI48& useAdapter_, const BTMode btMode_,
+ const bool use_SC_, const BTSecurityLevel adapterSecurityLevel_, const bool do_disconnect_)
+ {
this->adapterName = adapterName_;
this->useAdapter = useAdapter_;
this->btMode = btMode_;
this->use_SC = use_SC_;
this->adapterSecurityLevel = adapterSecurityLevel_;
+ this->do_disconnect = do_disconnect_;
dbGattServer->addListener( gattServerListener );
}
- DBTServer01(const std::string& adapterName_, const jau::EUI48& useAdapter_, const BTSecurityLevel adapterSecurityLevel_)
- : DBTServer01(adapterName_, useAdapter_, BTMode::DUAL, true /* SC */, adapterSecurityLevel_)
- { }
-
- DBTServer01(const std::string& adapterName_, const BTSecurityLevel adapterSecurityLevel_)
- : DBTServer01(adapterName_, EUI48::ALL_DEVICE, BTMode::DUAL, true /* SC */, adapterSecurityLevel_)
- { }
std::string getName() override { return adapterName; }
diff --git a/trial/direct_bt/test_provoke_client_server_i470.cpp b/trial/direct_bt/test_provoke_client_server_i470.cpp
index e393182f..ad10c837 100644
--- a/trial/direct_bt/test_provoke_client_server_i470.cpp
+++ b/trial/direct_bt/test_provoke_client_server_i470.cpp
@@ -50,22 +50,56 @@ static BaseDBTClientServer& base_test_framework = BaseDBTClientServer::get();
*/
class TestDBTClientServer_i470 : public DBTClientServer1x {
public:
- void test_i470() {
- base_test_framework.setupTest( 20_s );
+ void test_i470_a() {
+ base_test_framework.setupTest( 10_s );
{
const bool serverSC = true;
- const std::string suffix = "i470";
- const int protocolSessionCount = 2;
+ const std::string suffix = "i470_a";
+ const int protocolSessionCount = 10;
+ const int max_connections_per_session = 200;
+ const bool expSuccess = false;
const bool server_client_order = true;
const BTSecurityLevel secLevelServer = BTSecurityLevel::ENC_ONLY;
const BTSecurityLevel secLevelClient = BTSecurityLevel::ENC_ONLY;
const ExpectedPairing serverExpPairing = ExpectedPairing::DONT_CARE;
const ExpectedPairing clientExpPairing = ExpectedPairing::DONT_CARE;
+ const bool client_do_disconnect = true;
+ const bool server_do_disconnect = false;
- // std::shared_ptr<DBTServerTest> server = std::make_shared<DBTServer01>("S-"+suffix, EUI48::ALL_DEVICE, BTMode::DUAL, serverSC, secLevelServer);
- std::shared_ptr<DBTServerTest> server = std::make_shared<DBTServer00>("S-"+suffix, EUI48::ALL_DEVICE, BTMode::DUAL, serverSC, secLevelServer);
- std::shared_ptr<DBTClientTest> client = std::make_shared<DBTClient01>("C-"+suffix, EUI48::ALL_DEVICE, BTMode::DUAL);
- test8x_fullCycle(suffix, protocolSessionCount, server_client_order,
+ std::shared_ptr<DBTServerTest> server = std::make_shared<DBTServer01>("S-"+suffix, EUI48::ALL_DEVICE, BTMode::DUAL, serverSC, secLevelServer, server_do_disconnect);
+ std::shared_ptr<DBTClientTest> client = std::make_shared<DBTClient01>("C-"+suffix, EUI48::ALL_DEVICE, BTMode::DUAL, client_do_disconnect);
+
+ test8x_fullCycle(suffix,
+ protocolSessionCount, max_connections_per_session, expSuccess,
+ server_client_order,
+ server, secLevelServer, serverExpPairing,
+ client, secLevelClient, clientExpPairing);
+ }
+ base_test_framework.cleanupTest();
+ }
+
+ void test_i470_b() {
+ base_test_framework.setupTest( 10_s );
+ {
+ const bool serverSC = true;
+ const std::string suffix = "i470_b";
+ const int protocolSessionCount = 10;
+ const int max_connections_per_session = 200;
+ const bool expSuccess = false;
+ const bool server_client_order = true;
+ const BTSecurityLevel secLevelServer = BTSecurityLevel::ENC_ONLY;
+ const BTSecurityLevel secLevelClient = BTSecurityLevel::ENC_ONLY;
+ const ExpectedPairing serverExpPairing = ExpectedPairing::DONT_CARE;
+ const ExpectedPairing clientExpPairing = ExpectedPairing::DONT_CARE;
+ const bool client_do_disconnect = false;
+ const bool server_do_disconnect = true;
+
+ std::shared_ptr<DBTServerTest> server = std::make_shared<DBTServer01>("S-"+suffix, EUI48::ALL_DEVICE, BTMode::DUAL, serverSC, secLevelServer, server_do_disconnect);
+ std::shared_ptr<DBTClientTest> client = std::make_shared<DBTClient01>("C-"+suffix, EUI48::ALL_DEVICE, BTMode::DUAL, client_do_disconnect);
+
+ test8x_fullCycle(suffix,
+ protocolSessionCount, max_connections_per_session, expSuccess,
+ server_client_order,
server, secLevelServer, serverExpPairing,
client, secLevelClient, clientExpPairing);
}
@@ -73,4 +107,5 @@ class TestDBTClientServer_i470 : public DBTClientServer1x {
}
};
-METHOD_AS_TEST_CASE( TestDBTClientServer_i470::test_i470, "ClientServer i470 Trial", "[trial][i470]");
+METHOD_AS_TEST_CASE( TestDBTClientServer_i470::test_i470_a, "ClientServer i470 Trial a", "[trial][i470]");
+METHOD_AS_TEST_CASE( TestDBTClientServer_i470::test_i470_b, "ClientServer i470 Trial b", "[trial][i470]");