@@ -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+
522543static 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+
35193727static 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+
42214461SHELL_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