@@ -3826,6 +3826,256 @@ static int cmd_wifi_p2p_connect(const struct shell *sh, size_t argc, char *argv[
38263826 }
38273827 return 0 ;
38283828}
3829+
3830+ static int cmd_wifi_p2p_group_add (const struct shell * sh , size_t argc , char * argv [])
3831+ {
3832+ struct net_if * iface = get_iface (IFACE_TYPE_STA , argc , argv );
3833+ struct wifi_p2p_params params = {0 };
3834+ int opt ;
3835+ int opt_index = 0 ;
3836+ struct sys_getopt_state * state ;
3837+ static const struct sys_getopt_option long_options [] = {
3838+ {"freq" , sys_getopt_required_argument , 0 , 'f' },
3839+ {"persistent" , sys_getopt_required_argument , 0 , 'p' },
3840+ {"ht40" , sys_getopt_no_argument , 0 , 'h' },
3841+ {"vht" , sys_getopt_no_argument , 0 , 'v' },
3842+ {"he" , sys_getopt_no_argument , 0 , 'H' },
3843+ {"edmg" , sys_getopt_no_argument , 0 , 'e' },
3844+ {"go-bssid" , sys_getopt_required_argument , 0 , 'b' },
3845+ {"iface" , sys_getopt_required_argument , 0 , 'i' },
3846+ {"help" , sys_getopt_no_argument , 0 , '?' },
3847+ {0 , 0 , 0 , 0 }
3848+ };
3849+ long val ;
3850+ uint8_t mac_addr [WIFI_MAC_ADDR_LEN ];
3851+
3852+ context .sh = sh ;
3853+
3854+ params .oper = WIFI_P2P_GROUP_ADD ;
3855+ params .group_add .freq = 0 ;
3856+ params .group_add .persistent = -1 ;
3857+ params .group_add .ht40 = false;
3858+ params .group_add .vht = false;
3859+ params .group_add .he = false;
3860+ params .group_add .edmg = false;
3861+ params .group_add .go_bssid_length = 0 ;
3862+
3863+ while ((opt = sys_getopt_long (argc , argv , "f:p:hvHeb:i:?" , long_options ,
3864+ & opt_index )) != -1 ) {
3865+ state = sys_getopt_state_get ();
3866+ switch (opt ) {
3867+ case 'f' :
3868+ if (!parse_number (sh , & val , state -> optarg , "freq" , 0 , 6000 )) {
3869+ return - EINVAL ;
3870+ }
3871+ params .group_add .freq = (int )val ;
3872+ break ;
3873+ case 'p' :
3874+ if (!parse_number (sh , & val , state -> optarg , "persistent" , -1 , 255 )) {
3875+ return - EINVAL ;
3876+ }
3877+ params .group_add .persistent = (int )val ;
3878+ break ;
3879+ case 'h' :
3880+ params .group_add .ht40 = true;
3881+ break ;
3882+ case 'v' :
3883+ params .group_add .vht = true;
3884+ params .group_add .ht40 = true;
3885+ break ;
3886+ case 'H' :
3887+ params .group_add .he = true;
3888+ break ;
3889+ case 'e' :
3890+ params .group_add .edmg = true;
3891+ break ;
3892+ case 'b' :
3893+ if (sscanf (state -> optarg , "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx" ,
3894+ & mac_addr [0 ], & mac_addr [1 ], & mac_addr [2 ], & mac_addr [3 ],
3895+ & mac_addr [4 ], & mac_addr [5 ]) != WIFI_MAC_ADDR_LEN ) {
3896+ PR_ERROR ("Invalid GO BSSID format. Use: XX:XX:XX:XX:XX:XX\n" );
3897+ return - EINVAL ;
3898+ }
3899+ memcpy (params .group_add .go_bssid , mac_addr , WIFI_MAC_ADDR_LEN );
3900+ params .group_add .go_bssid_length = WIFI_MAC_ADDR_LEN ;
3901+ break ;
3902+ case 'i' :
3903+ /* Unused, but parsing to avoid unknown option error */
3904+ break ;
3905+ case '?' :
3906+ shell_help (sh );
3907+ return - ENOEXEC ;
3908+ default :
3909+ PR_ERROR ("Invalid option %c\n" , state -> optopt );
3910+ return - EINVAL ;
3911+ }
3912+ }
3913+
3914+ if (net_mgmt (NET_REQUEST_WIFI_P2P_OPER , iface , & params , sizeof (params ))) {
3915+ PR_WARNING ("P2P group add request failed\n" );
3916+ return - ENOEXEC ;
3917+ }
3918+ PR ("P2P group add initiated\n" );
3919+ return 0 ;
3920+ }
3921+
3922+ static int cmd_wifi_p2p_group_remove (const struct shell * sh , size_t argc , char * argv [])
3923+ {
3924+ struct net_if * iface = get_iface (IFACE_TYPE_STA , argc , argv );
3925+ struct wifi_p2p_params params = {0 };
3926+
3927+ context .sh = sh ;
3928+
3929+ if (argc < 2 ) {
3930+ PR_ERROR ("Interface name required. Usage: wifi p2p group_remove <ifname>\n" );
3931+ return - EINVAL ;
3932+ }
3933+
3934+ params .oper = WIFI_P2P_GROUP_REMOVE ;
3935+ strncpy (params .group_remove .ifname , argv [1 ],
3936+ CONFIG_NET_INTERFACE_NAME_LEN );
3937+ params .group_remove .ifname [CONFIG_NET_INTERFACE_NAME_LEN ] = '\0' ;
3938+
3939+ if (net_mgmt (NET_REQUEST_WIFI_P2P_OPER , iface , & params , sizeof (params ))) {
3940+ PR_WARNING ("P2P group remove request failed\n" );
3941+ return - ENOEXEC ;
3942+ }
3943+ PR ("P2P group remove initiated\n" );
3944+ return 0 ;
3945+ }
3946+
3947+ static int cmd_wifi_p2p_invite (const struct shell * sh , size_t argc , char * argv [])
3948+ {
3949+ struct net_if * iface = get_iface (IFACE_TYPE_STA , argc , argv );
3950+ struct wifi_p2p_params params = {0 };
3951+ uint8_t mac_addr [WIFI_MAC_ADDR_LEN ];
3952+ int opt ;
3953+ int opt_index = 0 ;
3954+ struct sys_getopt_state * state ;
3955+ static const struct sys_getopt_option long_options [] = {
3956+ {"persistent" , sys_getopt_required_argument , 0 , 'p' },
3957+ {"group" , sys_getopt_required_argument , 0 , 'g' },
3958+ {"peer" , sys_getopt_required_argument , 0 , 'P' },
3959+ {"freq" , sys_getopt_required_argument , 0 , 'f' },
3960+ {"go-dev-addr" , sys_getopt_required_argument , 0 , 'd' },
3961+ {"iface" , sys_getopt_required_argument , 0 , 'i' },
3962+ {"help" , sys_getopt_no_argument , 0 , 'h' },
3963+ {0 , 0 , 0 , 0 }
3964+ };
3965+ long val ;
3966+
3967+ context .sh = sh ;
3968+
3969+ params .oper = WIFI_P2P_INVITE ;
3970+ params .invite .type = WIFI_P2P_INVITE_PERSISTENT ;
3971+ params .invite .persistent_id = -1 ;
3972+ params .invite .group_ifname [0 ] = '\0' ;
3973+ params .invite .freq = 0 ;
3974+ params .invite .go_dev_addr_length = 0 ;
3975+ memset (params .invite .peer_addr , 0 , WIFI_MAC_ADDR_LEN );
3976+
3977+ if (argc < 2 ) {
3978+ PR_ERROR ("Usage: wifi p2p invite --persistent=<id> <peer MAC> OR "
3979+ "wifi p2p invite --group=<ifname> --peer=<MAC> [options]\n" );
3980+ return - EINVAL ;
3981+ }
3982+
3983+ while ((opt = sys_getopt_long (argc , argv , "p:g:P:f:d:i:h" , long_options ,
3984+ & opt_index )) != -1 ) {
3985+ state = sys_getopt_state_get ();
3986+ switch (opt ) {
3987+ case 'p' :
3988+ if (!parse_number (sh , & val , state -> optarg , "persistent" , 0 , 255 )) {
3989+ return - EINVAL ;
3990+ }
3991+ params .invite .type = WIFI_P2P_INVITE_PERSISTENT ;
3992+ params .invite .persistent_id = (int )val ;
3993+ break ;
3994+ case 'g' :
3995+ params .invite .type = WIFI_P2P_INVITE_GROUP ;
3996+ strncpy (params .invite .group_ifname , state -> optarg ,
3997+ CONFIG_NET_INTERFACE_NAME_LEN );
3998+ params .invite .group_ifname [CONFIG_NET_INTERFACE_NAME_LEN ] = '\0' ;
3999+ break ;
4000+ case 'P' :
4001+ if (sscanf (state -> optarg , "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx" ,
4002+ & mac_addr [0 ], & mac_addr [1 ], & mac_addr [2 ], & mac_addr [3 ],
4003+ & mac_addr [4 ], & mac_addr [5 ]) != WIFI_MAC_ADDR_LEN ) {
4004+ PR_ERROR ("Invalid peer MAC address format\n" );
4005+ return - EINVAL ;
4006+ }
4007+ memcpy (params .invite .peer_addr , mac_addr , WIFI_MAC_ADDR_LEN );
4008+ break ;
4009+ case 'f' :
4010+ if (!parse_number (sh , & val , state -> optarg , "freq" , 0 , 6000 )) {
4011+ return - EINVAL ;
4012+ }
4013+ params .invite .freq = (int )val ;
4014+ break ;
4015+ case 'd' :
4016+ if (sscanf (state -> optarg , "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx" ,
4017+ & mac_addr [0 ], & mac_addr [1 ], & mac_addr [2 ], & mac_addr [3 ],
4018+ & mac_addr [4 ], & mac_addr [5 ]) != WIFI_MAC_ADDR_LEN ) {
4019+ PR_ERROR ("Invalid GO device address format\n" );
4020+ return - EINVAL ;
4021+ }
4022+ memcpy (params .invite .go_dev_addr , mac_addr , WIFI_MAC_ADDR_LEN );
4023+ params .invite .go_dev_addr_length = WIFI_MAC_ADDR_LEN ;
4024+ break ;
4025+ case 'i' :
4026+ /* Unused, but parsing to avoid unknown option error */
4027+ break ;
4028+ case 'h' :
4029+ shell_help (sh );
4030+ return - ENOEXEC ;
4031+ default :
4032+ PR_ERROR ("Invalid option %c\n" , state -> optopt );
4033+ return - EINVAL ;
4034+ }
4035+ }
4036+
4037+ state = sys_getopt_state_get ();
4038+
4039+ if (params .invite .type == WIFI_P2P_INVITE_PERSISTENT &&
4040+ params .invite .persistent_id >= 0 &&
4041+ params .invite .peer_addr [0 ] == 0 && params .invite .peer_addr [1 ] == 0 &&
4042+ argc > state -> optind && argv [state -> optind ][0 ] != '-' ) {
4043+ if (sscanf (argv [state -> optind ], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx" ,
4044+ & mac_addr [0 ], & mac_addr [1 ], & mac_addr [2 ], & mac_addr [3 ],
4045+ & mac_addr [4 ], & mac_addr [5 ]) != WIFI_MAC_ADDR_LEN ) {
4046+ PR_ERROR ("Invalid peer MAC address format\n" );
4047+ return - EINVAL ;
4048+ }
4049+ memcpy (params .invite .peer_addr , mac_addr , WIFI_MAC_ADDR_LEN );
4050+ }
4051+
4052+ if (params .invite .type == WIFI_P2P_INVITE_PERSISTENT ) {
4053+ if (params .invite .persistent_id < 0 ) {
4054+ PR_ERROR ("Persistent group ID required. Use --persistent=<id>\n" );
4055+ return - EINVAL ;
4056+ }
4057+ if (params .invite .peer_addr [0 ] == 0 && params .invite .peer_addr [1 ] == 0 ) {
4058+ PR_ERROR ("Peer MAC address required\n" );
4059+ return - EINVAL ;
4060+ }
4061+ } else if (params .invite .type == WIFI_P2P_INVITE_GROUP ) {
4062+ if (params .invite .group_ifname [0 ] == '\0' ) {
4063+ PR_ERROR ("Group interface name required. Use --group=<ifname>\n" );
4064+ return - EINVAL ;
4065+ }
4066+ if (params .invite .peer_addr [0 ] == 0 && params .invite .peer_addr [1 ] == 0 ) {
4067+ PR_ERROR ("Peer MAC address required. Use --peer=<MAC>\n" );
4068+ return - EINVAL ;
4069+ }
4070+ }
4071+
4072+ if (net_mgmt (NET_REQUEST_WIFI_P2P_OPER , iface , & params , sizeof (params ))) {
4073+ PR_WARNING ("P2P invite request failed\n" );
4074+ return - ENOEXEC ;
4075+ }
4076+ PR ("P2P invite initiated\n" );
4077+ return 0 ;
4078+ }
38294079#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */
38304080
38314081static int cmd_wifi_pmksa_flush (const struct shell * sh , size_t argc , char * argv [])
@@ -4572,6 +4822,35 @@ SHELL_STATIC_SUBCMD_SET_CREATE(
45724822 " wifi p2p connect 9c:b1:50:e3:81:96 pin -g 0 (displays PIN)\n"
45734823 " wifi p2p connect 9c:b1:50:e3:81:96 pin 12345670 -g 0 (uses PIN)\n" ,
45744824 cmd_wifi_p2p_connect , 3 , 5 ),
4825+ SHELL_CMD_ARG (group_add , NULL ,
4826+ "Add a P2P group (start as GO)\n"
4827+ "Usage: group_add [options]\n"
4828+ "[-f, --freq=<MHz>]: Frequency in MHz (0 = auto)\n"
4829+ "[-p, --persistent=<id>]: Persistent group ID (-1 = not persistent)\n"
4830+ "[-h, --ht40]: Enable HT40\n"
4831+ "[-v, --vht]: Enable VHT (also enables HT40)\n"
4832+ "[-H, --he]: Enable HE\n"
4833+ "[-e, --edmg]: Enable EDMG\n"
4834+ "[-b, --go-bssid=<MAC>]: GO BSSID (format: XX:XX:XX:XX:XX:XX)\n"
4835+ "[-i, --iface=<interface index>]: Interface index\n" ,
4836+ cmd_wifi_p2p_group_add , 1 , 10 ),
4837+ SHELL_CMD_ARG (group_remove , NULL ,
4838+ "Remove a P2P group\n"
4839+ "Usage: group_remove <ifname>\n"
4840+ "<ifname>: Interface name (e.g., wlan0)\n"
4841+ "[-i, --iface=<interface index>]: Interface index\n" ,
4842+ cmd_wifi_p2p_group_remove , 2 , 3 ),
4843+ SHELL_CMD_ARG (invite , NULL ,
4844+ "Invite a peer to a P2P group\n"
4845+ "Usage: invite --persistent=<id> <peer MAC> OR\n"
4846+ " invite --group=<ifname> --peer=<MAC> [options]\n"
4847+ "[-p, --persistent=<id>]: Persistent group ID\n"
4848+ "[-g, --group=<ifname>]: Group interface name\n"
4849+ "[-P, --peer=<MAC>]: Peer MAC address (format: XX:XX:XX:XX:XX:XX)\n"
4850+ "[-f, --freq=<MHz>]: Frequency in MHz (0 = auto)\n"
4851+ "[-d, --go-dev-addr=<MAC>]: GO device address (for group type)\n"
4852+ "[-i, --iface=<interface index>]: Interface index\n" ,
4853+ cmd_wifi_p2p_invite , 2 , 8 ),
45754854 SHELL_SUBCMD_SET_END
45764855);
45774856
0 commit comments