WiFi Client Service

API Reference


This API provides WiFi Client setup. Please note that the WiFi Client cannot be used at the same time as the WiFi Access Points service, due to the sharing of same wifi hardware.

IPC interfaces binding

Here's a code sample binding to WiFi service:

bindings:
{
   clientExe.clientComponent.le_wifiClient -> wifiService.le_wifiClient
}

Starting the WiFi Client

First of all the function le_wifiClient_Start() must be called to start the WiFi Service.

  • le_wifiClient_Start(): returns LE_OK if the call went ok. If WiFi Access Point is active, this will fail.

To subscribe to wifi events le_wifiClient_AddConnectionEventHandler() is to be called. The event indication contains the event type, interface name, AP bssid, and disconnection cause.

static void EventHandler
(
const le_wifiClient_EventInd_t* wifiEventPtr,
void *contextPtr
)
{
switch( wifiEventPtr->event )
{
case LE_WIFICLIENT_EVENT_CONNECTED:
{
LE_INFO("WiFi Client Connected.");
LE_INFO("Interface: %s, bssid: %s",
&wifiEventPtr->ifName[0],
&wifiEventPtr->apBssid[0]);
}
break;
case LE_WIFICLIENT_EVENT_DISCONNECTED:
{
LE_INFO("WiFi Client Disconnected.");
LE_INFO("Interface: %s, disconnectCause: %d",
&wifiEventPtr->ifName[0],
wifiEventPtr->cause);
}
break;
case LE_WIFICLIENT_EVENT_SCAN_DONE:
{
LE_INFO("WiFi Client Scan is done.");
MyHandleScanResult();
}
break;
}
}
 
le_wifiClient_ConnectionEventHandlerRef_t WifiEventHandlerRef = NULL;
 
static void MyInit
(
void
)
{
le_result_t result = le_wifiClient_start();
 
if ( LE_OK == result )
{
LE_INFO("WiFi Client started.");
WiFiEventHandlerRef = le_wifiClient_AddConnectionEventHandler( EventHandler, NULL );
}
else if ( LE_BUSY == result )
{
LE_INFO("ERROR: WiFi Client already started.");
}
else
{
LE_INFO("ERROR: WiFi Client not started.");
}
 
}

To subscribe to wifi events le_wifiClient_AddNewEventHandler() is to be called.

Deprecated:
le_wifiClient_AddNewEventHandler() will be removed in near future. It will be replaced by le_wifiClient_AddConnectionEventHandler().
static void EventHandler
(
le_wifiClient_Event_t clientEvent,
void *contextPtr
)
{
switch( clientEvent )
{
case LE_WIFICLIENT_EVENT_CONNECTED:
{
LE_INFO("WiFi Client Connected.");
}
break;
case LE_WIFICLIENT_EVENT_DISCONNECTED:
{
LE_INFO("WiFi Client Disconnected.");
}
break;
case LE_WIFICLIENT_EVENT_SCAN_DONE:
{
LE_INFO("WiFi Client Scan is done.");
MyHandleScanResult();
}
break;
}
}
 
le_wifiClient_NewEventHandler WiFiEventHandlerRef = NULL;
 
static void MyInit
(
void
)
{
le_result_t result = le_wifiClient_start();
 
if ( LE_OK == result )
{
LE_INFO("WiFi Client started.");
WiFiEventHandlerRef = le_wifiClient_AddNewEventHandler( EventHandler, NULL );
}
else if ( LE_BUSY == result )
{
LE_INFO("ERROR: WiFi Client already started.");
}
else
{
LE_INFO("ERROR: WiFi Client not started.");
}
 
}

Scanning Access Points with WiFi Client

To start a scan for Access Points, the le_wifiClient_Scan() should be called.

Processing the WiFi scan results

Once the scan results are available, the event LE_WIFICLIENT_EVENT_SCAN_DONE is received. The found Access Points can then be gotten with

The Access Points SSID, Service Set Identifier, is not a string. It does however often contain human readable ASCII values. It can be read with the following function:

The Access Points signal strength can be read with the following function:

