2020-12-28 11:37:14

by Yun-hao Chung

[permalink] [raw]
Subject: [Bluez PATCH v3 1/4] shared/mgmt: Add supports of parsing mgmt tlv list

Response from Read System Default Configuration is a list of mgmt_tlv,
which requires further processing to get the values of each parameters.

This adds APIs for parsing response into mgmt_tlv_list, retrieving
parameter from mgmt_tlv_list.

Reviewed-by: [email protected]
---

Changes in v3:
- Fix CheckBuild error

Changes in v2:
- Fix incompatible pointer type error in mgmt_tlv_list_load_from_buf

src/shared/mgmt.c | 38 ++++++++++++++++++++++++++++++++++++++
src/shared/mgmt.h | 6 ++++++
2 files changed, 44 insertions(+)

diff --git a/src/shared/mgmt.c b/src/shared/mgmt.c
index 9ea9974f5535..dc8107846668 100644
--- a/src/shared/mgmt.c
+++ b/src/shared/mgmt.c
@@ -626,6 +626,44 @@ static void mgmt_tlv_to_buf(void *data, void *user_data)
*buf_ptr += entry_size;
}

+struct mgmt_tlv_list *mgmt_tlv_list_load_from_buf(const uint8_t *buf,
+ uint16_t len)
+{
+ struct mgmt_tlv_list *tlv_list;
+ const uint8_t *cur = buf;
+
+ if (!len || !buf)
+ return NULL;
+
+ tlv_list = mgmt_tlv_list_new();
+
+ while (cur < buf + len) {
+ struct mgmt_tlv *entry = (struct mgmt_tlv *)cur;
+
+ cur += sizeof(*entry) + entry->length;
+ if (cur > buf + len)
+ goto failed;
+
+ if (!mgmt_tlv_add(tlv_list, entry->type, entry->length,
+ entry->value)) {
+ goto failed;
+ }
+ }
+
+ return tlv_list;
+failed:
+ mgmt_tlv_list_free(tlv_list);
+
+ return NULL;
+}
+
+void mgmt_tlv_list_foreach(struct mgmt_tlv_list *tlv_list,
+ mgmt_tlv_list_foreach_func_t callback,
+ void *user_data)
+{
+ queue_foreach(tlv_list->tlv_queue, callback, user_data);
+}
+
unsigned int mgmt_send_tlv(struct mgmt *mgmt, uint16_t opcode, uint16_t index,
struct mgmt_tlv_list *tlv_list,
mgmt_request_func_t callback,
diff --git a/src/shared/mgmt.h b/src/shared/mgmt.h
index 319beb62f9eb..808bf4c7ff09 100644
--- a/src/shared/mgmt.h
+++ b/src/shared/mgmt.h
@@ -41,6 +41,12 @@ bool mgmt_tlv_add(struct mgmt_tlv_list *tlv_list, uint16_t type, uint8_t length,
#define mgmt_tlv_add_fixed(_list, _type, _value) \
mgmt_tlv_add(_list, _type, sizeof(*(_value)), _value)

+struct mgmt_tlv_list *mgmt_tlv_list_load_from_buf(const uint8_t *buf,
+ uint16_t len);
+typedef void (*mgmt_tlv_list_foreach_func_t)(void *data, void *user_data);
+void mgmt_tlv_list_foreach(struct mgmt_tlv_list *tlv_list,
+ mgmt_tlv_list_foreach_func_t callback,
+ void *user_data);
unsigned int mgmt_send_tlv(struct mgmt *mgmt, uint16_t opcode, uint16_t index,
struct mgmt_tlv_list *tlv_list,
mgmt_request_func_t callback,
--
2.29.2.729.g45daf8777d-goog


2020-12-28 11:37:13

by Yun-hao Chung

[permalink] [raw]
Subject: [Bluez PATCH v3 2/4] btmgmt: Add command read-sysconfig

Add command read-sysconfig in btmgmt

Example usage:
localhost ~ # btmgmt
[mgmt]# read-sysconfig
Type: 0x0000 Length: 02 Value: 0000
Type: 0x0001 Length: 02 Value: 0008
...
Type: 0x001f Length: 01 Value: 01

Reviewed-by: [email protected]
---

Changes in v3:
- Removed unused variable in read_sysconfig_rsp

tools/btmgmt.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)

diff --git a/tools/btmgmt.c b/tools/btmgmt.c
index 2f7cb2efcc38..7d83d3ee6bd5 100644
--- a/tools/btmgmt.c
+++ b/tools/btmgmt.c
@@ -1752,6 +1752,52 @@ static void cmd_exp_debug(int argc, char **argv)
}
}

