Bluetooth: Add helper for parsing advertising data

It is quite easy to implement a buggy or security vulnerable
advertising data parser. Provide a helper for this purpose, which uses
the existing bt_data struct which is used for programming the local
advertising data.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2018-06-26 13:48:56 +03:00 committed by Johan Hedberg
commit 8818244959
2 changed files with 48 additions and 0 deletions

View file

@ -279,6 +279,23 @@ 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 Helper for parsing advertising (or EIR or OOB) data.
*
* A helper for parsing the basic data types used for Extended Inquiry
* Response (EIR), Advertising Data (AD), and OOB data blocks. The most
* common scenario is to call this helper on the adverstising data
* received in the callback that was given to bt_le_scan_start().
*
* @param ad Advertising data as given to the bt_le_scan_cb_t callback.
* @param func Callback function which will be called for each element
* that's found in the data. The callback should return
* true to continue parsing, or false to stop parsing.
* @param user_data User data to be passed to the callback.
*/
void bt_data_parse(struct net_buf_simple *ad,
bool (*func)(struct bt_data *data, void *user_data),
void *user_data);
struct bt_le_oob {
/** LE address. If local privacy is enabled this is Resolvable Private
* Address.

View file

@ -3104,6 +3104,37 @@ int bt_le_scan_update(bool fast_scan)
return 0;
}
void bt_data_parse(struct net_buf_simple *ad,
bool (*func)(struct bt_data *data, void *user_data),
void *user_data)
{
while (ad->len > 1) {
struct bt_data data;
u8_t len;
len = net_buf_simple_pull_u8(ad);
if (len == 0) {
/* Early termination */
return;
}
if (len > ad->len) {
BT_WARN("Malformed data");
return;
}
data.type = net_buf_simple_pull_u8(ad);
data.data_len = len - 1;
data.data = ad->data;
if (!func(&data, user_data)) {
return;
}
net_buf_simple_pull(ad, len - 1);
}
}
static void le_adv_report(struct net_buf *buf)
{
u8_t num_reports = net_buf_pull_u8(buf);