Wi-Fi Connection Manager Library
Overview

This library provides a set of APIs that can be used to establish and monitor Wi-Fi connections on Infineon platforms that support Wi-Fi connectivity. WCM library APIs are easy to use; in addition, the library provides additional features such as Wi-Fi Protected Setup (WPS) and connection monitoring.

Multi-core architecture and virtual API support

The library supports multi-core architecture by making a subset of APIs available as virtual APIs. The virtualization of the WCM library helps to access the WCM APIs defined in one core from the other core using Inter Process Communication (IPC). WCM can now be run on two cores simultaneously, with one core containing the full connectivity stack (primary core) and the other core containing the subset of virtual-only APIs (secondary core). The virtual APIs pipe the API requests over IPC to the primary core where the API is actually executed and the result is passed back to the secondary core. This virtualization abstracts out the implementation details and complexity of IPC, thus making multi-core connectivity application development simple.

For more information on virtualization, see the Virtual Connectivity Manager library.

Features and functionality

The current implementation has the following features and functionality:

  • Supports WPA3 personal network security
  • Supports STA, SoftAP, and Concurrent (simultaneous SoftAP + STA) modes
  • Support for Wi-Fi Protected Setup (WPS) - Enrollee role
  • Exposes Wi-Fi APIs to scan, join, and leave the Wi-Fi network
  • Connection monitoring: Monitors active connections and link events. Automatically reconnects to the AP if the connection with the AP is lost intermittently. Notifies the connection state change through event the notification registration mechanism.
  • Part of the ModusToolbox™ environment that supports connectivity applications based on FreeRTOS, lwIP, and mbed TLS
  • The library is built on top of the abstraction-rtos library that provides RTOS abstraction API for FreeRTOS
  • Supports multi-core architecture by providing the following APIs as virtual APIs which can be invoked from another core:
    • cy_wcm_is_connected_to_ap
    • cy_wcm_register_event_callback
    • cy_wcm_deregister_event_callback

Supported platforms

This library and its features are supported on the following Infineon platforms:

Dependent libraries

This library is bundled in wifi-core-freertos-lwip-mbedtls by default. The wifi-core-freertos-lwip-mbedtls library helps code examples to fetch all the components needed to enable Wi-Fi connectivity.

If virtual APIs are to be used, it additionally depends on Virtual Connectivity Manager library.

Quick start

  • To use wifi-connection-manager library for FreeRTOS, lwIP, and mbed TLS, the application should pull wifi-core-freertos-lwip-mbedtls library which will internally pull wifi-connection-manager, FreeRTOS, lwIP, mbed TLS and other dependent modules.
  • To pull wifi-core-freertos-lwip-mbedtls create the following .mtb file in deps folder.
  • For existing Wi-Fi Connection Manager version 2.x users, a porting guide is available to migrate to Wi-Fi Connection Manager version 3.0.
  • Review the pre-defined configuration files bundled with the wifi-core-freertos-lwip-mbedtls library for FreeRTOS, lwIP, and mbed TLS, and make adjustments. See the quick start section in README.md.
  • Define a set of COMPONENTS in the code example project's Makefile for this library. See the quick start section in README.md.
  • WPS is disabled by default. WPS uses Mbed TLS security stack. Enable the following components for WPS:
    COMPONENTS+=WPS MBEDTLS
  • The WCM library disables all the debug log messages by default. To enable log messages, the application must perform the following:
    1. Add the ENABLE_WCM_LOGS macro to the DEFINES in the code example's Makefile. The Makefile entry would look like as follows:
      DEFINES+=ENABLE_WCM_LOGS
    2. Call the cy_log_init() function provided by the cy-log module. cy-log is part of the connectivity-utilities library. See *connectivity-utilities library API documentation.

use virtual APIs

  • To use WCM virtual APIs, pull Virtual Connectivity Manager library. Create the following *.mtb* file to pull the library
  • Note
    To use WCM APIs in a multi-core environment, applications on both the cores should include WCM and VCM libraries.
  • Define the following compile-time macro in the primary core application's Makefile:
    DEFINES+=ENABLE_MULTICORE_CONN_MW
  • Define the following compile-time macros in the secondary core application's Makefile:
    DEFINES+=ENABLE_MULTICORE_CONN_MW USE_VIRTUAL_API
  • Call the cy_vcm_init() function provided by the VCM library from the application on both cores, before invoking the virtual WCM APIs. See Virtual Connectivity Manager API documentation.
    Note
    - To ensure that the VCM initialization is synchronized, the project which boots first(i.e CM0+ project in case of psoc62) must call cy_vcm_init before bringing up the second project(i.e CM4 project in case of psoc62).
    - The first project must initialize VCM, by passing config.hal_resource_opt as CY_VCM_CREATE_HAL_RESOURCE in cy_vcm_init. The second project must pass config.hal_resource_opt as CY_VCM_USE_HAL_RESOURCE.

Code snippets

Snippet 1: Scan for all APs

The following snippet demonstrates how to initialize the Wi-Fi device and network stack, and start scanning for APs without any filters. The scan_callback receives the scan results and prints them over the serial terminal.

/* Scan callback function */
void scan_callback(cy_wcm_scan_result_t *result_ptr, void *user_data, cy_wcm_scan_status_t status)
{
/* Print the scan result only when scan is incomplete because on scan completion
* the contents of result_ptr are empty.
*/
if (status == CY_WCM_SCAN_INCOMPLETE)
{
printf(" %-32s %4d %2d\n",
result_ptr->SSID, result_ptr->signal_strength, result_ptr->channel);
}
}
void snippet_wcm_scan_without_filter()
{
cy_rslt_t result;
/* Initialize the Wi-Fi device as a STA.*/
/* Initialize the Wi-Fi device, Wi-Fi transport, and lwIP network stack.*/
result = cy_wcm_init(&config);
if(result != CY_RSLT_SUCCESS)
{
printf("\ncy_wcm_init failed....!\n");
}
/* Filter is set to NULL.*/
result = cy_wcm_start_scan(scan_callback, NULL, NULL);
if(result != CY_RSLT_SUCCESS)
{
printf("\ncy_wcm_start_scan failed....!\n");
}
}
cy_wcm_scan_status_t
Enumeration of scan status.
Definition: cy_wcm.h:237
@ CY_WCM_SCAN_INCOMPLETE
Scan is in progress; more scan results will be returned.
Definition: cy_wcm.h:238
@ CY_WCM_INTERFACE_TYPE_STA
STA or client interface.
Definition: cy_wcm.h:218
cy_rslt_t cy_wcm_init(cy_wcm_config_t *config)
Initializes the WCM.
cy_rslt_t cy_wcm_start_scan(cy_wcm_scan_result_callback_t scan_callback, void *user_data, cy_wcm_scan_filter_t *scan_filter)
Performs a Wi-Fi network scan.
Structure used to pass WCM configuration to cy_wcm_init.
Definition: cy_wcm.h:413
cy_wcm_interface_t interface
Interface type.
Definition: cy_wcm.h:414
Structure used for storing scan results.
Definition: cy_wcm.h:495
uint8_t channel
Radio channel that the AP beacon was received on.
Definition: cy_wcm.h:502
int16_t signal_strength
RSSI in dBm.
Definition: cy_wcm.h:498
cy_wcm_ssid_t SSID
SSID (i.e., name of the AP).
Definition: cy_wcm.h:496

Snippet 2: Scan for a specific AP

The following snippet demonstrates the configuration of a scan filter to filter by the SSID provided and start a scan. The scan_callback receives the scan results and prints them over the serial terminal.

void snippet_wcm_scan_with_ssid_filter()
{
cy_rslt_t result;
cy_wcm_scan_filter_t scan_filter;
/* SSID value which is used to filter the scan results.*/
static const cy_wcm_ssid_t ssid = "SSID";
/* Configure the scan filter specified by the variable ssid.*/
memcpy(scan_filter.param.SSID, ssid, sizeof(cy_wcm_ssid_t));
printf("\n---------------------------------------------------------------------------------\n"
" SSID RSSI Channel \n"
"---------------------------------------------------------------------------------\n");
result = cy_wcm_start_scan(scan_callback, NULL, &scan_filter);
if(result != CY_RSLT_SUCCESS)
{
printf("\ncy_wcm_start_scan failed....!\n");
}
}
@ CY_WCM_SCAN_FILTER_TYPE_SSID
SSID-based scan filtering.
Definition: cy_wcm.h:340
uint8_t cy_wcm_ssid_t[CY_WCM_MAX_SSID_LEN+1]
SSID name (AP name in null-terminated string format).
Definition: cy_wcm.h:382
Structure used to pass scan filters to cy_wcm_start_scan.
Definition: cy_wcm.h:479
cy_wcm_scan_filter_type_t mode
Scan filter mode.
Definition: cy_wcm.h:480
union cy_wcm_scan_filter_t::@1 param
Parameter specific to scan filter mode.
cy_wcm_ssid_t SSID
SSID.
Definition: cy_wcm.h:483

