Bluetooth: Add initial support for BR/EDR discovery
This allows to start (general or limited) BR/EDR discovery. Inquiry is active until explicitly disabled by application. This is to keep BR/EDR discovery API similar to LE scan API. < HCI Command: Inquiry (0x01|0x0001) plen 5 Access code: 0x9e8b33 (General Inquiry) Length: 61.44s (0x30) Num responses: 0 > HCI Event: Command Status (0x0f) plen 4 Inquiry (0x01|0x0001) ncmd 1 Status: Success (0x00) > HCI Event: Inquiry Complete (0x01) plen 1 Status: Success (0x00) Change-Id: I946fbd881e6d0460be28a9975acd564ae32896e8 Signed-off-by: Szymon Janc <ext.szymon.janc@tieto.com>
This commit is contained in:
parent
a4836f4da4
commit
ca662c14f1
3 changed files with 188 additions and 5 deletions
|
@ -247,6 +247,67 @@ int bt_le_scan_start(const struct bt_le_scan_param *param, bt_le_scan_cb_t cb);
|
|||
*/
|
||||
int bt_le_scan_stop(void);
|
||||
|
||||
/** @brief BR/EDR discovery result structure */
|
||||
struct bt_br_discovery_result {
|
||||
/** Remote device address */
|
||||
bt_addr_t addr;
|
||||
|
||||
/** RSSI from inquiry */
|
||||
int8_t rssi;
|
||||
|
||||
/** Class of Device */
|
||||
uint8_t cod[3];
|
||||
|
||||
/** Extended Inquiry Response */
|
||||
uint8_t eir[240];
|
||||
};
|
||||
|
||||
/** @brief Define a type allowing user to implement a function that can
|
||||
* be used to get back BR/EDR discovery (inquiry) results.
|
||||
*
|
||||
* A function of this type will be called back when user application
|
||||
* triggers BR/EDR discovery and discovery process completes.
|
||||
*
|
||||
* @param results Storage used for discovery results
|
||||
* @param count Number of valid discovery results.
|
||||
*/
|
||||
typedef void bt_br_discovery_cb_t(struct bt_br_discovery_result *results,
|
||||
size_t count);
|
||||
|
||||
/** BR/EDR discovery parameters */
|
||||
struct bt_br_discovery_param {
|
||||
/** True if limited discovery procedure is to be used. */
|
||||
bool limited_discovery;
|
||||
};
|
||||
|
||||
/** @brief Start BR/EDR discovery
|
||||
*
|
||||
* Start BR/EDR discovery (inquiry) and provide results through the specified
|
||||
* callback. When bt_br_discovery_cb_t is called it indicates that discovery
|
||||
* has completed.
|
||||
*
|
||||
* @param param Discovery parameters.
|
||||
* @param results Storage for discovery results.
|
||||
* @param count Number of results in storage
|
||||
* @param cb Callback to notify discovery results.
|
||||
*
|
||||
* @return Zero on success or error code otherwise, positive in case
|
||||
* of protocol error or negative (POSIX) in case of stack internal error
|
||||
*/
|
||||
int bt_br_discovery_start(const struct bt_br_discovery_param *param,
|
||||
struct bt_br_discovery_result *results, size_t count,
|
||||
bt_br_discovery_cb_t cb);
|
||||
|
||||
/** @brief Stop BR/EDR discovery.
|
||||
*
|
||||
* Stops ongoing BR/EDR discovery. If discovery was stopped by this call
|
||||
* results won't be reported
|
||||
*
|
||||
* @return Zero on success or error code otherwise, positive in case
|
||||
* of protocol error or negative (POSIX) in case of stack internal error
|
||||
*/
|
||||
int bt_br_discovery_stop(void);
|
||||
|
||||
/** @def BT_ADDR_STR_LEN
|
||||
*
|
||||
* @brief Recommended length of user string buffer for Bluetooth address
|
||||
|
|
|
@ -63,6 +63,13 @@ struct bt_dev bt_dev;
|
|||
|
||||
static bt_le_scan_cb_t *scan_dev_found_cb;
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||
static bt_br_discovery_cb_t *discovery_cb;
|
||||
struct bt_br_discovery_result *discovery_results;
|
||||
static size_t discovery_results_size;
|
||||
static size_t discovery_results_count;
|
||||
#endif /* CONFIG_BLUETOOTH_BREDR */
|
||||
|
||||
struct cmd_data {
|
||||
/** The command OpCode that the buffer contains */
|
||||
uint16_t opcode;
|
||||
|
@ -1305,7 +1312,18 @@ static void user_passkey_req(struct net_buf *buf)
|
|||
bt_conn_ssp_auth(conn, 0);
|
||||
bt_conn_unref(conn);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void inquiry_complete(struct net_buf *buf)
|
||||
{
|
||||
struct bt_hci_evt_inquiry_complete *evt = (void *)buf->data;
|
||||
|
||||
BT_DBG("status %u", evt->status);
|
||||
|
||||
if (evt->status) {
|
||||
BT_ERR("Failed to complete inquiry");
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_BLUETOOTH_BREDR */
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_SMP) || defined(CONFIG_BLUETOOTH_BREDR)
|
||||
static void update_sec_level(struct bt_conn *conn)
|
||||
|
@ -1587,6 +1605,12 @@ static void hci_reset_complete(struct net_buf *buf)
|
|||
}
|
||||
|
||||
scan_dev_found_cb = NULL;
|
||||
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||
discovery_cb = NULL;
|
||||
discovery_results = NULL;
|
||||
discovery_results_size = 0;
|
||||
discovery_results_count = 0;
|
||||
#endif /* CONFIG_BLUETOOTH_BREDR */
|
||||
atomic_set(bt_dev.flags, 0);
|
||||
}
|
||||
|
||||
|
@ -1995,6 +2019,9 @@ static void hci_event(struct net_buf *buf)
|
|||
case BT_HCI_EVT_USER_PASSKEY_REQ:
|
||||
user_passkey_req(buf);
|
||||
break;
|
||||
case BT_HCI_EVT_INQUIRY_COMPLETE:
|
||||
inquiry_complete(buf);
|
||||
break;
|
||||
#endif
|
||||
#if defined(CONFIG_BLUETOOTH_CONN)
|
||||
case BT_HCI_EVT_DISCONN_COMPLETE:
|
||||
|
@ -2387,7 +2414,8 @@ static int le_init(void)
|
|||
static int br_init(void)
|
||||
{
|
||||
struct net_buf *buf;
|
||||
struct bt_hci_cp_write_ssp_mode *cp;
|
||||
struct bt_hci_cp_write_ssp_mode *ssp_cp;
|
||||
struct bt_hci_cp_write_inquiry_mode *inq_cp;
|
||||
int err;
|
||||
|
||||
/* Get BR/EDR buffer size */
|
||||
|
@ -2400,18 +2428,31 @@ static int br_init(void)
|
|||
net_buf_unref(buf);
|
||||
|
||||
/* Set SSP mode */
|
||||
buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_SSP_MODE, sizeof(*cp));
|
||||
buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_SSP_MODE, sizeof(*ssp_cp));
|
||||
if (!buf) {
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
cp = net_buf_add(buf, sizeof(*cp));
|
||||
cp->mode = 0x01;
|
||||
ssp_cp = net_buf_add(buf, sizeof(*ssp_cp));
|
||||
ssp_cp->mode = 0x01;
|
||||
err = bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_SSP_MODE, buf, NULL);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Enable Inquiry results with RSSI or extended Inquiry */
|
||||
buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_INQUIRY_MODE, sizeof(*inq_cp));
|
||||
if (!buf) {
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
inq_cp = net_buf_add(buf, sizeof(*inq_cp));
|
||||
inq_cp->mode = 0x02;
|
||||
err = bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_INQUIRY_MODE, buf, NULL);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
@ -2451,6 +2492,7 @@ static int set_event_mask(void)
|
|||
memset(ev, 0, sizeof(*ev));
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||
ev->events[0] |= 0x01; /* Inquiry Complete */
|
||||
ev->events[0] |= 0x04; /* Connection Complete */
|
||||
ev->events[0] |= 0x08; /* Connection Request */
|
||||
ev->events[2] |= 0x20; /* Pin Code Request */
|
||||
|
@ -2925,6 +2967,85 @@ struct net_buf *bt_buf_get_acl(void)
|
|||
}
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||
static int br_start_inquiry(bool limited)
|
||||
{
|
||||
const uint8_t iac[3] = { 0x33, 0x8b, 0x9e };
|
||||
struct bt_hci_op_inquiry *cp;
|
||||
struct net_buf *buf;
|
||||
|
||||
buf = bt_hci_cmd_create(BT_HCI_OP_INQUIRY, sizeof(*cp));
|
||||
if (!buf) {
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
cp = net_buf_add(buf, sizeof(*cp));
|
||||
|
||||
/* do inquiry for maximum allowed time without results limit */
|
||||
cp->length = 0x30;
|
||||
cp->num_rsp = 0x00;
|
||||
|
||||
memcpy(cp->lap, iac, 3);
|
||||
if (limited) {
|
||||
cp->lap[0] = 0x00;
|
||||
}
|
||||
|
||||
return bt_hci_cmd_send_sync(BT_HCI_OP_INQUIRY, buf, NULL);
|
||||
}
|
||||
|
||||
int bt_br_discovery_start(const struct bt_br_discovery_param *param,
|
||||
struct bt_br_discovery_result *results, size_t cnt,
|
||||
bt_br_discovery_cb_t cb)
|
||||
{
|
||||
int err;
|
||||
|
||||
BT_DBG("");
|
||||
|
||||
if (atomic_test_bit(bt_dev.flags, BT_DEV_INQUIRY)) {
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
err = br_start_inquiry(param->limited_discovery);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
atomic_set_bit(bt_dev.flags, BT_DEV_INQUIRY);
|
||||
|
||||
memset(results, 0, sizeof(*results) * cnt);
|
||||
|
||||
discovery_cb = cb;
|
||||
discovery_results = results;
|
||||
discovery_results_size = cnt;
|
||||
discovery_results_count = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_br_discovery_stop(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
BT_DBG("");
|
||||
|
||||
if (!atomic_test_bit(bt_dev.flags, BT_DEV_INQUIRY)) {
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
err = bt_hci_cmd_send_sync(BT_HCI_OP_INQUIRY_CANCEL, NULL, NULL);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
atomic_clear_bit(bt_dev.flags, BT_DEV_INQUIRY);
|
||||
|
||||
discovery_cb = NULL;
|
||||
discovery_results = NULL;
|
||||
discovery_results_size = 0;
|
||||
discovery_results_count = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int write_scan_enable(uint8_t scan)
|
||||
{
|
||||
struct net_buf *buf;
|
||||
|
|
|
@ -36,6 +36,7 @@ enum {
|
|||
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||
BT_DEV_ISCAN,
|
||||
BT_DEV_PSCAN,
|
||||
BT_DEV_INQUIRY,
|
||||
#endif /* CONFIG_BLUETOOTH_BREDR */
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue