aboutsummaryrefslogtreecommitdiff
path: root/src/HciSocket.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/HciSocket.cpp')
-rw-r--r--src/HciSocket.cpp62
1 files changed, 54 insertions, 8 deletions
diff --git a/src/HciSocket.cpp b/src/HciSocket.cpp
index 214ef85..c3cadc3 100644
--- a/src/HciSocket.cpp
+++ b/src/HciSocket.cpp
@@ -92,7 +92,7 @@ bool HciSocket::connect()
return false;
}
- Logger::debug(SSTR << "Connected to HCI control socket (file descriptor = " << fdSocket << ")");
+ Logger::debug(SSTR << "Connected to HCI control socket (fd = " << fdSocket << ")");
return true;
}
@@ -108,8 +108,15 @@ void HciSocket::disconnect()
{
if (isConnected())
{
- close(fdSocket);
+ Logger::debug("HciSocket disconnecting");
+
+ if (close(fdSocket) != 0)
+ {
+ logErrno("close(fdSocket)");
+ }
+
fdSocket = -1;
+ Logger::trace("HciSocket closed");
}
}
@@ -124,8 +131,11 @@ bool HciSocket::read(std::vector<uint8_t> &response) const
// Fill our response with empty data
response.resize(kResponseMaxSize, 0);
- // Ensure we have blocking I/O
- fcntl(fdSocket, F_SETFL, 0);
+ // Wait for data or a cancellation
+ if (!waitForDataOrShutdown())
+ {
+ return false;
+ }
// Block until we receive data, a disconnect, or a signal
ssize_t bytesRead = ::recv(fdSocket, &response[0], kResponseMaxSize, MSG_WAITALL);
@@ -146,7 +156,7 @@ bool HciSocket::read(std::vector<uint8_t> &response) const
}
else if (bytesRead == 0)
{
- Logger::error(" + Peer closed the socket");
+ Logger::error("Peer closed the socket");
response.resize(0);
return false;
}
@@ -155,7 +165,7 @@ bool HciSocket::read(std::vector<uint8_t> &response) const
response.resize(bytesRead);
std::string dump = "";
- dump += "> Read " + std::to_string(response.size()) + " bytes\n";
+ dump += " > Read " + std::to_string(response.size()) + " bytes\n";
dump += Utils::hex(response.data(), response.size());
Logger::debug(dump);
@@ -176,7 +186,7 @@ bool HciSocket::write(std::vector<uint8_t> buffer) const
bool HciSocket::write(const uint8_t *pBuffer, size_t count) const
{
std::string dump = "";
- dump += "> Writing " + std::to_string(count) + " bytes\n";
+ dump += " > Writing " + std::to_string(count) + " bytes\n";
dump += Utils::hex(pBuffer, count);
Logger::debug(dump);
@@ -191,10 +201,46 @@ bool HciSocket::write(const uint8_t *pBuffer, size_t count) const
return true;
}
+// Wait for data to arrive, or for a shutdown event
+//
+// Returns true if data is available, false if we are shutting down
+bool HciSocket::waitForDataOrShutdown() const
+{
+ while(ggkIsServerRunning())
+ {
+ fd_set rfds;
+ FD_ZERO(&rfds);
+ FD_SET(fdSocket, &rfds);
+
+ struct timeval tv;
+ tv.tv_sec = 0;
+ tv.tv_usec = kDataWaitTimeMS * 1000;
+
+ int retval = select(fdSocket+1, &rfds, NULL, NULL, &tv);
+
+ // Do we have data?
+ if (retval > 0) { return true; }
+
+ // We have an error
+ if (retval < 0) { return false; }
+
+ // No data; keep waiting
+ continue;
+ }
+
+ return false;
+}
+
// Utilitarian function for logging errors for the given operation
void HciSocket::logErrno(const char *pOperation) const
{
- Logger::error(SSTR << "" << pOperation << " on Bluetooth management socket error (" << errno << "): " << strerror(errno));
+ std::string errorDetail(strerror(errno));
+ if (errno == EAGAIN)
+ {
+ errorDetail += " or not enough permission for this operation";
+ }
+
+ Logger::error(SSTR << "Error on Bluetooth management socket during " << pOperation << " operation. Error code " << errno << ": " << errorDetail);
}
}; // namespace ggk