Snippet 3: Connect to an AP

The following snippet demonstrates scanning for WIFI_SSID to get the security type of the AP and then connect to it. After a successful connection, the device registers an event callback through which the middleware notifies the application on disconnection, reconnection, and IP change events. If the connection to AP fails, it is retried up to MAX_WIFI_RETRY_COUNT times before reporting failure.

/* Wi-Fi Credentials: Modify WIFI_SSID and WIFI_PASSWORD to match your Wi-Fi network
* credentials.
*/
#define WIFI_SSID "SSID"
#define WIFI_PASSWORD "PASSWORD"
#define MAX_WIFI_RETRY_COUNT (3u)
#define WIFI_CONN_RETRY_INTERVAL_MSEC (100u)
/* The size of the cy_wcm_ip_address_t array that is passed to
* cy_wcm_get_ip_addr API. In the case of stand-alone AP or STA mode, the size of
* the array is 1. In concurrent AP/STA mode, the size of the array is 2 where
* the first index stores the IP address of the STA and the second index
* stores the IP address of the AP.
*/
/* Scan callback function */
void scan_to_get_security(cy_wcm_scan_result_t *result_ptr, void *user_data, cy_wcm_scan_status_t status)
{
cy_wcm_security_t* security = (cy_wcm_security_t *)user_data;
/* Scan for SSID and pass the security type through user_data.*/
if ((strlen((const char *)result_ptr->SSID) != 0) && (status == CY_WCM_SCAN_INCOMPLETE))
{
*security = result_ptr->security;
}
}
void network_event_callback(cy_wcm_event_t event, cy_wcm_event_data_t *event_data)
{
{
printf("Disconnected from Wi-Fi\n");
}
else if (CY_WCM_EVENT_RECONNECTED == event)
{
printf("Reconnected to Wi-Fi.\n");
}
/* This event corresponds to the event when the IP address of the device
* changes.
*/
else if (CY_WCM_EVENT_IP_CHANGED == event)
{
if (event_data->ip_addr.version == CY_WCM_IP_VER_V4)
{
printf("IP Address: %d.%d.%d.%d\n", (uint8_t)event_data->ip_addr.ip.v4,
(uint8_t)(event_data->ip_addr.ip.v4 >> 8), (uint8_t)(event_data->ip_addr.ip.v4 >> 16),
(uint8_t)(event_data->ip_addr.ip.v4 >> 24));
}
else if(event_data->ip_addr.version == CY_WCM_IP_VER_V6)
{
printf("IP Address: %X:%X:%X:%X\n", (uint8_t)event_data->ip_addr.ip.v6[0],
(uint8_t)(event_data->ip_addr.ip.v6[1]), (uint8_t)(event_data->ip_addr.ip.v6[2]),
(uint8_t)(event_data->ip_addr.ip.v6[3]));
}
}
}
void snippet_wcm_connect_ap()
{
cy_rslt_t result;
cy_wcm_connect_params_t connect_param;
cy_wcm_ip_address_t ip_address;
cy_wcm_scan_filter_t scan_filter;
/* Configure the scan filter specified by the macro WIFI_SSID.*/
memcpy(scan_filter.param.SSID, WIFI_SSID, sizeof(WIFI_SSID));
/* Scan with the filter to obtain the security type. The function waits
* until the security type is obtained in scan_to_get_security.
*/
cy_wcm_start_scan(scan_to_get_security, (void *)(&security), &scan_filter);
cy_rtos_delay_milliseconds(10000);
memset(&connect_param, 0, sizeof(cy_wcm_connect_params_t));
memset(&ip_address, 0, sizeof(cy_wcm_ip_address_t));
memcpy(connect_param.ap_credentials.SSID, WIFI_SSID, sizeof(WIFI_SSID));
memcpy(connect_param.ap_credentials.password, WIFI_PASSWORD, sizeof(WIFI_PASSWORD));
connect_param.ap_credentials.security = security;
/* Attempt to connect to Wi-Fi until a connection is made or
* MAX_WIFI_RETRY_COUNT attempts have been made.
*/
for (uint32_t conn_retries = 0; conn_retries < MAX_WIFI_RETRY_COUNT; conn_retries++)
{
result = cy_wcm_connect_ap(&connect_param, &ip_address);
if (result == CY_RSLT_SUCCESS)
{
printf("Successfully connected to Wi-Fi network '%s'.\n", connect_param.ap_credentials.SSID);
/* Register event callbacks for changes in the Wi-Fi link status. These
* events could be related to IP address changes, connection, and
* disconnection events.
*/
cy_wcm_register_event_callback(network_event_callback);
break;
}
printf("Connection to Wi-Fi network failed with error code %d."
"Retrying in %d ms...\n", (int)result, WIFI_CONN_RETRY_INTERVAL_MSEC);
cy_rtos_delay_milliseconds(WIFI_CONN_RETRY_INTERVAL_MSEC);
}
}
cy_wcm_security_t
Enumeration of Wi-Fi Security Modes.
Definition: cy_wcm.h:151
cy_wcm_event_t
Enumeration of WCM events.
Definition: cy_wcm.h:323
@ CY_WCM_IP_VER_V4
Denotes IPv4 version.
Definition: cy_wcm.h:134
@ CY_WCM_IP_VER_V6
Denotes IPv6 version.
Definition: cy_wcm.h:135
@ CY_WCM_EVENT_DISCONNECTED
STA disconnected from the AP.
Definition: cy_wcm.h:328
@ CY_WCM_EVENT_RECONNECTED
STA reconnected to the AP.
Definition: cy_wcm.h:327
@ CY_WCM_EVENT_IP_CHANGED
IP address change event.
Definition: cy_wcm.h:329
cy_rslt_t cy_wcm_register_event_callback(cy_wcm_event_callback_t event_callback)
Registers an event callback to monitor the connection and IP address change events.
cy_rslt_t cy_wcm_connect_ap(cy_wcm_connect_params_t *connect_params, cy_wcm_ip_address_t *ip_addr)
Connects the STA interface to a AP using the Wi-Fi credentials and configuration parameters provided.
cy_rslt_t cy_wcm_stop_scan(void)
Stops an ongoing Wi-Fi network scan.
cy_rslt_t cy_wcm_get_ip_addr(cy_wcm_interface_t interface_type, cy_wcm_ip_address_t *ip_addr)
Retrieves the IPv4 address of the given interface.
cy_wcm_security_t security
Wi-Fi Security.
Definition: cy_wcm.h:449
cy_wcm_passphrase_t password
Password needed to join the AP; should be a null-terminated string.
Definition: cy_wcm.h:448
cy_wcm_ssid_t SSID
SSID of the Wi-Fi network to join; should be a null-terminated string.
Definition: cy_wcm.h:447
Structure used to pass the Wi-Fi connection parameter information to cy_wcm_connect_ap.
Definition: cy_wcm.h:468
cy_wcm_ap_credentials_t ap_credentials
AP credentials.
Definition: cy_wcm.h:469
Structure used to receive the IP address information from cy_wcm_connect_ap.
Definition: cy_wcm.h:422
cy_wcm_ip_version_t version
IP version.
Definition: cy_wcm.h:423
union cy_wcm_ip_address_t::@0 ip
IP address bytes.
uint32_t v6[4]
IPv6 address in network byte order.
Definition: cy_wcm.h:427
uint32_t v4
IPv4 address in network byte order.
Definition: cy_wcm.h:426
cy_wcm_security_t security
Security type.
Definition: cy_wcm.h:501
Structure used to receive the IP address of the STA or MAC address of the connected STA to SoftAP thr...
Definition: cy_wcm.h:435
cy_wcm_ip_address_t ip_addr
Contains the IP address for the CY_WCM_EVENT_IP_CHANGED event.
Definition: cy_wcm.h:436

