Hi Yun-hao, On Mon, Oct 26, 2020 at 7:27 PM Yun-hao Chung <howardchung@xxxxxxxxxx> wrote: > > Hi Luiz, > > Thanks for the reply. > > On Tue, Oct 27, 2020 at 1:31 AM Luiz Augusto von Dentz <luiz.dentz@xxxxxxxxx> wrote: >> >> Hi Howard, >> >> On Mon, Oct 26, 2020 at 3:20 AM Howard Chung <howardchung@xxxxxxxxxx> wrote: >> > >> > This adds support of variable length parameters in mgmt_config. >> > Also fixed the endian issue. >> > >> > Reviewed-by: Miao-chen Chou <mcchou@xxxxxxxxxxxx> >> > --- >> > >> > Changes in v3: >> > - use iovec to fill buffer >> > >> > Changes in v2: >> > - fix multiple line dereference issue >> > >> > src/adapter.c | 300 +++++++++++++++++++++------------------------- >> > src/main.c | 35 +++++- >> > src/shared/mgmt.c | 42 +++++++ >> > src/shared/mgmt.h | 4 + >> > 4 files changed, 213 insertions(+), 168 deletions(-) >> > >> > diff --git a/src/adapter.c b/src/adapter.c >> > index c0053000ac19..561737bebd33 100644 >> > --- a/src/adapter.c >> > +++ b/src/adapter.c >> > @@ -4163,269 +4163,237 @@ static void probe_devices(void *user_data) >> > device_probe_profiles(device, btd_device_get_uuids(device)); >> > } >> > >> > +static void set_mgmt_tlv(struct iovec *iov, uint16_t type, uint8_t length, >> > + void *value) >> > +{ >> > + struct mgmt_tlv *entry; >> > + size_t iov_size; >> > + >> > + iov_size = sizeof(struct mgmt_tlv) + length; >> > + iov->iov_base = g_malloc(iov_size); >> > + iov->iov_len = iov_size; >> > + >> > + entry = (struct mgmt_tlv *)iov->iov_base; >> > + entry->type = htobs(type); >> > + entry->length = length; >> > + memcpy(entry->value, value, length); >> >> Perhaps it is better to have such helper in mgmt.c e.g. mgmt_tlv_new, >> mgmt_tlv_free, etc. >> >> > +} >> > + >> > static void load_default_system_params(struct btd_adapter *adapter) >> > { >> > - struct { >> > - struct mgmt_tlv entry; >> > - union { >> > - uint16_t u16; >> > - }; >> > - } __packed *params; >> > - uint16_t i = 0; >> > - size_t len = 0; >> > + struct iovec iovs[main_opts.default_params.num_entries]; >> > + int cnt = 0, i; >> > unsigned int err; >> > >> > if (!main_opts.default_params.num_entries || >> > !btd_has_kernel_features(KERNEL_SET_SYSTEM_CONFIG)) >> > return; >> > >> > - params = malloc0(sizeof(*params) * >> > - main_opts.default_params.num_entries); >> > - >> > - len = sizeof(params->entry) * main_opts.default_params.num_entries; >> > - >> > if (main_opts.default_params.br_page_scan_type != 0xFFFF) { >> > - params[i].entry.type = 0x0000; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = main_opts.default_params.br_page_scan_type; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0000, >> > + sizeof(main_opts.default_params.br_page_scan_type), >> > + &main_opts.default_params.br_page_scan_type); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.br_page_scan_interval) { >> > - params[i].entry.type = 0x0001; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = main_opts.default_params.br_page_scan_interval; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0001, >> > + sizeof(main_opts.default_params.br_page_scan_interval), >> > + &main_opts.default_params.br_page_scan_interval); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.br_page_scan_win) { >> > - params[i].entry.type = 0x0002; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = main_opts.default_params.br_page_scan_win; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0002, >> > + sizeof(main_opts.default_params.br_page_scan_win), >> > + &main_opts.default_params.br_page_scan_win); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.br_scan_type != 0xFFFF) { >> > - params[i].entry.type = 0x0003; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = main_opts.default_params.br_scan_type; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0003, >> > + sizeof(main_opts.default_params.br_scan_type), >> > + &main_opts.default_params.br_scan_type); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.br_scan_interval) { >> > - params[i].entry.type = 0x0004; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = main_opts.default_params.br_scan_interval; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0004, >> > + sizeof(main_opts.default_params.br_scan_interval), >> > + &main_opts.default_params.br_scan_interval); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.br_scan_win) { >> > - params[i].entry.type = 0x0005; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = main_opts.default_params.br_scan_win; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0005, >> > + sizeof(main_opts.default_params.br_scan_win), >> > + &main_opts.default_params.br_scan_win); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.br_link_supervision_timeout) { >> > - params[i].entry.type = 0x0006; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = >> > - main_opts.default_params.br_link_supervision_timeout; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0006, >> > + sizeof(main_opts.default_params.br_link_supervision_timeout), >> > + &main_opts.default_params.br_link_supervision_timeout); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.br_page_timeout) { >> > - params[i].entry.type = 0x0007; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = main_opts.default_params.br_page_timeout; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0007, >> > + sizeof(main_opts.default_params.br_page_timeout), >> > + &main_opts.default_params.br_page_timeout); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.br_min_sniff_interval) { >> > - params[i].entry.type = 0x0008; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = main_opts.default_params.br_min_sniff_interval; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0008, >> > + sizeof(main_opts.default_params.br_min_sniff_interval), >> > + &main_opts.default_params.br_min_sniff_interval); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.br_max_sniff_interval) { >> > - params[i].entry.type = 0x0009; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = main_opts.default_params.br_max_sniff_interval; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0009, >> > + sizeof(main_opts.default_params.br_max_sniff_interval), >> > + &main_opts.default_params.br_max_sniff_interval); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.le_min_adv_interval) { >> > - params[i].entry.type = 0x000a; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = main_opts.default_params.le_min_adv_interval; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x000a, >> > + sizeof(main_opts.default_params.le_min_adv_interval), >> > + &main_opts.default_params.le_min_adv_interval); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.le_max_adv_interval) { >> > - params[i].entry.type = 0x000b; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = main_opts.default_params.le_max_adv_interval; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x000b, >> > + sizeof(main_opts.default_params.le_max_adv_interval), >> > + &main_opts.default_params.le_max_adv_interval); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.le_multi_adv_rotation_interval) { >> > - params[i].entry.type = 0x000c; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = >> > - main_opts.default_params.le_multi_adv_rotation_interval; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x000c, >> > + sizeof(main_opts.default_params.le_multi_adv_rotation_interval), >> > + &main_opts.default_params.le_multi_adv_rotation_interval); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.le_scan_interval_autoconnect) { >> > - params[i].entry.type = 0x000d; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = >> > - main_opts.default_params.le_scan_interval_autoconnect; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x000d, >> > + sizeof(main_opts.default_params.le_scan_interval_autoconnect), >> > + &main_opts.default_params.le_scan_interval_autoconnect); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.le_scan_win_autoconnect) { >> > - params[i].entry.type = 0x000e; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = >> > - main_opts.default_params.le_scan_win_autoconnect; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x000e, >> > + sizeof(main_opts.default_params.le_scan_win_autoconnect), >> > + &main_opts.default_params.le_scan_win_autoconnect); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.le_scan_interval_suspend) { >> > - params[i].entry.type = 0x000f; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = >> > - main_opts.default_params.le_scan_interval_suspend; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x000f, >> > + sizeof(main_opts.default_params.le_scan_interval_suspend), >> > + &main_opts.default_params.le_scan_interval_suspend); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.le_scan_win_suspend) { >> > - params[i].entry.type = 0x0010; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = main_opts.default_params.le_scan_win_suspend; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0010, >> > + sizeof(main_opts.default_params.le_scan_win_suspend), >> > + &main_opts.default_params.le_scan_win_suspend); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.le_scan_interval_discovery) { >> > - params[i].entry.type = 0x0011; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = >> > - main_opts.default_params.le_scan_interval_discovery; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0011, >> > + sizeof(main_opts.default_params.le_scan_interval_discovery), >> > + &main_opts.default_params.le_scan_interval_discovery); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.le_scan_win_discovery) { >> > - params[i].entry.type = 0x0012; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = >> > - main_opts.default_params.le_scan_win_discovery; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0012, >> > + sizeof(main_opts.default_params.le_scan_win_discovery), >> > + &main_opts.default_params.le_scan_win_discovery); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.le_scan_interval_adv_monitor) { >> > - params[i].entry.type = 0x0013; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = >> > - main_opts.default_params.le_scan_interval_adv_monitor; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0013, >> > + sizeof(main_opts.default_params.le_scan_interval_adv_monitor), >> > + &main_opts.default_params.le_scan_interval_adv_monitor); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.le_scan_win_adv_monitor) { >> > - params[i].entry.type = 0x0014; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = >> > - main_opts.default_params.le_scan_win_adv_monitor; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0014, >> > + sizeof(main_opts.default_params.le_scan_win_adv_monitor), >> > + &main_opts.default_params.le_scan_win_adv_monitor); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.le_scan_interval_connect) { >> > - params[i].entry.type = 0x0015; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = >> > - main_opts.default_params.le_scan_interval_connect; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0015, >> > + sizeof(main_opts.default_params.le_scan_interval_connect), >> > + &main_opts.default_params.le_scan_interval_connect); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.le_scan_win_connect) { >> > - params[i].entry.type = 0x0016; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = main_opts.default_params.le_scan_win_connect; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0016, >> > + sizeof(main_opts.default_params.le_scan_win_connect), >> > + &main_opts.default_params.le_scan_win_connect); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.le_min_conn_interval) { >> > - params[i].entry.type = 0x0017; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = main_opts.default_params.le_min_conn_interval; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0017, >> > + sizeof(main_opts.default_params.le_min_conn_interval), >> > + &main_opts.default_params.le_min_conn_interval); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.le_max_conn_interval) { >> > - params[i].entry.type = 0x0018; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = main_opts.default_params.le_max_conn_interval; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0018, >> > + sizeof(main_opts.default_params.le_max_conn_interval), >> > + &main_opts.default_params.le_max_conn_interval); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.le_conn_latency) { >> > - params[i].entry.type = 0x0019; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = main_opts.default_params.le_conn_latency; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x0019, >> > + sizeof(main_opts.default_params.le_conn_latency), >> > + &main_opts.default_params.le_conn_latency); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.le_conn_lsto) { >> > - params[i].entry.type = 0x001a; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = main_opts.default_params.le_conn_lsto; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x001a, >> > + sizeof(main_opts.default_params.le_conn_lsto), >> > + &main_opts.default_params.le_conn_lsto); >> > + cnt++; >> > } >> > >> > if (main_opts.default_params.le_autoconnect_timeout) { >> > - params[i].entry.type = 0x001b; >> > - params[i].entry.length = sizeof(params[i].u16); >> > - params[i].u16 = main_opts.default_params.le_autoconnect_timeout; >> > - ++i; >> > - len += sizeof(params[i].u16); >> > + set_mgmt_tlv(iovs + cnt, 0x001b, >> > + sizeof(main_opts.default_params.le_autoconnect_timeout), >> > + &main_opts.default_params.le_autoconnect_timeout); >> > + cnt++; >> > } >> > >> > - err = mgmt_send(adapter->mgmt, MGMT_OP_SET_DEF_SYSTEM_CONFIG, >> > - adapter->dev_id, len, params, NULL, NULL, NULL); >> > + err = mgmt_sendv(adapter->mgmt, MGMT_OP_SET_DEF_SYSTEM_CONFIG, >> > + adapter->dev_id, cnt, iovs, NULL, NULL, NULL); >> > if (!err) >> > btd_error(adapter->dev_id, >> > "Failed to set default system config for hci%u", >> > adapter->dev_id); >> > >> > - free(params); >> > + for (i = 0; i < cnt; i++) >> > + g_free(iovs[i].iov_base); >> > } >> > >> > static void load_devices(struct btd_adapter *adapter) >> > diff --git a/src/main.c b/src/main.c >> > index 77be776686a8..b83f7bffb485 100644 >> > --- a/src/main.c >> > +++ b/src/main.c >> > @@ -305,120 +305,149 @@ static void parse_controller_config(GKeyFile *config) >> > { >> > static const struct { >> > const char * const val_name; >> > - uint16_t * const val; >> > + void * const val; >> > + const size_t size; >> > const uint16_t min; >> > const uint16_t max; >> > } params[] = { >> > { "BRPageScanType", >> > &main_opts.default_params.br_page_scan_type, >> > + sizeof(main_opts.default_params.br_page_scan_type), >> > 0, >> > 1}, >> > { "BRPageScanInterval", >> > &main_opts.default_params.br_page_scan_interval, >> > + sizeof(main_opts.default_params.br_page_scan_interval), >> > 0x0012, >> > 0x1000}, >> > { "BRPageScanWindow", >> > &main_opts.default_params.br_page_scan_win, >> > + sizeof(main_opts.default_params.br_page_scan_win), >> > 0x0011, >> > 0x1000}, >> > { "BRInquiryScanType", >> > &main_opts.default_params.br_scan_type, >> > + sizeof(main_opts.default_params.br_scan_type), >> > 0, >> > 1}, >> > { "BRInquiryScanInterval", >> > &main_opts.default_params.br_scan_interval, >> > + sizeof(main_opts.default_params.br_scan_interval), >> > 0x0012, >> > 0x1000}, >> > { "BRInquiryScanWindow", >> > &main_opts.default_params.br_scan_win, >> > + sizeof(main_opts.default_params.br_scan_win), >> > 0x0011, >> > 0x1000}, >> > { "BRLinkSupervisionTimeout", >> > &main_opts.default_params.br_link_supervision_timeout, >> > + sizeof(main_opts.default_params.br_link_supervision_timeout), >> > 0x0001, >> > 0xFFFF}, >> > { "BRPageTimeout", >> > &main_opts.default_params.br_page_timeout, >> > + sizeof(main_opts.default_params.br_page_scan_win), >> > 0x0001, >> > 0xFFFF}, >> > { "BRMinSniffInterval", >> > &main_opts.default_params.br_min_sniff_interval, >> > + sizeof(main_opts.default_params.br_min_sniff_interval), >> > 0x0001, >> > 0xFFFE}, >> > { "BRMaxSniffInterval", >> > &main_opts.default_params.br_max_sniff_interval, >> > + sizeof(main_opts.default_params.br_max_sniff_interval), >> > 0x0001, >> > 0xFFFE}, >> > { "LEMinAdvertisementInterval", >> > &main_opts.default_params.le_min_adv_interval, >> > + sizeof(main_opts.default_params.le_min_adv_interval), >> > 0x0020, >> > 0x4000}, >> > { "LEMaxAdvertisementInterval", >> > &main_opts.default_params.le_max_adv_interval, >> > + sizeof(main_opts.default_params.le_max_adv_interval), >> > 0x0020, >> > 0x4000}, >> > { "LEMultiAdvertisementRotationInterval", >> > &main_opts.default_params.le_multi_adv_rotation_interval, >> > + sizeof(main_opts.default_params.le_multi_adv_rotation_interval), >> > 0x0001, >> > 0xFFFF}, >> > { "LEScanIntervalAutoConnect", >> > &main_opts.default_params.le_scan_interval_autoconnect, >> > + sizeof(main_opts.default_params.le_scan_interval_autoconnect), >> > 0x0004, >> > 0x4000}, >> > { "LEScanWindowAutoConnect", >> > &main_opts.default_params.le_scan_win_autoconnect, >> > + sizeof(main_opts.default_params.le_scan_win_autoconnect), >> > 0x0004, >> > 0x4000}, >> > { "LEScanIntervalSuspend", >> > &main_opts.default_params.le_scan_interval_suspend, >> > + sizeof(main_opts.default_params.le_scan_interval_suspend), >> > 0x0004, >> > 0x4000}, >> > { "LEScanWindowSuspend", >> > &main_opts.default_params.le_scan_win_suspend, >> > + sizeof(main_opts.default_params.le_scan_win_suspend), >> > 0x0004, >> > 0x4000}, >> > { "LEScanIntervalDiscovery", >> > &main_opts.default_params.le_scan_interval_discovery, >> > + sizeof(main_opts.default_params.le_scan_interval_discovery), >> > 0x0004, >> > 0x4000}, >> > { "LEScanWindowDiscovery", >> > &main_opts.default_params.le_scan_win_discovery, >> > + sizeof(main_opts.default_params.le_scan_win_discovery), >> > 0x0004, >> > 0x4000}, >> > { "LEScanIntervalAdvMonitor", >> > &main_opts.default_params.le_scan_interval_adv_monitor, >> > + sizeof(main_opts.default_params.le_scan_interval_adv_monitor), >> > 0x0004, >> > 0x4000}, >> > { "LEScanWindowAdvMonitor", >> > &main_opts.default_params.le_scan_win_adv_monitor, >> > + sizeof(main_opts.default_params.le_scan_win_adv_monitor), >> > 0x0004, >> > 0x4000}, >> > { "LEScanIntervalConnect", >> > &main_opts.default_params.le_scan_interval_connect, >> > + sizeof(main_opts.default_params.le_scan_interval_connect), >> > 0x0004, >> > 0x4000}, >> > { "LEScanWindowConnect", >> > &main_opts.default_params.le_scan_win_connect, >> > + sizeof(main_opts.default_params.le_scan_win_connect), >> > 0x0004, >> > 0x4000}, >> > { "LEMinConnectionInterval", >> > &main_opts.default_params.le_min_conn_interval, >> > + sizeof(main_opts.default_params.le_min_conn_interval), >> > 0x0006, >> > 0x0C80}, >> > { "LEMaxConnectionInterval", >> > &main_opts.default_params.le_max_conn_interval, >> > + sizeof(main_opts.default_params.le_max_conn_interval), >> > 0x0006, >> > 0x0C80}, >> > { "LEConnectionLatency", >> > &main_opts.default_params.le_conn_latency, >> > + sizeof(main_opts.default_params.le_conn_latency), >> > 0x0000, >> > 0x01F3}, >> > { "LEConnectionSupervisionTimeout", >> > &main_opts.default_params.le_conn_lsto, >> > + sizeof(main_opts.default_params.le_conn_lsto), >> > 0x000A, >> > 0x0C80}, >> > { "LEAutoconnecttimeout", >> > &main_opts.default_params.le_autoconnect_timeout, >> > + sizeof(main_opts.default_params.le_autoconnect_timeout), >> > 0x0001, >> > 0x4000}, >> > }; >> > @@ -439,7 +468,9 @@ static void parse_controller_config(GKeyFile *config) >> > >> > val = MAX(val, params[i].min); >> > val = MIN(val, params[i].max); >> > - *params[i].val = val; >> > + >> > + val = htobl(val); >> > + memcpy(params[i].val, &val, params[i].size); >> > ++main_opts.default_params.num_entries; >> > } >> > } >> > diff --git a/src/shared/mgmt.c b/src/shared/mgmt.c >> > index b327b4088c6f..c6560e9c265b 100644 >> > --- a/src/shared/mgmt.c >> > +++ b/src/shared/mgmt.c >> > @@ -558,6 +558,48 @@ static struct mgmt_request *create_request(uint16_t opcode, uint16_t index, >> > return request; >> > } >> > >> > +unsigned int mgmt_sendv(struct mgmt *mgmt, uint16_t opcode, uint16_t index, >> > + int count, void *iovecs, >> > + mgmt_request_func_t callback, >> > + void *user_data, mgmt_destroy_func_t destroy) >> > +{ >> > + FILE *ptr = NULL; >> > + int fd; >> > + uint8_t *buf = NULL; >> > + uint16_t buf_len; >> > + unsigned int ret = 0; >> > + >> > + ptr = tmpfile(); >> >> Not sure what is the intent with the tempory file here, we can in fact >> use writev/sendmsg with the MGMT socket directly, in fact we do use >> io_send that takes an iov but it looks like we would have to copy the >> iovs since it does the transfer asynchronously in that case perhaps it >> is not efficient to pass an iov array, except if we do want to check >> if we can write right away thus avoiding the alloc + memcpy >> everywhere. >> >> To make the API perhaps have all the TLVs combined in a single iov, >> e.g. mgmt_tlv_add(iov), to make it simpler to copy if we cannot send > > > If we combined all the TLV in a single iov, then I guess that makes no > difference than using a buffer to accommodate each entry manually. > How about we store each TLV in a different iov and simply call > mgmt_tlv_add(iov) for each TLV? Like I said this wouldn't avoid the memcpy which was why I suggested using iovec in the first place, but moving the TLV logic to mgmt.c is probably a good idea anyway since it makes it easier to be shared with the likes of btmgmt, etc. >> >> the message directly, also please split the mgmt.c chances from the >> daemon changes. >> >> > + >> > + if (!ptr) >> > + goto done; >> > + >> > + fd = fileno(ptr); >> > + buf_len = writev(fd, (struct iovec *)iovecs, count); >> > + >> > + if (buf_len < 0) >> > + goto done; >> > + >> > + buf = malloc(buf_len); >> > + >> > + if (!buf) >> > + goto done; >> > + >> > + rewind(ptr); >> > + if (fread(buf, 1, buf_len, ptr) < buf_len) >> > + goto done; >> > + >> > + ret = mgmt_send(mgmt, opcode, index, buf_len, buf, callback, user_data, >> > + destroy); >> > + >> > +done: >> > + if (ptr) >> > + fclose(ptr); >> > + if (buf) >> > + free(buf); >> > + return ret; >> > +} >> > + >> > unsigned int mgmt_send(struct mgmt *mgmt, uint16_t opcode, uint16_t index, >> > uint16_t length, const void *param, >> > mgmt_request_func_t callback, >> > diff --git a/src/shared/mgmt.h b/src/shared/mgmt.h >> > index 6608faa7ed0f..87158ebc3774 100644 >> > --- a/src/shared/mgmt.h >> > +++ b/src/shared/mgmt.h >> > @@ -33,6 +33,10 @@ bool mgmt_set_close_on_unref(struct mgmt *mgmt, bool do_close); >> > typedef void (*mgmt_request_func_t)(uint8_t status, uint16_t length, >> > const void *param, void *user_data); >> > >> > +unsigned int mgmt_sendv(struct mgmt *mgmt, uint16_t opcode, uint16_t index, >> > + int count, void *iovecs, >> > + mgmt_request_func_t callback, >> > + void *user_data, mgmt_destroy_func_t destroy); >> > unsigned int mgmt_send(struct mgmt *mgmt, uint16_t opcode, uint16_t index, >> > uint16_t length, const void *param, >> > mgmt_request_func_t callback, >> > -- >> > 2.29.0.rc1.297.gfa9743e501-goog >> > >> >> >> -- >> Luiz Augusto von Dentz -- Luiz Augusto von Dentz