HttpExampleClient SD card
응답
18. 1. 18 오후 4:37

Hello there.

I have a HttpExampleClient which is functioning as per what I wanted it to be, but now I want to make the XDK read server IP address, network SSID and password from XDK SD card? Similar to the BoschXDKCloudConnectivity so as that I do not have to flash the XDK everytime to change my wifi etc.

How do I do this and if you could guide me through it would be good!

Thanks and hope to hear from you soon.

Danial

+1 (1 투표)
RE: HttpExampleClient SD card
응답
18. 1. 18 오후 7:13 as a reply to Danial Rohmat.

Great - i need that too.
Should be an easy and simple code snipet - just init the SD Card Reader,
grab and provide some standard needed datas like wlan, server, port, user,  etc.

0 (0 투표)
RE: HttpExampleClient SD card
응답
18. 1. 19 오전 3:01 as a reply to Achim Kern.
Just init the SD card reader? You mean adding the init as header and add the wlan etc in? Not too sure about this steps, though. 
0 (0 투표)
RE: HttpExampleClient SD card
응답
18. 1. 19 오후 3:35 as a reply to Danial Rohmat.

Hello Danial,

It is of course possible to adapt the functionality of the HttpExampleClient to read certain credentials and other useful information from a config file on the SD card. For that, I recommend going through the SD card guide available in the Learning section of the XDK Community to get familiar with how to search for a file on the SD card and how to read its content.

I would recommend putting all your SD card implementation code into a new source file. If you feel up to it, you can also look through the SdCardExample from the Workbench's Welcome-screen. It already initializes, writes and reads data to and from the SD Card. Of course, you would have to remove writing functionality and add some logic to reading.

The easiest way to read information would be to have the first line in your configuration file on the SD card be the SSID, and the second the PW, and so on. This would result in one piece of information per line in your file.

Of course, you will need to store the SSID and PW in variables afterwards, and exchange any use of defines that have been previously used instead.

An example would be to change the Wi-Fi credential defines in the function WlanConnect(), where currently the defines WLAN_CONNECT_WPA_SSID and WLAN_CONNECT_WPA_PASS are used.

As mentioned before, all relevant information regarding SD cards on the XDK can be found in the learning section. Customizing the provided code-snippets to suit your specific use case is plain C-Programming.

Please let me know if that was helpful and feel free to ask if you have further questions.

Kind regards,
Franjo

0 (0 투표)
RE: HttpExampleClient SD card
응답
18. 1. 22 오전 9:11 as a reply to Franjo Stjepandic.

Hello - as already showed to many XDK resposible people.
Why do we not have here solutions like on other IoT Development systems ?

It would be great - if it looks a little bit like the particle photon ide system.
We have perfect libraries, which provide header and code files - and one or two examples how we can use them to build things.

Would be great to see such a solution with the SD card for example.
Here an example of using an bme280 Bosch sensor.

/***************************************************************************
  This is a library for the BME280 humidity, temperature & pressure sensor

  Designed specifically to work with the Adafruit BME280 Breakout
  ----> http://www.adafruit.com/products/2650

  These sensors use I2C or SPI to communicate, 2 or 4 pins are required
  to interface.

  Hint: the default I2C address used by the library is (0x77), as in
  Adafruit_BME280.h. If you sensor board uses a different address you
  can set your own via the .begin(...) method.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit andopen-source hardware by purchasing products
  from Adafruit!

  Written by Limor Fried & Kevin Townsend for Adafruit Industries.
  BSD license, all text above must be included in any redistribution

  This file was modified by Markus Haack (https://github.com/mhaack)
  in order to work with Particle Photon & Core.
 ***************************************************************************/

#include "Adafruit_Sensor.h"
#include "Adafruit_BME280.h"

#define BME_SCK D4
#define BME_MISO D3
#define BME_MOSI D2
#define BME_CS D5

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO,  BME_SCK);

void setup() {
  Serial.begin(9600);
  Serial.println(F("BME280 test"));

  // if (!bme.begin(0x76)) {
  if (!bme.begin()) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }
}

void loop() {
    Serial.print("Temperature = ");
    Serial.print(bme.readTemperature());
    Serial.println(" *C");

    Serial.print("Pressure = ");

    Serial.print(bme.readPressure() / 100.0F);
    Serial.println(" hPa");

    Serial.print("Approx. Altitude = ");
    Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
    Serial.println(" m");

    Serial.print("Humidity = ");
    Serial.print(bme.readHumidity());
    Serial.println(" %");

    Serial.println();
    delay(2000);
}

 

+1 (1 투표)
RE: HttpExampleClient SD card
응답
18. 1. 22 오후 1:04 as a reply to Achim Kern.

Hello Achim,

I can understand that the current form of documentation may not be optimal for everyone. At the very least, there are code-snippets for all major functionalities in the guides, including the SD Card Guide.

As such, you can simply go to chapters 3, 4.3, 5.2, 5.3 and 5.4, take the appropriate code snippets and copy them into your project.

Most functionality should be understandable from the code snippets alone.

What I can agree on, is the fact that the file system library could potentially be simplified into a few basic functions for easier use. But this is a decision that has to be made by the responsible department at Bosch.

I hope this was helpful, and feel free to ask further questions.

Kind regards,
Franjo

0 (0 투표)
RE: HttpExampleClient SD card
응답
18. 1. 23 오후 12:23 as a reply to Franjo Stjepandic.
/*
* Licensee agrees that the example code provided to Licensee has been developed and released by Bosch solely as an example to be used as a potential reference for Licensee�s application development.
* Fitness and suitability of the example code for any use within Licensee�s applications need to be verified by Licensee on its own authority by taking appropriate state of the art actions and measures (e.g. by means of quality assurance measures).
* Licensee shall be responsible for conducting the development of its applications as well as integration of parts of the example code into such applications, taking into account the state of the art of technology and any statutory regulations and provisions applicable for such applications. Compliance with the functional system requirements and testing there of (including validation of information/data security aspects and functional safety) and release shall be solely incumbent upon Licensee.
* For the avoidance of doubt, Licensee shall be responsible and fully liable for the applications and any distribution of such applications into the market.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
*     (1) Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*
*     (2) 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.
*
*     (3)The name of the author may not be used to
*     endorse or promote products derived from this software without
*     specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
/*----------------------------------------------------------------------------*/

/**
* @ingroup APPS_LIST
*
* @defgroup HTTP_EXAMPLE_CLIENT HttpExampleClient
* @{
*
* @brief Demo application for communicating with the HTTP to GET and POST content on the Server and demonstrate the use of custom headers.
*
* @details This example shows how to use the network stack to perform an HTTP Client Request.
*
* The example connects to the server <a href="http://www.posttestserver.com">www.posttestserver.com</a> and establishes a connection to the server.
*
* To view your posts, browse to the year, month, day, time and directory name XDK:
* <a href="http://posttestserver.com/data/">http://posttestserver.com/data/</a> This means all posts are visible to everybody so don't test with secure credentials.
* There you can see your custem heders as well.
*
* You need to add your WLAN-Credatials in \ref HttpExampleClient.h\n
* When running the program keep the USB plugged in to the PC. You can see in the consol output of the XDK-Workbench the content of the GET request.
*
* @file HttpExampleClient.c
**/

/* module includes ********************************************************** */

/* own header files */
#include "XDKAppInfo.h"

#undef BCDS_MODULE_ID  /* Module ID define before including Basics package*/
#define BCDS_MODULE_ID XDK_APP_MODULE_ID_HTTP_EXAMPLE_CLIENT
#define DEFAULT_LOGICAL_DRIVE ""
#define DRIVE_ZERO UINT8_C(0)
#define FORCE_MOUNT UINT8_C(1)
#define FIRST_LOCATION UINT8_C(0)

/* own header files */
#include "HttpExampleClient.h"

/* system header files */
#include <stdio.h>

/* additional interface header files */
#include "BCDS_SDCard_Driver.h"
#include "ff.h"
#include "BCDS_WlanConnect.h"
#include "BCDS_NetworkConfig.h"
#include "BCDS_CmdProcessor.h"
#include <Serval_HttpClient.h>
#include <Serval_Network.h>
#include "PAL_socketMonitor_ih.h"
#include "PAL_initialize_ih.h"
#include "BCDS_LightSensor.h"
#include "XdkSensorHandle.h"

/* constant definitions ***************************************************** */

/* local variables ********************************************************** */

/* global variables ********************************************************* */
static xTimerHandle connectTimerHandle; /**< variable to store timer handle*/
Ip_Address_T destAddr = UINT32_C(0);/*< variable to store the Ip address of the server */
static uint32_t intialOffset = UINT32_C(0); /* < variable to store the offset, the first byte to be received */
static uint32_t noOfBytesRecv = UINT32_C(512); /*< variable to store the number of bytes to receive */
static FIL fileObject; // file object pointer to be used for all file actions
char const *urlPtrReq = "/post.php?dump&html&dir=XDK"; /* URL string for the http website to post the payload*/
uint8_t payload[] = "XDK Testing"; /* payload to add to a request */
uint32_t tempData = UINT32_C(0);
uint32_t luxData = UINT32_C(0);
Accelerometer_XyzData_T aData = { INT32_C(0), INT32_C(0), INT32_C(0) };

/*Application Command Processor Instance */
CmdProcessor_T *AppCmdProcessor;

/* inline functions ********************************************************* */

/* local functions ********************************************************** */

/**
 * @brief This API is called when the HTTP page
 *      Connecting to a WLAN Access point.
 *       This function connects to the required AP (SSID_NAME).
 *       The function will return once we are connected and have acquired IP address
 *   @warning
 *      If the WLAN connection fails or we don't acquire an IP address, We will be stuck in this function forever.
 *      Check whether the callback "SimpleLinkWlanEventHandler" or "SimpleLinkNetAppEventHandler" hits once the
 *      sl_WlanConnect() API called, if not check for proper GPIO pin interrupt configuration or for any other issue
 *
 * @retval     RC_OK       IP address returned successfully
 *
 * @retval     RC_PLATFORM_ERROR         Error occurred in fetching the ip address
 *
 */
//HTTP code starts
static retcode_t WlanConnect(void)
{
    NetworkConfig_IpSettings_T myIpSettings;
    char ipAddress[PAL_IP_ADDRESS_SIZE] = { 0 };
    Ip_Address_T* IpaddressHex = Ip_getMyIpAddr();
    WlanConnect_SSID_T connectSSID;
    WlanConnect_PassPhrase_T connectPassPhrase;
    Retcode_T ReturnValue = (Retcode_T) RETCODE_FAILURE;
    int32_t Result = INT32_C(-1);

    if (RETCODE_OK != WlanConnect_Init())
    {
        return (RC_PLATFORM_ERROR);
    }

    printf("Connecting to %s \r\n ", WLAN_CONNECT_WPA_SSID);

    connectSSID = (WlanConnect_SSID_T) WLAN_CONNECT_WPA_SSID;
    connectPassPhrase = (WlanConnect_PassPhrase_T) WLAN_CONNECT_WPA_PASS;
    ReturnValue = NetworkConfig_SetIpDhcp(NULL);
    if (RETCODE_OK != ReturnValue)
    {
        printf("Error in setting IP to DHCP \r\n");
        return (RC_PLATFORM_ERROR);
    }
    if (RETCODE_OK == WlanConnect_WPA(connectSSID, connectPassPhrase, NULL))
    {
        ReturnValue = NetworkConfig_GetIpSettings(&myIpSettings);
        if (RETCODE_OK == ReturnValue)
        {
            *IpaddressHex = Basics_htonl(myIpSettings.ipV4);
            Result = Ip_convertAddrToString(IpaddressHex, ipAddress);
            if (Result < 0)
            {
                printf("Couldn't convert the IP address to string format \r\n ");
                return (RC_PLATFORM_ERROR);
            }
            printf("Connected to WPA network successfully \r\n ");
            printf(" Ip address of the device %s \r\n ", ipAddress);
            return (RC_OK);
        }
        else
        {
            printf("Error in getting IP settings \r\n");
            return (RC_PLATFORM_ERROR);
        }
    }
    else
    {
        return (RC_PLATFORM_ERROR);
    }

}


