Gbox 4.20
Grow box automation and monitoring - <a href='https://sites.google.com/site/growboxguy/'>https://sites.google.com/site/growboxguy/</a>
 
Loading...
Searching...
No Matches
ELClientWebServer.cpp
Go to the documentation of this file.
1
4#include "ELClientWebServer.h"
5
6typedef enum {
7 WS_LOAD=0, // page first load
8 WS_REFRESH, // page refresh
9 WS_BUTTON, // button press
10 WS_SUBMIT, // form submission
12
13typedef enum
14{
15 WEB_STRING=0, // value type string
16 WEB_NULL, // value type null
17 WEB_INTEGER, // value type integer
18 WEB_BOOLEAN, // value type boolean
19 WEB_FLOAT, // value type float
20 WEB_JSON // value type json
22
23
24ELClientWebServer * ELClientWebServer::instance = 0;
25
26
43ELClientWebServer::ELClientWebServer(ELClient* elc) :_elc(elc),handlers(0), arg_ptr(0) {
44 // save the current packet handler and register a new one
45 instance = this;
46
47 webServerCb.attach(&ELClientWebServer::webServerPacketHandler);
48}
49
50// packet handler for web-server
51void ELClientWebServer::webServerPacketHandler(void * response)
52{
53 ELClientWebServer::getInstance()->processResponse((ELClientResponse*)response);
54}
55
56
96{
97 String s = URL;
98 return createURLHandler(s);
99}
100
101
140URLHandler * ELClientWebServer::createURLHandler(const __FlashStringHelper * URL)
141{
142 String s = URL;
143 return createURLHandler(s);
144}
145
146
187{
188 struct URL_HANDLER * hnd = new struct URL_HANDLER(); // "new" is used here instead of malloc to call String destructor at freeing. DOn't use malloc/free.
189 hnd->URL = URL; // handler URL
190 hnd->next = handlers; // next handler
191 handlers = hnd; // change the first handler
192 return hnd;
193}
194
195
210{
211 struct URL_HANDLER *prev = 0;
212 struct URL_HANDLER *hnd = handlers;
213 while( hnd != 0 )
214 {
215 if( hnd == handler )
216 {
217 if( prev == 0 )
218 handlers = hnd->next;
219 else
220 prev->next = hnd->next;
221
222 delete hnd;
223 return;
224 }
225 prev = hnd;
226 hnd = hnd->next;
227 }
228}
229
230
265{
266 // WebServer doesn't send messages to MCU only if asked
267 // register here to the web callback
268 // periodic reregistration is required in case of ESP8266 reset
269 _elc->Request(CMD_WEB_SETUP, 0, 1);
270 uint32_t cb = (uint32_t)&webServerCb;
271 _elc->Request(&cb, 4);
272 _elc->Request();
273}
274
275void ELClientWebServer::processResponse(ELClientResponse *response)
276{
277 uint16_t shrt;
278 response->popArg(&shrt, 2);
279 RequestReason reason = (RequestReason)shrt; // request reason
280
281 response->popArg(remote_ip, 4); // remote IP address
282 response->popArg(&remote_port, 2); // remote port
283
284 char * url;
285 uint16_t urlLen = response->popArgPtr((void**)&url);
286
287 struct URL_HANDLER *hnd = handlers;
288 while( hnd != 0 )
289 {
290 if( hnd->URL.length() == urlLen && memcmp( url, hnd->URL.c_str(), urlLen ) == 0 )
291 break;
292 hnd = hnd->next;
293 }
294
295 if( hnd == 0 ) // no handler found for the URL
296 {
297 if( _elc->_debugEn )
298 {
299 _elc->_debug->print(F("Handler not found for URL:"));
300
301 for(uint16_t i=0; i < urlLen; i++)
302 _elc->_debug->print( url[i] );
303 _elc->_debug->println();
304 }
305 return;
306 }
307
308 switch(reason)
309 {
310 case WS_BUTTON: // invoked when a button pressed
311 {
312 char * idPtr;
313 int idLen = response->popArgPtr((void**)&idPtr);
314
315 // add terminating 0
316 char id[idLen+1];
317 memcpy(id, idPtr, idLen);
318 id[idLen] = 0;
319
320 hnd->buttonCb(id);
321 }
322 break;
323 case WS_SUBMIT: // invoked when a form submitted
324 {
325 uint16_t cnt = 4;
326
327 while( cnt < response->argc() )
328 {
329 char * idPtr;
330 int idLen = response->popArgPtr((void**)&idPtr);
331 int nameLen = strlen(idPtr+1);
332 int valueLen = idLen - nameLen -2;
333
334 // add terminating 0
335 arg_ptr = (char *)malloc(valueLen+1);
336 arg_ptr[valueLen] = 0;
337 memcpy(arg_ptr, idPtr + 2 + nameLen, valueLen);
338
339 hnd->setFieldCb(idPtr+1);
340
341 free(arg_ptr);
342 arg_ptr = 0;
343 cnt++;
344 }
345 }
346 return;
347 case WS_LOAD: // invoked at refresh / load
348 case WS_REFRESH:
349 break;
350 default:
351 return;
352 }
353
354 // the response is generated here with the fields to refresh
355
357 _elc->Request(remote_ip, 4); // send remote IP address
358 _elc->Request((uint8_t *)&remote_port, 2); // send remote port
359
360 if( reason == WS_LOAD )
361 hnd->loadCb( (char*)hnd->URL.c_str() );
362 else
363 hnd->refreshCb( (char*)hnd->URL.c_str() );
364
365 _elc->Request((uint8_t *)NULL, 0); // end indicator
366 _elc->Request(); // finish packet
367}
368
404void ELClientWebServer::setArgJson(const char * name, const char * value)
405{
406 uint8_t nlen = strlen(name);
407 uint8_t vlen = strlen(value);
408 char buf[nlen+vlen+3];
409 buf[0] = WEB_JSON;
410 strcpy(buf+1, name);
411 strcpy(buf+2+nlen, value);
412 _elc->Request(buf, nlen+vlen+2);
413}
414
450void ELClientWebServer::setArgJson(const __FlashStringHelper * name, const __FlashStringHelper * value)
451{
452 const char * name_p = reinterpret_cast<const char *>(name);
453 const char * value_p = reinterpret_cast<const char *>(value);
454
455 uint8_t nlen = strlen_P(name_p);
456 uint8_t vlen = strlen_P(value_p);
457 char buf[nlen+vlen+3];
458 buf[0] = WEB_JSON;
459 strcpy_P(buf+1, name_p);
460 strcpy_P(buf+2+nlen, value_p);
461 _elc->Request(buf, nlen+vlen+2);
462}
463
464
500void ELClientWebServer::setArgJson(const __FlashStringHelper * name, const char * value)
501{
502 const char * name_p = reinterpret_cast<const char *>(name);
503
504 uint8_t nlen = strlen_P(name_p);
505 uint8_t vlen = strlen(value);
506 char buf[nlen+vlen+3];
507 buf[0] = WEB_JSON;
508 strcpy_P(buf+1, name_p);
509 strcpy(buf+2+nlen, value);
510 _elc->Request(buf, nlen+vlen+2);
511}
512
513
564void ELClientWebServer::setArgString(const char * name, const char * value)
565{
566 uint8_t nlen = strlen(name);
567 uint8_t vlen = strlen(value);
568 char buf[nlen+vlen+3];
569 buf[0] = WEB_STRING;
570 strcpy(buf+1, name);
571 strcpy(buf+2+nlen, value);
572 _elc->Request(buf, nlen+vlen+2);
573}
574
625void ELClientWebServer::setArgString(const __FlashStringHelper * name, const __FlashStringHelper * value)
626{
627 const char * name_p = reinterpret_cast<const char *>(name);
628 const char * value_p = reinterpret_cast<const char *>(value);
629
630 uint8_t nlen = strlen_P(name_p);
631 uint8_t vlen = strlen_P(value_p);
632 char buf[nlen+vlen+3];
633 buf[0] = WEB_STRING;
634 strcpy_P(buf+1, name_p);
635 strcpy_P(buf+2+nlen, value_p);
636 _elc->Request(buf, nlen+vlen+2);
637}
638
688void ELClientWebServer::setArgString(const __FlashStringHelper * name, const char * value)
689{
690 const char * name_p = reinterpret_cast<const char *>(name);
691
692 uint8_t nlen = strlen_P(name_p);
693 uint8_t vlen = strlen(value);
694 char buf[nlen+vlen+3];
695 buf[0] = WEB_STRING;
696 strcpy_P(buf+1, name_p);
697 strcpy(buf+2+nlen, value);
698 _elc->Request(buf, nlen+vlen+2);
699}
700
701
729void ELClientWebServer::setArgBoolean(const char * name, uint8_t value)
730{
731 uint8_t nlen = strlen(name);
732 char buf[nlen + 4];
733 buf[0] = WEB_BOOLEAN;
734 strcpy(buf+1, name);
735 buf[2 + nlen] = value;
736 _elc->Request(buf, nlen+3);
737}
738
739
767void ELClientWebServer::setArgBoolean(const __FlashStringHelper * name, uint8_t value)
768{
769 const char * name_p = reinterpret_cast<const char *>(name);
770
771 uint8_t nlen = strlen_P(name_p);
772 char buf[nlen + 4];
773 buf[0] = WEB_BOOLEAN;
774 strcpy_P(buf+1, name_p);
775 buf[2 + nlen] = value;
776 _elc->Request(buf, nlen+3);
777}
778
779
807void ELClientWebServer::setArgInt(const char * name, int32_t value)
808{
809 uint8_t nlen = strlen(name);
810 char buf[nlen + 7];
811 buf[0] = WEB_INTEGER;
812 strcpy(buf+1, name);
813 memcpy(buf+2+nlen, &value, 4);
814 _elc->Request(buf, nlen+6);
815}
816
817
845void ELClientWebServer::setArgInt(const __FlashStringHelper * name, int32_t value)
846{
847 const char * name_p = reinterpret_cast<const char *>(name);
848
849 uint8_t nlen = strlen_P(name_p);
850 char buf[nlen + 7];
851 buf[0] = WEB_INTEGER;
852 strcpy_P(buf+1, name_p);
853 memcpy(buf+2+nlen, &value, 4);
854 _elc->Request(buf, nlen+6);
855}
856
857
888void ELClientWebServer::setArgNull(const char * name)
889{
890 uint8_t nlen = strlen(name);
891 char buf[nlen + 2];
892 buf[0] = WEB_NULL;
893 strcpy(buf+1, name);
894 _elc->Request(buf, nlen+2);
895}
896
897
928void ELClientWebServer::setArgNull(const __FlashStringHelper * name)
929{
930 const char * name_p = reinterpret_cast<const char *>(name);
931
932 uint8_t nlen = strlen_P(name_p);
933 char buf[nlen + 2];
934 buf[0] = WEB_NULL;
935 strcpy_P(buf+1, name_p);
936 _elc->Request(buf, nlen+2);
937}
938
939
967void ELClientWebServer::setArgFloat(const char * name, float value)
968{
969 uint8_t nlen = strlen(name);
970 char buf[nlen + 7];
971 buf[0] = WEB_FLOAT;
972 strcpy(buf+1, name);
973 memcpy(buf+2+nlen, &value, 4);
974 _elc->Request(buf, nlen+6);
975}
976
977
1005void ELClientWebServer::setArgFloat(const __FlashStringHelper * name, float value)
1006{
1007 const char * name_p = reinterpret_cast<const char *>(name);
1008
1009 uint8_t nlen = strlen_P(name_p);
1010 char buf[nlen + 7];
1011 buf[0] = WEB_FLOAT;
1012 strcpy_P(buf+1, name_p);
1013 memcpy(buf+2+nlen, &value, 4);
1014 _elc->Request(buf, nlen+6);
1015}
1016
1040{
1041 return (int32_t)atol(arg_ptr);
1042}
1043
1066{
1067 return arg_ptr;
1068}
1069
1093{
1094 if( strcmp_P(arg_ptr, PSTR("on")) == 0 )
1095 return 1;
1096 if( strcmp_P(arg_ptr, PSTR("true")) == 0 )
1097 return 1;
1098 if( strcmp_P(arg_ptr, PSTR("yes")) == 0 )
1099 return 1;
1100 if( strcmp_P(arg_ptr, PSTR("1")) == 0 )
1101 return 1;
1102 return 0;
1103}
1104
1128{
1129 return atof(arg_ptr);
1130}
#define VARIABLE_ARG_NUM
@ WEB_FLOAT
@ WEB_BOOLEAN
@ WEB_STRING
@ WEB_INTEGER
RequestReason
@ WS_REFRESH
@ WS_LOAD
@ WS_SUBMIT
@ WS_BUTTON
Definitions for ELClientWebServer.
@ CMD_WEB_SETUP
Definition ELClient.h:38
@ CMD_WEB_DATA
Definition ELClient.h:39
int16_t popArg(void *data, uint16_t maxLen)
Extract an argument from the response packet.
int16_t popArgPtr(void **data)
Extract pointer to an argument from the response packet.
void setArgString(const char *name, const char *value)
Sets string value of a field.
void setArgBoolean(const char *name, uint8_t value)
Sets boolean value of a field.
void setArgInt(const char *name, int32_t value)
Sets integer value of a field.
ELClientWebServer(ELClient *elc)
Creates a Web-Server instance.
void setup()
Initializes web-server.
float getArgFloat()
Returns an HTML field value as float.
void setArgJson(const char *name, const char *value)
Sets JSON value of a field.
int32_t getArgInt()
Returns an HTML field value as integer.
uint8_t getArgBoolean()
Returns an HTML field value as boolean.
void setArgFloat(const char *name, float f)
Sets float value of a field.
void destroyURLHandler(URLHandler *handler)
Unregisters an destroys an URL handler.
char * getArgString()
Returns an HTML field value as string.
static ELClientWebServer * getInstance()
Returns the singleton web-server instance.
void setArgNull(const char *name)
Sets null value to a field.
URLHandler * createURLHandler(const char *URL)
Creates and registers an URL handler.
void Request(uint16_t cmd, uint32_t value, uint16_t argc)
Start a request.
Definition ELClient.cpp:211
boolean _debugEn
Definition ELClient.h:125
Stream * _debug
Definition ELClient.h:85
void attach(T *item, retT(T::*method)(argT))
Definition FP.h:147
FP< void, char * > setFieldCb
callback for setting a field from a HTML form
FP< void, char * > loadCb
Callback for HTML page loading.
struct URL_HANDLER * next
next handler
FP< void, char * > buttonCb
callback for a HTML button press
String URL
the URL to handle
FP< void, char * > refreshCb
Callback for HTML page refresh.