+static void print_mgmt_tlv(void *data, void *user_data)
+{
+ const struct mgmt_tlv *entry = data;
+ char buf[256];
+
+ bin2hex(entry->value, entry->length, buf, sizeof(buf));
+ print("Type: 0x%04x\tLength: %02hhu\tValue: %s", entry->type,
+ entry->length, buf);
+}
+
+static void read_sysconfig_rsp(uint8_t status, uint16_t len, const void *param,
+ void *user_data)
+{
+ struct mgmt_tlv_list *tlv_list;
+
+ if (status != 0) {
+ error("Read system configuration failed with status "
+ "0x%02x (%s)", status, mgmt_errstr(status));
+ return;
+ }
+
+ tlv_list = mgmt_tlv_list_load_from_buf(param, len);
+ if (!tlv_list) {
+ error("Unable to parse response of read system configuration");
+ return;
+ }
+
+ mgmt_tlv_list_foreach(tlv_list, print_mgmt_tlv, NULL);
+ mgmt_tlv_list_free(tlv_list);
+}
+
+static void cmd_read_sysconfig(int argc, char **argv)
+{
+ uint16_t index;
+
+ index = mgmt_index;
+ if (index == MGMT_INDEX_NONE)
+ index = 0;
+
+ if (!mgmt_send(mgmt, MGMT_OP_READ_DEF_SYSTEM_CONFIG, index,
+ 0, NULL, read_sysconfig_rsp, NULL, NULL)) {
+ error("Unable to send read system configuration cmd");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+}
+
static void auto_power_enable_rsp(uint8_t status, uint16_t len,
const void *param, void *user_data)
{
@@ -5030,6 +5076,8 @@ static const struct bt_shell_menu main_menu = {
cmd_expinfo, "Show experimental features" },
{ "exp-debug", "<on/off>",
cmd_exp_debug, "Set debug feature" },
+ { "read-sysconfig", NULL,
+ cmd_read_sysconfig, "Read System Configuration" },
{} },
};

--
2.29.2.729.g45daf8777d-goog

2020-12-28 11:37:14

by Yun-hao Chung

[permalink] [raw]
Subject: [Bluez PATCH v3 3/4] btmgmt: Add command set-sysconfig

Add command set-sysconfig in btmgmt

Example usage:
[mgmt]# set-sysconfig -h
Parameters:
-v <type:length:value>...
e.g.:
set-sysconfig -v 001a:2:1234 001f:1:00
[mgmt]# set-sysconfig -v 8:2:abcd 1:02:0100 0016:2:0600

Reviewed-by: [email protected]
---

(no changes since v2)

Changes in v2:
- Replace hard tabs with soft tabs in commit messages

tools/btmgmt.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 109 insertions(+)

diff --git a/tools/btmgmt.c b/tools/btmgmt.c
index 7d83d3ee6bd5..850268b4c322 100644
--- a/tools/btmgmt.c
+++ b/tools/btmgmt.c
@@ -1798,6 +1798,113 @@ static void cmd_read_sysconfig(int argc, char **argv)
}
}

+static bool parse_mgmt_tlv(const char *input, uint16_t *type, uint8_t *length,
+ uint8_t *value)
+{
+ int i, value_starting_pos;
+
+ if (sscanf(input, "%4hx:%1hhu:%n", type, length,
+ &value_starting_pos) < 2) {
+ return false;
+ }
+
+ input += value_starting_pos;
+
+ if (*length * 2 != strlen(input))
+ return false;
+
+ for (i = 0; i < *length; i++) {
+ if (!sscanf(input + i * 2, "%2hhx", &value[i]))
+ return false;
+ }
+
+ return true;
+}
+
+static void set_sysconfig_rsp(uint8_t status, uint16_t len, const void *param,
+ void *user_data)
+{
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Could not set default system configuration with status "
+ "0x%02x (%s)", status, mgmt_errstr(status));
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ print("Set default system configuration success");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+}
+
+static bool set_sysconfig(int argc, char **argv)
+{
+ struct mgmt_tlv_list *tlv_list = NULL;
+ int i;
+ uint16_t index, type;
+ uint8_t length;
+ uint8_t value[256] = {};
+ bool success = false;
+
+ index = mgmt_index;
+ if (index == MGMT_INDEX_NONE)
+ index = 0;
+
+ tlv_list = mgmt_tlv_list_new();
+ if (!tlv_list) {
+ error("tlv_list failed to init");
+ goto failed;
+ }
+
+ for (i = 0; i < argc; i++) {
+ if (!parse_mgmt_tlv(argv[i], &type, &length, value)) {
+ error("failed to parse");
+ goto failed;
+ }
+
+ if (!mgmt_tlv_add(tlv_list, type, length, value)) {
+ error("failed to add");
+ goto failed;
+ }
+ }
+
+ if (!mgmt_send_tlv(mgmt, MGMT_OP_SET_DEF_SYSTEM_CONFIG, index,
+ tlv_list, set_sysconfig_rsp, NULL, NULL)) {
+ error("Failed to send \"Set Default System Configuration\""
+ " command");
+ goto failed;
+ }
+
+ success = true;
+
+failed:
+ if (tlv_list)
+ mgmt_tlv_list_free(tlv_list);
+
+ return success;
+}
+
+static void set_sysconfig_usage(void)
+{
+ bt_shell_usage();
+ print("Parameters:\n\t-v <type:length:value>...\n"
+ "e.g.:\n\tset-sysconfig -v 001a:2:1234 001f:1:00");
+}
+
+static void cmd_set_sysconfig(int argc, char **argv)
+{
+ bool success = false;
+
+ if (strcasecmp(argv[1], "-v") == 0 && argc > 2) {
+ argc -= 2;
+ argv += 2;
+ success = set_sysconfig(argc, argv);
+ }
+
+ if (!success) {
+ set_sysconfig_usage();
+ bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+}
+
static void auto_power_enable_rsp(uint8_t status, uint16_t len,
const void *param, void *user_data)
{
@@ -5078,6 +5185,8 @@ static const struct bt_shell_menu main_menu = {
cmd_exp_debug, "Set debug feature" },
{ "read-sysconfig", NULL,
cmd_read_sysconfig, "Read System Configuration" },
+ { "set-sysconfig", "<-v|-h> [options...]",
+ cmd_set_sysconfig, "Set System Configuration" },
{} },
};

