/* Copyright (c) 2012 VECTARE * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * - Neither the name of VECTARE 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 * VECTARE. OR ITS 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 * * Author: Don Pitchford */ #include "webfunctions.h" #include #include #include #include "efmboard_leds.h" char newbuf[BUFFERSIZE]; /** * Decode the GET / Statement for filename, and request type. * Return the characters of the filename. The filename * starts at position5, ends at either a space or ? */ void getDecode(char *getbuf, u16_t buflen, webinfo *webdata) { u16_t i; char ext[5]; // hold copy of the file extensions for(i=5; ifilename,"index.htm"); strcpy (webdata->filename,"index.htm"); webdata->filetype = 0; } else { webdata->filetype=50; substr(webdata->filename,getbuf,5,i-5); // Get the filename from the buffer substr(ext,getbuf,i-3, 3); // extract last 3 char (assume extensions) bzero(webdata->content_type,20); if (ext[0] == 'h' && ext[1] == 't' && ext[2] == 'm') { strcpy(webdata->content_type,"text/html"); webdata->filetype = 0; // } else if (ext[0] == 'i' && ext[1] == 'c' && ext[2] == 'o') { strcpy(webdata->content_type,"image/ico"); webdata->filetype = 3; // } else if (ext[0] == 'j' && ext[1] == 'p' && ext[2] == 'g') { strcpy(webdata->content_type,"image/jpeg"); webdata->filetype = 1; // } else if (ext[0] == 'p' && ext[1] == 'n' && ext[2] == 'g') { strcpy(webdata->content_type,"image/png"); webdata->filetype = 2; } else if (ext[0] == 'c' && ext[1] == 's' && ext[2] == 's') { strcpy(webdata->content_type,"text/css"); webdata->filetype = 3; } else { strcpy(webdata->content_type,"text/html"); // default - text html webdata->filetype = 0; } } } /** * Generate the ACK message for the HTTP */ int webSendAck(char *indexdata, u16_t buflen, webinfo *webdata, unsigned long rfc868) { // TODO: NEED TO GET REAL DATE char textdata[15]; // Send the HTTP 1.1 Header information for successful file. strcpy(indexdata,"HTTP/1.1 200 OK\r\n"); //strcat(indexdata,"Date: Thu, 17 Apr 2012 11:06:09 GMT\r\n"); // TODO: NEED TO GET REAL DATE strcat(indexdata,"Server: EnergyMicro (FreeRTOS) lwIP 1.4.1\r\n"); // ETAG Number - Based off the RFC868 number to ensure that data is not cache strcat(indexdata,"ETAG: \""); webLTOA(rfc868, textdata, 14); strcat(indexdata,textdata); strcat(indexdata,"\"\r\n"); // Content Length strcat(indexdata,"Content-Length: "); webLTOA(webdata->filesize, textdata, 14); strcat(indexdata,textdata); strcat(indexdata,"\r\n"); strcat(indexdata,"Connection: close\r\n"); strcat(indexdata,"Content-Type: "); strcat(indexdata,webdata->content_type); strcat(indexdata,"\r\n"); strcat(indexdata,"\r\n\0"); return strlen(indexdata); } /** * Send 404 Message if the file is not found * * @param char *indexdata - empty string of data that is large enough for all this data. * @param u16_t buflen - Buffer length. Not used. * * @return int - size of the string buffer created. */ int webSend404(char *indexdata, u16_t buflen) { //TODO: NEED TO GET REAL DATE strcpy(indexdata,"HTTP/1.1 404 Not Found\r\n"); //strcat(indexdata,"Date: Thu, 19 Apr 2012 11:06:09 GMT\r\n"); // strcat(indexdata,"Server: EnergyMicro (RTOS)\r\n"); strcat(indexdata,"Content-Type: text/html\r\n"); strcat(indexdata,"Connection: close\r\n"); strcat(indexdata,"\r\n\0"); strcat(indexdata,"404 Not Found</TITLE</HEAD>"); strcat(indexdata,"<BODY><H1>404 Not Found</H1><br /><hr><br /"); strcat(indexdata,"<H3> The requested URL is not found on this server.</H3></Body></HTML>"); return strlen(indexdata); } /** * Substring function * From vijayinterviwquestions.com */ void substr(char *dest, char *src, int position, int length) { u16_t i; for (i=0; i<length; i++) { dest[i]=src[i+position]; } dest[i]='\0'; } /** * Copy string from one to another. */ void web_strcpy (char *s, char*t) { while((*s++=*t++) != '\0'); } /** * @brief * Parse the paramaters and return the number via the function. * * @param[in] char *buf - * content of the GET / string * * @param[in] u16_t buflen * length of the GET / string * * @param[in] webinfo * webdata * Struct that contains filename, paramaters and two pointers * that hold variable name & value. * * @return u16_t count * number of parameters */ u16_t getWebParam(char *getbuf, u16_t buflen, webinfo *webdata) { u16_t i, count=0, start=0, finish=0, size=0; char *p; webdata->numparam=0; for (i=5; i<buflen;i++) { // Start at end of GET / if (getbuf[i] == ' ') break; // If detects a space, we have reached the end of the string. if (getbuf[i] == '?') start=i+1; if (getbuf[i] == '=') { // Receive the Variable Name finish = i-1; if (start > 0) { size = finish-start+2; if ((p = (char *)malloc(size)) == NULL) return 0; // Not enough memory... exit substr(p,getbuf,start,finish-start+1); // Copy the value over.. webdata->webvar[count] = p; } start = i+1; } if (getbuf[i] == '&') { // Look for the second, third, etc set of parameters finish = i-1; if (start > 0) { size = finish-start+2; if ((p = (char *)malloc(size)) == NULL) return 0; substr(p,getbuf,start,finish-start+1); webdata->webval[count++] = p; } if (count >= MAXPARAM) break; // Make sure that we don't accept too many parameters. // MAPARAM is define in webfunctions.h start = i+1; // Move ptr fwd } } if (start == 0) return 0; // Never Started... no filename no parameters.. finish = i-1; size = finish-start+2; if (size<1) return 0; if ((p = (char *)malloc(size)) == NULL) return 0; substr(p,getbuf,start,(finish-start+1)); webdata->webval[count++] = p; webdata->numparam = count; return count; } /** * Evaluate the LINE and determine if it matches any of the parameters exist. * If they do, then return the position of the match that occurred. To add * new variables, see webfunctions.h * * @param *line - character string of the line to search for match * * @return Returns an integer based on the position the match occurred from * webreplace variables */ int webFindVar(char *line) { char *ptr; u16_t i, slen; if (strlen(line) < 10) return -1; // If the line is short, probably doesn't contain a variable. for (i=0; i< MAXWEBREPLACE; i++) { // Single variable on a line if ((ptr=strstr(line,webreplace[i]) != NULL)) return i; } return -1; } /** * Replace a variable in the buffer that begins with @@. The buffer can grow to maximum size * of BUFFERSIZEMAX. If you have a lot of pameters, either try to make your parameters names * similar to the size of the value that being replace, or increase BUFFERMAX. * * @param char *original - Original buffer string. Dimensions are done by BUFFERSIZEMAX, but treated at only BUFFERSIZE. * @param u16_t len - size of the buffer read. * @param char * newval - the new value that will swap the @@ find param. * @param u16_t newvalen - length of the new value * @param char *findparam - The @@ paramater that we are replacing * @param u16_t position - position within the string * * @return u16_t - length of the new string * */ u16_t webReplaceVar(char *original, u16_t len, char *newval, u16_t newvalen, char *findparam, u16_t position) { u16_t i=0,j=0, findparamlen=0; if ((position < 1) || (position > len)) return 0; strcpy(newbuf,original); // create a copy of the string findparamlen = strlen(findparam); // get length of the found paramater to be replace with value // Replace the parameter with the value in the original string. for (i=position; i<(newvalen+position);i++) { original[i]=newval[j++]; } // Skip over the value that was just entered j = newvalen+position; // reset the pointer to start copying the old to the new position+=findparamlen; // advance the pointer // Copy the rest of the buffer into it. for (i=position; i<len; i++) { original[j++] = newbuf[i]; } return j; } /** * Copies the unsigned long to a character string. * * Return 0 if buffer will overrun. * Return 1 if no error */ int webLTOA(uint32_t number, char *buffer, u16_t len) { u16_t n; n = sprintf (NULL,"%lu",number); // Test to see the size of the buffer requirement. if (n > (len-1)) return 0; // If the result too large, error out. n = sprintf(buffer,"%lu",number); // Copy the number to the buffer buffer[n+1] = '\0'; // Add terminator return n; } /** * Process the web parameters: This is the main system that will * take data passed in from the browsers via GET ?xxxx=yyyyy * * */ void webParamProcess(webinfo *webdata) { int i=0,j,k; char *wptr; if (webdata->numparam > 0) { for (i=0; i< webdata->numparam; i++) { for (j=0; j<MAXWEBVARIABLES; j++) { if ((k = strcmp(webdata->webvar[i],webvariables[j])) == WEB_MATCH ) { /* * To add parameterts to pull from the URI, you need to add methods here * as well as updating the webfunctions.h webvariables char array for the parameters * that you are searching for. */ switch (j) { case NODETIME: { // EPOCH uint32_t rfc868 = strtoul(webdata->webval[i], &wptr, 10); // convert the string to an unsigned long value. if (!*wptr) { // successfully converted string setCurrentRfc868(rfc868); } break; } case LED0: { // LED0 if((k = strcmp(webdata->webval[i], "ON")) == WEB_MATCH) { // Check if it on or off efmboard_Leds_set(LED1); } else { efmboard_Leds_clear(LED0); } break; } case LED1: { // LED 1 if((k = strcmp(webdata->webval[i], "ON")) == WEB_MATCH) { // Check if it on or off efmboard_Leds_set(LED1); } else { efmboard_Leds_clear(LED1); } break; } } //switch } } // end for j // Free the pointer data after processing free((char *) webdata->webvar[i]); webdata->webvar[i] = NULL; free((char *) webdata->webval[i]); webdata->webval[i] = NULL; } // End of For i webdata->numparam = 0; // Reset the variable to zero } }