Snippet 4: Connect to an AP using the WPS-Push button

The following snippet demonstrates joining an AP and obtaining its credentials through WPS using the push button mode. The credentials obtained are printed on the serial terminal.

/* The value of this macro specifies the maximum number of Wi-Fi networks the
* device can join through WPS in one call to cy_wcm_wps_enrollee. This value is
* 2 for dual-band AP. Note that the device can obtain Wi-Fi credentials of only
* one network and therefore can receive a maximum of 1 for single-band Wi-Fi AP or
* 2 for dual-band AP.
*/
#define MAX_WIFI_CREDENTIALS_COUNT (2)
/* Device's enrollee details. Details of WPS mode, WPS authentication, and
* encryption methods supported are provided in this structure.
*/
const cy_wcm_wps_device_detail_t enrollee_details =
{
.device_name = "PSoC 6",
.manufacturer = "Cypress",
.model_name = "PSoC 6",
.model_number = "1.0",
.serial_number = "1234567",
.device_category = CY_WCM_WPS_DEVICE_COMPUTER,
.sub_category = 7,
};
void snippet_wcm_wps_pbc()
{
cy_rslt_t result;
/* Store the credentials obtained through WPS.*/
cy_wcm_wps_credential_t credentials[MAX_WIFI_CREDENTIALS_COUNT];
cy_wcm_wps_config_t wps_config;
/* Store the PIN used for WPS. It is unused when PBC mode is employed.*/
char pin_string[CY_WCM_WPS_PIN_LENGTH];
uint16_t credential_count = MAX_WIFI_CREDENTIALS_COUNT;
/*Configure the mode of the WPS as CY_WCM_WPS_PBC_MODE.*/
wps_config.mode = CY_WCM_WPS_PBC_MODE;
wps_config.password = pin_string;
memset(credentials, 0, sizeof(credentials));
printf("Press the push button on your WPS AP.\n");
result = cy_wcm_wps_enrollee(&wps_config, &enrollee_details, credentials, &credential_count);
if (CY_RSLT_SUCCESS == result)
{
printf("WPS Success.\n");
/* Print the WPS credentials obtained through WPS.*/
for (uint32_t loop = 0; loop < credential_count; loop++)
{
printf("%d. SSID = %s, Password = %c%c******.\n", (uint8_t)loop + 1, credentials[loop].ssid, credentials[loop].passphrase[0], credentials[loop].passphrase[1]);
}
}
}
@ CY_WCM_WPS_DEVICE_COMPUTER
Computer devices.
Definition: cy_wcm.h:304
@ CY_WCM_WPS_PBC_MODE
Push button mode.
Definition: cy_wcm.h:247
@ CY_WCM_WPS_AES_ENCRYPTION
AES encryption.
Definition: cy_wcm.h:292
@ CY_WCM_WPS_TKIP_ENCRYPTION
TKIP encryption - Deprecated in WSC 2.0.
Definition: cy_wcm.h:293
@ CY_WCM_WPS_NO_ENCRYPTION
OPEN - No encryption.
Definition: cy_wcm.h:295
@ CY_WCM_WPS_WPA2_PSK_AUTHENTICATION
WPA2-PSK authentication type.
Definition: cy_wcm.h:282
@ CY_WCM_WPS_WPA2_WPA_PSK_MIXED_AUTHENTICATION
WPA2-WPA-PSK authentication type.
Definition: cy_wcm.h:283
@ CY_WCM_WPS_WPA_PSK_AUTHENTICATION
WPA-PSK authentication type - Deprecated in version 2.0.
Definition: cy_wcm.h:278
@ CY_WCM_WPS_OPEN_AUTHENTICATION
Authentication type OPEN.
Definition: cy_wcm.h:277
@ CY_WCM_WPS_CONFIG_VIRTUAL_PUSH_BUTTON
Virtual push button configuration.
Definition: cy_wcm.h:265
@ CY_WCM_WPS_CONFIG_VIRTUAL_DISPLAY_PIN
Virtual display pin configuration.
Definition: cy_wcm.h:267
@ CY_WCM_WPS_CONFIG_LABEL
Label configuration.
Definition: cy_wcm.h:258
cy_rslt_t cy_wcm_wps_enrollee(cy_wcm_wps_config_t *config, const cy_wcm_wps_device_detail_t *details, cy_wcm_wps_credential_t *credentials, uint16_t *credential_count)
Negotiates securely with a Wi-Fi Protected Setup (WPS) Registrar (usually an AP) and obtains the Wi-F...
#define CY_WCM_WPS_PIN_LENGTH
WPS password length for PIN mode.
Definition: cy_wcm.h:113
Structure used to pass WPS configuration parameters to cy_wcm_wps_enrollee.
Definition: cy_wcm.h:404
char * password
Used only for CY_WCM_WPS_PIN mode.
Definition: cy_wcm.h:406
cy_wcm_wps_mode_t mode
WPS mode.
Definition: cy_wcm.h:405
Structure used to receive the AP credential after WPS is completed successfully from cy_wcm_wps_enrol...
Definition: cy_wcm.h:534
Structure used to pass the device information to cy_wcm_wps_enrollee.
Definition: cy_wcm.h:515
const char * device_name
Device name.
Definition: cy_wcm.h:518

Snippet 5: Connect to an AP using WPS-PIN

The following snippet demonstrates joining an AP and obtaining its credentials through WPS using the PIN mode. The credentials obtained are printed on the serial terminal.

void snippet_wcm_wps_pin()
{
cy_rslt_t result;
cy_wcm_wps_credential_t credentials[MAX_WIFI_CREDENTIALS_COUNT];
cy_wcm_wps_config_t wps_config;
char pin_string[CY_WCM_WPS_PIN_LENGTH];
uint16_t credential_count = MAX_WIFI_CREDENTIALS_COUNT;
memset(credentials, 0, sizeof(credentials));
/* Here, the WPS PIN is generated by the device. The user must
* enter the PIN in the AP to join the network through WPS.
*/
/*Configure the mode of WPS as CY_WCM_WPS_PIN_MODE.*/
wps_config.mode = CY_WCM_WPS_PIN_MODE;
wps_config.password = pin_string;
printf("Enter this PIN: \'%s\' in your AP.\n", pin_string);
result = cy_wcm_wps_enrollee(&wps_config, &enrollee_details, credentials, &credential_count);
if (CY_RSLT_SUCCESS == result)
{
printf("WPS Success.\n");
/* Print the WPS credentials obtained through WPS.*/
for (uint32_t loop = 0; loop < credential_count; loop++)
{
printf("%d. SSID = %s, Password = %c%c******.\n", (uint8_t)loop + 1, credentials[loop].ssid, credentials[loop].passphrase[0], credentials[loop].passphrase[1]);
}
}
}
@ CY_WCM_WPS_PIN_MODE
PIN mode.
Definition: cy_wcm.h:248
cy_rslt_t cy_wcm_wps_generate_pin(char wps_pin_string[CY_WCM_WPS_PIN_LENGTH])
Generates a random WPS PIN for PIN mode connection.

Snippet 6: Pinging the gateway IP address

The following snippet demonstrates ping to the gateway IP address with a STA mode connection.

