aboutsummaryrefslogtreecommitdiffstats
path: root/api/direct_bt/HCIHandler.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'api/direct_bt/HCIHandler.hpp')
-rw-r--r--api/direct_bt/HCIHandler.hpp90
1 files changed, 74 insertions, 16 deletions
diff --git a/api/direct_bt/HCIHandler.hpp b/api/direct_bt/HCIHandler.hpp
index 61c41e4f..f259bf20 100644
--- a/api/direct_bt/HCIHandler.hpp
+++ b/api/direct_bt/HCIHandler.hpp
@@ -53,6 +53,33 @@
*/
namespace direct_bt {
+ class HCIHandleBDAddr {
+ public:
+ uint16_t handle;
+ EUI48 address;
+ BDAddressType addressType;
+
+ public:
+ HCIHandleBDAddr(const uint16_t handle, const EUI48 &address, const BDAddressType addressType)
+ : handle(handle), address(address), addressType(addressType) {}
+
+ HCIHandleBDAddr(const HCIHandleBDAddr &o) = default;
+ HCIHandleBDAddr(HCIHandleBDAddr &&o) = default;
+ HCIHandleBDAddr& operator=(const HCIHandleBDAddr &o) = default;
+ HCIHandleBDAddr& operator=(HCIHandleBDAddr &&o) = default;
+
+ bool operator==(const HCIHandleBDAddr& rhs) const
+ { return handle == rhs.handle; }
+
+ bool operator!=(const HCIHandleBDAddr& rhs) const
+ { return !(*this == rhs); }
+
+ std::string toString() const {
+ return "HCIHandleBDAddr[handle "+uint16HexString(handle)+
+ ", address="+address.toString()+", addressType "+getBDAddressTypeString(addressType)+"]";
+ }
+ };
+
/**
* A thread safe singleton handler of the HCI control channel to one controller (BT adapter)
* <p>
@@ -75,9 +102,10 @@ namespace direct_bt {
};
static const pid_t pidSelf;
+ static MgmtEvent::Opcode translate(HCIEventType evt, HCIMetaEventType met);
+ std::shared_ptr<MgmtEvent> translate(std::shared_ptr<HCIEvent> ev);
private:
- const bool pass_replies_only_filter;
const BTMode btMode;
const uint16_t dev_id;
POctets rbuffer;
@@ -90,9 +118,9 @@ namespace direct_bt {
inline bool filter_test_metaev(HCIMetaEventType mec) { return 0 != test_bit_uint32(number(mec)-1, metaev_filter_mask); }
inline void filter_put_metaevs(const uint32_t mask) { metaev_filter_mask=mask; }
- inline void filter_clear_metaevs(uint32_t &mask) { mask=0; }
- inline void filter_all_metaevs(uint32_t &mask) { mask=0xffff; }
- inline void filter_set_metaev(HCIMetaEventType mec, uint32_t &mask) { set_bit_uint32(number(mec)-1, mask); }
+ inline static void filter_clear_metaevs(uint32_t &mask) { mask=0; }
+ inline static void filter_all_metaevs(uint32_t &mask) { mask=0xffff; }
+ inline static void filter_set_metaev(HCIMetaEventType mec, uint32_t &mask) { set_bit_uint32(number(mec)-1, mask); }
LFRingbuffer<std::shared_ptr<HCIEvent>, nullptr> hciEventRing;
std::atomic<pthread_t> hciReaderThreadId;
@@ -102,6 +130,18 @@ namespace direct_bt {
std::condition_variable cv_hciReaderInit;
std::recursive_mutex mtx_sendReply; // for sendWith*Reply, process*Command, ..
+ std::vector<HCIHandleBDAddr> disconnectHandleAddrList;
+ std::recursive_mutex mtx_disconnectHandleAddrList;
+
+ /** One MgmtAdapterEventCallbackList per event type, allowing multiple callbacks to be invoked for each event */
+ std::array<MgmtEventCallbackList, static_cast<uint16_t>(MgmtEvent::Opcode::MGMT_EVENT_TYPE_COUNT)> mgmtEventCallbackLists;
+ std::recursive_mutex mtx_callbackLists;
+ inline void checkMgmtEventCallbackListsIndex(const MgmtEvent::Opcode opc) const {
+ if( static_cast<uint16_t>(opc) >= mgmtEventCallbackLists.size() ) {
+ throw IndexOutOfBoundsException(static_cast<uint16_t>(opc), 1, mgmtEventCallbackLists.size(), E_FILE_LINE);
+ }
+ }
+
void hciReaderThreadImpl();
bool sendCommand(HCICommand &req);
@@ -112,19 +152,23 @@ namespace direct_bt {
template<typename hci_cmd_event_struct>
std::shared_ptr<HCIEvent> processSimpleCommand(HCIOpcode opc, const hci_cmd_event_struct **res, HCIStatusCode *status);
- template<typename hci_command_struct, typename hci_cmd_event_struct>
- std::shared_ptr<HCIEvent> processStructCommand(HCIStructCommand<hci_command_struct> &req,
- HCIEventType evc, const hci_cmd_event_struct **res,
- HCIStatusCode *status);
+ template<typename hci_command_struct>
+ std::shared_ptr<HCIEvent> processStructCommand(HCIStructCommand<hci_command_struct> &req, HCIStatusCode *status);
- template<typename hci_command_struct, typename hci_cmd_event_struct>
- std::shared_ptr<HCIEvent> processStructMetaCmd(HCIStructCommand<hci_command_struct> &req,
- HCIMetaEventType mec, const hci_cmd_event_struct **res,
- HCIStatusCode *status);
+ template<typename hci_cmd_event_struct>
+ const hci_cmd_event_struct* getReplyStruct(std::shared_ptr<HCIEvent> event, HCIEventType evc, HCIStatusCode *status);
+
+ template<typename hci_cmd_event_struct>
+ const hci_cmd_event_struct* getMetaReplyStruct(std::shared_ptr<HCIEvent> event, HCIMetaEventType mec, HCIStatusCode *status);
HCIHandler(const HCIHandler&) = delete;
void operator=(const HCIHandler&) = delete;
+ bool mgmtEvDeviceDisconnectedCB(std::shared_ptr<MgmtEvent> e);
+ bool mgmtEvDeviceConnectedCB(std::shared_ptr<MgmtEvent> e);
+ bool mgmtEvConnectFailedCB(std::shared_ptr<MgmtEvent> e);
+ void sendMgmtEvent(std::shared_ptr<MgmtEvent> event);
+
public:
HCIHandler(const BTMode btMode, const uint16_t dev_id, const int replyTimeoutMS=Defaults::HCI_COMMAND_REPLY_TIMEOUT);
@@ -162,7 +206,6 @@ namespace direct_bt {
* Set window to the same value as the interval, enables continuous scanning.
* </p>
*
- * @param handle_return
* @param peer_bdaddr
* @param peer_mac_type
* @param own_mac_type
@@ -174,7 +217,7 @@ namespace direct_bt {
* @param supervision_timeout in units of 10ms, default value 1000 for 10000ms or 10s.
* @return
*/
- HCIStatusCode le_create_conn(uint16_t * handle_return, const EUI48 &peer_bdaddr,
+ HCIStatusCode le_create_conn(const EUI48 &peer_bdaddr,
const HCIAddressType peer_mac_type=HCIAddressType::HCIADDR_LE_PUBLIC,
const HCIAddressType own_mac_type=HCIAddressType::HCIADDR_LE_PUBLIC,
const uint16_t le_scan_interval=48, const uint16_t le_scan_window=48,
@@ -187,7 +230,7 @@ namespace direct_bt {
* BT Core Spec v5.2: Vol 4, Part E HCI: 7.1.5 Create Connection command
* </p>
*/
- HCIStatusCode create_conn(uint16_t * handle_return, const EUI48 &bdaddr,
+ HCIStatusCode create_conn(const EUI48 &bdaddr,
const uint16_t pkt_type=HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5,
const uint16_t clock_offset=0x0000, const uint8_t role_switch=0x01);
@@ -197,7 +240,22 @@ namespace direct_bt {
* BT Core Spec v5.2: Vol 4, Part E HCI: 7.1.6 Disconnect command
* </p>
*/
- HCIStatusCode disconnect(const uint16_t conn_handle, const HCIStatusCode reason=HCIStatusCode::REMOTE_USER_TERMINATED_CONNECTION);
+ HCIStatusCode disconnect(const uint16_t conn_handle, const EUI48 &peer_bdaddr, const BDAddressType peer_mac_type,
+ const HCIStatusCode reason=HCIStatusCode::REMOTE_USER_TERMINATED_CONNECTION);
+
+ /** MgmtEventCallback handling */
+
+ /**
+ * Appends the given MgmtEventCallback to the named MgmtEvent::Opcode list,
+ * if it is not present already (opcode + callback).
+ */
+ void addMgmtEventCallback(const MgmtEvent::Opcode opc, const MgmtEventCallback &cb);
+ /** Returns count of removed given MgmtEventCallback from the named MgmtEvent::Opcode list. */
+ int removeMgmtEventCallback(const MgmtEvent::Opcode opc, const MgmtEventCallback &cb);
+ /** Removes all MgmtEventCallbacks from the to the named MgmtEvent::Opcode list. */
+ void clearMgmtEventCallbacks(const MgmtEvent::Opcode opc);
+ /** Removes all MgmtEventCallbacks from all MgmtEvent::Opcode lists. */
+ void clearAllMgmtEventCallbacks();
};
} // namespace direct_bt