static void MyHandleScanResult
(
void
)
{
uint8 ssid[MAX_SSID_BYTES];
le_wifiClient_AccessPointRef_t accessPointRef = le_wifiClient_GetFirstAccessPoint();
 
while( NULL != accessPointRef )
{
result = le_wifiClient_GetSsid( accessPointRef, ssid, MAX_SSID_BYTES );
if (( result == LE_OK ) && ( memcmp( ssid, "MySSID", 6) == 0 ))
{
LE_INFO("WiFi Client found.");
break;
}
}
}

Connecting to Access Point

First of all, an Access Point reference should be created using the SSID of the target Access Point. Use the following function to create a reference:

To set the pass phrase prior for the Access Point use the function:

WPA-Enterprise requires a username and password to authenticate. To set them use the function:

If an Access Point is hidden, it does not announce its presence and will not show up in scan. So, the SSID of this Access Point must be known in advance. Then, use the following function to allow connections to hidden Access Points: le_wifiClient_SetHiddenNetworkAttribute(): returns the function execution status.

Finally and when the Access Point parameters have been configured, use the following function to attempt a connection:

static void MyConnectTo
(
le_wifiClient_AccessPointRef_t accessPointRef
)
{
le_result_t result;
le_wifiClient_SetPassphrase ( accessPointRef, "Secret1" );
result = le_wifiClient_Connect( accessPointRef );
if (result == LE_OK)
{
LE_INFO("Connecting to AP.");
}
}

Configure security protocol

The Wifi security configurations are SSID-based so that different SSIDs or Wifi networks can employ different security protocols independently. The following subsections explain the wifiClient APIs that can be used to configure the supported security protocols onto an SSID. The currently supported Wifi security protocols are:

  • No or open security.
  • WEP,
  • WPA PSK and WPA2 PSK,
  • WPA EAP PEAP and WPA2 EAP PEAP.

To ensure high confidentiality, all configured credentials including any keys, usernames, passwords, phrases, secrets, etc., are stored in Legato's secured storage. There they are encrypted and can only be accessed by the wifiClient component. But to allow easy cross-checking and debugging of non-confidential Wifi configurations, an SSID's configured security protocol is still saved on the config tree under the same path as for other Wifi configurations, i.e. "dataConnectionService:/wifi/channel/<ssid>/secProtocol" as in the following example. Note that an application doesn't need to explicitly set this onto the config tree itself, but can use the APIs to be explained in the upcoming subsections for configuring security to complete this step.

root-mdm9x28:~# config get wifiService:/wifi/ wifi/ channel/ MY-MOBILE/ secProtocol<string> == 2 hidden<bool> == false MY-WLAN/ secProtocol<string> == 3 hidden<bool> == true

Clear security

The le_wifiClient_RemoveSsidSecurityConfigs() function can be used for the following purposes:

  • Reset the security protocol type to use no security, i.e. LE_WIFICLIENT_SECURITY_NONE,
  • Remove any previously installed Wifi security configurations including security protocol type and any user credentials.

The following is an example of how to use this API:

if ((ret != LE_OK) && (ret != LE_NOT_FOUND))
{
LE_ERROR("Failed to clear Wifi security configs; retcode %d", ret);
}
else
{
LE_INFO("Succeeded clearing Wifi security configs");
}

Configure an SSID with WEP

The API for configuring a given SSID to use WEP is le_wifiClient_ConfigureWep(). It will set WEP as the security protocol used for this SSID and saved the provided WEP key into secured storage for its later use via le_wifiClient_LoadSsid().

The following is an example of how to use this API. The wepKey input has to be non-null.

le_wifiClient_AccessPointRef_t ref;
ret = le_wifiClient_ConfigureWep(ssid, sizeof(ssid), wepKey, sizeof(wepKey));
if (ret != LE_OK)
{
LE_ERROR("Failed to configure WEP into secStore; retcode %d", ret);
}
else
{
ret = le_wifiClient_LoadSsid(ssid, sizeof(ssid), &ref);
if (ret != LE_OK)
{
LE_ERROR("LoadSsid failed over WEP; retcode %d", ret);
}
else
{
ref = NULL;
}
}

Configure an SSID with PSK

The API for configuring a given SSID to use WPA or WPA2 PSK is le_wifiClient_ConfigurePsk(). It will set this security protocoly type as the one used for this SSID and saved the provided credentials into secured storage for its later use via le_wifiClient_LoadSsid().

