Overview

group index

This library provides a set of APIs that can be used to establish and monitor Wi-Fi connections on Cypress 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.

Features and Functionality

The current implementation has the following features and functionality:

  • 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.

  • This library is part of the AnyCloud framework 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.

Supported Platforms

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

Dependent Libraries

This library includes Wi-Fi Middleware Core by default. It helps code examples to enable Wi-Fi connectivity components without having to include additional libraries. The Wi-Fi Host Driver library is part of the Wi-Fi Middleware Core.

Quick Start

  • A set of pre-defined configuration files have been bundled with the wifi-mw-core library for FreeRTOS, lwIP, and mbed TLS. The developer is expected to review the configuration and make adjustments. See the Quick Start section in README.md. A set of COMPONENTS must be defined in the code example project’s Makefile for this library. See the Quick Start section in README.md. 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.

Code Snippets

Snippet 1: Scan for All APs

The following snippet demonstrates how to initialize the Wi-Fi device and network stack, and starts 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.*/
    cy_wcm_config_t config = {.interface = CY_WCM_INTERFACE_TYPE_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");
    }
}

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.*/
    scan_filter.mode = CY_WCM_SCAN_FILTER_TYPE_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");
    }
}

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.
 */
#define SIZE_OF_IP_ARRAY_STA                (1u)

/* 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;
        cy_wcm_stop_scan();
    }
}

void network_event_callback(cy_wcm_event_t event, cy_wcm_event_data_t *event_data)
{
    if (CY_WCM_EVENT_DISCONNECTED == event)
    {
        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)
    {
        cy_wcm_ip_address_t ip_addr;
        cy_wcm_get_ip_addr(CY_WCM_INTERFACE_TYPE_STA, &ip_addr, SIZE_OF_IP_ARRAY_STA);

        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: %lX:%lX:%lX:%lX\n", event_data->ip_addr.ip.v6[0],
                   (event_data->ip_addr.ip.v6[1]), (event_data->ip_addr.ip.v6[2]),
                   (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_security_t security;
    cy_wcm_scan_filter_t scan_filter;

    /* Configure the scan filter specified by the macro WIFI_SSID.*/
    scan_filter.mode = CY_WCM_SCAN_FILTER_TYPE_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);
    xTaskNotifyWait(0, 0, NULL, portMAX_DELAY);

    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);

        vTaskDelay(pdMS_TO_TICKS(WIFI_CONN_RETRY_INTERVAL_MSEC));
    }

}

Snippet 4: Connect to an AP using 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,
    .config_methods            = CY_WCM_WPS_CONFIG_LABEL | CY_WCM_WPS_CONFIG_VIRTUAL_PUSH_BUTTON | CY_WCM_WPS_CONFIG_VIRTUAL_DISPLAY_PIN,
    .authentication_type_flags = CY_WCM_WPS_OPEN_AUTHENTICATION | CY_WCM_WPS_WPA_PSK_AUTHENTICATION | CY_WCM_WPS_WPA2_PSK_AUTHENTICATION | CY_WCM_WPS_WPA2_WPA_PSK_MIXED_AUTHENTICATION,
    .encryption_type_flags     = CY_WCM_WPS_NO_ENCRYPTION | CY_WCM_WPS_AES_ENCRYPTION | CY_WCM_WPS_TKIP_ENCRYPTION
};

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("%ld. SSID = %s, Password = %c%c******.\n", loop + 1, credentials[loop].ssid, credentials[loop].passphrase[0], credentials[loop].passphrase[1]);
        }
    }
}

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.
     */
    cy_wcm_wps_generate_pin(pin_string);

    /*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("%ld. SSID = %s, Password = %c%c******.\n", loop + 1, credentials[loop].ssid, credentials[loop].passphrase[0], credentials[loop].passphrase[1]);
        }
    }
}

Snippet 6: Pinging 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)

static void print_ip4(uint32_t ip)
{
    unsigned char bytes[4];
    bytes[0] = ip & 0xFF;
    bytes[1] = (ip >> 8) & 0xFF;
    bytes[2] = (ip >> 16) & 0xFF;
    bytes[3] = (ip >> 24) & 0xFF;
    printf("IPV4 addr = %d.%d.%d.%d\n", bytes[0], bytes[1], bytes[2], bytes[3]);
}

void snippet_wcm_sta_ping()
{
    cy_rslt_t result;

    /* Initialize the Wi-Fi device as a STA.*/
    cy_wcm_config_t config = {.interface = CY_WCM_INTERFACE_TYPE_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));
    connect_param.ap_credentials.security = CY_WCM_SECURITY_WPA2_AES_PSK;

    /* 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);

        vTaskDelay(pdMS_TO_TICKS(WIFI_CONN_RETRY_INTERVAL_MSEC));
    }

    /* Get IPv4 address */
    cy_wcm_get_ip_addr(CY_WCM_INTERFACE_TYPE_STA, &ip_addr, 1);
    print_ip4(ip_addr.ip.v4);

    /* Get gateway address */
    cy_wcm_get_gateway_ip_address(CY_WCM_INTERFACE_TYPE_STA, &gateway_addr, 1);
    print_ip4(gateway_addr.ip.v4);

    vTaskDelay(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 = %lu\n", elapsed_time_ms);
    }
    else
    {
        printf("Ping failed !!\n");
    }

}

