34 #include <type_traits>
44 #include <sys/param.h>
46 #include <sys/types.h>
47 #include <sys/ioctl.h>
48 #include <sys/socket.h>
54 int HCIComm::hci_open_dev(
const uint16_t dev_id,
const uint16_t channel) noexcept
56 static_assert(
sizeof(
struct sockaddr) >
sizeof(sockaddr_hci),
"Requirement sizeof(struct sockaddr) > sizeof(sockaddr_hci)" );
58 sockaddr_hci * ptr_hci_addr = (sockaddr_hci*)&addr_holder;
70 fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
72 ERR_PRINT(
"HCIComm::hci_open_dev: socket failed");
77 bzero(&addr_holder,
sizeof(addr_holder));
78 ptr_hci_addr->hci_family = AF_BLUETOOTH;
79 ptr_hci_addr->hci_dev = dev_id;
80 ptr_hci_addr->hci_channel = channel;
81 if (bind(fd, &addr_holder,
sizeof(sockaddr_hci)) < 0) {
96 int HCIComm::hci_close_dev(
int dd) noexcept
106 : dev_id( _dev_id ), channel( _channel ),
107 socket_descriptor( hci_open_dev(_dev_id, _channel) ), interrupt_flag(
false), tid_read(0)
112 const std::lock_guard<std::recursive_mutex> lock(mtx_write);
113 if( 0 > socket_descriptor ) {
114 DBG_PRINT(
"HCIComm::close: Not opened: dd %d", socket_descriptor.load());
117 DBG_PRINT(
"HCIComm::close: Start: dd %d", socket_descriptor.load());
120 interrupt_flag =
true;
122 pthread_t _tid_read = tid_read;
124 if( 0 != _tid_read ) {
125 pthread_t tid_self = pthread_self();
126 if( tid_self != _tid_read ) {
128 if( 0 != ( kerr = pthread_kill(_tid_read, SIGALRM) ) ) {
129 ERR_PRINT(
"HCIComm::close: pthread_kill read %p FAILED: %d", (
void*)_tid_read, kerr);
134 hci_close_dev(socket_descriptor);
135 socket_descriptor = -1;
136 interrupt_flag =
false;
138 DBG_PRINT(
"HCIComm::close: End: dd %d", socket_descriptor.load());
143 if( 0 > socket_descriptor ) {
146 if( 0 == capacity ) {
154 p.fd = socket_descriptor; p.events = POLLIN;
155 while ( !interrupt_flag && (n = poll(&p, 1, timeoutMS)) < 0 ) {
156 if ( !interrupt_flag && ( errno == EAGAIN || errno == EINTR ) ) {
168 while ((len = ::read(socket_descriptor, buffer, capacity)) < 0) {
169 if (errno == EAGAIN || errno == EINTR ) {
184 const std::lock_guard<std::recursive_mutex> lock(mtx_write);
186 if( 0 > socket_descriptor ) {
193 while( ( len = ::write(socket_descriptor, buffer, size) ) < 0 ) {
194 if( EAGAIN == errno || EINTR == errno ) {