Skip to content

Commit 4a63937

Browse files
committed
net: wifi: Add Wi-Fi direct P2P GO mode shell command
Add shell commands support for P2P GO mode. Signed-off-by: Kapil Bhatt <kapil.bhatt@nordicsemi.no>
1 parent 146b3ab commit 4a63937

File tree

1 file changed

+275
-0
lines changed

1 file changed

+275
-0
lines changed

subsys/net/l2/wifi/wifi_shell.c

Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3822,6 +3822,252 @@ static int cmd_wifi_p2p_connect(const struct shell *sh, size_t argc, char *argv[
38223822
}
38233823
return 0;
38243824
}
3825+
3826+
static int cmd_wifi_p2p_group_add(const struct shell *sh, size_t argc, char *argv[])
3827+
{
3828+
struct net_if *iface = get_iface(IFACE_TYPE_STA, argc, argv);
3829+
struct wifi_p2p_params params = {0};
3830+
int opt;
3831+
int opt_index = 0;
3832+
struct getopt_state *state;
3833+
static const struct option long_options[] = {
3834+
{"freq", required_argument, 0, 'f'},
3835+
{"persistent", required_argument, 0, 'p'},
3836+
{"ht40", no_argument, 0, 'h'},
3837+
{"vht", no_argument, 0, 'v'},
3838+
{"he", no_argument, 0, 'H'},
3839+
{"edmg", no_argument, 0, 'e'},
3840+
{"go-bssid", required_argument, 0, 'b'},
3841+
{"iface", required_argument, 0, 'i'},
3842+
{"help", no_argument, 0, '?'},
3843+
{0, 0, 0, 0}
3844+
};
3845+
long val;
3846+
uint8_t mac_addr[WIFI_MAC_ADDR_LEN];
3847+
3848+
context.sh = sh;
3849+
3850+
params.oper = WIFI_P2P_GROUP_ADD;
3851+
params.group_add.freq = 0;
3852+
params.group_add.persistent = -1;
3853+
params.group_add.ht40 = false;
3854+
params.group_add.vht = false;
3855+
params.group_add.he = false;
3856+
params.group_add.edmg = false;
3857+
params.group_add.go_bssid_length = 0;
3858+
3859+
while ((opt = getopt_long(argc, argv, "f:p:hvHeb:i:?", long_options, &opt_index)) != -1) {
3860+
state = getopt_state_get();
3861+
switch (opt) {
3862+
case 'f':
3863+
if (!parse_number(sh, &val, state->optarg, "freq", 0, 6000)) {
3864+
return -EINVAL;
3865+
}
3866+
params.group_add.freq = (int)val;
3867+
break;
3868+
case 'p':
3869+
if (!parse_number(sh, &val, state->optarg, "persistent", -1, 255)) {
3870+
return -EINVAL;
3871+
}
3872+
params.group_add.persistent = (int)val;
3873+
break;
3874+
case 'h':
3875+
params.group_add.ht40 = true;
3876+
break;
3877+
case 'v':
3878+
params.group_add.vht = true;
3879+
params.group_add.ht40 = true;
3880+
break;
3881+
case 'H':
3882+
params.group_add.he = true;
3883+
break;
3884+
case 'e':
3885+
params.group_add.edmg = true;
3886+
break;
3887+
case 'b':
3888+
if (sscanf(state->optarg, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
3889+
&mac_addr[0], &mac_addr[1], &mac_addr[2],
3890+
&mac_addr[3], &mac_addr[4], &mac_addr[5]) != WIFI_MAC_ADDR_LEN) {
3891+
PR_ERROR("Invalid GO BSSID format. Use: XX:XX:XX:XX:XX:XX\n");
3892+
return -EINVAL;
3893+
}
3894+
memcpy(params.group_add.go_bssid, mac_addr, WIFI_MAC_ADDR_LEN);
3895+
params.group_add.go_bssid_length = WIFI_MAC_ADDR_LEN;
3896+
break;
3897+
case 'i':
3898+
/* Unused, but parsing to avoid unknown option error */
3899+
break;
3900+
case '?':
3901+
shell_help(sh);
3902+
return -ENOEXEC;
3903+
default:
3904+
PR_ERROR("Invalid option %c\n", state->optopt);
3905+
return -EINVAL;
3906+
}
3907+
}
3908+
3909+
if (net_mgmt(NET_REQUEST_WIFI_P2P_OPER, iface, &params, sizeof(params))) {
3910+
PR_WARNING("P2P group add request failed\n");
3911+
return -ENOEXEC;
3912+
}
3913+
PR("P2P group add initiated\n");
3914+
return 0;
3915+
}
3916+
3917+
static int cmd_wifi_p2p_group_remove(const struct shell *sh, size_t argc, char *argv[])
3918+
{
3919+
struct net_if *iface = get_iface(IFACE_TYPE_STA, argc, argv);
3920+
struct wifi_p2p_params params = {0};
3921+
3922+
context.sh = sh;
3923+
3924+
if (argc < 2) {
3925+
PR_ERROR("Interface name required. Usage: wifi p2p group_remove <ifname>\n");
3926+
return -EINVAL;
3927+
}
3928+
3929+
params.oper = WIFI_P2P_GROUP_REMOVE;
3930+
strncpy(params.group_remove.ifname, argv[1],
3931+
CONFIG_NET_INTERFACE_NAME_LEN);
3932+
params.group_remove.ifname[CONFIG_NET_INTERFACE_NAME_LEN] = '\0';
3933+
3934+
if (net_mgmt(NET_REQUEST_WIFI_P2P_OPER, iface, &params, sizeof(params))) {
3935+
PR_WARNING("P2P group remove request failed\n");
3936+
return -ENOEXEC;
3937+
}
3938+
PR("P2P group remove initiated\n");
3939+
return 0;
3940+
}
3941+
3942+
static int cmd_wifi_p2p_invite(const struct shell *sh, size_t argc, char *argv[])
3943+
{
3944+
struct net_if *iface = get_iface(IFACE_TYPE_STA, argc, argv);
3945+
struct wifi_p2p_params params = {0};
3946+
uint8_t mac_addr[WIFI_MAC_ADDR_LEN];
3947+
int opt;
3948+
int opt_index = 0;
3949+
struct getopt_state *state;
3950+
static const struct option long_options[] = {
3951+
{"persistent", required_argument, 0, 'p'},
3952+
{"group", required_argument, 0, 'g'},
3953+
{"peer", required_argument, 0, 'P'},
3954+
{"freq", required_argument, 0, 'f'},
3955+
{"go-dev-addr", required_argument, 0, 'd'},
3956+
{"iface", required_argument, 0, 'i'},
3957+
{"help", no_argument, 0, 'h'},
3958+
{0, 0, 0, 0}
3959+
};
3960+
long val;
3961+
3962+
context.sh = sh;
3963+
3964+
params.oper = WIFI_P2P_INVITE;
3965+
params.invite.type = WIFI_P2P_INVITE_PERSISTENT;
3966+
params.invite.persistent_id = -1;
3967+
params.invite.group_ifname[0] = '\0';
3968+
params.invite.freq = 0;
3969+
params.invite.go_dev_addr_length = 0;
3970+
memset(params.invite.peer_addr, 0, WIFI_MAC_ADDR_LEN);
3971+
3972+
if (argc < 2) {
3973+
PR_ERROR("Usage: wifi p2p invite --persistent=<id> <peer MAC> OR "
3974+
"wifi p2p invite --group=<ifname> --peer=<MAC> [options]\n");
3975+
return -EINVAL;
3976+
}
3977+
3978+
while ((opt = getopt_long(argc, argv, "p:g:P:f:d:i:h", long_options, &opt_index)) != -1) {
3979+
state = getopt_state_get();
3980+
switch (opt) {
3981+
case 'p':
3982+
if (!parse_number(sh, &val, state->optarg, "persistent", 0, 255)) {
3983+
return -EINVAL;
3984+
}
3985+
params.invite.type = WIFI_P2P_INVITE_PERSISTENT;
3986+
params.invite.persistent_id = (int)val;
3987+
break;
3988+
case 'g':
3989+
params.invite.type = WIFI_P2P_INVITE_GROUP;
3990+
strncpy(params.invite.group_ifname, state->optarg,
3991+
CONFIG_NET_INTERFACE_NAME_LEN);
3992+
params.invite.group_ifname[CONFIG_NET_INTERFACE_NAME_LEN] = '\0';
3993+
break;
3994+
case 'P':
3995+
if (sscanf(state->optarg, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
3996+
&mac_addr[0], &mac_addr[1], &mac_addr[2],
3997+
&mac_addr[3], &mac_addr[4], &mac_addr[5]) != WIFI_MAC_ADDR_LEN) {
3998+
PR_ERROR("Invalid peer MAC address format. Use: XX:XX:XX:XX:XX:XX\n");
3999+
return -EINVAL;
4000+
}
4001+
memcpy(params.invite.peer_addr, mac_addr, WIFI_MAC_ADDR_LEN);
4002+
break;
4003+
case 'f':
4004+
if (!parse_number(sh, &val, state->optarg, "freq", 0, 6000)) {
4005+
return -EINVAL;
4006+
}
4007+
params.invite.freq = (int)val;
4008+
break;
4009+
case 'd':
4010+
if (sscanf(state->optarg, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
4011+
&mac_addr[0], &mac_addr[1], &mac_addr[2],
4012+
&mac_addr[3], &mac_addr[4], &mac_addr[5]) != WIFI_MAC_ADDR_LEN) {
4013+
PR_ERROR("Invalid GO device address format. Use: XX:XX:XX:XX:XX:XX\n");
4014+
return -EINVAL;
4015+
}
4016+
memcpy(params.invite.go_dev_addr, mac_addr, WIFI_MAC_ADDR_LEN);
4017+
params.invite.go_dev_addr_length = WIFI_MAC_ADDR_LEN;
4018+
break;
4019+
case 'i':
4020+
/* Unused, but parsing to avoid unknown option error */
4021+
break;
4022+
case 'h':
4023+
shell_help(sh);
4024+
return -ENOEXEC;
4025+
default:
4026+
PR_ERROR("Invalid option %c\n", state->optopt);
4027+
return -EINVAL;
4028+
}
4029+
}
4030+
4031+
if (params.invite.type == WIFI_P2P_INVITE_PERSISTENT &&
4032+
params.invite.persistent_id >= 0 &&
4033+
params.invite.peer_addr[0] == 0 && params.invite.peer_addr[1] == 0 &&
4034+
argc > optind && argv[optind][0] != '-') {
4035+
if (sscanf(argv[optind], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
4036+
&mac_addr[0], &mac_addr[1], &mac_addr[2],
4037+
&mac_addr[3], &mac_addr[4], &mac_addr[5]) != WIFI_MAC_ADDR_LEN) {
4038+
PR_ERROR("Invalid peer MAC address format. Use: XX:XX:XX:XX:XX:XX\n");
4039+
return -EINVAL;
4040+
}
4041+
memcpy(params.invite.peer_addr, mac_addr, WIFI_MAC_ADDR_LEN);
4042+
}
4043+
4044+
if (params.invite.type == WIFI_P2P_INVITE_PERSISTENT) {
4045+
if (params.invite.persistent_id < 0) {
4046+
PR_ERROR("Persistent group ID required. Use --persistent=<id>\n");
4047+
return -EINVAL;
4048+
}
4049+
if (params.invite.peer_addr[0] == 0 && params.invite.peer_addr[1] == 0) {
4050+
PR_ERROR("Peer MAC address required\n");
4051+
return -EINVAL;
4052+
}
4053+
} else if (params.invite.type == WIFI_P2P_INVITE_GROUP) {
4054+
if (params.invite.group_ifname[0] == '\0') {
4055+
PR_ERROR("Group interface name required. Use --group=<ifname>\n");
4056+
return -EINVAL;
4057+
}
4058+
if (params.invite.peer_addr[0] == 0 && params.invite.peer_addr[1] == 0) {
4059+
PR_ERROR("Peer MAC address required. Use --peer=<MAC>\n");
4060+
return -EINVAL;
4061+
}
4062+
}
4063+
4064+
if (net_mgmt(NET_REQUEST_WIFI_P2P_OPER, iface, &params, sizeof(params))) {
4065+
PR_WARNING("P2P invite request failed\n");
4066+
return -ENOEXEC;
4067+
}
4068+
PR("P2P invite initiated\n");
4069+
return 0;
4070+
}
38254071
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */
38264072