Snippet 7: Soft AP start-stop

The following snippet demonstrates Soft AP start and stop.


#define WIFI_SSID_AP                      "AnyCloud"
#define WIFI_KEY_AP                       "abcd@9009"

#define INITIALISER_IPV4_ADDRESS1( addr_var, addr_val )  addr_var = { CY_WCM_IP_VER_V4, { .v4 = (uint32_t)(addr_val) } }
#define MAKE_IPV4_ADDRESS1(a, b, c, d) ((((uint32_t) d) << 24) | (((uint32_t) c) << 16) | (((uint32_t) b) << 8) |((uint32_t) a))
static const cy_wcm_ip_setting_t ap_mode_ip_settings =
{
    INITIALISER_IPV4_ADDRESS1( .ip_address, MAKE_IPV4_ADDRESS1( 192, 168, 0,  2 )),
    INITIALISER_IPV4_ADDRESS1( .netmask,    MAKE_IPV4_ADDRESS1( 255, 255, 255, 0 )),
    INITIALISER_IPV4_ADDRESS1( .gateway,    MAKE_IPV4_ADDRESS1( 192, 168, 0, 2 ) ),
};

#define HTONS(x) ( ( ( (x) & 0x0000FF00) >> 8 ) | ((x) & 0x000000FF) << 8 )

static void print_ipv6(uint32_t* ipv6)
{
    uint16_t* ipv6_ptr = (uint16_t*) ipv6;

    printf("IPV6 Address : %0x, %0x, %0x, %0x, %0x, %0x, %0x, %0x \n", HTONS(ipv6_ptr[0]), HTONS(ipv6_ptr[1]), HTONS(ipv6_ptr[2]), HTONS(ipv6_ptr[3]), HTONS(ipv6_ptr[4]), HTONS(ipv6_ptr[5]), HTONS(ipv6_ptr[6]), HTONS(ipv6_ptr[7]));
}

static void print_ipv4(uint32_t ip)
{
    unsigned char bytes[4];
    bytes[0] = ip & 0xFF;
    bytes[1] = (ip >> 8) & 0xFF;
    bytes[2] = (ip >> 16) & 0xFF;
    bytes[3] = (ip >> 24) & 0xFF;
    printf("IPV4 addr = %d.%d.%d.%d\n", bytes[0], bytes[1], bytes[2], bytes[3]);
}

static void ap_event_cb(cy_wcm_event_t event, cy_wcm_event_data_t *event_data)
{
    printf("######### Received event changed from wcm, event = %d #######\n", event);
    if(event == CY_WCM_EVENT_DISCONNECTED)
    {
        printf("Network is down! \n");
    }

    if(event == CY_WCM_EVENT_RECONNECTED)
    {
        printf("Network is up again! \n");
    }

    if(event == CY_WCM_EVENT_CONNECTING)
    {
        printf("Connecting to AP ... \n");
    }

    if(event == CY_WCM_EVENT_CONNECTED)
    {
        printf("Connected to AP and network is up !! \n");
    }

    if(event == CY_WCM_EVENT_CONNECT_FAILED)
    {
        printf("Connection to AP Failed ! \n");
    }

    if(event == CY_WCM_EVENT_IP_CHANGED)
    {
        cy_wcm_ip_address_t ip_addr;
        cy_wcm_get_ip_addr(CY_WCM_INTERFACE_TYPE_STA, &ip_addr, 1);

        if(event_data->ip_addr.version == CY_WCM_IP_VER_V4)
        {
            print_ip4(event_data->ip_addr.ip.v4);
        }
    }

    if(event == CY_WCM_EVENT_STA_JOINED_SOFTAP)
    {
        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]);
    }

    if(event == CY_WCM_EVENT_STA_LEFT_SOFTAP)
    {
        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]);
    }
}

