53 static constexpr const fraction_i64 timeout_preempt_diff = 500_ms;
57 PairingMode lastCompletedDevicePairingMode = PairingMode::NONE;
58 BTSecurityLevel lastCompletedDeviceSecurityLevel = BTSecurityLevel::NONE;
60 int client_power_down_count = 0;
61 int client_power_up_count = 0;
62 bool client_reset_at_ready =
false;
63 bool server_reset_at_ready =
false;
64 bool client_reset_test =
false;
65 bool server_reset_test =
false;
71 void test8x_fullCycle(
const std::string& suffix,
const int protocolSessionCount,
const bool server_client_order,
75 std::shared_ptr<DBTServer01> server = std::make_shared<DBTServer01>(
"S-"+suffix, EUI48::ALL_DEVICE, BTMode::DUAL,
76 serverSC, secLevelServer);
77 std::shared_ptr<DBTClient01> client = std::make_shared<DBTClient01>(
"C-"+suffix, EUI48::ALL_DEVICE, BTMode::DUAL);
79 server->setProtocolSessionsLeft( protocolSessionCount );
81 client->setProtocolSessionsLeft( protocolSessionCount );
82 client->setDisconnectDevice(
true );
83 client->setRemoveDevice(
false );
84 client->setDiscoveryPolicy( DiscoveryPolicy::PAUSE_CONNECTED_UNTIL_DISCONNECTED );
89 server, secLevelServer, serverExpPairing,
90 client, secLevelClient, clientExpPairing);
94 const int max_connections_per_session,
const bool expSuccess,
95 const bool server_client_order,
100 (void)serverExpPairing;
102 const int protocolSessionCount =
std::min(server->getProtocolSessionsLeft(), client->getProtocolSessionsLeft());
111 jau::fprintf_td(stderr,
"%u: %s\n", i, adapters[i]->toString().c_str());
113 REQUIRE( adapters.
size() >= 2 );
117 server_client_order ? std::vector<DBTEndpointRef>{ server, client } : std::vector<DBTEndpointRef>{ client, server } );
119 const std::string serverName = server->getName();
127 const std::lock_guard<std::mutex> lock(mtx_sync);
128 lastCompletedDevice =
nullptr;
129 lastCompletedDevicePairingMode = PairingMode::NONE;
130 lastCompletedDeviceSecurityLevel = BTSecurityLevel::NONE;
131 lastCompletedDeviceEIR.
clear();
140 const AdapterSetting changedmask,
const uint64_t timestamp)
override {
141 const bool initialSetting = AdapterSetting::NONE == oldmask;
143 const std::lock_guard<std::mutex> lock(parent.mtx_sync);
145 ++parent.client_power_up_count;
147 ++parent.client_power_down_count;
154 void deviceReady(
const BTDeviceRef& device,
const uint64_t timestamp)
override {
156 const std::lock_guard<std::mutex> lock(parent.mtx_sync);
157 parent.lastCompletedDevice = device;
158 parent.lastCompletedDevicePairingMode = device->getPairingMode();
159 parent.lastCompletedDeviceSecurityLevel = device->getConnSecurityLevel();
160 parent.lastCompletedDeviceEIR = *device->getEIR();
161 fprintf_td(stderr,
"XXXXXX Client Ready: %s\n", device->toString(
true).c_str());
162 if( parent.client_reset_at_ready ) {
163 parent.client_reset_at_ready =
false;
164 fprintf_td(stderr,
"XXXXXX Client Reset.0: %s\n", device->toString(
true).c_str());
170 std::string toString()
const noexcept override {
return "DBTClientServer1x::Client"; }
172 std::shared_ptr<AdapterStatusListener> clientAdapterStatusListener = std::make_shared<MyAdapterStatusListener>(*
this);
173 REQUIRE(
true == client->getAdapter()->addStatusListener(clientAdapterStatusListener) );
191 bool timeout =
false;
192 bool max_connections_hit =
false;
195 const std::lock_guard<std::mutex> lock(mtx_sync);
196 done = ! ( protocolSessionCount > server->getProtocolSessionsDoneSuccess() ||
197 protocolSessionCount > client->getProtocolSessionsDoneSuccess() ||
198 nullptr == lastCompletedDevice ||
199 lastCompletedDevice->getConnected() );
201 max_connections_hit = ( protocolSessionCount * max_connections_per_session ) <= server->getDisconnectCount();
204 ( 0_s < timeout_value && timeout_value <=
test_duration + timeout_preempt_diff );
205 if( !done && !max_connections_hit && !timeout ) {
208 }
while( !done && !max_connections_hit && !timeout );
212 fprintf_td(stderr,
"****** Test Stats: duration %" PRIi64
" ms, timeout[hit %d, value %s sec], max_connections hit %d\n",
214 fprintf_td(stderr,
" Server ProtocolSessions[success %d/%d total, requested %d], disconnects %d of %d max\n",
215 server->getProtocolSessionsDoneSuccess(), server->getProtocolSessionsDoneTotal(), protocolSessionCount,
216 server->getDisconnectCount(), ( protocolSessionCount * max_connections_per_session ));
217 fprintf_td(stderr,
" Client ProtocolSessions[success %d/%d total, requested %d], disconnects %d of %d max, power[down %d, up %d]\n",
218 client->getProtocolSessionsDoneSuccess(), client->getProtocolSessionsDoneTotal(), protocolSessionCount,
219 client->getDisconnectCount(), ( protocolSessionCount * max_connections_per_session ),
220 client_power_down_count, client_power_up_count);
224 REQUIRE(
false == max_connections_hit );
225 REQUIRE(
false == timeout );
227 const std::lock_guard<std::mutex> lock(mtx_sync);
228 REQUIRE( protocolSessionCount <= server->getProtocolSessionsDoneTotal() );
229 REQUIRE( protocolSessionCount == server->getProtocolSessionsDoneSuccess() );
230 REQUIRE( protocolSessionCount <= client->getProtocolSessionsDoneTotal() );
231 REQUIRE( protocolSessionCount == client->getProtocolSessionsDoneSuccess() );
232 REQUIRE(
nullptr != lastCompletedDevice );
233 REQUIRE( EIRDataType::NONE != lastCompletedDeviceEIR.
getEIRDataMask() );
234 REQUIRE(
false == lastCompletedDevice->getConnected() );
235 REQUIRE( ( protocolSessionCount * max_connections_per_session ) > server->getDisconnectCount() );
236 if( client_reset_test ) {
237 REQUIRE( 1 == client_power_down_count );
238 REQUIRE( 1 == client_power_up_count );
240 REQUIRE( 0 == client_power_down_count );
241 REQUIRE( 0 == client_power_up_count );
249 const bool current_exp_discovering_state = expSuccess ? true : client->getAdapter()->isDiscovering();
251 client->close(
"test"+suffix+
"_close");
263 REQUIRE(
true == clientKeys.
isValid() );
265 REQUIRE( secLevelClient == clientKeysSecLevel);
269 REQUIRE( PairingMode::PRE_PAIRED == lastCompletedDevicePairingMode );
270 REQUIRE( BTSecurityLevel::ENC_ONLY == lastCompletedDeviceSecurityLevel );
273 REQUIRE( PairingMode::PRE_PAIRED != lastCompletedDevicePairingMode );
274 REQUIRE_MSG(
"PairingMode client "+
to_string(lastCompletedDevicePairingMode)+
" not > NONE", PairingMode::NONE < lastCompletedDevicePairingMode );
275 REQUIRE_MSG(
"SecurityLevel client "+
to_string(lastCompletedDeviceSecurityLevel)+
" not >= "+
to_string(secLevelClient), secLevelClient <= lastCompletedDeviceSecurityLevel );
278 REQUIRE_MSG(
"PairingMode client "+
to_string(lastCompletedDevicePairingMode)+
" not > NONE", PairingMode::NONE < lastCompletedDevicePairingMode );
279 REQUIRE_MSG(
"SecurityLevel client "+
to_string(lastCompletedDeviceSecurityLevel)+
" not >= "+
to_string(secLevelClient), secLevelClient <= lastCompletedDeviceSecurityLevel );
282 REQUIRE( PairingMode::NONE == lastCompletedDevicePairingMode );
283 REQUIRE( BTSecurityLevel::NONE == lastCompletedDeviceSecurityLevel );
291 const std::lock_guard<std::mutex> lock(mtx_sync);
292 fprintf_td(stderr,
"lastCompletedDevice.connectedEIR: %s\n", lastCompletedDeviceEIR.
toString().c_str());
293 REQUIRE( EIRDataType::NONE != lastCompletedDeviceEIR.
getEIRDataMask() );
294 REQUIRE(
true == lastCompletedDeviceEIR.
isSet(EIRDataType::FLAGS) );
295 REQUIRE(
true == lastCompletedDeviceEIR.
isSet(EIRDataType::SERVICE_UUID) );
296 REQUIRE(
true == lastCompletedDeviceEIR.
isSet(EIRDataType::NAME) );
297 REQUIRE(
true == lastCompletedDeviceEIR.
isSet(EIRDataType::CONN_IVAL) );
298 REQUIRE( serverName == lastCompletedDeviceEIR.
getName() );
300 const EInfoReport eir = *lastCompletedDevice->getEIR();
303 REQUIRE( 0 == eir.
getName().length());
313 adapter->removeAllStatusListener();
322 fprintf_td(stderr,
"****** EOL Removed ChangedAdapterSetCallback %zu\n", (
size_t)count);
#define REQUIRE_MSG(MSG,...)
bool is_timedout() const noexcept
jau::fraction_i64 get_timeout_value() const
static BaseDBTClientServer & get(const bool btmanager_hold_and_close=true)
Testing a full Bluetooth server and client lifecycle of operations, requiring two BT adapter:
void test8x_fullCycle(const std::string &suffix, const int max_connections_per_session, const bool expSuccess, const bool server_client_order, const std::shared_ptr< DBTServerTest > &server, const BTSecurityLevel secLevelServer, const ExpectedPairing serverExpPairing, const std::shared_ptr< DBTClientTest > &client, const BTSecurityLevel secLevelClient, const ExpectedPairing clientExpPairing)
void set_client_reset_at_ready(const bool v) noexcept
void test8x_fullCycle(const std::string &suffix, const int protocolSessionCount, const bool server_client_order, const bool serverSC, const BTSecurityLevel secLevelServer, const ExpectedPairing serverExpPairing, const BTSecurityLevel secLevelClient, const ExpectedPairing clientExpPairing)
void set_server_reset_at_ready(const bool v) noexcept
virtual HCIStatusCode startDiscovery(const std::string &msg)=0
virtual HCIStatusCode stopDiscovery(const std::string &msg)=0
static constexpr const int max_connections_per_session
static constexpr const char CLIENT_KEY_PATH[]
C++20 we could use constexpr std::string
static void checkInitializedState(const DBTEndpointRef &endp)
static void stopDiscovery(const BTAdapterRef &adapter, const bool current_exp_discovering_state)
static ChangedAdapterSetCallback initChangedAdapterSetListener(const BTManagerRef &manager, std::vector< DBTEndpointRef > endpts)
static void startDiscovery(const BTAdapterRef &adapter, const bool current_exp_discovering_state)
virtual HCIStatusCode startAdvertising(const std::string &msg)=0
static void stop(const DBTServerTestRef &server, const std::string &msg)
BTAdapter status listener for remote BTDevice discovery events: Added, updated and removed; as well a...
BTAdapter represents one local Bluetooth Controller.
Collection of 'Extended Advertising Data' (EAD), 'Advertising Data' (AD) or 'Extended Inquiry Respons...
std::string toString(const bool includeServices=true) const noexcept
bool isSet(EIRDataType bit) const noexcept
EIRDataType getEIRDataMask() const noexcept
void clear() noexcept
Reset all data fields.
std::string const & getName() const noexcept
Storage for SMP keys including required connection parameter per local adapter and remote device.
constexpr bool isValid() const noexcept
Returns true if.
constexpr BTSecurityLevel getSecLevel() const noexcept
Implementation of a dynamic linear array storage, aka vector.
constexpr size_type size() const noexcept
Like std::vector::size().
std::string to_string(const bool show_double=false) const noexcept
Returns a string representation of this fraction.
Class template jau::function is a general-purpose static-polymorphic function wrapper.
static BaseDBTClientServer & base_test_framework
static void myChangedAdapterSetFunc(const bool added, std::shared_ptr< BTAdapter > &adapter)
std::string to_string(const alphabet &v) noexcept
Entry * getOrCreate(const std::string &addrOrNameSub) noexcept
Determines whether the given addrOrNameSub is a EUI48Sub or just a name and retrieves an entry.
std::shared_ptr< BTDevice > BTDeviceRef
std::string to_string(const DiscoveryPolicy v) noexcept
std::shared_ptr< BTAdapter > BTAdapterRef
Entry * get(const EUI48 &addr, const std::string &name, AddressNameEntryMatchFunc m) noexcept
Returns a matching BTSecurityRegistry::Entry with the given addr and/or name.
AdapterSetting
Adapter Setting Bits.
constexpr bool isAdapterSettingBitSet(const AdapterSetting mask, const AdapterSetting bit) noexcept
BTSecurityLevel
Bluetooth Security Level.
PairingMode
Bluetooth secure pairing mode.
HCIStatusCode
BT Core Spec v5.2: Vol 1, Part F Controller Error Codes: 1.3 List of Error Codes.
bool to_fraction_i64(fraction_i64 &result, const std::string &value, const fraction_i64 &min_allowed, const fraction_i64 &max_allowed) noexcept
Stores the fraction_i64 value of the given string value in format <num>/<denom>, which may contain wh...
fraction_timespec getMonotonicTime() noexcept
Returns current monotonic time since Unix Epoch 00:00:00 UTC on 1970-01-01.
constexpr T min(const T x, const T y) noexcept
Returns the minimum of two integrals (w/ branching) in O(1)
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
void addToWaitForDevices(const std::string &addrOrNameSub) noexcept
int fprintf_td(const uint64_t elapsed_ms, FILE *stream, const char *format,...) noexcept
Convenient fprintf() invocation, prepending the given elapsed_ms timestamp.
bool sleep_for(const fraction_timespec &relative_time, const bool monotonic=true, const bool ignore_irq=true) noexcept
sleep_for causes the current thread to block until a specific amount of time has passed.
BTSecurityLevel sec_level
Timespec structure using int64_t for its components in analogy to struct timespec_t on 64-bit platfor...
static void test_duration(const fraction< int_type > &a, const std::chrono::duration< Rep, Period > &dur_ref, const Rep exp_count)