Skip to content

Commit e76dd30

Browse files
kapbhrado17
authored andcommitted
[nrf fromlist] net: wifi: Add Wi-Fi direct P2P discovery shell command support
Add shell command support for P2P discovery. Upstream PR #: 97183 Signed-off-by: Kapil Bhatt <[email protected]>
1 parent af361f8 commit e76dd30

File tree

1 file changed

+241
-1
lines changed

1 file changed

+241
-1
lines changed

subsys/net/l2/wifi/wifi_shell.c

Lines changed: 241 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF);
4646
NET_EVENT_WIFI_AP_STA_CONNECTED |\
4747
NET_EVENT_WIFI_AP_STA_DISCONNECTED|\
4848
NET_EVENT_WIFI_SIGNAL_CHANGE |\
49-
NET_EVENT_WIFI_NEIGHBOR_REP_COMP)
49+
NET_EVENT_WIFI_NEIGHBOR_REP_COMP |\
50+
NET_EVENT_WIFI_P2P_DEVICE_FOUND)
5051

5152
#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY
5253
#define WIFI_SHELL_SCAN_EVENTS ( \
@@ -519,6 +520,26 @@ static void handle_wifi_neighbor_rep_complete(struct net_mgmt_event_callback *cb
519520
}
520521
#endif
521522

523+
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
524+
static void handle_wifi_p2p_device_found(struct net_mgmt_event_callback *cb)
525+
{
526+
const struct wifi_p2p_device_info *peer_info =
527+
(const struct wifi_p2p_device_info *)cb->info;
528+
const struct shell *sh = context.sh;
529+
530+
if (!peer_info || peer_info->device_name[0] == '\0') {
531+
return;
532+
}
533+
534+
PR("Device Name: %-20s MAC Address: %02x:%02x:%02x:%02x:%02x:%02x "
535+
"Config Methods: 0x%x\n",
536+
peer_info->device_name,
537+
peer_info->mac[0], peer_info->mac[1], peer_info->mac[2],
538+
peer_info->mac[3], peer_info->mac[4], peer_info->mac[5],
539+
peer_info->config_methods);
540+
}
541+
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */
542+
522543
static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb,
523544
uint64_t mgmt_event, struct net_if *iface)
524545
{
@@ -552,6 +573,11 @@ static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb,
552573
handle_wifi_neighbor_rep_complete(cb, iface);
553574
break;
554575
#endif
576+
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
577+
case NET_EVENT_WIFI_P2P_DEVICE_FOUND:
578+
handle_wifi_p2p_device_found(cb);
579+
break;
580+
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */
555581
default:
556582
break;
557583
}
@@ -3516,6 +3542,188 @@ static int cmd_wifi_dpp_reconfig(const struct shell *sh, size_t argc, char *argv
35163542
}
35173543

