Received: by 2002:a05:6a10:9e8c:0:0:0:0 with SMTP id y12csp3479318pxx; Mon, 2 Nov 2020 09:57:04 -0800 (PST) X-Google-Smtp-Source: ABdhPJx0HbXCJ76rBQ72UTFIRmU5qIdsliuFpw4t2+yduD7kQBAdFd87+V09clfc6ZlITMr28GDt X-Received: by 2002:a05:6402:1119:: with SMTP id u25mr18643547edv.37.1604339824116; Mon, 02 Nov 2020 09:57:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1604339824; cv=none; d=google.com; s=arc-20160816; b=gnhbBPt1HDhiO7bugSbJXf1nByMwbGR2CQjQB4xV8UlNmhZM5TGLI97wVZ4ziJ5F31 8YCjI3x9QiDShiXPRwEjZwfv6LIQs5vjiyaDrlMwYkcwjTCntexXJg1z8ZqdIDoCy1Y9 JmBZEApAwr4bJLM1qzupKDWpcvgpLE8oiyAQB0KpsEsO3AjE6UBcF+vpEu8Aukl/CKde Gb5/7Ox18+hRJytqlBT63r62eX8vwhz7bAw9myGBhF/Tzb0CH0272epdd7rqZterj7Vg pqRW7SGaX/1WIxxqxfgH1qA8MxLbyxQQp8YjsNwup/IdpHiKHH8P2UXj5LcBlpkbbidW oEIQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=9J+2kaBauYF/sB5Ci9b7Cub0G0NBKhvBLjAlByvt+IA=; b=AvVTynEnvhWrjCdIjCv9kjq3bMIbLbWMkqUxnbC7qjbSZBE/kROdKG6qXGydZDVv+F DrkrQ/R4/GSaPMTDrHlCe9XH1PUYJay85ZEMFVZtxUz+IMUfiTmw5Cm5vfj1oWX7Xz6e APKzLJwDTI7mi6GQAbgqg5gMJmTH8T87v+u8hq/bDYNcvZFKhzHFsc9RcQTEXLSju0si djfKpEt1PI/3wCPHjCO7/S2ZWb5NByPK5xot1T/LUrnZoGECF6byjJs2DChMNYSUDT4I GJ8BM9B2/rh5hho/EPJSjVm8VmoUjGTNWBMKl/tsCixUHERRX/6CE4GadNEMv769GM2t UAoA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=IdA00Ypc; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id y24si10592128ejw.503.2020.11.02.09.56.26; Mon, 02 Nov 2020 09:57:04 -0800 (PST) Received-SPF: pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=IdA00Ypc; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725968AbgKBRzr (ORCPT + 99 others); Mon, 2 Nov 2020 12:55:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53192 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725791AbgKBRzq (ORCPT ); Mon, 2 Nov 2020 12:55:46 -0500 Received: from mail-ot1-x341.google.com (mail-ot1-x341.google.com [IPv6:2607:f8b0:4864:20::341]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B546CC0617A6 for ; Mon, 2 Nov 2020 09:55:46 -0800 (PST) Received: by mail-ot1-x341.google.com with SMTP id 79so5958478otc.7 for ; Mon, 02 Nov 2020 09:55:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=9J+2kaBauYF/sB5Ci9b7Cub0G0NBKhvBLjAlByvt+IA=; b=IdA00YpcWdDeRwoOwNhLzc3LKhjJj7Dx1TVz7CGGxCr5W2RC1lOjUe+FxO2Z5b7Gqq skWA9sUzueYWtfjYwDzhmT0hpmuNHFYkjzner7L4DT+JQLA9cFu88M5tkaoXxb0y/8BL TGzoD8kK+KMWeAsNYLLBK629QPukwbHh6GDxiUqYXR/Jcyv2vPN50vuOdbf5G1K2A7+4 07m8OGXymAiIidD8PXidLtclOz1bSmyxdIohx0Ba+y9EPBrGmzyKVMOY7EmelRyyZk4w ynwnpvaBhLu6GWt7lc82VFznWvIfpQ33Z+RB9rS9qMSC5iLc5Ho2mRCty6EXjtOEGVay teIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=9J+2kaBauYF/sB5Ci9b7Cub0G0NBKhvBLjAlByvt+IA=; b=G4lAbYdvwI7SPHy+G5fQL2OmB8vvS/qjPIZmV8SmSKa4nqzs65BXGBMm/1+4niWCFO kNNdkQww8uhDh5pkId+HNGdFygidg3NhdHeHZ3AYB8xkbZZY2QTgUjdtN9hLaM9SMS06 zRTqkRrX3cJ+QxayP1NLHM+4dNgHvKKsqINUDf1+KxAIKcAKuzVlcY3C8+N8a3je+iyl lF/pr/AKTutfP9jrP6Jj7X6bUleqN+jyQrcEofGlte8WxxzzSIFK/tA8uNz+4JNWXBEE jG6ul9NDC4m2cPbik+SsXjAdcA5M8WHWHAu1NB7N4RPbzPjKtkbPA8GKWuSNSgX8FViT oBrQ== X-Gm-Message-State: AOAM530PFkyF33wQHczYDlCEweq10abwwnSGF5hXV/MfB2rR/esiJcid gPtvkY8T7g9Qs59Xq9t97P85slN4go1F687LLxg= X-Received: by 2002:a9d:1a9:: with SMTP id e38mr5370708ote.240.1604339746018; Mon, 02 Nov 2020 09:55:46 -0800 (PST) MIME-Version: 1.0 References: <20201030175219.BlueZ.v8.1.Ie670925d87068d24a6e5c2e7dd9dd0e88c89a7da@changeid> In-Reply-To: <20201030175219.BlueZ.v8.1.Ie670925d87068d24a6e5c2e7dd9dd0e88c89a7da@changeid> From: Luiz Augusto von Dentz Date: Mon, 2 Nov 2020 09:55:35 -0800 Message-ID: Subject: Re: [BlueZ PATCH v8 1/6] shared/ad: Add support of bt_ad_pattern To: Miao-chen Chou Cc: Bluetooth Kernel Mailing List , Alain Michaud , Manish Mandlik , Marcel Holtmann , ChromeOS Bluetooth Upstreaming , Howard Chung , Luiz Augusto von Dentz , Archie Pusaka , Sonny Sasaka Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Hi Miao, On Fri, Oct 30, 2020 at 5:56 PM Miao-chen Chou wrote: > > This adds struct bt_ad_pattern and helpers functions to facilitate > pattern matching. > > Reviewed-by: Archie Pusaka > Reviewed-by: Sonny Sasaka > Reviewed-by: Howard Chung > --- > > Changes in v8: > - Modify signature of ad_replace_data() to avoid memory copy > > src/shared/ad.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++- > src/shared/ad.h | 16 +++++ > 2 files changed, 166 insertions(+), 1 deletion(-) > > diff --git a/src/shared/ad.c b/src/shared/ad.c > index a34d7a147..23c8c34f4 100644 > --- a/src/shared/ad.c > +++ b/src/shared/ad.c > @@ -31,6 +31,12 @@ struct bt_ad { > struct queue *data; > }; > > +struct pattern_match_info { > + struct bt_ad *ad; > + struct bt_ad_pattern *current_pattern; > + struct bt_ad_pattern *matched_pattern; > +}; > + > struct bt_ad *bt_ad_new(void) > { > struct bt_ad *ad; > @@ -46,6 +52,65 @@ struct bt_ad *bt_ad_new(void) > return bt_ad_ref(ad); > } > > +static bool ad_replace_data(struct bt_ad *ad, uint8_t type, const void *data, > + size_t len); > + > +static bool ad_is_type_valid(uint8_t type) > +{ > + if (type > BT_AD_3D_INFO_DATA && type != BT_AD_MANUFACTURER_DATA) > + return false; > + if (type < BT_AD_FLAGS) > + return false; > + > + return true; > +} > + > +struct bt_ad *bt_ad_new_with_data(size_t len, const uint8_t *data) > +{ > + struct bt_ad *ad; > + uint16_t parsed_len = 0; > + > + if (data == NULL || !len) > + return NULL; > + > + ad = bt_ad_new(); > + if (!ad) > + return NULL; > + > + while (parsed_len < len - 1) { > + uint8_t d_len; > + uint8_t d_type; > + const uint8_t *d; > + uint8_t field_len = data[0]; > + > + if (field_len == 0) > + break; > + > + parsed_len += field_len + 1; > + > + if (parsed_len > len) > + break; > + > + d = &data[2]; > + d_type = data[1]; > + d_len = field_len - 1; > + > + if (!ad_is_type_valid(d_type)) > + goto failed; > + > + if (!ad_replace_data(ad, d_type, d, d_len)) > + goto failed; > + > + data += field_len + 1; > + } > + > + return ad; > + > +failed: > + bt_ad_unref(ad); > + return NULL; > +} > + > struct bt_ad *bt_ad_ref(struct bt_ad *ad) > { > if (!ad) > @@ -126,7 +191,7 @@ static bool data_type_match(const void *data, const void *user_data) > return a->type == type; > } > > -static bool ad_replace_data(struct bt_ad *ad, uint8_t type, void *data, > +static bool ad_replace_data(struct bt_ad *ad, uint8_t type, const void *data, > size_t len) > { > struct bt_ad_data *new_data; > @@ -994,3 +1059,87 @@ void bt_ad_clear_data(struct bt_ad *ad) > > queue_remove_all(ad->data, NULL, NULL, data_destroy); > } > + > +struct bt_ad_pattern *bt_ad_pattern_new(uint8_t type, size_t offset, size_t len, > + const uint8_t *data) > +{ > + struct bt_ad_pattern *pattern; > + > + if (!data || !len || offset >= BT_AD_MAX_DATA_LEN || > + len > BT_AD_MAX_DATA_LEN || offset + len > BT_AD_MAX_DATA_LEN) { > + return NULL; > + } > + > + if (!ad_is_type_valid(type)) > + return NULL; > + > + pattern = new0(struct bt_ad_pattern, 1); > + if (!pattern) > + return NULL; > + > + pattern->len = len; > + pattern->type = type; > + pattern->offset = offset; > + memcpy(pattern->data, data, len); > + > + return pattern; > +} > + > +static void pattern_ad_data_match(void *data, void *user_data) > +{ > + struct bt_ad_data *ad_data = data; > + struct pattern_match_info *info = user_data; > + struct bt_ad_pattern *pattern; > + > + if (!ad_data || !info) > + return; > + > + if (info->matched_pattern) > + return; > + > + pattern = info->current_pattern; > + > + if (!pattern || ad_data->type != pattern->type) > + return; > + > + if (ad_data->len < pattern->offset + pattern->len) > + return; > + > + if (!memcmp(ad_data->data + pattern->offset, pattern->data, > + pattern->len)) { > + info->matched_pattern = pattern; > + } > +} > + > +static void pattern_match(void *data, void *user_data) > +{ > + struct bt_ad_pattern *pattern = data; > + struct pattern_match_info *info = user_data; > + > + if (!pattern || !info) > + return; > + > + if (info->matched_pattern) > + return; > + > + info->current_pattern = pattern; > + > + bt_ad_foreach_data(info->ad, pattern_ad_data_match, info); > +} > + > +struct bt_ad_pattern *bt_ad_pattern_match(struct bt_ad *ad, > + struct queue *patterns) > +{ > + struct pattern_match_info info; > + > + if (!ad || queue_isempty(patterns)) > + return NULL; > + > + info.ad = ad; > + info.matched_pattern = NULL; > + info.current_pattern = NULL; > + > + queue_foreach(patterns, pattern_match, &info); > + > + return info.matched_pattern; > +} > diff --git a/src/shared/ad.h b/src/shared/ad.h > index 83eacab66..13adcb406 100644 > --- a/src/shared/ad.h > +++ b/src/shared/ad.h > @@ -68,6 +68,7 @@ > typedef void (*bt_ad_func_t)(void *data, void *user_data); > > struct bt_ad; > +struct queue; > > struct bt_ad_manufacturer_data { > uint16_t manufacturer_id; > @@ -87,8 +88,17 @@ struct bt_ad_data { > size_t len; > }; > > +struct bt_ad_pattern { > + uint8_t type; > + uint8_t offset; > + uint8_t len; > + uint8_t data[BT_AD_MAX_DATA_LEN]; > +}; > + > struct bt_ad *bt_ad_new(void); > > +struct bt_ad *bt_ad_new_with_data(size_t len, const uint8_t *data); > + > struct bt_ad *bt_ad_ref(struct bt_ad *ad); > > void bt_ad_unref(struct bt_ad *ad); > @@ -156,3 +166,9 @@ void bt_ad_foreach_data(struct bt_ad *ad, bt_ad_func_t func, void *user_data); > bool bt_ad_remove_data(struct bt_ad *ad, uint8_t type); > > void bt_ad_clear_data(struct bt_ad *ad); > + > +struct bt_ad_pattern *bt_ad_pattern_new(uint8_t type, size_t offset, > + size_t len, const uint8_t *data); > + > +struct bt_ad_pattern *bt_ad_pattern_match(struct bt_ad *ad, > + struct queue *patterns); > -- > 2.26.2 Applied, thanks. -- Luiz Augusto von Dentz