@@ -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
38274073static 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