diff options
| author | Yuval Adam <yuv.adm@gmail.com> | 2014-03-16 14:31:22 +0200 |
|---|---|---|
| committer | Yuval Adam <yuv.adm@gmail.com> | 2014-03-16 14:31:22 +0200 |
| commit | ac4fd8e8340886f455add8cf92ee1c8458b8ae19 (patch) | |
| tree | fdeb96af9d57573855405fb5099468244772cd49 /boards/ek-tm4c1294xl/drivers/http.c | |
| parent | 821e3405f23958760f7c27e8934940abfed3d5cb (diff) | |
Add ek-tm4c1294xl example projects
Diffstat (limited to 'boards/ek-tm4c1294xl/drivers/http.c')
| -rw-r--r-- | boards/ek-tm4c1294xl/drivers/http.c | 587 |
1 files changed, 587 insertions, 0 deletions
diff --git a/boards/ek-tm4c1294xl/drivers/http.c b/boards/ek-tm4c1294xl/drivers/http.c new file mode 100644 index 0000000..22d4f0f --- /dev/null +++ b/boards/ek-tm4c1294xl/drivers/http.c @@ -0,0 +1,587 @@ +//*****************************************************************************
+//
+// http.c - HTTP request creation functions.
+//
+// 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 EK-TM4C1294XL Firmware Package.
+//
+//*****************************************************************************
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include "inc/hw_types.h"
+#include "utils/ustdlib.h"
+#include "http.h"
+
+//*****************************************************************************
+//
+// Buffer used to store temporary strings for constructing/parsing requests.
+//
+//*****************************************************************************
+static char g_pcTempData[256];
+
+//*****************************************************************************
+//
+// Declarations for request type strings.
+//
+//*****************************************************************************
+static char g_pcHttpConnect[] = "CONNECT ";
+static char g_pcHttpGet[] = "GET ";
+static char g_pcHttpPost[] = "POST ";
+static char g_pcHttpPut[] = "PUT ";
+static char g_pcHttpDelete[] = "DELETE ";
+static char g_pcHttpHead[] = "HEAD ";
+static char g_pcHttpTrace[] = "TRACE ";
+static char g_pcHttpOptions[] = "OPTIONS ";
+static char g_pcHttpPatch[] = "PATCH ";
+
+//*****************************************************************************
+//
+// HTTP suffixes used by HTTPMessageTypeSet(). Default is HTTP 1.1.
+//
+//*****************************************************************************
+#ifdef USE_HTTP_1_0
+static const char g_pcSuffixHttp10[] = " HTTP/1.0\r\n\r\n";
+#else
+static const char g_pcSuffixHttp11[] = " HTTP/1.1\r\n\r\n";
+#endif
+
+//*****************************************************************************
+//
+//! Extract the portion of a string up to a specified character.
+//!
+//! \param cWhichOne specifies the character to compare against.
+//! \param pcSource is a pointer to the source/input string.
+//! \param pcOutput is a pointer to the destination/output string.
+//! \param pui32Size is a pointer to a variable that will receive the size of
+//! the destination/output string.
+//!
+//! \return None.
+//
+//*****************************************************************************
+static void
+BufferFillToCharacter(char cWhichOne, char *pcSource, char *pcOutput,
+ uint32_t *pui32Size)
+{
+ //
+ // Search the string until the character is found.
+ //
+ *pui32Size = 0;
+ while(*pcSource)
+ {
+ if(*pcSource == cWhichOne)
+ {
+ pcOutput[*pui32Size] = 0;
+ pcSource++;
+ return;
+ }
+ else
+ {
+ pcOutput[*pui32Size] = *pcSource;
+ pcSource++;
+ *pui32Size += 1;
+ }
+ }
+
+ return;
+}
+
+//*****************************************************************************
+//
+//! Extract the portion of a string up to end-of-line (EOL).
+//!
+//! \param pcSource is a pointer to the source/input string.
+//! \param pcOutput is a pointer to the destination/output string.
+//! \param pui32Size is a pointer to a variable that will receive the size of
+//! the destination/output string.
+//!
+//! \return None.
+//
+//*****************************************************************************
+static void
+BufferFillToEOL(char *pcSource, char *pcOutput, uint32_t *pui32Size)
+{
+ //
+ // Search the string until EOL is found.
+ //
+ *pui32Size = 0;
+ while(*pcSource)
+ {
+ if((*pcSource == '\r') && (*(pcSource+ 1) == '\n'))
+ {
+ pcOutput[*pui32Size] = 0;
+ pcSource += 2;
+ return;
+ }
+ else
+ {
+ pcOutput[*pui32Size] = *pcSource;
+ pcSource++;
+ *pui32Size += 1;
+ }
+ }
+
+ return;
+}
+
+static void
+InsertRequest(char *pcDest, char *pcRequest)
+{
+ uint32_t i;
+ uint32_t ui32ReqSize;
+ uint32_t ui32DstSize;
+
+ ui32ReqSize = strlen(pcRequest);
+ ui32DstSize = strlen(pcDest);
+
+ pcDest[ui32DstSize + ui32ReqSize] = 0;
+ for(i = ui32DstSize; i-- > 0; )
+ {
+ pcDest[ui32ReqSize + i] = pcDest[i];
+ }
+
+ for(i = 0; i < ui32ReqSize; i++)
+ {
+ pcDest[i] = pcRequest[i];
+ }
+}
+
+//*****************************************************************************
+//
+//! Set the HTTP message type.
+//!
+//! \param pcDest is a pointer to the destination/output string.
+//! \param ui8Type is the HTTP request type. Macros such as HTTP_MESSAGE_GET
+//! are defined in http.h.
+//! \param pcResource is a pointer to a string containing the resource portion
+//! of the HTTP message. The resource goes in between the type (ex: GET) and
+//! HTTP suffix on the first line of a HTTP request. An example would be
+//! index.html.
+//!
+//! This function should be called to start off a new HTTP request.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+HTTPMessageTypeSet(char *pcDest, uint8_t ui8Type, char *pcResource)
+{
+ //
+ // Check to see if the resource and destination pointers are the same. If
+ // yes, insert the request type at the beginning of the resource string.
+ //
+ if(pcDest == pcResource)
+ {
+ //
+ // Add the request type to the buffer.
+ //
+ switch(ui8Type)
+ {
+ case HTTP_MESSAGE_CONNECT:
+ {
+ InsertRequest(pcDest, g_pcHttpConnect);
+ break;
+ }
+ case HTTP_MESSAGE_GET:
+ {
+ InsertRequest(pcDest, g_pcHttpGet);
+ break;
+ }
+ case HTTP_MESSAGE_POST:
+ {
+ InsertRequest(pcDest, g_pcHttpPost);
+ break;
+ }
+ case HTTP_MESSAGE_PUT:
+ {
+ InsertRequest(pcDest, g_pcHttpPut);
+ break;
+ }
+ case HTTP_MESSAGE_DELETE:
+ {
+ InsertRequest(pcDest, g_pcHttpDelete);
+ break;
+ }
+ case HTTP_MESSAGE_HEAD:
+ {
+ InsertRequest(pcDest, g_pcHttpHead);
+ break;
+ }
+ case HTTP_MESSAGE_TRACE:
+ {
+ InsertRequest(pcDest, g_pcHttpTrace);
+ break;
+ }
+ case HTTP_MESSAGE_OPTIONS:
+ {
+ InsertRequest(pcDest, g_pcHttpOptions);
+ break;
+ }
+ case HTTP_MESSAGE_PATCH:
+ {
+ InsertRequest(pcDest, g_pcHttpPatch);
+ break;
+ }
+ }
+ }
+ else
+ {
+ //
+ // Add the request type to the buffer.
+ //
+ switch(ui8Type)
+ {
+ case HTTP_MESSAGE_CONNECT:
+ {
+ usprintf(pcDest, g_pcHttpConnect);
+ break;
+ }
+ case HTTP_MESSAGE_GET:
+ {
+ usprintf(pcDest, g_pcHttpGet);
+ break;
+ }
+ case HTTP_MESSAGE_POST:
+ {
+ usprintf(pcDest, g_pcHttpPost);
+ break;
+ }
+ case HTTP_MESSAGE_PUT:
+ {
+ usprintf(pcDest, g_pcHttpPut);
+ break;
+ }
+ case HTTP_MESSAGE_DELETE:
+ {
+ usprintf(pcDest, g_pcHttpDelete);
+ break;
+ }
+ case HTTP_MESSAGE_HEAD:
+ {
+ usprintf(pcDest, g_pcHttpHead);
+ break;
+ }
+ case HTTP_MESSAGE_TRACE:
+ {
+ usprintf(pcDest, g_pcHttpTrace);
+ break;
+ }
+ case HTTP_MESSAGE_OPTIONS:
+ {
+ usprintf(pcDest, g_pcHttpOptions);
+ break;
+ }
+ case HTTP_MESSAGE_PATCH:
+ {
+ usprintf(pcDest, g_pcHttpPatch);
+ break;
+ }
+ }
+
+ //
+ // Add the resource to the buffer.
+ //
+ strcat(pcDest, pcResource);
+ }
+
+ //
+ // Finish the first "line" by adding the HTTP suffix.
+ //
+#ifdef USE_HTTP_1_0
+ strcat(pcDest, g_pcSuffixHttp10);
+#else
+ strcat(pcDest, g_pcSuffixHttp11);
+#endif
+}
+
+//*****************************************************************************
+//
+//! Add a header to a HTTP request.
+//!
+//! \param pcDest is a pointer to the destination/output string.
+//! \param pcHeaderName is a pointer to a string containing the header name.
+//! \param pcHeaderValue is a pointer to a string containing the header data.
+//!
+//! Note that this function must be called after HTTPMessageTypeSet() as it
+//! simply appends a header to an existing string/buffer.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+HTTPMessageHeaderAdd(char *pcDest, char *pcHeaderName, char *pcHeaderValue)
+{
+ //
+ // Add the header name to the buffer.
+ //
+ strcat(pcDest, pcHeaderName);
+
+ //
+ // Add ":" and space.
+ //
+ strcat(pcDest, ": ");
+
+ //
+ // Add header value.
+ //
+ strcat(pcDest, pcHeaderValue);
+
+ //
+ // Add \r and \n.
+ //
+ strcat(pcDest, "\r\n");
+}
+
+//*****************************************************************************
+//
+//! Add body data to to a HTTP request.
+//!
+//! \param pcDest is a pointer to the destination/output string.
+//! \param pcBodyData is a pointer to a string containing the body data. This
+//! can be anything from HTML to encoded data (such as JSON).
+//!
+//! Note that this function must be called after HTTPMessageTypeSet() and
+//! HTTPMessageHeaderAdd() as it simply appends the body data to an existing
+//! string/buffer.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+HTTPMessageBodyAdd(char *pcDest, char *pcBodyData)
+{
+ //
+ // First, insert blank line between header section and body.
+ //
+ strcat(pcDest, "\r\n");
+
+ //
+ // Add body content.
+ //
+ strcat(pcDest, pcBodyData);
+
+ //
+ // Add blank line.
+ //
+ strcat(pcDest, "\r\n\r\n");
+}
+
+//*****************************************************************************
+//
+//! Parse a HTTP response.
+//!
+//! \param pcData is a pointer to the source string/buffer.
+//! \param pcResponseText is a pointer to a string that will receive the
+//! response text from the first line of the HTTP response.
+//! \param pui32NumHeaders is a pointer to a variable that will receive the
+//! number of headers detected in pcData.
+//!
+//! Note that this function must be called after HTTPMessageTypeSet() as it
+//! simply appends a header to an existing string/buffer.
+//!
+//! \return Returns the HTTP response code. If parsing error occurs, returns 0.
+//
+//*****************************************************************************
+uint32_t
+HTTPResponseParse(char *pcData, char *pcResponseText, uint32_t *pui32NumHeaders)
+{
+ uint32_t ui32Response = 0;
+ uint32_t ui32Size;
+
+ //
+ // Look for "HTTP/n.n" piece.
+ //
+ BufferFillToCharacter(' ', pcData, g_pcTempData, &ui32Size);
+ pcData += (ui32Size + 1);
+
+ //
+ // Fail if not a HTTP response.
+ //
+ if(ustrncmp(g_pcTempData, "HTTP/", 5))
+ {
+ *pcResponseText = 0;
+ *pui32NumHeaders = 0;
+ return 0;
+ }
+
+ //
+ // Get the return code.
+ //
+ BufferFillToCharacter(' ', pcData, g_pcTempData, &ui32Size);
+ pcData += (ui32Size + 1);
+
+ //
+ // Convert return code to unsigned long.
+ //
+ ui32Response = ustrtoul(g_pcTempData, 0, 10);
+
+ //
+ // Get the response text.
+ //
+ BufferFillToEOL(pcData, pcResponseText, &ui32Size);
+ pcData += (ui32Size + 2);
+
+ //
+ // Parse the remainder of the packet.
+ //
+ *pui32NumHeaders = 0;
+ while(*pcData)
+ {
+ //
+ // Search line by line and count headers. Search until there is a blank
+ // line, which means end of headers.
+ //
+ BufferFillToEOL(pcData, g_pcTempData, &ui32Size);
+ pcData += (ui32Size + 2);
+
+ //
+ // Blank line. For the purposes of this function, we're done.
+ //
+ if(ui32Size == 0)
+ {
+ break;
+ }
+ else
+ {
+ //
+ // Increment header counter.
+ //
+ *pui32NumHeaders += 1;
+ }
+ }
+
+ return ui32Response;
+}
+
+//*****************************************************************************
+//
+//! Extract a specified header from a HTTP response string/buffer.
+//!
+//! \param pcData is a pointer to the source string/buffer.
+//! \param ui32HeaderIdx specifies the index of the header to extract.
+//! \param pcHeaderName is a pointer to a string that will receive the name of
+//! the header specified by ui32HeaderIdx.
+//! \param pcHeaderValue is a pointer to a string that will receive the value of
+//! the header specified by ui32HeaderIdx.
+//!
+//! Note that this function should be used in conjunction with
+//! HTTPResponseParse() since it notifies the application of the number of
+//! headers in a string/buffer.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+HTTPResponseHeaderExtract(char *pcData, uint32_t ui32HeaderIdx,
+ char *pcHeaderName, char *pcHeaderValue)
+{
+ uint32_t ui32Size;
+ uint32_t ui32HeaderNumber = 0;
+
+ //
+ // Read first line and discard.
+ //
+ BufferFillToEOL(pcData, g_pcTempData, &ui32Size);
+ pcData += (ui32Size + 2);
+
+ //
+ // Find and return the requested header.
+ //
+ while(*pcData)
+ {
+ BufferFillToEOL(pcData, g_pcTempData, &ui32Size);
+ pcData += (ui32Size + 2);
+
+ //
+ // Blank line, end of header section.
+ //
+ if(ui32Size == 0)
+ {
+ break;
+ }
+ else
+ {
+ if(ui32HeaderNumber == ui32HeaderIdx)
+ {
+ BufferFillToCharacter(':', g_pcTempData, pcHeaderName,
+ &ui32Size);
+ BufferFillToCharacter(0, &g_pcTempData[ui32Size + 2],
+ pcHeaderValue, &ui32Size);
+ pcHeaderValue[ui32Size] = 0;
+
+ break;
+ }
+ else
+ {
+ //
+ // Increment header counter.
+ //
+ ui32HeaderNumber++;
+ }
+ }
+ }
+}
+
+//*****************************************************************************
+//
+//! Extract the body from a HTTP response string/buffer.
+//!
+//! \param pcData is a pointer to the source string/buffer.
+//! \param pcDest is a pointer to a string that will receive the body data.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+HTTPResponseBodyExtract(char *pcData, char *pcDest)
+{
+ bool bBodyFound = false;
+ uint32_t ui32Size;
+
+ //
+ // Find and return the body.
+ //
+ while(*pcData)
+ {
+ //
+ // Read lines until a blank line is found. This is the start of the
+ // body.
+ //
+ BufferFillToEOL(pcData, g_pcTempData, &ui32Size);
+ pcData += (ui32Size + 2);
+
+ //
+ // Blank line, end of header section.
+ //
+ if(ui32Size == 0)
+ {
+ bBodyFound = true;
+ }
+
+ //
+ // If the body has been found, start filling the buffer.
+ //
+ if(bBodyFound)
+ {
+
+ pcDest[0] = 0;
+ strcat(pcDest, pcData);
+ break;
+ }
+ }
+}
|
