net: wifi: Add Wi-Fi direct P2P discovery API support
Add supplicant api and mgmt ops support for P2P discovery. Signed-off-by: Kapil Bhatt <kapil.bhatt@nordicsemi.no>
This commit is contained in:
committed by
Henrik Brix Andersen
parent
3ac9a46aba
commit
84db77c46b
@@ -139,6 +139,8 @@ enum net_request_wifi_cmd {
|
||||
NET_REQUEST_WIFI_CMD_BSS_MAX_IDLE_PERIOD,
|
||||
/** Configure background scanning */
|
||||
NET_REQUEST_WIFI_CMD_BGSCAN,
|
||||
/** Wi-Fi Direct (P2P) operations*/
|
||||
NET_REQUEST_WIFI_CMD_P2P_OPER,
|
||||
/** @cond INTERNAL_HIDDEN */
|
||||
NET_REQUEST_WIFI_CMD_MAX
|
||||
/** @endcond */
|
||||
@@ -339,6 +341,11 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_BSS_MAX_IDLE_PERIOD);
|
||||
|
||||
NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_BGSCAN);
|
||||
|
||||
#define NET_REQUEST_WIFI_P2P_OPER \
|
||||
(NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_P2P_OPER)
|
||||
|
||||
NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_P2P_OPER);
|
||||
|
||||
/** @cond INTERNAL_HIDDEN */
|
||||
|
||||
enum {
|
||||
@@ -359,7 +366,7 @@ enum {
|
||||
NET_EVENT_WIFI_CMD_AP_STA_CONNECTED_VAL,
|
||||
NET_EVENT_WIFI_CMD_AP_STA_DISCONNECTED_VAL,
|
||||
NET_EVENT_WIFI_CMD_SUPPLICANT_VAL,
|
||||
|
||||
NET_EVENT_WIFI_CMD_P2P_DEVICE_FOUND_VAL,
|
||||
NET_EVENT_WIFI_CMD_MAX,
|
||||
};
|
||||
|
||||
@@ -406,6 +413,8 @@ enum net_event_wifi_cmd {
|
||||
NET_MGMT_CMD(NET_EVENT_WIFI_CMD_AP_STA_DISCONNECTED),
|
||||
/** Supplicant specific event */
|
||||
NET_MGMT_CMD(NET_EVENT_WIFI_CMD_SUPPLICANT),
|
||||
/** P2P device found */
|
||||
NET_MGMT_CMD(NET_EVENT_WIFI_CMD_P2P_DEVICE_FOUND),
|
||||
};
|
||||
|
||||
/** Event emitted for Wi-Fi scan result */
|
||||
@@ -468,6 +477,51 @@ enum net_event_wifi_cmd {
|
||||
#define NET_EVENT_WIFI_AP_STA_DISCONNECTED \
|
||||
(NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_AP_STA_DISCONNECTED)
|
||||
|
||||
/** Event emitted for P2P device found event */
|
||||
#define NET_EVENT_WIFI_P2P_DEVICE_FOUND \
|
||||
(NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_P2P_DEVICE_FOUND)
|
||||
|
||||
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
|
||||
/** Maximum length for P2P device name */
|
||||
#define WIFI_P2P_DEVICE_NAME_MAX_LEN 32
|
||||
/** Size of P2P primary device type (8 bytes) */
|
||||
#define WIFI_P2P_PRI_DEV_TYPE_SIZE 8
|
||||
/** Maximum length for P2P primary device type string */
|
||||
#define WIFI_P2P_PRI_DEV_TYPE_STR_MAX_LEN 32
|
||||
/** Maximum length for P2P WPS configuration methods string */
|
||||
#define WIFI_P2P_CONFIG_METHODS_STR_MAX_LEN 16
|
||||
/** Maximum length for P2P manufacturer name */
|
||||
#define WIFI_P2P_MANUFACTURER_MAX_LEN 64
|
||||
/** Maximum length for P2P model name */
|
||||
#define WIFI_P2P_MODEL_NAME_MAX_LEN 32
|
||||
|
||||
/** @brief Wi-Fi P2P device info */
|
||||
struct wifi_p2p_device_info {
|
||||
/** Device MAC address */
|
||||
uint8_t mac[WIFI_MAC_ADDR_LEN];
|
||||
/** Device name (max 32 chars + null terminator) */
|
||||
char device_name[WIFI_P2P_DEVICE_NAME_MAX_LEN + 1];
|
||||
/** Primary device type */
|
||||
uint8_t pri_dev_type[WIFI_P2P_PRI_DEV_TYPE_SIZE];
|
||||
/** Primary device type string */
|
||||
char pri_dev_type_str[WIFI_P2P_PRI_DEV_TYPE_STR_MAX_LEN];
|
||||
/** Signal strength (RSSI) */
|
||||
int8_t rssi;
|
||||
/** WPS configuration methods supported */
|
||||
uint16_t config_methods;
|
||||
/** WPS configuration methods string */
|
||||
char config_methods_str[WIFI_P2P_CONFIG_METHODS_STR_MAX_LEN];
|
||||
/** Device capability */
|
||||
uint8_t dev_capab;
|
||||
/** Group capability */
|
||||
uint8_t group_capab;
|
||||
/** Manufacturer (max 64 chars + null terminator) */
|
||||
char manufacturer[WIFI_P2P_MANUFACTURER_MAX_LEN + 1];
|
||||
/** Model name (max 32 chars + null terminator) */
|
||||
char model_name[WIFI_P2P_MODEL_NAME_MAX_LEN + 1];
|
||||
};
|
||||
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */
|
||||
|
||||
/** @brief Wi-Fi version */
|
||||
struct wifi_version {
|
||||
/** Driver version */
|
||||
@@ -1114,6 +1168,9 @@ union wifi_mgmt_events {
|
||||
#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */
|
||||
struct wifi_twt_params twt_params;
|
||||
struct wifi_ap_sta_info ap_sta_info;
|
||||
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
|
||||
struct wifi_p2p_device_info p2p_device_info;
|
||||
#endif
|
||||
};
|
||||
|
||||
/** @endcond */
|
||||
@@ -1397,6 +1454,51 @@ struct wifi_wps_config_params {
|
||||
char pin[WIFI_WPS_PIN_MAX_LEN + 1];
|
||||
};
|
||||
|
||||
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
|
||||
/** Wi-Fi P2P operation */
|
||||
enum wifi_p2p_op {
|
||||
/** P2P find/discovery */
|
||||
WIFI_P2P_FIND = 0,
|
||||
/** P2P stop find/discovery */
|
||||
WIFI_P2P_STOP_FIND,
|
||||
/** P2P query peer info use broadcast MAC (ff:ff:ff:ff:ff:ff) to list all peers,
|
||||
* or specific MAC address to query a single peer
|
||||
*/
|
||||
WIFI_P2P_PEER,
|
||||
};
|
||||
|
||||
/** Wi-Fi P2P discovery type */
|
||||
enum wifi_p2p_discovery_type {
|
||||
/** Start with full scan, then only social channels */
|
||||
WIFI_P2P_FIND_START_WITH_FULL = 0,
|
||||
/** Only social channels (1, 6, 11) */
|
||||
WIFI_P2P_FIND_ONLY_SOCIAL,
|
||||
/** Progressive - scan through all channels one at a time */
|
||||
WIFI_P2P_FIND_PROGRESSIVE,
|
||||
};
|
||||
|
||||
/** Maximum number of P2P peers that can be returned in a single query */
|
||||
#define WIFI_P2P_MAX_PEERS CONFIG_WIFI_P2P_MAX_PEERS
|
||||
|
||||
/** Wi-Fi P2P parameters */
|
||||
struct wifi_p2p_params {
|
||||
/** P2P operation */
|
||||
enum wifi_p2p_op oper;
|
||||
/** Discovery type (for find operation) */
|
||||
enum wifi_p2p_discovery_type discovery_type;
|
||||
/** Timeout in seconds (0 = no timeout, run until stopped) */
|
||||
uint16_t timeout;
|
||||
/** Peer device address (for peer operation) */
|
||||
uint8_t peer_addr[WIFI_MAC_ADDR_LEN];
|
||||
/** Flag to list only discovered peers (for peers operation) */
|
||||
bool discovered_only;
|
||||
/** Pointer to array for peer info results */
|
||||
struct wifi_p2p_device_info *peers;
|
||||
/** Actual number of peers returned */
|
||||
uint16_t peer_count;
|
||||
};
|
||||
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */
|
||||
|
||||
/** Wi-Fi AP status
|
||||
*/
|
||||
enum wifi_sap_iface_state {
|
||||
@@ -1785,6 +1887,17 @@ struct wifi_mgmt_ops {
|
||||
*/
|
||||
int (*set_bgscan)(const struct device *dev, struct wifi_bgscan_params *params);
|
||||
#endif
|
||||
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
|
||||
/** Wi-Fi Direct (P2P) operations for device discovery
|
||||
*
|
||||
* @param dev Pointer to the device structure for the driver instance.
|
||||
* @param params P2P operation parameters including operation type, discovery settings,
|
||||
* timeout values and peer information retrieval options
|
||||
*
|
||||
* @return 0 if ok, < 0 if error
|
||||
*/
|
||||
int (*p2p_oper)(const struct device *dev, struct wifi_p2p_params *params);
|
||||
#endif
|
||||
};
|
||||
|
||||
/** Wi-Fi management offload API */
|
||||
@@ -1916,6 +2029,17 @@ void wifi_mgmt_raise_ap_sta_connected_event(struct net_if *iface,
|
||||
void wifi_mgmt_raise_ap_sta_disconnected_event(struct net_if *iface,
|
||||
struct wifi_ap_sta_info *sta_info);
|
||||
|
||||
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
|
||||
/**
|
||||
* @brief Raise P2P device found event
|
||||
*
|
||||
* @param iface Network interface
|
||||
* @param device_info P2P device information
|
||||
*/
|
||||
void wifi_mgmt_raise_p2p_device_found_event(struct net_if *iface,
|
||||
struct wifi_p2p_device_info *peer_info);
|
||||
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -61,6 +61,14 @@ enum status_thread_state {
|
||||
static struct wifi_enterprise_creds_params enterprise_creds;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
|
||||
#define P2P_CMD_BUF_SIZE 128
|
||||
#define P2P_RESP_BUF_SIZE 64
|
||||
#define P2P_PEER_INFO_SIZE 512
|
||||
#define P2P_ADDR_SIZE 32
|
||||
#define P2P_CMD_SIZE 64
|
||||
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */
|
||||
|
||||
K_MUTEX_DEFINE(wpa_supplicant_mutex);
|
||||
|
||||
extern struct k_work_q *get_workq(void);
|
||||
@@ -2607,3 +2615,249 @@ out:
|
||||
k_mutex_unlock(&wpa_supplicant_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
|
||||
static inline void extract_value(const char *src, char *dest, size_t dest_size)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
while (src[i] != '\0' && src[i] != '\n' && i < dest_size - 1) {
|
||||
dest[i] = src[i];
|
||||
i++;
|
||||
}
|
||||
dest[i] = '\0';
|
||||
}
|
||||
|
||||
static void parse_peer_info_line(const char *line, struct wifi_p2p_device_info *info)
|
||||
{
|
||||
const char *pos;
|
||||
|
||||
if (strncmp(line, "device_name=", 12) == 0) {
|
||||
extract_value(line + 12, info->device_name, sizeof(info->device_name));
|
||||
} else if (strncmp(line, "pri_dev_type=", 13) == 0) {
|
||||
extract_value(line + 13, info->pri_dev_type_str, sizeof(info->pri_dev_type_str));
|
||||
} else if (strncmp(line, "level=", 6) == 0) {
|
||||
char *endptr;
|
||||
long val;
|
||||
|
||||
pos = line + 6;
|
||||
val = strtol(pos, &endptr, 10);
|
||||
if (endptr != pos && val >= INT8_MIN && val <= INT8_MAX) {
|
||||
info->rssi = (int8_t)val;
|
||||
}
|
||||
} else if (strncmp(line, "config_methods=", 15) == 0) {
|
||||
char *endptr;
|
||||
long val;
|
||||
|
||||
pos = line + 15;
|
||||
extract_value(pos, info->config_methods_str, sizeof(info->config_methods_str));
|
||||
|
||||
if (pos[0] == '0' && (pos[1] == 'x' || pos[1] == 'X')) {
|
||||
val = strtol(pos, &endptr, 16);
|
||||
} else {
|
||||
val = strtol(pos, &endptr, 10);
|
||||
}
|
||||
if (endptr != pos && val >= 0 && val <= UINT16_MAX) {
|
||||
info->config_methods = (uint16_t)val;
|
||||
}
|
||||
} else if (strncmp(line, "manufacturer=", 13) == 0) {
|
||||
extract_value(line + 13, info->manufacturer, sizeof(info->manufacturer));
|
||||
} else if (strncmp(line, "model_name=", 11) == 0) {
|
||||
extract_value(line + 11, info->model_name, sizeof(info->model_name));
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_peer_info_response(const char *resp, const uint8_t *mac,
|
||||
struct wifi_p2p_device_info *info)
|
||||
{
|
||||
const char *line = resp;
|
||||
const char *next_line;
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
if (mac != NULL) {
|
||||
memcpy(info->mac, mac, WIFI_MAC_ADDR_LEN);
|
||||
}
|
||||
|
||||
while (line != NULL && *line != '\0') {
|
||||
if (*line == '\n') {
|
||||
line++;
|
||||
continue;
|
||||
}
|
||||
next_line = strchr(line, '\n');
|
||||
parse_peer_info_line(line, info);
|
||||
if (next_line != NULL) {
|
||||
line = next_line + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int supplicant_p2p_oper(const struct device *dev, struct wifi_p2p_params *params)
|
||||
{
|
||||
struct wpa_supplicant *wpa_s = get_wpa_s_handle(dev);
|
||||
char cmd_buf[P2P_CMD_BUF_SIZE];
|
||||
char resp_buf[P2P_RESP_BUF_SIZE];
|
||||
int ret = -1;
|
||||
const char *discovery_type_str = "";
|
||||
|
||||
if (wpa_s == NULL || wpa_s->ctrl_conn == NULL) {
|
||||
wpa_printf(MSG_ERROR, "wpa_supplicant control interface not initialized");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
switch (params->oper) {
|
||||
case WIFI_P2P_FIND:
|
||||
switch (params->discovery_type) {
|
||||
case WIFI_P2P_FIND_ONLY_SOCIAL:
|
||||
discovery_type_str = "type=social";
|
||||
break;
|
||||
case WIFI_P2P_FIND_PROGRESSIVE:
|
||||
discovery_type_str = "type=progressive";
|
||||
break;
|
||||
case WIFI_P2P_FIND_START_WITH_FULL:
|
||||
default:
|
||||
discovery_type_str = "";
|
||||
break;
|
||||
}
|
||||
|
||||
if (params->timeout > 0) {
|
||||
if (strlen(discovery_type_str) > 0) {
|
||||
snprintk(cmd_buf, sizeof(cmd_buf), "P2P_FIND %u %s",
|
||||
params->timeout, discovery_type_str);
|
||||
} else {
|
||||
snprintk(cmd_buf, sizeof(cmd_buf), "P2P_FIND %u",
|
||||
params->timeout);
|
||||
}
|
||||
} else {
|
||||
if (strlen(discovery_type_str) > 0) {
|
||||
snprintk(cmd_buf, sizeof(cmd_buf), "P2P_FIND %s",
|
||||
discovery_type_str);
|
||||
} else {
|
||||
snprintk(cmd_buf, sizeof(cmd_buf), "P2P_FIND");
|
||||
}
|
||||
}
|
||||
ret = zephyr_wpa_cli_cmd_resp_noprint(wpa_s->ctrl_conn, cmd_buf, resp_buf);
|
||||
if (ret < 0) {
|
||||
wpa_printf(MSG_ERROR, "P2P_FIND command failed: %d", ret);
|
||||
return -EIO;
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case WIFI_P2P_STOP_FIND:
|
||||
snprintk(cmd_buf, sizeof(cmd_buf), "P2P_STOP_FIND");
|
||||
ret = zephyr_wpa_cli_cmd_resp_noprint(wpa_s->ctrl_conn, cmd_buf, resp_buf);
|
||||
if (ret < 0) {
|
||||
wpa_printf(MSG_ERROR, "P2P_STOP_FIND command failed: %d", ret);
|
||||
return -EIO;
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case WIFI_P2P_PEER: {
|
||||
char addr[P2P_ADDR_SIZE];
|
||||
char cmd[P2P_CMD_SIZE];
|
||||
char peer_info[P2P_PEER_INFO_SIZE];
|
||||
char *pos;
|
||||
size_t len;
|
||||
uint16_t peer_idx = 0;
|
||||
uint8_t mac[WIFI_MAC_ADDR_LEN];
|
||||
struct net_eth_addr peer_mac;
|
||||
bool query_all_peers;
|
||||
|
||||
if (params->peers == NULL) {
|
||||
wpa_printf(MSG_ERROR, "Peer info array not provided");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(&peer_mac, params->peer_addr, WIFI_MAC_ADDR_LEN);
|
||||
query_all_peers = net_eth_is_addr_broadcast(&peer_mac);
|
||||
|
||||
if (query_all_peers == true) {
|
||||
snprintk(cmd_buf, sizeof(cmd_buf), "P2P_PEER FIRST");
|
||||
|
||||
while (peer_idx < params->peer_count) {
|
||||
ret = zephyr_wpa_cli_cmd_resp_noprint(wpa_s->ctrl_conn,
|
||||
cmd_buf, resp_buf);
|
||||
|
||||
if (ret < 0 || resp_buf[0] == '\0' ||
|
||||
strncmp(resp_buf, "FAIL", 4) == 0) {
|
||||
if (peer_idx == 0) {
|
||||
wpa_printf(MSG_DEBUG, "No P2P peers found");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
len = 0;
|
||||
pos = resp_buf;
|
||||
while (*pos != '\0' && *pos != '\n' && len < sizeof(addr) - 1) {
|
||||
addr[len++] = *pos++;
|
||||
}
|
||||
addr[len] = '\0';
|
||||
|
||||
if (strncmp(addr, "00:00:00:00:00:00", 17) != 0 &&
|
||||
sscanf(addr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
|
||||
&mac[0], &mac[1], &mac[2],
|
||||
&mac[3], &mac[4], &mac[5]) ==
|
||||
WIFI_MAC_ADDR_LEN) {
|
||||
|
||||
snprintk(cmd, sizeof(cmd), "P2P_PEER %s", addr);
|
||||
ret = zephyr_wpa_cli_cmd_resp_noprint(
|
||||
wpa_s->ctrl_conn, cmd, peer_info);
|
||||
|
||||
if (ret >= 0 &&
|
||||
(!params->discovered_only ||
|
||||
strstr(peer_info,
|
||||
"[PROBE_REQ_ONLY]") == NULL)) {
|
||||
parse_peer_info_response(peer_info,
|
||||
mac,
|
||||
¶ms->peers[peer_idx]);
|
||||
peer_idx++;
|
||||
}
|
||||
}
|
||||
snprintk(cmd_buf, sizeof(cmd_buf), "P2P_PEER NEXT-%s", addr);
|
||||
}
|
||||
params->peer_count = peer_idx;
|
||||
} else {
|
||||
char addr_str[18];
|
||||
|
||||
if (params->peer_count < 1) {
|
||||
wpa_printf(MSG_ERROR, "Peer count must be at least 1");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
snprintk(addr_str, sizeof(addr_str), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
params->peer_addr[0], params->peer_addr[1], params->peer_addr[2],
|
||||
params->peer_addr[3], params->peer_addr[4], params->peer_addr[5]);
|
||||
snprintk(cmd_buf, sizeof(cmd_buf), "P2P_PEER %s", addr_str);
|
||||
|
||||
/* Use peer_info buffer for single peer query to avoid large resp_buf */
|
||||
ret = zephyr_wpa_cli_cmd_resp_noprint(wpa_s->ctrl_conn,
|
||||
cmd_buf, peer_info);
|
||||
if (ret < 0) {
|
||||
wpa_printf(MSG_ERROR, "P2P_PEER command failed: %d", ret);
|
||||
return -EIO;
|
||||
}
|
||||
if (strncmp(peer_info, "FAIL", 4) == 0) {
|
||||
wpa_printf(MSG_ERROR, "Peer %s not found", addr_str);
|
||||
return -ENODEV;
|
||||
}
|
||||
parse_peer_info_response(peer_info, params->peer_addr,
|
||||
¶ms->peers[0]);
|
||||
params->peer_count = 1;
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
wpa_printf(MSG_ERROR, "Unknown P2P operation: %d", params->oper);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */
|
||||
|
||||
@@ -386,4 +386,16 @@ int supplicant_dpp_dispatch(const struct device *dev, struct wifi_dpp_params *pa
|
||||
* @return 0 for OK; -1 for ERROR
|
||||
*/
|
||||
int supplicant_config_params(const struct device *dev, struct wifi_config_params *params);
|
||||
|
||||
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
|
||||
/**
|
||||
* @brief P2P operation
|
||||
*
|
||||
* @param dev Wi-Fi interface handle to use
|
||||
* @param params P2P parameters
|
||||
* @return 0 for OK; -1 for ERROR
|
||||
*/
|
||||
int supplicant_p2p_oper(const struct device *dev, struct wifi_p2p_params *params);
|
||||
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */
|
||||
|
||||
#endif /* ZEPHYR_SUPP_MGMT_H */
|
||||
|
||||
@@ -43,6 +43,9 @@ static const struct wpa_supp_event_info {
|
||||
{ "CTRL-EVENT-NETWORK-REMOVED", SUPPLICANT_EVENT_NETWORK_REMOVED },
|
||||
{ "CTRL-EVENT-DSCP-POLICY", SUPPLICANT_EVENT_DSCP_POLICY },
|
||||
{ "CTRL-EVENT-REGDOM-CHANGE", SUPPLICANT_EVENT_REGDOM_CHANGE },
|
||||
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
|
||||
{ "P2P-DEVICE-FOUND", SUPPLICANT_EVENT_P2P_DEVICE_FOUND },
|
||||
#endif
|
||||
};
|
||||
|
||||
static void copy_mac_addr(const unsigned int *src, uint8_t *dst)
|
||||
@@ -174,6 +177,43 @@ static int supplicant_process_status(struct supplicant_int_event_data *event_dat
|
||||
event_data->data_len = sizeof(data->bss_removed);
|
||||
copy_mac_addr(tmp_mac_addr, data->bss_removed.bssid);
|
||||
break;
|
||||
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
|
||||
case SUPPLICANT_EVENT_P2P_DEVICE_FOUND:
|
||||
{
|
||||
char *ptr, *name_start, *name_end;
|
||||
unsigned int config_methods = 0;
|
||||
|
||||
memset(&data->p2p_device_found, 0, sizeof(data->p2p_device_found));
|
||||
ret = sscanf(event_no_prefix, MACSTR, MACADDR2STR(tmp_mac_addr));
|
||||
if (ret > 0) {
|
||||
copy_mac_addr(tmp_mac_addr, data->p2p_device_found.mac);
|
||||
}
|
||||
name_start = strstr(event_no_prefix, "name='");
|
||||
if (name_start) {
|
||||
name_start += 6;
|
||||
name_end = strchr(name_start, '\'');
|
||||
if (name_end) {
|
||||
size_t name_len = name_end - name_start;
|
||||
|
||||
if (name_len >= sizeof(data->p2p_device_found.device_name)) {
|
||||
name_len = sizeof(data->p2p_device_found.device_name) - 1;
|
||||
}
|
||||
memcpy(data->p2p_device_found.device_name, name_start, name_len);
|
||||
data->p2p_device_found.device_name[name_len] = '\0';
|
||||
}
|
||||
}
|
||||
ptr = strstr(event_no_prefix, "config_methods=");
|
||||
if (ptr) {
|
||||
ret = sscanf(ptr, "config_methods=%x", &config_methods);
|
||||
if (ret > 0) {
|
||||
data->p2p_device_found.config_methods = config_methods;
|
||||
}
|
||||
}
|
||||
event_data->data_len = sizeof(data->p2p_device_found);
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case SUPPLICANT_EVENT_TERMINATING:
|
||||
case SUPPLICANT_EVENT_SCAN_STARTED:
|
||||
case SUPPLICANT_EVENT_SCAN_RESULTS:
|
||||
@@ -386,8 +426,18 @@ int supplicant_send_wifi_mgmt_event(const char *ifname, enum net_event_wifi_cmd
|
||||
case NET_EVENT_WIFI_CMD_SUPPLICANT:
|
||||
event_data.data = &data;
|
||||
if (supplicant_process_status(&event_data, (char *)supplicant_status) > 0) {
|
||||
net_mgmt_event_notify_with_info(NET_EVENT_SUPPLICANT_INT_EVENT,
|
||||
iface, &event_data, sizeof(event_data));
|
||||
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
|
||||
/* Handle P2P events directly */
|
||||
if (event_data.event == SUPPLICANT_EVENT_P2P_DEVICE_FOUND) {
|
||||
wifi_mgmt_raise_p2p_device_found_event(iface,
|
||||
&data.p2p_device_found);
|
||||
} else {
|
||||
#endif
|
||||
net_mgmt_event_notify_with_info(NET_EVENT_SUPPLICANT_INT_EVENT,
|
||||
iface, &event_data, sizeof(event_data));
|
||||
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -137,6 +137,10 @@ union supplicant_event_data {
|
||||
unsigned int id;
|
||||
} network_removed;
|
||||
|
||||
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
|
||||
struct wifi_p2p_device_info p2p_device_found;
|
||||
#endif
|
||||
|
||||
char supplicant_event_str[NM_WIFI_EVENT_STR_LEN];
|
||||
};
|
||||
|
||||
@@ -158,6 +162,9 @@ enum supplicant_event_num {
|
||||
SUPPLICANT_EVENT_NETWORK_REMOVED,
|
||||
SUPPLICANT_EVENT_DSCP_POLICY,
|
||||
SUPPLICANT_EVENT_REGDOM_CHANGE,
|
||||
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
|
||||
SUPPLICANT_EVENT_P2P_DEVICE_FOUND,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct supplicant_int_event_data {
|
||||
|
||||
@@ -100,6 +100,9 @@ static const struct wifi_mgmt_ops mgmt_ops = {
|
||||
.enterprise_creds = supplicant_add_enterprise_creds,
|
||||
#endif
|
||||
.config_params = supplicant_config_params,
|
||||
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
|
||||
.p2p_oper = supplicant_p2p_oper,
|
||||
#endif
|
||||
};
|
||||
|
||||
DEFINE_WIFI_NM_INSTANCE(wifi_supplicant, &mgmt_ops);
|
||||
@@ -244,6 +247,12 @@ static void zephyr_wpa_supplicant_msg(void *ctx, const char *txt, size_t len)
|
||||
supplicant_send_wifi_mgmt_event(wpa_s->ifname,
|
||||
NET_EVENT_WIFI_CMD_NEIGHBOR_REP_RECEIVED,
|
||||
(void *)txt, len);
|
||||
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
|
||||
} else if (strncmp(txt, "P2P-", 4) == 0) {
|
||||
supplicant_send_wifi_mgmt_event(wpa_s->ifname,
|
||||
NET_EVENT_WIFI_CMD_SUPPLICANT,
|
||||
(void *)txt, len);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,15 @@ config WIFI_SHELL_MAX_AP_STA
|
||||
This option defines the maximum number of APs and STAs that can be managed
|
||||
in Wi-Fi shell.
|
||||
|
||||
config WIFI_P2P_MAX_PEERS
|
||||
int "Maximum number of P2P peers that can be returned in a single query"
|
||||
depends on WIFI_NM_WPA_SUPPLICANT_P2P
|
||||
default 32
|
||||
range 1 256
|
||||
help
|
||||
This option defines the maximum number of P2P peers that can be returned
|
||||
in a single query operation.
|
||||
|
||||
config WIFI_NM
|
||||
bool "Wi-Fi Network manager support"
|
||||
help
|
||||
|
||||
@@ -1474,6 +1474,35 @@ static int wifi_set_bgscan(uint64_t mgmt_request, struct net_if *iface, void *da
|
||||
|
||||
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_BGSCAN, wifi_set_bgscan);
|
||||
#endif
|
||||
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P
|
||||
static int wifi_p2p_oper(uint64_t mgmt_request, struct net_if *iface,
|
||||
void *data, size_t len)
|
||||
{
|
||||
const struct device *dev = net_if_get_device(iface);
|
||||
const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
|
||||
struct wifi_p2p_params *params = data;
|
||||
|
||||
if (wifi_mgmt_api == NULL || wifi_mgmt_api->p2p_oper == NULL) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (data == NULL || len != sizeof(*params)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return wifi_mgmt_api->p2p_oper(dev, params);
|
||||
}
|
||||
|
||||
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_P2P_OPER, wifi_p2p_oper);
|
||||
|
||||
void wifi_mgmt_raise_p2p_device_found_event(struct net_if *iface,
|
||||
struct wifi_p2p_device_info *peer_info)
|
||||
{
|
||||
net_mgmt_event_notify_with_info(NET_EVENT_WIFI_P2P_DEVICE_FOUND,
|
||||
iface, peer_info,
|
||||
sizeof(*peer_info));
|
||||
}
|
||||
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */
|
||||
|
||||
#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS
|
||||
void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface,
|
||||
|
||||
Reference in New Issue
Block a user