#define WIFI_SSID "SSID"
#define WIFI_PASSWORD "PASSWORD"
#define MAX_WIFI_RETRY_COUNT (3u)
#define WIFI_CONN_RETRY_INTERVAL_MSEC (100u)
void snippet_wcm_sta_ping()
{
cy_rslt_t result;
char ip4_str[16];
cy_nw_ip_address_t nw_ipv4;
/* Initialize the Wi-Fi device as a STA.*/
cy_wcm_connect_params_t connect_param;
cy_wcm_ip_address_t ip_address;
cy_wcm_ip_address_t ip_addr, gateway_addr;
uint32_t elapsed_time_ms;
memset(&connect_param, 0, sizeof(cy_wcm_connect_params_t));
memset(&ip_address, 0, sizeof(cy_wcm_ip_address_t));
memcpy(connect_param.ap_credentials.SSID, WIFI_SSID, sizeof(WIFI_SSID));
memcpy(connect_param.ap_credentials.password, WIFI_PASSWORD, sizeof(WIFI_PASSWORD));
/* Initialize the Wi-Fi device, Wi-Fi transport, and lwIP network stack.*/
result = cy_wcm_init(&config);
if (result != CY_RSLT_SUCCESS)
{
printf("\ncy_wcm_init failed...!\n");
return;
}
printf("\n*** Starting STA Mode ***\n");
/* Attempt to connect to Wi-Fi until a connection is made or
* MAX_WIFI_RETRY_COUNT attempts have been made.
*/
for (uint32_t conn_retries = 0; conn_retries < MAX_WIFI_RETRY_COUNT; conn_retries++)
{
result = cy_wcm_connect_ap(&connect_param, &ip_address);
if (result == CY_RSLT_SUCCESS)
{
printf("Successfully connected to Wi-Fi network '%s'.\n", connect_param.ap_credentials.SSID);
break;
}
printf("Connection to Wi-Fi network failed with error code %d."
"Retrying in %d ms...\n", (int)result, WIFI_CONN_RETRY_INTERVAL_MSEC);
cy_rtos_delay_milliseconds(WIFI_CONN_RETRY_INTERVAL_MSEC);
}
/* Get IPv4 address */
nw_ipv4.ip.v4 = ip_addr.ip.v4;
cy_nw_ntoa(&nw_ipv4, ip4_str);
printf("IPV4 address: %s\n", ip4_str);
/* Get gateway address */
nw_ipv4.ip.v4 = gateway_addr.ip.v4;
cy_nw_ntoa(&nw_ipv4, ip4_str);
printf("IPV4 address: %s\n", ip4_str);
cy_rtos_delay_milliseconds(2000);
printf("Pinging to gateway IP address ... \n");
/* Send PING request with 3000ms ping timeout */
result = cy_wcm_ping(CY_WCM_INTERFACE_TYPE_STA, &gateway_addr, 3000, &elapsed_time_ms);
if( result == CY_RSLT_SUCCESS)
{
printf("ping was successful time elapsed = %u\n", (uint8_t)elapsed_time_ms);
}
else
{
printf("Ping failed !!\n");
}
}
@ CY_WCM_SECURITY_WPA2_AES_PSK
WPA2 PSK security with AES.
Definition: cy_wcm.h:158
cy_rslt_t cy_wcm_get_gateway_ip_address(cy_wcm_interface_t interface_type, cy_wcm_ip_address_t *gateway_addr)
Retrieves the gateway IP address of the given interface.
cy_rslt_t cy_wcm_ping(cy_wcm_interface_t interface, cy_wcm_ip_address_t *ip_addr, uint32_t timeout_ms, uint32_t *elapsed_ms)
Sends a ping request to the given IP address.

Snippet 7: SoftAP start-stop

The following snippet demonstrates SoftAP start and stop.

#define WIFI_SSID_AP "AnyCloud"
#define WIFI_KEY_AP "abcd@9009"
static cy_wcm_ip_setting_t ap_mode_ip_settings;
static void ap_event_cb(cy_wcm_event_t event, cy_wcm_event_data_t *event_data)
{
char ip4_str[16];
cy_nw_ip_address_t nw_ipv4;
printf("######### Received event changed from wcm, event = %d #######\n", event);
switch(event)
{
{
printf("Network is down! \n");
break;
}
{
printf("Network is up again! \n");
break;
}
{
printf("Connecting to AP ... \n");
break;
}
{
printf("Connected to AP and network is up !! \n");
break;
}
{
printf("Connection to AP Failed ! \n");
break;
}
{
if(event_data->ip_addr.version == CY_WCM_IP_VER_V4)
{
nw_ipv4.ip.v4 = event_data->ip_addr.ip.v4;
cy_nw_ntoa(&nw_ipv4, ip4_str);
printf("IPV4 address: %s\n", ip4_str);
}
break;
}
{
printf("mac address of the STA which joined = %02X : %02X : %02X : %02X : %02X : %02X \n",
event_data->sta_mac[0], event_data->sta_mac[1], event_data->sta_mac[2],
event_data->sta_mac[3], event_data->sta_mac[4], event_data->sta_mac[5]);
break;
}
{
printf("mac address of the STA which left = %02X : %02X : %02X : %02X : %02X : %02X \n",
event_data->sta_mac[0], event_data->sta_mac[1], event_data->sta_mac[2],
event_data->sta_mac[3], event_data->sta_mac[4], event_data->sta_mac[5]);
break;
}
default:
{
printf("Invalid event \n");
break;
}
}
}
void snippet_wcm_ap_start_stop()
{
cy_rslt_t result;
char ip6_str[40];
char ip4_str[16];
char *ip = "192.168.0.2";
char *netmask = "255.255.255.0";
char *gateway = "192.168.0.2";
cy_nw_ip_address_t nw_ipv4;
cy_nw_ip_address_t nw_ipv6;
/* Initialize the Wi-Fi device, Wi-Fi transport, and lwIP network stack.*/
result = cy_wcm_init(&config);
if(result != CY_RSLT_SUCCESS)
{
printf("\ncy_wcm_init failed...!\n");
return;
}
/* AP settings */
cy_wcm_set_ap_ip_setting(&ap_mode_ip_settings, ip, netmask, gateway, CY_WCM_IP_VER_V4);
memset(&ap_conf, 0, sizeof(cy_wcm_ap_config_t));
ap_conf.channel = 1;
memcpy(ap_conf.ap_credentials.SSID, WIFI_SSID_AP, strlen(WIFI_SSID_AP) + 1);
memcpy(ap_conf.ap_credentials.password, WIFI_KEY_AP, strlen(WIFI_KEY_AP) + 1);
ap_conf.ip_settings.ip_address = ap_mode_ip_settings.ip_address;
ap_conf.ip_settings.netmask = ap_mode_ip_settings.netmask;
ap_conf.ip_settings.gateway = ap_mode_ip_settings.gateway;
printf("configured ip address of the AP = %u \n", (uint8_t)ap_conf.ip_settings.ip_address.ip.v4);
nw_ipv4.ip.v4 = ap_conf.ip_settings.ip_address.ip.v4;
cy_nw_ntoa(&nw_ipv4, ip4_str);
printf("IPV4 address: %s\n", ip4_str);
/* Start AP */
result = cy_wcm_start_ap(&ap_conf);
if( result != CY_RSLT_SUCCESS )
{
printf("\ncy_wcm_start_ap failed....! \n");
return;
}
/* Register AP event callback */
result = cy_wcm_register_event_callback(&ap_event_cb);
if( result != CY_RSLT_SUCCESS )
{
printf("\ncy_wcm_register_event_callback failed....! \n");
return;
}
/* Link Local IPV6 AP address for AP */
if( result != CY_RSLT_SUCCESS )
{
printf("\ncy_wcm_get_ipv6_addr failed....! \n");
return;
}
nw_ipv6.ip.v6[0] = ipv6_addr.ip.v6[0];
nw_ipv6.ip.v6[1] = ipv6_addr.ip.v6[1];
nw_ipv6.ip.v6[2] = ipv6_addr.ip.v6[2];
nw_ipv6.ip.v6[3] = ipv6_addr.ip.v6[3];
cy_nw_ntoa_ipv6(&nw_ipv6, ip6_str);
printf("IPV6 address: %s\n", ip6_str);
/* wait for 30 seconds to check whether AP is visible or not */
cy_rtos_delay_milliseconds(30000);
/* Stop AP */
result = cy_wcm_stop_ap();
if( result != CY_RSLT_SUCCESS )
{
printf("\ncy_wcm_stop_ap failed....! \n");
}
return;
}
@ CY_WCM_IPV6_LINK_LOCAL
Denotes IPv6 link-local address type.
Definition: cy_wcm.h:143
@ CY_WCM_INTERFACE_TYPE_AP
SoftAP interface.
Definition: cy_wcm.h:219
@ CY_WCM_EVENT_CONNECTED
STA connected to the AP.
Definition: cy_wcm.h:325
@ CY_WCM_EVENT_STA_LEFT_SOFTAP
An STA device disconnected from SoftAP.
Definition: cy_wcm.h:332
@ CY_WCM_EVENT_CONNECTING
STA connecting to an AP.
Definition: cy_wcm.h:324
@ CY_WCM_EVENT_STA_JOINED_SOFTAP
An STA device connected to SoftAP.
Definition: cy_wcm.h:331
@ CY_WCM_EVENT_CONNECT_FAILED
STA connection to the AP failed.
Definition: cy_wcm.h:326
cy_rslt_t cy_wcm_start_ap(const cy_wcm_ap_config_t *ap_config)
Starts an infrastructure Wi-Fi network (SoftAP).
cy_rslt_t cy_wcm_get_ipv6_addr(cy_wcm_interface_t interface_type, cy_wcm_ipv6_type_t ipv6_addr_type, cy_wcm_ip_address_t *ip_addr)
Retrieves the IPv6 address of the given interface.
cy_rslt_t cy_wcm_stop_ap(void)
Stops the infrastructure Wi-Fi network (SoftAP), removes the information element and stops the intern...
cy_rslt_t cy_wcm_set_ap_ip_setting(cy_wcm_ip_setting_t *ap_ip, const char *ip_addr, const char *netmask, const char *gateway_addr, cy_wcm_ip_version_t ver)
Stores the AP settings provided by the user.
Structure used to configure the access point.
Definition: cy_wcm.h:583
cy_wcm_ap_credentials_t ap_credentials
AP credentials.
Definition: cy_wcm.h:584
uint8_t channel
Radio channel of the AP.
Definition: cy_wcm.h:585
cy_wcm_ip_setting_t ip_settings
IP settings of the AP interface.
Definition: cy_wcm.h:586
Structure used to pass the static IP address information to cy_wcm_connect_ap.
Definition: cy_wcm.h:457
cy_wcm_ip_address_t gateway
Gateway address.
Definition: cy_wcm.h:459
cy_wcm_ip_address_t netmask
Netmask.
Definition: cy_wcm.h:460
cy_wcm_ip_address_t ip_address
IP address.
Definition: cy_wcm.h:458
cy_wcm_mac_t sta_mac
MAC address of the STA for the CY_WCM_EVENT_STA_JOINED or CY_WCM_EVENT_STA_LEFT.
Definition: cy_wcm.h:437

