2018-03-09 07:25:51

by Jaganath K

[permalink] [raw]
Subject: [PATCH 1/4 v1] monitor: Add support PHY management commands and event

---
monitor/packet.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 65 insertions(+)

diff --git a/monitor/packet.c b/monitor/packet.c
index b800a2d..e3b5ab7 100644
--- a/monitor/packet.c
+++ b/monitor/packet.c
@@ -97,6 +97,7 @@
#define COLOR_UNKNOWN_ADDRESS_TYPE COLOR_WHITE_BG
#define COLOR_UNKNOWN_DEVICE_FLAG COLOR_WHITE_BG
#define COLOR_UNKNOWN_ADV_FLAG COLOR_WHITE_BG
+#define COLOR_UNKNOWN_PHY COLOR_WHITE_BG

#define COLOR_PHY_PACKET COLOR_BLUE

@@ -10611,6 +10612,7 @@ static const struct {
{ 13, "Privacy" },
{ 14, "Controller Configuration"},
{ 15, "Static Address" },
+ { 16, "PHY Configuration" },
{ }
};

@@ -11905,6 +11907,54 @@ static void mgmt_set_apperance_cmd(const void *data, uint16_t size)
print_appearance(appearance);
}

+static const struct {
+ uint8_t bit;
+ const char *str;
+} mgmt_phy_table[] = {
+ { 0, "1MTX" },
+ { 1, "1MRX" },
+ { 2, "2MTX" },
+ { 3, "2MRX" },
+ { 4, "CODEDTX" },
+ { 5, "CODEDRX" },
+ { }
+};
+
+static void mgmt_print_phys(const char *label, uint16_t phys)
+{
+ uint16_t mask = phys;
+ int i;
+
+ print_field("%s: 0x%4.4x", label, phys);
+
+ for (i = 0; mgmt_phy_table[i].str; i++) {
+ if (phys & (1 << mgmt_phy_table[i].bit)) {
+ print_field(" %s", mgmt_phy_table[i].str);
+ mask &= ~(1 << mgmt_phy_table[i].bit);
+ }
+ }
+
+ if (mask)
+ print_text(COLOR_UNKNOWN_PHY, " Unknown PHYs"
+ " (0x%8.8x)", mask);
+}
+
+static void mgmt_get_phy_rsp(const void *data, uint16_t size)
+{
+ uint16_t supported_phys = get_le16(data);
+ uint16_t selected_phys = get_le16(data + 2);
+
+ mgmt_print_phys("Supported PHYs", supported_phys);
+ mgmt_print_phys("Selected PHYs", selected_phys);
+}
+
+static void mgmt_set_phy_cmd(const void *data, uint16_t size)
+{
+ uint16_t default_phys = get_le16(data);
+
+ mgmt_print_phys("Default PHYs", default_phys);
+}
+
struct mgmt_data {
uint16_t opcode;
const char *str;
@@ -12118,6 +12168,12 @@ static const struct mgmt_data mgmt_command_table[] = {
{ 0x0043, "Set Appearance",
mgmt_set_apperance_cmd, 2, true,
mgmt_null_rsp, 0, true },
+ { 0x0044, "Get PHY Configuration",
+ mgmt_null_cmd, 0, true,
+ mgmt_get_phy_rsp, 4, true },
+ { 0x0045, "Set PHY Configuration",
+ mgmt_set_phy_cmd, 2, true,
+ mgmt_null_rsp, 0, true },
{ }
};

@@ -12496,6 +12552,13 @@ static void mgmt_ext_controller_info_changed_evt(const void *data, uint16_t size
print_eir(data + 2, size - 2, false);
}

+static void mgmt_phy_changed_evt(const void *data, uint16_t size)
+{
+ uint16_t selected_phys = get_le16(data);
+
+ mgmt_print_phys("Selected PHYs", selected_phys);
+}
+
static const struct mgmt_data mgmt_event_table[] = {
{ 0x0001, "Command Complete",
mgmt_command_complete_evt, 3, false },
@@ -12571,6 +12634,8 @@ static const struct mgmt_data mgmt_event_table[] = {
mgmt_advertising_removed_evt, 1, true },
{ 0x0025, "Extended Controller Information Changed",
mgmt_ext_controller_info_changed_evt, 2, false },
+ { 0x0026, "PHY Configuration Changed",
+ mgmt_phy_changed_evt, 2, true },
{ }
};

--
2.7.4



2018-03-13 06:02:50

by Jaganath K

[permalink] [raw]
Subject: Re: [PATCH 2/4 v1] btmgmt: Add PHY configuration get/set commands

Hi Eramoto,

On Mon, Mar 12, 2018 at 1:44 PM, ERAMOTO Masaya
<[email protected]> wrote:
> Hi Jaganath,
>
> On 03/09/2018 04:25 PM, Jaganath Kanakkassery wrote:
>> ---
>> lib/mgmt.h | 33 +++++++++++++++
>> tools/btmgmt.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
>
>
> Could you rebase the patches which change btmgmt since it had massive
> changes by commit 6523d168 ("tools/btmgmt: Port to use bt_shell"). And
> now, commands need to call properly the exit function on non-interactive
> mode.
>
>

Thanks for pointing it out. I have raised v2 after rebasing.

Thanks,
Jaganath

2018-03-12 08:14:12

by ERAMOTO Masaya

[permalink] [raw]
Subject: Re: [PATCH 2/4 v1] btmgmt: Add PHY configuration get/set commands

Hi Jaganath,

On 03/09/2018 04:25 PM, Jaganath Kanakkassery wrote:
> ---
> lib/mgmt.h | 33 +++++++++++++++
> tools/btmgmt.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++



Could you rebase the patches which change btmgmt since it had massive
changes by commit 6523d168 ("tools/btmgmt: Port to use bt_shell"). And
now, commands need to call properly the exit function on non-interactive
mode.


Regards,
Eramoto


> 2 files changed, 162 insertions(+)
> mode change 100644 => 100755 tools/btmgmt.c
>
> diff --git a/lib/mgmt.h b/lib/mgmt.h
> index 798a05e..7a25e17 100644
> --- a/lib/mgmt.h
> +++ b/lib/mgmt.h
> @@ -101,6 +101,7 @@ struct mgmt_rp_read_index_list {
> #define MGMT_SETTING_PRIVACY 0x00002000
> #define MGMT_SETTING_CONFIGURATION 0x00004000
> #define MGMT_SETTING_STATIC_ADDRESS 0x00008000
> +#define MGMT_SETTING_PHY_CONFIGURATION 0x00010000
>
> #define MGMT_OP_READ_INFO 0x0004
> struct mgmt_rp_read_info {
> @@ -546,6 +547,30 @@ struct mgmt_cp_set_appearance {
> uint16_t appearance;
> } __packed;
>
> +#define MGMT_OP_GET_PHY_CONFIGURATION 0x0044
> +struct mgmt_rp_get_phy_confguration {
> + uint16_t supported_phys;
> + uint16_t selected_phys;
> +} __packed;
> +
> +#define MGMT_PHY_LE_1M_TX 0x0001
> +#define MGMT_PHY_LE_1M_RX 0x0002
> +#define MGMT_PHY_LE_2M_TX 0x0004
> +#define MGMT_PHY_LE_2M_RX 0x0008
> +#define MGMT_PHY_LE_CODED_TX 0x0010
> +#define MGMT_PHY_LE_CODED_RX 0x0020
> +
> +#define MGMT_PHY_LE_TX_MASK (MGMT_PHY_LE_1M_TX | MGMT_PHY_LE_2M_TX | \
> + MGMT_PHY_LE_CODED_TX)
> +#define MGMT_PHY_LE_RX_MASK (MGMT_PHY_LE_1M_RX | MGMT_PHY_LE_2M_RX | \
> + MGMT_PHY_LE_CODED_RX)
> +
> +#define MGMT_OP_SET_PHY_CONFIGURATION 0x0045
> +struct mgmt_cp_set_phy_confguration {
> + uint16_t default_phys;
> +} __packed;
> +
> +
> #define MGMT_EV_CMD_COMPLETE 0x0001
> struct mgmt_ev_cmd_complete {
> uint16_t opcode;
> @@ -764,6 +789,11 @@ struct mgmt_ev_ext_info_changed {
> uint8_t eir[0];
> } __packed;
>
> +#define MGMT_EV_PHY_CONFIGURATION_CHANGED 0x0026
> +struct mgmt_ev_phy_configuration_changed {
> + uint16_t selected_phys;
> +} __packed;
> +
> static const char *mgmt_op[] = {
> "<0x0000>",
> "Read Version",
> @@ -833,6 +863,8 @@ static const char *mgmt_op[] = {
> "Start Limited Discovery",
> "Read Extended Controller Information",
> "Set Appearance",
> + "Get PHY Configuration",
> + "Set PHY Configuration",
> };
>
> static const char *mgmt_ev[] = {
> @@ -874,6 +906,7 @@ static const char *mgmt_ev[] = {
> "Advertising Added",
> "Advertising Removed",
> "Extended Controller Information Changed",
> + "PHY Configuration Changed",
> };
>
> static const char *mgmt_status[] = {
> diff --git a/tools/btmgmt.c b/tools/btmgmt.c
> old mode 100644
> new mode 100755
> index 3911ba2..5ad534f
> --- a/tools/btmgmt.c
> +++ b/tools/btmgmt.c
> @@ -4341,6 +4341,131 @@ static void cmd_appearance(struct mgmt *mgmt, uint16_t index, int argc,
> }
> }
>
> +static const char *phys_str[] = {
> + "1MTX",
> + "1MRX",
> + "2MTX",
> + "2MRX",
> + "CODEDTX",
> + "CODEDRX",
> +};
> +
> +static const char *phys2str(uint16_t phys)
> +{
> + static char str[256];
> + unsigned i;
> + int off;
> +
> + off = 0;
> + str[0] = '\0';
> +
> + for (i = 0; i < NELEM(phys_str); i++) {
> + if ((phys & (1 << i)) != 0)
> + off += snprintf(str + off, sizeof(str) - off, "%s ",
> + phys_str[i]);
> + }
> +
> + return str;
> +}
> +
> +static void get_phy_rsp(uint8_t status, uint16_t len, const void *param,
> + void *user_data)
> +{
> + const struct mgmt_rp_get_phy_confguration *rp = param;
> + uint16_t supported_flags, selected_phys;
> +
> + if (status != 0) {
> + error("Reading mgmt version failed with status 0x%02x (%s)",
> + status, mgmt_errstr(status));
> + goto done;
> + }
> +
> + if (len < sizeof(*rp)) {
> + error("Too small version reply (%u bytes)", len);
> + goto done;
> + }
> +
> + supported_flags = get_le16(&rp->supported_phys);
> + selected_phys = get_le16(&rp->selected_phys);
> +
> + print("Supported phys: %s", phys2str(supported_flags));
> + print("Selected phys: %s", phys2str(selected_phys));
> +
> +done:
> + noninteractive_quit(EXIT_SUCCESS);
> +}
> +
> +static void cmd_get_phy(struct mgmt *mgmt, uint16_t index, int argc,
> + char **argv)
> +{
> + if (index == MGMT_INDEX_NONE)
> + index = 0;
> +
> + if (mgmt_send(mgmt, MGMT_OP_GET_PHY_CONFIGURATION, index, 0, NULL,
> + get_phy_rsp, NULL, NULL) == 0) {
> + error("Unable to send Get PHY cmd");
> + return noninteractive_quit(EXIT_FAILURE);
> + }
> +}
> +
> +static void set_phy_rsp(uint8_t status, uint16_t len, const void *param,
> + void *user_data)
> +{
> + if (status != 0)
> + error("Could not set PHY Configuration with status 0x%02x (%s)",
> + status, mgmt_errstr(status));
> + else
> + print("PHY Configuration successfully set");
> +
> + noninteractive_quit(EXIT_SUCCESS);
> +}
> +
> +static void cmd_set_phy(struct mgmt *mgmt, uint16_t index,
> + int argc, char **argv)
> +{
> + struct mgmt_cp_set_phy_confguration cp;
> + int i;
> + uint16_t phys = 0;
> +
> + if (argc < 2) {
> + print("Specify one or more of \"1MTX\" \"1MRX\" \"2MTX\" \
> + \"2MRX\" \"CODEDTX\" \"CODEDRX\"");
> + return noninteractive_quit(EXIT_FAILURE);
> + }
> +
> + for (i = 1; i < argc; i++) {
> + if (strcasecmp(argv[i], "1MTX") == 0)
> + phys |= MGMT_PHY_LE_1M_TX;
> +
> + if (strcasecmp(argv[i], "1MRX") == 0)
> + phys |= MGMT_PHY_LE_1M_RX;
> +
> + if (strcasecmp(argv[i], "2MTX") == 0)
> + phys |= MGMT_PHY_LE_2M_TX;
> +
> + if (strcasecmp(argv[i], "2MRX") == 0)
> + phys |= MGMT_PHY_LE_2M_RX;
> +
> + if (strcasecmp(argv[i], "CODEDTX") == 0)
> + phys |= MGMT_PHY_LE_CODED_TX;
> +
> + if (strcasecmp(argv[i], "CODEDRX") == 0)
> + phys |= MGMT_PHY_LE_CODED_RX;
> + }
> +
> + cp.default_phys = cpu_to_le16(phys);
> +
> + if (index == MGMT_INDEX_NONE)
> + index = 0;
> +
> + if (mgmt_send(mgmt, MGMT_OP_SET_PHY_CONFIGURATION, index, sizeof(cp),
> + &cp, set_phy_rsp, NULL, NULL) == 0) {
> + error("Unable to send %s cmd",
> + mgmt_opstr(MGMT_OP_GET_PHY_CONFIGURATION));
> + return noninteractive_quit(EXIT_FAILURE);
> + }
> +}
> +
> struct cmd_info {
> char *cmd;
> const char *arg;
> @@ -4473,6 +4598,10 @@ static struct cmd_info all_cmd[] = {
> cmd_clr_adv, "Clear advertising instances" },
> { "appearance", "<appearance>",
> cmd_appearance, "Set appearance" },
> + { "get-phy", NULL,
> + cmd_get_phy, "Get PHY Configuration" },
> + { "set-phy", "<phys>",
> + cmd_set_phy, "Set PHY Configuration" },
> };
>
> static void cmd_quit(struct mgmt *mgmt, uint16_t index,
>


2018-03-09 07:25:54

by Jaganath K

[permalink] [raw]
Subject: [PATCH 4/4 v1] btmgmt: Add support for setting PHY in add-adv

---
lib/mgmt.h | 3 +++
tools/btmgmt.c | 15 +++++++++++++++
2 files changed, 18 insertions(+)

diff --git a/lib/mgmt.h b/lib/mgmt.h
index 7a25e17..ec6a380 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
@@ -506,6 +506,9 @@ struct mgmt_rp_add_advertising {
#define MGMT_ADV_FLAG_TX_POWER (1 << 4)
#define MGMT_ADV_FLAG_APPEARANCE (1 << 5)
#define MGMT_ADV_FLAG_LOCAL_NAME (1 << 6)
+#define MGMT_ADV_FLAG_SEC_1M (1 << 7)
+#define MGMT_ADV_FLAG_SEC_2M (1 << 8)
+#define MGMT_ADV_FLAG_SEC_CODED (1 << 9)

#define MGMT_OP_REMOVE_ADVERTISING 0x003F
struct mgmt_cp_remove_advertising {
diff --git a/tools/btmgmt.c b/tools/btmgmt.c
index 5ad534f..3c6b543 100755
--- a/tools/btmgmt.c
+++ b/tools/btmgmt.c
@@ -3802,6 +3802,9 @@ static const char *adv_flags_str[] = {
"tx-power",
"scan-rsp-appearance",
"scan-rsp-local-name",
+ "Secondary-channel-1M",
+ "Secondary-channel-2M",
+ "Secondary-channel-CODED",
};

static const char *adv_flags2str(uint32_t flags)
@@ -4016,6 +4019,7 @@ static void add_adv_usage(void)
"\t -s, --scan-rsp <data> Scan Response Data bytes\n"
"\t -t, --timeout <timeout> Timeout in seconds\n"
"\t -D, --duration <duration> Duration in seconds\n"
+ "\t -P, --phy <phy> Phy type, Specify 1M/2M/CODED\n"
"\t -c, --connectable \"connectable\" flag\n"
"\t -g, --general-discov \"general-discoverable\" flag\n"
"\t -l, --limited-discov \"limited-discoverable\" flag\n"
@@ -4034,6 +4038,7 @@ static struct option add_adv_options[] = {
{ "scan-rsp", 1, 0, 's' },
{ "timeout", 1, 0, 't' },
{ "duration", 1, 0, 'D' },
+ { "phy", 1, 0, 'P' },
{ "connectable", 0, 0, 'c' },
{ "general-discov", 0, 0, 'g' },
{ "limited-discov", 0, 0, 'l' },
@@ -4187,6 +4192,16 @@ static void cmd_add_adv(struct mgmt *mgmt, uint16_t index,
case 'a':
flags |= MGMT_ADV_FLAG_APPEARANCE;
break;
+ case 'P':
+ if (strcasecmp(optarg, "1M") == 0)
+ flags |= MGMT_ADV_FLAG_SEC_1M;
+ else if (strcasecmp(optarg, "2M") == 0)
+ flags |= MGMT_ADV_FLAG_SEC_2M;
+ else if (strcasecmp(optarg, "CODED") == 0)
+ flags |= MGMT_ADV_FLAG_SEC_CODED;
+ else
+ goto done;
+ break;
case 'h':
success = true;
/* fall through */
--
2.7.4


2018-03-09 07:25:53

by Jaganath K

[permalink] [raw]
Subject: [PATCH 3/4 v1] monitor: Add support for Secondary PHY flags in Add Advertising

---
monitor/packet.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/monitor/packet.c b/monitor/packet.c
index e3b5ab7..2a22e7d 100644
--- a/monitor/packet.c
+++ b/monitor/packet.c
@@ -10741,6 +10741,9 @@ static const struct {
{ 4, "Add TX Power field to Advertising Data" },
{ 5, "Add Appearance field to Scan Response" },
{ 6, "Add Local Name in Scan Response" },
+ { 7, "Advertise in 1M on Secondary channel" },
+ { 8, "Advertise in 2M on Secondary channel" },
+ { 9, "Advertise in CODED on Secondary channel" },
{ }
};

--
2.7.4


2018-03-09 07:25:52

by Jaganath K

[permalink] [raw]
Subject: [PATCH 2/4 v1] btmgmt: Add PHY configuration get/set commands

---
lib/mgmt.h | 33 +++++++++++++++
tools/btmgmt.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 162 insertions(+)
mode change 100644 => 100755 tools/btmgmt.c

diff --git a/lib/mgmt.h b/lib/mgmt.h
index 798a05e..7a25e17 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
@@ -101,6 +101,7 @@ struct mgmt_rp_read_index_list {
#define MGMT_SETTING_PRIVACY 0x00002000
#define MGMT_SETTING_CONFIGURATION 0x00004000
#define MGMT_SETTING_STATIC_ADDRESS 0x00008000
+#define MGMT_SETTING_PHY_CONFIGURATION 0x00010000

#define MGMT_OP_READ_INFO 0x0004
struct mgmt_rp_read_info {
@@ -546,6 +547,30 @@ struct mgmt_cp_set_appearance {
uint16_t appearance;
} __packed;

+#define MGMT_OP_GET_PHY_CONFIGURATION 0x0044
+struct mgmt_rp_get_phy_confguration {
+ uint16_t supported_phys;
+ uint16_t selected_phys;
+} __packed;
+
+#define MGMT_PHY_LE_1M_TX 0x0001
+#define MGMT_PHY_LE_1M_RX 0x0002
+#define MGMT_PHY_LE_2M_TX 0x0004
+#define MGMT_PHY_LE_2M_RX 0x0008
+#define MGMT_PHY_LE_CODED_TX 0x0010
+#define MGMT_PHY_LE_CODED_RX 0x0020
+
+#define MGMT_PHY_LE_TX_MASK (MGMT_PHY_LE_1M_TX | MGMT_PHY_LE_2M_TX | \
+ MGMT_PHY_LE_CODED_TX)
+#define MGMT_PHY_LE_RX_MASK (MGMT_PHY_LE_1M_RX | MGMT_PHY_LE_2M_RX | \
+ MGMT_PHY_LE_CODED_RX)
+
+#define MGMT_OP_SET_PHY_CONFIGURATION 0x0045
+struct mgmt_cp_set_phy_confguration {
+ uint16_t default_phys;
+} __packed;
+
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
uint16_t opcode;
@@ -764,6 +789,11 @@ struct mgmt_ev_ext_info_changed {
uint8_t eir[0];
} __packed;

+#define MGMT_EV_PHY_CONFIGURATION_CHANGED 0x0026
+struct mgmt_ev_phy_configuration_changed {
+ uint16_t selected_phys;
+} __packed;
+
static const char *mgmt_op[] = {
"<0x0000>",
"Read Version",
@@ -833,6 +863,8 @@ static const char *mgmt_op[] = {
"Start Limited Discovery",
"Read Extended Controller Information",
"Set Appearance",
+ "Get PHY Configuration",
+ "Set PHY Configuration",
};

static const char *mgmt_ev[] = {
@@ -874,6 +906,7 @@ static const char *mgmt_ev[] = {
"Advertising Added",
"Advertising Removed",
"Extended Controller Information Changed",
+ "PHY Configuration Changed",
};

static const char *mgmt_status[] = {
diff --git a/tools/btmgmt.c b/tools/btmgmt.c
old mode 100644
new mode 100755
index 3911ba2..5ad534f
--- a/tools/btmgmt.c
+++ b/tools/btmgmt.c
@@ -4341,6 +4341,131 @@ static void cmd_appearance(struct mgmt *mgmt, uint16_t index, int argc,
}
}

+static const char *phys_str[] = {
+ "1MTX",
+ "1MRX",
+ "2MTX",
+ "2MRX",
+ "CODEDTX",
+ "CODEDRX",
+};
+
+static const char *phys2str(uint16_t phys)
+{
+ static char str[256];
+ unsigned i;
+ int off;
+
+ off = 0;
+ str[0] = '\0';
+
+ for (i = 0; i < NELEM(phys_str); i++) {
+ if ((phys & (1 << i)) != 0)
+ off += snprintf(str + off, sizeof(str) - off, "%s ",
+ phys_str[i]);
+ }
+
+ return str;
+}
+
+static void get_phy_rsp(uint8_t status, uint16_t len, const void *param,
+ void *user_data)
+{
+ const struct mgmt_rp_get_phy_confguration *rp = param;
+ uint16_t supported_flags, selected_phys;
+
+ if (status != 0) {
+ error("Reading mgmt version failed with status 0x%02x (%s)",
+ status, mgmt_errstr(status));
+ goto done;
+ }
+
+ if (len < sizeof(*rp)) {
+ error("Too small version reply (%u bytes)", len);
+ goto done;
+ }
+
+ supported_flags = get_le16(&rp->supported_phys);
+ selected_phys = get_le16(&rp->selected_phys);
+
+ print("Supported phys: %s", phys2str(supported_flags));
+ print("Selected phys: %s", phys2str(selected_phys));
+
+done:
+ noninteractive_quit(EXIT_SUCCESS);
+}
+
+static void cmd_get_phy(struct mgmt *mgmt, uint16_t index, int argc,
+ char **argv)
+{
+ if (index == MGMT_INDEX_NONE)
+ index = 0;
+
+ if (mgmt_send(mgmt, MGMT_OP_GET_PHY_CONFIGURATION, index, 0, NULL,
+ get_phy_rsp, NULL, NULL) == 0) {
+ error("Unable to send Get PHY cmd");
+ return noninteractive_quit(EXIT_FAILURE);
+ }
+}
+
+static void set_phy_rsp(uint8_t status, uint16_t len, const void *param,
+ void *user_data)
+{
+ if (status != 0)
+ error("Could not set PHY Configuration with status 0x%02x (%s)",
+ status, mgmt_errstr(status));
+ else
+ print("PHY Configuration successfully set");
+
+ noninteractive_quit(EXIT_SUCCESS);
+}
+
+static void cmd_set_phy(struct mgmt *mgmt, uint16_t index,
+ int argc, char **argv)
+{
+ struct mgmt_cp_set_phy_confguration cp;
+ int i;
+ uint16_t phys = 0;
+
+ if (argc < 2) {
+ print("Specify one or more of \"1MTX\" \"1MRX\" \"2MTX\" \
+ \"2MRX\" \"CODEDTX\" \"CODEDRX\"");
+ return noninteractive_quit(EXIT_FAILURE);
+ }
+
+ for (i = 1; i < argc; i++) {
+ if (strcasecmp(argv[i], "1MTX") == 0)
+ phys |= MGMT_PHY_LE_1M_TX;
+
+ if (strcasecmp(argv[i], "1MRX") == 0)
+ phys |= MGMT_PHY_LE_1M_RX;
+
+ if (strcasecmp(argv[i], "2MTX") == 0)
+ phys |= MGMT_PHY_LE_2M_TX;
+
+ if (strcasecmp(argv[i], "2MRX") == 0)
+ phys |= MGMT_PHY_LE_2M_RX;
+
+ if (strcasecmp(argv[i], "CODEDTX") == 0)
+ phys |= MGMT_PHY_LE_CODED_TX;
+
+ if (strcasecmp(argv[i], "CODEDRX") == 0)
+ phys |= MGMT_PHY_LE_CODED_RX;
+ }
+
+ cp.default_phys = cpu_to_le16(phys);
+
+ if (index == MGMT_INDEX_NONE)
+ index = 0;
+
+ if (mgmt_send(mgmt, MGMT_OP_SET_PHY_CONFIGURATION, index, sizeof(cp),
+ &cp, set_phy_rsp, NULL, NULL) == 0) {
+ error("Unable to send %s cmd",
+ mgmt_opstr(MGMT_OP_GET_PHY_CONFIGURATION));
+ return noninteractive_quit(EXIT_FAILURE);
+ }
+}
+
struct cmd_info {
char *cmd;
const char *arg;
@@ -4473,6 +4598,10 @@ static struct cmd_info all_cmd[] = {
cmd_clr_adv, "Clear advertising instances" },
{ "appearance", "<appearance>",
cmd_appearance, "Set appearance" },
+ { "get-phy", NULL,
+ cmd_get_phy, "Get PHY Configuration" },
+ { "set-phy", "<phys>",
+ cmd_set_phy, "Set PHY Configuration" },
};

static void cmd_quit(struct mgmt *mgmt, uint16_t index,
--
2.7.4