38274073
static int cmd_wifi_pmksa_flush(const struct shell *sh, size_t argc, char *argv[])
@@ -4566,6 +4812,35 @@ SHELL_STATIC_SUBCMD_SET_CREATE(
45664812
" wifi p2p connect 9c:b1:50:e3:81:96 pin -g 0 (displays PIN)\n"
45674813
" wifi p2p connect 9c:b1:50:e3:81:96 pin 12345670 -g 0 (uses PIN)\n",
45684814
cmd_wifi_p2p_connect, 3, 5),
4815+
SHELL_CMD_ARG(group_add, NULL,
4816+
"Add a P2P group (start as GO)\n"
4817+
"Usage: group_add [options]\n"
4818+
"[-f, --freq=<MHz>]: Frequency in MHz (0 = auto)\n"
4819+
"[-p, --persistent=<id>]: Persistent group ID (-1 = not persistent)\n"
4820+
"[-h, --ht40]: Enable HT40\n"
4821+
"[-v, --vht]: Enable VHT (also enables HT40)\n"
4822+
"[-H, --he]: Enable HE\n"
4823+
"[-e, --edmg]: Enable EDMG\n"
4824+
"[-b, --go-bssid=<MAC>]: GO BSSID (format: XX:XX:XX:XX:XX:XX)\n"
4825+
"[-i, --iface=<interface index>]: Interface index\n",
4826+
cmd_wifi_p2p_group_add, 1, 10),
4827+
SHELL_CMD_ARG(group_remove, NULL,
4828+
"Remove a P2P group\n"
4829+
"Usage: group_remove <ifname>\n"
4830+
"<ifname>: Interface name (e.g., wlan0)\n"
4831+
"[-i, --iface=<interface index>]: Interface index\n",
4832+
cmd_wifi_p2p_group_remove, 2, 3),
4833+
SHELL_CMD_ARG(invite, NULL,
4834+
"Invite a peer to a P2P group\n"
4835+
"Usage: invite --persistent=<id> <peer MAC> OR\n"
4836+
" invite --group=<ifname> --peer=<MAC> [options]\n"
4837+
"[-p, --persistent=<id>]: Persistent group ID\n"
4838+
"[-g, --group=<ifname>]: Group interface name\n"
4839+
"[-P, --peer=<MAC>]: Peer MAC address (format: XX:XX:XX:XX:XX:XX)\n"
4840+
"[-f, --freq=<MHz>]: Frequency in MHz (0 = auto)\n"
4841+
"[-d, --go-dev-addr=<MAC>]: GO device address (for group type)\n"
4842+
"[-i, --iface=<interface index>]: Interface index\n",
4843+
cmd_wifi_p2p_invite, 2, 8),
45694844
SHELL_SUBCMD_SET_END
45704845
);
45714846

0 commit comments

Comments
 (0)