--
2.29.2.729.g45daf8777d-goog

2020-12-28 11:37:14

by Yun-hao Chung

[permalink] [raw]
Subject: [Bluez PATCH v3 4/4] shared/mgmt: Fix memory leak in mgmt_tlv_list

This patch freed the mgmt_tlv properly in mgmt_tlv_list_free.

Reviewed-by: [email protected]
Reviewed-by: [email protected]
---

(no changes since v2)

Changes in v2:
- Fix incompatible pointer type error of mgmt_tlv_free

src/shared/mgmt.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/shared/mgmt.c b/src/shared/mgmt.c
index dc8107846668..0d0c957709d7 100644
--- a/src/shared/mgmt.c
+++ b/src/shared/mgmt.c
@@ -588,14 +588,15 @@ static struct mgmt_tlv *mgmt_tlv_new(uint16_t type, uint8_t length,
return entry;
}

-static void mgmt_tlv_free(struct mgmt_tlv *entry)
+static void mgmt_tlv_free(void *data)
{
+ struct mgmt_tlv *entry = data;
free(entry);
}

void mgmt_tlv_list_free(struct mgmt_tlv_list *tlv_list)
{
- queue_destroy(tlv_list->tlv_queue, NULL);
+ queue_destroy(tlv_list->tlv_queue, mgmt_tlv_free);
free(tlv_list);
}

--
2.29.2.729.g45daf8777d-goog

2020-12-28 12:02:24

by bluez.test.bot

[permalink] [raw]
Subject: RE: [Bluez,v3,1/4] shared/mgmt: Add supports of parsing mgmt tlv list

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=406753

---Test result---

##############################
Test: CheckPatch - FAIL
Output:
btmgmt: Add command set-sysconfig
WARNING:NAKED_SSCANF: unchecked sscanf return value
#42: FILE: tools/btmgmt.c:1817:
+ if (!sscanf(input + i * 2, "%2hhx", &value[i]))
+ return false;

- total: 0 errors, 1 warnings, 121 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.

"[PATCH] btmgmt: Add command set-sysconfig" has style problems, please review.

NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPLIT_STRING SSCANF_TO_KSTRTO

NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.


##############################
Test: CheckGitLint - PASS

##############################
Test: CheckBuild - PASS

##############################
Test: MakeCheck - PASS



---
Regards,
Linux Bluetooth

2021-01-04 07:03:49

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [Bluez PATCH v3 4/4] shared/mgmt: Fix memory leak in mgmt_tlv_list

Hi Howard,

On Mon, Dec 28, 2020 at 3:34 AM Howard Chung <[email protected]> wrote:
>
> This patch freed the mgmt_tlv properly in mgmt_tlv_list_free.
>
> Reviewed-by: [email protected]
> Reviewed-by: [email protected]
> ---
>
> (no changes since v2)
>
> Changes in v2:
> - Fix incompatible pointer type error of mgmt_tlv_free
>
> src/shared/mgmt.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/src/shared/mgmt.c b/src/shared/mgmt.c
> index dc8107846668..0d0c957709d7 100644
> --- a/src/shared/mgmt.c
> +++ b/src/shared/mgmt.c
> @@ -588,14 +588,15 @@ static struct mgmt_tlv *mgmt_tlv_new(uint16_t type, uint8_t length,
> return entry;
> }
>
> -static void mgmt_tlv_free(struct mgmt_tlv *entry)
> +static void mgmt_tlv_free(void *data)
> {
> + struct mgmt_tlv *entry = data;
> free(entry);
> }
>
> void mgmt_tlv_list_free(struct mgmt_tlv_list *tlv_list)
> {
> - queue_destroy(tlv_list->tlv_queue, NULL);
> + queue_destroy(tlv_list->tlv_queue, mgmt_tlv_free);

It might be better to just pass free directly instead of mgmt_tlv_free
since all it does currently is call free anyway.

> free(tlv_list);
> }
>
> --
> 2.29.2.729.g45daf8777d-goog
>


--
Luiz Augusto von Dentz