if ( wl_scan() != WL_SUCCESS ) { // May be busy scanning already, no fatal error return 0; }
Since wl_scan() only starts the scanning process the application should add code to the event handler to catch the "scan complete" event and retrieve the list of seen networks from the library
static void event_cb(struct wl_event_t event, void* ctx) { switch(event.id) { case WL_EVENT_INIT_COMPLETE: app_init_ip_stack(); break; case WL_EVENT_SCAN_COMPLETE: struct wl_network_t* netlist; uint8_t netcnt; wl_get_network_list(&netlist, &netcnt); while (--netcnt) { print_network(netlist + netcnt); } break; } }
The function print_network() could display the network name, the SSID, in a user interface. It is important to keep in mind is that despite the fact that the SSID is usually presented as a ASCII string, it is in fact just a byte string and can legally contain all kinds of non-printable characters, including a 0-byte. This means that it is easy to end up with buffer overrun bugs if the SSID is ever treated as a normal string without precautions.
void print_network(struct wl_network_t* wl_network) { char ssid[WL_SSID_MAX_LENGTH + 1]; memset(ssid, 0, sizeof(ssid)); memcpy(ssid, wl_network->ssid.ssid, wl_network->ssid.len); if (app_is_printable(ssid)) { app_print("\"%s\" ", ssid); } else { app_print("<binary SSID> "); } switch (wl_network->enc_type) { case ENC_TYPE_WEP : app_print("(WEP encryption)"); break; case ENC_TYPE_TKIP : app_print("(TKIP encryption)"); break; case ENC_TYPE_CCMP : app_print("(CCMP encryption)"); break; } app_print("\n"); }
if ( wl_connect("My AP", strlen("My AP")) != WL_SUCCESS ) { app_error("Connection failed.\n"); return 0; }
and the WL_EVENT_MEDIA_CONNECTED and WL_EVENT_CONN_FAILURE events should be caught. To detect that a connection is terminated after it has been successfully established (such as when the AP goes out of range) the WL_EVENT_MEDIA_DISCONNECTED event must be also be caught
static void event_cb(struct wl_event_t event, void* ctx) { switch(event.id) { case WL_EVENT_INIT_COMPLETE: app_init_ip_stack(); break; case WL_EVENT_SCAN_COMPLETE: struct wl_network_t* netlist; uint8_t netcnt; wl_get_network_list(&netlist, &netcnt); while (--netcnt) { print_network(netlist + netcnt); } break; case WL_EVENT_CONN_FAILURE: app_error("Connection failed\n"); break; case WL_EVENT_MEDIA_CONNECTED: app_print("Connected to Access Point\n"); app_ip_interface_up(); break; case WL_EVENT_MEDIA_DISCONNECTED: app_print("Disconnected from Access Point\n"); app_ip_interface_down(); break; } }
char key[5] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x00 }; struct wl_mac_addr_t bssid; // This means that the bssid is a broadcast bssid and the WEP key will be a default key instead of a key-mapping key. memset(&bssid.octet, 0xff, sizeof bssid.octet); if ( wl_add_wep_key(0, sizeof key, key, &bssid) != WL_SUCCESS ) { app_error("Failed to add WEP key."); return 0; }
If Shared Key authentication is required then this is configured through a call to wl_set_auth_mode().
if ( wl_set_auth_mode(AUTH_MODE_SHARED_KEY) != WL_SUCCESS) { app_error("Failed to set authentication mode."); return 0; }
It is important to know that wl_set_auth_mode() sets a forcing authentication mode. If the mode is set to AUTH_MODE_SHARED_KEY then all connection attempts made will fail if the target of the connection attempt does not support Shared Key authentication. This is true of all non-WEP Access Points, including Access Points with WPA or WPA2. To reset the authentication mode call wl_set_auth_mode() with the mode set to AUTH_MODE_OPEN_SYSTEM (this is the default mode if wl_set_auth_mode() is never called).
To use WPA/WPA2 with a Pre-shared key a passphrase must be associated with the network before the connection is initiated.
struct wl_network_t net; char passphrase[] = "MySecretKey"; memset(&net, 0, sizeof net); memset(net.bssid.octet, 0xFF, sizeof net.bssid.octet); strncpy(net.ssid.ssid, "My AP", strlen("My AP")); net.ssid.len = strlen("My AP"); net.enc_type = ENC_TYPE_AUTO; if (wl_set_passphrase(&net, passphrase, strlen(passphrase), ENC_TYPE_AUTO, AUTH_MODE_AUTO) != WL_SUCCESS) { app_error("Failed to add passphrase"); }
The library supports several passphrase-network associations to be configured simultaneously. Be aware that the wl_connect() call can take up to 15 seconds longer than normal when using a pre-shared WPA/WPA2 key since the platform must calculate a temporal encryption key from the passphrase before the connection attempt can start.
Data Structures | |
struct | wl_event_t |
struct | wl_ssid_t |
SSID representation. More... | |
struct | wl_mac_addr_t |
struct | wl_network_t |
Functions | |
wl_err_t | wl_scan (void) |
Scan all channels. | |
wl_err_t | wl_get_network_list (struct wl_network_t **network_list, uint8_t *network_cnt) |
Get the list of currently known networks. | |
wl_err_t | wl_connect (char *ssid, size_t ssid_len) |
Connect to a SSID. | |
wl_err_t | wl_connect_bssid (struct wl_mac_addr_t bssid) |
Connect to a BSSID. | |
wl_err_t | wl_disconnect (void) |
Disconnect from the network. | |
wl_err_t | wl_set_auth_mode (enum wl_auth_mode mode) |
Set the WEP authentication mode of the driver. | |
wl_err_t | wl_add_wep_key (uint8_t key_idx, size_t key_len, const void *key, struct wl_mac_addr_t *bssid) |
Add a WEP encryption key to the device. | |
wl_err_t | wl_set_default_wep_key (uint8_t key_idx) |
Set the default WEP key index. | |
wl_err_t | wl_delete_wep_key (uint8_t key_idx, struct wl_mac_addr_t *bssid) |
Delete a WEP key. | |
wl_err_t | wl_set_passphrase (const struct wl_network_t *net, const char *passphrase, const size_t len, const enum wl_enc_type enc_type, const enum wl_auth_mode auth_mode) |
Set a WPA/WPA2 passphase. | |
wl_err_t | wl_clear_passphrase (struct wl_network_t *net) |
Remove a WPA/WPA2 passphase. | |
wl_err_t | wl_enable_ps (void) |
Enable legacy power save mode. | |
wl_err_t | wl_disable_ps (void) |
Disable legacy power save mode. | |
wl_err_t | wl_conf_ps (uint8_t use_ps_poll, uint32_t ps_traffic_timeout, uint32_t ps_delay, uint8_t rx_all_dtim, uint16_t listen_interval) |
Configure power save parameters. | |
wl_err_t | wl_get_mac_addr (uint8_t *buf) |
Get the interface MAC address. | |
struct wl_network_t * | wl_get_current_network (void) |
Return the associated network. | |
Defines | |
#define | ALIGN __attribute__ ((aligned (4))) |
Enumerations | |
enum | wl_event_id_t { WL_EVENT_MEDIA_CONNECTED = 0, WL_EVENT_CONN_FAILURE, WL_EVENT_MEDIA_DISCONNECTED, WL_EVENT_CONN_LOST, WL_EVENT_SCAN_COMPLETE, MAX_WL_EVENT } |
enum | wl_auth_mode { AUTH_MODE_INVALID, AUTH_MODE_AUTO, AUTH_MODE_OPEN_SYSTEM, AUTH_MODE_SHARED_KEY, AUTH_MODE_WPA, AUTH_MODE_WPA2, AUTH_MODE_WPA_PSK, AUTH_MODE_WPA2_PSK } |
enum | wl_enc_type { ENC_TYPE_WEP = 5, ENC_TYPE_TKIP = 2, ENC_TYPE_CCMP = 4, ENC_TYPE_NONE = 7, ENC_TYPE_AUTO = 8 } |
Variables | |
struct wl_ssid_t | ALIGN |
SSID representation. |
wl_err_t wl_add_wep_key | ( | uint8_t | key_idx, | |
size_t | key_len, | |||
const void * | key, | |||
struct wl_mac_addr_t * | bssid | |||
) |
Add a WEP encryption key to the device.
Configure a key into the device. The key type (WEP-40, WEP-104) is determined by the size of the key (5 bytes for WEP-40, 13 bytes for WEP-104).
key_idx | The key index to set. Valid values are 0-3. | |
key_len | Length of key in bytes. Valid values are 5 and 13. | |
key | Key input buffer. | |
bssid | BSSID that the key applies to. If this is the broadcast BSSID then the key is configured as one of the default keys (not _the_ default key, this must be set by calling set_default_wep_key() after adding it). If the BSSID is a valid unicast bssid then the key is configured as a key-mapping key ( See 802.11-2007 8.2.1.3 ). |
wl_err_t wl_clear_passphrase | ( | struct wl_network_t * | net | ) |
Remove a WPA/WPA2 passphase.
Remove a WPA/WPA2/RSN passphrase associated with a network.
net | Network with which to associate the passphrase. If net is NULL then all stored passphrases will be cleared. |
wl_err_t wl_conf_ps | ( | uint8_t | use_ps_poll, | |
uint32_t | ps_traffic_timeout, | |||
uint32_t | ps_delay, | |||
uint8_t | rx_all_dtim, | |||
uint16_t | listen_interval | |||
) |
Configure power save parameters.
use_ps_poll | Use PS-Poll frames to retrieve buffered data. Any changes to this parameter will take effect upon next connect or when power save is enabled through wl_enable_ps(). Note: To retrieve one buffered packet, the ps poll scheme needs one ps poll packet to the AP instead of two null packets in the power management bit scheme. Ps poll avoids the overhead of traffic monitoring time in active mode as well. But since each ps poll request can make the AP release only one buffered packet, it is not the optimal scheme for applications with heavy downlink traffic. | |
ps_traffic_timeout | Timeout in [ms] to wait for more buffered data from AP. This setting has no effect if use_ps_poll is 1. Any changes to this parameter will take effect immediately. | |
ps_delay | Power save will de delayed ps_delay [ms] after connecting to an AP. | |
rx_all_dtim | If set to 1, then STA will wake up to listen to every beacon containing DTIM (delivery traffic indication messages) when connected. The actual DTIM interval is configured in the AP. If the DTIM interval, as configured in the AP, is larger than listen_interval, the STA will wakeup according to the listen_interval parameter. | |
listen_interval | The Listen Interval field is used to indicate to the AP how often a STA in power save mode wakes to listen to beacon frames. The value of this parameter is expressed in units of Beacon Interval. An AP may use the Listen Interval information in determining the lifetime of frames that it buffers for a STA. Any changes to this parameter will take effect upon next association. |
wl_err_t wl_connect | ( | char * | ssid, | |
size_t | ssid_len | |||
) |
Connect to a SSID.
Attempt to connect to a given SSID. If the driver is already connected to an AP with a different SSID then this call will return WL_BUSY and wl_disconnect() should be called before trying again.
The connection process will proceed asynchronously and will raise a WL_EVENT_MEDIA_CONNECTED event when completed, or a WL_EVENT_CONN_FAILURE when failed. After a WL_EVENT_MEDIA_CONNECTED event has been raised a WL_EVENT_MEDIA_DISCONNECT event will be raised if the connection is terminated. Note that this can be caused by external factors and can happen at any time.
ssid | Pointer to the SSID string. Freed by caller. | |
ssid_len | Length of the SSID string in octets. Max value is 32. |
wl_err_t wl_connect_bssid | ( | struct wl_mac_addr_t | bssid | ) |
Connect to a BSSID.
Attempt to connect to a given BSSID. If the driver is already connected to an AP with a different BSSID then this call will return WL_BUSY and wl_disconnect() should be called before trying again.
The connection process will proceed asynchronously and will raise a WL_EVENT_MEDIA_CONNECTED event when completed, or a WL_EVENT_CONN_FAILURE when failed. After a WL_EVENT_MEDIA_CONNECTED event has been raised a WL_EVENT_MEDIA_DISCONNECT event will be raised if the connection is terminated. Note that this can be caused by external factors and can happen at any time.
bssid | Pointer to the BSSID. Freed by caller. |
wl_err_t wl_delete_wep_key | ( | uint8_t | key_idx, | |
struct wl_mac_addr_t * | bssid | |||
) |
Delete a WEP key.
Deletes a WEP key from the driver.
key_idx | The index of the key to delete. Valid values are 0-3. | |
bssid | BSSID that the key applies to. If this is the broadcast BSSID then the key deleted is a default key. If the BSSID is a valid unicast bssid then the deleted key is a key-mapping key. |
wl_err_t wl_disable_ps | ( | void | ) |
Disable legacy power save mode.
wl_err_t wl_disconnect | ( | void | ) |
Disconnect from the network.
Disconnect from any currently associated network.
The disconnection process will proceed asynchronously and will raise a WL_EVENT_MEDIA_DISCONNECTED event when completed.
wl_err_t wl_enable_ps | ( | void | ) |
Enable legacy power save mode.
Enable legacy power save mode. In legacy power save mode, the device will power down when idle. When connected, the device will wake up to receive beacon frames and any buffered data from the AP. The response time when legacy power save is enabled might therefore be as long as the AP beacon interval (mostly 100 ms). However, the throughput should not be affected.
struct wl_network_t* wl_get_current_network | ( | void | ) | [read] |
Return the associated network.
Return the description of the currently associated network, if any.
wl_err_t wl_get_mac_addr | ( | uint8_t * | buf | ) |
Get the interface MAC address.
Return the 802.3 MAC address of the network interface.
buf | Output buffer. It must be at least WL_MAC_ADDR_LENGTH bytes long and only the first WL_MAC_ADDR_LENGTH bytes will contain valid data. |
wl_err_t wl_get_network_list | ( | struct wl_network_t ** | network_list, | |
uint8_t * | network_cnt | |||
) |
Get the list of currently known networks.
Retrieves the list of currently known networks from the driver. To ensure that this list is up-to-date a wl_scan() call should be issued and this function should be called upon reception of the WL_EVENT_SCAN_COMPLETE event. This function can be called at other times but the list of networks retrieved then might not correspond to the networks actually in range.
Note that a successful scan does not necessarily find any networks.
This function is not thread safe. It must be called in the same execution context as wl_poll().
network_list | Output buffer. The API call returns a pointer to allocated memory containing network_cnt network entries. | |
network_cnt | The number of networks allocated in network_list. |
wl_err_t wl_scan | ( | void | ) |
Scan all channels.
Starts a scan of all WiFi channels allowed in this regulatory domain. The list of allowed channels (the domain) is adapted to the channels announced as allowed by the first AP heard.
The scan will proceed asynchronously and will raise a WL_EVENT_SCAN_COMPLETE event when completed.
wl_err_t wl_set_auth_mode | ( | enum wl_auth_mode | mode | ) |
Set the WEP authentication mode of the driver.
Set the authentication mode to use. This is only for enforcing Shared Key authentication in WEP networks. The default mode is AUTH_MODE_OPEN_SYSTEM which works with all types of encryption.
Note that as long as the mode is set to AUTH_MODE_SHARED_KEY all connections to APs using no encryption or WPA/WPA2 will fail since those require Open System authenticaton.
mode | AUTH_MODE_OPEN_SYSTEM for Open System authentication (that is no authentication). This should be used for WPA/WPA2 connections. AUTH_MODE_SHARED_KEY for WEP shared key authentication. Other values of mode are invalid with this call and will cause WL_FAILURE to be returned. |
wl_err_t wl_set_default_wep_key | ( | uint8_t | key_idx | ) |
Set the default WEP key index.
Select which WEP key to use for transmitted packets. For this to work correctly you must have added a WEP key with wl_add_wep_key() as a default key, using the same index as the one set in this call.
key_idx | Index of the key to make the default key. Valid values are 0-3. |
wl_err_t wl_set_passphrase | ( | const struct wl_network_t * | net, | |
const char * | passphrase, | |||
const size_t | len, | |||
const enum wl_enc_type | enc_type, | |||
const enum wl_auth_mode | auth_mode | |||
) |
Set a WPA/WPA2 passphase.
Associate a WPA/WPA2/RSN passphrase with a network. The number of passphrases that can be stored can vary but is always at least one. Passphrases can be added until wl_add_wpa_passphrase() returns WL_RESOURCES.
net | Network with which to associate the passphrase. | |
passphrase | Passphrase. Valid characters in a passphrase must lie between ASCII 32-126 (decimal). | |
len | Length of passphrase. Valid lengths are 8-63. | |
enc_type | Encryption type. If this is set to ENC_TYPE_AUTO then the most secure supported mode will be automatically selected. Normally you only need to pass something else here if you need to enforce picking a certain encryption mode when the network supports several modes and you don't want to use the best one. | |
auth_mode | Authentication mode. If this is set to AUTH_MODE_AUTO then the most secure mode will be automatically selected. Normally you only need to pass something else here if the network announces support for both WPA and WPA2/RSN and the passphrases are different. |
struct wl_network_t ALIGN __attribute__ ((aligned (4))) |
Struct member alignment macro
Network representation
enum wl_auth_mode |
Authentication modes
enum wl_enc_type |
Encryption modes
enum wl_event_id_t |
Event identifiers
struct wl_network_t ALIGN |
SSID representation.
The SSID is a binary string and cannot be treated as a C-string safely. An empty SSID is represented by a SSID struct with the len field set to 0.
Network representation