Snippet 8: Clients connected to the SoftAP

The following snippet demonstrates usage of the cy_wcm_get_associated_client_list API function to get the list of clients connected to the SoftAP.

#define WIFI_SSID_AP "AnyCloud"
#define WIFI_KEY_AP "abcd@9009"
static cy_wcm_ip_setting_t ap_ip_settings;
static void ap_eve_callback(cy_wcm_event_t event, cy_wcm_event_data_t *event_data)
{
char ip4_str[16];
cy_nw_ip_address_t nw_ipv4;
printf("######### Received event changed from wcm, event = %d #######\n", event);
switch(event)
{
{
printf("Network is down! \n");
break;
}
{
printf("Network is up again! \n");
break;
}
{
printf("Connecting to AP ... \n");
break;
}
{
printf("Connected to AP and network is up !! \n");
break;
}
{
printf("Connection to AP Failed ! \n");
break;
}
{
if(event_data->ip_addr.version == CY_WCM_IP_VER_V4)
{
nw_ipv4.ip.v4 = event_data->ip_addr.ip.v4;
cy_nw_ntoa(&nw_ipv4, ip4_str);
printf("IPV4 address: %s\n", ip4_str);
}
break;
}
{
printf("mac address of the STA which joined = %02X : %02X : %02X : %02X : %02X : %02X \n",
event_data->sta_mac[0], event_data->sta_mac[1], event_data->sta_mac[2],
event_data->sta_mac[3], event_data->sta_mac[4], event_data->sta_mac[5]);
break;
}
{
printf("mac address of the STA which left = %02X : %02X : %02X : %02X : %02X : %02X \n",
event_data->sta_mac[0], event_data->sta_mac[1], event_data->sta_mac[2],
event_data->sta_mac[3], event_data->sta_mac[4], event_data->sta_mac[5]);
break;
}
default:
{
printf("Invalid event \n");
break;
}
}
}
void snippet_wcm_ap_get_client()
{
cy_rslt_t result;
char ip6_str[40];
char ip4_str[16];
char *ip = "192.168.0.2";
char *netmask = "255.255.255.0";
char *gateway = "192.168.0.2";
cy_nw_ip_address_t nw_ipv6;
cy_nw_ip_address_t nw_ipv4;
/* Initialize the Wi-Fi device, Wi-Fi transport, and lwIP network stack.*/
result = cy_wcm_init(&config);
if(result != CY_RSLT_SUCCESS)
{
printf("\ncy_wcm_init failed...!\n");
return;
}
/* AP settings */
cy_wcm_set_ap_ip_setting(&ap_ip_settings, ip, netmask, gateway, CY_WCM_IP_VER_V4);
memset(&ap_conf, 0, sizeof(cy_wcm_ap_config_t));
ap_conf.channel = 1;
memcpy(ap_conf.ap_credentials.SSID, WIFI_SSID_AP, strlen(WIFI_SSID_AP) + 1);
memcpy(ap_conf.ap_credentials.password, WIFI_KEY_AP, strlen(WIFI_KEY_AP) + 1);
ap_conf.ip_settings.ip_address = ap_ip_settings.ip_address;
ap_conf.ip_settings.netmask = ap_ip_settings.netmask;
ap_conf.ip_settings.gateway = ap_ip_settings.gateway;
printf("configured ip address of the AP = %u \n", (uint8_t)ap_conf.ip_settings.ip_address.ip.v4);
nw_ipv4.ip.v4 = ap_conf.ip_settings.ip_address.ip.v4;
cy_nw_ntoa(&nw_ipv4, ip4_str);
printf("IPV4 address: %s\n", ip4_str);
/* Start AP */
result = cy_wcm_start_ap(&ap_conf);
if( result != CY_RSLT_SUCCESS )
{
printf("\ncy_wcm_start_ap failed....! \n");
return;
}
/* Register AP event callback */
result = cy_wcm_register_event_callback(&ap_eve_callback);
if( result != CY_RSLT_SUCCESS )
{
printf("\ncy_wcm_register_event_callback failed....! \n");
return;
}
/* Link Local IPV6 AP address for AP */
if( result != CY_RSLT_SUCCESS )
{
printf("\ncy_wcm_get_ipv6_addr failed....! \n");
return;
}
nw_ipv6.ip.v6[0] = ipv6_addr.ip.v6[0];
nw_ipv6.ip.v6[1] = ipv6_addr.ip.v6[1];
nw_ipv6.ip.v6[2] = ipv6_addr.ip.v6[2];
nw_ipv6.ip.v6[3] = ipv6_addr.ip.v6[3];
cy_nw_ntoa_ipv6(&nw_ipv6, ip6_str);
printf("IPV6 address: %s\n", ip6_str);
/* wait for 30 seconds for a client to connect */
cy_rtos_delay_milliseconds(30000);
/* get connected client */
cy_wcm_mac_t mac_add;
result = cy_wcm_get_associated_client_list(&mac_add, 1);
if( result != CY_RSLT_SUCCESS )
{
printf("\ncy_wcm_get_associated_client_list failed....! \n");
return;
}
printf("mac address obtained from cy_wcm_get_associated_client_list = %02X : %02X : %02X : %02X : %02X : %02X \n",
mac_add[0], mac_add[1], mac_add[2],mac_add[3], mac_add[4], mac_add[5]);
return;
}
cy_rslt_t cy_wcm_get_associated_client_list(cy_wcm_mac_t *sta_list, uint8_t num_clients)
Gets the MAC address of the clients associated with the SoftAP.
uint8_t cy_wcm_mac_t[CY_WCM_MAC_ADDR_LEN]
Unique 6-byte MAC address represented in network byte order.
Definition: cy_wcm.h:384

Snippet 9: AP+STA concurrent mode

The following snippet demonstrates AP+STA concurrent mode operation.