With this protocol type, either a pass phrase or a pre-shared key has to be provided. If both are provided, pass-phrase has precedence and will be used. But it fails to authenticate during a connect attempt, wifiClient will not do a second attempt using an available pre-shared key.

The following is an example of how to use this API. The passphrase input has to be non-null.

le_wifiClient_AccessPointRef_t ref;
ret = le_wifiClient_ConfigurePsk(ssid, sizeof(ssid), LE_WIFICLIENT_SECURITY_WPA_PSK_PERSONAL,
passphrase, sizeof(passphrase), NULL, 0);
if (ret != LE_OK)
{
LE_ERROR("Failed to configure WPA passphrase into secStore; retcode %d", ret);
}
else
{
ret = le_wifiClient_LoadSsid(ssid, sizeof(ssid), &ref);
if (ret != LE_OK)
{
LE_ERROR("LoadSsid failed over WPA passphrase; retcode %d", ret);
}
else
{
ref = NULL;
}
}

Configure an SSID with EAP

The API for configuring a given SSID to use WPA or WPA2 EAP is le_wifiClient_ConfigureEap(). It will set this security protocoly type as the one used for this SSID and saved the provided user name and password into secured storage for its later use via le_wifiClient_LoadSsid().

The following is an example of how to use this API. Both the user name and password inputs have to be non-null.

le_wifiClient_AccessPointRef_t ref;
ret = le_wifiClient_ConfigureEap(ssid, sizeof(ssid),
LE_WIFICLIENT_SECURITY_WPA2_EAP_PEAP0_ENTERPRISE,
username, sizeof(username), password, sizeof(password));
if (ret != LE_OK)
{
LE_ERROR("Failed to configure WPA2 EAP into secStore; retcode %d", ret);
}
else
{
ret = le_wifiClient_LoadSsid(ssid, sizeof(ssid), &ref);
if (ret != LE_OK)
{
LE_ERROR("LoadSsid failed over WPA2 EAP; retcode %d", ret);
}
else
{
ref = NULL;
}
}

Configure Wifi client with an SSID

Before a Wifi connection can be established over an SSID via le_wifiClient_Connect(), a few preparations have to be first done. The following are the ones that can be done via the le_wifiClient_LoadSsid() function in this component:

  • Have the SSID selected: The SSID provided in this function's input argument is considered the one selected for establishing the Wifi connection.
  • Load the pre-configured Wifi security configurations into wifiClient: These include the security protocol type and its involved user credentials, e.g. WEP key for WEP, pass phrase or pre-shared key for PSK, user name and password for EAP.
  • Load other pre-configured Wifi configuration: So far there is only the Wifi hidden attribute pre-configured via le_wifiClient_SetHiddenNetworkAttribute().
  • Create an AP object reference: This reference is created for this given and configured SSID. And it is to be returned to the API caller in its output argument so that it can be used as the reference for subsequent connection operations including connecting, disconnecting, etc.

The following is a sample code to illustrate how this API can be used:

le_result_t ret = le_wifiClient_LoadSsid(ssid, strlen(ssid), &apRef);
if (ret == LE_OK)
{
LE_DEBUG("Wifi configs installed to connect over SSID %s with AP reference %p",
ssid, apRef);
}
else
{
LE_ERROR("Failed to install wifi configs to connect over SSID %s", ssid);
}

Get the currently selected connection

A selected SSID via its AP reference is set for use in Wifi connection establishment since the API call to le_wifiClient_Connect(). Note that while the input argument is actually an Access Point reference, this reference specifically refers to a given SSID on the device. This is considered the selected connection for use until le_wifiClient_Disconnect() is called to deselect it.

During the time when this AP reference is set for use, there comes the need to be able to query le_wifiClient for it back. This is what this le_wifiClient_GetCurrentConnection() API seeks to return. The following is a sample code to illustrate how it can be used. The retrieved AP reference is returned in the output argument.

if (!apRef)
{
return;
}
ret = le_wifiClient_GetSsid(apRef, &ssid[0], &ssidSize);
if (LE_OK != ret)
{
LE_ERROR("Failed to find SSID of AP reference %p", apRef);
return;
}
ssid[ssidSize] = '\0';
LE_DEBUG("Found currently selected Wifi connection to get established: %s, reference %p",
ssid, apRef);