Linux Wi-Fi 编程API介绍
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                Linux Wi-Fi 编程API介绍
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.                        
                                本文為《深入理解Android Wi-Fi、NFC和GPS卷》讀書筆記,Android源碼為Android 5.1
 
Linux平臺(tái)上目前常用的專門針對無線網(wǎng)絡(luò)設(shè)備編程的API有兩套
最早的一套API由HP公司員工 Jean Tourrilhes于1997年開發(fā),全稱為 Linux Wireless Extensions。一般縮寫為 wex 或 wext。 這套API使得用戶空間的程序能通過 ioctl 函數(shù)來控制無線網(wǎng)卡驅(qū)動(dòng)。由于利用ioctl開展編程的方式不太符合 Linux 驅(qū)動(dòng)開發(fā)的要求,后來 Linux 又提供了 cfg80211 和 nl80211 兩套編程接口用于替代 wext。 其中, cfg80211 用于驅(qū)動(dòng)開發(fā),而 nl80211 API 供用戶控件進(jìn)程使用以操作那些利用 cfg80211 API 開發(fā)的無線網(wǎng)卡驅(qū)動(dòng)。
Linux Wireless Extensions 介紹
所有用戶空間發(fā)起的請求都統(tǒng)一包括在 struct iwreq 中:
android-5.1/external/kernel-headers/original/uapi/linux/wireless.h
//該結(jié)構(gòu)體專門用于往socket句柄傳遞 ioctrl 控制參數(shù)
struct	iwreq 
{union{char	ifrn_name[IFNAMSIZ];	/* if name, e.g. "eth0" 用于指定要操作的網(wǎng)卡設(shè)備名,如 wlan0*/} ifr_ifrn;/* Data part (defined just above) */union	iwreq_data	u;	//用于存儲(chǔ)具體的參數(shù)信息
};
union	iwreq_data
{/* Config - generic */char		name[IFNAMSIZ];/* Name : used to verify the presence of  wireless extensions.* Name of the protocol/provider... */struct iw_point	essid;		/* Extended network name */struct iw_param	nwid;		/* network id (or domain - the cell) */struct iw_freq	freq;		/* frequency or channel :* 0-1000 = channel* > 1000 = frequency in Hz */struct iw_param	sens;		/* signal level threshold */struct iw_param	bitrate;	/* default bit rate */struct iw_param	txpower;	/* default transmit power */struct iw_param	rts;		/* RTS threshold threshold */struct iw_param	frag;		/* Fragmentation threshold */__u32		mode;		/* Operation mode */struct iw_param	retry;		/* Retry limits & lifetime */struct iw_point	encoding;	/* Encoding stuff : tokens */struct iw_param	power;		/* PM duration/timeout */struct iw_quality qual;		/* Quality part of statistics */struct sockaddr	ap_addr;	/* Access point address */struct sockaddr	addr;		/* Destination address (hw/mac) */struct iw_param	param;		/* Other small parameters */struct iw_point	data;		/* Other large parameters */
}; 
當(dāng)參數(shù)信息的長度超過16字節(jié)時(shí),就只能通過 iw_point 指向另外一塊內(nèi)存區(qū)域,而參數(shù)就存儲(chǔ)在那個(gè)區(qū)域中。這就是我們常用的指針方式。
struct	iw_point
{void __user	*pointer;	/* Pointer to the data  (in user space) */__u16		length;		/* number of fields or size in bytes */__u16		flags;		/* Optional params */
};當(dāng)參數(shù)信息不超過16字節(jié)時(shí),可以把信息存儲(chǔ)在 iw_param 中。
 