/**
 * @brief This API is called after the HTTP connects with the server to get the Content.
 *
 * @param[in]: callfunc
 *               The structure storing the pointer to the message handler
 * @param[in]: retcode_t
 *               The return code of the HTTP connect
 * @retval: retcode_t
 *               The return code of the callback Function
 */
static retcode_t CallbackOnSent(Callable_T *callfunc, retcode_t status)
{
    BCDS_UNUSED(callfunc);

    if (status != RC_OK)
    {
        //printf("error occurred in connecting server \r\n");
    }
    return (RC_OK);
}

/**
 * @brief This API is called after the HTTP connects with the server to post the Content.
 *
 * @param[in]: callfunc
 *               The structure storing the pointer to the message handler
 * @param[in]: retcode_t
 *               The return code of the HTTP connect
 * @retval: retcode_t
 *               The return code of the callback Function
 */
static retcode_t CallbackOnRecv(Callable_T *callfunc, retcode_t status)
{
    BCDS_UNUSED(callfunc);

    if (status != RC_OK)
    {
        //printf("error occurred in connecting server \r\n");
    }
    else
    {
        printf("Post Request Sent \r\n");
    }
    return (RC_OK);
}

/**
 * @brief API responsible to pass the payload to the requested URL
 *
 * @param[in] omsh_ptr This data structure is used hold the buffer and information needed by the serializer.
 *
 */
static retcode_t httpPayloadSerializer(
        OutMsgSerializationHandover_T *omsh_ptr)
{
    retcode_t rc = RC_OK;
    memcpy(omsh_ptr->buf_ptr, payload, strlen((char*) payload));
    omsh_ptr->len = strlen((char*) payload);

    return rc;
}

/**
 * @brief API responsible to internal headers have been serialized but before the header-terminating token
 *
 * @param[in] omsh_ptr This data structure is used hold the buffer and information needed by the serializer.
 *
 */
static retcode_t serializeMyHeaders(OutMsgSerializationHandover_T *omsh_ptr)
{
    retcode_t rc;
    omsh_ptr->len = 0;
    int n;
    static const char* myheader1 = "MyHeader: XDK\r\n";
    static const char* myheader2 = "MyOtherHeader: TestPurpose\r\n";

    switch (omsh_ptr->position)
    {
    case 0:
        n = strlen(myheader1);
        rc = TcpMsg_copyStaticContent(omsh_ptr, myheader1, n);
        if (rc != RC_OK)
            return rc;
        omsh_ptr->position = 1;
    case 1:
        n = strlen(myheader2);
        rc = TcpMsg_copyContentAtomic(omsh_ptr, myheader2, n);
        if (rc != RC_OK)
            return rc;
        omsh_ptr->position = 2;
    default:
        return RC_OK;
        break;
    }
}

/**
 * @brief API responsible to Post Data on html page.
 *
 * @param[in] Not used.
 *
 *
 * @param[in] Not used.
 */
static void PostContentOnWebpage(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);
    retcode_t rc = RC_OK;
    Msg_T* msg_ptr;
    Ip_Port_T destPort = (Ip_Port_T) DEST_PORT_NUMBER;
    static Callable_T RecvCallable;
    Callable_T * Callable_pointer;
    Callable_pointer = Callable_assign(&RecvCallable, CallbackOnRecv);
    if (Callable_pointer == NULL)
    {
        printf("Failed Callable_assign\r\n ");
        return;
    }
    rc = HttpClient_initRequest(&destAddr, Ip_convertIntToPort(destPort), &msg_ptr);

    if (rc != RC_OK || msg_ptr == NULL)
    {
        //printf("Failed HttpClient_initRequest \r\n ");
        return;
    }
    HttpMsg_serializeCustomHeaders(msg_ptr, serializeMyHeaders);
    HttpMsg_setReqMethod(msg_ptr, Http_Method_Post);

    rc = HttpMsg_setReqUrl(msg_ptr, urlPtrReq);
    if (rc != RC_OK)
    {
        printf("Failed to fill message \r\n ");
        return;
    }

    /* set content type and payload */
    HttpMsg_setContentType(msg_ptr, Http_ContentType_Text_Plain);

    rc = Msg_prependPartFactory(msg_ptr, &httpPayloadSerializer);
    if (RC_OK == rc)
    {
        rc = HttpClient_pushRequest(msg_ptr, &RecvCallable,
        NULL);
        if (rc != RC_OK)
        {
            printf("Failed HttpClient_pushRequest \r\n  ");
            return;
        }
    }
    if (rc != RC_OK)
    {
        printf("Failed to Fill the payload on payloadSerializer \r\n  ");
        return;
    }
}

/**
 * @brief This API is called after downloading the HTTP page from the server
 *
 * @param[in]: HttpSession_T
 *               The pointer holding the details of the http session
 * @param[in]: Msg_T
 *               The structure storing the pointer to the message handler
 * @param[in]: retcode_t
 *               The return code of the HTTP page download
 *
 * @retval: retcode_t
 *               The return code of the HTTP connect
 *
 */
static retcode_t HttpClientResponseCallback(HttpSession_T *httpSession,
        Msg_T *msg_ptr, retcode_t status)
{
    BCDS_UNUSED(httpSession);
    retcode_t rc = status;
    uint32_t pageContentSize; /* total length of the content at the server */
    bool flag = false; /* flag to set to true if this is the last piece of the message */
    Retcode_T returnValue = RETCODE_OK;
    if (rc != RC_OK)
    {
        /* Error occurred in downloading the page */
        printf("error occurred in downloading HTML \r\n");
    }
    else if (msg_ptr == NULL)
    {
        rc = RC_HTTP_PARSER_INVALID_CONTENT_TYPE;
    }
    else
    {
        rc = HttpMsg_getRange(msg_ptr, UINT32_C(0), &pageContentSize, &flag);
        if (rc != RC_OK)
        {
            printf("Failed to Get Range \r\n ");
        }
        else
        {
            if (HttpMsg_getContentType(msg_ptr) != Http_ContentType_Text_Html)
            {
                rc = RC_HTTP_INVALID_RESPONSE;
            }
            else
            {
                char const *content_ptr = "";
                unsigned int len = UINT32_C(0);
                HttpMsg_getContent(msg_ptr, &content_ptr, &len);
                printf("GET Response Content %s \r\n", content_ptr);
                intialOffset += (len);
                /* Clear the Content Buffer */
                memset(content_ptr, UINT32_C(0), len);
                /* check if this is the last piece of the message. This parameter will also be true if the message is not fragmented.*/
/*                if (flag == true)
                {
                    printf("Page content %lu Bytes Download Completed \r\n", pageContentSize);
                    if (xTimerStop(connectTimerHandle, 0) != pdTRUE)
                    {
                        assert(false);
                    }
                    /* En-queuing to application command processor to post the content on Http page */
/*                    returnValue = CmdProcessor_enqueue(AppCmdProcessor, PostContentOnWebpage, NULL, UINT32_C(0));
                    if (RETCODE_OK != returnValue)
                    {
                        printf("En-queuing to application command processor failed \r\n");
                    }
                } */
            }
        }
    }

    if (rc != RC_OK)
    {
        printf("error occurred in downloading HTML \r\n");
    }
    return (rc);
}
/* global functions ********************************************************** */

static void initSensor(void)
{
    Retcode_T returnValue = RETCODE_FAILURE;
    returnValue = Environmental_init(xdkEnvironmental_BME280_Handle);
    returnValue = LightSensor_init(xdkLightSensor_MAX44009_Handle);
    if(RETCODE_OK != returnValue)
    {
        //printf("Light Sensor initialization Failed\n\r");
    }
}

static void readSensor(xTimerHandle xTimer)
{
    (void) xTimer;

    //uint32_t milliLuxData = UINT32_C(0);
    Retcode_T returnValue = RETCODE_FAILURE;

    returnValue = Environmental_readTemperature(xdkEnvironmental_BME280_Handle,
            &tempData);
    returnValue = LightSensor_readLuxData(xdkLightSensor_MAX44009_Handle,
                &luxData);

    if(RETCODE_OK == returnValue)
    {
        //printf("Light sensor data obtained in milli lux: %d \n\r",(unsigned int) milliLuxData);
    }
}

/**
 * @brief API responsible to read html page content of the client and print it on the console.
 *
 * @param[in] Not used.
 *
 *
 * @param[in] Not used.
 */
static void PrintWebpageContent(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);
    retcode_t rc = RC_OK;
    Msg_T* msg_ptr;
    Ip_Port_T destPort = (Ip_Port_T) DEST_PORT_NUMBER;
    static Callable_T SentCallable;
    const char url_ptr[100]; /* URL string for the http website */
    int n = sprintf(url_ptr,"/bothinsert.php?tempData=%d&luxData=%d",tempData/1000, luxData/1000);
    Callable_T * Callable_pointer;
    Callable_pointer = Callable_assign(&SentCallable, CallbackOnSent);
    if (Callable_pointer == NULL)
    {
        printf("Failed Callable_assign\r\n ");
        return;
    }
    rc = HttpClient_initRequest(&destAddr, Ip_convertIntToPort(destPort), &msg_ptr);

    if (rc != RC_OK || msg_ptr == NULL)
    {
        //printf("Failed HttpClient_initRequest \r\n ");
        return;
    }
    HttpMsg_setRange(msg_ptr, intialOffset, noOfBytesRecv);
    HttpMsg_setReqMethod(msg_ptr, Http_Method_Get);
    rc = HttpMsg_setReqUrl(msg_ptr, url_ptr);
    if (rc != RC_OK)
    {
        printf("Failed to fill message \r\n ");
        return;
    }

    rc = HttpClient_pushRequest(msg_ptr, &SentCallable,
            HttpClientResponseCallback);
    if (rc != RC_OK)
    {
        printf("Failed HttpClient_pushRequest \r\n  ");
        return;
    }
}

/**
 * @brief This API triggers periodically and initiate PrintWebpageContent to download the web page content.
 *
 * @param[in]: xTimer
 *               The timer handle of the function
 *
 */
static void ConnectServer(xTimerHandle xTimer)
{
    BCDS_UNUSED(xTimer);
    Retcode_T returnValue = RETCODE_OK;

    returnValue = CmdProcessor_enqueue(AppCmdProcessor, PrintWebpageContent, NULL, UINT32_C(0));
    if (RETCODE_OK != returnValue)
    {
        printf("En-queuing to application command processor failed \r\n");
    }
}

/* The description is in the interface header file. */
static void Init(void)
{
    retcode_t rc = RC_OK;

    rc = WlanConnect();
    if (RC_OK != rc)
    {
        printf("Network init/connection failed %i \r\n", rc);
        return;
    }

    rc = PAL_initialize();
    if (RC_OK != rc)
    {
        printf("PAL and network initialize %i \r\n", rc);
        return;
    }

    PAL_socketMonitorInit();

    /* start client */
    rc = HttpClient_initialize();
    if (rc != RC_OK)
    {
        printf("Failed to initialize http client \r\n ");
        return;
    }

    if (RC_OK != PAL_getIpaddress((uint8_t*) "192.168.43.74", &destAddr))
    {
        return;
    }

    else
    {
        uint32_t Ticks = 2500;

/*        if (Ticks != UINT32_MAX) /* Validated for portMAX_DELAY to assist the task to wait Infinitely (without timing out) */
/*        {
            Ticks /= portTICK_RATE_MS;
        }
        if (UINT32_C(0) == Ticks) /* ticks cannot be 0 in FreeRTOS timer. So ticks is assigned to 1 */
/*        {
            Ticks = UINT32_C(1);
        }
        /* Timer to Get Content from the connected server */
        connectTimerHandle = xTimerCreate((const char * const ) "ConnectServer", Ticks,TIMER_AUTORELOAD_ON, NULL, ConnectServer);
        if (connectTimerHandle != NULL)
        {
            if (xTimerStart(connectTimerHandle, TIMERBLOCKTIME) != pdTRUE)
            {
                assert(false);
            }
            else
            {
                printf("Started the timer successfully \r\n ");
            }

        }
    }
}