35183544
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP */
3545+
3546+
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
3547+
static void print_peer_info(const struct shell *sh, int index,
3548+
const struct wifi_p2p_device_info *peer)
3549+
{
3550+
uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")];
3551+
const char *device_name;
3552+
const char *device_type;
3553+
const char *config_methods;
3554+
3555+
device_name = (peer->device_name[0] != '\0') ?
3556+
peer->device_name : "<Unknown>";
3557+
device_type = (peer->pri_dev_type_str[0] != '\0') ?
3558+
peer->pri_dev_type_str : "-";
3559+
config_methods = (peer->config_methods_str[0] != '\0') ?
3560+
peer->config_methods_str : "-";
3561+
3562+
PR("%-4d | %-32s | %-17s | %-4d | %-20s | %s\n",
3563+
index,
3564+
device_name,
3565+
net_sprint_ll_addr_buf(peer->mac, WIFI_MAC_ADDR_LEN,
3566+
mac_string_buf,
3567+
sizeof(mac_string_buf)),
3568+
peer->rssi,
3569+
device_type,
3570+
config_methods);
3571+
}
3572+
3573+
static int cmd_wifi_p2p_peer(const struct shell *sh, size_t argc, char *argv[])
3574+
{
3575+
struct net_if *iface = get_iface(IFACE_TYPE_STA, argc, argv);
3576+
struct wifi_p2p_params params = {0};
3577+
uint8_t mac_addr[WIFI_MAC_ADDR_LEN];
3578+
struct wifi_p2p_device_info *peers = NULL;
3579+
int ret;
3580+
int max_peers = (argc < 2) ? WIFI_P2P_MAX_PEERS : 1;
3581+
3582+
context.sh = sh;
3583+
3584+
peers = k_malloc(sizeof(struct wifi_p2p_device_info) * max_peers);
3585+
if (!peers) {
3586+
PR_ERROR("Failed to allocate memory for peer info\n");
3587+
return -ENOMEM;
3588+
}
3589+
memset(peers, 0, sizeof(struct wifi_p2p_device_info) * max_peers);
3590+
3591+
params.peers = peers;
3592+
params.oper = WIFI_P2P_PEER;
3593+
params.peer_count = max_peers;
3594+
3595+
if (argc >= 2) {
3596+
if (sscanf(argv[1], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
3597+
&mac_addr[0], &mac_addr[1], &mac_addr[2],
3598+
&mac_addr[3], &mac_addr[4], &mac_addr[5]) != WIFI_MAC_ADDR_LEN) {
3599+
PR_ERROR("Invalid MAC address format. Use: XX:XX:XX:XX:XX:XX\n");
3600+
k_free(peers);
3601+
return -EINVAL;
3602+
}
3603+
memcpy(params.peer_addr, mac_addr, WIFI_MAC_ADDR_LEN);
3604+
params.peer_count = 1;
3605+
} else {
3606+
/* Use broadcast MAC to query all peers */
3607+
memset(params.peer_addr, 0xFF, WIFI_MAC_ADDR_LEN);
3608+
}
3609+
3610+
ret = net_mgmt(NET_REQUEST_WIFI_P2P_OPER, iface, &params, sizeof(params));
3611+
if (ret) {
3612+
PR_WARNING("P2P peer info request failed\n");
3613+
k_free(peers);
3614+
return -ENOEXEC;
3615+
}
3616+
3617+
if (params.peer_count > 0) {
3618+
PR("\n%-4s | %-32s | %-17s | %-4s | %-20s | %s\n",
3619+
"Num", "Device Name", "MAC Address", "RSSI", "Device Type", "Config Methods");
3620+
for (int i = 0; i < params.peer_count; i++) {
3621+
print_peer_info(sh, i + 1, &peers[i]);
3622+
}
3623+
} else {
3624+
if (argc >= 2) {
3625+
shell_print(sh, "No information available for peer %s", argv[1]);
3626+
} else {
3627+
shell_print(sh, "No P2P peers found");
3628+
}
3629+
}
3630+
3631+
k_free(peers);
3632+
return 0;
3633+
}
3634+
3635+
3636+
static int cmd_wifi_p2p_find(const struct shell *sh, size_t argc, char *argv[])
3637+
{
3638+
struct net_if *iface = get_iface(IFACE_TYPE_STA, argc, argv);
3639+
struct wifi_p2p_params params = {0};
3640+
3641+
context.sh = sh;
3642+
3643+
params.oper = WIFI_P2P_FIND;
3644+
params.discovery_type = WIFI_P2P_FIND_START_WITH_FULL;
3645+
params.timeout = 10; /* Default 10 second timeout */
3646+
3647+
if (argc > 1) {
3648+
int opt;
3649+
int opt_index = 0;
3650+
struct getopt_state *state;
3651+
static const struct option long_options[] = {
3652+
{"timeout", required_argument, 0, 't'},
3653+
{"type", required_argument, 0, 'T'},
3654+
{"iface", required_argument, 0, 'i'},
3655+
{"help", no_argument, 0, 'h'},
3656+
{0, 0, 0, 0}
3657+
};
3658+
long val;
3659+
3660+
while ((opt = getopt_long(argc, argv, "t:T:i:h",
3661+
long_options, &opt_index)) != -1) {
3662+
state = getopt_state_get();
3663+
switch (opt) {
3664+
case 't':
3665+
if (!parse_number(sh, &val, state->optarg, "timeout", 0, 65535)) {
3666+
return -EINVAL;
3667+
}
3668+
params.timeout = (uint16_t)val;
3669+
break;
3670+
case 'T':
3671+
if (!parse_number(sh, &val, state->optarg, "type", 0, 2)) {
3672+
return -EINVAL;
3673+
}
3674+
switch (val) {
3675+
case 0:
3676+
params.discovery_type = WIFI_P2P_FIND_ONLY_SOCIAL;
3677+
break;
3678+
case 1:
3679+
params.discovery_type = WIFI_P2P_FIND_PROGRESSIVE;
3680+
break;
3681+
case 2:
3682+
params.discovery_type = WIFI_P2P_FIND_START_WITH_FULL;
3683+
break;
3684+
default:
3685+
return -EINVAL;
3686+
}
3687+
break;
3688+
case 'i':
3689+
/* Unused, but parsing to avoid unknown option error */
3690+
break;
3691+
case 'h':
3692+
shell_help(sh);
3693+
return -ENOEXEC;
3694+
default:
3695+
PR_ERROR("Invalid option %c\n", state->optopt);
3696+
return -EINVAL;
3697+
}
3698+
}
3699+
}
3700+
3701+
if (net_mgmt(NET_REQUEST_WIFI_P2P_OPER, iface, &params, sizeof(params))) {
3702+
PR_WARNING("P2P find request failed\n");
3703+
return -ENOEXEC;
3704+
}
3705+
PR("P2P find started\n");
3706+
return 0;
3707+
}
3708+
3709+
static int cmd_wifi_p2p_stop_find(const struct shell *sh, size_t argc, char *argv[])
3710+
{
3711+
struct net_if *iface = get_iface(IFACE_TYPE_STA, argc, argv);
3712+
struct wifi_p2p_params params = {0};
3713+
3714+
context.sh = sh;
3715+
3716+
params.oper = WIFI_P2P_STOP_FIND;
3717+
3718+
if (net_mgmt(NET_REQUEST_WIFI_P2P_OPER, iface, &params, sizeof(params))) {
3719+
PR_WARNING("P2P stop find request failed\n");
3720+
return -ENOEXEC;
3721+
}
3722+
PR("P2P find stopped\n");
3723+
return 0;
3724+
}
3725+
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */
3726+
35193727
static int cmd_wifi_pmksa_flush(const struct shell *sh, size_t argc, char *argv[])
35203728
{
35213729
struct net_if *iface = get_iface(IFACE_TYPE_STA, argc, argv);
@@ -4218,6 +4426,38 @@ SHELL_SUBCMD_ADD((wifi), bgscan, NULL,
42184426
2, 6);
42194427
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN */
42204428

4429+
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
4430+
SHELL_STATIC_SUBCMD_SET_CREATE(
4431+
wifi_cmd_p2p,
4432+
SHELL_CMD_ARG(find, NULL,
4433+
"Start P2P device discovery\n"
4434+
"[-t, --timeout=<timeout in seconds>]: Discovery timeout\n"
4435+
"[-T, --type=<0|1|2>]: Discovery type\n"
4436+
" 0: Social channels only (1, 6, 11)\n"
4437+
" 1: Progressive scan (all channels)\n"
4438+
" 2: Full scan first, then social (default)\n"
4439+
"[-i, --iface=<interface index>]: Interface index\n"
4440+
"[-h, --help]: Show help\n",
4441+
cmd_wifi_p2p_find, 1, 6),
4442+
SHELL_CMD_ARG(stop_find, NULL,
4443+
"Stop P2P device discovery\n"
4444+
"[-i, --iface=<interface index>]: Interface index\n",
4445+
cmd_wifi_p2p_stop_find, 1, 2),
4446+
SHELL_CMD_ARG(peer, NULL,
4447+
"Show information about P2P peers\n"
4448+
"Usage: peer [<MAC address>]\n"
4449+
"<MAC address>: Show detailed info for specific peer (format: XX:XX:XX:XX:XX:XX)\n"
4450+
"[-i, --iface=<interface index>]: Interface index\n",
4451+
cmd_wifi_p2p_peer, 1, 3),
4452+
SHELL_SUBCMD_SET_END
4453+
);
4454+
4455+
SHELL_SUBCMD_ADD((wifi), p2p, &wifi_cmd_p2p,
4456+
"Wi-Fi Direct (P2P) commands.",
4457+
NULL,
4458+
0, 0);
4459+
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */
4460+
42214461
SHELL_SUBCMD_ADD((wifi), config, NULL,
42224462
"Configure STA parameters.\n"
42234463
"-o, --okc=<0/1>: Opportunistic Key Caching. 0: disable, 1: enable\n"

0 commit comments

Comments
 (0)