Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: NVIC_set_all_priorities mbed cc3000_hostdriver_mbedsocket TEMT6200 TSI Wi-Go_eCompass_Lib_V3 WiGo_BattCharger
Webserver/demo.cpp
- Committer:
- frankvnk
- Date:
- 2015-02-28
- Revision:
- 7:9d86d022fa68
- Parent:
- 5:bd9705c7cf51
File content as of revision 7:9d86d022fa68:
/*****************************************************************************
* Dynamic HTML string handlers:
* Nine dynamic HTML fields are updated on browser refresh or button press:
* Acceleration
* Magnetometer
* eCompass
* Altitude
* Battery Voltage
* Ambient Light
* Temperature
* Slider Position
* Page Views
*
* CGI HTML forms:
* Three CGI form inputs are used to submit data from browser to the Server:
* On screen buttons: -Red-, Green, Blue (for control of RGB LED output color)
*
* myindex[] contains the HTML string that defines the webpage that is served
* Use an online HTML validator to verify HTML code before running it on the MCU
* eg.
* www.w3schools.com/tags/tryit.asp?filename=tryhtml_div_test
* www.onlinewebcheck.com/check.php?adv=1
* Note: Before checking the HTML in one of these validators,
* strip-out all “\” backslash characters (using search & replace)
*
* Webserver code is based on TI's CC3000 Simple HTTP Webserver:
* http://processors.wiki.ti.com/index.php/CC3000_Wi-Fi_for_MCU
*
* More detail on implementation of this Webserver App is available here:
* http://processors.wiki.ti.com/index.php/CC3000_HTTP_Server_Demo_Session
*
* A more advanced Webserver and Client App is also available from TI for the CC3000:
* http://processors.wiki.ti.com/index.php/CC3000_Web_Server_Client_Application
* (at this time not yet ported to Kinetis-L as the host processor)
*
******************************************************************************
*
* demo.c - CC3000 Main Demo Application
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#include "mbed.h"
#include "defLED.h"
#include "demo.h"
#include "AvnetHTML.h"
#include "TSISensor.h"
#include "Wi-Go_eCompass_Lib_V3.h"
extern DigitalOut ledr;
extern DigitalOut ledg;
extern DigitalOut ledb;
extern DigitalOut led1;
extern DigitalOut led2;
extern DigitalOut led3;
extern TSISensor tsi;
// Setup the functions to handle our CGI parameters
cgi_handler pHandlers;
dyn_html_handler htmlHandlers;
extern tNetappIpconfigRetArgs ipinfo2;
extern axis6_t axis6;
extern int server_running;
extern unsigned char newData;
extern unsigned short adc_sample3;
// Variable declared in main and checked in the systick handler
// Code in the systick handler is only processed when Systick_Allowed = 1
extern bool Systick_Allowed;
/** \brief Pointer to the index HTML page */
char * indexPage;
/** \brief Pointer to CGI handler structure */
cgi_handler * chList;
/** \brief Pointer to Dynamic HTML handler structure */
dyn_html_handler * htmlList;
/** \brief Page view counter */
int viewCounter = 1;
#define REQ_BUFFER_SIZE 400
#define HTTP_TX_BLOCK_SIZE 256
//#define HTTP_TX_BLOCK_SIZE 1024
//#define HTTP_TX_BLOCK_SIZE 512
// Setup the functions to handle our CGI parameters
char requestBuffer[REQ_BUFFER_SIZE];
/*
// ---------- HTML Webpage Content is defined here ----------
// Caution! Field labels and spaces in the HTML should not be edited without making corresponding changes in the C-code!
char index[] = {
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"><html lang=\"en-US\">"
"<head>"
"<META content=\"text/html;charset=ISO-8859-1\" http-equiv=\"content-type\">"
"<title>Wi-Go WebServer</title>"
//"<META HTTP-EQUIV=\"refresh\" content=\"2\">" // Uncomment for auto-refresh every 2 seconds
"</head>"
"<body><div style=\"text-align: left\"><font size=\"6\" color=\"Red\" face=\"Tahoma\">"
"<b>Avnet Wi-Go Webserver</b></font>"
"<hr size=3 width=600 align=left>"
"<font size=\"5\" color=\"Red\" face=\"Tahoma\"><b>LED RGB color select...</b></font>"
//"<font size=\"5\" color=\"Black\" face=\"monospace\"></font>"
"<form method=\"get\" action=\"index.html\" name=\"server\">"
"<input name=\"ledCon\" type=\"submit\" value=\"-Red-\"> "
"<input name=\"ledCon\" type=\"submit\" value=\"Green\"> "
"<input name=\"ledCon\" type=\"submit\" value=\"Blue-\">"
"</form></div>"
"<hr size=3 width=600 align=left>"
"<div style=\"text-align: left\"><font size=\"5\" color=\"Red\" face=\"Tahoma\">"
"<b>Navigation Sensors</b></font></div>"
"<div style=\"text-align:left\"><font size=\"4\" color=\"Black\" face=\"monospace\"><b>"
"Acceleration(G).. <br>"
"Magnetometer(uT). <br>"
"eCompass......... <br>"
"Altitude......... <br></b></font></div>"
"<hr size=3 width=600 align=left>"
"<div style=\"text-align: left\"><font size=\"5\" color=\"Red\" face=\"Tahoma\">"
"<b>Status and Control</b></font></div>"
"<div style=\"text-align:left\"><font size=\"4\" color=\"Black\" face=\"monospace\"><b>"
"Battery Voltage.. <br>"
"Ambient Light.... <br>"
"Temperature...... <br>"
"Slider Position.. <br>"
"Page Views....... </b></font>"
"<hr size=3 width=600 align=left>"
"</body></html>"}; // delete this line if adding the SVG code below...
*/
// Optional section 1: Full SVG graphic example: Uncomment this section to display the standard Wi-Fi logo in lower area of webpage
// Browsers supporting SVG: Chrome and FireFox (all versions), Android (3.0 onwards), Safari (5.0 onwards), IE (9.0 onwards?)
/*
"<!--[if !IE]><!-->" // This prevents SVG content being sent to Internet Explorer
"<svg>"
"xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" height=\"175.49\" width=\"400\""
"xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\""
"xmlns:cc=\"http://creativecommons.org/ns#\""
"xmlns:dc=\"http://purl.org/dc/elements/1.1/\">"
"<defs></defs>"
"<metadata>"
"<rdf:RDF>"
"<cc:Work rdf:about=\"\">"
"<dc:format>image/svg+xml</dc:format>"
"<dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/>"
"<dc:title/>"
"</cc:Work>"
"</rdf:RDF>"
"</metadata>"
"<g transform=\"translate(-309.85919,-343.20843)\">"
"<g transform=\"matrix(3.7361528,0,0,-3.7361528,576.05074,474.82936)\">"
"<path fill-rule=\"nonzero\" fill=\"#231f20\" d=\"m0,0c4.977,0,9.049,4.077,9.049,9.049v5.389c0,4.973-4.072,9.048-9.049,9.048h-35.433c-4.973,0-9.049-4.075-9.049-9.048v-5.389c0-4.972,4.076-9.049,9.049-9.049\"/>"
"</g>"
"<g transform=\"matrix(3.7361528,0,0,-3.7361528,514.3818,441.01715)\">"
"<path fill-rule=\"nonzero\" fill=\"#FFF\" d=\"m0,0,0,5.389c0,4.072,3.314,7.32,7.32,7.32h9.187c4.007,0,7.253-3.248,7.253-7.32v-5.389c0-4.005-3.246-7.32-7.253-7.32h-20.239c2.281,1.656,3.732,4.284,3.732,7.32\"/>"
"</g>"
"<g transform=\"matrix(3.7361528,0,0,-3.7361528,469.99257,451.60916)\">"
"<path fill-rule=\"nonzero\" fill=\"#FFF\" d=\"m0,0-3.043,0-0.55,2.56c-0.345,1.794-0.692,4.005-0.761,4.833-0.069-0.828-0.416-3.039-0.825-4.833l-0.555-2.56h-2.968l-2.767,11.748h3.317l0.343-2.004c0.276-1.66,0.556-3.659,0.695-5.044,0.136,1.385,0.481,3.384,0.896,5.044l0.412,2.004h2.972l0.413-2.004c0.348-1.66,0.693-3.659,0.833-5.044,0.136,1.385,0.482,3.384,0.757,5.044l0.278,2.004h3.313\"/>"
"</g>"
"<g transform=\"matrix(3.7361528,0,0,-3.7361528,491.40819,416.23898)\">"
"<path fill-rule=\"nonzero\" fill=\"#FFF\" d=\"m0,0c-0.968,0-1.727,0.553-1.727,1.451,0,0.899,0.759,1.45,1.727,1.45,1.036,0,1.796-0.551,1.796-1.45,0-0.898-0.76-1.451-1.796-1.451m-1.521-0.968,3.0401,0,0-8.4984-3.0401,0,0,8.4984z\"/>"
"</g>"
"<g transform=\"matrix(3.7361528,0,0,-3.7361528,541.9845,418.05849)\">"
"<path fill-rule=\"nonzero\" fill=\"#231f20\" d=\"m0,0,0-2.618,6.22,0,0-2.767-6.22,0,0-3.593-3.247,0,0,11.748,10.156,0,0-2.77\"/>"
"</g>"
"<g transform=\"matrix(3.7361528,0,0,-3.7361528,580.44446,416.23898)\">"
"<path fill-rule=\"nonzero\" fill=\"#231f20\" d=\"m0,0c-0.97,0-1.727,0.553-1.727,1.451,0,0.899,0.757,1.45,1.727,1.45,1.035,0,1.797-0.551,1.797-1.45,0-0.898-0.762-1.451-1.797-1.451m-1.521-0.968,3.0371,0,0-8.4984-3.0371,0,0,8.4984z\"/>"
"</g>"
"</g>"
"</svg>"
"<!--<![endif]-->"
*/ // end of conditional inclusion of SVG graphic (excludes Internet Explorer browser)
// ---- End of Wi-Fi logo SVG image definition ----
// Optional section 2: Simple SVG graphic example: Uncomment this section to generate a filled circle in lower area of webpage
// eg. Could use to indicate RGB LED color (with addition of applicable C-code to dynamically update specified "fill=" color)
/*
"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">"
"<circle cx=\"155\" cy=\"22\" r=\"20\" stroke=\"DimGrey\" stroke-width=\"2\" fill=\"Red\"/>"
"</svg>"
"</body></html>"};
*/
// ----------------------------------------------------------
//char ssid_name[] = SSID;
char testString[20];
//int vcc = 0;
//*****************************************************************************
//
//! demo_wi-fi_main
//!
//! \param None
//!
//! \return none
//!
//! \brief The main loop is executed here
//
//*****************************************************************************
int demo_wifi_main(void)
{
server_running = 1;
while(1)
{
/* Configure dynamic HTML string handlers
0 : Acceleration
1 : Magnetometer
2 : eCompass
3 : Altitude
-------------------
4 : Battery Voltage
5 : Ambient Light
6 : Temperature
7 : Slider Position
8 : Page Views
*/
(htmlHandlers.dynHtmlFunc[0]) = getAccelXYZ_Str;
memcpy(htmlHandlers.dynHtmlParamName[0],"Acceleration(G).. ",strlen("Acceleration(G).. "));
htmlHandlers.dynHtmlParamName[0][strlen("Acceleration(G).. ")] ='\0';
(htmlHandlers.dynHtmlFunc[1]) = getM3110Str;
memcpy(htmlHandlers.dynHtmlParamName[1],"Magnetometer(uT). ",strlen("Magnetometer(uT). "));
htmlHandlers.dynHtmlParamName[1][strlen("Magnetometer(uT). ")] ='\0';
(htmlHandlers.dynHtmlFunc[2]) = getCompassStr;
memcpy(htmlHandlers.dynHtmlParamName[2],"eCompass......... ",strlen("eCompass......... "));
htmlHandlers.dynHtmlParamName[2][strlen("eCompass......... ")] ='\0';
(htmlHandlers.dynHtmlFunc[3]) = getAltitudeStr;
memcpy(htmlHandlers.dynHtmlParamName[3],"Altitude......... ",strlen("Altitude......... "));
htmlHandlers.dynHtmlParamName[3][strlen("Altitude......... ")] ='\0';
(htmlHandlers.dynHtmlFunc[4]) = getBatteryVoltageStr;
memcpy(htmlHandlers.dynHtmlParamName[4],"Battery Voltage.. ",strlen("Battery Voltage.. "));
htmlHandlers.dynHtmlParamName[4][strlen("Battery Voltage.. ")] ='\0';
(htmlHandlers.dynHtmlFunc[5]) = getLightVoltageStr;
memcpy(htmlHandlers.dynHtmlParamName[5],"Ambient Light.... ",strlen("Ambient Light.... "));
htmlHandlers.dynHtmlParamName[5][strlen("Ambient Light.... ")] ='\0';
(htmlHandlers.dynHtmlFunc[6]) = getTemperatureStr;
memcpy(htmlHandlers.dynHtmlParamName[6],"Temperature...... ",strlen("Temperature...... "));
htmlHandlers.dynHtmlParamName[6][strlen("Temperature...... ")] ='\0';
(htmlHandlers.dynHtmlFunc[7]) = getTSI_sliderStr;
memcpy(htmlHandlers.dynHtmlParamName[7],"Slider Position.. ",strlen("Slider Position.. "));
htmlHandlers.dynHtmlParamName[7][strlen("Slider Position.. ")] ='\0';
(htmlHandlers.dynHtmlFunc[8]) = getViewsNum;
memcpy(htmlHandlers.dynHtmlParamName[8],"Page Views....... ",strlen("Page Views....... "));
htmlHandlers.dynHtmlParamName[8][strlen("Page Views....... ")] ='\0';
// Configure CGI Handler
(pHandlers.cgiHandlerFunc[0]) = testFunc;
serverMain(HTTP_PORT,(char *)index, &pHandlers, &htmlHandlers);
}
}
void testFunc(char * str)
{
memcpy(testString,str,strlen(str));
if(strcmp(str, "-Red-") == 0)
{
RED_ON; GREEN_OFF; BLUE_OFF;
}
else if(strcmp(str, "Green") == 0)
{
RED_OFF; GREEN_ON; BLUE_OFF;
}
else if (strcmp(str, "Blue-") == 0)
{
RED_OFF; GREEN_OFF; BLUE_ON;
}
}
void getBatteryVoltageStr(char * str)
{
sprintf(str," "); //clears field (needed if previous string had more characters)
sprintf(str, "%d %%", adc_sample3);
}
void getLightVoltageStr(char * str)
{
int LightPercent = 0;
LightPercent = (axis6.light * 100) / 4096;
sprintf(str," "); //clears field (needed if previous string had more characters)
sprintf(str, "%d %%", LightPercent);
}
void getAccelXYZ_Str(char * str) // MMA8451Q accelerometer - report axis with highest value
{
sprintf(str," "); //clears field (needed if previous string had more characters)
sprintf(str, "X= %1.2f, Y= %1.2f, Z= %1.2f", axis6.fGax, axis6.fGay, axis6.fGaz);;
}
void getTemperatureStr(char * str) //
{
sprintf(str, "%+d C", axis6.temp);
}
void getTSI_sliderStr(char * str) // TSI Slider position
{
uint8_t slider_position;
slider_position = tsi.readPercentage() * 100; // Slider position as percentage
sprintf(str," "); //clears field (needed if previous string had more characters)
sprintf(str, "%d %%", slider_position);
}
void getCompassStr(char * str) // Mag3110 generated Compass bearing
{
char *compass_points[9] = {"North", "N-East", "East", "S-East", "South", "S-West", "West", "N-West", "North"};
signed short compass_bearing = (axis6.compass + 23) / 45;
sprintf(str," "); //clears field (needed if previous string had more characters)
sprintf(str, "Roll=%-d Pitch=%-d Yaw=%-d [%s]", axis6.roll, axis6.pitch, axis6.yaw, compass_points[compass_bearing]); //
}
void getM3110Str(char * str) // Mag3110 displayed in units of UT
{
sprintf(str," "); //clears field (needed if previous string had more characters)
sprintf(str, "X= %3.1f, Y= %3.1f, Z= %3.1f", axis6.fUTmx, axis6.fUTmy, axis6.fUTmz);
}
void getAltitudeStr(char * str) // Get Altitude
{
sprintf(str, "%+d meters", axis6.alt); // str = integer portion of result
}
//*****************************************************************************
//
//! \brief Main HTTP Server
//!
//! \param none
//!
//! \return none
//!
//
//*****************************************************************************
void serverMain(int port,
char * ipage,
cgi_handler * handleList,
dyn_html_handler * dhList)
{
static TCPSocketServer server;
static TCPSocketConnection client;
indexPage = ipage;
chList = handleList;
htmlList = dhList;
server.bind(port);
printf("Main HTTP server\r\n");
// Start Listening
if(server.listen() != 0); // !!?? if statement is of no use - replace with server.listen();
// Handle Clients and Data
while(1)
{
int32_t status = server.accept(client);
if (status >= 0)
{
LED_D2_ON;
// Connection Accepted, Send Data
// Wait for a data update
client.set_blocking(true);
printf("Connection\r\n");
// printf("Connection from: %s \r\n", client.get_address());
if(newData)
{
Systick_Allowed = 0;
// Alternative to Systick_Allowed - more intrusive as it will entirely disable systicks
// SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; // *** Disable SysTick Timer
handleHTTPRequest(&client);
}
newData = 0;
client.close();
LED_D2_OFF;
}
else if(status == -57)
{
// BUG: Socket inactive so reopen socket
// Inactive Socket, close and reopen it
printf("Oops!!!\r\n");
server.close();
indexPage = ipage;
chList = handleList;
htmlList = dhList;
server.bind(port);
// Start Listening
if (server.listen() != 0); // !!?? if statement is of no use - replace with server.listen();
}
Systick_Allowed = 1;
// SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; // *** Re-Enable SysTick Timer
}
}
//*****************************************************************************
//
//! \brief Handles HTTP Requests
//!
//! \param cnum is the client socket handle to be used
//!
//! \return none
//!
//
//*****************************************************************************
void handleHTTPRequest(TCPSocketConnection *client)
{
char * reqline[3];
char * cgiTok;
int i = 0;
char paramBuf[20];
int bytesRecvd;
char tempStr[40]; //PF was 26
memset(requestBuffer,0,sizeof (requestBuffer));
bytesRecvd = client->receive(requestBuffer, sizeof(requestBuffer));
printf("handleHTTPRequest\r\n");
if(bytesRecvd > 0)
{
// Received some data, check it and send data back
reqline[0] = strstr(requestBuffer, "GET");
if ( reqline[0] != NULL )
{
if (strstr (requestBuffer, "HTTP/1.0") != NULL && strstr (requestBuffer, "HTTP/1.1") != NULL )
{
client->send_all("HTTP/1.0 400 Bad Request\n", 25);
}
else
{
#ifdef HTTP_CGI_ENABLED
// Do we have CGI parameters we need to parse?
if(strchr(requestBuffer, '?') != NULL)
{
// Decode URL and handle each parameter sequentially
// according to table previously setup.
cgiTok = strstr(requestBuffer,"=");
if(cgiTok != NULL)
{
memset(paramBuf,0,sizeof(paramBuf));
memcpy(paramBuf,cgiTok+1,5); // hard-coded for demo: 5 character parameter (-Red-/Green/Blue-)
chList->cgiHandlerFunc[0](paramBuf);
}
}
#endif
#ifdef HTTP_DYN_HTML_ENABLED
// The code below replaces data in the HTML page
// with that generated by the specified functions.
for(i = 0; i < 9; i++) // change the range here for more dynamic fields on webpage
{
memset(tempStr,0,sizeof(tempStr));
htmlList->dynHtmlFunc[i](tempStr);
tempStr[strlen(tempStr)]= ' ';
pageReplace((char *)indexPage,
(char *)htmlList->dynHtmlParamName[i],
(char *)tempStr);
}
#endif
viewCounter++;
sendHTTPData(HTTP_RESP, strlen(HTTP_RESP), client);
for(i = 0; i < strlen(indexPage); i += HTTP_TX_BLOCK_SIZE)
{
if(strlen(indexPage) - i < HTTP_TX_BLOCK_SIZE)
{
sendHTTPData(&indexPage[i], strlen(indexPage) - i, client);
}
else
{
sendHTTPData(&indexPage[i], HTTP_TX_BLOCK_SIZE, client);
}
}
}
}
}
}
//*****************************************************************************
//
//! \brief Inserts characters in page that appear after an indicator ind
//! with the value from val
//!
//! \param page is a pointer to the array holding the page's HTML code
//! \param ind is a pointer to a string that has the name of the parameter on the page to modify
//! \param val is the pointer to a string holding the string to insert in the XXX
//!
//! \return none
//!
//
//*****************************************************************************
void pageReplace(char * page, char * ind, char * val)
{
char * indicLoc;
indicLoc = strstr (page,ind);
memcpy(indicLoc+strlen(ind), val, strlen(val));
}
//*****************************************************************************
//
//! \brief Returns a string with the number of views of the page
//!
//! \param str is a pointer to the array where the number of views will be put
//!
//! \return none
//!
//
//*****************************************************************************
void getViewsNum(char * str)
{
sprintf(str, "%d", viewCounter);
}
//*****************************************************************************
//
//! \brief Sends HTTP Data
//!
//! \param sdesc is the socket descriptor of the socket used for sending data
//! \param buf is a pointer to the buffer with the data to be sent
//! \param len is the number of bytes to send
//!
//! \return none
//!
//
//*****************************************************************************
void sendHTTPData(char * buf, long len, TCPSocketConnection *client)
{
int bytesSent = -2;
while(bytesSent == -2) bytesSent = client->send_all(buf, len);
}
Avnet Wi-Go System