Guest User

Untitled

a guest
Apr 15th, 2018
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 73.65 KB | None | 0 0
  1. /*********************************************************************
  2.  *
  3.  *  Application to Demo HTTP2 Server
  4.  *  Support for HTTP2 module in Microchip TCP/IP Stack
  5.  *   -Implements the application
  6.  *   -Reference: RFC 1002
  7.  *
  8.  *********************************************************************
  9.  * FileName:        CustomHTTPApp.c
  10.  * Dependencies:    TCP/IP stack
  11.  * Processor:       PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F, PIC32
  12.  * Compiler:        Microchip C32 v1.05 or higher
  13.  *                  Microchip C30 v3.12 or higher
  14.  *                  Microchip C18 v3.30 or higher
  15.  *                  HI-TECH PICC-18 PRO 9.63PL2 or higher
  16.  * Company:         Microchip Technology, Inc.
  17.  *
  18.  * Software License Agreement
  19.  *
  20.  * Copyright (C) 2002-2010 Microchip Technology Inc.  All rights
  21.  * reserved.
  22.  *
  23.  * Microchip licenses to you the right to use, modify, copy, and
  24.  * distribute:
  25.  * (i)  the Software when embedded on a Microchip microcontroller or
  26.  *      digital signal controller product ("Device") which is
  27.  *      integrated into Licensee's product; or
  28.  * (ii) ONLY the Software driver source files ENC28J60.c, ENC28J60.h,
  29.  *      ENCX24J600.c and ENCX24J600.h ported to a non-Microchip device
  30.  *      used in conjunction with a Microchip ethernet controller for
  31.  *      the sole purpose of interfacing with the ethernet controller.
  32.  *
  33.  * You should refer to the license agreement accompanying this
  34.  * Software for additional information regarding your rights and
  35.  * obligations.
  36.  *
  37.  * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
  38.  * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
  39.  * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
  40.  * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  41.  * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR
  42.  * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
  43.  * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
  44.  * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
  45.  * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
  46.  * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
  47.  * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
  48.  *
  49.  *
  50.  * Author               Date    Comment
  51.  *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  52.  * Elliott Wood         6/18/07 Original
  53.  ********************************************************************/
  54. #define __CUSTOMHTTPAPP_C
  55.  
  56. #include "Config.h"
  57. #include "TCPIPConfig.h"
  58. #include "Upload.h"
  59. #if defined(STACK_USE_HTTP2_SERVER)
  60.  
  61. #include "TCPIP Stack/TCPIP.h"
  62. //#include "MainDemo.h"     // Needed for SaveAppConfig() prototype
  63. #include "string.h"
  64. #include "CentrContrCon.h"
  65. //#include "FSIO.h"
  66. #include "BoxDb.h"
  67. #include "PackDb.h"
  68. #include "main.h"
  69. #include "BoxTime.h"
  70. #include "Events.h"
  71. #include "SystemData.h"
  72. #include "FAT/ff.h"
  73. #include "FAT/SD-SPI.h"
  74. #include "Debug.h"
  75. #include "ParametersParser.h"
  76. #include "HtmlPrint.h"
  77. #include "ExpanderDb.h"
  78. #include "Scanner/BarcodeScanner.h"
  79. #include "cgi.h"
  80. #include "BoxMsg.h"
  81. #include "ModbusCtrl.h"
  82. #include "SystemData.h"
  83. #include "OutTrans.h"
  84. #include "MiscHelpFunctions.h"
  85. #include "Router.h"
  86. #include "ExpanderDb.h"
  87. #include "AutoTest.h"
  88. #include "NetPrint.h"
  89. #include "MiscHelpFunctions.h"
  90. #include "HttpPrintCommon.h"
  91.  
  92. #define MAX_CGI_NAME_SIZE 20
  93.  
  94. typedef enum
  95. {
  96.     CGI_VOID_NONE_VOID = 0,   // returning void, no request parameter, no arguments
  97.     CGI_VOID_SINGLE_INT,      // returning void, one request parameter, int argument
  98.     CGI_VOID_SINGLE_VOID,     // returning void, one request parameter, void argument
  99.     CGI_VOID_SINGLE_STRING,   // returning void, one request parameter, string argument
  100.     CGI_VOID_MULTI_INT,       // returning void, many request parameters, int argument
  101.     CGI_VOID_MULTI_STRING,    // returning void, many request parameters, string argument
  102.     CGI_INT_SINGLE_INT,       // returning int, one request parameter, int argument
  103.     CGI_INT_SINGLE_STRING,     // returning int, one request parameter, string argument
  104.     CGI_INT_SINGLE_VOID      // returning int, one request parameter, no arguments      
  105. }
  106. CgiRequestType_e;
  107.  
  108. typedef struct
  109. {
  110.     char*            filename;      // cgi file name
  111.     char*            parameter;     // cgi file parameter name
  112.     CgiRequestType_e requestType;   // request type
  113.     FunctionType_t   callback;      // callback to appropriate function
  114. }
  115. CgiRequest_t;
  116.  
  117. void ResetSystemDevice(char * ptr);
  118. void VS1053SetVolume(int volume);
  119. void SetShockSensorThreshold(int threshold);
  120. void HttpSetViewedBox(char* boxName);
  121. void HTTPSetBoxState(char state);
  122. int HttpOpenBox(char* boxName);
  123. void HttpUpdateCouriers(void);
  124. void HttpSetAlarm(void);
  125. void HttpCleanAlarm(void);
  126. void HttpFormat(char * database);
  127. void HttpReset(char * action);
  128. void HttpOpenAll(void);
  129.  
  130. extern SystemData RestartSystemData;
  131.  
  132. extern INT16 SHTTempMeasure;
  133. extern UINT16 SHTHumMeasure;
  134. extern INT16 MCPTempMeasure1;
  135. extern INT16 MCPTempMeasure2;
  136. extern INT16 KTYTempMeasure1;
  137. extern INT16 KTYTempMeasure2;
  138.  
  139. extern UINT16 IValCTRL;
  140. extern UINT16 IValSCN;
  141. extern UINT16 IValRES;
  142. extern UINT16 IValLCD;
  143. extern UINT16 IValMAC;
  144. extern UINT16 IValFRES;
  145. extern UINT16 IValPRN;
  146.  
  147. extern UINT16 UValDCDC;
  148. extern UINT16 UValMAC;
  149. extern UINT16 UValSCN;
  150. extern UINT16 UVal5V;
  151. extern UINT16 UValPRN;
  152. extern UINT16 UVal12V;
  153. extern UINT16 UValCTRL;
  154. extern UINT16 UValRES;
  155.  
  156. extern UINT32 RepIO;
  157.  
  158. extern INT16 EnvTemp1;
  159. extern INT16 EnvTemp2;
  160.  
  161. /****************************************************************************
  162.   Section:
  163.         Function Prototypes and Memory Globalizers
  164.  ***************************************************************************/
  165. #if defined(HTTP_USE_POST)
  166. #if defined(USE_LCD)
  167. static HTTP_IO_RESULT HTTPPostLCD(void);
  168. #endif
  169. #if defined(STACK_USE_HTTP_MD5_DEMO)
  170. #if !defined(STACK_USE_MD5)
  171. #error The HTTP_MD5_DEMO requires STACK_USE_MD5
  172. #endif
  173. static HTTP_IO_RESULT HTTPPostMD5(void);
  174. #endif
  175. #if defined(STACK_USE_HTTP_APP_RECONFIG)
  176. extern APP_CONFIG AppConfig;
  177. extern HTTP_IO_RESULT HTTPPostConfig(void);
  178. #if defined(STACK_USE_SNMP_SERVER)
  179. static HTTP_IO_RESULT HTTPPostSNMPCommunity(void);
  180. #endif
  181. #endif
  182. #if defined(STACK_USE_HTTP_EMAIL_DEMO) || defined(STACK_USE_SMTP_CLIENT)
  183. #if !defined(STACK_USE_SMTP_CLIENT)
  184. #error The HTTP_EMAIL_DEMO requires STACK_USE_SMTP_CLIENT
  185. #endif
  186. static HTTP_IO_RESULT HTTPPostEmail(void);
  187. #endif
  188. #if defined(STACK_USE_DYNAMICDNS_CLIENT)
  189. static HTTP_IO_RESULT HTTPPostDDNSConfig(void);
  190. #endif
  191. #endif
  192.  
  193. // RAM allocated for DDNS parameters
  194. #if defined(STACK_USE_DYNAMICDNS_CLIENT)
  195. static BYTE DDNSData[100];
  196. #endif
  197.  
  198. // Sticky status message variable.
  199. // This is used to indicated whether or not the previous POST operation was
  200. // successful.  The application uses these to store status messages when a
  201. // POST operation redirects.  This lets the application provide status messages
  202. // after a redirect, when connection instance data has already been lost.
  203. static BOOL lastSuccess = FALSE;
  204.  
  205. // Stick status message variable.  See lastSuccess for details.
  206. //static BOOL lastFailure = FALSE;
  207. //FSFILE * UploadFile;
  208. //FSFILE * UploadFile;
  209.  
  210.  
  211. /****************************************************************************
  212.   Section:
  213.         Authorization Handlers
  214.  ***************************************************************************/
  215.  
  216. /*****************************************************************************
  217.   Function:
  218.         BYTE HTTPNeedsAuth(BYTE* cFile)
  219.    
  220.   Internal:
  221.         See documentation in the TCP/IP Stack API or HTTP2.h for details.
  222.  ***************************************************************************/
  223. #if defined(HTTP_USE_AUTHENTICATION)
  224.  
  225. BYTE HTTPNeedsAuth(BYTE* cFile)
  226. {
  227. #ifndef WEBSERVICE_AUTHENTICATION_DISABLED
  228.     return 0x00; // Authentication required
  229. #endif
  230.    
  231.     // If the filename begins with the folder "protect", then require auth
  232.     if (memcmppgm2ram(cFile, (ROM void*) "protect", 7) == 0)
  233.         return 0x00; // Authentication will be needed later
  234.  
  235.     // If the filename begins with the folder "snmp", then require auth
  236.     if (memcmppgm2ram(cFile, (ROM void*) "snmp", 4) == 0)
  237.         return 0x00; // Authentication will be needed later
  238.  
  239. #if defined(HTTP_MPFS_UPLOAD_REQUIRES_AUTH)
  240.     if (memcmppgm2ram(cFile, (ROM void*) "mpfsupload", 10) == 0)
  241.         return 0x00;
  242. #endif
  243.  
  244.     // You can match additional strings here to password protect other files.
  245.     // You could switch this and exclude files from authentication.
  246.     // You could also always return 0x00 to require auth for all files.
  247.     // You can return different values (0x00 to 0x79) to track "realms" for below.
  248.  
  249.     return 0x80; // No authentication required
  250. }
  251. #endif
  252.  
  253. /*****************************************************************************
  254.   Function:
  255.         BYTE HTTPCheckAuth(BYTE* cUser, BYTE* cPass)
  256.    
  257.   Internal:
  258.         See documentation in the TCP/IP Stack API or HTTP2.h for details.
  259.  ***************************************************************************/
  260. #if defined(HTTP_USE_AUTHENTICATION)
  261.  
  262. BYTE HTTPCheckAuth(BYTE* cUser, BYTE* cPass)
  263. {
  264.     if (strcmppgm2ram((char *) cUser, (ROM char *) "NEXT_user") == 0
  265.             && strcmppgm2ram((char *) cPass, (ROM char *) "Inpost,123") == 0)
  266.         return 0x80; // We accept this combination
  267.  
  268.     // You can add additional user/pass combos here.
  269.     // If you return specific "realm" values above, you can base this
  270.     //   decision on what specific file or folder is being accessed.
  271.     // You could return different values (0x80 to 0xff) to indicate
  272.     //   various users or groups, and base future processing decisions
  273.     //   in HTTPExecuteGet/Post or HTTPPrint callbacks on this value.
  274.  
  275.     return 0x00; // Provided user/pass is invalid
  276. }
  277. #endif
  278.  
  279. /****************************************************************************
  280.   Section:
  281.         GET Form Handlers
  282.  ***************************************************************************/
  283.  
  284. /*****************************************************************************
  285.   Function:
  286.         HTTP_IO_RESULT HTTPExecuteGet(void)
  287.    
  288.   Internal:
  289.         See documentation in the TCP/IP Stack API or HTTP2.h for details.
  290.  ***************************************************************************/
  291.  
  292. static const CgiRequest_t CgiRequestTable[] =
  293. {
  294. /*  |------filename------| |------parameter------| |-----requestType-----| |--------------------------callback-------------------------| */
  295.     {"scannerReset.cgi",    "",                     CGI_VOID_NONE_VOID,     .callback.voidFunctionVoid = BarcodeScannerFactorySettings},
  296.     {"scannerSetup.cgi",    "",                     CGI_VOID_NONE_VOID,     .callback.voidFunctionVoid = BarcodeScannerSetup},
  297.     {"scannerWake.cgi",     "",                     CGI_VOID_NONE_VOID,     .callback.voidFunctionVoid = BarcodeScanOn},
  298.     {"scannerSleep.cgi",    "",                     CGI_VOID_NONE_VOID,     .callback.voidFunctionVoid = BarcodeScanOff},
  299.     {"scannerBeep.cgi",     "",                     CGI_VOID_NONE_VOID,     .callback.voidFunctionVoid = BarcodeScannerBeep},
  300.     {"scannerOn.cgi",       "",                     CGI_VOID_NONE_VOID,     .callback.voidFunctionVoid = BarcodeScanPowerOn},
  301.     {"scannerOff.cgi",      "",                     CGI_VOID_NONE_VOID,     .callback.voidFunctionVoid = BarcodeScanPowerOff},
  302.     {"scannerLowBR.cgi",    "",                     CGI_VOID_NONE_VOID,     .callback.voidFunctionVoid = SetScannerBaudrate9600},
  303.     {"routerSetup.cgi",     "",                     CGI_VOID_NONE_VOID,     .callback.voidFunctionVoid = SetupRouter},
  304.     {"alarmOn.cgi",         "",                     CGI_VOID_NONE_VOID,     .callback.voidFunctionVoid = HttpSetAlarm},
  305.     {"alarmOff.cgi",        "",                     CGI_VOID_NONE_VOID,     .callback.voidFunctionVoid = HttpCleanAlarm},
  306.     {"openAllLockers.cgi",  "",                     CGI_VOID_NONE_VOID,     .callback.voidFunctionVoid = HttpOpenAll},
  307.     {"layoutReport.cgi",    "",                     CGI_VOID_NONE_VOID,     .callback.voidFunctionVoid = SendBoxLayoutReport},
  308.     {"layoutScan.cgi",      "",                     CGI_VOID_NONE_VOID,     .callback.voidFunctionVoid = SearchNewExpanderRequest},
  309.     {"resetESD.cgi",        "",                     CGI_VOID_NONE_VOID,     .callback.voidFunctionVoid = ResetCounterESDDetect},
  310.     {"updateCouriers.cgi",  "",                     CGI_VOID_NONE_VOID,     .callback.voidFunctionVoid = HttpUpdateCouriers},
  311.     {"getLog.log",          "",                     CGI_VOID_NONE_VOID,     .callback.voidFunctionVoid = HttpFindLogFile},
  312.    
  313.     {"deleteExpander.cgi",  "channel",              CGI_VOID_SINGLE_INT,    .callback.voidFunctionInt = DeleteNextExpanderInChannel},
  314.     {"historyPage.xml",     "page",                 CGI_VOID_SINGLE_INT,    .callback.voidFunctionInt = OuttransPrintPage},
  315.     {"testPrint.cgi",       "index",                CGI_VOID_SINGLE_INT,    .callback.voidFunctionInt = PrintTestReceipt},
  316.     {"confirmPack.cgi",     "pack",                 CGI_VOID_SINGLE_STRING, .callback.voidFunctionString = ConfirmTransactionManual},
  317.     {"historyPack.xml",     "pack",                 CGI_VOID_SINGLE_STRING, .callback.voidFunctionString = OuttransPrintPack},
  318.     {"format.cgi",          "format",               CGI_VOID_SINGLE_STRING, .callback.voidFunctionString = HttpFormat},
  319.     {"reset.cgi",           "action",               CGI_VOID_SINGLE_STRING, .callback.voidFunctionString = HttpReset},  
  320.     {"deviceReset.cgi",     "device",               CGI_VOID_SINGLE_STRING, .callback.voidFunctionString = ResetSystemDevice},
  321.     {"openBox.cgi",         "box",                  CGI_INT_SINGLE_STRING,  .callback.voidFunctionString = HttpOpenBox},
  322.    
  323.     {"utiliz.htm",          "box_name",             CGI_VOID_MULTI_STRING,  .callback.voidFunctionString = HttpSetViewedBox},
  324.     {"utiliz.htm",          "box_state",            CGI_VOID_MULTI_INT,     .callback.voidFunctionInt = HTTPSetBoxState},
  325.     {"setHardware.cgi",     "volume",               CGI_VOID_SINGLE_INT,    .callback.voidFunctionInt = VS1053SetVolume},
  326.     {"setHardware.cgi",     "threshold",            CGI_VOID_SINGLE_INT,    .callback.voidFunctionInt = SetShockSensorThreshold},
  327.  
  328.     /********************************************************** AUTO-TEST **********************************************************/
  329.     {AT_CGI,                "button",               CGI_INT_SINGLE_STRING,  .callback.intFunctionString = ATPushButton},
  330.     {AT_CGI,                "screen",               CGI_INT_SINGLE_STRING,  .callback.intFunctionString = ATGoToScreen},
  331.     {AT_CGI,                "barcode",              CGI_INT_SINGLE_STRING,  .callback.intFunctionString = ATScanBarcode},
  332.     {AT_CGI,                "openBox",              CGI_INT_SINGLE_STRING,  .callback.intFunctionString = ATOpenBox},
  333.     {AT_CGI,                "closeBox",             CGI_INT_SINGLE_STRING,  .callback.intFunctionString = ATCloseBox},
  334.     {AT_CGI,                "setATControlFlag",     CGI_INT_SINGLE_INT,     .callback.intFunctionInt    = ATSetControlFlag},
  335.     {AT_CGI,                "clearATControlFlag",   CGI_INT_SINGLE_INT,     .callback.intFunctionInt    = ATClearControlFlag},
  336.    
  337.     {AT_CGI,                "getProcessedPack",     CGI_INT_SINGLE_VOID,    .callback.intFunctionVoid   = ATGetProcessedPack},
  338.     {AT_CGI,                "getPackByIndex",       CGI_INT_SINGLE_INT,     .callback.intFunctionInt    = ATGetPackByIndex},
  339.     {AT_CGI,                "getPackByCode",        CGI_INT_SINGLE_STRING,  .callback.intFunctionString = ATGetPackByCode},
  340.     {AT_CGI,                "getProcessedBox",      CGI_INT_SINGLE_VOID,    .callback.intFunctionVoid   = ATGetProcessedBox},
  341.     {AT_CGI,                "getBoxByIndex",        CGI_INT_SINGLE_INT,     .callback.intFunctionInt    = ATGetBoxByIndex},
  342.     {AT_CGI,                "getBoxByName",         CGI_INT_SINGLE_STRING,  .callback.intFunctionString = ATGetBoxByName},
  343.     {AT_CGI,                "getCurrentMenu",       CGI_VOID_SINGLE_VOID,   .callback.voidFunctionVoid  = ATGetCurrentMenu},
  344.     {AT_CGI,                "getBoxList",           CGI_VOID_SINGLE_VOID,   .callback.voidFunctionVoid  = ATGetBoxList},
  345.     {AT_CGI,                "setBoxMachineTime",    CGI_VOID_SINGLE_STRING, .callback.voidFunctionString= ATSetBoxMachineTime}
  346.  };
  347.  
  348.  
  349. HTTP_IO_RESULT HTTPExecuteGet(void)
  350. {
  351.     char  filename[MAX_CGI_NAME_SIZE];
  352.     char* parameterString;
  353.     int   i;
  354.  
  355.     MPFSGetFilename(curHTTP.file, filename, sizeof(filename));
  356.        
  357.     for(i = 0; i < ARRAY_SIZE(CgiRequestTable); i++)
  358.     {
  359.         if(memcmppgm2ram(filename, CgiRequestTable[i].filename, strlen(CgiRequestTable[i].filename)))
  360.             continue;
  361.        
  362.         // Parse parameter and create log              
  363.         if(CgiRequestTable[i].requestType == CGI_VOID_NONE_VOID)
  364.         {
  365.             DEBUG_STR("Web Server", DBG_LOG, "HTTPExecuteGet calls %s.", CgiRequestTable[i].filename);
  366.         }
  367.         else if(CgiRequestTable[i].requestType == CGI_VOID_SINGLE_VOID)
  368.         {
  369.             parameterString = HTTPGetROMArg(curHTTP.data, (ROM BYTE*)CgiRequestTable[i].parameter);
  370.  
  371.             if(parameterString == NULL)
  372.                 continue;
  373.            
  374.             DEBUG_STR_STR("Web Server", DBG_LOG, "HTTPExecuteGet calls %s with %s.", CgiRequestTable[i].filename,
  375.                                                                                      CgiRequestTable[i].parameter);
  376.         }
  377.         else
  378.         {
  379.             parameterString = HTTPGetROMArg(curHTTP.data, (ROM BYTE*)CgiRequestTable[i].parameter);
  380.  
  381.             if(parameterString == NULL)
  382.                 continue;
  383.  
  384.             DEBUG_STR_STR_STR("Web Server", DBG_LOG, "HTTPExecuteGet calls %s with %s = %s.", CgiRequestTable[i].filename,
  385.                                                                                               CgiRequestTable[i].parameter,
  386.                                                                                               parameterString);
  387.         }
  388.        
  389.         // Call the appropriate function
  390.         switch(CgiRequestTable[i].requestType)
  391.         {
  392.             case CGI_VOID_NONE_VOID:
  393.             case CGI_VOID_SINGLE_VOID:
  394.                 CgiRequestTable[i].callback.voidFunctionVoid();
  395.                 return HTTP_IO_DONE;
  396.                
  397.             case CGI_VOID_SINGLE_INT:
  398.                 CgiRequestTable[i].callback.voidFunctionInt(atoi(parameterString));
  399.                 return HTTP_IO_DONE;
  400.  
  401.             case CGI_VOID_SINGLE_STRING:
  402.                 CgiRequestTable[i].callback.voidFunctionString(parameterString);
  403.                 return HTTP_IO_DONE;
  404.                
  405.             case CGI_VOID_MULTI_INT:
  406.                 CgiRequestTable[i].callback.voidFunctionInt(atoi(parameterString));
  407.                 break;
  408.                
  409.             case CGI_VOID_MULTI_STRING:
  410.                 CgiRequestTable[i].callback.voidFunctionString(parameterString);
  411.                 break;
  412.                
  413.             case CGI_INT_SINGLE_VOID:
  414.                 return CgiRequestTable[i].callback.intFunctionVoid();
  415.                
  416.             case CGI_INT_SINGLE_INT:
  417.                 return CgiRequestTable[i].callback.intFunctionInt(atoi(parameterString));
  418.                
  419.             case CGI_INT_SINGLE_STRING:
  420.                 return CgiRequestTable[i].callback.intFunctionString(parameterString);
  421.         }
  422.     }
  423.    
  424.     return HTTP_IO_DONE;
  425. }
  426.  
  427. /****************************************************************************
  428.   Section:
  429.         POST Form Handlers
  430.  ***************************************************************************/
  431. #if defined(HTTP_USE_POST)
  432.  
  433. /*****************************************************************************
  434.   Function:
  435.         HTTP_IO_RESULT HTTPExecutePost(void)
  436.    
  437.   Internal:
  438.         See documentation in the TCP/IP Stack API or HTTP2.h for details.
  439.  ***************************************************************************/
  440. HTTP_IO_RESULT HTTPExecutePost(void)
  441. {
  442.     // Resolve which function to use and pass along
  443.     BYTE filename[20];
  444.  
  445.     // Load the file name
  446.     // Make sure BYTE filename[] above is large enough for your longest name
  447.     MPFSGetFilename(curHTTP.file, filename, sizeof (filename));
  448.  
  449. #if defined(USE_LCD)
  450.     if (!memcmppgm2ram(filename, "forms.htm", 9))
  451.         return HTTPPostLCD();
  452. #endif
  453.  
  454. #if defined(STACK_USE_HTTP_MD5_DEMO)
  455.     if (!memcmppgm2ram(filename, "upload.htm", 10))
  456.         return HTTPPostMD5();
  457. #endif
  458.     if (!memcmppgm2ram(filename, HTTP_FIRMWARE_FILENAME, sizeof (HTTP_FIRMWARE_FILENAME)))
  459.         return UploadHTTPTask();
  460.  
  461.     if (!memcmppgm2ram(filename, HTTP_CONFIG_FILENAME, sizeof (HTTP_CONFIG_FILENAME)))
  462.         return HTTPPostConfig();
  463.  
  464. #if defined(STACK_USE_HTTP_APP_RECONFIG)
  465. #if defined(STACK_USE_SNMP_SERVER)
  466.     else if (!memcmppgm2ram(filename, "snmp/snmpconfig.htm", 19))
  467.         return HTTPPostSNMPCommunity();
  468. #endif
  469. #endif
  470.  
  471.     //TODO jczop (11.03.14) : create POST method for box change parameters for
  472.     // utiliz.htm, for now file is using GET method, HTTPPostChangesToBox()
  473.     // has been started being made in MachineDraw.c, but is commented out
  474.     //        if (!memcmppgm2ram(filename, "/utiliz.htm" + 1, sizeof("/utiliz.htm") - 1));
  475.     //                return HTTPPostChangesToBox();
  476.  
  477. #if defined(STACK_USE_SMTP_CLIENT)
  478.     if (!strcmppgm2ram((char*) filename, "email/index.htm"))
  479.         return HTTPPostEmail();
  480. #endif
  481.  
  482. #if defined(STACK_USE_DYNAMICDNS_CLIENT)
  483.     if (!strcmppgm2ram((char*) filename, "dyndns/index.htm"))
  484.         return HTTPPostDDNSConfig();
  485. #endif
  486.  
  487.     return HTTP_IO_DONE;
  488. }
  489.  
  490. /*****************************************************************************
  491.   Function:
  492.         static HTTP_IO_RESULT HTTPPostLCD(void)
  493.  
  494.   Summary:
  495.         Processes the LCD form on forms.htm
  496.  
  497.   Description:
  498.         Locates the 'lcd' parameter and uses it to update the text displayed
  499.         on the board's LCD display.
  500.    
  501.         This function has four states.  The first reads a name from the data
  502.         string returned as part of the POST request.  If a name cannot
  503.         be found, it returns, asking for more data.  Otherwise, if the name
  504.         is expected, it reads the associated value and writes it to the LCD.
  505.         If the name is not expected, the value is discarded and the next name
  506.         parameter is read.
  507.    
  508.         In the case where the expected string is never found, this function
  509.         will eventually return HTTP_IO_NEED_DATA when no data is left.  In that
  510.         case, the HTTP2 server will automatically trap the error and issue an
  511.         Internal Server Error to the browser.
  512.  
  513.   Precondition:
  514.         None
  515.  
  516.   Parameters:
  517.         None
  518.  
  519.   Return Values:
  520.         HTTP_IO_DONE - the parameter has been found and saved
  521.         HTTP_IO_WAITING - the function is pausing to continue later
  522.         HTTP_IO_NEED_DATA - data needed by this function has not yet arrived
  523.  ***************************************************************************/
  524. #if defined(USE_LCD)
  525.  
  526. static HTTP_IO_RESULT HTTPPostLCD(void)
  527. {
  528.     BYTE* cDest;
  529.  
  530. #define SM_POST_LCD_READ_NAME       (0u)
  531. #define SM_POST_LCD_READ_VALUE      (1u)
  532.  
  533.     switch (curHTTP.smPost)
  534.     {
  535.             // Find the name
  536.         case SM_POST_LCD_READ_NAME:
  537.  
  538.             // Read a name
  539.             if (HTTPReadPostName(curHTTP.data, HTTP_MAX_DATA_LEN) == HTTP_READ_INCOMPLETE)
  540.                 return HTTP_IO_NEED_DATA;
  541.  
  542.             curHTTP.smPost = SM_POST_LCD_READ_VALUE;
  543.             // No break...continue reading value
  544.  
  545.             // Found the value, so store the LCD and return
  546.         case SM_POST_LCD_READ_VALUE:
  547.  
  548.             // If value is expected, read it to data buffer,
  549.             // otherwise ignore it (by reading to NULL)
  550.             if (!strcmppgm2ram((char*) curHTTP.data, (ROM char*) "lcd"))
  551.                 cDest = curHTTP.data;
  552.             else
  553.                 cDest = NULL;
  554.  
  555.             // Read a value string
  556.             if (HTTPReadPostValue(cDest, HTTP_MAX_DATA_LEN) == HTTP_READ_INCOMPLETE)
  557.                 return HTTP_IO_NEED_DATA;
  558.  
  559.             // If this was an unexpected value, look for a new name
  560.             if (!cDest)
  561.             {
  562.                 curHTTP.smPost = SM_POST_LCD_READ_NAME;
  563.                 break;
  564.             }
  565.  
  566.             // Copy up to 32 characters to the LCD
  567.             if (strlen((char*) cDest) < 32u)
  568.             {
  569.                 memset(LCDText, ' ', 32);
  570.                 strcpy((char*) LCDText, (char*) cDest);
  571.             }
  572.             else
  573.             {
  574.                 memcpy(LCDText, (void *) cDest, 32);
  575.             }
  576.             LCDUpdate();
  577.  
  578.             // This is the only expected value, so callback is done
  579.             strcpypgm2ram((char*) curHTTP.data, "/forms.htm");
  580.             curHTTP.httpStatus = HTTP_REDIRECT;
  581.             return HTTP_IO_DONE;
  582.     }
  583.  
  584.     // Default assumes that we're returning for state machine convenience.
  585.     // Function will be called again later.
  586.     return HTTP_IO_WAITING;
  587. }
  588. #endif
  589.  
  590. /*****************************************************************************
  591.   Function:
  592.         static HTTP_IO_RESULT HTTPPostConfig(void)
  593.  
  594.   Summary:
  595.         Processes the configuration form on config/index.htm
  596.  
  597.   Description:
  598.         Accepts configuration parameters from the form, saves them to a
  599.         temporary location in RAM, then eventually saves the data to EEPROM or
  600.         external Flash.
  601.    
  602.         When complete, this function redirects to config/reboot.htm, which will
  603.         display information on reconnecting to the board.
  604.  
  605.         This function creates a shadow copy of the AppConfig structure in
  606.         RAM and then overwrites incoming data there as it arrives.  For each
  607.         name/value pair, the name is first read to curHTTP.data[0:5].  Next, the
  608.         value is read to newAppConfig.  Once all data has been read, the new
  609.         AppConfig is saved back to EEPROM and the browser is redirected to
  610.         reboot.htm.  That file includes an AJAX call to reboot.cgi, which
  611.         performs the actual reboot of the machine.
  612.    
  613.         If an IP address cannot be parsed, too much data is POSTed, or any other
  614.         parsing error occurs, the browser reloads config.htm and displays an error
  615.         message at the top.
  616.  
  617.   Precondition:
  618.         None
  619.  
  620.   Parameters:
  621.         None
  622.  
  623.   Return Values:
  624.         HTTP_IO_DONE - all parameters have been processed
  625.         HTTP_IO_NEED_DATA - data needed by this function has not yet arrived
  626.  ***************************************************************************/
  627. #if defined(_STACK_USE_HTTP_APP_RECONFIG)
  628.  
  629. static HTTP_IO_RESULT HTTPPostConfig(void)
  630. {
  631.     APP_CONFIG newAppConfig;
  632.     BYTE *ptr;
  633.     BYTE i;
  634.  
  635.     // Check to see if the browser is attempting to submit more data than we
  636.     // can parse at once.  This function needs to receive all updated
  637.     // parameters and validate them all before committing them to memory so that
  638.     // orphaned configuration parameters do not get written (for example, if a
  639.     // static IP address is given, but the subnet mask fails parsing, we
  640.     // should not use the static IP address).  Everything needs to be processed
  641.     // in a single transaction.  If this is impossible, fail and notify the user.
  642.     // As a web devloper, if you add parameters to AppConfig and run into this
  643.     // problem, you could fix this by to splitting your update web page into two
  644.     // seperate web pages (causing two transactional writes).  Alternatively,
  645.     // you could fix it by storing a static shadow copy of AppConfig someplace
  646.     // in memory and using it instead of newAppConfig.  Lastly, you could
  647.     // increase the TCP RX FIFO size for the HTTP server.  This will allow more
  648.     // data to be POSTed by the web browser before hitting this limit.
  649.     if (curHTTP.byteCount > TCPIsGetReady(sktHTTP) + TCPGetRxFIFOFree(sktHTTP))
  650.         goto ConfigFailure;
  651.  
  652.     // Ensure that all data is waiting to be parsed.  If not, keep waiting for
  653.     // all of it to arrive.
  654.     if (TCPIsGetReady(sktHTTP) < curHTTP.byteCount)
  655.         return HTTP_IO_NEED_DATA;
  656.  
  657.  
  658.     // Use current config in non-volatile memory as defaults
  659. #if defined(EEPROM_CS_TRIS)
  660.     XEEReadArray(sizeof (NVM_VALIDATION_STRUCT), (BYTE*) & newAppConfig, sizeof (newAppConfig));
  661. #elif defined(SPIFLASH_CS_TRIS)
  662.     SPIFlashReadArray(sizeof (NVM_VALIDATION_STRUCT), (BYTE*) & newAppConfig, sizeof (newAppConfig));
  663. #endif
  664.  
  665.     // Start out assuming that DHCP is disabled.  This is necessary since the
  666.     // browser doesn't submit this field if it is unchecked (meaning zero).
  667.     // However, if it is checked, this will be overridden since it will be
  668.     // submitted.
  669.     newAppConfig.Flags.bIsDHCPEnabled = 0;
  670.  
  671.  
  672.     // Read all browser POST data
  673.     while (curHTTP.byteCount)
  674.     {
  675.         // Read a form field name
  676.         if (HTTPReadPostName(curHTTP.data, 6) != HTTP_READ_OK)
  677.             goto ConfigFailure;
  678.  
  679.         // Read a form field value
  680.         if (HTTPReadPostValue(curHTTP.data + 6, sizeof (curHTTP.data) - 6 - 2) != HTTP_READ_OK)
  681.             goto ConfigFailure;
  682.  
  683.         // Parse the value that was read
  684.         if (!strcmppgm2ram((char*) curHTTP.data, (ROM char*) "ip"))
  685.         {// Read new static IP Address
  686.             if (!StringToIPAddress(curHTTP.data + 6, &newAppConfig.MyIPAddr))
  687.                 goto ConfigFailure;
  688.  
  689.             newAppConfig.DefaultIPAddr.Val = newAppConfig.MyIPAddr.Val;
  690.         }
  691.         else if (!strcmppgm2ram((char*) curHTTP.data, (ROM char*) "gw"))
  692.         {// Read new gateway address
  693.             if (!StringToIPAddress(curHTTP.data + 6, &newAppConfig.MyGateway))
  694.                 goto ConfigFailure;
  695.         }
  696.         else if (!strcmppgm2ram((char*) curHTTP.data, (ROM char*) "sub"))
  697.         {// Read new static subnet
  698.             if (!StringToIPAddress(curHTTP.data + 6, &newAppConfig.MyMask))
  699.                 goto ConfigFailure;
  700.  
  701.             newAppConfig.DefaultMask.Val = newAppConfig.MyMask.Val;
  702.         }
  703.         else if (!strcmppgm2ram((char*) curHTTP.data, (ROM char*) "dns1"))
  704.         {// Read new primary DNS server
  705.             if (!StringToIPAddress(curHTTP.data + 6, &newAppConfig.PrimaryDNSServer))
  706.                 goto ConfigFailure;
  707.         }
  708.         else if (!strcmppgm2ram((char*) curHTTP.data, (ROM char*) "dns2"))
  709.         {// Read new secondary DNS server
  710.             if (!StringToIPAddress(curHTTP.data + 6, &newAppConfig.SecondaryDNSServer))
  711.                 goto ConfigFailure;
  712.         }
  713.         else if (!strcmppgm2ram((char*) curHTTP.data, (ROM char*) "mac"))
  714.         {
  715.             // Read new MAC address
  716.             WORD w;
  717.             BYTE i;
  718.  
  719.             ptr = curHTTP.data + 6;
  720.  
  721.             for (i = 0; i < 12u; i++)
  722.             {// Read the MAC address
  723.  
  724.                 // Skip non-hex bytes
  725.                 while (*ptr != 0x00u && !(*ptr >= '0' && *ptr <= '9') && !(*ptr >= 'A' && *ptr <= 'F') && !(*ptr >= 'a' && *ptr <= 'f'))
  726.                     ptr++;
  727.  
  728.                 // MAC string is over, so zeroize the rest
  729.                 if (*ptr == 0x00u)
  730.                 {
  731.                     for (; i < 12u; i++)
  732.                         curHTTP.data[i] = '0';
  733.                     break;
  734.                 }
  735.  
  736.                 // Save the MAC byte
  737.                 curHTTP.data[i] = *ptr++;
  738.             }
  739.  
  740.             // Read MAC Address, one byte at a time
  741.             for (i = 0; i < 6u; i++)
  742.             {
  743.                 ((BYTE*) & w)[1] = curHTTP.data[i * 2];
  744.                 ((BYTE*) & w)[0] = curHTTP.data[i * 2 + 1];
  745.                 newAppConfig.MyMACAddr.v[i] = hexatob(*((WORD_VAL*) & w));
  746.             }
  747.         }
  748.         else if (!strcmppgm2ram((char*) curHTTP.data, (ROM char*) "host"))
  749.         {// Read new hostname
  750.             FormatNetBIOSName(&curHTTP.data[6]);
  751.             memcpy((void*) newAppConfig.NetBIOSName, (void*) curHTTP.data + 6, 16);
  752.         }
  753.         else if (!strcmppgm2ram((char*) curHTTP.data, (ROM char*) "dhcp"))
  754.         {// Read new DHCP Enabled flag
  755.             if (curHTTP.data[6] == '1')
  756.                 newAppConfig.Flags.bIsDHCPEnabled = 1;
  757.         }
  758.     }
  759.  
  760.  
  761.     // All parsing complete!  Save new settings and force a reboot
  762.     SaveAppConfig(&newAppConfig);
  763.  
  764.     // Set the board to reboot and display reconnecting information
  765.     strcpypgm2ram((char*) curHTTP.data, "/protect/reboot.htm?");
  766.     memcpy((void*) (curHTTP.data + 20), (void*) newAppConfig.NetBIOSName, 16);
  767.     curHTTP.data[20 + 16] = 0x00; // Force null termination
  768.     for (i = 20; i < 20u + 16u; i++)
  769.     {
  770.         if (curHTTP.data[i] == ' ')
  771.             curHTTP.data[i] = 0x00;
  772.     }
  773.     curHTTP.httpStatus = HTTP_REDIRECT;
  774.  
  775.     return HTTP_IO_DONE;
  776.  
  777.  
  778. ConfigFailure:
  779.     lastFailure = TRUE;
  780.     strcpypgm2ram((char*) curHTTP.data, "/protect/config.htm");
  781.     curHTTP.httpStatus = HTTP_REDIRECT;
  782.  
  783.     return HTTP_IO_DONE;
  784. }
  785.  
  786. #if defined(STACK_USE_SNMP_SERVER)
  787.  
  788. static HTTP_IO_RESULT HTTPPostSNMPCommunity(void)
  789. {
  790.     BYTE vCommunityIndex;
  791.     BYTE *dest;
  792.  
  793. #define SM_CFG_SNMP_READ_NAME   (0u)
  794. #define SM_CFG_SNMP_READ_VALUE  (1u)
  795.  
  796.     switch (curHTTP.smPost)
  797.     {
  798.         case SM_CFG_SNMP_READ_NAME:
  799.             // If all parameters have been read, end
  800.             if (curHTTP.byteCount == 0u)
  801.             {
  802.                 SaveAppConfig(&AppConfig);
  803.                 return HTTP_IO_DONE;
  804.             }
  805.  
  806.             // Read a name
  807.             if (HTTPReadPostName(curHTTP.data, sizeof (curHTTP.data) - 2) == HTTP_READ_INCOMPLETE)
  808.                 return HTTP_IO_NEED_DATA;
  809.  
  810.             // Move to reading a value, but no break
  811.             curHTTP.smPost = SM_CFG_SNMP_READ_VALUE;
  812.  
  813.         case SM_CFG_SNMP_READ_VALUE:
  814.             // Read a value
  815.             if (HTTPReadPostValue(curHTTP.data + 6, sizeof (curHTTP.data) - 6 - 2) == HTTP_READ_INCOMPLETE)
  816.                 return HTTP_IO_NEED_DATA;
  817.  
  818.             // Default action after this is to read the next name, unless there's an error
  819.             curHTTP.smPost = SM_CFG_SNMP_READ_NAME;
  820.  
  821.             // See if this is a known parameter and legal (must be null
  822.             // terminator in 4th field name byte, string must no greater than
  823.             // SNMP_COMMUNITY_MAX_LEN bytes long, and SNMP_MAX_COMMUNITY_SUPPORT
  824.             // must not be violated.
  825.             vCommunityIndex = curHTTP.data[3] - '0';
  826.             if (vCommunityIndex >= SNMP_MAX_COMMUNITY_SUPPORT)
  827.                 break;
  828.             if (curHTTP.data[4] != 0x00u)
  829.                 break;
  830.             if (memcmppgm2ram((void*) curHTTP.data, (ROM void*) "rcm", 3) == 0)
  831.                 dest = AppConfig.readCommunity[vCommunityIndex];
  832.             else if (memcmppgm2ram((void*) curHTTP.data, (ROM void*) "wcm", 3) == 0)
  833.                 dest = AppConfig.writeCommunity[vCommunityIndex];
  834.             else
  835.                 break;
  836.             if (strlen((char*) curHTTP.data + 6) > SNMP_COMMUNITY_MAX_LEN)
  837.                 break;
  838.  
  839.             // String seems valid, lets copy it to AppConfig
  840.             strcpy((char*) dest, (char*) curHTTP.data + 6);
  841.             break;
  842.     }
  843.  
  844.     return HTTP_IO_WAITING; // Assume we're waiting to process more data
  845. }
  846. #endif //#if defined(STACK_USE_SNMP_SERVER)
  847.  
  848. #endif  // #if defined(STACK_USE_HTTP_APP_RECONFIG)
  849.  
  850. /*****************************************************************************
  851.   Function:
  852.         static HTTP_IO_RESULT HTTPPostMD5(void)
  853.  
  854.   Summary:
  855.         Processes the file upload form on upload.htm
  856.  
  857.   Description:
  858.         This function demonstrates the processing of file uploads.  First, the
  859.         function locates the file data, skipping over any headers that arrive.
  860.         Second, it reads the file 64 bytes at a time and hashes that data.  Once
  861.         all data has been received, the function calculates the MD5 sum and
  862.         stores it in curHTTP.data.
  863.  
  864.         After the headers, the first line from the form will be the MIME
  865.         separator.  Following that is more headers about the file, which we
  866.         discard.  After another CRLFCRLF, the file data begins, and we read
  867.         it 16 bytes at a time and add that to the MD5 calculation.  The reading
  868.         terminates when the separator string is encountered again on its own
  869.         line.  Notice that the actual file data is trashed in this process,
  870.         allowing us to accept files of arbitrary size, not limited by RAM.
  871.         Also notice that the data buffer is used as an arbitrary storage array
  872.         for the result.  The ~uploadedmd5~ callback reads this data later to
  873.         send back to the client.
  874.    
  875.   Precondition:
  876.         None
  877.  
  878.   Parameters:
  879.         None
  880.  
  881.   Return Values:
  882.         HTTP_IO_DONE - all parameters have been processed
  883.         HTTP_IO_WAITING - the function is pausing to continue later
  884.         HTTP_IO_NEED_DATA - data needed by this function has not yet arrived
  885.  ***************************************************************************/
  886. #if defined(STACK_USE_HTTP_MD5_DEMO)
  887.  
  888. static HTTP_IO_RESULT HTTPPostMD5(void)
  889. {
  890.     WORD lenA, lenB, lenC;
  891.     int i;
  892.     static HASH_SUM md5; // Assume only one simultaneous MD5
  893.  
  894. #define SM_MD5_READ_SEPARATOR   (0u)
  895. #define SM_MD5_SKIP_TO_DATA     (1u)
  896. #define SM_MD5_READ_DATA        (2u)
  897. #define SM_MD5_POST_COMPLETE    (3u)
  898.  
  899.     // Don't care about curHTTP.data at this point, so use that for buffer
  900.     switch (curHTTP.smPost)
  901.     {
  902.             // Just started, so try to find the separator string
  903.         case SM_MD5_READ_SEPARATOR:
  904.             // Reset the MD5 calculation
  905.             MD5Initialize(&md5);
  906.  
  907.             // See if a CRLF is in the buffer
  908.             lenA = TCPFindROMArray(sktHTTP, (ROM BYTE*) "\r\n", 2, 0, FALSE);
  909.             if (lenA == 0xffff)
  910.             {//if not, ask for more data
  911.                 return HTTP_IO_NEED_DATA;
  912.             }
  913.  
  914.             // If so, figure out where the last byte of data is
  915.             // Data ends at CRLFseparator--CRLF, so 6+len bytes
  916.             curHTTP.byteCount -= lenA + 6;
  917.  
  918.             // Read past the CRLF
  919.             curHTTP.byteCount -= TCPGetArray(sktHTTP, NULL, lenA + 2);
  920.  
  921.             // Save the next state (skip to CRLFCRLF)
  922.             curHTTP.smPost = SM_MD5_SKIP_TO_DATA;
  923.  
  924.             // No break...continue reading the headers if possible
  925.  
  926.             // Skip the headers
  927.         case SM_MD5_SKIP_TO_DATA:
  928.             // Look for the CRLFCRLF
  929.             lenA = TCPFindROMArray(sktHTTP, (ROM BYTE*) "\r\n\r\n", 4, 0, FALSE);
  930.  
  931.             if (lenA != 0xffff)
  932.             {// Found it, so remove all data up to and including
  933.                 lenA = TCPGetArray(sktHTTP, NULL, lenA + 4);
  934.                 curHTTP.byteCount -= lenA;
  935.                 curHTTP.smPost = SM_MD5_READ_DATA;
  936.                 DownloadFile = FSfopen("Upload.hex", "w+");
  937.             }
  938.             else
  939.             {// Otherwise, remove as much as possible
  940.                 lenA = TCPGetArray(sktHTTP, NULL, TCPIsGetReady(sktHTTP) - 4);
  941.                 curHTTP.byteCount -= lenA;
  942.  
  943.                 // Return the need more data flag
  944.                 return HTTP_IO_NEED_DATA;
  945.             }
  946.  
  947.             // No break if we found the header terminator
  948.  
  949.             // Read and hash file data
  950.         case SM_MD5_READ_DATA:
  951.             // Find out how many bytes are available to be read
  952.             lenA = TCPIsGetReady(sktHTTP);
  953.             if (lenA > curHTTP.byteCount)
  954.                 lenA = curHTTP.byteCount;
  955.  
  956.             while (lenA > 0u)
  957.             {// Add up to 128 bytes at a time to the sum
  958.                 lenB = TCPGetArray(sktHTTP, curHTTP.data, (lenA < 64u) ? lenA : 64);
  959.                 curHTTP.byteCount -= lenB;
  960.                 lenA -= lenB;
  961.                 MD5AddData(&md5, curHTTP.data, lenB);
  962.                 if (DownloadFile != NULL)
  963.                 {
  964.                     lenC = FSfwrite(curHTTP.data, 1, lenB, DownloadFile);
  965.                     //                                  LAT_LED ^= 1;
  966.                 }
  967.  
  968.             }
  969.  
  970.             // If we've read all the data
  971.             if (curHTTP.byteCount == 0u)
  972.             {// Calculate and copy result to curHTTP.data for printout
  973.                 curHTTP.smPost = SM_MD5_POST_COMPLETE;
  974.                 MD5Calculate(&md5, curHTTP.data);
  975.                 FSfclose(DownloadFile);
  976.                 strcpypgm2ram((char*) curHTTP.data, "reboot.htm?192.168.0.2");
  977.                 //                                //memcpy((void*)(curHTTP.data+20), (void*)AppConfig.NetBIOSName, 16);
  978.                 //                                memcpy((void*)(curHTTP.data+11), "192.168.0.2 ", 16);
  979.                 //                                curHTTP.data[11+16] = 0x00;   // Force null termination
  980.                 //                                for(i = 20; i < 20u+16u; i++)
  981.                 //                                {
  982.                 //                                    if(curHTTP.data[i] == ' ')
  983.                 //                                    curHTTP.data[i] = 0x00;
  984.                 //                                }
  985.                 curHTTP.httpStatus = HTTP_REDIRECT;
  986.  
  987.                 return HTTP_IO_DONE;
  988.             }
  989.  
  990.             // Ask for more data
  991.             return HTTP_IO_NEED_DATA;
  992.     }
  993.  
  994.     return HTTP_IO_DONE;
  995. }
  996.  
  997. #endif // #if defined(STACK_USE_HTTP_MD5_DEMO)
  998.  
  999. /*****************************************************************************
  1000.   Function:
  1001.         static HTTP_IO_RESULT HTTPPostEmail(void)
  1002.  
  1003.   Summary:
  1004.         Processes the e-mail form on email/index.htm
  1005.  
  1006.   Description:
  1007.         This function sends an e-mail message using the SMTP client and
  1008.         optionally encrypts the connection to the SMTP server using SSL.  It
  1009.         demonstrates the use of the SMTP client, waiting for asynchronous
  1010.         processes in an HTTP callback, and how to send e-mail attachments using
  1011.         the stack.
  1012.  
  1013.         Messages with attachments are sent using multipart/mixed MIME encoding,
  1014.         which has three sections.  The first has no headers, and is only to be
  1015.         displayed by old clients that cannot interpret the MIME format.  (The
  1016.         overwhelming majority of these clients have been obseleted, but the
  1017.         so-called "ignored" section is still used.)  The second has a few
  1018.         headers to indicate that it is the main body of the message in plain-
  1019.         text encoding.  The third section has headers indicating an attached
  1020.         file, along with its name and type.  All sections are separated by a
  1021.         boundary string, which cannot appear anywhere else in the message.
  1022.    
  1023.   Precondition:
  1024.         None
  1025.  
  1026.   Parameters:
  1027.         None
  1028.  
  1029.   Return Values:
  1030.         HTTP_IO_DONE - the message has been sent
  1031.         HTTP_IO_WAITING - the function is waiting for the SMTP process to complete
  1032.         HTTP_IO_NEED_DATA - data needed by this function has not yet arrived
  1033.  ***************************************************************************/
  1034. #if defined(STACK_USE_SMTP_CLIENT)
  1035.  
  1036. static HTTP_IO_RESULT HTTPPostEmail(void)
  1037. {
  1038.     static BYTE *ptrData;
  1039.     static BYTE *szPort;
  1040. #if defined(STACK_USE_SSL_CLIENT)
  1041.     static BYTE *szUseSSL;
  1042. #endif
  1043.     WORD len, rem;
  1044.     BYTE cName[8];
  1045.  
  1046. #define SM_EMAIL_CLAIM_MODULE               (0u)
  1047. #define SM_EMAIL_READ_PARAM_NAME            (1u)
  1048. #define SM_EMAIL_READ_PARAM_VALUE           (2u)
  1049. #define SM_EMAIL_PUT_IGNORED                (3u)
  1050. #define SM_EMAIL_PUT_BODY                   (4u)
  1051. #define SM_EMAIL_PUT_ATTACHMENT_HEADER      (5u)
  1052. #define SM_EMAIL_PUT_ATTACHMENT_DATA_BTNS   (6u)
  1053. #define SM_EMAIL_PUT_ATTACHMENT_DATA_LEDS   (7u)
  1054. #define SM_EMAIL_PUT_ATTACHMENT_DATA_POT    (8u)
  1055. #define SM_EMAIL_PUT_TERMINATOR             (9u)
  1056. #define SM_EMAIL_FINISHING                  (10u)
  1057.  
  1058. #define EMAIL_SPACE_REMAINING               (HTTP_MAX_DATA_LEN - (ptrData - curHTTP.data))
  1059.  
  1060.     switch (curHTTP.smPost)
  1061.     {
  1062.         case SM_EMAIL_CLAIM_MODULE:
  1063.             // Try to claim module
  1064.             if (SMTPBeginUsage())
  1065.             {// Module was claimed, so set up static parameters
  1066.                 SMTPClient.Subject.szROM = (ROM BYTE*) "Microchip TCP/IP Stack Status Update";
  1067.                 SMTPClient.ROMPointers.Subject = 1;
  1068.                 SMTPClient.From.szROM = (ROM BYTE*) "\"SMTP Service\" <mchpboard@picsaregood.com>";
  1069.                 SMTPClient.ROMPointers.From = 1;
  1070.  
  1071.                 // The following two lines indicate to the receiving client that
  1072.                 // this message has an attachment.  The boundary field *must not*
  1073.                 // be included anywhere in the content of the message.  In real
  1074.                 // applications it is typically a long random string.
  1075.                 SMTPClient.OtherHeaders.szROM = (ROM BYTE*) "MIME-version: 1.0\r\nContent-type: multipart/mixed; boundary=\"frontier\"\r\n";
  1076.                 SMTPClient.ROMPointers.OtherHeaders = 1;
  1077.  
  1078.                 // Move our state machine forward
  1079.                 ptrData = curHTTP.data;
  1080.                 szPort = NULL;
  1081.                 curHTTP.smPost = SM_EMAIL_READ_PARAM_NAME;
  1082.             }
  1083.             return HTTP_IO_WAITING;
  1084.  
  1085.         case SM_EMAIL_READ_PARAM_NAME:
  1086.             // Search for a parameter name in POST data
  1087.             if (HTTPReadPostName(cName, sizeof (cName)) == HTTP_READ_INCOMPLETE)
  1088.                 return HTTP_IO_NEED_DATA;
  1089.  
  1090.             // Try to match the name value
  1091.             if (!strcmppgm2ram((char*) cName, (ROM char*) "server"))
  1092.             {// Read the server name
  1093.                 SMTPClient.Server.szRAM = ptrData;
  1094.                 curHTTP.smPost = SM_EMAIL_READ_PARAM_VALUE;
  1095.             }
  1096.             else if (!strcmppgm2ram((char*) cName, (ROM char*) "port"))
  1097.             {// Read the server port
  1098.                 szPort = ptrData;
  1099.                 curHTTP.smPost = SM_EMAIL_READ_PARAM_VALUE;
  1100.             }
  1101. #if defined(STACK_USE_SSL_CLIENT)
  1102.             else if (!strcmppgm2ram((char*) cName, (ROM char*) "ssl"))
  1103.             {// Read the server port
  1104.                 szUseSSL = ptrData;
  1105.                 curHTTP.smPost = SM_EMAIL_READ_PARAM_VALUE;
  1106.             }
  1107. #endif
  1108.             else if (!strcmppgm2ram((char*) cName, (ROM char*) "user"))
  1109.             {// Read the user name
  1110.                 SMTPClient.Username.szRAM = ptrData;
  1111.                 curHTTP.smPost = SM_EMAIL_READ_PARAM_VALUE;
  1112.             }
  1113.             else if (!strcmppgm2ram((char*) cName, (ROM char*) "pass"))
  1114.             {// Read the password
  1115.                 SMTPClient.Password.szRAM = ptrData;
  1116.                 curHTTP.smPost = SM_EMAIL_READ_PARAM_VALUE;
  1117.             }
  1118.             else if (!strcmppgm2ram((char*) cName, (ROM char*) "to"))
  1119.             {// Read the To string
  1120.                 SMTPClient.To.szRAM = ptrData;
  1121.                 curHTTP.smPost = SM_EMAIL_READ_PARAM_VALUE;
  1122.             }
  1123.             else if (!strcmppgm2ram((char*) cName, (ROM char*) "msg"))
  1124.             {// Done with headers, move on to the message
  1125.                 // Delete paramters that are just null strings (no data from user) or illegal (ex: password without username)
  1126.                 if (SMTPClient.Server.szRAM)
  1127.                     if (*SMTPClient.Server.szRAM == 0x00u)
  1128.                         SMTPClient.Server.szRAM = NULL;
  1129.                 if (SMTPClient.Username.szRAM)
  1130.                     if (*SMTPClient.Username.szRAM == 0x00u)
  1131.                         SMTPClient.Username.szRAM = NULL;
  1132.                 if (SMTPClient.Password.szRAM)
  1133.                     if ((*SMTPClient.Password.szRAM == 0x00u) || (SMTPClient.Username.szRAM == NULL))
  1134.                         SMTPClient.Password.szRAM = NULL;
  1135.  
  1136.                 // Decode server port string if it exists
  1137.                 if (szPort)
  1138.                     if (*szPort)
  1139.                         SMTPClient.ServerPort = (WORD) atol((char*) szPort);
  1140.  
  1141.                 // Determine if SSL should be used
  1142. #if defined(STACK_USE_SSL_CLIENT)
  1143.                 if (szUseSSL)
  1144.                     if (*szUseSSL == '1')
  1145.                         SMTPClient.UseSSL = TRUE;
  1146. #endif
  1147.  
  1148.                 // Start sending the message
  1149.                 SMTPSendMail();
  1150.                 curHTTP.smPost = SM_EMAIL_PUT_IGNORED;
  1151.                 return HTTP_IO_WAITING;
  1152.             }
  1153.             else
  1154.             {// Don't know what we're receiving
  1155.                 curHTTP.smPost = SM_EMAIL_READ_PARAM_VALUE;
  1156.             }
  1157.  
  1158.             // No break...continue to try reading the value
  1159.  
  1160.         case SM_EMAIL_READ_PARAM_VALUE:
  1161.             // Search for a parameter value in POST data
  1162.             if (HTTPReadPostValue(ptrData, EMAIL_SPACE_REMAINING) == HTTP_READ_INCOMPLETE)
  1163.                 return HTTP_IO_NEED_DATA;
  1164.  
  1165.             // Move past the data that was just read
  1166.             ptrData += strlen((char*) ptrData);
  1167.             if (ptrData < curHTTP.data + HTTP_MAX_DATA_LEN - 1)
  1168.                 ptrData += 1;
  1169.  
  1170.             // Try reading the next parameter
  1171.             curHTTP.smPost = SM_EMAIL_READ_PARAM_NAME;
  1172.             return HTTP_IO_WAITING;
  1173.  
  1174.         case SM_EMAIL_PUT_IGNORED:
  1175.             // This section puts a message that is ignored by compatible clients.
  1176.             // This text will not display unless the receiving client is obselete
  1177.             // and does not understand the MIME structure.
  1178.             // The "--frontier" indicates the start of a section, then any
  1179.             // needed MIME headers follow, then two CRLF pairs, and then
  1180.             // the actual content (which will be the body text in the next state).
  1181.  
  1182.             // Check to see if a failure occured
  1183.             if (!SMTPIsBusy())
  1184.             {
  1185.                 curHTTP.smPost = SM_EMAIL_FINISHING;
  1186.                 return HTTP_IO_WAITING;
  1187.             }
  1188.  
  1189.             // See if we're ready to write data
  1190.             if (SMTPIsPutReady() < 90u)
  1191.                 return HTTP_IO_WAITING;
  1192.  
  1193.             // Write the ignored text
  1194.             SMTPPutROMString((ROM BYTE*) "This is a multi-part message in MIME format.\r\n");
  1195.             SMTPPutROMString((ROM BYTE*) "--frontier\r\nContent-type: text/plain\r\n\r\n");
  1196.             SMTPFlush();
  1197.  
  1198.             // Move to the next state
  1199.             curHTTP.smPost = SM_EMAIL_PUT_BODY;
  1200.  
  1201.         case SM_EMAIL_PUT_BODY:
  1202.             // Write as much body text as is available from the TCP buffer
  1203.             // return HTTP_IO_NEED_DATA or HTTP_IO_WAITING
  1204.             // On completion, => PUT_ATTACHMENT_HEADER and continue
  1205.  
  1206.             // Check to see if a failure occurred
  1207.             if (!SMTPIsBusy())
  1208.             {
  1209.                 curHTTP.smPost = SM_EMAIL_FINISHING;
  1210.                 return HTTP_IO_WAITING;
  1211.             }
  1212.  
  1213.             // Loop as long as data remains to be read
  1214.             while (curHTTP.byteCount)
  1215.             {
  1216.                 // See if space is available to write
  1217.                 len = SMTPIsPutReady();
  1218.                 if (len == 0u)
  1219.                     return HTTP_IO_WAITING;
  1220.  
  1221.                 // See if data is ready to be read
  1222.                 rem = TCPIsGetReady(sktHTTP);
  1223.                 if (rem == 0u)
  1224.                     return HTTP_IO_NEED_DATA;
  1225.  
  1226.                 // Only write as much as we can handle
  1227.                 if (len > rem)
  1228.                     len = rem;
  1229.                 if (len > HTTP_MAX_DATA_LEN - 2)
  1230.                     len = HTTP_MAX_DATA_LEN - 2;
  1231.  
  1232.                 // Read the data from HTTP POST buffer and send it to SMTP
  1233.                 curHTTP.byteCount -= TCPGetArray(sktHTTP, curHTTP.data, len);
  1234.                 curHTTP.data[len] = '\0';
  1235.                 HTTPURLDecode(curHTTP.data);
  1236.                 SMTPPutString(curHTTP.data);
  1237.                 SMTPFlush();
  1238.             }
  1239.  
  1240.             // We're done with the POST data, so continue
  1241.             curHTTP.smPost = SM_EMAIL_PUT_ATTACHMENT_HEADER;
  1242.  
  1243.         case SM_EMAIL_PUT_ATTACHMENT_HEADER:
  1244.             // This section writes the attachment to the message.
  1245.             // This portion generally will not display in the reader, but
  1246.             // will be downloadable to the local machine.  Use caution
  1247.             // when selecting the content-type and file name, as certain
  1248.             // types and extensions are blocked by virus filters.
  1249.  
  1250.             // The same structure as the message body is used.
  1251.             // Any attachment must not include high-bit ASCII characters or
  1252.             // binary data.  If binary data is to be sent, the data should
  1253.             // be encoded using Base64 and a MIME header should be added:
  1254.             // Content-transfer-encoding: base64
  1255.  
  1256.             // Check to see if a failure occurred
  1257.             if (!SMTPIsBusy())
  1258.             {
  1259.                 curHTTP.smPost = SM_EMAIL_FINISHING;
  1260.                 return HTTP_IO_WAITING;
  1261.             }
  1262.  
  1263.             // See if we're ready to write data
  1264.             if (SMTPIsPutReady() < 100u)
  1265.                 return HTTP_IO_WAITING;
  1266.  
  1267.             // Write the attachment header
  1268.             SMTPPutROMString((ROM BYTE*) "\r\n--frontier\r\nContent-type: text/csv\r\nContent-Disposition: attachment; filename=\"status.csv\"\r\n\r\n");
  1269.             SMTPFlush();
  1270.  
  1271.             // Move to the next state
  1272.             curHTTP.smPost = SM_EMAIL_PUT_ATTACHMENT_DATA_BTNS;
  1273.  
  1274.         case SM_EMAIL_PUT_ATTACHMENT_DATA_BTNS:
  1275.             // The following states output the system status as a CSV file.
  1276.  
  1277.             // Check to see if a failure occurred
  1278.             if (!SMTPIsBusy())
  1279.             {
  1280.                 curHTTP.smPost = SM_EMAIL_FINISHING;
  1281.                 return HTTP_IO_WAITING;
  1282.             }
  1283.  
  1284.             // See if we're ready to write data
  1285.             if (SMTPIsPutReady() < 36u)
  1286.                 return HTTP_IO_WAITING;
  1287.  
  1288.             // Write the header and button strings
  1289.             SMTPPutROMString((ROM BYTE*) "SYSTEM STATUS\r\n");
  1290.             SMTPPutROMString((ROM BYTE*) "Buttons:,");
  1291.             SMTPPut(BUTTON0_IO + '0');
  1292.             SMTPPut(',');
  1293.             SMTPPut(BUTTON1_IO + '0');
  1294.             SMTPPut(',');
  1295.             SMTPPut(BUTTON2_IO + '0');
  1296.             SMTPPut(',');
  1297.             SMTPPut(BUTTON3_IO + '0');
  1298.             SMTPPut('\r');
  1299.             SMTPPut('\n');
  1300.             SMTPFlush();
  1301.  
  1302.             // Move to the next state
  1303.             curHTTP.smPost = SM_EMAIL_PUT_ATTACHMENT_DATA_LEDS;
  1304.  
  1305.         case SM_EMAIL_PUT_ATTACHMENT_DATA_LEDS:
  1306.             // Check to see if a failure occurred
  1307.             if (!SMTPIsBusy())
  1308.             {
  1309.                 curHTTP.smPost = SM_EMAIL_FINISHING;
  1310.                 return HTTP_IO_WAITING;
  1311.             }
  1312.  
  1313.             // See if we're ready to write data
  1314.             if (SMTPIsPutReady() < 30u)
  1315.                 return HTTP_IO_WAITING;
  1316.  
  1317.             // Write the header and button strings
  1318.             SMTPPutROMString((ROM BYTE*) "LEDs:,");
  1319.             SMTPPut(LED0_IO + '0');
  1320.             SMTPPut(',');
  1321.             SMTPPut(LED1_IO + '0');
  1322.             SMTPPut(',');
  1323.             SMTPPut(LED2_IO + '0');
  1324.             SMTPPut(',');
  1325.             SMTPPut(LED3_IO + '0');
  1326.             SMTPPut(',');
  1327.             SMTPPut(LED4_IO + '0');
  1328.             SMTPPut(',');
  1329.             SMTPPut(LED5_IO + '0');
  1330.             SMTPPut(',');
  1331.             SMTPPut(LED6_IO + '0');
  1332.             SMTPPut(',');
  1333.             SMTPPut(LED7_IO + '0');
  1334.             SMTPPut('\r');
  1335.             SMTPPut('\n');
  1336.             SMTPFlush();
  1337.  
  1338.             // Move to the next state
  1339.             curHTTP.smPost = SM_EMAIL_PUT_ATTACHMENT_DATA_POT;
  1340.  
  1341.         case SM_EMAIL_PUT_ATTACHMENT_DATA_POT:
  1342.             // Check to see if a failure occurred
  1343.             if (!SMTPIsBusy())
  1344.             {
  1345.                 curHTTP.smPost = SM_EMAIL_FINISHING;
  1346.                 return HTTP_IO_WAITING;
  1347.             }
  1348.  
  1349.             // See if we're ready to write data
  1350.             if (SMTPIsPutReady() < 16u)
  1351.                 return HTTP_IO_WAITING;
  1352.  
  1353.             // Do the A/D conversion
  1354. #if defined(__18CXX)
  1355.             // Wait until A/D conversion is done
  1356.             ADCON0bits.GO = 1;
  1357.             while (ADCON0bits.GO);
  1358.             // Convert 10-bit value into ASCII string
  1359.             len = (WORD) ADRES;
  1360.             uitoa(len, (BYTE*) & curHTTP.data[1]);
  1361. #else
  1362.             len = (WORD) ADC1BUF0;
  1363.             uitoa(len, (BYTE*) & curHTTP.data[1]);
  1364. #endif
  1365.  
  1366.             // Write the header and button strings
  1367.             SMTPPutROMString((ROM BYTE*) "Pot:,");
  1368.             SMTPPutString(&curHTTP.data[1]);
  1369.             SMTPPut('\r');
  1370.             SMTPPut('\n');
  1371.             SMTPFlush();
  1372.  
  1373.             // Move to the next state
  1374.             curHTTP.smPost = SM_EMAIL_PUT_TERMINATOR;
  1375.  
  1376.         case SM_EMAIL_PUT_TERMINATOR:
  1377.             // This section finishes the message
  1378.             // This consists of two dashes, the boundary, and two more dashes
  1379.             // on a single line, followed by a CRLF pair to terminate the message.
  1380.  
  1381.             // Check to see if a failure occured
  1382.             if (!SMTPIsBusy())
  1383.             {
  1384.                 curHTTP.smPost = SM_EMAIL_FINISHING;
  1385.                 return HTTP_IO_WAITING;
  1386.             }
  1387.  
  1388.             // See if we're ready to write data
  1389.             if (SMTPIsPutReady() < 16u)
  1390.                 return HTTP_IO_WAITING;
  1391.  
  1392.             // Write the ignored text
  1393.             SMTPPutROMString((ROM BYTE*) "--frontier--\r\n");
  1394.             SMTPPutDone();
  1395.             SMTPFlush();
  1396.  
  1397.             // Move to the next state
  1398.             curHTTP.smPost = SM_EMAIL_FINISHING;
  1399.  
  1400.         case SM_EMAIL_FINISHING:
  1401.             // Wait for status
  1402.             if (!SMTPIsBusy())
  1403.             {
  1404.                 // Release the module and check success
  1405.                 // Redirect the user based on the result
  1406.                 if (SMTPEndUsage() == SMTP_SUCCESS)
  1407.                     lastSuccess = TRUE;
  1408.                 else
  1409.                     lastFailure = TRUE;
  1410.  
  1411.                 // Redirect to the page
  1412.                 strcpypgm2ram((char*) curHTTP.data, "/email/index.htm");
  1413.                 curHTTP.httpStatus = HTTP_REDIRECT;
  1414.                 return HTTP_IO_DONE;
  1415.             }
  1416.  
  1417.             return HTTP_IO_WAITING;
  1418.     }
  1419.  
  1420.     return HTTP_IO_DONE;
  1421. }
  1422. #endif  // #if defined(STACK_USE_SMTP_CLIENT)
  1423.  
  1424. /****************************************************************************
  1425.   Function:
  1426.     HTTP_IO_RESULT HTTPPostDDNSConfig(void)
  1427.    
  1428.   Summary:
  1429.     Parsing and collecting http data received from http form.
  1430.  
  1431.   Description:
  1432.     This routine will be excuted every time the Dynamic DNS Client
  1433.     configuration form is submitted.  The http data is received
  1434.     as a string of the variables seperated by '&' characters in the TCP RX
  1435.     buffer.  This data is parsed to read the required configuration values,
  1436.     and those values are populated to the global array (DDNSData) reserved
  1437.     for this purpose.  As the data is read, DDNSPointers is also populated
  1438.     so that the dynamic DNS client can execute with the new parameters.
  1439.    
  1440.   Precondition:
  1441.      curHTTP is loaded.
  1442.  
  1443.   Parameters:
  1444.     None.
  1445.  
  1446.   Return Values:
  1447.     HTTP_IO_DONE        -  Finished with procedure
  1448.     HTTP_IO_NEED_DATA   -  More data needed to continue, call again later
  1449.     HTTP_IO_WAITING     -  Waiting for asynchronous process to complete,
  1450.                                                 call again later
  1451.  ***************************************************************************/
  1452. #if defined(STACK_USE_DYNAMICDNS_CLIENT)
  1453.  
  1454. static HTTP_IO_RESULT HTTPPostDDNSConfig(void)
  1455. {
  1456.     static BYTE *ptrDDNS;
  1457.  
  1458. #define SM_DDNS_START           (0u)
  1459. #define SM_DDNS_READ_NAME       (1u)
  1460. #define SM_DDNS_READ_VALUE      (2u)
  1461. #define SM_DDNS_READ_SERVICE    (3u)
  1462. #define SM_DDNS_DONE            (4u)
  1463.  
  1464. #define DDNS_SPACE_REMAINING                (sizeof(DDNSData) - (ptrDDNS - DDNSData))
  1465.  
  1466.     switch (curHTTP.smPost)
  1467.     {
  1468.             // Sets defaults for the system
  1469.         case SM_DDNS_START:
  1470.             ptrDDNS = DDNSData;
  1471.             DDNSSetService(0);
  1472.             DDNSClient.Host.szROM = NULL;
  1473.             DDNSClient.Username.szROM = NULL;
  1474.             DDNSClient.Password.szROM = NULL;
  1475.             DDNSClient.ROMPointers.Host = 0;
  1476.             DDNSClient.ROMPointers.Username = 0;
  1477.             DDNSClient.ROMPointers.Password = 0;
  1478.             curHTTP.smPost++;
  1479.  
  1480.             // Searches out names and handles them as they arrive
  1481.         case SM_DDNS_READ_NAME:
  1482.             // If all parameters have been read, end
  1483.             if (curHTTP.byteCount == 0u)
  1484.             {
  1485.                 curHTTP.smPost = SM_DDNS_DONE;
  1486.                 break;
  1487.             }
  1488.  
  1489.             // Read a name
  1490.             if (HTTPReadPostName(curHTTP.data, HTTP_MAX_DATA_LEN) == HTTP_READ_INCOMPLETE)
  1491.                 return HTTP_IO_NEED_DATA;
  1492.  
  1493.             if (!strcmppgm2ram((char *) curHTTP.data, (ROM char*) "service"))
  1494.             {
  1495.                 // Reading the service (numeric)
  1496.                 curHTTP.smPost = SM_DDNS_READ_SERVICE;
  1497.                 break;
  1498.             }
  1499.             else if (!strcmppgm2ram((char *) curHTTP.data, (ROM char*) "user"))
  1500.                 DDNSClient.Username.szRAM = ptrDDNS;
  1501.             else if (!strcmppgm2ram((char *) curHTTP.data, (ROM char*) "pass"))
  1502.                 DDNSClient.Password.szRAM = ptrDDNS;
  1503.             else if (!strcmppgm2ram((char *) curHTTP.data, (ROM char*) "host"))
  1504.                 DDNSClient.Host.szRAM = ptrDDNS;
  1505.  
  1506.             // Move to reading the value for user/pass/host
  1507.             curHTTP.smPost++;
  1508.  
  1509.             // Reads in values and assigns them to the DDNS RAM
  1510.         case SM_DDNS_READ_VALUE:
  1511.             // Read a name
  1512.             if (HTTPReadPostValue(ptrDDNS, DDNS_SPACE_REMAINING) == HTTP_READ_INCOMPLETE)
  1513.                 return HTTP_IO_NEED_DATA;
  1514.  
  1515.             // Move past the data that was just read
  1516.             ptrDDNS += strlen((char*) ptrDDNS);
  1517.             if (ptrDDNS < DDNSData + sizeof (DDNSData) - 1)
  1518.                 ptrDDNS += 1;
  1519.  
  1520.             // Return to reading names
  1521.             curHTTP.smPost = SM_DDNS_READ_NAME;
  1522.             break;
  1523.  
  1524.             // Reads in a service ID
  1525.         case SM_DDNS_READ_SERVICE:
  1526.             // Read the integer id
  1527.             if (HTTPReadPostValue(curHTTP.data, HTTP_MAX_DATA_LEN) == HTTP_READ_INCOMPLETE)
  1528.                 return HTTP_IO_NEED_DATA;
  1529.  
  1530.             // Convert to a service ID
  1531.             DDNSSetService((BYTE) atol((char*) curHTTP.data));
  1532.  
  1533.             // Return to reading names
  1534.             curHTTP.smPost = SM_DDNS_READ_NAME;
  1535.             break;
  1536.  
  1537.             // Sets up the DDNS client for an update
  1538.         case SM_DDNS_DONE:
  1539.             // Since user name and password changed, force an update immediately
  1540.             DDNSForceUpdate();
  1541.  
  1542.             // Redirect to prevent POST errors
  1543.             lastSuccess = TRUE;
  1544.             strcpypgm2ram((char*) curHTTP.data, "/dyndns/index.htm");
  1545.             curHTTP.httpStatus = HTTP_REDIRECT;
  1546.             return HTTP_IO_DONE;
  1547.     }
  1548.  
  1549.     return HTTP_IO_WAITING; // Assume we're waiting to process more data
  1550. }
  1551. #endif  // #if defined(STACK_USE_DYNAMICDNS_CLIENT)
  1552.  
  1553. #endif //(use_post)
  1554.  
  1555. /****************************************************************************
  1556.   Section:
  1557.         Dynamic Variable Callback Functions
  1558.  ***************************************************************************/
  1559.  
  1560. void HTTPPrint_pot(void)
  1561. {
  1562.     BYTE AN0String[8];
  1563.     WORD ADval;
  1564.  
  1565. #if defined(__18CXX)
  1566.     // Wait until A/D conversion is done
  1567.     ADCON0bits.GO = 1;
  1568.     while (ADCON0bits.GO);
  1569.  
  1570.     // Convert 10-bit value into ASCII string
  1571.     ADval = (WORD) ADRES;
  1572.     //ADval *= (WORD)10;
  1573.     //ADval /= (WORD)102;
  1574.     uitoa(ADval, AN0String);
  1575. #else
  1576.     ADval = (WORD) ADC1BUF0;
  1577.     //ADval *= (WORD)10;
  1578.     //ADval /= (WORD)102;
  1579.     uitoa(ADval, (BYTE*) AN0String);
  1580. #endif
  1581.  
  1582.     TCPPutString(sktHTTP, AN0String);
  1583. }
  1584.  
  1585. void HTTPPrint_lcdtext(void)
  1586. {
  1587.     WORD len;
  1588.  
  1589.     // Determine how many bytes we can write
  1590.     len = TCPIsPutReady(sktHTTP);
  1591.  
  1592. #if defined(USE_LCD)
  1593.     // If just starting, set callbackPos
  1594.     if (curHTTP.callbackPos == 0u)
  1595.         curHTTP.callbackPos = 32;
  1596.  
  1597.     // Write a byte at a time while we still can
  1598.     // It may take up to 12 bytes to write a character
  1599.     // (spaces and newlines are longer)
  1600.     while (len > 12u && curHTTP.callbackPos)
  1601.     {
  1602.         // After 16 bytes write a newline
  1603.         if (curHTTP.callbackPos == 16u)
  1604.             len -= TCPPutROMArray(sktHTTP, (ROM BYTE*) "<br />", 6);
  1605.  
  1606.         if (LCDText[32 - curHTTP.callbackPos] == ' ' || LCDText[32 - curHTTP.callbackPos] == '\0')
  1607.             len -= TCPPutROMArray(sktHTTP, (ROM BYTE*) "&nbsp;", 6);
  1608.         else
  1609.             len -= TCPPut(sktHTTP, LCDText[32 - curHTTP.callbackPos]);
  1610.  
  1611.         curHTTP.callbackPos--;
  1612.     }
  1613. #else
  1614.     TCPPutROMString(sktHTTP, (ROM BYTE*) "No LCD Present");
  1615. #endif
  1616.  
  1617.     return;
  1618. }
  1619.  
  1620. void HTTPPrint_hellomsg(void)
  1621. {
  1622.     BYTE *ptr;
  1623.  
  1624.     ptr = HTTPGetROMArg(curHTTP.data, (ROM BYTE*) "name");
  1625.  
  1626.     // We omit checking for space because this is the only data being written
  1627.     if (ptr != NULL)
  1628.     {
  1629.         TCPPutROMString(sktHTTP, (ROM BYTE*) "Hello, ");
  1630.         TCPPutString(sktHTTP, ptr);
  1631.     }
  1632.  
  1633.     return;
  1634. }
  1635.  
  1636. void HTTPPrint_cookiename(void)
  1637. {
  1638.     BYTE *ptr;
  1639.  
  1640.     ptr = HTTPGetROMArg(curHTTP.data, (ROM BYTE*) "name");
  1641.  
  1642.     if (ptr)
  1643.         TCPPutString(sktHTTP, ptr);
  1644.     else
  1645.         TCPPutROMString(sktHTTP, (ROM BYTE*) "not set");
  1646.  
  1647.     return;
  1648. }
  1649.  
  1650. void HTTPPrint_uploadedmd5(void)
  1651. {
  1652.     BYTE i;
  1653.  
  1654.     // Set a flag to indicate not finished
  1655.     curHTTP.callbackPos = 1;
  1656.  
  1657.     // Make sure there's enough output space
  1658.     if (TCPIsPutReady(sktHTTP) < 32u + 37u + 5u)
  1659.         return;
  1660.  
  1661.     // Check for flag set in HTTPPostMD5
  1662. #if defined(STACK_USE_HTTP_MD5_DEMO)
  1663.     if (curHTTP.smPost != SM_MD5_POST_COMPLETE)
  1664. #endif
  1665.     {// No file uploaded, so just return
  1666.         TCPPutROMString(sktHTTP, (ROM BYTE*) "<b>Upload a File</b>");
  1667.         curHTTP.callbackPos = 0;
  1668.         return;
  1669.     }
  1670.  
  1671.     TCPPutROMString(sktHTTP, (ROM BYTE*) "<b>Uploaded File </b><br />");
  1672.  
  1673.     // Write a byte of the md5 sum at a time
  1674.     /*  for(i = 0; i < 16u; i++)
  1675.             {
  1676.                     TCPPut(sktHTTP, btohexa_high(curHTTP.data[i]));
  1677.                     TCPPut(sktHTTP, btohexa_low(curHTTP.data[i]));
  1678.                     if((i & 0x03) == 3u)
  1679.                             TCPPut(sktHTTP, ' ');
  1680.             }
  1681.      */
  1682.     curHTTP.callbackPos = 0x00;
  1683.     return;
  1684. }
  1685.  
  1686. extern APP_CONFIG AppConfig;
  1687.  
  1688. // SNMP Read communities configuration page
  1689.  
  1690. void HTTPPrint_read_comm(WORD num)
  1691. {
  1692. #if defined(STACK_USE_SNMP_SERVER)
  1693.     // Ensure no one tries to read illegal memory addresses by specifying
  1694.     // illegal num values.
  1695.     if (num >= SNMP_MAX_COMMUNITY_SUPPORT)
  1696.         return;
  1697.  
  1698.     // Send proper string
  1699.     TCPPutString(sktHTTP, AppConfig.readCommunity[num]);
  1700. #endif
  1701. }
  1702.  
  1703. // SNMP Write communities configuration page
  1704.  
  1705. void HTTPPrint_write_comm(WORD num)
  1706. {
  1707. #if defined(STACK_USE_SNMP_SERVER)
  1708.     // Ensure no one tries to read illegal memory addresses by specifying
  1709.     // illegal num values.
  1710.     if (num >= SNMP_MAX_COMMUNITY_SUPPORT)
  1711.         return;
  1712.  
  1713.     // Send proper string
  1714.     TCPPutString(sktHTTP, AppConfig.writeCommunity[num]);
  1715. #endif
  1716. }
  1717.  
  1718. void HTTPPrint_reboot(void)
  1719. {
  1720.     // This is not so much a print function, but causes the board to reboot
  1721.     // when the configuration is changed.  If called via an AJAX call, this
  1722.     // will gracefully reset the board and bring it back online immediately
  1723.     Reset();
  1724. }
  1725.  
  1726. void HTTPPrint_rebootaddr(void)
  1727. {// This is the expected address of the board upon rebooting
  1728.     //rebTCPPutString(sktHTTP, curHTTP.data);
  1729.     //TCPPutString(sktHTTP, "192.168.0.2");
  1730. }
  1731.  
  1732. void HTTPPrint_ddns_user(void)
  1733. {
  1734. #if defined(STACK_USE_DYNAMICDNS_CLIENT)
  1735.     if (DDNSClient.ROMPointers.Username || !DDNSClient.Username.szRAM)
  1736.         return;
  1737.     if (curHTTP.callbackPos == 0x00u)
  1738.         curHTTP.callbackPos = (PTR_BASE) DDNSClient.Username.szRAM;
  1739.     curHTTP.callbackPos = (PTR_BASE) TCPPutString(sktHTTP, (BYTE*) (PTR_BASE) curHTTP.callbackPos);
  1740.     if (*(BYTE*) (PTR_BASE) curHTTP.callbackPos == '\0')
  1741.         curHTTP.callbackPos = 0x00;
  1742. #endif
  1743. }
  1744.  
  1745. void HTTPPrint_ddns_pass(void)
  1746. {
  1747. #if defined(STACK_USE_DYNAMICDNS_CLIENT)
  1748.     if (DDNSClient.ROMPointers.Password || !DDNSClient.Password.szRAM)
  1749.         return;
  1750.     if (curHTTP.callbackPos == 0x00u)
  1751.         curHTTP.callbackPos = (PTR_BASE) DDNSClient.Password.szRAM;
  1752.     curHTTP.callbackPos = (PTR_BASE) TCPPutString(sktHTTP, (BYTE*) (PTR_BASE) curHTTP.callbackPos);
  1753.     if (*(BYTE*) (PTR_BASE) curHTTP.callbackPos == '\0')
  1754.         curHTTP.callbackPos = 0x00;
  1755. #endif
  1756. }
  1757.  
  1758. void HTTPPrint_ddns_host(void)
  1759. {
  1760. #if defined(STACK_USE_DYNAMICDNS_CLIENT)
  1761.     if (DDNSClient.ROMPointers.Host || !DDNSClient.Host.szRAM)
  1762.         return;
  1763.     if (curHTTP.callbackPos == 0x00u)
  1764.         curHTTP.callbackPos = (PTR_BASE) DDNSClient.Host.szRAM;
  1765.     curHTTP.callbackPos = (PTR_BASE) TCPPutString(sktHTTP, (BYTE*) (PTR_BASE) curHTTP.callbackPos);
  1766.     if (*(BYTE*) (PTR_BASE) curHTTP.callbackPos == '\0')
  1767.         curHTTP.callbackPos = 0x00;
  1768. #endif
  1769. }
  1770.  
  1771. extern ROM char * ROM ddnsServiceHosts[];
  1772.  
  1773. void HTTPPrint_ddns_service(WORD i)
  1774. {
  1775. #if defined(STACK_USE_DYNAMICDNS_CLIENT)
  1776.     if (!DDNSClient.ROMPointers.UpdateServer || !DDNSClient.UpdateServer.szROM)
  1777.         return;
  1778.     if ((ROM char*) DDNSClient.UpdateServer.szROM == ddnsServiceHosts[i])
  1779.         TCPPutROMString(sktHTTP, (ROM BYTE*) "selected");
  1780. #endif
  1781. }
  1782.  
  1783. void HTTPPrint_ddns_status(void)
  1784. {
  1785. #if defined(STACK_USE_DYNAMICDNS_CLIENT)
  1786.     DDNS_STATUS s;
  1787.     s = DDNSGetLastStatus();
  1788.     if (s == DDNS_STATUS_GOOD || s == DDNS_STATUS_UNCHANGED || s == DDNS_STATUS_NOCHG)
  1789.         TCPPutROMString(sktHTTP, (ROM BYTE*) "ok");
  1790.     else if (s == DDNS_STATUS_UNKNOWN)
  1791.         TCPPutROMString(sktHTTP, (ROM BYTE*) "unk");
  1792.     else
  1793.         TCPPutROMString(sktHTTP, (ROM BYTE*) "fail");
  1794. #else
  1795.     TCPPutROMString(sktHTTP, (ROM BYTE*) "fail");
  1796. #endif
  1797. }
  1798.  
  1799. void HTTPPrint_ddns_status_msg(void)
  1800. {
  1801.     if (TCPIsPutReady(sktHTTP) < 75u)
  1802.     {
  1803.         curHTTP.callbackPos = 0x01;
  1804.         return;
  1805.     }
  1806.  
  1807. #if defined(STACK_USE_DYNAMICDNS_CLIENT)
  1808.     switch (DDNSGetLastStatus())
  1809.     {
  1810.         case DDNS_STATUS_GOOD:
  1811.         case DDNS_STATUS_NOCHG:
  1812.             TCPPutROMString(sktHTTP, (ROM BYTE*) "The last update was successful.");
  1813.             break;
  1814.         case DDNS_STATUS_UNCHANGED:
  1815.             TCPPutROMString(sktHTTP, (ROM BYTE*) "The IP has not changed since the last update.");
  1816.             break;
  1817.         case DDNS_STATUS_UPDATE_ERROR:
  1818.         case DDNS_STATUS_CHECKIP_ERROR:
  1819.             TCPPutROMString(sktHTTP, (ROM BYTE*) "Could not communicate with DDNS server.");
  1820.             break;
  1821.         case DDNS_STATUS_INVALID:
  1822.             TCPPutROMString(sktHTTP, (ROM BYTE*) "The current configuration is not valid.");
  1823.             break;
  1824.         case DDNS_STATUS_UNKNOWN:
  1825.             TCPPutROMString(sktHTTP, (ROM BYTE*) "The Dynamic DNS client is pending an update.");
  1826.             break;
  1827.         default:
  1828.             TCPPutROMString(sktHTTP, (ROM BYTE*) "An error occurred during the update.<br />The DDNS Client is suspended.");
  1829.             break;
  1830.     }
  1831. #else
  1832.     TCPPutROMString(sktHTTP, (ROM BYTE*) "The Dynamic DNS Client is not enabled.");
  1833. #endif
  1834.  
  1835.     curHTTP.callbackPos = 0x00;
  1836. }
  1837.  
  1838. void HTTPPrint_smtps_en(void)
  1839. {
  1840. #if defined(STACK_USE_SSL_CLIENT)
  1841.     TCPPutROMString(sktHTTP, (ROM BYTE*) "inline");
  1842. #else
  1843.     TCPPutROMString(sktHTTP, (ROM BYTE*) "none");
  1844. #endif
  1845. }
  1846.  
  1847. void HTTPPrint_snmp_en(void)
  1848. {
  1849. #if defined(STACK_USE_SNMP_SERVER)
  1850.     TCPPutROMString(sktHTTP, (ROM BYTE*) "none");
  1851. #else
  1852.     TCPPutROMString(sktHTTP, (ROM BYTE*) "block");
  1853. #endif
  1854. }
  1855.  
  1856. void HTTPPrint_status_ok(void)
  1857. {
  1858.     if (lastSuccess)
  1859.         TCPPutROMString(sktHTTP, (ROM BYTE*) "block");
  1860.     else
  1861.         TCPPutROMString(sktHTTP, (ROM BYTE*) "none");
  1862.     lastSuccess = FALSE;
  1863. }
  1864.  
  1865. #endif
  1866.  
  1867. /*******************************************************************************/
  1868. /*                           CUSTOM PRINT FUNCTIONS                            */
  1869. /*******************************************************************************/
  1870.  
  1871. void HTTPPrint_files(void)
  1872. {
  1873.     DIR dir;
  1874.     FILINFO fno;
  1875.     FRESULT res;
  1876.     unsigned char name[64];
  1877.     unsigned int charWritten = 0;
  1878.  
  1879. #if _USE_LFN == 1
  1880.     unsigned char lfnname[64];
  1881.     fno.lfname = lfnname;
  1882.     fno.lfsize = sizeof (lfnname);
  1883. #endif
  1884.  
  1885.     if (curHTTP.callbackPos == 0)
  1886.     {
  1887.         curHTTP.callbackPos = 1;
  1888.     }
  1889.    
  1890.     res = f_opendir(&dir, "\\");
  1891.     res = f_readdir(&dir, &fno);
  1892.    
  1893.     if (curHTTP.callbackPos > 1)
  1894.     {
  1895.         // NEXT-2409: W przypadku gdy nastąpiło wyjście z funkcji przez brak miejsca w
  1896.         // buforze nadawczym TCP, wykonywane jest "przewinięcie" do poprzedniego kontekstu
  1897.         // funkcji poprzez zapętlone wykonanie funkcji f_readdir().
  1898.         //
  1899.         // Funkcja wykorzystywana jest stosunkowo rzadko, i czas jej wykonania nie
  1900.         // jest znaczący, stąd wybór takiego rozwiązania zamiast używania zmiennych
  1901.         // static (oszczędność pamięci statycznej RAM), oraz  funkcji typu malloc()
  1902.         // (w ustawieniach projektu nie ma przydzielonej przestrzeni pamięci dla sterty).
  1903.         int i;
  1904.         for(i = 1; i < curHTTP.callbackPos; i++)
  1905.         {
  1906.             res = f_readdir(&dir, &fno);
  1907.         }
  1908.     }
  1909.            
  1910.     while ((res == FR_OK) && (fno.fname[0] != 0))
  1911.     {
  1912.         if (fno.fattrib & AM_DIR)
  1913.         {
  1914. #if _USE_LFN == 1
  1915.             charWritten = sprintf(name, "<dir>%s - %s</dir>", fno.fname, *fno.lfname ? fno.lfname : fno.fname);
  1916. #else
  1917.             charWritten = sprintf(name, "<dir>%s</dir>", fno.fname);
  1918. #endif
  1919.         }
  1920.         else
  1921.         {
  1922. #if _USE_LFN == 1
  1923.             charWritten = sprintf(name, "<file>%s - %s - %d</file>", fno.fname, *fno.lfname ? fno.lfname : fno.fname, fno.fsize);
  1924. #else
  1925.             charWritten = sprintf(name, "<file>%s - %d</file>", fno.fname, fno.fsize);
  1926. #endif
  1927.         }
  1928.         if (TCPIsPutReady(sktHTTP) < charWritten)
  1929.         {
  1930.             TCPFlush(sktHTTP);
  1931.             return;
  1932.         }
  1933.         TCPPutString(sktHTTP, name);
  1934.         res = f_readdir(&dir, &fno);
  1935.         curHTTP.callbackPos++;
  1936.     }
  1937.     f_closedir(&dir);
  1938.     curHTTP.callbackPos = 0;
  1939.     return;
  1940. }
  1941.  
  1942. void HTTPPrint_machineName(void)
  1943. {
  1944.     char httpBuffer[MAX_MACHINE_NAME_LEN + 1];
  1945.        
  1946.     if (TCPIsPutReady(sktHTTP) < PrintHtmlString(httpBuffer, MainConfig.MachineName))
  1947.     {
  1948.         curHTTP.callbackPos = 1;
  1949.         return;
  1950.     }
  1951.     TCPPutString(sktHTTP, (BYTE*)httpBuffer);
  1952.     curHTTP.callbackPos = 0;
  1953. }
  1954.  
  1955. void PrintIP(char * buf, IP_ADDR ip)
  1956. {
  1957.     sprintf(buf, "%d.%d.%d.%d", ip.v[0], ip.v[1], ip.v[2], ip.v[3]);
  1958. }
Add Comment
Please, Sign In to add comment