/**
 * @brief This is a template function where the user can write his custom application.
 *
 */
void appInitSystem(void * CmdProcessorHandle, uint32_t param2)
{
    if (CmdProcessorHandle == NULL)
    {
        printf("Command processor handle is null \n\r");
        assert(false);
    }
    BCDS_UNUSED(param2);
    uint32_t timerBlockTime = UINT32_MAX;
    uint32_t OneSecondDelay = UINT32_C(2500);
    uint32_t timerAutoReloadOn = pdTRUE;

    xTimerHandle SensorHandle= NULL;

    initSensor();

    SensorHandle = xTimerCreate((const char *) "readTempSensor", OneSecondDelay, timerAutoReloadOn, NULL, readSensor);

    xTimerStart(SensorHandle,timerBlockTime);

    AppCmdProcessor = (CmdProcessor_T *) CmdProcessorHandle;
    BCDS_UNUSED(param2);
    /*Call the RHC init API */
    Init();

}
/**@} */

 

Hi there.

I believe what you told me was to copy only the reading part of the SDCardExample and paste it in my HttpExampleClient source code, am I right? Done that but the XDK does not read the SD card. Tested it with the BoschXDKCloudConnectivity and it worked flawlessly. I've also tried to create my own source code and make use of the SD Card tutorial but to no success. I kept on getting error, either the XDK doesnt want to connect to ANY wifi, or it will connect to the old wifi. It would be nice and great if you can give me a step by step instruction on what to add on to my source code. 

By the way, attached is my HttpExampleClient.c source code.

 

0 (0 투표)
RE: HttpExampleClient SD card
응답
18. 1. 23 오후 5:50 as a reply to Danial Rohmat.

Hello Danial,

You are correct, taking a look at the SdCardExample as well as at the SD Card guide was a hint of mine.

As far as I can see, you were able to integrate the constant definitions from chapter 3 of the SD Card guide and I assume you deleted the other integrated code because it threw errors? Am I right so far?

If this is correct, then it would be helpful if you could provide us with the erroneous code as well. I can, of course, provide you with more detailed descriptions regarding SD cards on the XDK, so that you can integrate it. But I really require you to show me your progress more clearly.

As I already mentioned to Achim, I recommend integrating the code into an additional implementation file. For your use case, you only need to add the outlines from the codes 3, 3 and 5.

Please note that there is a small mistake with the numbering of the code snippets and code 3 is used as numeration for two code snippets.

With that, you should have all utility you need to read the entire content of a config file on the SD card.

In addition to that, I recommend taking a look at the XDK Knowledge Base at the section Data Storage. There, you can find the entire content of the SD Card guide, in addition to a full code example combining all code snippets from the guide in one working application file.

Keep in mind that after reading the contents of a file, you also need to parse it. This means, you have to add logic that determines which parts of the file represent which part of the credentials.

For that, I recommend, as you already mentioned, taking a look at the implementation file CfgParser.c of the BoschXDKCloudConnectivity example. There you can find the complete parser logic for the credentials inserted in the config file for the BoschXDKCloudConnectivity example. Thus, I would recommend only taking the relevant parts for your own implementation from the CfgParser.c implementation file.

Please let me know if that was helpful and feel free to ask if you have further questions.

Kind regards,
Franjo

0 (0 투표)
RE: HttpExampleClient SD card
응답
18. 1. 25 오후 1:44 as a reply to Franjo Stjepandic.
/* own header files */
#include "XDKAppInfo.h"

#undef BCDS_MODULE_ID  /* Module ID define before including Basics package*/
#define BCDS_MODULE_ID XDK_APP_MODULE_ID_HTTP_EXAMPLE_CLIENT
#define DEFAULT_LOGICAL_DRIVE ""
#define DRIVE_ZERO UINT8_C(0)
#define FORCE_MOUNT UINT8_C(1)
#define FIRST_LOCATION UINT8_C(0)

/* own header files */
#include "HttpExampleClient.h"
#include "BCDS_CmdProcessor.h"
#include "BCDS_Assert.h"

/* system header files */
#include <stdio.h>

/* additional interface header files */
#include "BCDS_SDCard_Driver.h"
#include "ff.h"
#include "BCDS_WlanConnect.h"
#include "BCDS_NetworkConfig.h"
#include "BCDS_CmdProcessor.h"
#include <Serval_HttpClient.h>
#include <Serval_Network.h>
#include "PAL_socketMonitor_ih.h"
#include "PAL_initialize_ih.h"
#include "BCDS_LightSensor.h"
#include "XdkSensorHandle.h"
#include "FreeRTOS.h"
#include "timers.h"

/* constant definitions ***************************************************** */
#define DEFAULT_LOGICAL_DRIVE   ""
#define DRIVE_ZERO              UINT8_C(0)
#define FORCE_MOUNT             UINT8_C(1)
#define FIRST_LOCATION          UINT8_C(0)


/* local variables ********************************************************** */

/* global variables ********************************************************* */
static xTimerHandle connectTimerHandle; /**< variable to store timer handle*/
Ip_Address_T destAddr = UINT32_C(0);/*< variable to store the Ip address of the server */
static uint32_t intialOffset = UINT32_C(0); /* < variable to store the offset, the first byte to be received */
static uint32_t noOfBytesRecv = UINT32_C(512); /*< variable to store the number of bytes to receive */
static FIL fileObject; // file object pointer to be used for all file actions
char const *urlPtrReq = "/post.php?dump&html&dir=XDK"; /* URL string for the http website to post the payload*/
uint8_t payload[] = "XDK Testing"; /* payload to add to a request */
uint32_t tempData = UINT32_C(0);
uint32_t luxData = UINT32_C(0);
Accelerometer_XyzData_T aData = { INT32_C(0), INT32_C(0), INT32_C(0) };

/*Application Command Processor Instance */
CmdProcessor_T *AppCmdProcessor;

/* inline functions ********************************************************* */

/* local functions ********************************************************** */


//HTTP code starts

void InitSdCard(void){
  Retcode_T retVal = RETCODE_FAILURE;
  FRESULT FileSystemResult = FR_OK;
  static FATFS FatFileSystemObject;
  SDCardDriver_Initialize();
  if(SDCARD_INSERTED == SDCardDriver_GetDetectStatus()){
    retVal = SDCardDriver_DiskInitialize(DRIVE_ZERO);
    if(RETCODE_OK == retVal){
      printf("SD Card Disk initialize succeeded \n\r");
      FileSystemResult = f_mount(&FatFileSystemObject, DEFAULT_LOGICAL_DRIVE,
                                    FORCE_MOUNT);
      if (FR_OK != FileSystemResult){
        printf("Mounting SD card failed \n\r");
      }
    }
  }
}

Retcode_T searchForFileOnSdCard(const char* filename, FILINFO* fileData){
  if(FR_OK == f_stat(filename, fileData)){
    printf("File %s found on SD card. \n\r",filename);
    return RETCODE_OK;
  } else {
    printf("File %s does not exist. \n\r",filename);
    return RETCODE_FAILURE;
  }
}

void createFileOnSdCard(const char* filename){
  if(FR_OK == f_open(&fileObject, filename, FA_CREATE_NEW)){
    printf("File %s was created successfully \n\r",filename);
  }
}

static retcode_t WlanConnect(void)
{
    NetworkConfig_IpSettings_T myIpSettings;
    char ipAddress[PAL_IP_ADDRESS_SIZE] = { 0 };
    Ip_Address_T* IpaddressHex = Ip_getMyIpAddr();
    WlanConnect_SSID_T connectSSID;
    WlanConnect_PassPhrase_T connectPassPhrase;
    Retcode_T ReturnValue = (Retcode_T) RETCODE_FAILURE;
    int32_t Result = INT32_C(-1);

    if (RETCODE_OK != WlanConnect_Init())
    {
        return (RC_PLATFORM_ERROR);
    }

    printf("Connecting to %s \r\n ", WLAN_CONNECT_WPA_SSID);

    connectSSID = (WlanConnect_SSID_T) WLAN_CONNECT_WPA_SSID;
    connectPassPhrase = (WlanConnect_PassPhrase_T) WLAN_CONNECT_WPA_PASS;
    ReturnValue = NetworkConfig_SetIpDhcp(NULL);
    if (RETCODE_OK != ReturnValue)
    {
        printf("Error in setting IP to DHCP \r\n");
        return (RC_PLATFORM_ERROR);
    }
    if (RETCODE_OK == WlanConnect_WPA(connectSSID, connectPassPhrase, NULL))
    {
        ReturnValue = NetworkConfig_GetIpSettings(&myIpSettings);
        if (RETCODE_OK == ReturnValue)
        {
            *IpaddressHex = Basics_htonl(myIpSettings.ipV4);
            Result = Ip_convertAddrToString(IpaddressHex, ipAddress);
            if (Result < 0)
            {
                printf("Couldn't convert the IP address to string format \r\n ");
                return (RC_PLATFORM_ERROR);
            }
            printf("Connected to WPA network successfully \r\n ");
            printf(" Ip address of the device %s \r\n ", ipAddress);
            return (RC_OK);
        }
        else
        {
            printf("Error in getting IP settings \r\n");
            return (RC_PLATFORM_ERROR);
        }
    }
    else
    {
        return (RC_PLATFORM_ERROR);
    }

}

static retcode_t CallbackOnSent(Callable_T *callfunc, retcode_t status)
{
    BCDS_UNUSED(callfunc);

    if (status != RC_OK)
    {
        //printf("error occurred in connecting server \r\n");
    }
    return (RC_OK);
}

static retcode_t CallbackOnRecv(Callable_T *callfunc, retcode_t status)
{
    BCDS_UNUSED(callfunc);

    if (status != RC_OK)
    {
        //printf("error occurred in connecting server \r\n");
    }
    else
    {
        printf("Post Request Sent \r\n");
    }
    return (RC_OK);
}

static retcode_t httpPayloadSerializer(
        OutMsgSerializationHandover_T *omsh_ptr)
{
    retcode_t rc = RC_OK;
    memcpy(omsh_ptr->buf_ptr, payload, strlen((char*) payload));
    omsh_ptr->len = strlen((char*) payload);

    return rc;
}

static retcode_t serializeMyHeaders(OutMsgSerializationHandover_T *omsh_ptr)
{
    retcode_t rc;
    omsh_ptr->len = 0;
    int n;
    static const char* myheader1 = "MyHeader: XDK\r\n";
    static const char* myheader2 = "MyOtherHeader: TestPurpose\r\n";

    switch (omsh_ptr->position)
    {
    case 0:
        n = strlen(myheader1);
        rc = TcpMsg_copyStaticContent(omsh_ptr, myheader1, n);
        if (rc != RC_OK)
            return rc;
        omsh_ptr->position = 1;
    case 1:
        n = strlen(myheader2);
        rc = TcpMsg_copyContentAtomic(omsh_ptr, myheader2, n);
        if (rc != RC_OK)
            return rc;
        omsh_ptr->position = 2;
    default:
        return RC_OK;
        break;
    }
}

