This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC3220SF: CC3220SF - HTTPS client

Part Number: CC3220SF

Hi,

After lots of tries and retries I'm getting -688 error in httpget demo application.I'm doing HTTPS client connection and tries to connect in example.com. Can anyone help me this is a certificate issue I exported from example.com it downloads as .cer format how do I flash? I'm using Benjamin's shared file of httpsget.c and platform.c. Please solve this certificate error I'm doing this for 17 days and got frustrated by this example to execute it properly

Regards

Manish

  • Hi Manish,

    I just tested this out by downloading the DigiCert Global Root CA file from my browser (as "example.cer"), loading it to my device's file system, and modifying the httpget application from the latest SDK v3.10.00.04 to use an https connection (referencing "example.cer" as the rootCA). It works as expected without the -688 error.

    Please make sure your device is running the latest servicepack and test with the latest SDK rather than the files directly from my previous post.

    Best Regards,
    Ben M
  • Hi Ben,

    As per your instructions I did that but it is asking for HTTP server private key. Where do I get server private key? I'll attach a screenshot of that image. See the private key option there.

  • Hi Ben,
    Kindly check two files which have been attached in this reply.

    /*
     * Copyright (c) 2015-2017, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *  ======== httpget.c ========
     *  HTTP Client GET example application
     */
    
    /* BSD support */
    #include "string.h"
    #include <ti/display/Display.h>
    #include <ti/net/http/httpclient.h>
    #include <ti/drivers/net/wifi/simplelink.h>
    #include "semaphore.h"
    #include "device.h"
    
    #define HOSTNAME              "https://example.com/"
    #define REQUEST_URI           "/"
    #define USER_AGENT            "HTTPClient (ARM; TI-RTOS)"
    
    extern Display_Handle display;
    extern sem_t    ipEventSyncObj;
    extern void printError(char *errString, int code);
    
    /*
     *  ======== httpTask ========
     *  Makes a HTTP GET request
     */
    void* httpTask(void* pvParameters)
    {
        bool moreDataFlag = false;
        char data[256];
        int16_t ret = 0;
        int16_t len = 0;
        SlDateTime_t dateTimeSet = {0};
        uint16_t configLen = sizeof(SlDateTime_t);
        uint8_t configOpt = SL_DEVICE_GENERAL_DATE_TIME;
        sem_wait(&ipEventSyncObj);
        Display_printf(display, 0, 0, "Sending a HTTP GET request to '%s'\n",
                HOSTNAME);
    
        HTTPClient_Handle httpClientHandle;
        HTTPClient_extSecParams httpClientSecParams;
        int16_t statusCode;
        httpClientHandle = HTTPClient_create(&statusCode,0);
        if (statusCode < 0)
        {
            printError("httpTask: creation of http client handle failed", ret);
        }
    
        ret = HTTPClient_setHeader(httpClientHandle, HTTPClient_HFIELD_REQ_USER_AGENT,USER_AGENT,strlen(USER_AGENT),HTTPClient_HFIELD_PERSISTENT);
        if (ret < 0) {
            printError("httpTask: setting request header failed", ret);
        }
    
        httpClientSecParams.rootCa    =  NULL;
        httpClientSecParams.clientCert = NULL;
        httpClientSecParams.privateKey = NULL;
    
        dateTimeSet.tm_day = 29;
        dateTimeSet.tm_hour = 4;
        dateTimeSet.tm_min = 42;
        dateTimeSet.tm_mon = 4;
        dateTimeSet.tm_sec = 0;
        dateTimeSet.tm_year = 2019;
    
        ret = sl_DeviceSet(SL_DEVICE_GENERAL, configOpt, configLen, (uint8_t *)(&dateTimeSet));
        if(ret < 0)
        {
            printError("httpTask: failed to set device time", ret);
        }
    
        ret = HTTPClient_connect(httpClientHandle,HOSTNAME,&httpClientSecParams,0);
    
        if (ret < 0) {
            printError("httpTask: connect failed", ret);
        }
        ret = HTTPClient_sendRequest(httpClientHandle,HTTP_METHOD_GET,REQUEST_URI,NULL,0,0);
        if (ret < 0) {
            printError("httpTask: send failed", ret);
        }
    
        if (ret != HTTP_SC_OK) {
            printError("httpTask: cannot get status", ret);
        }
    
        Display_printf(display, 0, 0, "HTTP Response Status Code: %d\n", ret);
    
        len = 0;
        do {
            ret = HTTPClient_readResponseBody(httpClientHandle, data, sizeof(data), &moreDataFlag);
            if (ret < 0) {
                printError("httpTask: response body processing failed", ret);
            }
            Display_printf(display, 0, 0, "%.*s \r\n",ret ,data);
            len += ret;
        }while (moreDataFlag);
    
        Display_printf(display, 0, 0, "Received %d bytes of payload\n", len);
    
        ret = HTTPClient_disconnect(httpClientHandle);
        if (ret < 0)
        {
            printError("httpTask: disconnect failed", ret);
        }
    
        HTTPClient_destroy(httpClientHandle);
        return(0);
    }
    
    /*
     * Copyright (c) 2015-2017, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    #include <ti/drivers/net/wifi/simplelink.h>
    #include <ti/drivers/net/wifi/slnetifwifi.h>
    
    #include <ti/display/Display.h>
    
    #include <ti/drivers/SPI.h>
    
    #include "Board.h"
    #include "pthread.h"
    #include "semaphore.h"
    
    
    #define SPAWN_TASK_PRIORITY                   (9)
    #define SPAWN_STACK_SIZE                      (4096)
    #define TASK_STACK_SIZE                       (2048)
    #define SLNET_IF_WIFI_PRIO                    (5)
    #define SLNET_IF_WIFI_NAME                    "CC3220"
    
    #define SSID_NAME                             "IMPL_GUEST"          /* AP SSID */
    #define SECURITY_TYPE                         SL_WLAN_SEC_TYPE_WPA_WPA2 /* Security type could be SL_WLAN_SEC_TYPE_WPA_WPA2 */
    #define SECURITY_KEY                          "IMPL_wlan*123"                    /* Password of the secured AP */
    
    sem_t     ipEventSyncObj;
    
    pthread_t httpThread = (pthread_t)NULL;
    pthread_t spawn_thread = (pthread_t)NULL;
    
    Display_Handle display;
    
    extern void* httpTask(void* pvParameters);
    
    /*!
        \brief          SimpleLinkNetAppEventHandler
    
        This handler gets called whenever a Netapp event is reported
        by the host driver / NWP. Here user can implement he's own logic
        for any of these events. This handler is used by 'network_terminal'
        application to show case the following scenarios:
    
        1. Handling IPv4 / IPv6 IP address acquisition.
        2. Handling IPv4 / IPv6 IP address Dropping.
    
        \param          pNetAppEvent     -   pointer to Netapp event data.
    
        \return         void
    
        \note           For more information, please refer to: user.h in the porting
                        folder of the host driver and the  CC3120/CC3220 NWP programmer's
                        guide (SWRU455) section 5.7
    
    */
    void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent)
    {
        if(pNetAppEvent == NULL)
        {
            return;
        }
    
        switch(pNetAppEvent->Id)
        {
            case SL_NETAPP_EVENT_IPV4_ACQUIRED:
            case SL_NETAPP_EVENT_IPV6_ACQUIRED:
                /* Initialize SlNetSock layer with CC3x20 interface                      */
                SlNetIf_init(0);
                SlNetIf_add(SLNETIF_ID_1, SLNET_IF_WIFI_NAME, (const SlNetIf_Config_t *)&SlNetIfConfigWifi, SLNET_IF_WIFI_PRIO);
    
                SlNetSock_init(0);
                SlNetUtil_init(0);
                sem_post(&ipEventSyncObj);
                break;
            default:
                break;
       }
    }
    /*!
        \brief          SimpleLinkFatalErrorEventHandler
    
        This handler gets called whenever a socket event is reported
        by the NWP / Host driver. After this routine is called, the user's
        application must restart the device in order to recover.
    
        \param          slFatalErrorEvent    -   pointer to fatal error event.
    
        \return         void
    
        \note           For more information, please refer to: user.h in the porting
                        folder of the host driver and the  CC3120/CC3220 NWP programmer's
                        guide (SWRU455) section 17.9.
    
    */
    void SimpleLinkFatalErrorEventHandler(SlDeviceFatal_t *slFatalErrorEvent)
    {
        /* Unused in this application */
    }
    /*!
        \brief          SimpleLinkNetAppRequestMemFreeEventHandler
    
        This handler gets called whenever the NWP is done handling with
        the buffer used in a NetApp request. This allows the use of
        dynamic memory with these requests.
    
        \param          pNetAppRequest     -   Pointer to NetApp request structure.
    
        \param          pNetAppResponse    -   Pointer to NetApp request Response.
    
        \note           For more information, please refer to: user.h in the porting
                        folder of the host driver and the  CC3120/CC3220 NWP programmer's
                        guide (SWRU455) section 17.9.
    
        \return         void
    
    */
    void SimpleLinkNetAppRequestMemFreeEventHandler(uint8_t *buffer)
    {
        /* Unused in this application */
    }
    
    /*!
        \brief          SimpleLinkNetAppRequestEventHandler
    
        This handler gets called whenever a NetApp event is reported
        by the NWP / Host driver. User can write he's logic to handle
        the event here.
    
        \param          pNetAppRequest     -   Pointer to NetApp request structure.
    
        \param          pNetAppResponse    -   Pointer to NetApp request Response.
    
        \note           For more information, please refer to: user.h in the porting
                        folder of the host driver and the  CC3120/CC3220 NWP programmer's
                        guide (SWRU455) section 17.9.
    
        \return         void
    
    */
    void SimpleLinkNetAppRequestEventHandler(SlNetAppRequest_t *pNetAppRequest, SlNetAppResponse_t *pNetAppResponse)
    {
        /* Unused in this application */
    }
    
    /*!
        \brief          SimpleLinkHttpServerEventHandler
    
        This handler gets called whenever a HTTP event is reported
        by the NWP internal HTTP server.
    
        \param          pHttpEvent       -   pointer to http event data.
    
        \param          pHttpEvent       -   pointer to http response.
    
        \return         void
    
        \note           For more information, please refer to: user.h in the porting
                        folder of the host driver and the  CC3120/CC3220 NWP programmer's
                        guide (SWRU455) chapter 9.
    
    */
    void SimpleLinkHttpServerEventHandler(SlNetAppHttpServerEvent_t *pHttpEvent,
                                          SlNetAppHttpServerResponse_t *pHttpResponse)
    {
        /* Unused in this application */
    }
    
    /*!
        \brief          SimpleLinkWlanEventHandler
    
        This handler gets called whenever a WLAN event is reported
        by the host driver / NWP. Here user can implement he's own logic
        for any of these events. This handler is used by 'network_terminal'
        application to show case the following scenarios:
    
        1. Handling connection / Disconnection.
        2. Handling Addition of station / removal.
        3. RX filter match handler.
        4. P2P connection establishment.
    
        \param          pWlanEvent       -   pointer to Wlan event data.
    
        \return         void
    
        \note           For more information, please refer to: user.h in the porting
                        folder of the host driver and the  CC3120/CC3220 NWP programmer's
                        guide (SWRU455) sections 4.3.4, 4.4.5 and 4.5.5.
    
        \sa             cmdWlanConnectCallback, cmdEnableFilterCallback, cmdWlanDisconnectCallback,
                        cmdP2PModecallback.
    
    */
    void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent)
    {
        /* Unused in this application */
    }
    /*!
        \brief          SimpleLinkGeneralEventHandler
    
        This handler gets called whenever a general error is reported
        by the NWP / Host driver. Since these errors are not fatal,
        application can handle them.
    
        \param          pDevEvent    -   pointer to device error event.
    
        \return         void
    
        \note           For more information, please refer to: user.h in the porting
                        folder of the host driver and the  CC3120/CC3220 NWP programmer's
                        guide (SWRU455) section 17.9.
    
    */
    void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent)
    {
        /* Unused in this application */
    }
    
    /*!
        \brief          SimpleLinkSockEventHandler
    
        This handler gets called whenever a socket event is reported
        by the NWP / Host driver.
    
        \param          SlSockEvent_t    -   pointer to socket event data.
    
        \return         void
    
        \note           For more information, please refer to: user.h in the porting
                        folder of the host driver and the  CC3120/CC3220 NWP programmer's
                        guide (SWRU455) section 7.6.
    
    */
    void SimpleLinkSockEventHandler(SlSockEvent_t *pSock)
    {
        /* Unused in this application */
    }
    
    /*
     *  ======== printError ========
     */
    void printError(char *errString, int code)
    {
        Display_printf(display, 0, 0, "Error! code = %d, desc = %s\n", code,
                errString);
        while(1);
    }
    
    void Connect(void)
    {
        SlWlanSecParams_t   secParams = {0};
        int16_t ret = 0;
        secParams.Key = (signed char*)SECURITY_KEY;
        secParams.KeyLen = strlen(SECURITY_KEY);
        secParams.Type = SECURITY_TYPE;
        Display_printf(display, 0, 0, "Connecting to : %s.\r\n",SSID_NAME);
        ret = sl_WlanConnect((signed char*)SSID_NAME, strlen(SSID_NAME), 0, &secParams, 0);
        if (ret)
        {
            printError("Connection failed , error code : %d \r\n", ret);
        }
    }
    
    //*****************************************************************************
    //! \brief This function puts the device in its default state. It:
    //!           - Set the mode to STA
    //!           - Configures connection policy to Auto
    //!           - Deletes all the stored profiles
    //!           - Enables DHCP
    //!       - Disable IPV6
    //!           - Disables Scan policy
    //!           - Sets Tx power to maximum
    //!           - Sets power policy to normal
    //!           - Unregister mDNS services
    //!           - Remove all filters
    //!
    //!           IMPORTANT NOTE - This is an example reset function, user must
    //!           update this function to match the application settings.
    //!
    //! \param   none
    //! \return  On success, zero is returned. On error, negative is returned
    //*****************************************************************************
    static int32_t ConfigureSimpleLinkToDefaultState(void)
    {
        SlWlanRxFilterOperationCommandBuff_t  RxFilterIdMask;
    
        uint8_t     ucConfigOpt = 0;
        uint16_t    ifBitmap  = 0;
        uint8_t     ucPower = 0;
    
        int32_t             ret = -1;
        int32_t             mode = -1;
    
        memset(&RxFilterIdMask,0,sizeof(SlWlanRxFilterOperationCommandBuff_t));
    
        /* Start Simplelink - Blocking mode */
        mode = sl_Start(0, 0, 0);
        if (SL_RET_CODE_DEV_ALREADY_STARTED != mode)
        {
    //            ASSERT_ON_ERROR(mode);
        }
    
        /* If the device is not in STA mode, try configuring it in STA mode
         in case device is already started (got SL_RET_CODE_DEV_ALREADY_STARTED error code), then mode would remain -1 and in this case we do not know the role. Move to STA role anyway */
        if (ROLE_STA != mode)
        {
            /* Switch to STA role and restart */
            ret = sl_WlanSetMode(ROLE_STA);
    
            ret = sl_Stop(100);
    
            ret = sl_Start(0, 0, 0);
    
            /* Check if the device is in STA again */
            if (ROLE_STA != ret)
            {
                return ret;
            }
        }
    
        /* Set connection policy to Auto (no AutoProvisioning)  */
        ret = sl_WlanPolicySet(SL_WLAN_POLICY_CONNECTION,
                                    SL_WLAN_CONNECTION_POLICY(1, 0, 0, 0), NULL, 0);
    //    ASSERT_ON_ERROR(ret);
    
        /* Remove all profiles */
        ret = sl_WlanProfileDel(0xFF);
    //    ASSERT_ON_ERROR(ret);
    
        /* Enable DHCP client */
        ret = sl_NetCfgSet(SL_NETCFG_IPV4_STA_ADDR_MODE,SL_NETCFG_ADDR_DHCP,0,0);
    //    ASSERT_ON_ERROR(ret);
    
        /* Disable IPV6 */
        ifBitmap = 0;
        ret = sl_NetCfgSet(SL_NETCFG_IF, SL_NETCFG_IF_STATE, sizeof(ifBitmap), (uint8_t *)&ifBitmap);
    //    ASSERT_ON_ERROR(ret);
    
        /* Disable scan */
        ucConfigOpt = SL_WLAN_SCAN_POLICY(0, 0);
        ret = sl_WlanPolicySet(SL_WLAN_POLICY_SCAN , ucConfigOpt, NULL, 0);
    //    ASSERT_ON_ERROR(ret);
    
        /* Set Tx power level for station mode
         Number between 0-15, as dB offset from max power - 0 will set max power */
        ucPower = 0;
        ret = sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID,
                            SL_WLAN_GENERAL_PARAM_OPT_STA_TX_POWER, 1, (uint8_t *)&ucPower);
    //    ASSERT_ON_ERROR(ret);
    
        /* Set PM policy to normal */
        ret = sl_WlanPolicySet(SL_WLAN_POLICY_PM , SL_WLAN_NORMAL_POLICY, NULL, 0);
    //    ASSERT_ON_ERROR(ret);
    
        /* Unregister mDNS services */
        ret = sl_NetAppMDNSUnRegisterService(0, 0, 0);
    //    ASSERT_ON_ERROR(ret);
    
        /* Remove  all 64 filters (8*8) */
        memset(RxFilterIdMask.FilterBitmap, 0xFF, 8);
        ret = sl_WlanSet(SL_WLAN_RX_FILTERS_ID,
                   SL_WLAN_RX_FILTER_REMOVE,
                   sizeof(SlWlanRxFilterOperationCommandBuff_t),
                   (uint8_t *)&RxFilterIdMask);
    //    ASSERT_ON_ERROR(ret);
    
        ret = sl_Stop(100);
    //    ASSERT_ON_ERROR(ret);
    
        return ret;
    }
    
    void mainThread(void *pvParameters)
    {
        int32_t             status = 0;
        pthread_attr_t      pAttrs_spawn;
        pthread_attr_t      pAttrs;
        struct sched_param  priParam;
        int32_t             mode;
        int16_t             ret;
    
        SPI_init();
        Display_init();
        display = Display_open(Display_Type_UART, NULL);
        if (display == NULL) {
            /* Failed to open display driver */
            while(1);
        }
        ret = sem_init(&ipEventSyncObj,0,0);
        if(ret != 0)
        {
            printError("Semaphore init failed, error code : %d \r\n", ret);
            return;
        }
        /* Start the SimpleLink Host */
        pthread_attr_init(&pAttrs_spawn);
        priParam.sched_priority = SPAWN_TASK_PRIORITY;
        status = pthread_attr_setschedparam(&pAttrs_spawn, &priParam);
        status |= pthread_attr_setstacksize(&pAttrs_spawn, SPAWN_STACK_SIZE);
    
        status = pthread_create(&spawn_thread, &pAttrs_spawn, sl_Task, NULL);
        if(status)
        {
            printError("Task create failed, error code : %d \r\n", status);
        }
    
        ConfigureSimpleLinkToDefaultState();
    
        /* initialize the device */
        mode = sl_Start(0, 0, 0);
        if (mode < 0)
        {
            printError("Sl_start failed, error code : %d \r\n", status);
        }
        Connect();
    
        pthread_attr_init(&pAttrs);
        priParam.sched_priority = 1;
        status = pthread_attr_setschedparam(&pAttrs, &priParam);
        status |= pthread_attr_setstacksize(&pAttrs, TASK_STACK_SIZE);
    
        status = pthread_create(&httpThread, &pAttrs, httpTask, NULL);
        if (status)
        {
            printError("Task create failed, error code : %d \r\n", status);
        }
    }

  • Hi Ben,
    Finally I did it thanks for your support man it means a lot means a lot I cannot bear this. Thanks once again.



    Regards