void snippet_wcm_ap_start_stop()
{
    cy_rslt_t result;

    cy_wcm_config_t config;
    cy_wcm_ap_config_t ap_conf;
    cy_wcm_ip_address_t ipv6_addr;

    /* Initialize the Wi-Fi device, Wi-Fi transport, and lwIP network stack.*/
    config.interface = CY_WCM_INTERFACE_TYPE_AP;
    result = cy_wcm_init(&config);
    if(result != CY_RSLT_SUCCESS)
    {
        printf("\ncy_wcm_init failed...!\n");
        return;
    }

    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.ap_credentials.security = CY_WCM_SECURITY_WPA2_AES_PSK;

    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 = %lu \n", ap_conf.ip_settings.ip_address.ip.v4);
    print_ipv4(ap_conf.ip_settings.ip_address.ip.v4);

    /* 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 */
    result = cy_wcm_get_ipv6_addr(CY_WCM_INTERFACE_TYPE_AP, CY_WCM_IPV6_LINK_LOCAL, &ipv6_addr, 1);
    if( result != CY_RSLT_SUCCESS )
    {
        printf("\ncy_wcm_get_ipv6_addr failed....! \n");
        return;
    }
    print_ipv6(ipv6_addr.ip.v6);

    /* wait for 30 seconds to check whether AP is visible or not */
    vTaskDelay(30000);

    /* Stop AP */
    result = cy_wcm_stop_ap();
    if( result != CY_RSLT_SUCCESS )
    {
        printf("\ncy_wcm_stop_ap failed....! \n");
    }
    return;
}

Snippet 8: Clients connected to the Soft AP

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


#define WIFI_SSID_AP                      "AnyCloud"
#define WIFI_KEY_AP                       "abcd@9009"

#define INITIALISER_IPV4_ADDRESS1( addr_var, addr_val )  addr_var = { CY_WCM_IP_VER_V4, { .v4 = (uint32_t)(addr_val) } }
#define MAKE_IPV4_ADDRESS1(a, b, c, d) ((((uint32_t) d) << 24) | (((uint32_t) c) << 16) | (((uint32_t) b) << 8) |((uint32_t) a))

static const cy_wcm_ip_setting_t ap_ip_settings =
{
    INITIALISER_IPV4_ADDRESS1( .ip_address, MAKE_IPV4_ADDRESS1( 192, 168, 0,  2 )),
    INITIALISER_IPV4_ADDRESS1( .netmask,    MAKE_IPV4_ADDRESS1( 255, 255, 255, 0 )),
    INITIALISER_IPV4_ADDRESS1( .gateway,    MAKE_IPV4_ADDRESS1( 192, 168, 0, 2 ) ),
};

static void print_ip_v6(uint32_t* ipv6)
{
    uint16_t* ipv6_ptr = (uint16_t*) ipv6;

    printf("IPV6 Address : %0x, %0x, %0x, %0x, %0x, %0x, %0x, %0x \n", HTONS(ipv6_ptr[0]), HTONS(ipv6_ptr[1]), HTONS(ipv6_ptr[2]), HTONS(ipv6_ptr[3]), HTONS(ipv6_ptr[4]), HTONS(ipv6_ptr[5]), HTONS(ipv6_ptr[6]), HTONS(ipv6_ptr[7]));
}

static void print_ip_v4(uint32_t ip)
{
    unsigned char bytes[4];
    bytes[0] = ip & 0xFF;
    bytes[1] = (ip >> 8) & 0xFF;
    bytes[2] = (ip >> 16) & 0xFF;
    bytes[3] = (ip >> 24) & 0xFF;
    printf("IPV4 addr = %d.%d.%d.%d\n", bytes[0], bytes[1], bytes[2], bytes[3]);
}

