diff options
| author | Yuval Adam <yuv.adm@gmail.com> | 2014-06-29 12:34:32 +0300 |
|---|---|---|
| committer | Yuval Adam <yuv.adm@gmail.com> | 2014-06-29 12:34:32 +0300 |
| commit | c3e4c9a25c2910d2d66d52215b3406b13d5b23d5 (patch) | |
| tree | added370d1e356901f8579f076e3263fb0464db7 /boards/dk-tm4c129x/qs_weather/json.c | |
| parent | 990090a4cc9070837d31e66b58d40f0c3d038741 (diff) | |
Add more board models
Diffstat (limited to 'boards/dk-tm4c129x/qs_weather/json.c')
| -rw-r--r-- | boards/dk-tm4c129x/qs_weather/json.c | 843 |
1 files changed, 843 insertions, 0 deletions
diff --git a/boards/dk-tm4c129x/qs_weather/json.c b/boards/dk-tm4c129x/qs_weather/json.c new file mode 100644 index 0000000..1f71bc7 --- /dev/null +++ b/boards/dk-tm4c129x/qs_weather/json.c @@ -0,0 +1,843 @@ +//*****************************************************************************
+//
+// json.c - File to handle json formatted data from websites.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the DK-TM4C129X Firmware Package.
+//
+//*****************************************************************************
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "utils/ustdlib.h"
+#include "utils/lwiplib.h"
+#include "eth_client.h"
+#include "json.h"
+#include "images.h"
+
+//****************************************************************************
+//
+// The locally defined lwIP buffer parsing pointer.
+//
+//****************************************************************************
+typedef struct
+{
+ //
+ // A pbuf pointer from lwIP.
+ //
+ struct pbuf *psBuf;
+
+ //
+ // The current index into the pbuf pointer.
+ //
+ uint32_t ui32Idx;
+}
+tBufPtr;
+
+//****************************************************************************
+//
+// Initialize a buffer parsing pointer.
+//
+//****************************************************************************
+static void
+BufPtrInit(tBufPtr *psBufPtr, struct pbuf *psBuf)
+{
+ psBufPtr->psBuf = psBuf;
+ psBufPtr->ui32Idx = 0;
+}
+
+//****************************************************************************
+//
+// Get a single byte from a parsing pointer.
+//
+//****************************************************************************
+static uint8_t
+BufData8Get(tBufPtr *psBufPtr)
+{
+ return(((uint8_t *)psBufPtr->psBuf->payload)[psBufPtr->ui32Idx]);
+}
+
+//*****************************************************************************
+//
+// Increment a parsing pointer by a given value.
+//
+//*****************************************************************************
+uint32_t
+BufPtrInc(tBufPtr *psBufPtr, uint32_t ui32Inc)
+{
+ psBufPtr->ui32Idx += ui32Inc;
+
+ if(psBufPtr->ui32Idx >= psBufPtr->psBuf->len)
+ {
+ psBufPtr->ui32Idx = 0;
+
+ psBufPtr->psBuf = psBufPtr->psBuf->next;
+
+ if(psBufPtr->psBuf == 0)
+ {
+ ui32Inc = 0;
+ }
+ }
+ return(ui32Inc);
+}
+
+//*****************************************************************************
+//
+// Return the image to use for the given icon returned from the weather update.
+//
+//*****************************************************************************
+void
+GetImage(char *pcIcon, const uint8_t **ppui8Image, const char **ppcDescription)
+{
+ static const struct
+ {
+ char pcId[2];
+ const uint8_t *pui8Image;
+ const char *pcDescription;
+ }
+ pcIconTable[9] =
+ {
+ //
+ // Clear Sky.
+ //
+ { "01", g_pui8SunImage, "Clear Sky"},
+
+ //
+ // Light Clouds.
+ //
+ { "02", g_pui8CloudyImage, "Light Clouds"},
+
+ //
+ // Scattered Clouds.
+ //
+ { "03", g_pui8CloudyImage, "Scattered Clouds"},
+
+ //
+ // Broken Clouds.
+ //
+ { "04", g_pui8CloudyImage, "Broken Clouds"},
+
+ //
+ // Rain showers.
+ //
+ { "09", g_pui8RainImage, "Light Rain"},
+
+ //
+ // Rain.
+ //
+ { "10", g_pui8RainImage, "Rain"},
+
+ //
+ // Thunderstorms.
+ //
+ { "11", g_pui8ThuderStormImage, "Thunderstorms"},
+
+ //
+ // Snow.
+ //
+ { "13", g_pui8SnowImage, "Snow"},
+
+ //
+ // Mist/Fog.
+ //
+ { "50", g_pui8FogImage, "Mist/Fog"},
+ };
+ int32_t i32Idx;
+
+ for(i32Idx = 0; i32Idx < 9; i32Idx++)
+ {
+ if((pcIcon[0] == pcIconTable[i32Idx].pcId[0]) &&
+ (pcIcon[1] == pcIconTable[i32Idx].pcId[1]))
+ {
+ *ppui8Image = pcIconTable[i32Idx].pui8Image;
+ *ppcDescription = pcIconTable[i32Idx].pcDescription;
+ break;
+ }
+ }
+}
+
+//*****************************************************************************
+//
+// Compare a string at the current location of a parsing pointer.
+//
+//*****************************************************************************
+uint32_t
+CompareString(tBufPtr *psBufPtr, const char *pcField, uint32_t ui32Size)
+{
+ uint32_t ui32Idx;
+
+ for(ui32Idx = 0; ui32Idx < ui32Size; ui32Idx++)
+ {
+ if(BufData8Get(psBufPtr) == pcField[ui32Idx])
+ {
+ if(BufPtrInc(psBufPtr, 1) != 1)
+ {
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if(ui32Idx == ui32Size)
+ {
+ return(0);
+ }
+
+ return(1);
+}
+
+//*****************************************************************************
+//
+// This function searches for a field from the JSON data. The field should be
+// quoted in the data and immediately follow a '{' character. This can be used
+// to also search for sub data in another field if the pointer to the data for
+// the parent field.
+//
+//*****************************************************************************
+static uint32_t
+GetField(char *pcField, tBufPtr *psBufPtr)
+{
+ uint32_t ui32Curly, ui32Quote;
+ int32_t i32NewItem;
+
+ ui32Curly = 0;
+ i32NewItem = 0;
+ ui32Quote = 0;
+
+ while(1)
+ {
+ if(BufData8Get(psBufPtr) == '{')
+ {
+ ui32Curly++;
+ }
+ else if(BufData8Get(psBufPtr) == '}')
+ {
+ ui32Curly--;
+
+ if(ui32Curly == 1)
+ {
+ ui32Quote = 0;
+ }
+ }
+ else if(BufData8Get(psBufPtr) == ',')
+ {
+ if((ui32Curly == 1) && ((ui32Quote & 1) == 0))
+ {
+ ui32Quote = 0;
+ }
+ }
+ else if(BufData8Get(psBufPtr) == '"')
+ {
+ if((ui32Curly == 1) && (ui32Quote == 0))
+ {
+ i32NewItem = 1;
+ }
+ ui32Quote++;
+ }
+
+ if(BufPtrInc(psBufPtr, 1) != 1)
+ {
+ break;
+ }
+
+ if(i32NewItem)
+ {
+ i32NewItem = 0;
+ if(CompareString(psBufPtr, pcField, ustrlen(pcField)) == 0)
+ {
+ while(1)
+ {
+ if(BufData8Get(psBufPtr) == ':')
+ {
+ if(BufPtrInc(psBufPtr, 1) != 1)
+ {
+ break;
+ }
+ return(1);
+ }
+
+ if(BufPtrInc(psBufPtr, 1) != 1)
+ {
+ break;
+ }
+ }
+ return(0);
+ }
+ }
+ }
+ return(0);
+}
+
+//*****************************************************************************
+//
+// This function searches for a value in a JSON item as an integer. These are
+// non-quoted values so if the number is a quoted integer this function returns
+// -1. If the value is found then it is returned by this function.
+//
+//*****************************************************************************
+int32_t
+GetFieldValueInt(tBufPtr *psBufPtr)
+{
+ int32_t i32Idx;
+ char pcTemp[20];
+ const char *pEnd;
+
+ i32Idx = 0;
+
+ while(1)
+ {
+ //
+ // Find the end of this item.
+ //
+ if((BufData8Get(psBufPtr) == '}') || (BufData8Get(psBufPtr) == ','))
+ {
+ //
+ // null terminate the string and get the value from the string in
+ // decimal.
+ //
+ pcTemp[i32Idx] = 0;
+ return(ustrtoul(pcTemp, &pEnd, 10));
+ }
+
+ //
+ // Should not hit a " char or something went wrong.
+ //
+ if(BufData8Get(psBufPtr) == '"')
+ {
+ break;
+ }
+
+ //
+ // Copy the string to the local variable.
+ //
+ pcTemp[i32Idx] = BufData8Get(psBufPtr);
+
+ if((pcTemp[i32Idx] == '\r') || (pcTemp[i32Idx] == '\n'))
+ {
+ pcTemp[i32Idx] = 0;
+ }
+ else
+ {
+ i32Idx++;
+ }
+
+ if(BufPtrInc(psBufPtr, 1) != 1)
+ {
+ break;
+ }
+
+ //
+ // Number was too large to represent.
+ //
+ if(i32Idx >= sizeof(pcTemp))
+ {
+ break;
+ }
+ }
+ return(INVALID_INT);
+}
+
+//*****************************************************************************
+//
+// This function searches for a value in a JSON item as quoted value. These
+// values are quoted values so if the number is not a quoted value this
+// function returns -1. If the quoted value is found then it is returned in
+// the pcDataDest array.
+//
+//*****************************************************************************
+int32_t
+GetFieldValueString(tBufPtr *psBufPtr, char *pcDataDest, uint32_t ui32SizeDest)
+{
+ int32_t i32OutIdx;
+
+ //
+ // The value should always start with a " char or something went wrong.
+ //
+ if(BufData8Get(psBufPtr) != '"')
+ {
+ return(-1);
+ }
+
+ //
+ // Skip the initial " char.
+ //
+ if(BufPtrInc(psBufPtr, 1) != 1)
+ {
+ return(-1);
+ }
+
+ for(i32OutIdx = 0; i32OutIdx < ui32SizeDest;)
+ {
+ //
+ // Either a '}', ',', or '"' ends an item.
+ //
+ if((BufData8Get(psBufPtr) == '}') ||
+ (BufData8Get(psBufPtr) == ',') ||
+ (BufData8Get(psBufPtr) == '"'))
+ {
+ //
+ // Null terminate the string and return.
+ //
+ pcDataDest[i32OutIdx] = 0;
+ return(i32OutIdx);
+ }
+
+ //
+ // Continue coping chars into the destination buffer.
+ //
+ pcDataDest[i32OutIdx] = BufData8Get(psBufPtr);
+
+ //
+ // These can occur in the response string and need to be ignored.
+ //
+ if((pcDataDest[i32OutIdx] == '\r') || (pcDataDest[i32OutIdx] == '\n'))
+ {
+ pcDataDest[i32OutIdx] = 0;
+ }
+ else
+ {
+ i32OutIdx++;
+ }
+
+ if(BufPtrInc(psBufPtr, 1) != 1)
+ {
+ break;
+ }
+ }
+
+ //
+ // Make sure to null terminate inside the current string.
+ //
+ if(i32OutIdx == ui32SizeDest)
+ {
+ pcDataDest[i32OutIdx-1] = 0;
+ return(i32OutIdx - 1);
+ }
+ return(-1);
+}
+
+//*****************************************************************************
+//
+// Fill out the psWeatherReport structure from data returned from the JSON
+// query.
+//
+//*****************************************************************************
+int32_t
+JSONParseForecast(uint32_t ui32Index, tWeatherReport *psWeatherReport,
+ struct pbuf *psBuf)
+{
+ tBufPtr sBufPtr, sBufList, sBufTemp;
+ char pcCode[4];
+ int32_t i32Items,i32Code;
+
+
+ //
+ // Reset the pointers.
+ //
+ BufPtrInit(&sBufPtr, psBuf);
+
+ //
+ // Check and see if the request was valid.
+ //
+ if(GetField("cod", &sBufPtr) != 0)
+ {
+ //
+ // Check for a 404 not found error.
+ //
+ sBufTemp = sBufPtr;
+
+ //
+ // Check for a 404 not found error.
+ //
+ i32Code = GetFieldValueInt(&sBufTemp);
+
+ sBufTemp = sBufPtr;
+
+ if(i32Code != INVALID_INT)
+ {
+ if(i32Code == 404)
+ {
+ return(-1);
+ }
+ }
+ else if(GetFieldValueString(&sBufTemp, pcCode, sizeof(pcCode)) >= 0)
+ {
+ //
+ // Check for a 404 not found error.
+ //
+ if(ustrncmp(pcCode, "404", 3) == 0)
+ {
+ return(-1);
+ }
+ }
+ }
+
+ //
+ // Reset the pointers.
+ //
+ BufPtrInit(&sBufPtr, psBuf);
+
+ //
+ // Initialize the number of items found.
+ //
+ i32Items = 0;
+
+ if(GetField("list", &sBufPtr) != 0)
+ {
+ //
+ // Save the list pointer.
+ //
+ sBufList = sBufPtr;
+
+ //
+ // Get the humidity.
+ //
+ if(GetField("humidity", &sBufPtr) != 0)
+ {
+ psWeatherReport->i32Humidity = GetFieldValueInt(&sBufPtr);
+ i32Items++;
+ }
+ else
+ {
+ psWeatherReport->i32Humidity = INVALID_INT;
+ }
+
+ //
+ // Reset the pointer to the start of the list values.
+ //
+ sBufPtr = sBufList;
+
+ //
+ // Get the average daily pressure.
+ //
+ if(GetField("pressure", &sBufPtr) != 0)
+ {
+ psWeatherReport->i32Pressure = GetFieldValueInt(&sBufPtr);
+ i32Items++;
+ }
+ else
+ {
+ psWeatherReport->i32Pressure = INVALID_INT;
+ }
+
+ //
+ // Reset the pointer to the start of the list values.
+ //
+ sBufPtr = sBufList;
+
+ //
+ // Get the average daily temperature.
+ //
+ if(GetField("temp", &sBufPtr) != 0)
+ {
+ if(GetField("day", &sBufPtr) != 0)
+ {
+ psWeatherReport->i32Temp = GetFieldValueInt(&sBufPtr);
+ i32Items++;
+ }
+ else
+ {
+ psWeatherReport->i32Temp = INVALID_INT;
+ }
+ }
+
+ //
+ // Reset the pointer to the start of the list values.
+ //
+ sBufPtr = sBufList;
+
+ //
+ // Get the low temperature.
+ //
+ if(GetField("temp", &sBufPtr) != 0)
+ {
+ if(GetField("min", &sBufPtr) != 0)
+ {
+ psWeatherReport->i32TempLow = GetFieldValueInt(&sBufPtr);
+ i32Items++;
+ }
+ else
+ {
+ psWeatherReport->i32TempLow = INVALID_INT;
+ }
+ }
+
+ //
+ // Reset the pointer to the start of the list values.
+ //
+ sBufPtr = sBufList;
+
+ //
+ // Get the high temperature.
+ //
+ if(GetField("temp", &sBufPtr) != 0)
+ {
+ if(GetField("max", &sBufPtr) != 0)
+ {
+ psWeatherReport->i32TempHigh = GetFieldValueInt(&sBufPtr);
+ i32Items++;
+ }
+ else
+ {
+ psWeatherReport->i32TempHigh = INVALID_INT;
+ }
+ }
+ //
+ // Reset the pointer to the start of the list values.
+ //
+ sBufPtr = sBufList;
+
+ if(GetField("dt", &sBufPtr) != 0)
+ {
+ psWeatherReport->ui32Time = GetFieldValueInt(&sBufPtr);
+ i32Items++;
+ }
+ else
+ {
+ psWeatherReport->ui32Time = 0;
+ }
+ }
+
+ return(i32Items);
+}
+
+//*****************************************************************************
+//
+// Fill out the psWeatherReport structure from data returned from the JSON
+// query.
+//
+//*****************************************************************************
+int32_t
+JSONParseCurrent(uint32_t ui32Index, tWeatherReport *psWeatherReport,
+ struct pbuf *psBuf)
+{
+ tBufPtr sBufPtr, sBufMain, sBufTemp;
+ char pcIcon[3];
+ char pcCode[4];
+ int32_t i32Items, i32Code;
+
+ //
+ // Reset the pointers.
+ //
+ BufPtrInit(&sBufPtr, psBuf);
+
+ //
+ // Check and see if the request was valid.
+ //
+ if(GetField("cod", &sBufPtr) != 0)
+ {
+ sBufTemp = sBufPtr;
+
+ //
+ // Check for a 404 not found error.
+ //
+ i32Code = GetFieldValueInt(&sBufTemp);
+
+ sBufTemp = sBufPtr;
+
+ if(i32Code != INVALID_INT)
+ {
+ if(i32Code == 404)
+ {
+ return(-1);
+ }
+ }
+ else if(GetFieldValueString(&sBufTemp, pcCode, sizeof(pcCode)) >= 0)
+ {
+ //
+ // Check for a 404 not found error.
+ //
+ if(ustrncmp(pcCode, "404", 3) == 0)
+ {
+ return(-1);
+ }
+ }
+ }
+
+ //
+ // Initialize the number of items that have been found.
+ //
+ i32Items = 0;
+
+ //
+ // Reset the pointers.
+ //
+ BufPtrInit(&sBufPtr, psBuf);
+
+ //
+ // Find the basic weather description(weather.description).
+ //
+ if(GetField("weather", &sBufPtr) != 0)
+ {
+ if(GetField("icon", &sBufPtr) != 0)
+ {
+ if(GetFieldValueString(&sBufPtr, pcIcon, sizeof(pcIcon)) > 0)
+ {
+ //
+ // Save the image pointer.
+ //
+ GetImage(pcIcon, &psWeatherReport->pui8Image,
+ &psWeatherReport->pcDescription);
+
+ i32Items++;
+ }
+ else
+ {
+ //
+ // No image was found.
+ //
+ psWeatherReport->pui8Image = 0;
+ }
+ }
+ }
+
+ //
+ // Reset the pointers.
+ //
+ BufPtrInit(&sBufPtr, psBuf);
+
+ //
+ // Find the humidity value(main.humidity).
+ //
+ if(GetField("sys", &sBufPtr) != 0)
+ {
+ //
+ // Save the pointer to the data.
+ //
+ sBufMain = sBufPtr;
+
+ //
+ // Get the sunrise time.
+ //
+ if(GetField("sunrise", &sBufPtr) != 0)
+ {
+ psWeatherReport->ui32SunRise = GetFieldValueInt(&sBufPtr);
+
+ i32Items++;
+ }
+ else
+ {
+ psWeatherReport->ui32SunRise = 0;
+ }
+
+ //
+ // Restore the pointer to the data.
+ //
+ sBufPtr = sBufMain;
+
+ //
+ // Get the sunset time.
+ //
+ if(GetField("sunset", &sBufPtr) != 0)
+ {
+ psWeatherReport->ui32SunSet = GetFieldValueInt(&sBufPtr);
+
+ i32Items++;
+ }
+ else
+ {
+ psWeatherReport->ui32SunSet = 0;
+ }
+ }
+
+ //
+ // Reset the pointers.
+ //
+ BufPtrInit(&sBufPtr, psBuf);
+
+ //
+ // Get the last update time.
+ //
+ if(GetField("dt", &sBufPtr) != 0)
+ {
+ psWeatherReport->ui32Time = GetFieldValueInt(&sBufPtr);
+
+ i32Items++;
+ }
+ else
+ {
+ psWeatherReport->ui32Time = 0;
+ }
+
+ //
+ // Reset the pointers.
+ //
+ BufPtrInit(&sBufPtr, psBuf);
+
+ //
+ // Find the humidity value(main.humidity).
+ //
+ if(GetField("main", &sBufPtr) != 0)
+ {
+ //
+ // Save the pointer to the main data.
+ //
+ sBufMain = sBufPtr;
+
+ if(GetField("humidity", &sBufPtr) != 0)
+ {
+ psWeatherReport->i32Humidity = GetFieldValueInt(&sBufPtr);
+ i32Items++;
+ }
+ else
+ {
+ psWeatherReport->i32Humidity = INVALID_INT;
+ }
+
+ //
+ // Reset the buffer pointer to main.
+ //
+ sBufPtr = sBufMain;
+
+ //
+ // Find the current temperature value.
+ //
+ if(GetField("temp", &sBufPtr) != 0)
+ {
+ psWeatherReport->i32Temp = GetFieldValueInt(&sBufPtr);
+ i32Items++;
+ }
+ else
+ {
+ psWeatherReport->i32Temp = INVALID_INT;
+ }
+
+ //
+ // Reset the buffer pointer to main.
+ //
+ sBufPtr = sBufMain;
+
+ //
+ // Find the current atmospheric pressure.
+ //
+ if(GetField("pressure", &sBufPtr) != 0)
+ {
+ psWeatherReport->i32Pressure = GetFieldValueInt(&sBufPtr);
+ i32Items++;
+ }
+ else
+ {
+ psWeatherReport->i32Pressure = INVALID_INT;
+ }
+ }
+ return(i32Items);
+}
|
