Files
wifimngr/policy.c
2025-10-14 11:22:07 +02:00

546 lines
16 KiB
C

/* SPDX-License-Identifier: GPL-2.0-only */
/*
* policy.c - provides attribute names and policies for commands.
*
* Copyright (C) 2022-2024 IOPSYS Software Solutions AB. All rights reserved.
* Copyright (C) 2025 Genexis AB.
*
*/
enum {
SCAN_SSID,
SCAN_BSSID,
SCAN_CHANNEL,
SCAN_OPCLASS,
/* SCAN_TYPE, // active, passsive, background */
__SCAN_MAX,
};
static const struct blobmsg_policy wl_scan_policy[__SCAN_MAX] = {
[SCAN_SSID] = { .name = "ssid", .type = BLOBMSG_TYPE_STRING },
[SCAN_BSSID] = { .name = "bssid", .type = BLOBMSG_TYPE_STRING },
[SCAN_CHANNEL] = { .name = "channel", .type = BLOBMSG_TYPE_INT32 },
[SCAN_OPCLASS] = { .name = "opclass", .type = BLOBMSG_TYPE_INT32 },
/* [SCAN_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_INT32 }, */
};
enum {
SCAN_EX_SSID,
SCAN_EX_BSSID,
SCAN_EX_OPCLASS,
SCAN_EX_CHANNEL,
// SCAN_EX_TYPE, // active, passsive, cached */
SCAN_EX_DURATION,
__SCAN_EX_MAX,
};
static const struct blobmsg_policy wl_scan_ex_policy[__SCAN_EX_MAX] = {
[SCAN_EX_SSID] = { .name = "ssid", .type = BLOBMSG_TYPE_ARRAY },
[SCAN_EX_BSSID] = { .name = "bssid", .type = BLOBMSG_TYPE_STRING },
[SCAN_EX_OPCLASS] = { .name = "opclass", .type = BLOBMSG_TYPE_ARRAY },
[SCAN_EX_CHANNEL] = { .name = "channel", .type = BLOBMSG_TYPE_ARRAY },
// [SCAN_EX_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_INT32 },
[SCAN_EX_DURATION] = { .name = "duration", .type = BLOBMSG_TYPE_INT16 },
};
enum {
SCANRES_BSSID,
SCANRES_CACHE,
__SCANRES_MAX,
};
static const struct blobmsg_policy wl_scanres_policy[__SCANRES_MAX] = {
[SCANRES_BSSID] = { .name = "bssid", .type = BLOBMSG_TYPE_STRING },
[SCANRES_CACHE] = { .name = "cache", .type = BLOBMSG_TYPE_BOOL },
};
enum {
ACS_PARAM_EXCLUDE_DFS,
ACS_PARAM_EXCLUDE_6GHZ_NON_PSC,
ACS_PARAM_EXCLUDE_OPCLASS,
ACS_PARAM_EXCLUDE_CHANNELS,
ACS_PARAM_EXCLUDE_BANDWIDTH,
ACS_PARAM_INCLUDE_CHANNELS,
ACS_PARAM_INCLUDE_BANDWIDTH,
ACS_PARAM_MODE,
NUM_ACS_PARAMS,
};
enum {
ACS_PARAM_CHANNEL_NUMBER,
ACS_PARAM_CHANNEL_BANDWIDTH,
ACS_PARAM_CHANNEL_WEIGHT,
NUM_ACS_CHANNEL_PARAMS,
};
static const struct blobmsg_policy wl_acs_policy[NUM_ACS_PARAMS] = {
[ACS_PARAM_EXCLUDE_DFS] = { .name = "exclude_dfs", .type = BLOBMSG_TYPE_BOOL },
[ACS_PARAM_EXCLUDE_6GHZ_NON_PSC] = { .name = "exclude_6ghz_non_psc", .type = BLOBMSG_TYPE_BOOL },
[ACS_PARAM_EXCLUDE_OPCLASS] = { .name = "exclude_opclass", .type = BLOBMSG_TYPE_ARRAY},
[ACS_PARAM_EXCLUDE_CHANNELS] = { .name = "exclude_channels", .type = BLOBMSG_TYPE_ARRAY},
[ACS_PARAM_EXCLUDE_BANDWIDTH] = { .name = "exclude_bandwidth", .type = BLOBMSG_TYPE_ARRAY},
[ACS_PARAM_INCLUDE_CHANNELS] = { .name = "channels", .type = BLOBMSG_TYPE_ARRAY},
[ACS_PARAM_INCLUDE_BANDWIDTH] = { .name = "bandwidth", .type = BLOBMSG_TYPE_ARRAY},
[ACS_PARAM_MODE] = { .name = "mode", .type = BLOBMSG_TYPE_STRING},
};
enum {
CAC_CHANNEL,
CAC_BANDWIDTH,
CAC_METHOD,
__CAC_MAX,
};
static const struct blobmsg_policy wl_cac_policy[__CAC_MAX] = {
[CAC_CHANNEL] = { .name = "channel", .type = BLOBMSG_TYPE_INT32 },
[CAC_BANDWIDTH] = { .name = "bandwidth", .type = BLOBMSG_TYPE_INT32 },
[CAC_METHOD] = { .name = "method", .type = BLOBMSG_TYPE_INT32 },
};
enum {
ADD_IFACE_ARGS,
ADD_IFACE_CONF,
__ADD_IFACE_MAX,
};
static const struct blobmsg_policy add_iface_policy[__ADD_IFACE_MAX] = {
[ADD_IFACE_ARGS] = { .name = "args", .type = BLOBMSG_TYPE_TABLE },
[ADD_IFACE_CONF] = { .name = "config", .type = BLOBMSG_TYPE_BOOL },
};
enum {
DEL_IFACE_IFNAME,
DEL_IFACE_CONF,
__DEL_IFACE_MAX,
};
static const struct blobmsg_policy del_iface_policy[__DEL_IFACE_MAX] = {
[DEL_IFACE_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING },
[DEL_IFACE_CONF] = { .name = "config", .type = BLOBMSG_TYPE_BOOL },
};
enum {
DUMP_CHANNELS_FOR_BANDWIDTH,
NUM_DUMP_CHANNELS,
};
static const struct blobmsg_policy wl_dump_channels_policy[NUM_DUMP_CHANNELS] = {
[DUMP_CHANNELS_FOR_BANDWIDTH] = { .name = "bandwidth", .type = BLOBMSG_TYPE_INT32 },
};
enum {
RADAR_CHANNEL,
RADAR_BANDWIDTH,
RADAR_TYPE,
RADAR_SUBBAND_MASK,
__RADAR_MAX,
};
static const struct blobmsg_policy wl_radar_policy[__RADAR_MAX] = {
[RADAR_CHANNEL] = { .name = "channel", .type = BLOBMSG_TYPE_INT32 },
[RADAR_BANDWIDTH] = { .name = "bandwidth", .type = BLOBMSG_TYPE_INT32 },
[RADAR_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_INT32 },
[RADAR_SUBBAND_MASK] = { .name = "subband_mask", .type = BLOBMSG_TYPE_INT32 },
};
enum {
GET_PNAME,
__GET_MAX,
};
static const struct blobmsg_policy radio_get_param_policy[__GET_MAX] = {
[GET_PNAME] = { .name = "param", .type = BLOBMSG_TYPE_STRING },
};
enum {
CHAN_SWITCH_COUNT,
CHAN_SWITCH_CHANNEL, /* primary ctrl-channel */
CHAN_SWITCH_FREQ,
CHAN_SWITCH_SEC_CHAN_OFFSET,
CHAN_SWITCH_CF1,
CHAN_SWITCH_CF2,
CHAN_SWITCH_BW,
CHAN_SWITCH_BLOCK_TX,
CHAN_SWITCH_HT,
CHAN_SWITCH_VHT,
CHAN_SWITCH_HE,
CHAN_SWITCH_EHT,
CHAN_SWITCH_AUTO_HT,
__CHAN_SWITCH_MAX,
};
static const struct blobmsg_policy chan_switch_policy[__CHAN_SWITCH_MAX] = {
[CHAN_SWITCH_COUNT] = { .name = "count", .type = BLOBMSG_TYPE_INT32 },
[CHAN_SWITCH_CHANNEL] = { .name = "channel", .type = BLOBMSG_TYPE_INT32 },
[CHAN_SWITCH_FREQ] = { .name = "freq", .type = BLOBMSG_TYPE_INT32 },
[CHAN_SWITCH_SEC_CHAN_OFFSET] = { .name = "sec_chan_offset", .type = BLOBMSG_TYPE_INT32 },
[CHAN_SWITCH_CF1] = { .name = "cf1", .type = BLOBMSG_TYPE_INT32 },
[CHAN_SWITCH_CF2] = { .name = "cf2", .type = BLOBMSG_TYPE_INT32 },
[CHAN_SWITCH_BW] = { .name = "bw", .type = BLOBMSG_TYPE_INT32 },
[CHAN_SWITCH_BLOCK_TX] = { .name = "blocktx", .type = BLOBMSG_TYPE_BOOL },
[CHAN_SWITCH_HT] = { .name = "ht", .type = BLOBMSG_TYPE_BOOL },
[CHAN_SWITCH_VHT] = { .name = "vht", .type = BLOBMSG_TYPE_BOOL },
[CHAN_SWITCH_HE] = { .name = "he", .type = BLOBMSG_TYPE_BOOL },
[CHAN_SWITCH_EHT] = { .name = "eht", .type = BLOBMSG_TYPE_BOOL },
[CHAN_SWITCH_AUTO_HT] = { .name = "auto-ht", .type = BLOBMSG_TYPE_BOOL },
};
enum {
DEBUG_LEVEL,
__DEBUG_LEVEL_MAX,
};
static const struct blobmsg_policy wifi_set_debug_policy[__DEBUG_LEVEL_MAX] = {
[DEBUG_LEVEL] = { .name = "level", .type = BLOBMSG_TYPE_INT32 },
};
/* detailed stainfo policy */
enum {
STAINFO_MACADDR, /* sta macaddress */
__STAINFO_MAX,
};
static const struct blobmsg_policy stainfo_policy[__STAINFO_MAX] = {
[STAINFO_MACADDR] = { .name = "sta", .type = BLOBMSG_TYPE_STRING },
};
/* list neighbors policy */
enum {
NBR_LIST_SSID, /* ssid filter */
NBR_LIST_CLIENT, /* from beacon report by client */
__NBR_LIST_MAX,
};
static const struct blobmsg_policy nbr_list_policy[__NBR_LIST_MAX] = {
[NBR_LIST_SSID] = { .name = "ssid", .type = BLOBMSG_TYPE_STRING },
[NBR_LIST_CLIENT] = { .name = "client", .type = BLOBMSG_TYPE_STRING },
};
/* sta disconnect policy */
enum {
STA_DISCONNECT_STA, /* sta mac ':' separated */
STA_DISCONNECT_REASON,
__STA_DISCONNECT_MAX,
};
static const struct blobmsg_policy sta_disconnect_policy[__STA_DISCONNECT_MAX] = {
[STA_DISCONNECT_STA] = { .name = "sta", .type = BLOBMSG_TYPE_STRING },
[STA_DISCONNECT_REASON] = { .name = "reason", .type = BLOBMSG_TYPE_INT32 }
};
/* sta monitor policy */
enum {
STA_MONITOR_ADDR, /* sta mac ':' separated */
__STA_MONITOR_MAX,
};
static const struct blobmsg_policy sta_monitor_policy[__STA_MONITOR_MAX] = {
[STA_MONITOR_ADDR] = { .name = "sta", .type = BLOBMSG_TYPE_STRING },
};
/* add neighbor policy */
enum {
NBR_ADD_BSSID, /* bssid ':' separated */
NBR_ADD_CHANNEL,
NBR_ADD_BINFO, /* bssid info; default = 0x3 (reachable) */
NBR_ADD_REG, /* regulatory; default = 0 */
NBR_ADD_PHY, /* phytype; default = 9 = PHY_VHT */
__NBR_ADD_MAX,
};
static const struct blobmsg_policy nbr_add_policy[__NBR_ADD_MAX] = {
[NBR_ADD_BSSID] = { .name = "bssid", .type = BLOBMSG_TYPE_STRING },
[NBR_ADD_CHANNEL] = { .name = "channel", .type = BLOBMSG_TYPE_INT32 },
[NBR_ADD_BINFO] = { .name = "bssid_info", .type = BLOBMSG_TYPE_STRING },
[NBR_ADD_REG] = { .name = "reg", .type = BLOBMSG_TYPE_INT32 },
[NBR_ADD_PHY] = { .name = "phy", .type = BLOBMSG_TYPE_INT32 },
};
/* delete neighbor policy */
enum {
NBR_DEL_BSSID,
__NBR_DEL_MAX,
};
static const struct blobmsg_policy nbr_del_policy[__NBR_DEL_MAX] = {
[NBR_DEL_BSSID] = { .name = "bssid", .type = BLOBMSG_TYPE_STRING },
};
/* send neighbor request policy */
enum {
NBR_REQ_CLIENT,
NBR_REQ_OPCLASS,
NBR_REQ_CHANNEL,
NBR_REQ_DURATION,
NBR_REQ_MODE,
NBR_REQ_BSSID,
NBR_REQ_REP_DETAIL,
NBR_REQ_SSID,
NBR_REQ_CHAN_REPORT,
NBR_REQ_ELEMENT_IDS,
__NBR_REQ_MAX,
};
static const struct blobmsg_policy nbr_req_policy[__NBR_REQ_MAX] = {
[NBR_REQ_CLIENT] = { .name = "client", .type = BLOBMSG_TYPE_STRING },
[NBR_REQ_OPCLASS] = { .name = "opclass", .type = BLOBMSG_TYPE_INT32 },
[NBR_REQ_CHANNEL] = { .name = "channel", .type = BLOBMSG_TYPE_INT32 },
[NBR_REQ_DURATION] = { .name = "duration", .type = BLOBMSG_TYPE_INT32 },
[NBR_REQ_MODE] = { .name = "mode", .type = BLOBMSG_TYPE_STRING },
[NBR_REQ_BSSID] = { .name = "bssid", .type = BLOBMSG_TYPE_STRING },
[NBR_REQ_REP_DETAIL] = { .name = "reporting_detail", .type = BLOBMSG_TYPE_INT32 },
[NBR_REQ_SSID] = { .name = "ssid", .type = BLOBMSG_TYPE_STRING },
[NBR_REQ_CHAN_REPORT] = { .name = "channel_report", .type = BLOBMSG_TYPE_ARRAY },
[NBR_REQ_ELEMENT_IDS] = { .name = "request_element", .type = BLOBMSG_TYPE_ARRAY },
};
/* send btm request policy */
enum {
BTM_REQ_STA,
BTM_REQ_TARGET,
BTM_REQ_MODE,
BTM_REQ_DISASSOC_TMO,
BTM_REQ_VALIDITY_INT,
BTM_REQ_DIALOG_TOKEN,
BTM_REQ_BSSTERM_DUR,
BTM_REQ_MBO_REASON, /* MBO r19, 4.2.6: Transition Reason Code Attribute (id=0x06) */
BTM_REQ_MBO_CELL_PREF, /* MBO r19, 4.2.5: Cellular Data Connection Preference (id=0x05) */
BTM_REQ_MBO_REASSOC_DELAY, /* MBO r19, 4.2.8: Assoc retry delay (id=0x08), 0-65535 */
__BTM_REQ_MAX,
};
static const struct blobmsg_policy btmreq_policy[__BTM_REQ_MAX] = {
[BTM_REQ_STA] = { .name = "sta", .type = BLOBMSG_TYPE_STRING },
[BTM_REQ_TARGET] = { .name = "target_ap", .type = BLOBMSG_TYPE_ARRAY },
[BTM_REQ_MODE] = { .name = "mode", .type = BLOBMSG_TYPE_INT32 },
[BTM_REQ_DISASSOC_TMO] = { .name = "disassoc_tmo", .type = BLOBMSG_TYPE_INT32 },
[BTM_REQ_VALIDITY_INT] = { .name = "validity_int", .type = BLOBMSG_TYPE_INT32 },
[BTM_REQ_DIALOG_TOKEN] = { .name = "dialog_token", .type = BLOBMSG_TYPE_INT32 },
[BTM_REQ_BSSTERM_DUR] = { .name = "bssterm_dur", .type = BLOBMSG_TYPE_INT32 },
[BTM_REQ_MBO_REASON] = { .name = "mbo_reason", .type = BLOBMSG_TYPE_INT32 },
[BTM_REQ_MBO_CELL_PREF] = { .name = "mbo_cell_pref", .type = BLOBMSG_TYPE_INT32 },
[BTM_REQ_MBO_REASSOC_DELAY] = { .name = "mbo_reassoc_delay", .type = BLOBMSG_TYPE_INT32 },
};
/* send association controll policy */
enum {
ASSOC_CNTRL_CLIENT,
ASSOC_CNTRL_ENABLE,
__ASSOC_CNTRL_MAX,
};
static const struct blobmsg_policy assoc_cntrl_policy[__ASSOC_CNTRL_MAX] = {
[ASSOC_CNTRL_CLIENT] = { .name = "client", .type = BLOBMSG_TYPE_ARRAY },
[ASSOC_CNTRL_ENABLE] = { .name = "enable", .type = BLOBMSG_TYPE_INT32 },
};
/* block station policy */
enum {
BLOCK_STATION_MACADDR,
BLOCK_STATION_BLOCK,
__BLOCK_STATION_MAX,
};
static const struct blobmsg_policy block_station_policy[__BLOCK_STATION_MAX] = {
[BLOCK_STATION_MACADDR] = { .name = "client", .type = BLOBMSG_TYPE_STRING },
[BLOCK_STATION_BLOCK] = { .name = "block", .type = BLOBMSG_TYPE_INT32 },
};
/* apmld block station policy */
enum {
APMLD_BLOCK_STATION_MACADDR,
APMLD_BLOCK_STATION_BLOCK,
APMLD_BLOCK_STATION_BAND,
__APMLD_BLOCK_STATION_MAX,
};
static const struct blobmsg_policy apmld_block_station_policy[__APMLD_BLOCK_STATION_MAX] = {
[APMLD_BLOCK_STATION_MACADDR] = { .name = "client", .type = BLOBMSG_TYPE_STRING },
[APMLD_BLOCK_STATION_BLOCK] = { .name = "block", .type = BLOBMSG_TYPE_INT32 },
[APMLD_BLOCK_STATION_BAND] = { .name = "band", .type = BLOBMSG_TYPE_INT32 },
};
/* apmld get blocked maclist */
enum {
APMLD_BLOCKED_MACLIST_BAND,
__APMLD_BLOCKED_MACLIST_MAX,
};
static const struct blobmsg_policy apmld_blocked_maclist_policy[__APMLD_BLOCKED_MACLIST_MAX] = {
[APMLD_BLOCKED_MACLIST_BAND] = { .name = "band", .type = BLOBMSG_TYPE_INT32 },
};
/* dump beacon policy */
enum {
DUMP_BEACON_BAND,
__DUMP_BEACON_MAX,
};
static const struct blobmsg_policy dump_beacon_policy[__DUMP_BEACON_MAX] = {
[DUMP_BEACON_BAND] = { .name = "band", .type = BLOBMSG_TYPE_INT32 },
};
/* vendor_ie add/del policy */
enum {
VSIE_MGMT_STYPE, /* bitmask of (1 << mgmt frame subtype) */
VSIE_OUI,
VSIE_DATA,
__VSIE_MAX,
};
static const struct blobmsg_policy vsie_policy[__VSIE_MAX] = {
[VSIE_MGMT_STYPE] = { .name = "mgmt", .type = BLOBMSG_TYPE_INT32 },
[VSIE_OUI] = { .name = "oui", .type = BLOBMSG_TYPE_STRING},
[VSIE_DATA] = { .name = "data", .type = BLOBMSG_TYPE_STRING},
};
/* link measure request policy */
enum {
LINKMEAS_STA,
__LINKMEAS_MAX,
};
static const struct blobmsg_policy linkmeas_policy[__LINKMEAS_MAX] = {
[LINKMEAS_STA] = { .name = "sta", .type = BLOBMSG_TYPE_STRING },
};
enum {
MBO_DISALLOW_ASSOC_REASON,
__MBO_DISALLOW_ASSOC_MAX,
};
static const struct blobmsg_policy mbo_disallow_assoc_policy[__MBO_DISALLOW_ASSOC_MAX] = {
[MBO_DISALLOW_ASSOC_REASON] = { .name = "reason", .type = BLOBMSG_TYPE_INT32 },
};
/* send qos map policy */
enum {
AP_SEND_QOS_MAP_CONF_ADDR, /* sta mac ':' separated */
__AP_SEND_QOS_MAP_CONF_MAX,
};
static const struct blobmsg_policy ap_send_qos_map_conf_policy[__AP_SEND_QOS_MAP_CONF_MAX] = {
[AP_SEND_QOS_MAP_CONF_ADDR] = { .name = "sta", .type = BLOBMSG_TYPE_STRING },
};
/* set qos map policy */
enum {
AP_SET_QOS_MAP_SET, /* Array of u32 elements making up a QoS map */
__AP_SET_QOS_MAP_SET_MAX,
};
static const struct blobmsg_policy ap_set_qos_map_policy[__AP_SET_QOS_MAP_SET_MAX] = {
[AP_SET_QOS_MAP_SET] = { .name = "set", .type = BLOBMSG_TYPE_ARRAY },
};
/* disconnect from ap policy */
enum {
AP_DISCONNECT_REASON, /* deauth/disassoc reason code */
__AP_DISCONNECT_MAX,
};
static const struct blobmsg_policy ap_disconnect_policy[__AP_DISCONNECT_MAX] = {
[AP_DISCONNECT_REASON] = { .name = "reason", .type = BLOBMSG_TYPE_INT32}
};
enum {
STA_4ADDR_ENABLE,
__STA_4ADDR_MAX,
};
static const struct blobmsg_policy sta_4addr_policy[__STA_4ADDR_MAX] = {
[STA_4ADDR_ENABLE] = { .name = "enable", .type = BLOBMSG_TYPE_INT32}
};
enum {
ACTION_DST,
ACTION_WAIT,
ACTION_FREQ,
ACTION_FRAME,
ACTION_SRC,
__ACTION_MAX,
};
static const struct blobmsg_policy send_action_policy[__ACTION_MAX] = {
[ACTION_DST] = { .name = "dst", .type = BLOBMSG_TYPE_STRING },
[ACTION_WAIT] = { .name = "wait", .type = BLOBMSG_TYPE_INT32 },
[ACTION_FREQ] = { .name = "freq", .type = BLOBMSG_TYPE_INT32 },
[ACTION_FRAME] = { .name = "frame", .type = BLOBMSG_TYPE_STRING },
[ACTION_SRC] = { .name = "src", .type = BLOBMSG_TYPE_STRING },
};
enum {
DPP_LISTEN_FREQ,
__DPP_LISTEN_MAX,
};
static const struct blobmsg_policy dpp_listen_policy[__DPP_LISTEN_MAX] = {
[DPP_LISTEN_FREQ] = { .name = "freq", .type = BLOBMSG_TYPE_INT32 }
};
enum {
SUBSCRIBE_FRAME_TYPE,
SUBSCRIBE_FRAME_SUBTYPE,
__SUBSCRIBE_FRAME_MAX,
};
static const struct blobmsg_policy subscribe_frame_policy[__SUBSCRIBE_FRAME_MAX] = {
[SUBSCRIBE_FRAME_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_INT32 },
[SUBSCRIBE_FRAME_SUBTYPE] = { .name = "stype", .type = BLOBMSG_TYPE_INT32 },
};
/* WPS attributes follow */
enum {
ATTR_PIN,
__ATTR_PIN_MAX,
};
static const struct blobmsg_policy pin_policy[__ATTR_PIN_MAX] = {
[ATTR_PIN] = { .name = "pin", .type = BLOBMSG_TYPE_STRING },
};
enum {
WPS_ATTR_IFNAME,
__ATTR_IFNAME_ONLY,
};
static const struct blobmsg_policy ifname_policy[__ATTR_IFNAME_ONLY] = {
[WPS_ATTR_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING },
};
enum {
PIN_SET_IFNAME,
PIN_SET_PIN,
__PIN_SET_MAX,
};
static const struct blobmsg_policy pin_set_policy[__PIN_SET_MAX] = {
[PIN_SET_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING },
[PIN_SET_PIN] = { .name = "pin", .type = BLOBMSG_TYPE_STRING },
};
enum {
WPS_START_ATTR_IFNAME,
WPS_START_ATTR_MODE,
WPS_START_ATTR_ROLE,
WPS_START_ATTR_STA_PIN,
__WPS_START_ATTR_MAX,
};
static const struct blobmsg_policy wps_start_policy[__WPS_START_ATTR_MAX] = {
[WPS_START_ATTR_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING },
[WPS_START_ATTR_MODE] = { .name = "mode", .type = BLOBMSG_TYPE_STRING },
[WPS_START_ATTR_ROLE] = { .name = "role", .type = BLOBMSG_TYPE_STRING },
[WPS_START_ATTR_STA_PIN] = { .name = "pin", .type = BLOBMSG_TYPE_STRING },
};