From 30436c84b2c35982c41c33a7adfb0307884f5ee9 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Sat, 5 Jan 2019 18:34:13 +0000 Subject: Add setting of discoverable mode This is necessary for the advertisements to be in "LE General Discoverable Mode" which makes them visible (especially to other Linux boxes). Signed-off-by: Bruno Randolf --- src/Init.cpp | 12 ++++++++++-- src/Mgmt.cpp | 31 ++++++++++++++++++++++++++++++- src/Mgmt.h | 9 ++++++++- src/Server.cpp | 1 + src/Server.h | 6 ++++++ 5 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/Init.cpp b/src/Init.cpp index 915209f..c3784df 100644 --- a/src/Init.cpp +++ b/src/Init.cpp @@ -695,11 +695,12 @@ void configureAdapter() bool scFlag = info.currentSettings.isSet(HciAdapter::EHciSecureConnections) == TheServer->getEnableSecureConnection(); bool bnFlag = info.currentSettings.isSet(HciAdapter::EHciBondable) == TheServer->getEnableBondable(); bool cnFlag = info.currentSettings.isSet(HciAdapter::EHciConnectable) == TheServer->getEnableConnectable(); + bool diFlag = info.currentSettings.isSet(HciAdapter::EHciDiscoverable) == TheServer->getEnableDiscoverable(); bool adFlag = info.currentSettings.isSet(HciAdapter::EHciAdvertising) == TheServer->getEnableAdvertising(); bool anFlag = (advertisingName.length() == 0 || advertisingName == info.name) && (advertisingShortName.length() == 0 || advertisingShortName == info.shortName); // If everything is setup already, we're done - if (!pwFlag || !leFlag || !brFlag || !scFlag || !bnFlag || !cnFlag || !adFlag || !anFlag) + if (!pwFlag || !leFlag || !brFlag || !scFlag || !bnFlag || !cnFlag || !diFlag || !adFlag || !anFlag) { // We need it off to start with if (pwFlag) @@ -745,6 +746,13 @@ void configureAdapter() if (!mgmt.setConnectable(TheServer->getEnableConnectable())) { setRetry(); return; } } + // Change the Discoverable state? + if (!diFlag) + { + Logger::debug(SSTR << (TheServer->getEnableDiscoverable() ? "Enabling":"Disabling") << " Discoverable"); + if (!mgmt.setDiscoverable(TheServer->getEnableDiscoverable() ? 1 : 0, 0)) { setRetry(); return; } + } + // Change the Advertising state? if (!adFlag) { @@ -1196,4 +1204,4 @@ void runServerThread() uninit(); } -}; // namespace ggk \ No newline at end of file +}; // namespace ggk diff --git a/src/Mgmt.cpp b/src/Mgmt.cpp index e61653e..2b80748 100644 --- a/src/Mgmt.cpp +++ b/src/Mgmt.cpp @@ -90,6 +90,35 @@ bool Mgmt::setName(std::string name, std::string shortName) return true; } +// Sets discoverable mode +// 0x00 disables discoverable +// 0x01 enables general discoverable +// 0x02 enables limited discoverable +// Timeout is the time in seconds. For 0x02, the timeout value is required. +bool Mgmt::setDiscoverable(uint8_t disc, uint16_t timeout) +{ + struct SRequest : HciAdapter::HciHeader + { + uint8_t disc; + uint16_t timeout; + } __attribute__((packed)); + + SRequest request; + request.code = Mgmt::ESetDiscoverableCommand; + request.controllerId = controllerIndex; + request.dataSize = sizeof(SRequest) - sizeof(HciAdapter::HciHeader); + request.disc = disc; + request.timeout = timeout; + + if (!HciAdapter::getInstance().sendCommand(request)) + { + Logger::warn(SSTR << " + Failed to set discoverable"); + return false; + } + + return true; +} + // Set a setting state to 'newState' // // Many settings are set the same way, this is just a convenience routine to handle them all @@ -202,4 +231,4 @@ std::string Mgmt::truncateShortName(const std::string &name) return name.substr(0, kMaxAdvertisingShortNameLength); } -}; // namespace ggk \ No newline at end of file +}; // namespace ggk diff --git a/src/Mgmt.h b/src/Mgmt.h index 196eb1a..1f746b5 100644 --- a/src/Mgmt.h +++ b/src/Mgmt.h @@ -190,6 +190,13 @@ struct Mgmt // Returns true on success, otherwise false bool setName(std::string name, std::string shortName); + // Sets discoverable mode + // 0x00 disables discoverable + // 0x01 enables general discoverable + // 0x02 enables limited discoverable + // Timeout is the time in seconds. For 0x02, the timeout value is required. + bool setDiscoverable(uint8_t disc, uint16_t timeout); + // Set a setting state to 'newState' // // Many settings are set the same way, this is just a convenience routine to handle them all @@ -258,4 +265,4 @@ private: static const uint16_t kDefaultControllerIndex = 0; }; -}; // namespace ggk \ No newline at end of file +}; // namespace ggk diff --git a/src/Server.cpp b/src/Server.cpp index 87b3279..47a74da 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -243,6 +243,7 @@ Server::Server(const std::string &serviceName, const std::string &advertisingNam enableBREDR = false; enableSecureConnection = false; enableConnectable = true; + enableDiscoverable = true; enableAdvertising = true; enableBondable = false; diff --git a/src/Server.h b/src/Server.h index d6154dc..8a5031e 100644 --- a/src/Server.h +++ b/src/Server.h @@ -84,6 +84,9 @@ struct Server // Returns the requested setting the connectable state (true = enabled, false = disabled) bool getEnableConnectable() const { return enableConnectable; } + // Returns the requested setting the discoverable state (true = enabled, false = disabled) + bool getEnableDiscoverable() const { return enableDiscoverable; } + // Returns the requested setting the LE advertising state (true = enabled, false = disabled) bool getEnableAdvertising() const { return enableAdvertising; } @@ -201,6 +204,9 @@ private: // Connectable requested state bool enableConnectable; + // Discoverable requested state + bool enableDiscoverable; + // LE advertising requested state bool enableAdvertising; -- cgit v1.2.3