Example of HTTPServer with additional features: * SNTPClient, DST rules * Link status indication * Local or SDCard-based WebServer * RPC-able class * Static and Dynamic HTML page
HTTPLinkStatus.h
- Committer:
- iva2k
- Date:
- 2010-01-12
- Revision:
- 2:360fda42fefd
- Parent:
- 0:886e4b3119ad
File content as of revision 2:360fda42fefd:
// HTTPLinkStatus.h // HTTP Server Logger class // // Provides: // 1. ETH port link state monitor // - lights LED for link // - default: logs link state to stdout; // - default: creates URL file on local filesystem (can be used to open browser to URL address) // 2. HTTP activity monitor (does not react to non-http traffic) // - blinks LED for activity / HTTP requests // - optional: log activity to stdout // - optional: log activity to file (file is opened for each log entry, so local file system can still be accessed via USB) // #ifndef HTTPLINKSTATUS_H #define HTTPLINKSTATUS_H #include "HTTPServer.h" // FIXME: should we be able to get this from *con? extern Ethernet eth; // eth is defined elsewhere, avoid compiler error. namespace mbed { class DigitalOutDelayed : public DigitalOut { public: DigitalOutDelayed(PinName pin, const char* name = NULL) : DigitalOut(pin, name) {} void write(int value, float delay=0.0) { _timeout.detach(); if (delay > 0.0) { _delay_value = value; _timeout.attach(this, &DigitalOutDelayed::_write_delayed, delay); } else { DigitalOut::write(value); } } void write_us(int value, unsigned int delay_us=0) { _timeout.detach(); if (delay_us > 0) { _delay_value = value; _timeout.attach_us(this, &DigitalOutDelayed::_write_delayed, delay_us); } else { DigitalOut::write(value); } } #ifdef MBED_OPERATORS using DigitalOut::operator = ; using DigitalOut::operator int; #endif protected: void _write_delayed(void) { DigitalOut::write(_delay_value); } Timeout _timeout; int _delay_value; }; } // namespace mbed class HTTPLinkStatus : public HTTPHandler { public: HTTPLinkStatus(const char *prefix, PinName link_led=NC, PinName act_led=NC, float poll_t = 0.1, bool do_urlfile = true, bool do_link_printf = true, bool do_log_printf = false, const char* log_file = NULL ) : HTTPHandler(prefix), _link_led(link_led), _act_led(act_led), _linkstate(-1), _first(true), _our_ip(0), _do_urlfile(do_urlfile), _do_link_printf(do_link_printf), _do_log_printf(do_log_printf), _log_file(log_file) { if (poll_t > 0) _ticker.attach(this, &HTTPLinkStatus::_link_poll, poll_t); } HTTPLinkStatus(HTTPServer *server, const char *prefix, PinName link_led=NC, PinName act_led=NC, float poll_t = 0.1, bool do_urlfile = true, bool do_link_printf = true, bool do_log_printf = false, const char* log_file = NULL ) : HTTPHandler(prefix), _link_led(link_led), _act_led(act_led), _linkstate(-1), _first(true), _our_ip(0), _do_urlfile(do_urlfile), _do_link_printf(do_link_printf), _do_log_printf(do_log_printf), _log_file(log_file) { server->addHandler(this); if (poll_t > 0) _ticker.attach(this, &HTTPLinkStatus::_link_poll, poll_t); } virtual ~HTTPLinkStatus() { _ticker.detach(); // Needeed? } void set_do_urlfile(bool val) { _do_urlfile = val; } void set_link_stdout(bool val) { _do_link_printf = val; } void set_log_stdout(bool val) { _do_log_printf = val; } void set_log_file(const char *file) { _log_file = file; if (_log_file) { FILE *fp = fopen(_log_file, "a"); if (fp) { fprintf(fp, "======== HTTPLinkStatus NEW LOG OPENED ========\r\n"); fclose(fp); } else { _log_file = NULL; // Error opening file. Reset file name so we won't waste our time trying to log to it. } } } private: void _link_poll() { int new_linkstate = eth.link(); if (new_linkstate) { // From http://mbed.org/forum/post/909/ NetServer *net = NetServer::get(); struct ip_addr ip = net->getIPAddr(); // struct ip_addr gw = net->getGateway(); // struct ip_addr nm = net->getNetmask(); // struct ip_addr dns = net->getDNS1(); if (ip.addr != _our_ip) { if (!_first &&_do_link_printf) { printf("IP: %hhu.%hhu.%hhu.%hhu\r\n", (ip.addr)&0xFF, (ip.addr>>8)&0xFF, (ip.addr>>16)&0xFF, (ip.addr>>24)&0xFF); } _first = false; if (_do_urlfile) { // Create a link file to our IP. FILE *fp = fopen("/local/Start.url", "w"); // Create a link to own IP if (fp) { fprintf(fp, "[InternetShortcut]\r\nURL=http://%hhu.%hhu.%hhu.%hhu/\r\n", (ip.addr)&0xFF, (ip.addr>>8)&0xFF, (ip.addr>>16)&0xFF, (ip.addr>>24)&0xFF); fclose(fp); } } _our_ip = ip.addr; } } else { if (_do_link_printf && _linkstate != new_linkstate) { printf("IP: <link down>\r\n"); } } _link_led = new_linkstate; _linkstate = new_linkstate; } virtual HTTPHandle action(HTTPConnection *con) const { _act_led = 1; // struct ip_addr ip = con->_pcb()->remote_ip; struct ip_addr ip = con->get_remote_ip(); // This requires a patch to TCPConnection.h file in lwip/Core if (_do_log_printf) { printf("HTTPStatus IP: %hhu.%hhu.%hhu.%hhu %s %s\r\n", (ip.addr)&0xFF, (ip.addr>>8)&0xFF, (ip.addr>>16)&0xFF, (ip.addr>>24)&0xFF, (con->getType() == POST? "POST" : "GET "), con->getURL() ); } if (_log_file) { FILE *fp = fopen(_log_file, "a"); if (fp) { fprintf(fp, "HTTPStatus IP: %hhu.%hhu.%hhu.%hhu %s %s\r\n", (ip.addr)&0xFF, (ip.addr>>8)&0xFF, (ip.addr>>16)&0xFF, (ip.addr>>24)&0xFF, (con->getType() == POST? "POST" : "GET "), con->getURL() ); fclose(fp); } } _act_led.write(0, 0.050); // Delayed write return HTTP_AddFields; } DigitalOut _link_led; // Link status LED mutable DigitalOutDelayed _act_led; // Link activity LED. Need "mutable" keyword to let it be changed from within action() const function. Ticker _ticker; // State polling timer int _linkstate; // Last state of eth link bool _first; // Avoid duplicate IP report on the very first pass unsigned int _our_ip; // Our last IP address (used for _do_urlfile) bool _do_urlfile; // True for creating url (link) to self on local file system /local/Start.url bool _do_link_printf; // True for printing to stdout bool _do_log_printf; // True for printing activity log to stdout const char *_log_file; // Optional file for activity logging }; #endif