WIFIReturnCode_t WIFI_ConnectAP()

in amazon-freertos/lib/wifi/portable/nxp/lpc54018iotmodule/aws_wifi.c [364:537]


WIFIReturnCode_t WIFI_ConnectAP( const WIFINetworkParams_t * const pxNetworkParams )
{
    WLAN_AUTH_MODE auth_mode;
    WLAN_CRYPT_TYPE crypt_type;
    WIFIReturnCode_t status = eWiFiFailure;
    const TickType_t connect_timeout = pdMS_TO_TICKS( 30000UL );
    const TickType_t dhcp_timeout = pdMS_TO_TICKS( 20000UL );
    uint32_t tmp_ip4_addr = 0, tmp_ip4_mask = 0, tmp_ip4_gw = 0;
    uint8_t ucDhcpSuccessful = 0;

    /* Check initialization */
    if (!g_wifi_is_on)
        return eWiFiFailure;

    /* Check params */
    if (NULL == pxNetworkParams || NULL == pxNetworkParams->pcSSID || NULL == pxNetworkParams->pcPassword)
        return eWiFiFailure;

    /* Acquire semaphore */
    if (xSemaphoreTake(g_wifi_semaph, portMAX_DELAY) == pdTRUE)
    {
        do {
            /* Reset "connect" and "dhcp" semaphores */
            g_expected_event = expected_event_default;
            xQueueReset((void*)g_connect_semaph);
            xQueueReset((void*)g_dhcp_semaph);
            /* Disconnect Wi-Fi */
            if (g_connected)
            {
                g_expected_event = expected_event_disconnect;
                if (A_OK == qcom_disconnect(g_devid))
                {
                    /* Consider disconnected */
                    g_connected = 0;
                    /* Wait for callback, that is invoked from 'driver_task' context */
                    if (pdTRUE != xSemaphoreTake(g_connect_semaph, connect_timeout))
                    {
                        break;
                    }
                    /* Workaround for ARP cache */
                    if (0 != g_ip4_gw)
                    {
                        if (A_OK != qcom_ipconfig(g_devid, QCOM_IPCONFIG_STATIC, &g_ip4_gw, &g_ip4_mask, &g_ip4_gw))
                        {
                            break;
                        }
                        g_ip4_addr = g_ip4_mask = g_ip4_gw = 0;
                    }
                }
                else
                {
                    break;
                }
            }
            /* Set Wi-Fi to device mode */
            if (A_OK != (A_STATUS)qcom_op_set_mode(g_devid, QCOM_WLAN_DEV_MODE_STATION))
            {
                break;
            }

            /* Set SSID, must be done before auth, cipher and passphrase */
            strncpy(g_ssid.ssid, pxNetworkParams->pcSSID, sizeof(g_ssid.ssid));
            if (A_OK != (A_STATUS)qcom_set_ssid(g_devid, &g_ssid))
            {
                break;
            }

            g_security = pxNetworkParams->xSecurity;
            /* Convert 'WIFISecurity_t' to 'WLAN_AUTH_MODE', 'WLAN_CRYPT_TYPE' */
            if (eWiFiSuccess != conv_security_to_qcom(pxNetworkParams->xSecurity, &auth_mode, &crypt_type))
            {
                break;
            }

            /* Set encyption mode */
            if (A_OK != (A_STATUS)qcom_sec_set_encrypt_mode(g_devid, crypt_type))
            {
                break;
            }

            /* Set auth mode */
            if (A_OK != qcom_sec_set_auth_mode(g_devid, auth_mode))
            {
                break;
            }

            /* Set passphrase */
            strncpy(g_passphr.passphrase, pxNetworkParams->pcPassword, sizeof(g_passphr.passphrase));
            if (A_OK != qcom_sec_set_passphrase(g_devid, &g_passphr))
            {
                break;
            }

            /* Set channel */
            if (0 != pxNetworkParams->cChannel)
            {
                if (A_OK != qcom_set_channel(g_devid, pxNetworkParams->cChannel))
                {
                    break;
                }
            }

            /* Set connect_callback */
            if (A_OK != qcom_set_connect_callback(g_devid, (void *)aws_connect_cb))
            {
                break;
            }

            g_expected_event = expected_event_connect;
            /* Commit settings to Wi-Fi module. Calling this function starts the connection process. */
            if (A_OK != qcom_commit(g_devid))
            {
                break;
            }

            /* Wait for callback, that is invoked from 'driver_task' context. This callback sets g_connected to connected (1) or disconnected (0). */
            if (pdTRUE != xSemaphoreTake(g_connect_semaph, connect_timeout))
            {
                break;
            }

            /* Register DHCP callback */
            if (A_OK != qcom_dhcpc_register_cb(0, (void*)aws_dhcpc_callback))
            {
                break;
            }

            /* Try several attempts in worst case */
            for (int i = 0; i < 10 && 0 == g_ip4_addr; i++)
            {
                /* Perform DHCP request */
                if (A_OK != qcom_ipconfig(g_devid, QCOM_IPCONFIG_DHCP, &tmp_ip4_addr, &tmp_ip4_mask, &tmp_ip4_gw))
                {
                    break;
                }

                /* If DHCP response is not available immediately, wait for DHCP callback */
                if (!IPs_are_valid(tmp_ip4_addr, tmp_ip4_mask, tmp_ip4_gw))
                {
                    /* Wait for DHCP response */
                    if (pdTRUE != xSemaphoreTake(g_dhcp_semaph, dhcp_timeout))
                    {
                        break;
                    }
                }
                else
                {
                    /* Valid IP of DHCP response */
                    g_ip4_addr = tmp_ip4_addr;
                    g_ip4_mask = tmp_ip4_mask;
                    g_ip4_gw = tmp_ip4_gw;
                }
            }

            /* Still not a valid IP, report error */
            if (!IPs_are_valid(g_ip4_addr, g_ip4_mask, g_ip4_gw))
            {
                break;
            }
            /* Otherwise after all is said and done the DHCP request is successful. */
            else
            {
                ucDhcpSuccessful = 1;
            }

            /* Everything is OK. We connected to the AP and got an IP address with DHCP. */
            status = ( g_connected && ucDhcpSuccessful ) ? eWiFiSuccess : eWiFiFailure;
        } while (0);

        /* Release semaphore */
        xSemaphoreGive(g_wifi_semaph);
    }
    return status;
}