diff --git a/include/bluetooth/bluetooth.h b/include/bluetooth/bluetooth.h index dfec4fb6928..ab8fe320f0c 100644 --- a/include/bluetooth/bluetooth.h +++ b/include/bluetooth/bluetooth.h @@ -443,6 +443,32 @@ struct bt_le_scan_param { u16_t window; }; +/** LE advertisement packet information */ +struct bt_le_adv_info { + /** Advertiser LE address and type */ + const bt_addr_le_t *addr; + + /** Strength of advertiser signal */ + s8_t rssi; + + /** Advertising packet type */ + u8_t adv_type; +}; + +/** Listener context for (LE) scanning. */ +struct bt_le_scan_cb { + + /** @brief Advertisement packet received callback. + * + * @param info Advertiser packet information. + * @param buf Buffer containing advertiser data. + */ + void (*recv)(const struct bt_le_adv_info *info, + struct net_buf_simple *buf); + + sys_snode_t node; +}; + /** Helper to declare scan parameters inline * * @param _type Scan Type, BT_LE_SCAN_TYPE_ACTIVE or @@ -481,7 +507,8 @@ struct bt_le_scan_param { * the specified callback. * * @param param Scan parameters. - * @param cb Callback to notify scan results. + * @param cb Callback to notify scan results. May be NULL if callback + * registration through @ref bt_le_scan_cb_register is preferred. * * @return Zero on success or error code otherwise, positive in case * of protocol error or negative (POSIX) in case of stack internal error @@ -497,6 +524,18 @@ 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 Register scanner packet callbacks. + * + * Adds the callback structure to the list of callback structures that monitors + * scanner activity. + * + * This callback will be called for all scanner activity, regardless of what + * API was used to start the scanner. + * + * @param cb Callback struct. Must point to static memory. + */ +void bt_le_scan_cb_register(struct bt_le_scan_cb *cb); + /** @brief Add device (LE) to whitelist. * * Add peer device LE address to the whitelist. diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 0ee4a367119..85586ebcc86 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -83,6 +83,10 @@ static bt_ready_cb_t ready_cb; static bt_le_scan_cb_t *scan_dev_found_cb; +#if defined(CONFIG_BT_OBSERVER) +static sys_slist_t scan_cbs = SYS_SLIST_STATIC_INIT(&scan_cbs); +#endif + #if defined(CONFIG_BT_HCI_VS_EVT_USER) static bt_hci_vnd_evt_cb_t *hci_vnd_evt_cb; #endif /* CONFIG_BT_HCI_VS_EVT_USER */ @@ -3662,6 +3666,9 @@ static void le_adv_report(struct net_buf *buf) BT_DBG("Adv number of reports %u", num_reports); while (num_reports--) { + struct bt_le_scan_cb *cb; + struct net_buf_simple_state state; + struct bt_le_adv_info adv_info; bt_addr_le_t id_addr; s8_t rssi; @@ -3687,9 +3694,11 @@ static void le_adv_report(struct net_buf *buf) &info->addr)); } - if (scan_dev_found_cb) { - struct net_buf_simple_state state; + adv_info.addr = &id_addr; + adv_info.adv_type = info->evt_type; + adv_info.rssi = rssi; + if (scan_dev_found_cb) { net_buf_simple_save(&buf->b, &state); buf->len = info->length; @@ -3699,6 +3708,15 @@ static void le_adv_report(struct net_buf *buf) net_buf_simple_restore(&buf->b, &state); } + SYS_SLIST_FOR_EACH_CONTAINER(&scan_cbs, cb, node) { + net_buf_simple_save(&buf->b, &state); + + buf->len = info->length; + cb->recv(&adv_info, &buf->b); + + net_buf_simple_restore(&buf->b, &state); + } + #if defined(CONFIG_BT_CENTRAL) check_pending_conn(&id_addr, &info->addr, info->evt_type); #endif /* CONFIG_BT_CENTRAL */ @@ -6064,6 +6082,11 @@ int bt_le_scan_stop(void) return bt_le_scan_update(false); } + +void bt_le_scan_cb_register(struct bt_le_scan_cb *cb) +{ + sys_slist_append(&scan_cbs, &cb->node); +} #endif /* CONFIG_BT_OBSERVER */ #if defined(CONFIG_BT_WHITELIST)