struct	iw_param
{__s32		value;		/* The value of the parameter itself */__u8		fixed;		/* Hardware should not use auto select */__u8		disabled;	/* Disable the feature */__u16		flags;		/* Various specifc flags (if any) */
};用于存儲(chǔ)頻率或信道值。
當(dāng)頻率小于109, m 直接等于頻率。否則 m=f/(10e)
struct	iw_freq
{__s32		m;		/* Mantissa */__s16		e;		/* Exponent */__u8		i;		/* List index (when in range struct) 該值表示此頻率對象在 channel_list 數(shù)組中的索引 */__u8		flags;		/* Flags (fixed/auto) 固定/自動(dòng) */
};當(dāng)參數(shù)字節(jié)超過16的時(shí)候, wext 還定義了和功能相關(guān)的參數(shù)類型:
數(shù)據(jù)結(jié)構(gòu) iw_scan_req 用于觸發(fā)無線網(wǎng)卡發(fā)起掃描請求:
struct	iw_scan_req
{__u8		scan_type; /* IW_SCAN_TYPE_{ACTIVE,PASSIVE} 主動(dòng)/被動(dòng)掃描*/__u8		essid_len;__u8		num_channels; /* num entries in channel_list; 信道個(gè)數(shù)* 0 = scan all allowed channels  0 掃描所有可允許的信道 */__u8		flags; /* reserved as padding; use zero, this may* be used in the future for adding flags* to request different scan behavior */struct sockaddr	bssid; /* ff:ff:ff:ff:ff:ff for broadcast BSSID or* individual address of a specific BSS * bssid用于指明 BSS的地址。 如果全為 FF 則為廣播 BSSID,即 wildcard bssid *//** Use this ESSID if IW_SCAN_THIS_ESSID flag is used instead of using* the current ESSID. This allows scan requests for specific ESSID* without having to change the current ESSID and potentially breaking* the current association.*/__u8		essid[IW_ESSID_MAX_SIZE];/** Optional parameters for changing the default scanning behavior.* These are based on the MLME-SCAN.request from IEEE Std 802.11.* TU is 1.024 ms. If these are set to 0, driver is expected to use* reasonable default values. min_channel_time defines the time that* will be used to wait for the first reply on each channel. If no* replies are received, next channel will be scanned after this. If* replies are received, total time waited on the channel is defined by* max_channel_time.*/__u32		min_channel_time; /* in TU 表示掃描過程中在每個(gè)信道等待到第一個(gè)回復(fù)的時(shí)間。如果在此時(shí)間內(nèi)沒有等到回復(fù),跳到下一個(gè)信道等待。如果等到一個(gè)回復(fù),則一共在該信道等待的最大時(shí)間為 max_channel_time 。所有時(shí)間單位均為TU(Time Units),即1024ms。*/__u32		max_channel_time; /* in TU */struct iw_freq	channel_list[IW_MAX_FREQUENCIES];//IW_MAX_FREQUENCIES = 32
};wext API使用實(shí)例
本例來源于 wpa_supplicant ,它是一個(gè)運(yùn)行于用戶空間的專門和無線網(wǎng)卡進(jìn)行交互的程序。 下面來看 wpa_supplicant 如何利用 wext API 和無線網(wǎng)卡交互。
android-5.1/external/wpa_supplicant_8/src/drivers/driver_wext.c
int wpa_driver_wext_scan(void *priv, struct wpa_driver_scan_params *params)
{struct wpa_driver_wext_data *drv = priv;struct iwreq iwr;	//定義一個(gè) iwreq 對象int ret = 0, timeout;struct iw_scan_req req;	//定義一個(gè) iw_scan_req 對象const u8 *ssid = params->ssids[0].ssid;size_t ssid_len = params->ssids[0].ssid_len;if (ssid_len > IW_ESSID_MAX_SIZE) {wpa_printf(MSG_DEBUG, "%s: too long SSID (%lu)",__FUNCTION__, (unsigned long) ssid_len);return -1;}os_memset(&iwr, 0, sizeof(iwr));//為 iwr 的 ifr_name 傳遞需操作的網(wǎng)卡設(shè)備名os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);if (ssid && ssid_len) {os_memset(&req, 0, sizeof(req));//設(shè)置 iw_scan_req 的信息req.essid_len = ssid_len;req.bssid.sa_family = ARPHRD_ETHER;//設(shè)置 bssid 的 MAC 地址全為 0XFF, 代表這是一個(gè) wildcard BSSID搜索os_memset(req.bssid.sa_data, 0xff, ETH_ALEN);os_memcpy(req.essid, ssid, ssid_len);//通過 data 域指向這個(gè) iw_scan_req 對象iwr.u.data.pointer = (caddr_t) &req;iwr.u.data.length = sizeof(req);//IW_SCAN_THIS_ESSID 表示只掃描指定ESSID的無線網(wǎng)絡(luò)iwr.u.data.flags = IW_SCAN_THIS_ESSID;}//ioctl_sock指向一個(gè) socket 句柄//SIOCSIWSCAN 用于通知驅(qū)動(dòng)進(jìn)行無線網(wǎng)絡(luò)掃描if (ioctl(drv->ioctl_sock, SIOCSIWSCAN, &iwr) < 0) {perror("ioctl[SIOCSIWSCAN]");ret = -1;}/* Not all drivers generate "scan completed" wireless event, so try to* read results after a timeout. */timeout = 10;if (drv->scan_complete_events) {/** The driver seems to deliver SIOCGIWSCAN events to notify* when scan is complete, so use longer timeout to avoid race* conditions with scanning and following association request.*/timeout = 30;}wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d ""seconds", ret, timeout);eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx);eloop_register_timeout(timeout, 0, wpa_driver_wext_scan_timeout, drv,drv->ctx);return ret;
}netlink 編程
external/libnl/include/netlink/netlink.h
struct sockaddr_nl {//nl_family 取值必須為 AF_NETLINK 或 PF_NETLINK__kernel_sa_family_t nl_family;unsigned short nl_pad;	//必須為0,無用__u32 nl_pid; //看起來是存儲(chǔ)進(jìn)程pid的,但實(shí)際上它只是用于標(biāo)示一個(gè) netlink socket。所以用戶空間只要保證進(jìn)程內(nèi)該值的唯一性即可。如果該值為0,表示通信的目標(biāo)是 kernel。//每一個(gè) netlink 協(xié)議都支持最多32個(gè)多播組,加入多播組的成員都能接收到對應(yīng)的多播消息。//采用多播的方式能減少消息發(fā)送/接收的次數(shù)//nl_groups 為 0,表示只處理單播消息__u32 nl_groups;
};nl80211 的核心就是通過 netlink 機(jī)制向 Kernel 中的無線網(wǎng)卡驅(qū)動(dòng)發(fā)送特定的消息:
下面是通過 nl80211 觸發(fā)網(wǎng)卡進(jìn)行無線網(wǎng)絡(luò)掃描:
android-5.1/external/wpa_supplicant_8/src/drivers/driver_nl80211.c
static int wpa_driver_nl80211_scan(struct i802_bss *bss,struct wpa_driver_scan_params *params)
{struct wpa_driver_nl80211_data *drv = bss->drv;int ret = -1, timeout;struct nl_msg *msg = NULL;wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: scan request");drv->scan_for_auth = 0;//創(chuàng)建 nl80211 消息,其中 NL80211_CMD_TRIGGER_SCAN 是 nl80211 定義的命令,用于觸發(fā)網(wǎng)絡(luò)掃描msg = nl80211_scan_common(drv, NL80211_CMD_TRIGGER_SCAN, params,bss->wdev_id_set ? &bss->wdev_id : NULL);if (!msg)return -1;if (params->p2p_probe) {struct nlattr *rates;wpa_printf(MSG_DEBUG, "nl80211: P2P probe - mask SuppRates");rates = nla_nest_start(msg, NL80211_ATTR_SCAN_SUPP_RATES);if (rates == NULL)goto nla_put_failure;/** Remove 2.4 GHz rates 1, 2, 5.5, 11 Mbps from supported rates* by masking out everything else apart from the OFDM rates 6,* 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS rates. All 5 GHz* rates are left enabled.*/NLA_PUT(msg, NL80211_BAND_2GHZ, 8,"\x0c\x12\x18\x24\x30\x48\x60\x6c");nla_nest_end(msg, rates);NLA_PUT_FLAG(msg, NL80211_ATTR_TX_NO_CCK_RATE);}//發(fā)送 netlink 消息ret = send_and_recv_msgs(drv, msg, NULL, NULL);msg = NULL;if (ret) {wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d ""(%s)", ret, strerror(-ret));if (drv->hostapd && is_ap_interface(drv->nlmode)) {enum nl80211_iftype old_mode = drv->nlmode;/** mac80211 does not allow scan requests in AP mode, so* try to do this in station mode.*/if (wpa_driver_nl80211_set_mode(bss, NL80211_IFTYPE_STATION))goto nla_put_failure;if (wpa_driver_nl80211_scan(bss, params)) {wpa_driver_nl80211_set_mode(bss, drv->nlmode);goto nla_put_failure;}/* Restore AP mode when processing scan results */drv->ap_scan_as_station = old_mode;ret = 0;} elsegoto nla_put_failure;}drv->scan_state = SCAN_REQUESTED;/* Not all drivers generate "scan completed" wireless event, so try to* read results after a timeout. */timeout = 10;if (drv->scan_complete_events) {/** The driver seems to deliver events to notify when scan is* complete, so use longer timeout to avoid race conditions* with scanning and following association request.*/timeout = 30;}wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d ""seconds", ret, timeout);eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);eloop_register_timeout(timeout, 0, wpa_driver_nl80211_scan_timeout,drv, drv->ctx);nla_put_failure:nlmsg_free(msg);return ret;
}上面代碼中的nl80211_scan_common
android-5.1/external/wpa_supplicant_8/src/drivers/driver_nl80211.c
static struct nl_msg *
nl80211_scan_common(struct wpa_driver_nl80211_data *drv, u8 cmd,struct wpa_driver_scan_params *params, u64 *wdev_id)
{struct nl_msg *msg;size_t i;u32 scan_flags = 0;//分配一個(gè) nl_msg 對象msg = nlmsg_alloc();if (!msg)return NULL;//nl80211_cmd 函數(shù)填充 nl_msg 信息nl80211_cmd(drv, msg, 0, cmd);if (!wdev_id)//NL80211_ATTR_IFINDEX 代表此次操作所指定的網(wǎng)絡(luò)設(shè)備編號。NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);elseNLA_PUT_U64(msg, NL80211_ATTR_WDEV, *wdev_id);if (params->num_ssids) {struct nlattr *ssids;ssids = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);if (ssids == NULL)goto fail;for (i = 0; i < params->num_ssids; i++) {wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Scan SSID",params->ssids[i].ssid,params->ssids[i].ssid_len);if (nla_put(msg, i + 1, params->ssids[i].ssid_len,params->ssids[i].ssid) < 0)goto fail;}nla_nest_end(msg, ssids);}if (params->extra_ies) {wpa_hexdump(MSG_MSGDUMP, "nl80211: Scan extra IEs",params->extra_ies, params->extra_ies_len);if (nla_put(msg, NL80211_ATTR_IE, params->extra_ies_len,params->extra_ies) < 0)goto fail;}if (params->freqs) {struct nlattr *freqs;freqs = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);if (freqs == NULL)goto fail;for (i = 0; params->freqs[i]; i++) {wpa_printf(MSG_MSGDUMP, "nl80211: Scan frequency %u ""MHz", params->freqs[i]);if (nla_put_u32(msg, i + 1, params->freqs[i]) < 0)goto fail;}nla_nest_end(msg, freqs);}os_free(drv->filter_ssids);drv->filter_ssids = params->filter_ssids;params->filter_ssids = NULL;drv->num_filter_ssids = params->num_filter_ssids;if (params->only_new_results) {wpa_printf(MSG_DEBUG, "nl80211: Add NL80211_SCAN_FLAG_FLUSH");scan_flags |= NL80211_SCAN_FLAG_FLUSH;}if (params->low_priority && drv->have_low_prio_scan) {wpa_printf(MSG_DEBUG,"nl80211: Add NL80211_SCAN_FLAG_LOW_PRIORITY");scan_flags |= NL80211_SCAN_FLAG_LOW_PRIORITY;}if (scan_flags)NLA_PUT_U32(msg, NL80211_ATTR_SCAN_FLAGS, scan_flags);return msg;fail:
nla_put_failure:nlmsg_free(msg);return NULL;
}nl80211_copy.h定義了 802.11 相關(guān)的命令:
android-5.1/external/wpa_supplicant_8/src/drivers/nl80211_copy.h
enum nl80211_commands {
/* don't change the order or add anything between, this is ABI! */NL80211_CMD_UNSPEC,NL80211_CMD_GET_WIPHY,		/* can dump */NL80211_CMD_SET_WIPHY,NL80211_CMD_NEW_WIPHY,NL80211_CMD_DEL_WIPHY,NL80211_CMD_GET_INTERFACE,	/* can dump */NL80211_CMD_SET_INTERFACE,NL80211_CMD_NEW_INTERFACE,NL80211_CMD_DEL_INTERFACE,NL80211_CMD_GET_KEY,NL80211_CMD_SET_KEY,NL80211_CMD_NEW_KEY,NL80211_CMD_DEL_KEY,NL80211_CMD_GET_BEACON,NL80211_CMD_SET_BEACON,NL80211_CMD_START_AP,NL80211_CMD_NEW_BEACON = NL80211_CMD_START_AP,NL80211_CMD_STOP_AP,NL80211_CMD_DEL_BEACON = NL80211_CMD_STOP_AP,NL80211_CMD_GET_STATION,NL80211_CMD_SET_STATION,NL80211_CMD_NEW_STATION,NL80211_CMD_DEL_STATION,NL80211_CMD_GET_MPATH,NL80211_CMD_SET_MPATH,NL80211_CMD_NEW_MPATH,NL80211_CMD_DEL_MPATH,NL80211_CMD_SET_BSS,NL80211_CMD_SET_REG,NL80211_CMD_REQ_SET_REG,NL80211_CMD_GET_MESH_CONFIG,NL80211_CMD_SET_MESH_CONFIG,NL80211_CMD_SET_MGMT_EXTRA_IE /* reserved; not used */,NL80211_CMD_GET_REG,NL80211_CMD_GET_SCAN,NL80211_CMD_TRIGGER_SCAN,NL80211_CMD_NEW_SCAN_RESULTS,NL80211_CMD_SCAN_ABORTED,NL80211_CMD_REG_CHANGE,NL80211_CMD_AUTHENTICATE,NL80211_CMD_ASSOCIATE,NL80211_CMD_DEAUTHENTICATE,NL80211_CMD_DISASSOCIATE,NL80211_CMD_MICHAEL_MIC_FAILURE,NL80211_CMD_REG_BEACON_HINT,NL80211_CMD_JOIN_IBSS,NL80211_CMD_LEAVE_IBSS,NL80211_CMD_TESTMODE,NL80211_CMD_CONNECT,NL80211_CMD_ROAM,NL80211_CMD_DISCONNECT,NL80211_CMD_SET_WIPHY_NETNS,NL80211_CMD_GET_SURVEY,NL80211_CMD_NEW_SURVEY_RESULTS,NL80211_CMD_SET_PMKSA,NL80211_CMD_DEL_PMKSA,NL80211_CMD_FLUSH_PMKSA,NL80211_CMD_REMAIN_ON_CHANNEL,NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,NL80211_CMD_SET_TX_BITRATE_MASK,NL80211_CMD_REGISTER_FRAME,NL80211_CMD_REGISTER_ACTION = NL80211_CMD_REGISTER_FRAME,NL80211_CMD_FRAME,NL80211_CMD_ACTION = NL80211_CMD_FRAME,NL80211_CMD_FRAME_TX_STATUS,NL80211_CMD_ACTION_TX_STATUS = NL80211_CMD_FRAME_TX_STATUS,NL80211_CMD_SET_POWER_SAVE,NL80211_CMD_GET_POWER_SAVE,NL80211_CMD_SET_CQM,NL80211_CMD_NOTIFY_CQM,NL80211_CMD_SET_CHANNEL,NL80211_CMD_SET_WDS_PEER,NL80211_CMD_FRAME_WAIT_CANCEL,NL80211_CMD_JOIN_MESH,NL80211_CMD_LEAVE_MESH,NL80211_CMD_UNPROT_DEAUTHENTICATE,NL80211_CMD_UNPROT_DISASSOCIATE,NL80211_CMD_NEW_PEER_CANDIDATE,NL80211_CMD_GET_WOWLAN,NL80211_CMD_SET_WOWLAN,NL80211_CMD_START_SCHED_SCAN,NL80211_CMD_STOP_SCHED_SCAN,NL80211_CMD_SCHED_SCAN_RESULTS,NL80211_CMD_SCHED_SCAN_STOPPED,NL80211_CMD_SET_REKEY_OFFLOAD,NL80211_CMD_PMKSA_CANDIDATE,NL80211_CMD_TDLS_OPER,NL80211_CMD_TDLS_MGMT,NL80211_CMD_UNEXPECTED_FRAME,NL80211_CMD_PROBE_CLIENT,NL80211_CMD_REGISTER_BEACONS,NL80211_CMD_UNEXPECTED_4ADDR_FRAME,NL80211_CMD_SET_NOACK_MAP,NL80211_CMD_CH_SWITCH_NOTIFY,NL80211_CMD_START_P2P_DEVICE,NL80211_CMD_STOP_P2P_DEVICE,NL80211_CMD_CONN_FAILED,NL80211_CMD_SET_MCAST_RATE,NL80211_CMD_SET_MAC_ACL,NL80211_CMD_RADAR_DETECT,NL80211_CMD_GET_PROTOCOL_FEATURES,NL80211_CMD_UPDATE_FT_IES,NL80211_CMD_FT_EVENT,NL80211_CMD_CRIT_PROTOCOL_START,NL80211_CMD_CRIT_PROTOCOL_STOP,NL80211_CMD_GET_COALESCE,NL80211_CMD_SET_COALESCE,NL80211_CMD_CHANNEL_SWITCH,NL80211_CMD_VENDOR,NL80211_CMD_SET_QOS_MAP,NL80211_CMD_ADD_TX_TS,NL80211_CMD_DEL_TX_TS,/* add new commands above here *//* used to define NL80211_CMD_MAX below */__NL80211_CMD_AFTER_LAST,NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1
};屬性的取值:
 