static void PostContentOnWebpage(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);
    retcode_t rc = RC_OK;
    Msg_T* msg_ptr;
    Ip_Port_T destPort = (Ip_Port_T) DEST_PORT_NUMBER;
    static Callable_T RecvCallable;
    Callable_T * Callable_pointer;
    Callable_pointer = Callable_assign(&RecvCallable, CallbackOnRecv);
    if (Callable_pointer == NULL)
    {
        printf("Failed Callable_assign\r\n ");
        return;
    }
    rc = HttpClient_initRequest(&destAddr, Ip_convertIntToPort(destPort), &msg_ptr);

    if (rc != RC_OK || msg_ptr == NULL)
    {
        //printf("Failed HttpClient_initRequest \r\n ");
        return;
    }
    HttpMsg_serializeCustomHeaders(msg_ptr, serializeMyHeaders);
    HttpMsg_setReqMethod(msg_ptr, Http_Method_Post);

    rc = HttpMsg_setReqUrl(msg_ptr, urlPtrReq);
    if (rc != RC_OK)
    {
        printf("Failed to fill message \r\n ");
        return;
    }

    /* set content type and payload */
    HttpMsg_setContentType(msg_ptr, Http_ContentType_Text_Plain);

    rc = Msg_prependPartFactory(msg_ptr, &httpPayloadSerializer);
    if (RC_OK == rc)
    {
        rc = HttpClient_pushRequest(msg_ptr, &RecvCallable,
        NULL);
        if (rc != RC_OK)
        {
            printf("Failed HttpClient_pushRequest \r\n  ");
            return;
        }
    }
    if (rc != RC_OK)
    {
        printf("Failed to Fill the payload on payloadSerializer \r\n  ");
        return;
    }
}

static retcode_t HttpClientResponseCallback(HttpSession_T *httpSession,
        Msg_T *msg_ptr, retcode_t status)
{
    BCDS_UNUSED(httpSession);
    retcode_t rc = status;
    uint32_t pageContentSize; /* total length of the content at the server */
    bool flag = false; /* flag to set to true if this is the last piece of the message */
    Retcode_T returnValue = RETCODE_OK;
    if (rc != RC_OK)
    {
        /* Error occurred in downloading the page */
        printf("error occurred in downloading HTML \r\n");
    }
    else if (msg_ptr == NULL)
    {
        rc = RC_HTTP_PARSER_INVALID_CONTENT_TYPE;
    }
    else
    {
        rc = HttpMsg_getRange(msg_ptr, UINT32_C(0), &pageContentSize, &flag);
        if (rc != RC_OK)
        {
            printf("Failed to Get Range \r\n ");
        }
        else
        {
            if (HttpMsg_getContentType(msg_ptr) != Http_ContentType_Text_Html)
            {
                rc = RC_HTTP_INVALID_RESPONSE;
            }
            else
            {
                char const *content_ptr = "";
                unsigned int len = UINT32_C(0);
                HttpMsg_getContent(msg_ptr, &content_ptr, &len);
                printf("GET Response Content %s \r\n", content_ptr);
                intialOffset += (len);
                /* Clear the Content Buffer */
                memset(content_ptr, UINT32_C(0), len);
                /* check if this is the last piece of the message. This parameter will also be true if the message is not fragmented.*/
/*                if (flag == true)
                {
                    printf("Page content %lu Bytes Download Completed \r\n", pageContentSize);
                    if (xTimerStop(connectTimerHandle, 0) != pdTRUE)
                    {
                        assert(false);
                    }
                    /* En-queuing to application command processor to post the content on Http page */
/*                    returnValue = CmdProcessor_enqueue(AppCmdProcessor, PostContentOnWebpage, NULL, UINT32_C(0));
                    if (RETCODE_OK != returnValue)
                    {
                        printf("En-queuing to application command processor failed \r\n");
                    }
                } */
            }
        }
    }

    if (rc != RC_OK)
    {
        printf("error occurred in downloading HTML \r\n");
    }
    return (rc);
}

/* global functions ********************************************************** */

static void initSensor(void)
{
    Retcode_T returnValue = RETCODE_FAILURE;
    returnValue = Environmental_init(xdkEnvironmental_BME280_Handle);
    returnValue = LightSensor_init(xdkLightSensor_MAX44009_Handle);
    if(RETCODE_OK != returnValue)
    {
        //printf("Light Sensor initialization Failed\n\r");
    }
}

static void readSensor(xTimerHandle xTimer)
{
    (void) xTimer;

    //uint32_t milliLuxData = UINT32_C(0);
    Retcode_T returnValue = RETCODE_FAILURE;

    returnValue = Environmental_readTemperature(xdkEnvironmental_BME280_Handle,
            &tempData);
    returnValue = LightSensor_readLuxData(xdkLightSensor_MAX44009_Handle,
                &luxData);

    if(RETCODE_OK == returnValue)
    {
        //printf("Light sensor data obtained in milli lux: %d \n\r",(unsigned int) milliLuxData);
    }
}

static void PrintWebpageContent(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);
    retcode_t rc = RC_OK;
    Msg_T* msg_ptr;
    Ip_Port_T destPort = (Ip_Port_T) DEST_PORT_NUMBER;
    static Callable_T SentCallable;
    const char url_ptr[100]; /* URL string for the http website */
    int n = sprintf(url_ptr,"/bothinsert.php?tempData=%d&luxData=%d",tempData/1000, luxData/1000);
    Callable_T * Callable_pointer;
    Callable_pointer = Callable_assign(&SentCallable, CallbackOnSent);
    if (Callable_pointer == NULL)
    {
        printf("Failed Callable_assign\r\n ");
        return;
    }
    rc = HttpClient_initRequest(&destAddr, Ip_convertIntToPort(destPort), &msg_ptr);

    if (rc != RC_OK || msg_ptr == NULL)
    {
        //printf("Failed HttpClient_initRequest \r\n ");
        return;
    }
    HttpMsg_setRange(msg_ptr, intialOffset, noOfBytesRecv);
    HttpMsg_setReqMethod(msg_ptr, Http_Method_Get);
    rc = HttpMsg_setReqUrl(msg_ptr, url_ptr);
    if (rc != RC_OK)
    {
        printf("Failed to fill message \r\n ");
        return;
    }

    rc = HttpClient_pushRequest(msg_ptr, &SentCallable,
            HttpClientResponseCallback);
    if (rc != RC_OK)
    {
        printf("Failed HttpClient_pushRequest \r\n  ");
        return;
    }
}

static void ConnectServer(xTimerHandle xTimer)
{
    BCDS_UNUSED(xTimer);
    Retcode_T returnValue = RETCODE_OK;

    returnValue = CmdProcessor_enqueue(AppCmdProcessor, PrintWebpageContent, NULL, UINT32_C(0));
    if (RETCODE_OK != returnValue)
    {
        printf("En-queuing to application command processor failed \r\n");
    }
}

/* The description is in the interface header file. */
static void Init(void)
{
    retcode_t rc = RC_OK;

    rc = WlanConnect();
    if (RC_OK != rc)
    {
        printf("Network init/connection failed %i \r\n", rc);
        return;
    }

    rc = PAL_initialize();
    if (RC_OK != rc)
    {
        printf("PAL and network initialize %i \r\n", rc);
        return;
    }

    PAL_socketMonitorInit();

    /* start client */
    rc = HttpClient_initialize();
    if (rc != RC_OK)
    {
        printf("Failed to initialize http client \r\n ");
        return;
    }

    if (RC_OK != PAL_getIpaddress((uint8_t*) "192.168.43.74", &destAddr))
    {
        return;
    }

    else
    {
        uint32_t Ticks = 2500;

/*        if (Ticks != UINT32_MAX) /* Validated for portMAX_DELAY to assist the task to wait Infinitely (without timing out) */
/*        {
            Ticks /= portTICK_RATE_MS;
        }
        if (UINT32_C(0) == Ticks) /* ticks cannot be 0 in FreeRTOS timer. So ticks is assigned to 1 */
/*        {
            Ticks = UINT32_C(1);
        }
        /* Timer to Get Content from the connected server */
        connectTimerHandle = xTimerCreate((const char * const ) "ConnectServer", Ticks,TIMER_AUTORELOAD_ON, NULL, ConnectServer);
        if (connectTimerHandle != NULL)
        {
            if (xTimerStart(connectTimerHandle, TIMERBLOCKTIME) != pdTRUE)
            {
                assert(false);
            }
            else
            {
                printf("Started the timer successfully \r\n ");
            }

        }
    }
}

void appInitSystem(void * CmdProcessorHandle, uint32_t param2)
{
    if (CmdProcessorHandle == NULL)
    {
        printf("Command processor handle is null \n\r");
        assert(false);
    }
    BCDS_UNUSED(param2);
    uint32_t timerBlockTime = UINT32_MAX;
    uint32_t OneSecondDelay = UINT32_C(2500);
    uint32_t timerAutoReloadOn = pdTRUE;

    xTimerHandle SensorHandle= NULL;

    initSensor();

    SensorHandle = xTimerCreate((const char *) "readTempSensor", OneSecondDelay, timerAutoReloadOn, NULL, readSensor);

    xTimerStart(SensorHandle,timerBlockTime);

    AppCmdProcessor = (CmdProcessor_T *) CmdProcessorHandle;
    BCDS_UNUSED(param2);
    /*Call the RHC init API */
    Init();

}

Hi.

I've tried my best and this is what I can come out of. I did what you have told me to do, except for the part about CfgParser from BoschXDKConnectivity. I do not understand which ones to take and implement as the code is too complicated and long for me to understand. 

I also have a feeling that the format of the SSID and PASSWORD in my SD card is wrong, and that might be the reason also why I cannot connect via the SD card. The format is as below, and attached is my latest updated code that I had tried out:

SSID = MySSID

PASSWORD = MyNetworkPassword

 

0 (0 투표)
RE: HttpExampleClient SD card
응답
18. 1. 25 오후 4:59 as a reply to Danial Rohmat.

Hello Danial,

so far so good. The initialization function and the searching functions seem correct. Be aware, that you do not need to create a new file (which is currently done within createFileOnSdCard()). As such, you only have to open it with read permission as follows

f_open(&fileObject, filename, FA_OPEN_EXISTING | FA_READ)

Once the file is opened, I would recommend that you actually change the structure of the file. You could set the first line as your SSID, and the second one as the password, like this:

mySSID
myPassword

This would make parsing easier, since you can now use the following code, to retrieve one of those lines. As an example, here is the code to retrieve the SSID, if the SSID is the first line as proposed above:

f_gets(ramBufferRead,UINT16_C(512),&fileObject);
ramBufferRead[strlen(ramBufferRead)-1] = '0'; // to remove 'n'
printf("Read first line from SD card %snr",ramBufferRead); // print to check
strcpy(ssidString, ramBufferRead); // copy string to a global variable

Make sure to not declare ssidString locally. This should be accessible by your other functions! And of course, remember to call the relevant functions within appInitSystem() somewhere.

Please tell me if this was helpful, and do not hesitate to ask further questions.

Kind regards,
Franjo

 

0 (0 투표)
RE: HttpExampleClient SD card
응답
18. 1. 25 오후 6:11 as a reply to Franjo Stjepandic.

Once the file is opened, I would recommend that you actually change the structure of the file. You could set the first line as your SSID, and the second one as the password, like this:

mySSID
myPassword

For this, this is to be placed in notepad txt file under what name? For example bosch xdk portal states put under NCONFIG.txt etc. 

 

This would make parsing easier, since you can now use the following code, to retrieve one of those lines. As an example, here is the code to retrieve the SSID, if the SSID is the first line as proposed above:

f_gets(ramBufferRead,UINT16_C(512),&fileObject);
ramBufferRead[strlen(ramBufferRead)-1] = '0'; // to remove 'n'
printf("Read first line from SD card %snr",ramBufferRead); // print to check
strcpy(ssidString, ramBufferRead); // copy string to a global variable

is this how its supposed to be placed like? 

void createFileOnSdCard(const char* filename){
  if(FR_OK == f_open(&fileObject, filename, FA_OPEN_EXISTING | FA_READ)){
    printf("File %s was opened successfully \n\r",filename);
  }
}
f_gets(ramBufferRead,UINT16_C(512),&fileObject);
ramBufferRead[strlen(ramBufferRead)-1] = '0'; // to remove 'n'
printf("Read first line from SD card %snr",ramBufferRead); // print to check
strcpy(ssidString, ramBufferRead); // copy string to a global variable

f_gets(ramBufferRead,UINT16_C(512),&fileObject);
ramBufferRead[strlen(ramBufferRead)-2] = '1'; // to remove 'n'
printf("Read second line from SD card %snr",ramBufferRead); // print to check
strcpy(passwordString, ramBufferRead); // copy string to a global variable
 

 

