Channel Switch Announcement (CSA) in WICED - KBA229053

Version 2

    Version: **

    Question:
    How do I make a channel switch announcement to devices connected as stations (STA) to a device acting as Access Point (AP)?

    Answer:

    Channel switch announcement (CSA) is a mechanism for an AP to notify the connected stations of its intention to change the operating channel. This allows the client/STAs to hop to the channel in which AP is hopping and maintain the connection.

     

    Background:

    Dynamic Frequency Selection (DFS) is a spectrum-sharing mechanism that allows wireless LANs (WLANs) to coexist with radar systems. It automatically selects a frequency that does not interfere with certain radar systems while operating in the 5-GHz band.

     

    DFS detects radar interference and moves the wireless network to another frequency with no interference. It maintains a list of channels where radar has been detected in the non-occupancy list (NOL). The AP avoids using these channels for at least 30 minutes after detecting radar on them. When DFS is enabled, the AP does the following:

     

    • Looks for radar detection before securing a frequency channel.
    • Scans continuously for radar signal patterns during normal operation.

     

    When DFS is enabled, the AP that wants to operate on one of the 5 GHz  channels (5.470 to 5.725 GHz) must continuously scan that channel for any presence of radar and must cease transmission on that channel if it detects a radar source. Therefore, the AP might move/hop to a different less noisy channel to reduce interference. The existing wireless clients  (connected to the AP on the older channel) may “time out” while waiting to receive a new beacon from the AP; the client must begin scanning to discover the new channel on which the AP is operating. If the disruption is long enough, the client may need to reassociate, reauthenticate, and request an IP address. To allow minimal disruption in service of Basic Service Set (BSS), this change in channel by the AP can be notified to the connected stations so that they can move to the same channel with minimum downtime. This information is shared as a Channel Switch Announcement (CSA) element in Beacon, Probe Response, and/or Action management frames to the connected stations. 

     

    The CSA element contains the new channel number, parameter to count the number of beacons before switching, and information of restrictions on transmission until a channel switch.

     

    In WICED™, CSA can be sent with the help of the wwd_wifi_send_csa API:

    /**

    * This function will send a channel switch announcement and switch to the specified channel at the specified time.

    * @param[in] wiced_chan_switch_t: pointer to channel switch information

    * @param interface              : WWD_AP_INTERFACE (works only in AP mode)

    * @return     @ref wwd_result_t

    */

    wwd_result_t wwd_wifi_send_csa( const wiced_chan_switch_t* csa, wwd_interface_t interface );

     

     

    This API can be used with the help of the “csa” wl command as follows (use the “test.console” application for testing wl commands):

    >wl csa <mode> <count> [2g|5g]<channel>[20 or 40u/l 0r 80]

     

    Example: wl csa 1 4 5g36/80

     

    This command will switch the AP channel to channel number 42 in the 80-MHz bandwidth (provided that the AP is in another channel)

     

    Use the following example code to add the wwd_wifi_send_csa API to other applications:

     

    Usage: send_csa <channel_number> <band> <bandwidth> <sideband>

     

    For example: send_csa 38 5 40 1

     

    This command will send the CSA to switch to channel number 36 in the 5-GHz band and use 40-MHz bandwidth (provided that the AP is in a channel other than 38).

     

    Do the following to add the API in the list of console commands in the “snip.apsta” application in WICED:

     

    1. Define the command in the source file apsta.c:

     

    static const command_t commands[] =

    {

        ALL_COMMANDS

        CSA_COMMAND

        CMD_TABLE_END

    };

     

    1. Add the send_csa function in apsta.c file:

     

    wiced_result_t send_csa(int argc, char *argv[]){

     

        int chan_no, band_n, bw, sb;

        chanspec_t chanspec_n=0;

        int chan_set=0, band_set = 0, bw_set=0, sb_set=0;

     

        chan_no = strtol(argv[1], NULL, 10);

        printf("Channel number: %d\n", chan_no);

        if(chan_no < 0 || chan_no > 224){

            printf("invalid channel number: %d\n", chan_no);

            return WICED_ERROR; //bad channel

        }

        else{

            chanspec_n |= chan_no;

            chan_set = 1;

        }

     

        band_n = strtol(argv[2], NULL, 10);

        printf("Band: %d\n", band_n);

        if(! (band_n == 5 || band_n == 2) ){

            printf("invalid band number: %d\nEnter either 2 or 5", band_n);

            return WICED_ERROR; //bad band

        }

        else{

            if (band_n == 5)

    chanspec_n |= WL_CHANSPEC_BAND_5G;

            else

    chanspec_n |= WL_CHANSPEC_BAND_2G;

            band_set = 1;

        }

     

        bw = strtol(argv[3], NULL, 10);

        printf("BW: %d\n", bw);

        if(!(bw == 20 || bw == 40 || bw == 80) ){

            printf("invalid bandwidth: %d\nEnter either 20 or 40 or 80", bw);

            return WICED_ERROR; //bad BW

        }

        else{

            if (bw == 20)

    chanspec_n |= WL_CHANSPEC_BW_20;

            else if (bw == 40)

    chanspec_n |= WL_CHANSPEC_BW_40;

            else

    chanspec_n |= WL_CHANSPEC_BW_80;

            bw_set = 1;

        }

     

       sb = strtol(argv[4], NULL, 10);

       printf("sb: %d\n", sb);

       if (! ((sb == 1) || (sb == 0) || (sb == -1)) ) {

            printf("invalid sideband: %d\nEnter either -1(lower) or 0 or 1(upper)", sb);

            return WICED_ERROR; //bad sideband

        }

        if (sb == -1)

            chanspec_n |= WL_CHANSPEC_CTL_SB_LOWER;

        else if (sb == 1)

            chanspec_n |= WL_CHANSPEC_CTL_SB_UPPER;

        sb_set = 1;

     

     

        /* set ctl sb to 20 if not set and 20mhz is selected */

        if (!sb_set && CHSPEC_IS20(chanspec_n)) {

            sb_set = 1;

            chanspec_n |= WL_CHANSPEC_CTL_SB_NONE;

        }

     

        if (chan_set==1 && band_set==1 && bw_set==1 && sb_set==1) {

            printf("Chanspec set to 0x%x\n", chanspec_n);

        }

     

        wiced_chan_switch_t * wiced_csa = (wiced_chan_switch_t *)malloc(sizeof(wiced_chan_switch_t));

     

        //count and mode can be changed

        wiced_csa->count = 5;

        wiced_csa->mode = 1;

        wiced_csa->chspec = chanspec_n;

     

        wiced_result_t result= wwd_wifi_send_csa(wiced_csa,WWD_AP_INTERFACE );

     

        if(result  == WICED_SUCCESS)

            {

                printf("Channel for AP interface is changed\n");

            }

        else{

                printf("Error in switching: %d\n", result);

        }

        return WICED_SUCCESS;

    }

     

    A snapshot of a CSA packet in Wire Shark is attached below:

    References:

    1. https://wifi-insider.com/wlan/dfs.htm
    2. http://wlanimp.blogspot.com/2014/08/80211h-in-action.html