enum nl80211_attrs {
/* don't change the order or add anything inbetween, this is ABI! */NL80211_ATTR_UNSPEC,NL80211_ATTR_WIPHY,NL80211_ATTR_WIPHY_NAME,NL80211_ATTR_IFINDEX,NL80211_ATTR_IFNAME,NL80211_ATTR_IFTYPE,NL80211_ATTR_MAC,NL80211_ATTR_KEY_DATA,NL80211_ATTR_KEY_IDX,NL80211_ATTR_KEY_CIPHER,NL80211_ATTR_KEY_SEQ,NL80211_ATTR_KEY_DEFAULT,NL80211_ATTR_BEACON_INTERVAL,NL80211_ATTR_DTIM_PERIOD,NL80211_ATTR_BEACON_HEAD,NL80211_ATTR_BEACON_TAIL,NL80211_ATTR_STA_AID,NL80211_ATTR_STA_FLAGS,NL80211_ATTR_STA_LISTEN_INTERVAL,NL80211_ATTR_STA_SUPPORTED_RATES,NL80211_ATTR_STA_VLAN,NL80211_ATTR_STA_INFO,NL80211_ATTR_WIPHY_BANDS,NL80211_ATTR_MNTR_FLAGS,NL80211_ATTR_MESH_ID,NL80211_ATTR_STA_PLINK_ACTION,NL80211_ATTR_MPATH_NEXT_HOP,NL80211_ATTR_MPATH_INFO,NL80211_ATTR_BSS_CTS_PROT,NL80211_ATTR_BSS_SHORT_PREAMBLE,NL80211_ATTR_BSS_SHORT_SLOT_TIME,NL80211_ATTR_HT_CAPABILITY,NL80211_ATTR_SUPPORTED_IFTYPES,NL80211_ATTR_REG_ALPHA2,NL80211_ATTR_REG_RULES,NL80211_ATTR_MESH_PARAMS,NL80211_ATTR_BSS_BASIC_RATES,NL80211_ATTR_WIPHY_TXQ_PARAMS,NL80211_ATTR_WIPHY_FREQ,NL80211_ATTR_WIPHY_CHANNEL_TYPE,NL80211_ATTR_KEY_DEFAULT_MGMT,NL80211_ATTR_MGMT_SUBTYPE,NL80211_ATTR_IE,NL80211_ATTR_MAX_NUM_SCAN_SSIDS,NL80211_ATTR_SCAN_FREQUENCIES,NL80211_ATTR_SCAN_SSIDS,NL80211_ATTR_GENERATION, /* replaces old SCAN_GENERATION */NL80211_ATTR_BSS,NL80211_ATTR_REG_INITIATOR,NL80211_ATTR_REG_TYPE,NL80211_ATTR_SUPPORTED_COMMANDS,NL80211_ATTR_FRAME,NL80211_ATTR_SSID,NL80211_ATTR_AUTH_TYPE,NL80211_ATTR_REASON_CODE,NL80211_ATTR_KEY_TYPE,NL80211_ATTR_MAX_SCAN_IE_LEN,NL80211_ATTR_CIPHER_SUITES,NL80211_ATTR_FREQ_BEFORE,NL80211_ATTR_FREQ_AFTER,NL80211_ATTR_FREQ_FIXED,NL80211_ATTR_WIPHY_RETRY_SHORT,NL80211_ATTR_WIPHY_RETRY_LONG,NL80211_ATTR_WIPHY_FRAG_THRESHOLD,NL80211_ATTR_WIPHY_RTS_THRESHOLD,NL80211_ATTR_TIMED_OUT,NL80211_ATTR_USE_MFP,NL80211_ATTR_STA_FLAGS2,NL80211_ATTR_CONTROL_PORT,NL80211_ATTR_TESTDATA,NL80211_ATTR_PRIVACY,NL80211_ATTR_DISCONNECTED_BY_AP,NL80211_ATTR_STATUS_CODE,NL80211_ATTR_CIPHER_SUITES_PAIRWISE,NL80211_ATTR_CIPHER_SUITE_GROUP,NL80211_ATTR_WPA_VERSIONS,NL80211_ATTR_AKM_SUITES,NL80211_ATTR_REQ_IE,NL80211_ATTR_RESP_IE,NL80211_ATTR_PREV_BSSID,NL80211_ATTR_KEY,NL80211_ATTR_KEYS,NL80211_ATTR_PID,NL80211_ATTR_4ADDR,NL80211_ATTR_SURVEY_INFO,/* add attributes here, update the policy in nl80211.c */__NL80211_ATTR_AFTER_LAST,NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
};
總結(jié)
以上是生活随笔為你收集整理的Linux Wi-Fi 编程API介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: NetworkManagementSer
 - 下一篇: 深入理解 wpa_supplicant(