Make sure to not declare ssidString locally. This should be accessible by your other functions! And of course, remember to call the relevant functions within appInitSystem() somewhere.

I don't think ssidString has been declared locally yet, and how do I not declare it locally? 

And for the part of the appInitSystem(), I think I know what you are talking about but that can only be done when all is implemented right? Hope you get back to me soon and thanks!

 

0 (0 투표)
RE: HttpExampleClient SD card
응답
18. 1. 26 오후 2:40 as a reply to Danial Rohmat.

Hello Danial,

regarding the filename, you can use any filename you want, as long as it is less than 13 characters, including the filetype extension (such as ".txt"). As such, CONFIG.TXT should suffice.

As for the code, I will try to keep it plain and simple, since at this point, you already have all the neccessary code pieces.
 

char *ssidString;
char *passwordString

void createFileOnSdCard(const char* filename){

if(FR_OK == f_open(&fileObject, filename, FA_OPEN_EXISTING | FA_READ)){ 
    f_gets(ramBufferRead,UINT16_C(512),&fileObject); ramBufferRead[strlen(ramBufferRead)-1] = '0'; 
    printf("Read first line from SD card %snr",ramBufferRead); strcpy(ssidString, ramBufferRead); 
    f_gets(ramBufferRead,UINT16_C(512),&fileObject); ramBufferRead[strlen(ramBufferRead)-2] = '1'; 
    printf("Read second line from SD card %snr",ramBufferRead); 
    strcpy(passwordString, ramBufferRead); 
    }
}

Like this, the function createFileOnSdCard will open a file, read its contents and store the SSID and Password. I have also taken the liberty to add the declarations for ssidString and passwordString. You should put those declarations somewhere near the top of your code.

Now, you should add the following code to your appInitSystem().

// before connecting to WiFi
InitSdCard();
if (RETCODE_OK == searchForFileOnSdCard("CONFIG.TXT", NULL))
{ 
    createFileOnSdCard("CONFIG.TXT"); 
}

// connect to WiFi now

Finally, make sure to use ssidString and passwordString in your WlanConnect().

Please tell me if this was helpful, and do not hesitate to ask further questions.

Kind regards,
Franjo

 

0 (0 투표)
RE: HttpExampleClient SD card
응답
18. 1. 29 오전 9:21 as a reply to Franjo Stjepandic.
/* own header files */
#include "XDKAppInfo.h"

#undef BCDS_MODULE_ID  /* Module ID define before including Basics package*/
#define BCDS_MODULE_ID XDK_APP_MODULE_ID_HTTP_EXAMPLE_CLIENT
#define DEFAULT_LOGICAL_DRIVE ""
#define DRIVE_ZERO UINT8_C(0)
#define FORCE_MOUNT UINT8_C(1)
#define FIRST_LOCATION UINT8_C(0)

/* own header files */
#include "HttpExampleClient.h"
#include "BCDS_CmdProcessor.h"
#include "BCDS_Assert.h"

/* system header files */
#include <stdio.h>

/* additional interface header files */
#include "BCDS_SDCard_Driver.h"
#include "ff.h"
#include "BCDS_WlanConnect.h"
#include "BCDS_NetworkConfig.h"
#include "BCDS_CmdProcessor.h"
#include <Serval_HttpClient.h>
#include <Serval_Network.h>
#include "PAL_socketMonitor_ih.h"
#include "PAL_initialize_ih.h"
#include "BCDS_LightSensor.h"
#include "XdkSensorHandle.h"
#include "FreeRTOS.h"
#include "timers.h"

/* constant definitions ***************************************************** */
#define DEFAULT_LOGICAL_DRIVE   ""
#define DRIVE_ZERO              UINT8_C(0)
#define FORCE_MOUNT             UINT8_C(1)
#define FIRST_LOCATION          UINT8_C(0)


/* local variables ********************************************************** */

/* global variables ********************************************************* */
static xTimerHandle connectTimerHandle; /**< variable to store timer handle*/
Ip_Address_T destAddr = UINT32_C(0);/*< variable to store the Ip address of the server */
static uint32_t intialOffset = UINT32_C(0); /* < variable to store the offset, the first byte to be received */
static uint32_t noOfBytesRecv = UINT32_C(512); /*< variable to store the number of bytes to receive */
static FIL fileObject; // file object pointer to be used for all file actions
char const *urlPtrReq = "/post.php?dump&html&dir=XDK"; /* URL string for the http website to post the payload*/
uint8_t payload[] = "XDK Testing"; /* payload to add to a request */
uint32_t tempData = UINT32_C(0);
uint32_t luxData = UINT32_C(0);
Accelerometer_XyzData_T aData = { INT32_C(0), INT32_C(0), INT32_C(0) };

/*Application Command Processor Instance */
CmdProcessor_T *AppCmdProcessor;

/* inline functions ********************************************************* */

/* local functions ********************************************************** */


//HTTP code starts

void InitSdCard(void){
  Retcode_T retVal = RETCODE_FAILURE;
  FRESULT FileSystemResult = FR_OK;
  static FATFS FatFileSystemObject;
  SDCardDriver_Initialize();
  if(SDCARD_INSERTED == SDCardDriver_GetDetectStatus()){
    retVal = SDCardDriver_DiskInitialize(DRIVE_ZERO);
    if(RETCODE_OK == retVal){
      printf("SD Card Disk initialize succeeded \n\r");
      FileSystemResult = f_mount(&FatFileSystemObject, DEFAULT_LOGICAL_DRIVE,
                                    FORCE_MOUNT);
      if (FR_OK != FileSystemResult){
        printf("Mounting SD card failed \n\r");
      }
    }
  }
}

Retcode_T searchForFileOnSdCard(const char* filename, FILINFO* fileData){
  if(FR_OK == f_stat(filename, fileData)){
    printf("File %s found on SD card. \n\r",filename);
    return RETCODE_OK;
  } else {
    printf("File %s does not exist. \n\r",filename);
    return RETCODE_FAILURE;
  }
}

char *ssidString;
char *passwordString

void createFileOnSdCard(const char* filename){
  if(FR_OK == f_open(&fileObject, filename, FA_OPEN_EXISTING | FA_READ)){ 
    f_gets(ramBufferRead,UINT16_C(512),&fileObject); ramBufferRead[strlen(ramBufferRead)-1] = '0'; 
    printf("Read first line from SD card %snr",ramBufferRead); strcpy(ssidString, ramBufferRead); 
    f_gets(ramBufferRead,UINT16_C(512),&fileObject); ramBufferRead[strlen(ramBufferRead)-2] = '1'; 
    printf("Read second line from SD card %snr",ramBufferRead); 
    strcpy(passwordString, ramBufferRead); 
    }
}

static retcode_t WlanConnect(void)
{
    NetworkConfig_IpSettings_T myIpSettings;
    char ipAddress[PAL_IP_ADDRESS_SIZE] = { 0 };
    Ip_Address_T* IpaddressHex = Ip_getMyIpAddr();
    WlanConnect_SSID_T connectSSID;
    WlanConnect_PassPhrase_T connectPassPhrase;
    Retcode_T ReturnValue = (Retcode_T) RETCODE_FAILURE;
    int32_t Result = INT32_C(-1);

    if (RETCODE_OK != WlanConnect_Init())
    {
        return (RC_PLATFORM_ERROR);
    }

    printf("Connecting to %s \r\n ", WLAN_CONNECT_WPA_SSID);

    connectSSID = (WlanConnect_SSID_T) WLAN_CONNECT_WPA_SSID;
    connectPassPhrase = (WlanConnect_PassPhrase_T) WLAN_CONNECT_WPA_PASS;
    ReturnValue = NetworkConfig_SetIpDhcp(NULL);
    if (RETCODE_OK != ReturnValue)
    {
        printf("Error in setting IP to DHCP \r\n");
        return (RC_PLATFORM_ERROR);
    }
    if (RETCODE_OK == WlanConnect_WPA(connectSSID, connectPassPhrase, NULL))
    {
        ReturnValue = NetworkConfig_GetIpSettings(&myIpSettings);
        if (RETCODE_OK == ReturnValue)
        {
            *IpaddressHex = Basics_htonl(myIpSettings.ipV4);
            Result = Ip_convertAddrToString(IpaddressHex, ipAddress);
            if (Result < 0)
            {
                printf("Couldn't convert the IP address to string format \r\n ");
                return (RC_PLATFORM_ERROR);
            }
            printf("Connected to WPA network successfully \r\n ");
            printf(" Ip address of the device %s \r\n ", ipAddress);
            return (RC_OK);
        }
        else
        {
            printf("Error in getting IP settings \r\n");
            return (RC_PLATFORM_ERROR);
        }
    }
    else
    {
        return (RC_PLATFORM_ERROR);
    }

}

static retcode_t CallbackOnSent(Callable_T *callfunc, retcode_t status)
{
    BCDS_UNUSED(callfunc);

    if (status != RC_OK)
    {
        //printf("error occurred in connecting server \r\n");
    }
    return (RC_OK);
}

static retcode_t CallbackOnRecv(Callable_T *callfunc, retcode_t status)
{
    BCDS_UNUSED(callfunc);

    if (status != RC_OK)
    {
        //printf("error occurred in connecting server \r\n");
    }
    else
    {
        printf("Post Request Sent \r\n");
    }
    return (RC_OK);
}

static retcode_t httpPayloadSerializer(
        OutMsgSerializationHandover_T *omsh_ptr)
{
    retcode_t rc = RC_OK;
    memcpy(omsh_ptr->buf_ptr, payload, strlen((char*) payload));
    omsh_ptr->len = strlen((char*) payload);

    return rc;
}

static retcode_t serializeMyHeaders(OutMsgSerializationHandover_T *omsh_ptr)
{
    retcode_t rc;
    omsh_ptr->len = 0;
    int n;
    static const char* myheader1 = "MyHeader: XDK\r\n";
    static const char* myheader2 = "MyOtherHeader: TestPurpose\r\n";

    switch (omsh_ptr->position)
    {
    case 0:
        n = strlen(myheader1);
        rc = TcpMsg_copyStaticContent(omsh_ptr, myheader1, n);
        if (rc != RC_OK)
            return rc;
        omsh_ptr->position = 1;
    case 1:
        n = strlen(myheader2);
        rc = TcpMsg_copyContentAtomic(omsh_ptr, myheader2, n);
        if (rc != RC_OK)
            return rc;
        omsh_ptr->position = 2;
    default:
        return RC_OK;
        break;
    }
}

static void PostContentOnWebpage(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);
    retcode_t rc = RC_OK;
    Msg_T* msg_ptr;
    Ip_Port_T destPort = (Ip_Port_T) DEST_PORT_NUMBER;
    static Callable_T RecvCallable;
    Callable_T * Callable_pointer;
    Callable_pointer = Callable_assign(&RecvCallable, CallbackOnRecv);
    if (Callable_pointer == NULL)
    {
        printf("Failed Callable_assign\r\n ");
        return;
    }
    rc = HttpClient_initRequest(&destAddr, Ip_convertIntToPort(destPort), &msg_ptr);

    if (rc != RC_OK || msg_ptr == NULL)
    {
        //printf("Failed HttpClient_initRequest \r\n ");
        return;
    }
    HttpMsg_serializeCustomHeaders(msg_ptr, serializeMyHeaders);
    HttpMsg_setReqMethod(msg_ptr, Http_Method_Post);

    rc = HttpMsg_setReqUrl(msg_ptr, urlPtrReq);
    if (rc != RC_OK)
    {
        printf("Failed to fill message \r\n ");
        return;
    }

    /* set content type and payload */
    HttpMsg_setContentType(msg_ptr, Http_ContentType_Text_Plain);

    rc = Msg_prependPartFactory(msg_ptr, &httpPayloadSerializer);
    if (RC_OK == rc)
    {
        rc = HttpClient_pushRequest(msg_ptr, &RecvCallable,
        NULL);
        if (rc != RC_OK)
        {
            printf("Failed HttpClient_pushRequest \r\n  ");
            return;
        }
    }
    if (rc != RC_OK)
    {
        printf("Failed to Fill the payload on payloadSerializer \r\n  ");
        return;
    }
}

