summaryrefslogtreecommitdiffstats
path: root/src/direct_bt/L2CAPComm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/direct_bt/L2CAPComm.cpp')
-rw-r--r--src/direct_bt/L2CAPComm.cpp38
1 files changed, 28 insertions, 10 deletions
diff --git a/src/direct_bt/L2CAPComm.cpp b/src/direct_bt/L2CAPComm.cpp
index 7d05c0f3..af81807a 100644
--- a/src/direct_bt/L2CAPComm.cpp
+++ b/src/direct_bt/L2CAPComm.cpp
@@ -32,6 +32,9 @@
#include <algorithm>
+// #define PERF_PRINT_ON 1
+#include <dbt_debug.hpp>
+
#include "BTIoctl.hpp"
#include "HCIIoctl.hpp"
#include "L2CAPIoctl.hpp"
@@ -47,8 +50,6 @@ extern "C" {
#include <signal.h>
}
-#include <dbt_debug.hpp>
-
using namespace direct_bt;
L2CAPEnv::L2CAPEnv() noexcept
@@ -108,7 +109,7 @@ L2CAPComm::L2CAPComm(std::shared_ptr<DBTDevice> device, const uint16_t psm, cons
: env(L2CAPEnv::get()),
device(device), deviceString(device->getAddressString()), psm(psm), cid(cid),
socket_descriptor( l2cap_open_dev(device->getAdapter().getAddress(), psm, cid, true /* pubaddrAdptr */) ),
- is_connected(true), has_ioerror(false), interrupt_flag(false), tid_connect(0)
+ is_connected(true), has_ioerror(false), interrupt_flag(false), tid_connect(0), tid_read(0)
{
/** BT Core Spec v5.2: Vol 3, Part A: L2CAP_CONNECTION_REQ */
sockaddr_l2 req;
@@ -179,17 +180,29 @@ bool L2CAPComm::disconnect() noexcept {
has_ioerror = false;
DBG_PRINT("L2CAPComm::disconnect: Start: %s, dd %d, %s, psm %u, cid %u, pubDevice %d",
getStateString().c_str(), socket_descriptor.load(), deviceString.c_str(), psm, cid, true);
- interrupt_flag = true;
+ PERF_TS_T0();
- // interrupt L2CAP ::connect(..), avoiding prolonged hang
- pthread_t _tid_connect = tid_connect;
- tid_connect = 0;
- if( 0 != _tid_connect ) {
+ interrupt_flag = true;
+ {
pthread_t tid_self = pthread_self();
- if( tid_self != _tid_connect ) {
+ pthread_t _tid_connect = tid_connect;
+ pthread_t _tid_read = tid_read;
+ tid_read = 0;
+ tid_connect = 0;
+
+ // interrupt read(..) and , avoiding prolonged hang
+ if( 0 != _tid_read && tid_self != _tid_read ) {
+ int kerr;
+ if( 0 != ( kerr = pthread_kill(_tid_read, SIGALRM) ) ) {
+ ERR_PRINT("L2CAPComm::disconnect: pthread_kill read %p FAILED: %d", (void*)_tid_read, kerr);
+ }
+ }
+ // interrupt connect(..) and , avoiding prolonged hang
+ interrupt_flag = true;
+ if( 0 != _tid_connect && _tid_read != _tid_connect && tid_self != _tid_connect ) {
int kerr;
if( 0 != ( kerr = pthread_kill(_tid_connect, SIGALRM) ) ) {
- ERR_PRINT("L2CAP::disconnect: pthread_kill %p FAILED: %d", (void*)_tid_connect, kerr);
+ ERR_PRINT("L2CAPComm::disconnect: pthread_kill connect %p FAILED: %d", (void*)_tid_connect, kerr);
}
}
}
@@ -197,6 +210,7 @@ bool L2CAPComm::disconnect() noexcept {
l2cap_close_dev(socket_descriptor);
socket_descriptor = -1;
interrupt_flag = false;
+ PERF_TS_TD("L2CAPComm::disconnect");
DBG_PRINT("L2CAPComm::disconnect: End: dd %d", socket_descriptor.load());
return true;
}
@@ -206,6 +220,8 @@ int L2CAPComm::read(uint8_t* buffer, const int capacity) {
int len = 0;
int err_res = 0;
+ tid_read = pthread_self(); // temporary safe tid to allow interruption
+
if( 0 > socket_descriptor || 0 > capacity ) {
err_res = -1; // invalid socket_descriptor or capacity
goto errout;
@@ -244,9 +260,11 @@ int L2CAPComm::read(uint8_t* buffer, const int capacity) {
}
done:
+ tid_read = 0;
return len;
errout:
+ tid_read = 0;
if( errno != ETIMEDOUT ) {
has_ioerror = true;
if( is_connected ) {