/* Wi-Fi Credentials: Modify WIFI_SSID and WIFI_PASSWORD to match your Wi-Fi network
* credentials.
*/
#define WIFI_SSID "SSID"
#define WIFI_PASSWORD "PASSWORD"
#define WIFI_SSID_AP "AnyCloud"
#define WIFI_KEY_AP "abcd@9009"
#define MAX_WIFI_RETRY_COUNT (3u)
#define WIFI_CONN_RETRY_INTERVAL_MSEC (100u)
/* The size of the cy_wcm_ip_address_t array that is passed to
* cy_wcm_get_ip_addr API. In the case of stand-alone AP or STA mode, the size of
* the array is 1. In concurrent AP/STA mode, the size of the array is 2 where
* the first index stores the IP address of the STA and the second index
* stores the IP address of the AP.
*/
static cy_wcm_ip_setting_t ap_sta_mode_ip_settings;
void sta_event_callback(cy_wcm_event_t event, cy_wcm_event_data_t *event_data)
{
{
printf("Disconnected from Wi-Fi\n");
}
else if (CY_WCM_EVENT_RECONNECTED == event)
{
printf("Reconnected to Wi-Fi.\n");
}
/* This event corresponds to the event when the IP address of the device
* changes.
*/
else if (CY_WCM_EVENT_IP_CHANGED == event)
{
if (event_data->ip_addr.version == CY_WCM_IP_VER_V4)
{
printf("IP Address: %d.%d.%d.%d\n", (uint8_t)event_data->ip_addr.ip.v4,
(uint8_t)(event_data->ip_addr.ip.v4 >> 8), (uint8_t)(event_data->ip_addr.ip.v4 >> 16),
(uint8_t)(event_data->ip_addr.ip.v4 >> 24));
}
else if(event_data->ip_addr.version == CY_WCM_IP_VER_V6)
{
printf("IP Address: %X:%X:%X:%X\n", (uint8_t)event_data->ip_addr.ip.v6[0],
(uint8_t)(event_data->ip_addr.ip.v6[1]), (uint8_t)(event_data->ip_addr.ip.v6[2]),
(uint8_t)(event_data->ip_addr.ip.v6[3]));
}
}
}
static void ap_event_callback(cy_wcm_event_t event, cy_wcm_event_data_t *event_data)
{
char ip4_str[16];
cy_nw_ip_address_t nw_ipv4;
printf("######### Received event changed from wcm, event = %d #######\n", event);
switch(event)
{
{
printf("Network is down! \n");
break;
}
{
printf("Network is up again! \n");
break;
}
{
printf("Connecting to AP ... \n");
break;
}
{
printf("Connected to AP and network is up !! \n");
break;
}
{
printf("Connection to AP Failed ! \n");
break;
}
{
if(event_data->ip_addr.version == CY_WCM_IP_VER_V4)
{
nw_ipv4.ip.v4 = event_data->ip_addr.ip.v4;
cy_nw_ntoa(&nw_ipv4, ip4_str);
printf("IPV4 address: %s\n", ip4_str);
}
break;
}
{
printf("mac address of the STA which joined = %02X : %02X : %02X : %02X : %02X : %02X \n",
event_data->sta_mac[0], event_data->sta_mac[1], event_data->sta_mac[2],
event_data->sta_mac[3], event_data->sta_mac[4], event_data->sta_mac[5]);
break;
}
{
printf("mac address of the STA which left = %02X : %02X : %02X : %02X : %02X : %02X \n",
event_data->sta_mac[0], event_data->sta_mac[1], event_data->sta_mac[2],
event_data->sta_mac[3], event_data->sta_mac[4], event_data->sta_mac[5]);
break;
}
default:
{
printf("Invalid event \n");
break;
}
}
}
void snippet_wcm_concurrent_mode()
{
cy_rslt_t result;
char ip6_str[40];
char ip4_str[16];
char *ip = "192.168.0.2";
char *netmask = "255.255.255.0";
char *gateway = "192.168.0.2";
cy_nw_ip_address_t nw_ipv4;
cy_nw_ip_address_t nw_ipv6;
/* Initialize the Wi-Fi device as a STA.*/
cy_wcm_connect_params_t connect_param;
cy_wcm_ip_address_t ip_address,ipv4_addr,ipv6_addr;
memset(&connect_param, 0, sizeof(cy_wcm_connect_params_t));
memset(&ip_address, 0, sizeof(cy_wcm_ip_address_t));
memset(&security, 0, sizeof(cy_wcm_security_t));
memcpy(connect_param.ap_credentials.SSID, WIFI_SSID, sizeof(WIFI_SSID));
memcpy(connect_param.ap_credentials.password, WIFI_PASSWORD, sizeof(WIFI_PASSWORD));
connect_param.ap_credentials.security = security;
/* Initialize the Wi-Fi device, Wi-Fi transport, and lwIP network stack.*/
result = cy_wcm_init(&config);
if(result != CY_RSLT_SUCCESS)
{
printf("\ncy_wcm_init failed...!\n");
return;
}
/* AP settings */
cy_wcm_set_ap_ip_setting(&ap_sta_mode_ip_settings, ip, netmask, gateway, CY_WCM_IP_VER_V4);
printf("\n*** Starting STA Mode ***\n");
/* Attempt to connect to Wi-Fi until a connection is made or
* MAX_WIFI_RETRY_COUNT attempts have been made.
*/
for (uint32_t conn_retries = 0; conn_retries < MAX_WIFI_RETRY_COUNT; conn_retries++)
{
result = cy_wcm_connect_ap(&connect_param, &ip_address);
if (result == CY_RSLT_SUCCESS)
{
printf("Successfully connected to Wi-Fi network '%s'.\n", connect_param.ap_credentials.SSID);
/* Register event callbacks for changes in the Wi-Fi link status. These
* events could be related to IP address changes, connection, and
* disconnection events.
*/
cy_wcm_register_event_callback(sta_event_callback);
break;
}
printf("Connection to Wi-Fi network failed with error code %d."
"Retrying in %d ms...\n", (int)result, WIFI_CONN_RETRY_INTERVAL_MSEC);
cy_rtos_delay_milliseconds(WIFI_CONN_RETRY_INTERVAL_MSEC);
}
printf("\n*** Starting AP Mode ***\n");
memset(&ap_conf, 0, sizeof(cy_wcm_ap_config_t));
memset(&ipv4_addr, 0, sizeof(cy_wcm_ip_address_t));
memset(&ipv6_addr, 0, sizeof(cy_wcm_ip_address_t));
ap_conf.channel = 1;
memcpy(ap_conf.ap_credentials.SSID, WIFI_SSID_AP, strlen(WIFI_SSID_AP) + 1);
memcpy(ap_conf.ap_credentials.password, WIFI_KEY_AP, strlen(WIFI_KEY_AP) + 1);
ap_conf.ip_settings.ip_address = ap_sta_mode_ip_settings.ip_address;
ap_conf.ip_settings.netmask = ap_sta_mode_ip_settings.netmask;
ap_conf.ip_settings.gateway = ap_sta_mode_ip_settings.gateway;
printf("configured ip address of the AP = %u \n", (uint8_t)ap_conf.ip_settings.ip_address.ip.v4);
nw_ipv4.ip.v4 = ap_conf.ip_settings.ip_address.ip.v4;
cy_nw_ntoa(&nw_ipv4, ip4_str);
printf("IPV4 address: %s\n", ip4_str);
cy_wcm_register_event_callback(&ap_event_callback);
result = cy_wcm_start_ap(&ap_conf);
if (result != CY_RSLT_SUCCESS)
{
printf("\ncy_wcm_start_ap failed...! \n");
return;
}
printf("\nAP started successfully... \n");
/* Get IPV4 address for AP */
if (result != CY_RSLT_SUCCESS)
{
printf("\ncy_wcm_get_ip_addr failed...! \n");
return;
}
printf("\nIPV4 address of AP : ");
nw_ipv4.ip.v4 = ipv4_addr.ip.v4;
cy_nw_ntoa(&nw_ipv4, ip4_str);
printf("IPV4 address: %s\n", ip4_str);
/* Get IPV6 address for AP */
printf("Link Local IPV6 AP address \n");
if (result != CY_RSLT_SUCCESS)
{
printf("\ncy_wcm_get_ipv6_addr failed...! \n");
return;
}
printf("\nLink Local IPV6 AP address : ");
nw_ipv6.ip.v6[0] = ipv6_addr.ip.v6[0];
nw_ipv6.ip.v6[1] = ipv6_addr.ip.v6[1];
nw_ipv6.ip.v6[2] = ipv6_addr.ip.v6[2];
nw_ipv6.ip.v6[3] = ipv6_addr.ip.v6[3];
cy_nw_ntoa_ipv6(&nw_ipv6, ip6_str);
printf("IPV6 address: %s\n", ip6_str);
/* Get Link Local IPV6 STA address */
if (result != CY_RSLT_SUCCESS)
{
printf("\ncy_wcm_get_ipv6_addr failed...! \n");
return;
}
printf("\nLink Local IPV6 STA address : ");
nw_ipv6.ip.v6[0] = ipv6_addr.ip.v6[0];
nw_ipv6.ip.v6[1] = ipv6_addr.ip.v6[1];
nw_ipv6.ip.v6[2] = ipv6_addr.ip.v6[2];
nw_ipv6.ip.v6[3] = ipv6_addr.ip.v6[3];
cy_nw_ntoa_ipv6(&nw_ipv6, ip6_str);
printf("IPV6 address: %s\n", ip6_str);
/* Get MAC address of both STA and AP interface using CY_WCM_INTERFACE_TYPE_AP_STA */
cy_wcm_mac_t *mac_addr_ptr;
mac_addr_ptr = (cy_wcm_mac_t*)malloc(sizeof(cy_wcm_mac_t) *2);
cy_wcm_mac_t sta_mac, ap_mac;
memcpy(&sta_mac, mac_addr_ptr, sizeof(sta_mac));
printf("mac address of STA = %02X : %02X : %02X : %02X : %02X : %02X \n",
sta_mac[0], sta_mac[1], sta_mac[2],sta_mac[3], sta_mac[4], sta_mac[5]);
memcpy(&ap_mac, &mac_addr_ptr[1], sizeof(ap_mac));
printf("mac address AP = %02X : %02X : %02X : %02X : %02X : %02X \n",
ap_mac[0], ap_mac[1], ap_mac[2],ap_mac[3], ap_mac[4], ap_mac[5]);
free(mac_addr_ptr);
}
@ CY_WCM_INTERFACE_TYPE_AP_STA
Concurrent AP + STA mode.
Definition: cy_wcm.h:220
cy_rslt_t cy_wcm_get_mac_addr(cy_wcm_interface_t interface_type, cy_wcm_mac_t *mac_addr)
Retrieves the MAC address of the given interface.