static retcode_t HttpClientResponseCallback(HttpSession_T *httpSession,
        Msg_T *msg_ptr, retcode_t status)
{
    BCDS_UNUSED(httpSession);
    retcode_t rc = status;
    uint32_t pageContentSize; /* total length of the content at the server */
    bool flag = false; /* flag to set to true if this is the last piece of the message */
    Retcode_T returnValue = RETCODE_OK;
    if (rc != RC_OK)
    {
        /* Error occurred in downloading the page */
        printf("error occurred in downloading HTML \r\n");
    }
    else if (msg_ptr == NULL)
    {
        rc = RC_HTTP_PARSER_INVALID_CONTENT_TYPE;
    }
    else
    {
        rc = HttpMsg_getRange(msg_ptr, UINT32_C(0), &pageContentSize, &flag);
        if (rc != RC_OK)
        {
            printf("Failed to Get Range \r\n ");
        }
        else
        {
            if (HttpMsg_getContentType(msg_ptr) != Http_ContentType_Text_Html)
            {
                rc = RC_HTTP_INVALID_RESPONSE;
            }
            else
            {
                char const *content_ptr = "";
                unsigned int len = UINT32_C(0);
                HttpMsg_getContent(msg_ptr, &content_ptr, &len);
                printf("GET Response Content %s \r\n", content_ptr);
                intialOffset += (len);
                /* Clear the Content Buffer */
                memset(content_ptr, UINT32_C(0), len);
                /* check if this is the last piece of the message. This parameter will also be true if the message is not fragmented.*/
/*                if (flag == true)
                {
                    printf("Page content %lu Bytes Download Completed \r\n", pageContentSize);
                    if (xTimerStop(connectTimerHandle, 0) != pdTRUE)
                    {
                        assert(false);
                    }
                    /* En-queuing to application command processor to post the content on Http page */
/*                    returnValue = CmdProcessor_enqueue(AppCmdProcessor, PostContentOnWebpage, NULL, UINT32_C(0));
                    if (RETCODE_OK != returnValue)
                    {
                        printf("En-queuing to application command processor failed \r\n");
                    }
                } */
            }
        }
    }

    if (rc != RC_OK)
    {
        printf("error occurred in downloading HTML \r\n");
    }
    return (rc);
}

/* global functions ********************************************************** */

static void initSensor(void)
{
    Retcode_T returnValue = RETCODE_FAILURE;
    returnValue = Environmental_init(xdkEnvironmental_BME280_Handle);
    returnValue = LightSensor_init(xdkLightSensor_MAX44009_Handle);
    if(RETCODE_OK != returnValue)
    {
        //printf("Light Sensor initialization Failed\n\r");
    }
}

static void readSensor(xTimerHandle xTimer)
{
    (void) xTimer;

    //uint32_t milliLuxData = UINT32_C(0);
    Retcode_T returnValue = RETCODE_FAILURE;

    returnValue = Environmental_readTemperature(xdkEnvironmental_BME280_Handle,
            &tempData);
    returnValue = LightSensor_readLuxData(xdkLightSensor_MAX44009_Handle,
                &luxData);

    if(RETCODE_OK == returnValue)
    {
        //printf("Light sensor data obtained in milli lux: %d \n\r",(unsigned int) milliLuxData);
    }
}

static void PrintWebpageContent(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);
    retcode_t rc = RC_OK;
    Msg_T* msg_ptr;
    Ip_Port_T destPort = (Ip_Port_T) DEST_PORT_NUMBER;
    static Callable_T SentCallable;
    const char url_ptr[100]; /* URL string for the http website */
    int n = sprintf(url_ptr,"/bothinsert.php?tempData=%d&luxData=%d",tempData/1000, luxData/1000);
    Callable_T * Callable_pointer;
    Callable_pointer = Callable_assign(&SentCallable, CallbackOnSent);
    if (Callable_pointer == NULL)
    {
        printf("Failed Callable_assign\r\n ");
        return;
    }
    rc = HttpClient_initRequest(&destAddr, Ip_convertIntToPort(destPort), &msg_ptr);

    if (rc != RC_OK || msg_ptr == NULL)
    {
        //printf("Failed HttpClient_initRequest \r\n ");
        return;
    }
    HttpMsg_setRange(msg_ptr, intialOffset, noOfBytesRecv);
    HttpMsg_setReqMethod(msg_ptr, Http_Method_Get);
    rc = HttpMsg_setReqUrl(msg_ptr, url_ptr);
    if (rc != RC_OK)
    {
        printf("Failed to fill message \r\n ");
        return;
    }

    rc = HttpClient_pushRequest(msg_ptr, &SentCallable,
            HttpClientResponseCallback);
    if (rc != RC_OK)
    {
        printf("Failed HttpClient_pushRequest \r\n  ");
        return;
    }
}

static void ConnectServer(xTimerHandle xTimer)
{
    BCDS_UNUSED(xTimer);
    Retcode_T returnValue = RETCODE_OK;

    returnValue = CmdProcessor_enqueue(AppCmdProcessor, PrintWebpageContent, NULL, UINT32_C(0));
    if (RETCODE_OK != returnValue)
    {
        printf("En-queuing to application command processor failed \r\n");
    }
}

/* The description is in the interface header file. */
static void Init(void)
{
    retcode_t rc = RC_OK;

    rc = WlanConnect();
    if (RC_OK != rc)
    {
        printf("Network init/connection failed %i \r\n", rc);
        return;
    }

    rc = PAL_initialize();
    if (RC_OK != rc)
    {
        printf("PAL and network initialize %i \r\n", rc);
        return;
    }

    PAL_socketMonitorInit();

    /* start client */
    rc = HttpClient_initialize();
    if (rc != RC_OK)
    {
        printf("Failed to initialize http client \r\n ");
        return;
    }

    if (RC_OK != PAL_getIpaddress((uint8_t*) "192.168.43.74", &destAddr))
    {
        return;
    }

    else
    {
        uint32_t Ticks = 2500;

/*        if (Ticks != UINT32_MAX) /* Validated for portMAX_DELAY to assist the task to wait Infinitely (without timing out) */
/*        {
            Ticks /= portTICK_RATE_MS;
        }
        if (UINT32_C(0) == Ticks) /* ticks cannot be 0 in FreeRTOS timer. So ticks is assigned to 1 */
/*        {
            Ticks = UINT32_C(1);
        }
        /* Timer to Get Content from the connected server */
        connectTimerHandle = xTimerCreate((const char * const ) "ConnectServer", Ticks,TIMER_AUTORELOAD_ON, NULL, ConnectServer);
        if (connectTimerHandle != NULL)
        {
            if (xTimerStart(connectTimerHandle, TIMERBLOCKTIME) != pdTRUE)
            {
                assert(false);
            }
            else
            {
                printf("Started the timer successfully \r\n ");
            }

        }
    }
}

void appInitSystem(void * CmdProcessorHandle, uint32_t param2)
// before connecting to WiFi
// connect to WiFi now
{
    InitSdCard();

    if (RETCODE_OK == searchForFileOnSdCard("CONFIG.TXT", NULL))
    {
        createFileOnSdCard("CONFIG.TXT");
    }


    if (CmdProcessorHandle == NULL)
    {
        printf("Command processor handle is null \n\r");
        assert(false);
    }
    BCDS_UNUSED(param2);
    uint32_t timerBlockTime = UINT32_MAX;
    uint32_t OneSecondDelay = UINT32_C(2500);
    uint32_t timerAutoReloadOn = pdTRUE;

    xTimerHandle SensorHandle= NULL;

    initSensor();

    SensorHandle = xTimerCreate((const char *) "readTempSensor", OneSecondDelay, timerAutoReloadOn, NULL, readSensor);

    xTimerStart(SensorHandle,timerBlockTime);

    AppCmdProcessor = (CmdProcessor_T *) CmdProcessorHandle;
    BCDS_UNUSED(param2);
    /*Call the RHC init API */
    Init();

}

I have also taken the liberty to add the declarations for ssidString and passwordString. You should put those declarations somewhere near the top of your code.

Hi there. How do I do the declarations? Is it the #include ssidString and #include passwordString ? 

 

Finally, make sure to use ssidString and passwordString in your WlanConnect().

Does this mean I change every single connectSSID and connectPassPhrase ? The whole code? 

 

Also, I am getting some building errors too from this, and this is the error Makefile:34: recipe for target 'debug' failed
mingw32-make: *** [debug] Error 2

I also realised that I need to change my wifi configurations in header file right? The SSID and password, etc. What do I change it to? 

#ifndef XDK110_HTTPEXAMPLECLIENT_H_
#define XDK110_HTTPEXAMPLECLIENT_H_


#include "BCDS_Basics.h"


#define CONNECT_TIME_INTERVAL           UINT32_C(10000)         /**< Macro to represent connect time interval */
#define TIMERBLOCKTIME                  UINT32_C(0xffff)        /**< Macro used to define blocktime of a timer*/
#define TIMER_AUTORELOAD_ON             UINT32_C(1)             /**< Auto reload of timer is enabled*/
#warning Please enter WLAN configurations with valid SSID & WPA key in below Macros and remove this line to avoid warnings.
#define WLAN_CONNECT_WPA_SSID           "Danial's S8 Plus"          /**< Macros to define WPA/WPA2 network settings */
#define WLAN_CONNECT_WPA_PASS           "helloboys"       /**< Macros to define WPA/WPA2 network settings */
#define DEST_PORT_NUMBER        		UINT16_C(80)            /**< Macro to define the unsecure Server Port number */

/* Will be used after encryption
 * #define DEST_SERVER_ADDRESS 			"www.xdk.bosch-connectivity.com"
 */


void appInitSystem(void * CmdProcessorHandle, uint32_t param2);

#endif 


Attached above is my c whereas next is my h file. Do let me know on the changes I need to make as I am receiving compilation errors to it too now.


Thanks and great day ahead!


Danial

 

+1 (1 투표)
RE: HttpExampleClient SD card
응답
18. 1. 29 오후 1:01 as a reply to Danial Rohmat.

Hello Danial,

I made a mistake in the code last week.

The following is the correct code for reading the SSID and PW.

char *ssidString;
char *passwordString;

void createFileOnSdCard(const char* filename){
    if(FR_OK == f_open(&fileObject, filename, FA_OPEN_EXISTING | FA_READ)){ 
        f_gets(ramBufferRead,UINT16_C(512),&fileObject); 
        ramBufferRead[strlen(ramBufferRead)-1] = '0'; 
        printf("Read first line from SD card %s\n\r",ramBufferRead); 
        strcpy(ssidString, ramBufferRead); 
        f_gets(ramBufferRead,UINT16_C(512),&fileObject); 
        ramBufferRead[strlen(ramBufferRead)-1] = '0'; 
        printf("Read second line from SD card %s\n\r",ramBufferRead); 
        strcpy(passwordString, ramBufferRead); 
    }
}

It was missing a semi-colon before, backslashes in the strings, and setting the last character of the strings was wrong for the SSID, as well. It should be correct now, and it will not throw errors most likely.

Regarding your questions, first:

How do I do the declarations? Is it the #include ssidString and #include passwordString ?

Since the declarations are already correct, and they are near the top of the code, you do not have to move them again. Let them stay where they are.

Does this mean I change every single connectSSID and connectPassPhrase ? The whole code?

Since the entire intention was to load the configuration from the SD card, yes, I recommend that you replace every single connectSSID and connectPassPhrase with ssidString and passwordString respectively.

Also, if you receive a compilation error, I would appreciate that you do post the errors here. The building error you posted is only indicating that the building process failed. If you scroll up, you may find other errors. They are always marked red. Also, please try to only copy the code that is throwing errors or code where you made changes.

Please tell me if this was helpful, and do not hesitate to ask further questions.

Kind regards,
Franjo

