| /****************************************************************************** |
| * |
| * Copyright 1999-2012 Broadcom Corporation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at: |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| ******************************************************************************/ |
| #ifndef BTM_INT_TYPES_H |
| #define BTM_INT_TYPES_H |
| |
| #include <cstdint> |
| #include <memory> |
| #include <string> |
| |
| #include "gd/common/circular_buffer.h" |
| #include "osi/include/allocator.h" |
| #include "osi/include/fixed_queue.h" |
| #include "osi/include/list.h" |
| #include "stack/acl/acl.h" |
| #include "stack/btm/btm_ble_int_types.h" |
| #include "stack/btm/btm_sco.h" |
| #include "stack/btm/neighbor_inquiry.h" |
| #include "stack/btm/security_device_record.h" |
| #include "stack/include/bt_octets.h" |
| #include "stack/include/btm_ble_api_types.h" |
| #include "stack/include/security_client_callbacks.h" |
| #include "types/raw_address.h" |
| |
| #define BTM_MAX_SCN_ 31 // PORT_MAX_RFC_PORTS system/bt/stack/include/rfcdefs.h |
| |
| constexpr size_t kMaxLogSize = 255; |
| class TimestampedStringCircularBuffer |
| : public bluetooth::common::TimestampedCircularBuffer<std::string> { |
| public: |
| explicit TimestampedStringCircularBuffer(size_t size) |
| : bluetooth::common::TimestampedCircularBuffer<std::string>(size) {} |
| |
| void Push(std::string s) { |
| bluetooth::common::TimestampedCircularBuffer<std::string>::Push( |
| s.substr(0, kMaxLogSize)); |
| } |
| |
| template <typename... Args> |
| void Push(Args... args) { |
| char buf[kMaxLogSize]; |
| std::snprintf(buf, sizeof(buf), args...); |
| bluetooth::common::TimestampedCircularBuffer<std::string>::Push( |
| std::string(buf)); |
| } |
| }; |
| |
| /* |
| * Local device configuration |
| */ |
| typedef struct { |
| tBTM_LOC_BD_NAME bd_name; /* local Bluetooth device name */ |
| bool pin_type; /* true if PIN type is fixed */ |
| uint8_t pin_code_len; /* Bonding information */ |
| PIN_CODE pin_code; /* PIN CODE if pin type is fixed */ |
| } tBTM_CFG; |
| |
| /* Pairing State */ |
| enum { |
| BTM_PAIR_STATE_IDLE, /* Idle */ |
| BTM_PAIR_STATE_GET_REM_NAME, /* Getting the remote name (to check for SM4) */ |
| BTM_PAIR_STATE_WAIT_PIN_REQ, /* Started authentication, waiting for PIN req |
| (PIN is pre-fetched) */ |
| BTM_PAIR_STATE_WAIT_LOCAL_PIN, /* Waiting for local PIN code */ |
| BTM_PAIR_STATE_WAIT_NUMERIC_CONFIRM, /* Waiting user 'yes' to numeric |
| confirmation */ |
| BTM_PAIR_STATE_KEY_ENTRY, /* Key entry state (we are a keyboard) */ |
| BTM_PAIR_STATE_WAIT_LOCAL_OOB_RSP, /* Waiting for local response to peer OOB |
| data */ |
| BTM_PAIR_STATE_WAIT_LOCAL_IOCAPS, /* Waiting for local IO capabilities and OOB |
| data */ |
| BTM_PAIR_STATE_INCOMING_SSP, /* Incoming SSP (got peer IO caps when idle) */ |
| BTM_PAIR_STATE_WAIT_AUTH_COMPLETE, /* All done, waiting authentication |
| cpmplete */ |
| BTM_PAIR_STATE_WAIT_DISCONNECT /* Waiting to disconnect the ACL */ |
| }; |
| typedef uint8_t tBTM_PAIRING_STATE; |
| |
| #define BTM_PAIR_FLAGS_WE_STARTED_DD \ |
| 0x01 /* We want to do dedicated bonding */ |
| #define BTM_PAIR_FLAGS_PEER_STARTED_DD \ |
| 0x02 /* Peer initiated dedicated bonding */ |
| #define BTM_PAIR_FLAGS_DISC_WHEN_DONE 0x04 /* Disconnect when done */ |
| #define BTM_PAIR_FLAGS_PIN_REQD \ |
| 0x08 /* set this bit when pin_callback is called */ |
| #define BTM_PAIR_FLAGS_PRE_FETCH_PIN \ |
| 0x10 /* set this bit when pre-fetch pin */ |
| #define BTM_PAIR_FLAGS_REJECTED_CONNECT \ |
| 0x20 /* set this bit when rejected incoming connection */ |
| #define BTM_PAIR_FLAGS_WE_CANCEL_DD \ |
| 0x40 /* set this bit when cancelling a bonding procedure */ |
| #define BTM_PAIR_FLAGS_LE_ACTIVE \ |
| 0x80 /* use this bit when SMP pairing is active */ |
| |
| typedef struct { |
| bool is_mux; |
| RawAddress bd_addr; |
| uint16_t psm; |
| bool is_orig; |
| tBTM_SEC_CALLBACK* p_callback; |
| void* p_ref_data; |
| uint16_t rfcomm_security_requirement; |
| tBT_TRANSPORT transport; |
| tBTM_BLE_SEC_ACT sec_act; |
| } tBTM_SEC_QUEUE_ENTRY; |
| |
| /* Define a structure to hold all the BTM data |
| */ |
| |
| #define BTM_STATE_BUFFER_SIZE 5 /* size of state buffer */ |
| |
| /* Define the Device Management control structure |
| */ |
| typedef struct tBTM_DEVCB { |
| tBTM_VS_EVT_CB* p_vend_spec_cb[BTM_MAX_VSE_CALLBACKS]; /* Register for vendor |
| specific events */ |
| |
| tBTM_CMPL_CB* |
| p_stored_link_key_cmpl_cb; /* Read/Write/Delete stored link key */ |
| |
| alarm_t* read_local_name_timer; /* Read local name timer */ |
| tBTM_CMPL_CB* p_rln_cmpl_cb; /* Callback function to be called when */ |
| /* read local name function complete */ |
| |
| alarm_t* read_rssi_timer; /* Read RSSI timer */ |
| tBTM_CMPL_CB* p_rssi_cmpl_cb; /* Callback function to be called when */ |
| /* read RSSI function completes */ |
| |
| alarm_t* read_failed_contact_counter_timer; /* Read Failed Contact Counter */ |
| /* timer */ |
| tBTM_CMPL_CB* p_failed_contact_counter_cmpl_cb; /* Callback function to be */ |
| /* called when read Failed Contact Counter function completes */ |
| |
| alarm_t* |
| read_automatic_flush_timeout_timer; /* Read Automatic Flush Timeout */ |
| /* timer */ |
| tBTM_CMPL_CB* p_automatic_flush_timeout_cmpl_cb; /* Callback function to be */ |
| /* called when read Automatic Flush Timeout function completes */ |
| |
| alarm_t* read_link_quality_timer; |
| tBTM_CMPL_CB* p_link_qual_cmpl_cb; /* Callback function to be called when */ |
| /* read link quality function completes */ |
| |
| alarm_t* read_tx_power_timer; /* Read tx power timer */ |
| tBTM_CMPL_CB* p_tx_power_cmpl_cb; /* Callback function to be called */ |
| |
| DEV_CLASS dev_class; /* Local device class */ |
| |
| tBTM_CMPL_CB* |
| p_le_test_cmd_cmpl_cb; /* Callback function to be called when |
| LE test mode command has been sent successfully */ |
| |
| RawAddress read_tx_pwr_addr; /* read TX power target address */ |
| |
| tBTM_BLE_LOCAL_ID_KEYS id_keys; /* local BLE ID keys */ |
| Octet16 ble_encryption_key_value; /* BLE encryption key */ |
| |
| #if (BTM_BLE_CONFORMANCE_TESTING == TRUE) |
| bool no_disc_if_pair_fail; |
| bool enable_test_mac_val; |
| BT_OCTET8 test_mac; |
| bool enable_test_local_sign_cntr; |
| uint32_t test_local_sign_cntr; |
| #endif |
| |
| tBTM_IO_CAP loc_io_caps; /* IO capability of the local device */ |
| tBTM_AUTH_REQ loc_auth_req; /* the auth_req flag */ |
| |
| void Init() { |
| read_local_name_timer = alarm_new("btm.read_local_name_timer"); |
| read_rssi_timer = alarm_new("btm.read_rssi_timer"); |
| read_failed_contact_counter_timer = |
| alarm_new("btm.read_failed_contact_counter_timer"); |
| read_automatic_flush_timeout_timer = |
| alarm_new("btm.read_automatic_flush_timeout_timer"); |
| read_link_quality_timer = alarm_new("btm.read_link_quality_timer"); |
| read_tx_power_timer = alarm_new("btm.read_tx_power_timer"); |
| } |
| |
| void Free() { |
| alarm_free(read_local_name_timer); |
| alarm_free(read_rssi_timer); |
| alarm_free(read_failed_contact_counter_timer); |
| alarm_free(read_automatic_flush_timeout_timer); |
| alarm_free(read_link_quality_timer); |
| alarm_free(read_tx_power_timer); |
| } |
| } tBTM_DEVCB; |
| |
| typedef struct tBTM_CB { |
| tBTM_CFG cfg; /* Device configuration */ |
| |
| /***************************************************** |
| ** Device control |
| *****************************************************/ |
| tBTM_DEVCB devcb; |
| |
| /***************************************************** |
| ** BLE Device controllers |
| *****************************************************/ |
| tBTM_BLE_CB ble_ctr_cb; |
| |
| private: |
| friend void btm_ble_ltk_request_reply(const RawAddress& bda, bool use_stk, |
| const Octet16& stk); |
| friend tBTM_STATUS btm_ble_start_encrypt(const RawAddress& bda, bool use_stk, |
| Octet16* p_stk); |
| friend void btm_ble_ltk_request_reply(const RawAddress& bda, bool use_stk, |
| const Octet16& stk); |
| uint16_t enc_handle{0}; |
| |
| friend void btm_ble_ltk_request(uint16_t handle, uint8_t rand[8], |
| uint16_t ediv); |
| BT_OCTET8 enc_rand; /* received rand value from LTK request*/ |
| |
| uint16_t ediv{0}; /* received ediv value from LTK request */ |
| |
| uint8_t key_size{0}; |
| |
| public: |
| tBTM_BLE_VSC_CB cmn_ble_vsc_cb; |
| |
| /* Packet types supported by the local device */ |
| uint16_t btm_sco_pkt_types_supported{0}; |
| |
| /***************************************************** |
| ** Inquiry |
| *****************************************************/ |
| tBTM_INQUIRY_VAR_ST btm_inq_vars; |
| |
| /***************************************************** |
| ** SCO Management |
| *****************************************************/ |
| tSCO_CB sco_cb; |
| |
| /***************************************************** |
| ** Security Management |
| *****************************************************/ |
| tBTM_APPL_INFO api; |
| |
| #define BTM_SEC_MAX_RMT_NAME_CALLBACKS 2 |
| tBTM_RMT_NAME_CALLBACK* p_rmt_name_callback[BTM_SEC_MAX_RMT_NAME_CALLBACKS]; |
| |
| tBTM_SEC_DEV_REC* p_collided_dev_rec{nullptr}; |
| alarm_t* sec_collision_timer{nullptr}; |
| uint64_t collision_start_time{0}; |
| uint32_t dev_rec_count{0}; /* Counter used for device record timestamp */ |
| uint8_t security_mode{0}; |
| bool pairing_disabled{false}; |
| bool security_mode_changed{false}; /* mode changed during bonding */ |
| bool pin_type_changed{false}; /* pin type changed during bonding */ |
| bool sec_req_pending{false}; /* true if a request is pending */ |
| |
| uint8_t pin_code_len{0}; /* for legacy devices */ |
| PIN_CODE pin_code; /* for legacy devices */ |
| tBTM_PAIRING_STATE pairing_state{ |
| BTM_PAIR_STATE_IDLE}; /* The current pairing state */ |
| uint8_t pairing_flags{0}; /* The current pairing flags */ |
| RawAddress pairing_bda; /* The device currently pairing */ |
| alarm_t* pairing_timer{nullptr}; /* Timer for pairing process */ |
| alarm_t* execution_wait_timer{nullptr}; /* To avoid concurrent auth request */ |
| uint16_t disc_handle{0}; /* for legacy devices */ |
| uint8_t disc_reason{0}; /* for legacy devices */ |
| tBTM_SEC_SERV_REC sec_serv_rec[BTM_SEC_MAX_SERVICE_RECORDS]; |
| list_t* sec_dev_rec{nullptr}; /* list of tBTM_SEC_DEV_REC */ |
| tBTM_SEC_SERV_REC* p_out_serv{nullptr}; |
| tBTM_MKEY_CALLBACK* mkey_cback{nullptr}; |
| |
| RawAddress connecting_bda; |
| DEV_CLASS connecting_dc; |
| uint8_t trace_level; |
| bool is_paging{false}; /* true, if paging is in progess */ |
| bool is_inquiry{false}; /* true, if inquiry is in progess */ |
| fixed_queue_t* page_queue{nullptr}; |
| |
| bool paging{false}; |
| void set_paging() { paging = true; } |
| void reset_paging() { paging = false; } |
| bool is_paging_active() const { |
| return paging; |
| } // TODO remove all this paging state |
| |
| fixed_queue_t* sec_pending_q{nullptr}; /* pending sequrity requests in |
| tBTM_SEC_QUEUE_ENTRY format */ |
| |
| // BQR Receiver |
| tBTM_BT_QUALITY_REPORT_RECEIVER* p_bqr_report_receiver{nullptr}; |
| |
| #define BTM_CODEC_TYPE_MAX_RECORDS 32 |
| tBTM_BT_DYNAMIC_AUDIO_BUFFER_CB |
| dynamic_audio_buffer_cb[BTM_CODEC_TYPE_MAX_RECORDS]; |
| |
| tACL_CB acl_cb_; |
| |
| std::shared_ptr<TimestampedStringCircularBuffer> history_{nullptr}; |
| |
| void Init(uint8_t initial_security_mode) { |
| memset(&cfg, 0, sizeof(cfg)); |
| memset(&devcb, 0, sizeof(devcb)); |
| memset(&ble_ctr_cb, 0, sizeof(ble_ctr_cb)); |
| memset(&enc_rand, 0, sizeof(enc_rand)); |
| memset(&cmn_ble_vsc_cb, 0, sizeof(cmn_ble_vsc_cb)); |
| memset(&btm_inq_vars, 0, sizeof(btm_inq_vars)); |
| memset(&sco_cb, 0, sizeof(sco_cb)); |
| memset(&api, 0, sizeof(api)); |
| memset(p_rmt_name_callback, 0, sizeof(p_rmt_name_callback)); |
| memset(&pin_code, 0, sizeof(pin_code)); |
| memset(sec_serv_rec, 0, sizeof(sec_serv_rec)); |
| |
| connecting_bda = RawAddress::kEmpty; |
| memset(&connecting_dc, 0, sizeof(connecting_dc)); |
| |
| memset(&acl_cb_, 0, sizeof(acl_cb_)); |
| |
| page_queue = fixed_queue_new(SIZE_MAX); |
| sec_pending_q = fixed_queue_new(SIZE_MAX); |
| sec_collision_timer = alarm_new("btm.sec_collision_timer"); |
| pairing_timer = alarm_new("btm.pairing_timer"); |
| execution_wait_timer = alarm_new("btm.execution_wait_timer"); |
| |
| #if defined(BTM_INITIAL_TRACE_LEVEL) |
| trace_level = BTM_INITIAL_TRACE_LEVEL; |
| #else |
| trace_level = BT_TRACE_LEVEL_NONE; /* No traces */ |
| #endif |
| security_mode = initial_security_mode; |
| pairing_bda = RawAddress::kAny; |
| sec_dev_rec = list_new(osi_free); |
| |
| /* Initialize BTM component structures */ |
| btm_inq_vars.Init(); /* Inquiry Database and Structures */ |
| acl_cb_ = {}; |
| sco_cb.Init(); /* SCO Database and Structures (If included) */ |
| devcb.Init(); |
| |
| history_ = std::make_shared<TimestampedStringCircularBuffer>(40); |
| CHECK(history_ != nullptr); |
| history_->Push(std::string("Initialized btm history")); |
| } |
| |
| void Free() { |
| history_.reset(); |
| |
| devcb.Free(); |
| btm_inq_vars.Free(); |
| |
| fixed_queue_free(page_queue, nullptr); |
| page_queue = nullptr; |
| |
| fixed_queue_free(sec_pending_q, nullptr); |
| sec_pending_q = nullptr; |
| |
| list_free(sec_dev_rec); |
| sec_dev_rec = nullptr; |
| |
| alarm_free(sec_collision_timer); |
| sec_collision_timer = nullptr; |
| |
| alarm_free(pairing_timer); |
| pairing_timer = nullptr; |
| |
| alarm_free(execution_wait_timer); |
| execution_wait_timer = nullptr; |
| } |
| |
| private: |
| friend uint8_t BTM_AllocateSCN(void); |
| friend bool BTM_TryAllocateSCN(uint8_t scn); |
| friend bool BTM_FreeSCN(uint8_t scn); |
| uint8_t btm_scn[BTM_MAX_SCN_]; |
| } tBTM_CB; |
| |
| /* security action for L2CAP COC channels */ |
| #define BTM_SEC_OK 1 |
| #define BTM_SEC_ENCRYPT 2 /* encrypt the link with current key */ |
| #define BTM_SEC_ENCRYPT_NO_MITM 3 /* unauthenticated encryption or better */ |
| #define BTM_SEC_ENCRYPT_MITM 4 /* authenticated encryption */ |
| #define BTM_SEC_ENC_PENDING 5 /* wait for link encryption pending */ |
| |
| typedef uint8_t tBTM_SEC_ACTION; |
| |
| #endif // BTM_INT_TYPES_H |