#define HCI_MAX_PAGES 3
+#ifdef TIZEN_BT
+#define HCI_MAX_EIR_MANUFACTURER_DATA_LENGTH 100
+#endif
+
struct hci_dev {
struct list_head list;
struct mutex lock;
struct work_struct cmd_sync_work;
struct list_head cmd_sync_work_list;
struct mutex cmd_sync_work_lock;
+ struct mutex unregister_lock;
struct work_struct cmd_sync_cancel_work;
struct work_struct reenable_adv_work;
u8 wake_reason;
bdaddr_t wake_addr;
u8 wake_addr_type;
+#ifdef TIZEN_BT
+ struct discovery_state le_discovery;
+#endif
struct hci_conn_hash conn_hash;
bool aosp_quality_report;
#endif
+#ifdef TIZEN_BT
+ __u8 adv_filter_policy;
+ __u8 adv_type;
+ __u8 manufacturer_len;
+ __u8 manufacturer_data[HCI_MAX_EIR_MANUFACTURER_DATA_LENGTH];
+#endif
+
int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev);
int (*flush)(struct hci_dev *hdev);
__u8 remote_id;
unsigned int sent;
+#ifdef TIZEN_BT
+ __u16 tx_len;
+ __u16 tx_time;
+ __u16 rx_len;
+ __u16 rx_time;
+#endif
struct sk_buff_head data_q;
struct list_head chan_list;
void *iso_data;
struct amp_mgr *amp_mgr;
+#ifdef TIZEN_BT
+ bool rssi_monitored;
+ __u8 sco_role;
+ __u16 voice_setting;
+#endif
struct hci_conn *link;
struct bt_codec codec;
u16 conn_latency;
u16 supervision_timeout;
+#ifdef TIZEN_BT
+ u16 max_tx_octets;
+ u16 max_tx_time;
+#endif
enum {
HCI_AUTO_CONN_DISABLED,
HCI_AUTO_CONN_REPORT,
void hci_inquiry_cache_flush(struct hci_dev *hdev);
/* ----- HCI Connections ----- */
+#ifdef TIZEN_BT
+#define LINK_SUPERVISION_TIMEOUT 0x1F40 /* n * 0.625 = 5 seconds */
+#endif /* TIZEN_BT */
+
enum {
HCI_CONN_AUTH_PEND,
HCI_CONN_REAUTH_PEND,
HCI_CONN_STK_ENCRYPT,
HCI_CONN_AUTH_INITIATOR,
HCI_CONN_DROP,
+ HCI_CONN_CANCEL,
HCI_CONN_PARAM_REMOVAL_PEND,
HCI_CONN_NEW_LINK_KEY,
HCI_CONN_SCANNING,
return NULL;
}
+#ifdef TIZEN_BT
+static inline bool hci_conn_rssi_state_set(struct hci_dev *hdev,
+ __u8 type, bdaddr_t *ba, bool value)
+{
+ struct hci_conn_hash *h = &hdev->conn_hash;
+ struct hci_conn *c;
+ __u8 conn_type;
+
+ if (type == 0x01)
+ conn_type = LE_LINK;
+ else
+ conn_type = ACL_LINK;
+
+ rcu_read_lock();
+
+ list_for_each_entry_rcu(c, &h->list, list) {
+ if (c->type == conn_type && !bacmp(&c->dst, ba)) {
+ c->rssi_monitored = value;
+ rcu_read_unlock();
+ return true;
+ }
+ }
+
+ rcu_read_unlock();
+ return false;
+}
+
+static inline void hci_conn_rssi_unset_all(struct hci_dev *hdev,
+ __u8 type)
+{
+ struct hci_conn_hash *h = &hdev->conn_hash;
+ struct hci_conn *c;
+ __u8 conn_type;
+
+ if (type == 0x01)
+ conn_type = LE_LINK;
+ else
+ conn_type = ACL_LINK;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(c, &h->list, list) {
+ if (c->type == conn_type)
+ c->rssi_monitored = false;
+ }
+ rcu_read_unlock();
+}
+
+static inline int hci_conn_hash_lookup_rssi_count(struct hci_dev *hdev)
+{
+ struct hci_conn_hash *h = &hdev->conn_hash;
+ struct hci_conn *c;
+ int count = 0;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(c, &h->list, list) {
+ if (c->rssi_monitored == true)
+ ++count;
+ }
+ rcu_read_unlock();
+
+ return count;
+}
+
+int hci_conn_change_supervision_timeout(struct hci_conn *conn, __u16 timeout);
+bool hci_le_discovery_active(struct hci_dev *hdev);
+void hci_le_discovery_set_state(struct hci_dev *hdev, int state);
+
+static inline struct hci_conn *hci_conn_hash_lookup_sco(struct hci_dev *hdev)
+{
+ struct hci_conn_hash *h = &hdev->conn_hash;
+ struct hci_conn *c;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(c, &h->list, list) {
+ if (c->type == SCO_LINK || c->type == ESCO_LINK) {
+ rcu_read_unlock();
+ return c;
+ }
+ }
+ rcu_read_unlock();
+
+ return NULL;
+}
+#endif
+
int hci_disconnect(struct hci_conn *conn, __u8 reason);
bool hci_setup_sync(struct hci_conn *conn, __u16 handle);
void hci_sco_setup(struct hci_conn *conn, __u8 status);
int hci_get_conn_list(void __user *arg);
int hci_get_conn_info(struct hci_dev *hdev, void __user *arg);
int hci_get_auth_info(struct hci_dev *hdev, void __user *arg);
+#ifdef TIZEN_BT
+u32 get_link_mode(struct hci_conn *conn);
+#endif
int hci_inquiry(void __user *arg);
struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *list,
/* Use ext scanning if set ext scan param and ext scan enable is supported */
#define use_ext_scan(dev) (((dev)->commands[37] & 0x20) && \
- ((dev)->commands[37] & 0x40))
+ ((dev)->commands[37] & 0x40) && \
+ !test_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &(dev)->quirks))
+
/* Use ext create connection if command is supported */
#define use_ext_conn(dev) ((dev)->commands[37] & 0x80)
((dev)->le_features[3] & HCI_LE_CIS_PERIPHERAL)
#define bis_capable(dev) ((dev)->le_features[3] & HCI_LE_ISO_BROADCASTER)
+#define mws_transport_config_capable(dev) (((dev)->commands[30] & 0x08) && \
+ (!test_bit(HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG, &(dev)->quirks)))
+
/* ----- HCI protocols ----- */
#define HCI_PROTO_DEFER 0x01
unsigned short channel;
size_t handler_count;
const struct hci_mgmt_handler *handlers;
+#ifdef TIZEN_BT
+ size_t tizen_handler_count;
+ const struct hci_mgmt_handler *tizen_handlers;
+#endif
void (*hdev_init) (struct sock *sk, struct hci_dev *hdev);
};
void mgmt_adv_monitor_device_lost(struct hci_dev *hdev, u16 handle,
bdaddr_t *bdaddr, u8 addr_type);
+#ifdef TIZEN_BT
+void mgmt_rssi_enable_success(struct sock *sk, struct hci_dev *hdev,
+ void *data, struct hci_cc_rsp_enable_rssi *rp, int success);
+void mgmt_rssi_disable_success(struct sock *sk, struct hci_dev *hdev,
+ void *data, struct hci_cc_rsp_enable_rssi *rp, int success);
+int mgmt_set_rssi_threshold(struct sock *sk, struct hci_dev *hdev,
+ void *data, u16 len);
+void mgmt_rssi_alert_evt(struct hci_dev *hdev, u16 conn_handle,
+ s8 alert_type, s8 rssi_dbm);
+void mgmt_raw_rssi_response(struct hci_dev *hdev,
+ struct hci_cc_rp_get_raw_rssi *rp, int success);
+void mgmt_enable_rssi_cc(struct hci_dev *hdev, void *response, u8 status);
+int mgmt_device_name_update(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *name,
+ u8 name_len);
+void mgmt_le_discovering(struct hci_dev *hdev, u8 discovering);
+int mgmt_le_conn_updated(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type,
+ u8 dst_type, u16 conn_interval, u16 conn_latency,
+ u16 supervision_timeout);
+int mgmt_le_conn_update_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
+ u8 link_type, u8 addr_type, u8 status);
+void mgmt_hardware_error(struct hci_dev *hdev, u8 err_code);
+void mgmt_tx_timeout_error(struct hci_dev *hdev);
+/* Pass adv type in the le device found */
+void mgmt_le_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
+ u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, u8 *eir,
+ u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len, u8 adv_type);
+void mgmt_multi_adv_state_change_evt(struct hci_dev *hdev, u8 adv_instance,
+ u8 state_change_reason, u16 connection_handle);
+void mgmt_6lowpan_conn_changed(struct hci_dev *hdev, char if_name[16],
+ bdaddr_t *bdaddr, u8 addr_type, bool connected);
+void mgmt_le_read_maximum_data_length_complete(struct hci_dev *hdev,
+ u8 status);
+void mgmt_le_write_host_suggested_data_length_complete(struct hci_dev *hdev,
+ u8 status);
+void mgmt_le_read_host_suggested_data_length_complete(struct hci_dev *hdev,
+ u8 status);
+void mgmt_le_data_length_change_complete(struct hci_dev *hdev,
+ bdaddr_t *bdaddr, u16 tx_octets, u16 tx_time,
+ u16 rx_octets, u16 rx_time);
+int hci_le_set_data_length(struct hci_conn *conn, u16 tx_octets, u16 tx_time);
+#endif
+
int hci_abort_conn(struct hci_conn *conn, u8 reason);
u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency,
u16 to_multiplier);