+1 (1 투표)
RE: HttpExampleClient SD card
응답
18. 1. 29 오후 1:41 as a reply to Franjo Stjepandic.

Hi there.

I am still having errors. I have done what you've told me to do including changing the ssidString etc.. I have also attached two screenshots of all the errors in the image, so feel free to take a look at it. One of them is due to me leaving the header file SSID and PASSWORD as ssidString and passwordString respectively. The rest of the errors are shown in the image.

Please do let me know and guide me on what to do to prevent this errors from occuring. Thanks and good day ahead!

Danial

0 (0 투표)
RE: HttpExampleClient SD card
응답
18. 1. 29 오후 4:56 as a reply to Danial Rohmat.

Hello Danial,

there is one error message, indicating that ramBufferRead is not declared.

Put the following line of code near the top of your implementation file.

char ramBufferRead[512];

This will resolve that issue. Please review your screenshots. You will find one line marked red in the first image. It is always good to learn from issues and to understand how and why they are solved.

Please tell me if this was helpful, and do not hesitate to ask further questions.

Kind regards,
Franjo

 

+1 (1 투표)
RE: HttpExampleClient SD card
응답
18. 1. 30 오후 12:46 as a reply to Franjo Stjepandic.

Hi there.

Thanks so much for the prompt help. I can compile and build it, and flashed it into the XDK 110. But now there is another problem. The old wifi can somehow be connected from the XDK to the network, and it seems like the data is not being read from SD card as I cannot connect to the network on the SD card, but it auto connects to my "old" network that I had used before. I have already changed the header file SSID etc to what you can see in the picture attached below, but I am also receiving the network error as shown. Does this have to do with the format of the SSID and Password in the SD card? Attached below are both the pictures of the error in workbench, header file, and also the SD card format. 

Thanks and hope to hear real soon!

Best wishes
Danial

0 (0 투표)
RE: HttpExampleClient SD card
응답
18. 1. 30 오후 7:00 as a reply to Danial Rohmat.
Hello Danial,

I am glad to hear that you were finally able to build the project. Regarding your new error, the structure in the CONFIG file of your SD card is currently incorrect.

It should be as follows:
 
PredatorInstinct (2.4GHz)
fbj5114x


This is necessary because the code snippet I provided to you is only able to read entire lines from a config file on the SD card. It does not extract the SSID actual from the string "mySSID = PredatorInstinct (2.4GHz)" . The same behaviour applies for the passphrase.

Furthermore, I assume that the print you received in the console indicates that the content of the SD card was not read properly.

Additionally, I recommend inserting the function call vTaskDelay(5000); before calling the function InitSdCard() , so you can actually see the other prints.

Please let me know if that was helpful and feel free to ask if you have further questions.

Kind regards,
Franjo
0 (0 투표)
RE: HttpExampleClient SD card
응답
18. 1. 30 오후 7:47 as a reply to Franjo Stjepandic.

Hi there. 

Tried it out; same issue, same problem, same results. The network init/connection failed 386. Tried to connect it to 4 different routers with different names, still failed. Cleaned the whole program, added XDK Nature, build, reimported, repasted most of the codes, changed what is needed, all have been done again by me. But, I think there is a problem with my code and if you don't mind, can you do let me know what is the issue? Do go through my c file code and let me know if there are errors.

I am still not able to make the XDK read the SD card wifi settings and connect from there without flashing for the second time to change SSID etc. I also have a feeling it's the import of the SDCardExample which I did was kind of wrong. But I can't be sure of this as I've tried to re import it and still same error. I will attach my latest source code on here for the last time, just for your reference on spotting the mistakes that I did.

Do help me out and hope to hear real soon!

Danial

 

/* own header files */
#include "XDKAppInfo.h"

#undef BCDS_MODULE_ID  /* Module ID define before including Basics package*/
#define BCDS_MODULE_ID XDK_APP_MODULE_ID_HTTP_EXAMPLE_CLIENT
#define DEFAULT_LOGICAL_DRIVE ""
#define DRIVE_ZERO UINT8_C(0)
#define FORCE_MOUNT UINT8_C(1)
#define FIRST_LOCATION UINT8_C(0)

/* own header files */
#include "HttpExampleClient.h"
#include "BCDS_CmdProcessor.h"
#include "BCDS_Assert.h"

/* system header files */
#include <stdio.h>

/* additional interface header files */
#include "BCDS_SDCard_Driver.h"
#include "ff.h"
#include "BCDS_WlanConnect.h"
#include "BCDS_NetworkConfig.h"
#include "BCDS_CmdProcessor.h"
#include <Serval_HttpClient.h>
#include <Serval_Network.h>
#include "PAL_socketMonitor_ih.h"
#include "PAL_initialize_ih.h"
#include "BCDS_LightSensor.h"
#include "XdkSensorHandle.h"
#include "FreeRTOS.h"
#include "timers.h"

/* constant definitions ***************************************************** */
#define DEFAULT_LOGICAL_DRIVE   ""
#define DRIVE_ZERO              UINT8_C(0)
#define FORCE_MOUNT             UINT8_C(1)
#define FIRST_LOCATION          UINT8_C(0)


/* local variables ********************************************************** */

/* global variables ********************************************************* */
static xTimerHandle connectTimerHandle; /**< variable to store timer handle*/
Ip_Address_T destAddr = UINT32_C(0);/*< variable to store the Ip address of the server */
static uint32_t intialOffset = UINT32_C(0); /* < variable to store the offset, the first byte to be received */
static uint32_t noOfBytesRecv = UINT32_C(512); /*< variable to store the number of bytes to receive */
static FIL fileObject; // file object pointer to be used for all file actions
char const *urlPtrReq = "/post.php?dump&html&dir=XDK"; /* URL string for the http website to post the payload*/
uint8_t payload[] = "XDK Testing"; /* payload to add to a request */
uint32_t tempData = UINT32_C(0);
uint32_t luxData = UINT32_C(0);
Accelerometer_XyzData_T aData = { INT32_C(0), INT32_C(0), INT32_C(0) };

/*Application Command Processor Instance */
CmdProcessor_T *AppCmdProcessor;

/* inline functions ********************************************************* */

/* local functions ********************************************************** */


//HTTP code starts

void InitSdCard(void){
  Retcode_T retVal = RETCODE_FAILURE;
  FRESULT FileSystemResult = FR_OK;
  static FATFS FatFileSystemObject;
  SDCardDriver_Initialize();
  if(SDCARD_INSERTED == SDCardDriver_GetDetectStatus()){
    retVal = SDCardDriver_DiskInitialize(DRIVE_ZERO);
    if(RETCODE_OK == retVal){
      printf("SD Card Disk initialize succeeded \n\r");
      FileSystemResult = f_mount(&FatFileSystemObject, DEFAULT_LOGICAL_DRIVE,
                                    FORCE_MOUNT);
      if (FR_OK != FileSystemResult){
        printf("Mounting SD card failed \n\r");
      }
    }
  }
}

Retcode_T searchForFileOnSdCard(const char* filename, FILINFO* fileData){
  if(FR_OK == f_stat(filename, fileData)){
    printf("File %s found on SD card. \n\r",filename);
    return RETCODE_OK;
  } else {
    printf("File %s does not exist. \n\r",filename);
    return RETCODE_FAILURE;
  }
}

char *ssidString;
char *passwordString;
char ramBufferRead[512];

void createFileOnSdCard(const char* filename){
    if(FR_OK == f_open(&fileObject, filename, FA_OPEN_EXISTING | FA_READ)){
        f_gets(ramBufferRead,UINT16_C(512),&fileObject);
        ramBufferRead[strlen(ramBufferRead)-1] = '0';
        printf("Read first line from SD card %s\n\r",ramBufferRead);
        strcpy(ssidString, ramBufferRead);
        f_gets(ramBufferRead,UINT16_C(512),&fileObject);
        ramBufferRead[strlen(ramBufferRead)-1] = '0';
        printf("Read second line from SD card %s\n\r",ramBufferRead);
        strcpy(passwordString, ramBufferRead);
    }
}

static retcode_t WlanConnect(void)
{
    NetworkConfig_IpSettings_T myIpSettings;
    char ipAddress[PAL_IP_ADDRESS_SIZE] = { 0 };
    Ip_Address_T* IpaddressHex = Ip_getMyIpAddr();
    WlanConnect_SSID_T ssidString;
    WlanConnect_PassPhrase_T passwordString;
    Retcode_T ReturnValue = (Retcode_T) RETCODE_FAILURE;
    int32_t Result = INT32_C(-1);

    if (RETCODE_OK != WlanConnect_Init())
    {
        return (RC_PLATFORM_ERROR);
    }

    printf("Connecting to %s \r\n ", WLAN_CONNECT_WPA_SSID);

    ssidString = (WlanConnect_SSID_T) WLAN_CONNECT_WPA_SSID;
    passwordString = (WlanConnect_PassPhrase_T) WLAN_CONNECT_WPA_PASS;
    ReturnValue = NetworkConfig_SetIpDhcp(NULL);
    if (RETCODE_OK != ReturnValue)
    {
        printf("Error in setting IP to DHCP \r\n");
        return (RC_PLATFORM_ERROR);
    }
    if (RETCODE_OK == WlanConnect_WPA(ssidString, passwordString, NULL))
    {
        ReturnValue = NetworkConfig_GetIpSettings(&myIpSettings);
        if (RETCODE_OK == ReturnValue)
        {
            *IpaddressHex = Basics_htonl(myIpSettings.ipV4);
            Result = Ip_convertAddrToString(IpaddressHex, ipAddress);
            if (Result < 0)
            {
                printf("Couldn't convert the IP address to string format \r\n ");
                return (RC_PLATFORM_ERROR);
            }
            printf("Connected to WPA network successfully \r\n ");
            printf(" Ip address of the device %s \r\n ", ipAddress);
            return (RC_OK);
        }
        else
        {
            printf("Error in getting IP settings \r\n");
            return (RC_PLATFORM_ERROR);
        }
    }
    else
    {
        return (RC_PLATFORM_ERROR);
    }

}

static retcode_t CallbackOnSent(Callable_T *callfunc, retcode_t status)
{
    BCDS_UNUSED(callfunc);

    if (status != RC_OK)
    {
        //printf("error occurred in connecting server \r\n");
    }
    return (RC_OK);
}

static retcode_t CallbackOnRecv(Callable_T *callfunc, retcode_t status)
{
    BCDS_UNUSED(callfunc);

    if (status != RC_OK)
    {
        //printf("error occurred in connecting server \r\n");
    }
    else
    {
        printf("Post Request Sent \r\n");
    }
    return (RC_OK);
}

static retcode_t httpPayloadSerializer(
        OutMsgSerializationHandover_T *omsh_ptr)
{
    retcode_t rc = RC_OK;
    memcpy(omsh_ptr->buf_ptr, payload, strlen((char*) payload));
    omsh_ptr->len = strlen((char*) payload);

    return rc;
}

static retcode_t serializeMyHeaders(OutMsgSerializationHandover_T *omsh_ptr)
{
    retcode_t rc;
    omsh_ptr->len = 0;
    int n;
    static const char* myheader1 = "MyHeader: XDK\r\n";
    static const char* myheader2 = "MyOtherHeader: TestPurpose\r\n";

    switch (omsh_ptr->position)
    {
    case 0:
        n = strlen(myheader1);
        rc = TcpMsg_copyStaticContent(omsh_ptr, myheader1, n);
        if (rc != RC_OK)
            return rc;
        omsh_ptr->position = 1;
    case 1:
        n = strlen(myheader2);
        rc = TcpMsg_copyContentAtomic(omsh_ptr, myheader2, n);
        if (rc != RC_OK)
            return rc;
        omsh_ptr->position = 2;
    default:
        return RC_OK;
        break;
    }
}