static void ap_eve_callback(cy_wcm_event_t event, cy_wcm_event_data_t *event_data)
{
    printf("######### Received event changed from wcm, event = %d #######\n", event);
    if(event == CY_WCM_EVENT_DISCONNECTED)
    {
        printf("Network is down! \n");
    }

    if(event == CY_WCM_EVENT_RECONNECTED)
    {
        printf("Network is up again! \n");
    }

    if(event == CY_WCM_EVENT_CONNECTING)
    {
        printf("Connecting to AP ... \n");
    }

    if(event == CY_WCM_EVENT_CONNECTED)
    {
        printf("Connected to AP and network is up !! \n");
    }

    if(event == CY_WCM_EVENT_CONNECT_FAILED)
    {
        printf("Connection to AP Failed ! \n");
    }

    if(event == CY_WCM_EVENT_IP_CHANGED)
    {
        cy_wcm_ip_address_t ip_addr;
        cy_wcm_get_ip_addr(CY_WCM_INTERFACE_TYPE_STA, &ip_addr, 1);

        if(event_data->ip_addr.version == CY_WCM_IP_VER_V4)
        {
            print_ip_v4(event_data->ip_addr.ip.v4);
        }
    }

    if(event == CY_WCM_EVENT_STA_JOINED_SOFTAP)
    {
        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]);
    }

    if(event == CY_WCM_EVENT_STA_LEFT_SOFTAP)
    {
        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]);
    }
}

void snippet_wcm_ap_get_client()
{
    cy_rslt_t result;

    cy_wcm_config_t config;
    cy_wcm_ap_config_t ap_conf;
    cy_wcm_ip_address_t ipv6_addr;

    /* Initialize the Wi-Fi device, Wi-Fi transport, and lwIP network stack.*/
    config.interface = CY_WCM_INTERFACE_TYPE_AP;
    result = cy_wcm_init(&config);
    if(result == CY_RSLT_SUCCESS)
    {
        printf("\ncy_wcm_init failed...!\n");
        return;
    }

    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.ap_credentials.security = CY_WCM_SECURITY_WPA2_AES_PSK;

    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 = %lu \n", ap_conf.ip_settings.ip_address.ip.v4);
    print_ip_v4(ap_conf.ip_settings.ip_address.ip.v4);

    /* 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 */
    result = cy_wcm_get_ipv6_addr(CY_WCM_INTERFACE_TYPE_AP, CY_WCM_IPV6_LINK_LOCAL, &ipv6_addr, 1);
    if( result != CY_RSLT_SUCCESS )
    {
        printf("\ncy_wcm_get_ipv6_addr failed....! \n");
        return;
    }
    print_ip_v6(ipv6_addr.ip.v6);

    /* wait for 30 seconds for a client to connect */
    vTaskDelay(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;

}

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.
 */
#define SIZE_OF_IP_ARRAY_STA                (1u)

#define INITIALISER_IPV4_ADDRESS1( addr_var, addr_val )  addr_var = { CY_WCM_IP_VER_V4, { .v4 = (uint32_t)(addr_val) } }
#define MAKE_IPV4_ADDRESS1(a, b, c, d) ((((uint32_t) d) << 24) | (((uint32_t) c) << 16) | (((uint32_t) b) << 8) |((uint32_t) a))
static const cy_wcm_ip_setting_t ap_sta_mode_ip_settings =
{
    INITIALISER_IPV4_ADDRESS1( .ip_address, MAKE_IPV4_ADDRESS1( 192, 168, 0,  2 )),
    INITIALISER_IPV4_ADDRESS1( .netmask,    MAKE_IPV4_ADDRESS1( 255, 255, 255, 0 )),
    INITIALISER_IPV4_ADDRESS1( .gateway,    MAKE_IPV4_ADDRESS1( 192, 168, 0, 2 ) ),
};

static void print_ip_6(uint32_t* ipv6)
{
    uint16_t* ipv6_ptr = (uint16_t*) ipv6;

    printf("IPV6 Address : %0x, %0x, %0x, %0x, %0x, %0x, %0x, %0x \n", HTONS(ipv6_ptr[0]), HTONS(ipv6_ptr[1]), HTONS(ipv6_ptr[2]), HTONS(ipv6_ptr[3]), HTONS(ipv6_ptr[4]), HTONS(ipv6_ptr[5]), HTONS(ipv6_ptr[6]), HTONS(ipv6_ptr[7]));
}

static void print_ip_4(uint32_t ip)
{
    unsigned char bytes[4];
    bytes[0] = ip & 0xFF;
    bytes[1] = (ip >> 8) & 0xFF;
    bytes[2] = (ip >> 16) & 0xFF;
    bytes[3] = (ip >> 24) & 0xFF;
    printf("IPV4 addr = %d.%d.%d.%d\n", bytes[0], bytes[1], bytes[2], bytes[3]);
}

void sta_event_callback(cy_wcm_event_t event, cy_wcm_event_data_t *event_data)
{
    if (CY_WCM_EVENT_DISCONNECTED == event)
    {
        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)
    {
        cy_wcm_ip_address_t ip_addr;
        cy_wcm_get_ip_addr(CY_WCM_INTERFACE_TYPE_STA, &ip_addr, SIZE_OF_IP_ARRAY_STA);

        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: %lX:%lX:%lX:%lX\n", event_data->ip_addr.ip.v6[0],
                   (event_data->ip_addr.ip.v6[1]), (event_data->ip_addr.ip.v6[2]),
                   (event_data->ip_addr.ip.v6[3]));
        }
    }
}