Snippet 10: Virtual API usage to check connection status from the secondary core

The following snippet demonstrates the usage of virtual WCM API - cy_wcm_is_connected_to_ap() in a multi-core environment.

/***************************** Secondary core ***************************/
/* Flag to be set when VCM initialization is completed on the other core */
static bool is_vcm_init_complete = false;
/* Callback registered on the secondary core to handle events from VCM. */
void vcm_callback_sec_core(cy_vcm_event_t event)
{
switch(event)
{
case CY_VCM_EVENT_INIT_COMPLETE:
{
/* VCM init complete */
is_vcm_init_complete = 1;
break;
}
default:
break;
}
}
/* The following snippet demostrates usage of VCM and virtual WCM APIs from the secondary core.
* The primary core is where the full WCM implementation is present. The secondary core only
* has the virtual implementation.
* In this example, the secondary core application runs first and it enables the primary core.
* Before enabling the primary core, the secondary core initializes the VCM library.
*/
void snippet_wcm_virtual_api_usage_sec_core()
{
cy_rslt_t result;
cy_vcm_config_t vcm_config;
/* Initialize the VCM library */
vcm_config.hal_resource_opt = CY_VCM_CREATE_HAL_RESOURCE; /* set to CY_VCM_CREATE_HAL_RESOURCE as the secondary core is the first one to initialize VCM. */
vcm_config.channel_num = CYHAL_IPC_CHAN_0;
vcm_config.event_cb = vcm_callback_sec_core;
result = cy_vcm_init(&vcm_config);
if( result != CY_RSLT_SUCCESS )
{
printf("\n cy_vcm_init failed! \n");
return;
}
/* Enable the other core.
* For example, for enabling CM4, the following code is applicable.
* When this is called, the application on core 2 will begin executing. Ensure cy_vcm_init()
* is called on the second core when the execution begins.
*/
Cy_SysEnableCM4(CY_CORTEX_M4_APPL_ADDR);
/* Wait for VCM initialization to complete */
while ( !is_vcm_init_complete )
{
cy_rtos_delay_milliseconds(1000);
}
/* Initialize the WCM library */
result = cy_wcm_init(NULL);
if( result != CY_RSLT_SUCCESS )
{
printf("\n cy_wcm_init failed on secondary core! \n");
return;
}
/* Check if the device is connected to an AP using the below virtual API */
uint8_t is_connected = cy_wcm_is_connected_to_ap();
printf("\n STA connection status: %u\n", is_connected);
/* ... */
/* When WCM virtual APIs are no longer needed on the secondary core, deinit WCM and VCM */
result = cy_wcm_deinit();
if( result != CY_RSLT_SUCCESS )
{
printf("\n cy_wcm_deinit failed on secondary core! \n");
return;
}
result = cy_vcm_deinit();
if( result != CY_RSLT_SUCCESS )
{
printf("\n cy_vcm_deinit failed on secondary core! \n");
return;
}
}
/***************************** Primary Core *****************************/
/* Wi-Fi Credentials: Modify WIFI_AP_SSID and WIFI_AP_PASSWORD to match your Wi-Fi network
* credentials.
*/
#define WIFI_AP_SSID "SSID"
#define WIFI_AP_PASSWORD "PASSWORD"
/* Flag that is set when VCM deinit is started by the other core.
* When this event is received, call cy_vcm_deinit() to deinitialize VCM
* on the current core.
*/
static bool is_vcm_deinit_requested = false;
/* Callback registered by the application on primary core to handle events from VCM. */
void vcm_callback_prim_core(cy_vcm_event_t event)
{
switch(event)
{
case CY_VCM_EVENT_DEINIT:
{
/* The other core has initiated VCM deinit. Deinitialize VCM locally. */
is_vcm_deinit_requested = true;
break;
}
default:
break;
}
}
/* The following snippet demostrates usage of VCM on the primary core.
* The primary core is where the full WCM implementation is present. The secondary core only
* has the virtual implementation. The primary core initializes wcm and connects to an AP.
* Ensure that this snippet is executed when the primary core is enabled.
*/
void snippet_wcm_virtual_api_usage_prim_core()
{
cy_rslt_t result;
cy_vcm_config_t vcm_config;
cy_wcm_config_t wcm_config;
cy_wcm_connect_params_t connect_params;
/* Initialize the VCM library */
vcm_config.hal_resource_opt = CY_VCM_USE_HAL_RESOURCE; /* set to CY_VCM_USE_HAL_RESOURCE as primary core initializes VCM after the secondary core. */
vcm_config.channel_num = CYHAL_IPC_CHAN_0;
vcm_config.event_cb = vcm_callback_prim_core;
result = cy_vcm_init(&vcm_config);
if( result != CY_RSLT_SUCCESS )
{
printf("\n cy_vcm_init failed on primary core! \n");
return;
}
/* Initialize the WCM library */
result = cy_wcm_init(&wcm_config);
if( result != CY_RSLT_SUCCESS )
{
printf("\n cy_wcm_init failed on primary core! \n");
return;
}
/* Connect to Wi-Fi */
memset(&connect_params, 0, sizeof(cy_wcm_connect_params_t));
memcpy(connect_params.ap_credentials.SSID, WIFI_AP_SSID, strlen(WIFI_AP_SSID) + 1);
memcpy(connect_params.ap_credentials.password, WIFI_AP_PASSWORD, strlen(WIFI_AP_PASSWORD) + 1);
result = cy_wcm_connect_ap(&connect_params, &ip_addr);
if(result == CY_RSLT_SUCCESS)
{
printf("Connect successful!\n");
}
/* Wait for VCM deinit on the other core. When deinit event is received,
* deinitialize the VCM library on this core. */
while( !is_vcm_deinit_requested )
{
cy_rtos_delay_milliseconds(1000);
}
/* VCM deinit event received. */
result = cy_vcm_deinit();
if( result != CY_RSLT_SUCCESS )
{
printf("\n cy_vcm_deinit failed on primary core! \n");
return;
}
/* If WCM is no longer needed, deinitialize WCM. */
result = cy_wcm_deinit();
if( result != CY_RSLT_SUCCESS )
{
printf("\n cy_wcm_deinit failed on primary core! \n");
return;
}
}
cy_rslt_t cy_wcm_deinit(void)
Shuts down the WCM.
uint8_t cy_wcm_is_connected_to_ap(void)
Checks if the STA interface is connected to an AP.

Snippet 11: Virtual API usage to register for WCM events from the secondary core

