summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2022-05-07 01:38:59 +0200
committerSven Gothel <[email protected]>2022-05-07 01:38:59 +0200
commit5544b00ee8f8560618aac8edb9ffa830fc294d97 (patch)
tree98c8ac179939f8ff5098ae6c3dee90e1a884e529
parent662486318a7509f2d610dbbcb39f1073d8b413c1 (diff)
trial i470 test_provoke (C++) / TestDBTProvoke (Java) demonstrating C++ survives while Java crashes (known issue)
-rw-r--r--scripts/build.sh18
-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
-rw-r--r--trial/java/trial/org/direct_bt/DBTClient01.java164
-rw-r--r--trial/java/trial/org/direct_bt/DBTClientServer1x.java160
-rw-r--r--trial/java/trial/org/direct_bt/DBTServer01.java29
-rw-r--r--trial/java/trial/org/direct_bt/TestDBTProvokeClientServer_i470.java45
9 files changed, 439 insertions, 390 deletions
diff --git a/scripts/build.sh b/scripts/build.sh
index b5a99a53..fdd6e238 100644
--- a/scripts/build.sh
+++ b/scripts/build.sh
@@ -43,16 +43,16 @@ buildit() {
cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TRIAL=ON ..
# cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TRIAL=ON -DDEBUG=ON ..
- # cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TESTING=ON ..
- # cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TESTING=ON -DDEBUG=ON ..
+ # cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DUSE_LIBUNWIND=OFF -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TRIAL=ON ..
+ # cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DUSE_LIBUNWIND=OFF -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TRIAL=ON -DDEBUG=ON ..
- # cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TESTING=ON -DUSE_STRIP=OFF ..
- # cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TESTING=ON -DUSE_STRIP=ON -DJAVAC_DEBUG_ARGS="none" ..
- # cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TESTING=ON -DGPROF=ON ..
- # cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TESTING=ON -DPERF_ANALYSIS=ON ..
- # cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TESTING=ON -DDEBUG=ON -DINSTRUMENTATION=ON ..
- # cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TESTING=ON -DDEBUG=ON -DINSTRUMENTATION_UNDEFINED=ON ..
- # cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TESTING=ON -DDEBUG=ON -DINSTRUMENTATION_THREAD=ON ..
+ # cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TRIAL=ON -DUSE_STRIP=OFF ..
+ # cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TRIAL=ON -DUSE_STRIP=ON -DJAVAC_DEBUG_ARGS="none" ..
+ # cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TRIAL=ON -DGPROF=ON ..
+ # cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TRIAL=ON -DPERF_ANALYSIS=ON ..
+ # cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TRIAL=ON -DDEBUG=ON -DINSTRUMENTATION=ON ..
+ # cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TRIAL=ON -DDEBUG=ON -DINSTRUMENTATION_UNDEFINED=ON ..
+ # cmake $CLANG_ARGS -DCMAKE_INSTALL_PREFIX=$rootdir/dist-$archabi -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TRIAL=ON -DDEBUG=ON -DINSTRUMENTATION_THREAD=ON ..
make -j $CPU_COUNT install
if [ $? -eq 0 ] ; then
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]");
diff --git a/trial/java/trial/org/direct_bt/DBTClient01.java b/trial/java/trial/org/direct_bt/DBTClient01.java
index 2f4d89b2..eca16ba8 100644
--- a/trial/java/trial/org/direct_bt/DBTClient01.java
+++ b/trial/java/trial/org/direct_bt/DBTClient01.java
@@ -68,8 +68,6 @@ public class DBTClient01 implements DBTClientTest {
private final MyAdapterStatusListener myAdapterStatusListener = new MyAdapterStatusListener();
- private final byte cmd_arg = (byte)0x44;
-
private String adapterName = "TestDev2_Clt";
private EUI48 useAdapter = EUI48.ALL_DEVICE;
private BTMode btMode = BTMode.DUAL;
@@ -86,14 +84,16 @@ public class DBTClient01 implements DBTClientTest {
private final AtomicInteger deviceReadyCount = new AtomicInteger(0);
private final AtomicInteger notificationsReceived = new AtomicInteger(0);
private final AtomicInteger indicationsReceived = new AtomicInteger(0);
- private final AtomicInteger completedGATTCommands = new AtomicInteger(0);
private final AtomicInteger completedMeasurementsTotal = new AtomicInteger(0);
private final AtomicInteger completedMeasurementsSuccess = new AtomicInteger(0);
- public DBTClient01(final String adapterName, final EUI48 useAdapter, final BTMode btMode) {
+ private final boolean do_disconnect;
+
+ public DBTClient01(final String adapterName, final EUI48 useAdapter, final BTMode btMode, final boolean do_disconnect) {
this.adapterName = adapterName;
this.useAdapter = useAdapter;
this.btMode = btMode;
+ this.do_disconnect = do_disconnect;
}
@Override
@@ -259,6 +259,19 @@ public class DBTClient01 implements DBTClientTest {
}
}
+ private void disconnectDevice(final BTDevice device) {
+ // sleep range: 100 - 1500 ms
+ final int sleep_min = 100;
+ final int sleep_max = 1500;
+ final int sleep_dur = (int) ( Math.random() * ( sleep_max - sleep_min + 1 ) + sleep_min );
+ try {
+ Thread.sleep(sleep_dur); // wait a little (FIXME: Fast restart of advertising error)
+ } catch (final InterruptedException e) { }
+
+ BTUtils.fprintf_td(System.err, "****** Client i470 disconnectDevice(delayed %d ms): client %s\n", sleep_dur, device.toString());
+ device.disconnect();
+ }
+
@Override
public void deviceReady(final BTDevice device, final long timestamp) {
{
@@ -271,8 +284,13 @@ public class DBTClient01 implements DBTClientTest {
// Be nice to Test* case, allowing to reach its own listener.deviceReady() added later
executeOffThread( () -> { processReadyDevice(device); },
- "DBT-Process-"+device.getAddressAndType(), true /* detach */);
+ "DBT-Process1-"+device.getAddressAndType(), true /* detach */);
// processReadyDevice(device); // AdapterStatusListener::deviceReady() explicitly allows prolonged and complex code execution!
+
+ if( do_disconnect ) {
+ executeOffThread( () -> { disconnectDevice(device); },
+ "DBT-Disconnect-"+device.getAddressAndType(), true /* detach */);
+ }
}
}
@@ -326,7 +344,6 @@ public class DBTClient01 implements DBTClientTest {
}
private void resetLastProcessingStats() {
- completedGATTCommands.set(0);
notificationsReceived.set(0);
indicationsReceived.set(0);
}
@@ -432,95 +449,65 @@ public class DBTClient01 implements DBTClientTest {
"PERF: get-gatt-services " + td35 + " ms,"+System.lineSeparator());
}
- {
- final BTGattCmd cmd = new BTGattCmd(device, "TestCmd", null /* service_uuid */, DBTConstants.CommandUUID, DBTConstants.ResponseUUID);
- cmd.setVerbose(true);
- final boolean cmd_resolved = cmd.isResolved();
- BTUtils.println(System.err, "Client Command test: "+cmd.toString()+", resolved "+cmd_resolved);
- final byte[] cmd_data = { cmd_arg };
- final HCIStatusCode cmd_res = cmd.send(true /* prefNoAck */, cmd_data, 3000 /* timeoutMS */);
- if( HCIStatusCode.SUCCESS == cmd_res ) {
- final byte[] resp = cmd.getResponse();
- if( 1 == resp.length && resp[0] == cmd_arg ) {
- BTUtils.fprintf_td(System.err, "Client Success: %s -> %s (echo response)\n", cmd.toString(), BTUtils.bytesHexString(resp, 0, resp.length, true /* lsb */));
- completedGATTCommands.incrementAndGet();
- } else {
- BTUtils.fprintf_td(System.err, "Client Failure: %s -> %s (different response)\n", cmd.toString(), BTUtils.bytesHexString(resp, 0, resp.length, true /* lsb */));
- }
- } else {
- BTUtils.fprintf_td(System.err, "Client Failure: %s -> %s\n", cmd.toString(), cmd_res.toString());
- }
- cmd.close();
- }
-
- try {
- int i=0;
- for(final Iterator<BTGattService> srvIter = primServices.iterator(); srvIter.hasNext(); i++) {
- final BTGattService primService = srvIter.next();
- if( GATT_VERBOSE ) {
- BTUtils.fprintf_td(System.err, " [%02d] Service UUID %s\n", i, primService.getUUID());
- BTUtils.fprintf_td(System.err, " [%02d] %s\n", i, primService.toString());
- }
- int j=0;
- final List<BTGattChar> serviceCharacteristics = primService.getChars();
- for(final Iterator<BTGattChar> charIter = serviceCharacteristics.iterator(); charIter.hasNext(); j++) {
- final BTGattChar serviceChar = charIter.next();
+ do {
+ try {
+ int i=0;
+ for(final Iterator<BTGattService> srvIter = primServices.iterator(); srvIter.hasNext(); i++) {
+ final BTGattService primService = srvIter.next();
if( GATT_VERBOSE ) {
- BTUtils.fprintf_td(System.err, " [%02d.%02d] Characteristic: UUID %s\n", i, j, serviceChar.getUUID());
- BTUtils.fprintf_td(System.err, " [%02d.%02d] %s\n", i, j, serviceChar.toString());
+ BTUtils.fprintf_td(System.err, " [%02d] Service UUID %s\n", i, primService.getUUID());
+ BTUtils.fprintf_td(System.err, " [%02d] %s\n", i, primService.toString());
}
- final GattCharPropertySet properties = serviceChar.getProperties();
- if( properties.isSet(GattCharPropertySet.Type.Read) ) {
- final byte[] value = serviceChar.readValue();
- final String svalue = BTUtils.decodeUTF8String(value, 0, value.length);
+ int j=0;
+ final List<BTGattChar> serviceCharacteristics = primService.getChars();
+ for(final Iterator<BTGattChar> charIter = serviceCharacteristics.iterator(); charIter.hasNext(); j++) {
+ final BTGattChar serviceChar = charIter.next();
if( GATT_VERBOSE ) {
- BTUtils.fprintf_td(System.err, " [%02d.%02d] value: %s ('%s')\n", i, j, BTUtils.bytesHexString(value, 0, -1, true), svalue);
+ BTUtils.fprintf_td(System.err, " [%02d.%02d] Characteristic: UUID %s\n", i, j, serviceChar.getUUID());
+ BTUtils.fprintf_td(System.err, " [%02d.%02d] %s\n", i, j, serviceChar.toString());
}
- }
- int k=0;
- final List<BTGattDesc> charDescList = serviceChar.getDescriptors();
- for(final Iterator<BTGattDesc> descIter = charDescList.iterator(); descIter.hasNext(); k++) {
- final BTGattDesc charDesc = descIter.next();
- if( GATT_VERBOSE ) {
- BTUtils.fprintf_td(System.err, " [%02d.%02d.%02d] Descriptor: UUID %s\n", i, j, k, charDesc.getUUID());
- BTUtils.fprintf_td(System.err, " [%02d.%02d.%02d] %s\n", i, j, k, charDesc.toString());
+ final GattCharPropertySet properties = serviceChar.getProperties();
+ if( properties.isSet(GattCharPropertySet.Type.Read) ) {
+ final byte[] value = serviceChar.readValue();
+ final String svalue = BTUtils.decodeUTF8String(value, 0, value.length);
+ if( GATT_VERBOSE ) {
+ BTUtils.fprintf_td(System.err, " [%02d.%02d] value: %s ('%s')\n", i, j, BTUtils.bytesHexString(value, 0, -1, true), svalue);
+ }
}
- }
- final boolean cccdEnableResult[] = { false, false };
- if( serviceChar.enableNotificationOrIndication( cccdEnableResult ) ) {
- // ClientCharConfigDescriptor (CCD) is available
- final boolean clAdded = null != serviceChar.addCharListener( new MyGATTEventListener(i, j) );
- if( GATT_VERBOSE ) {
- BTUtils.fprintf_td(System.err, " [%02d.%02d] Characteristic-Listener: Notification(%b), Indication(%b): Added %b\n",
- i, j, cccdEnableResult[0], cccdEnableResult[1], clAdded);
- BTUtils.fprintf_td(System.err, "\n");
+ int k=0;
+ final List<BTGattDesc> charDescList = serviceChar.getDescriptors();
+ for(final Iterator<BTGattDesc> descIter = charDescList.iterator(); descIter.hasNext(); k++) {
+ final BTGattDesc charDesc = descIter.next();
+ if( GATT_VERBOSE ) {
+ BTUtils.fprintf_td(System.err, " [%02d.%02d.%02d] Descriptor: UUID %s\n", i, j, k, charDesc.getUUID());
+ BTUtils.fprintf_td(System.err, " [%02d.%02d.%02d] %s\n", i, j, k, charDesc.toString());
+ }
+ }
+ final boolean cccdEnableResult[] = { false, false };
+ if( serviceChar.enableNotificationOrIndication( cccdEnableResult ) ) {
+ // ClientCharConfigDescriptor (CCD) is available
+ final boolean clAdded = null != serviceChar.addCharListener( new MyGATTEventListener(i, j) );
+ if( GATT_VERBOSE ) {
+ BTUtils.fprintf_td(System.err, " [%02d.%02d] Characteristic-Listener: Notification(%b), Indication(%b): Added %b\n",
+ i, j, cccdEnableResult[0], cccdEnableResult[1], clAdded);
+ BTUtils.fprintf_td(System.err, "\n");
+ }
}
}
- }
- if( GATT_VERBOSE ) {
- BTUtils.fprintf_td(System.err, "\n");
- }
- }
- } catch( final Exception ex) {
- BTUtils.println(System.err, "****** Client Processing Ready Device: Exception.2 caught for " + device.toString() + ": "+ex.getMessage());
- ex.printStackTrace();
- }
-
- {
- final long t0 = BTUtils.currentTimeMillis();
- boolean timeout = false;
- do {
- success = completedGATTCommands.get() >= 1 && ( notificationsReceived.get() >= 2 || indicationsReceived.get() >= 2 );
- if( !success ) {
- timeout = 3000 < ( BTUtils.currentTimeMillis() - t0 ); // 3s timeout
- if( !timeout ) {
- try { Thread.sleep(17); } catch (final InterruptedException e) { }
+ if( GATT_VERBOSE ) {
+ BTUtils.fprintf_td(System.err, "\n");
}
}
- } while( !success && !timeout );
- }
- {
+ success = notificationsReceived.get() >= 2 || indicationsReceived.get() >= 2;
+
+ } catch( final Exception ex) {
+ BTUtils.println(System.err, "****** Client Processing Ready Device: Exception.2 caught for " + device.toString() + ": "+ex.getMessage());
+ ex.printStackTrace();
+ }
+ } while( !success && device.getConnected() );
+
+ if( device.getConnected() ) {
// Tell server we have successfully completed the test.
final BTGattCmd cmd = new BTGattCmd(device, "FinalHandshake", null /* service_uuid */, DBTConstants.CommandUUID, DBTConstants.ResponseUUID);
cmd.setVerbose(true);
@@ -569,15 +556,14 @@ public class DBTClient01 implements DBTClientTest {
completedMeasurementsTotal.addAndGet(1);
if( success ) {
completedMeasurementsSuccess.addAndGet(1);
- }
- if( 0 < measurementsLeft.get() ) {
- measurementsLeft.decrementAndGet();
+ if( 0 < measurementsLeft.get() ) {
+ measurementsLeft.decrementAndGet();
+ }
}
BTUtils.println(System.err, "****** Client Processing Ready Device: Success "+success+
"; Measurements completed "+completedMeasurementsSuccess.get()+
", left "+measurementsLeft.get()+
"; Received notitifications "+notificationsReceived.get()+", indications "+indicationsReceived.get()+
- "; Completed GATT commands "+completedGATTCommands.get()+
": "+device.getAddressAndType());
}
diff --git a/trial/java/trial/org/direct_bt/DBTClientServer1x.java b/trial/java/trial/org/direct_bt/DBTClientServer1x.java
index 460e6ece..efffbfb8 100644
--- a/trial/java/trial/org/direct_bt/DBTClientServer1x.java
+++ b/trial/java/trial/org/direct_bt/DBTClientServer1x.java
@@ -58,6 +58,9 @@ import org.junit.Assert;
* - reuse server-adapter for client-mode discovery (just toggle on/off)
*/
public abstract class DBTClientServer1x extends BaseDBTClientServer {
+ // timeout check: timeout_value < test_duration + timeout_preempt_diff; // let's timeout here before our timeout timer
+ static final long timeout_preempt_diff = 500;
+
final Object mtx_sync = new Object();
BTDevice lastCompletedDevice = null;
PairingMode lastCompletedDevicePairingMode = PairingMode.NONE;
@@ -71,14 +74,16 @@ public abstract class DBTClientServer1x extends BaseDBTClientServer {
{
final DBTServer00 server = new DBTServer00("S-"+suffix, EUI48.ALL_DEVICE, BTMode.DUAL, serverSC, secLevelServer);
final DBTClient00 client = new DBTClient00("C-"+suffix, EUI48.ALL_DEVICE, BTMode.DUAL);
- test8x_fullCycle(timeout_value,
- suffix, protocolSessionCount, server_client_order,
+ test8x_fullCycle(timeout_value, suffix,
+ protocolSessionCount, DBTConstants.max_connections_per_session, true /* expSuccess */,
+ server_client_order,
server, secLevelServer, serverExpPairing,
client, secLevelClient, clientExpPairing);
}
- final void test8x_fullCycle(final long timeout_value,
- final String suffix, final int protocolSessionCount, final boolean server_client_order,
+ final void test8x_fullCycle(final long timeout_value, final String suffix,
+ final int protocolSessionCount, final int max_connections_per_session, final boolean expSuccess,
+ final boolean server_client_order,
final DBTServerTest server, final BTSecurityLevel secLevelServer, final ExpectedPairing serverExpPairing,
final DBTClientTest client, final BTSecurityLevel secLevelClient, final ExpectedPairing clientExpPairing)
{
@@ -162,9 +167,9 @@ public abstract class DBTClientServer1x extends BaseDBTClientServer {
null == 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 = BTUtils.currentTimeMillis() - t0;
- timeout = 0 < timeout_value && timeout_value <= test_duration + 500; // let's timeout here before our timeout timer
+ timeout = 0 < timeout_value && timeout_value <= test_duration + timeout_preempt_diff; // let's timeout here before our timeout timer
if( !done && !max_connections_hit && !timeout ) {
try { Thread.sleep(88); } catch (final InterruptedException e) { e.printStackTrace(); }
}
@@ -176,99 +181,104 @@ public abstract class DBTClientServer1x extends BaseDBTClientServer {
test_duration, timeout, timeout_value, max_connections_hit);
BTUtils.fprintf_td(System.err, " 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 ));
BTUtils.fprintf_td(System.err, " 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 ));
BTUtils.fprintf_td(System.err, "\n\n");
- Assert.assertFalse( max_connections_hit );
- Assert.assertFalse( timeout );
+ if( expSuccess ) {
+ Assert.assertFalse( max_connections_hit );
+ Assert.assertFalse( timeout );
- synchronized( mtx_sync ) {
- Assert.assertTrue(protocolSessionCount <= server.getProtocolSessionsDoneTotal());
- Assert.assertEquals(protocolSessionCount, server.getProtocolSessionsDoneSuccess());
- Assert.assertTrue(protocolSessionCount <= client.getProtocolSessionsDoneTotal());
- Assert.assertEquals(protocolSessionCount, client.getProtocolSessionsDoneSuccess());
- Assert.assertNotNull(lastCompletedDevice);
- Assert.assertNotNull(lastCompletedDeviceEIR);
- Assert.assertFalse(lastCompletedDevice.getConnected());
- Assert.assertTrue( ( 1 * DBTConstants.max_connections_per_session ) > server.getDisconnectCount() );
+ synchronized( mtx_sync ) {
+ Assert.assertTrue(protocolSessionCount <= server.getProtocolSessionsDoneTotal());
+ Assert.assertEquals(protocolSessionCount, server.getProtocolSessionsDoneSuccess());
+ Assert.assertTrue(protocolSessionCount <= client.getProtocolSessionsDoneTotal());
+ Assert.assertEquals(protocolSessionCount, client.getProtocolSessionsDoneSuccess());
+ Assert.assertNotNull(lastCompletedDevice);
+ Assert.assertNotNull(lastCompletedDeviceEIR);
+ Assert.assertFalse(lastCompletedDevice.getConnected());
+ Assert.assertTrue( ( 1 * max_connections_per_session ) > server.getDisconnectCount() );
+ }
}
//
// Client stop
//
- DBTClientTest.stopDiscovery(client, true /* current_exp_discovering_state */, "test"+suffix+"_stopDiscovery");
+ final boolean 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");
+ final boolean 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
- //
- final SMPKeyBin clientKeys = SMPKeyBin.read(DBTConstants.CLIENT_KEY_PATH, lastCompletedDevice, true /* verbose */);
- Assert.assertTrue(clientKeys.isValid());
- final BTSecurityLevel clientKeysSecLevel = clientKeys.getSecLevel();
- Assert.assertEquals(secLevelClient, clientKeysSecLevel);
- {
- if( ExpectedPairing.PREPAIRED == clientExpPairing && BTSecurityLevel.NONE.value < secLevelClient.value ) {
- // Using encryption: pre-paired
- Assert.assertEquals(PairingMode.PRE_PAIRED, lastCompletedDevicePairingMode);
- Assert.assertEquals(BTSecurityLevel.ENC_ONLY, lastCompletedDeviceSecurityLevel); // pre-paired fixed level, no auth
- } else if( ExpectedPairing.NEW_PAIRING == clientExpPairing && BTSecurityLevel.NONE.value < secLevelClient.value ) {
- // Using encryption: Newly paired
- Assert.assertNotEquals(PairingMode.PRE_PAIRED, lastCompletedDevicePairingMode);
- Assert.assertTrue("PairingMode client "+lastCompletedDevicePairingMode+" not > NONE", PairingMode.NONE.value < lastCompletedDevicePairingMode.value);
- Assert.assertTrue("SecurityLevel client "+lastCompletedDeviceSecurityLevel+" not >= "+secLevelClient, secLevelClient.value <= lastCompletedDeviceSecurityLevel.value);
- } else if( ExpectedPairing.DONT_CARE == clientExpPairing && BTSecurityLevel.NONE.value < secLevelClient.value ) {
- // Any encryption, any pairing
- Assert.assertTrue("PairingMode client "+lastCompletedDevicePairingMode+" not > NONE", PairingMode.NONE.value < lastCompletedDevicePairingMode.value);
- Assert.assertTrue("SecurityLevel client "+lastCompletedDeviceSecurityLevel+" not >= "+secLevelClient, secLevelClient.value <= lastCompletedDeviceSecurityLevel.value);
- } else {
- // No encryption: No pairing
- Assert.assertEquals(PairingMode.NONE, lastCompletedDevicePairingMode);
- Assert.assertEquals(BTSecurityLevel.NONE, lastCompletedDeviceSecurityLevel);
- }
- }
-
- //
- // Validating EIR
- //
- synchronized( mtx_sync ) {
- BTUtils.println(System.err, "lastCompletedDevice.connectedEIR: "+lastCompletedDeviceEIR.toString());
- Assert.assertNotEquals(0, lastCompletedDeviceEIR.getEIRDataMask().mask);
- Assert.assertTrue( lastCompletedDeviceEIR.isSet(EIRDataTypeSet.DataType.FLAGS) );
- Assert.assertTrue( lastCompletedDeviceEIR.isSet(EIRDataTypeSet.DataType.SERVICE_UUID) );
- Assert.assertTrue( lastCompletedDeviceEIR.isSet(EIRDataTypeSet.DataType.NAME) );
- Assert.assertTrue( lastCompletedDeviceEIR.isSet(EIRDataTypeSet.DataType.CONN_IVAL) );
- Assert.assertEquals(serverName, lastCompletedDeviceEIR.getName());
+ if( expSuccess ) {
+ //
+ // Validating Security Mode
+ //
+ final SMPKeyBin clientKeys = SMPKeyBin.read(DBTConstants.CLIENT_KEY_PATH, lastCompletedDevice, true /* verbose */);
+ Assert.assertTrue(clientKeys.isValid());
+ final BTSecurityLevel clientKeysSecLevel = clientKeys.getSecLevel();
+ Assert.assertEquals(secLevelClient, clientKeysSecLevel);
{
- final EInfoReport eir = lastCompletedDevice.getEIR().clone();
- BTUtils.println(System.err, "lastCompletedDevice.currentEIR: "+eir.toString());
- Assert.assertEquals(0, eir.getEIRDataMask().mask);
- Assert.assertEquals(0, eir.getName().length());
+ if( ExpectedPairing.PREPAIRED == clientExpPairing && BTSecurityLevel.NONE.value < secLevelClient.value ) {
+ // Using encryption: pre-paired
+ Assert.assertEquals(PairingMode.PRE_PAIRED, lastCompletedDevicePairingMode);
+ Assert.assertEquals(BTSecurityLevel.ENC_ONLY, lastCompletedDeviceSecurityLevel); // pre-paired fixed level, no auth
+ } else if( ExpectedPairing.NEW_PAIRING == clientExpPairing && BTSecurityLevel.NONE.value < secLevelClient.value ) {
+ // Using encryption: Newly paired
+ Assert.assertNotEquals(PairingMode.PRE_PAIRED, lastCompletedDevicePairingMode);
+ Assert.assertTrue("PairingMode client "+lastCompletedDevicePairingMode+" not > NONE", PairingMode.NONE.value < lastCompletedDevicePairingMode.value);
+ Assert.assertTrue("SecurityLevel client "+lastCompletedDeviceSecurityLevel+" not >= "+secLevelClient, secLevelClient.value <= lastCompletedDeviceSecurityLevel.value);
+ } else if( ExpectedPairing.DONT_CARE == clientExpPairing && BTSecurityLevel.NONE.value < secLevelClient.value ) {
+ // Any encryption, any pairing
+ Assert.assertTrue("PairingMode client "+lastCompletedDevicePairingMode+" not > NONE", PairingMode.NONE.value < lastCompletedDevicePairingMode.value);
+ Assert.assertTrue("SecurityLevel client "+lastCompletedDeviceSecurityLevel+" not >= "+secLevelClient, secLevelClient.value <= lastCompletedDeviceSecurityLevel.value);
+ } else {
+ // No encryption: No pairing
+ Assert.assertEquals(PairingMode.NONE, lastCompletedDevicePairingMode);
+ Assert.assertEquals(BTSecurityLevel.NONE, lastCompletedDeviceSecurityLevel);
+ }
}
- }
- //
- // Now reuse adapter for client mode -> Start discovery + Stop Discovery
- //
- {
- final BTAdapter adapter = server.getAdapter();
- { // if( false ) {
- adapter.removeAllStatusListener();
+ //
+ // Validating EIR
+ //
+ synchronized( mtx_sync ) {
+ BTUtils.println(System.err, "lastCompletedDevice.connectedEIR: "+lastCompletedDeviceEIR.toString());
+ Assert.assertNotEquals(0, lastCompletedDeviceEIR.getEIRDataMask().mask);
+ Assert.assertTrue( lastCompletedDeviceEIR.isSet(EIRDataTypeSet.DataType.FLAGS) );
+ Assert.assertTrue( lastCompletedDeviceEIR.isSet(EIRDataTypeSet.DataType.SERVICE_UUID) );
+ Assert.assertTrue( lastCompletedDeviceEIR.isSet(EIRDataTypeSet.DataType.NAME) );
+ Assert.assertTrue( lastCompletedDeviceEIR.isSet(EIRDataTypeSet.DataType.CONN_IVAL) );
+ Assert.assertEquals(serverName, lastCompletedDeviceEIR.getName());
+ {
+ final EInfoReport eir = lastCompletedDevice.getEIR().clone();
+ BTUtils.println(System.err, "lastCompletedDevice.currentEIR: "+eir.toString());
+ Assert.assertEquals(0, eir.getEIRDataMask().mask);
+ Assert.assertEquals(0, eir.getName().length());
+ }
}
- DBTEndpoint.startDiscovery(adapter, false /* current_exp_discovering_state */);
+ //
+ // Now reuse adapter for client mode -> Start discovery + Stop Discovery
+ //
+ {
+ final BTAdapter adapter = server.getAdapter();
+ { // if( false ) {
+ adapter.removeAllStatusListener();
+ }
+
+ DBTEndpoint.startDiscovery(adapter, false /* current_exp_discovering_state */);
- DBTEndpoint.stopDiscovery(adapter, true /* current_exp_discovering_state */);
+ DBTEndpoint.stopDiscovery(adapter, true /* current_exp_discovering_state */);
+ }
}
-
final int count = manager.removeChangedAdapterSetListener(myChangedAdapterSetListener);
BTUtils.println(System.err, "****** EOL Removed ChangedAdapterSetCallback " + count);
}
diff --git a/trial/java/trial/org/direct_bt/DBTServer01.java b/trial/java/trial/org/direct_bt/DBTServer01.java
index 2134d55a..1183d8fa 100644
--- a/trial/java/trial/org/direct_bt/DBTServer01.java
+++ b/trial/java/trial/org/direct_bt/DBTServer01.java
@@ -60,9 +60,6 @@ import org.direct_bt.SMPPairingState;
import org.direct_bt.ScanType;
import org.jau.net.EUI48;
-import trial.org.direct_bt.DBTServer00.MyAdapterStatusListener;
-import trial.org.direct_bt.DBTServer00.MyGATTServerListener;
-
/**
* This peripheral BTRole::Slave test participant works with DBTClient00.
*/
@@ -88,21 +85,18 @@ public class DBTServer01 implements DBTServerTest {
private final AtomicInteger servedProtocolSessionsSuccess = new AtomicInteger(0);
private final AtomicInteger servingProtocolSessionsLeft = new AtomicInteger(1);
- public DBTServer01(final String adapterName, final EUI48 useAdapter, final BTMode btMode, final boolean use_SC, final BTSecurityLevel adapterSecurityLevel) {
+ private final boolean do_disconnect;
+
+ public DBTServer01(final String adapterName, final EUI48 useAdapter, final BTMode btMode, final boolean use_SC, final BTSecurityLevel adapterSecurityLevel, final boolean 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 );
}
- public DBTServer01(final String adapterName, final EUI48 useAdapter, final BTSecurityLevel adapterSecurityLevel) {
- this(adapterName, useAdapter, BTMode.DUAL, true /* SC */, adapterSecurityLevel);
- }
- public DBTServer01(final String adapterName, final BTSecurityLevel adapterSecurityLevel) {
- this(adapterName, EUI48.ALL_DEVICE, BTMode.DUAL, true /* SC */, adapterSecurityLevel);
- }
@Override
public String getName() { return adapterName; }
@@ -470,17 +464,17 @@ public class DBTServer01 implements DBTServerTest {
}
}
- boolean onceDisconnect = true;
-
private void disconnectDevice() {
+ // sleep range: 100 - 1500 ms
+ final int sleep_min = 100;
+ final int sleep_max = 1500;
+ final int sleep_dur = (int) ( Math.random() * ( sleep_max - sleep_min + 1 ) + sleep_min );
try {
- Thread.sleep(300);
+ Thread.sleep(sleep_dur); // wait a little (FIXME: Fast restart of advertising error)
} catch (final InterruptedException e) { }
final BTDevice connectedDevice_ = getDevice();
- BTUtils.fprintf_td(System.err, "****** Server GATT::disconnectDevice(sessions [%d ok / %d total], left %d): client %s\n",
- servedProtocolSessionsSuccess.get(), servedProtocolSessionsTotal.get(), servingProtocolSessionsLeft.get(),
- connectedDevice_.toString());
+ BTUtils.fprintf_td(System.err, "****** Server i470 disconnectDevice(delayed %d ms): client %s\n", sleep_dur, connectedDevice_.toString());
connectedDevice_.disconnect();
}
@@ -533,8 +527,7 @@ public class DBTServer01 implements DBTServerTest {
BTUtils.fprintf_td(System.err, "****** Server GATT::mtuChanged(match %b, served %d, left %d): %d -> %d, %s\n",
match, servedProtocolSessionsTotal.get(), servingProtocolSessionsLeft.get(),
match ? usedMTU_old : 0, mtu, device.toString());
- if( onceDisconnect ) {
- onceDisconnect = false;
+ if( do_disconnect ) {
executeOffThread( () -> { disconnectDevice(); }, "GattServer-DisconnectDevice", true /* detach */);
}
}
diff --git a/trial/java/trial/org/direct_bt/TestDBTProvokeClientServer_i470.java b/trial/java/trial/org/direct_bt/TestDBTProvokeClientServer_i470.java
index cb96610c..b2e8e1c8 100644
--- a/trial/java/trial/org/direct_bt/TestDBTProvokeClientServer_i470.java
+++ b/trial/java/trial/org/direct_bt/TestDBTProvokeClientServer_i470.java
@@ -44,21 +44,50 @@ import org.junit.runners.MethodSorters;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestDBTProvokeClientServer_i470 extends DBTClientServer1x {
- @Test(timeout = 20000)
- public final void test_i470()
+ @Test(timeout = 10000)
+ public final void test_i470_a()
{
final boolean serverSC = true;
- final String suffix = "i470";
- final int protocolSessionCount = 2;
+ final String suffix = "i470_a";
+ final int protocolSessionCount = 10;
+ final int max_connections_per_session = 200;
+ final boolean expSuccess = false;
final boolean server_client_order = true;
final ExpectedPairing serverExpPairing = ExpectedPairing.DONT_CARE;
final ExpectedPairing clientExpPairing = ExpectedPairing.DONT_CARE;
+ final boolean client_do_disconnect = true;
+ final boolean server_do_disconnect = false;
- // final DBTServerTest server = new DBTServer01("S-"+suffix, EUI48.ALL_DEVICE, BTMode.DUAL, serverSC, BTSecurityLevel.ENC_ONLY);
- final DBTServerTest server = new DBTServer00("S-"+suffix, EUI48.ALL_DEVICE, BTMode.DUAL, serverSC, BTSecurityLevel.ENC_ONLY);
- final DBTClientTest client = new DBTClient01("C-"+suffix, EUI48.ALL_DEVICE, BTMode.DUAL);
+ final DBTServerTest server = new DBTServer01("S-"+suffix, EUI48.ALL_DEVICE, BTMode.DUAL, serverSC, BTSecurityLevel.ENC_ONLY, server_do_disconnect);
+ final DBTClientTest client = new DBTClient01("C-"+suffix, EUI48.ALL_DEVICE, BTMode.DUAL, client_do_disconnect);
- test8x_fullCycle(20000, suffix, protocolSessionCount, server_client_order,
+ test8x_fullCycle(10000, suffix,
+ protocolSessionCount, max_connections_per_session, expSuccess,
+ server_client_order,
+ server, BTSecurityLevel.ENC_ONLY, serverExpPairing,
+ client, BTSecurityLevel.ENC_ONLY, clientExpPairing);
+ }
+
+ @Test(timeout = 10000)
+ public final void test_i470_b()
+ {
+ final boolean serverSC = true;
+ final String suffix = "i470_b";
+ final int protocolSessionCount = 10;
+ final int max_connections_per_session = 200;
+ final boolean expSuccess = false;
+ final boolean server_client_order = true;
+ final ExpectedPairing serverExpPairing = ExpectedPairing.DONT_CARE;
+ final ExpectedPairing clientExpPairing = ExpectedPairing.DONT_CARE;
+ final boolean client_do_disconnect = false;
+ final boolean server_do_disconnect = true;
+
+ final DBTServerTest server = new DBTServer01("S-"+suffix, EUI48.ALL_DEVICE, BTMode.DUAL, serverSC, BTSecurityLevel.ENC_ONLY, server_do_disconnect);
+ final DBTClientTest client = new DBTClient01("C-"+suffix, EUI48.ALL_DEVICE, BTMode.DUAL, client_do_disconnect);
+
+ test8x_fullCycle(10000, suffix,
+ protocolSessionCount, max_connections_per_session, expSuccess,
+ server_client_order,
server, BTSecurityLevel.ENC_ONLY, serverExpPairing,
client, BTSecurityLevel.ENC_ONLY, clientExpPairing);
}