static void ap_event_callback(cy_wcm_event_t event, cy_wcm_event_data_t *event_data)
{
    printf("######### Received event changed from wcm, event = %d #######\n", event);
    if(event == CY_WCM_EVENT_DISCONNECTED)
    {
        printf("Network is down! \n");
    }

    if(event == CY_WCM_EVENT_RECONNECTED)
    {
        printf("Network is up again! \n");
    }

    if(event == CY_WCM_EVENT_CONNECTING)
    {
        printf("Connecting to AP ... \n");
    }

    if(event == CY_WCM_EVENT_CONNECTED)
    {
        printf("Connected to AP and network is up !! \n");
    }

    if(event == CY_WCM_EVENT_CONNECT_FAILED)
    {
        printf("Connection to AP Failed ! \n");
    }

    if(event == CY_WCM_EVENT_IP_CHANGED)
    {
        cy_wcm_ip_address_t ip_addr;
        cy_wcm_get_ip_addr(CY_WCM_INTERFACE_TYPE_STA, &ip_addr, 1);

        if(event_data->ip_addr.version == CY_WCM_IP_VER_V4)
        {
            print_ip_4(event_data->ip_addr.ip.v4);
        }
    }

    if(event == CY_WCM_EVENT_STA_JOINED_SOFTAP)
    {
        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]);
    }

    if(event == CY_WCM_EVENT_STA_LEFT_SOFTAP)
    {
        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]);
    }
}

void snippet_wcm_concurrent_mode()
{
    cy_rslt_t result;

    /* Initialize the Wi-Fi device as a STA.*/
    cy_wcm_config_t config = {.interface = CY_WCM_INTERFACE_TYPE_AP_STA};
    cy_wcm_ap_config_t ap_conf;
    cy_wcm_connect_params_t connect_param;
    cy_wcm_ip_address_t ip_address,ipv4_addr,ipv6_addr;
    cy_wcm_security_t security;

    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;
    }

    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);

        vTaskDelay(pdMS_TO_TICKS(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.ap_credentials.security = CY_WCM_SECURITY_WPA2_AES_PSK;

    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 = %lu \n", ap_conf.ip_settings.ip_address.ip.v4);
    print_ip4(ap_conf.ip_settings.ip_address.ip.v4);
    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 */
    result = cy_wcm_get_ip_addr(CY_WCM_INTERFACE_TYPE_AP, &ipv4_addr, 1);
    if (result == CY_RSLT_SUCCESS)
    {
        printf("\ncy_wcm_get_ip_addr failed...! \n");
        return;
    }
    printf("\nIPV4 address of AP : ");
    print_ip_4(ipv4_addr.ip.v4);

    /* Get IPV6 address for AP */
    printf("Link Local IPV6 AP address \n");
    result = cy_wcm_get_ipv6_addr(CY_WCM_INTERFACE_TYPE_AP, CY_WCM_IPV6_LINK_LOCAL, &ipv6_addr, 1);
    if (result == CY_RSLT_SUCCESS)
    {
        printf("\ncy_wcm_get_ipv6_addr failed...! \n");
        return;
    }
    printf("\nLink Local IPV6 AP address : ");
    print_ip_6(ipv6_addr.ip.v6);

    /* Get Link Local IPV6 STA address */
    result = cy_wcm_get_ipv6_addr(CY_WCM_INTERFACE_TYPE_STA, CY_WCM_IPV6_LINK_LOCAL, &ipv6_addr, 1);
    if (result == CY_RSLT_SUCCESS)
    {
        printf("\ncy_wcm_get_ipv6_addr failed...! \n");
        return;
    }
    printf("\nLink Local IPV6 STA address : ");
    print_ip_6(ipv6_addr.ip.v6);

    /* 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_get_mac_addr(CY_WCM_INTERFACE_TYPE_AP_STA, mac_addr_ptr, 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]);
    mac_addr_ptr++;
    memcpy(&ap_mac, mac_addr_ptr, 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);
}