The following snippet demonstrates the usage of virtual WCM API - cy_wcm_register_event_callback() and cy_wcm_deregister_event_callback() in a multi-core environment.

/***************************** Secondary core ***************************/
/* Flag to be set when VCM initialization is completed on the other core */
static bool is_vcm_init_complete_2 = false;
/* Callback registered on the secondary core to handle events from VCM. */
void vcm_callback_sec_core_2(cy_vcm_event_t event)
{
switch(event)
{
case CY_VCM_EVENT_INIT_COMPLETE:
{
/* VCM init complete */
is_vcm_init_complete_2 = 1;
break;
}
default:
break;
}
}
void event_callback_sec_core_2(cy_wcm_event_t event, cy_wcm_event_data_t *event_data)
{
{
printf("Disconnected from Wi-Fi\n");
}
else if (CY_WCM_EVENT_RECONNECTED == event)
{
printf("Reconnected to Wi-Fi.\n");
}
/* This event corresponds to the event when the IP address of the device
* changes.
*/
else if (CY_WCM_EVENT_IP_CHANGED == event)
{
if (event_data->ip_addr.version == CY_WCM_IP_VER_V4)
{
printf("IP Address: %d.%d.%d.%d\n", (uint8_t)event_data->ip_addr.ip.v4,
(uint8_t)(event_data->ip_addr.ip.v4 >> 8), (uint8_t)(event_data->ip_addr.ip.v4 >> 16),
(uint8_t)(event_data->ip_addr.ip.v4 >> 24));
}
else if(event_data->ip_addr.version == CY_WCM_IP_VER_V6)
{
printf("IP Address: %X:%X:%X:%X\n", (uint8_t)event_data->ip_addr.ip.v6[0],
(uint8_t)(event_data->ip_addr.ip.v6[1]), (uint8_t)(event_data->ip_addr.ip.v6[2]),
(uint8_t)(event_data->ip_addr.ip.v6[3]));
}
}
else if (CY_WCM_EVENT_CONNECTING == event)
{
printf("Connecting to Wi-Fi.\n");
}
else if (CY_WCM_EVENT_CONNECTED == event)
{
printf("Connected to Wi-Fi.\n");
}
else if (CY_WCM_EVENT_CONNECT_FAILED == event)
{
printf("Failed to connect to Wi-Fi.\n");
}
}
/* The following snippet demostrates usage of VCM and virtual WCM APIs from the secondary core.
* The primary core is where the full WCM implementation is present. The secondary core only
* has the virtual implementation.
* In this example, the secondary core application runs first and it enables the primary core.
* Before enabling the primary core, the secondary core initializes VCM library.
*/
void snippet_wcm_virtual_api_usage_sec_core_2()
{
cy_rslt_t result;
cy_vcm_config_t vcm_config;
/* Initialize the VCM library */
vcm_config.hal_resource_opt = CY_VCM_CREATE_HAL_RESOURCE; /* set to CY_VCM_CREATE_HAL_RESOURCE as the secondary core is the first one to initialize VCM. */
vcm_config.channel_num = CYHAL_IPC_CHAN_0;
vcm_config.event_cb = vcm_callback_sec_core_2;
result = cy_vcm_init(&vcm_config);
if( result != CY_RSLT_SUCCESS )
{
printf("\n cy_vcm_init failed! \n");
return;
}
/* Enable the other core.
* For example, for enabling CM4, the following code is applicable.
* When this is called, the application on core 2 will begin executing. Ensure cy_vcm_init()
* is called on the second core when the execution begins.
*/
Cy_SysEnableCM4(CY_CORTEX_M4_APPL_ADDR);
/* Wait for VCM initialization to complete */
while ( !is_vcm_init_complete )
{
cy_rtos_delay_milliseconds(1000);
}
/* Initialize the WCM library */
result = cy_wcm_init(NULL);
if( result != CY_RSLT_SUCCESS )
{
printf("\n cy_wcm_init failed on secondary core! \n");
return;
}
/* Listen for changes in the AP connection by registering event callback */
result = cy_wcm_register_event_callback(event_callback_sec_core_2);
if( result != CY_RSLT_SUCCESS )
{
printf("\n cy_wcm_register_event_callback failed on secondary core! \n");
return;
}
/* ... */
/* When no longer needed, deregister callback for WCM events */
result = cy_wcm_deregister_event_callback(event_callback_sec_core_2);
if( result != CY_RSLT_SUCCESS )
{
printf("\n cy_wcm_deregister_event_callback failed on secondary core! \n");
return;
}
/* When WCM virtual APIs are no longer needed on the secondary core, deinit WCM and VCM */
result = cy_wcm_deinit();
if( result != CY_RSLT_SUCCESS )
{
printf("\n cy_wcm_deinit failed on secondary core! \n");
return;
}
result = cy_vcm_deinit();
if( result != CY_RSLT_SUCCESS )
{
printf("\n cy_vcm_deinit failed on secondary core! \n");
return;
}
}
/***************************** Primary Core *****************************/
/* Wi-Fi Credentials: Modify WIFI_AP_SSID and WIFI_AP_PASSWORD to match your Wi-Fi network
* credentials.
*/
#define WIFI_AP_SSID "SSID"
#define WIFI_AP_PASSWORD "PASSWORD"
/* Flag that is set when VCM deinit is started by the other core.
* When this event is received, call cy_vcm_deinit() to deinitialize VCM
* on the current core.
*/
static bool is_vcm_deinit_requested_2 = false;
/* Callback registered by the application on primary core to handle events from VCM. */
void vcm_callback_prim_core_2(cy_vcm_event_t event)
{
switch(event)
{
case CY_VCM_EVENT_DEINIT:
{
/* The other core has initiated VCM deinit. Deinitialize VCM locally. */
is_vcm_deinit_requested_2 = true;
break;
}
default:
break;
}
}
/* The following snippet demostrates usage of VCM on the primary core.
* The primary core is where the full WCM implementation is present. The secondary core only
* has the virtual implementation. The primary core initializes wcm and connects to an AP.
* Ensure that this snippet is executed when the primary core is enabled.
*/
void snippet_wcm_virtual_api_usage_prim_core_2()
{
cy_rslt_t result;
cy_vcm_config_t vcm_config;
cy_wcm_config_t wcm_config;
cy_wcm_connect_params_t connect_params;
/* Initialize the VCM library */
vcm_config.hal_resource_opt = CY_VCM_USE_HAL_RESOURCE; /* set to CY_VCM_USE_HAL_RESOURCE as primary core initializes VCM after the secondary core. */
vcm_config.channel_num = CYHAL_IPC_CHAN_0;
vcm_config.event_cb = vcm_callback_prim_core_2;
result = cy_vcm_init(&vcm_config);
if( result != CY_RSLT_SUCCESS )
{
printf("\n cy_vcm_init failed on primary core! \n");
return;
}
/* Initialize the WCM library */
result = cy_wcm_init(&wcm_config);
if( result != CY_RSLT_SUCCESS )
{
printf("\n cy_wcm_init failed on primary core! \n");
return;
}
/* Connect to Wi-Fi */
memset(&connect_params, 0, sizeof(cy_wcm_connect_params_t));
memcpy(connect_params.ap_credentials.SSID, WIFI_AP_SSID, strlen(WIFI_AP_SSID) + 1);
memcpy(connect_params.ap_credentials.password, WIFI_AP_PASSWORD, strlen(WIFI_AP_PASSWORD) + 1);
result = cy_wcm_connect_ap(&connect_params, &ip_addr);
if(result == CY_RSLT_SUCCESS)
{
printf("Connect successful!\n");
}
/* Wait for VCM deinit on the other core. When deinit event is received,
* deinitialize the VCM library on this core. */
while( !is_vcm_deinit_requested_2 )
{
cy_rtos_delay_milliseconds(1000);
}
/* VCM deinit event received. */
result = cy_vcm_deinit();
if( result != CY_RSLT_SUCCESS )
{
printf("\n cy_vcm_deinit failed on primary core! \n");
return;
}
/* If WCM is no longer needed, deinitialize WCM. */
result = cy_wcm_deinit();
if( result != CY_RSLT_SUCCESS )
{
printf("\n cy_wcm_deinit failed on primary core! \n");
return;
}
}
cy_rslt_t cy_wcm_deregister_event_callback(cy_wcm_event_callback_t event_callback)
De-registers an event callback.