static void PostContentOnWebpage(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);
    retcode_t rc = RC_OK;
    Msg_T* msg_ptr;
    Ip_Port_T destPort = (Ip_Port_T) DEST_PORT_NUMBER;
    static Callable_T RecvCallable;
    Callable_T * Callable_pointer;
    Callable_pointer = Callable_assign(&RecvCallable, CallbackOnRecv);
    if (Callable_pointer == NULL)
    {
        printf("Failed Callable_assign\r\n ");
        return;
    }
    rc = HttpClient_initRequest(&destAddr, Ip_convertIntToPort(destPort), &msg_ptr);

    if (rc != RC_OK || msg_ptr == NULL)
    {
        //printf("Failed HttpClient_initRequest \r\n ");
        return;
    }
    HttpMsg_serializeCustomHeaders(msg_ptr, serializeMyHeaders);
    HttpMsg_setReqMethod(msg_ptr, Http_Method_Post);

    rc = HttpMsg_setReqUrl(msg_ptr, urlPtrReq);
    if (rc != RC_OK)
    {
        printf("Failed to fill message \r\n ");
        return;
    }

    /* set content type and payload */
    HttpMsg_setContentType(msg_ptr, Http_ContentType_Text_Plain);

    rc = Msg_prependPartFactory(msg_ptr, &httpPayloadSerializer);
    if (RC_OK == rc)
    {
        rc = HttpClient_pushRequest(msg_ptr, &RecvCallable,
        NULL);
        if (rc != RC_OK)
        {
            printf("Failed HttpClient_pushRequest \r\n  ");
            return;
        }
    }
    if (rc != RC_OK)
    {
        printf("Failed to Fill the payload on payloadSerializer \r\n  ");
        return;
    }
}

static retcode_t HttpClientResponseCallback(HttpSession_T *httpSession,
        Msg_T *msg_ptr, retcode_t status)
{
    BCDS_UNUSED(httpSession);
    retcode_t rc = status;
    uint32_t pageContentSize; /* total length of the content at the server */
    bool flag = false; /* flag to set to true if this is the last piece of the message */
    Retcode_T returnValue = RETCODE_OK;
    if (rc != RC_OK)
    {
        /* Error occurred in downloading the page */
        printf("error occurred in downloading HTML \r\n");
    }
    else if (msg_ptr == NULL)
    {
        rc = RC_HTTP_PARSER_INVALID_CONTENT_TYPE;
    }
    else
    {
        rc = HttpMsg_getRange(msg_ptr, UINT32_C(0), &pageContentSize, &flag);
        if (rc != RC_OK)
        {
            printf("Failed to Get Range \r\n ");
        }
        else
        {
            if (HttpMsg_getContentType(msg_ptr) != Http_ContentType_Text_Html)
            {
                rc = RC_HTTP_INVALID_RESPONSE;
            }
            else
            {
                char const *content_ptr = "";
                unsigned int len = UINT32_C(0);
                HttpMsg_getContent(msg_ptr, &content_ptr, &len);
                printf("GET Response Content %s \r\n", content_ptr);
                intialOffset += (len);
                /* Clear the Content Buffer */
                memset(content_ptr, UINT32_C(0), len);
                /* check if this is the last piece of the message. This parameter will also be true if the message is not fragmented.*/
/*                if (flag == true)
                {
                    printf("Page content %lu Bytes Download Completed \r\n", pageContentSize);
                    if (xTimerStop(connectTimerHandle, 0) != pdTRUE)
                    {
                        assert(false);
                    }
                    /* En-queuing to application command processor to post the content on Http page */
/*                    returnValue = CmdProcessor_enqueue(AppCmdProcessor, PostContentOnWebpage, NULL, UINT32_C(0));
                    if (RETCODE_OK != returnValue)
                    {
                        printf("En-queuing to application command processor failed \r\n");
                    }
                } */
            }
        }
    }

    if (rc != RC_OK)
    {
        printf("error occurred in downloading HTML \r\n");
    }
    return (rc);
}

/* global functions ********************************************************** */

static void initSensor(void)
{
    Retcode_T returnValue = RETCODE_FAILURE;
    returnValue = Environmental_init(xdkEnvironmental_BME280_Handle);
    returnValue = LightSensor_init(xdkLightSensor_MAX44009_Handle);
    if(RETCODE_OK != returnValue)
    {
        //printf("Light Sensor initialization Failed\n\r");
    }
}

static void readSensor(xTimerHandle xTimer)
{
    (void) xTimer;

    //uint32_t milliLuxData = UINT32_C(0);
    Retcode_T returnValue = RETCODE_FAILURE;

    returnValue = Environmental_readTemperature(xdkEnvironmental_BME280_Handle,
            &tempData);
    returnValue = LightSensor_readLuxData(xdkLightSensor_MAX44009_Handle,
                &luxData);

    if(RETCODE_OK == returnValue)
    {
        //printf("Light sensor data obtained in milli lux: %d \n\r",(unsigned int) milliLuxData);
    }
}

static void PrintWebpageContent(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);
    retcode_t rc = RC_OK;
    Msg_T* msg_ptr;
    Ip_Port_T destPort = (Ip_Port_T) DEST_PORT_NUMBER;
    static Callable_T SentCallable;
    const char url_ptr[100]; /* URL string for the http website */
    int n = sprintf(url_ptr,"/bothinsert.php?tempData=%d&luxData=%d",tempData/1000, luxData/1000);
    Callable_T * Callable_pointer;
    Callable_pointer = Callable_assign(&SentCallable, CallbackOnSent);
    if (Callable_pointer == NULL)
    {
        printf("Failed Callable_assign\r\n ");
        return;
    }
    rc = HttpClient_initRequest(&destAddr, Ip_convertIntToPort(destPort), &msg_ptr);

    if (rc != RC_OK || msg_ptr == NULL)
    {
        //printf("Failed HttpClient_initRequest \r\n ");
        return;
    }
    HttpMsg_setRange(msg_ptr, intialOffset, noOfBytesRecv);
    HttpMsg_setReqMethod(msg_ptr, Http_Method_Get);
    rc = HttpMsg_setReqUrl(msg_ptr, url_ptr);
    if (rc != RC_OK)
    {
        printf("Failed to fill message \r\n ");
        return;
    }

    rc = HttpClient_pushRequest(msg_ptr, &SentCallable,
            HttpClientResponseCallback);
    if (rc != RC_OK)
    {
        printf("Failed HttpClient_pushRequest \r\n  ");
        return;
    }
}

static void ConnectServer(xTimerHandle xTimer)
{
    BCDS_UNUSED(xTimer);
    Retcode_T returnValue = RETCODE_OK;

    returnValue = CmdProcessor_enqueue(AppCmdProcessor, PrintWebpageContent, NULL, UINT32_C(0));
    if (RETCODE_OK != returnValue)
    {
        printf("En-queuing to application command processor failed \r\n");
    }
}

/* The description is in the interface header file. */
static void Init(void)
{
    retcode_t rc = RC_OK;

    rc = WlanConnect();
    if (RC_OK != rc)
    {
        printf("Network init/connection failed %i \r\n", rc);
        return;
    }

    rc = PAL_initialize();
    if (RC_OK != rc)
    {
        printf("PAL and network initialize %i \r\n", rc);
        return;
    }

    PAL_socketMonitorInit();

    /* start client */
    rc = HttpClient_initialize();
    if (rc != RC_OK)
    {
        printf("Failed to initialize http client \r\n ");
        return;
    }

    if (RC_OK != PAL_getIpaddress((uint8_t*) "192.168.43.74", &destAddr))
    {
        return;
    }

    else
    {
        uint32_t Ticks = 2500;

/*        if (Ticks != UINT32_MAX) /* Validated for portMAX_DELAY to assist the task to wait Infinitely (without timing out) */
/*        {
            Ticks /= portTICK_RATE_MS;
        }
        if (UINT32_C(0) == Ticks) /* ticks cannot be 0 in FreeRTOS timer. So ticks is assigned to 1 */
/*        {
            Ticks = UINT32_C(1);
        }
        /* Timer to Get Content from the connected server */
        connectTimerHandle = xTimerCreate((const char * const ) "ConnectServer", Ticks,TIMER_AUTORELOAD_ON, NULL, ConnectServer);
        if (connectTimerHandle != NULL)
        {
            if (xTimerStart(connectTimerHandle, TIMERBLOCKTIME) != pdTRUE)
            {
                assert(false);
            }
            else
            {
                printf("Started the timer successfully \r\n ");
            }

        }
    }
}

void appInitSystem(void * CmdProcessorHandle, uint32_t param2)
// before connecting to WiFi
// connect to WiFi now

{
    InitSdCard();

    if (RETCODE_OK == searchForFileOnSdCard("CONFIG.TXT", NULL))
    {
        createFileOnSdCard("CONFIG.TXT");
    }


    if (CmdProcessorHandle == NULL)
    {
        printf("Command processor handle is null \n\r");
        assert(false);
    }
    BCDS_UNUSED(param2);
    uint32_t timerBlockTime = UINT32_MAX;
    uint32_t OneSecondDelay = UINT32_C(2500);
    uint32_t timerAutoReloadOn = pdTRUE;

    xTimerHandle SensorHandle= NULL;

    initSensor();

    SensorHandle = xTimerCreate((const char *) "readTempSensor", OneSecondDelay, timerAutoReloadOn, NULL, readSensor);

    xTimerStart(SensorHandle,timerBlockTime);

    AppCmdProcessor = (CmdProcessor_T *) CmdProcessorHandle;
    BCDS_UNUSED(param2);
    /*Call the RHC init API */
    Init();

}

 

0 (0 투표)
RE: HttpExampleClient SD card
응답
18. 1. 31 오후 4:32 as a reply to Danial Rohmat.

Hello Danial,

as I mentioned in my last post, I recommend adding vTaskDelay(5000); to the beginning of your appInitSystem(), so the messages printed during initialization of the SD card can be seen in the console.

Furthermore, I tried your code out, too, and found a couple of things. You named the local variables in WlanConnect() for the ssid and the passphrase ssidString and passwordString. Since setting WLAN_CONNECT_WPA_SSID and WLAN_CONNECT_WPA_PASS to ssidString and passwordString only works as a textual exchange, the content of your renamed local variables is used instead of the content of the global variables.

Therefore, I recommend leaving the names of the local variables connectSSID and connectPassPhrase.

Additionally, there was a small mistake in the declaration of the global variables, which hold the content of the read config file of the SD card.

These were previously declared as pointers with no allocated memory space, but need to be declared a arrays with a fixed size.

The following code should solve that issue.

char ssidString[128];

char passwordString[128];

char ramBufferRead[128];

void createFileOnSdCard(const char* filename){

   if(FR_OK == f_open(&fileObject, filename, FA_OPEN_EXISTING | FA_READ)){

        f_gets(ramBufferRead,UINT16_C(512),&fileObject);

        ramBufferRead[strlen(ramBufferRead)-1] = 0;

        printf("Read first line from SD card %s\n\r",ramBufferRead);

        sprintf(ssidString, "%s", ramBufferRead);

        f_gets(ramBufferRead,UINT16_C(512),&fileObject);

        ramBufferRead[strlen(ramBufferRead)-1] = 0;

        printf("Read second line from SD card %s\n\r",ramBufferRead);

        sprintf(passwordString, "%s", ramBufferRead);

        printf("%s\n\r", passwordString);

    }

}

 

Please note that you need to exchange this code with the existing declarations in your implementation file to make it work.

Additionally, some hints regarding your error search and workarounds.

Trying to connect the XDK one different Wi-Fi networks was a good start to narrow down were the error could be located. Cleaning the project would also sometimes help to get rid of corrupted binaries.

Adding XDK nature in this case will not make any sense. It is only necessary if you try to port and flash an application, which was build for bootloader versions beneath 1.1.0, to the XDK.

Reimporting and recoding may be a shot into the blue, because then you are still not aware about what actually causes your application not to work and how to solve the error.

For your case here, carefully reading the console log, especially the error marked in red, or the content which is printed from the XDK to the XDK-Workbench's console.

Please tell me if this was helpful and do not hesitate to ask further questions.

Kind regards,
Franjo

0 (0 투표)