aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno Randolf <br1@einfach.org>2019-01-05 18:34:13 +0000
committerBruno Randolf <br1@einfach.org>2019-01-05 18:36:39 +0000
commit30436c84b2c35982c41c33a7adfb0307884f5ee9 (patch)
tree540f790b12ca77bac7099d0885148e11fcb54ab4
parentImproved handling of connection counts dealing with latent disconnects on sta... (diff)
downloadgobbledegook-30436c84b2c35982c41c33a7adfb0307884f5ee9.tar.gz
gobbledegook-30436c84b2c35982c41c33a7adfb0307884f5ee9.tar.bz2
gobbledegook-30436c84b2c35982c41c33a7adfb0307884f5ee9.zip
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 <br1@einfach.org>
-rw-r--r--src/Init.cpp12
-rw-r--r--src/Mgmt.cpp31
-rw-r--r--src/Mgmt.h9
-rw-r--r--src/Server.cpp1
-rw-r--r--src/Server.h6
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;