LRSD stephane / Mbed 2 deprecated WEBserverv3

Dependencies:   mbed

Committer:
geiineuville
Date:
Thu Sep 08 08:57:21 2011 +0000
Revision:
0:9cf1d79ebe04
v0 v1 v2   \"v3\"

Who changed what in which revision?

UserRevisionLine numberNew contents of line
geiineuville 0:9cf1d79ebe04 1 // HTTPLinkStatus.h
geiineuville 0:9cf1d79ebe04 2 // HTTP Server Logger class
geiineuville 0:9cf1d79ebe04 3 //
geiineuville 0:9cf1d79ebe04 4 // Provides:
geiineuville 0:9cf1d79ebe04 5 // 1. ETH port link state monitor
geiineuville 0:9cf1d79ebe04 6 // - lights LED for link
geiineuville 0:9cf1d79ebe04 7 // - default: logs link state to stdout;
geiineuville 0:9cf1d79ebe04 8 // - default: creates URL file on local filesystem (can be used to open browser to URL address)
geiineuville 0:9cf1d79ebe04 9 // 2. HTTP activity monitor (does not react to non-http traffic)
geiineuville 0:9cf1d79ebe04 10 // - blinks LED for activity / HTTP requests
geiineuville 0:9cf1d79ebe04 11 // - optional: log activity to stdout
geiineuville 0:9cf1d79ebe04 12 // - optional: log activity to file (file is opened for each log entry, so local file system can still be accessed via USB)
geiineuville 0:9cf1d79ebe04 13 //
geiineuville 0:9cf1d79ebe04 14
geiineuville 0:9cf1d79ebe04 15 #ifndef HTTPLINKSTATUS_H
geiineuville 0:9cf1d79ebe04 16 #define HTTPLINKSTATUS_H
geiineuville 0:9cf1d79ebe04 17 #include "HTTPServer.h"
geiineuville 0:9cf1d79ebe04 18
geiineuville 0:9cf1d79ebe04 19
geiineuville 0:9cf1d79ebe04 20 // FIXME: should we be able to get this from *con?
geiineuville 0:9cf1d79ebe04 21 extern Ethernet eth; // eth is defined elsewhere, avoid compiler error.
geiineuville 0:9cf1d79ebe04 22
geiineuville 0:9cf1d79ebe04 23 namespace mbed {
geiineuville 0:9cf1d79ebe04 24
geiineuville 0:9cf1d79ebe04 25 class DigitalOutDelayed : public DigitalOut {
geiineuville 0:9cf1d79ebe04 26 public:
geiineuville 0:9cf1d79ebe04 27 DigitalOutDelayed(PinName pin, const char* name = NULL) : DigitalOut(pin, name) {}
geiineuville 0:9cf1d79ebe04 28 void write(int value, float delay=0.0) {
geiineuville 0:9cf1d79ebe04 29 _timeout.detach();
geiineuville 0:9cf1d79ebe04 30 if (delay > 0.0) {
geiineuville 0:9cf1d79ebe04 31 _delay_value = value;
geiineuville 0:9cf1d79ebe04 32 _timeout.attach(this, &DigitalOutDelayed::_write_delayed, delay);
geiineuville 0:9cf1d79ebe04 33 } else {
geiineuville 0:9cf1d79ebe04 34 DigitalOut::write(value);
geiineuville 0:9cf1d79ebe04 35 }
geiineuville 0:9cf1d79ebe04 36 }
geiineuville 0:9cf1d79ebe04 37 void write_us(int value, unsigned int delay_us=0) {
geiineuville 0:9cf1d79ebe04 38 _timeout.detach();
geiineuville 0:9cf1d79ebe04 39 if (delay_us > 0) {
geiineuville 0:9cf1d79ebe04 40 _delay_value = value;
geiineuville 0:9cf1d79ebe04 41 _timeout.attach_us(this, &DigitalOutDelayed::_write_delayed, delay_us);
geiineuville 0:9cf1d79ebe04 42 } else {
geiineuville 0:9cf1d79ebe04 43 DigitalOut::write(value);
geiineuville 0:9cf1d79ebe04 44 }
geiineuville 0:9cf1d79ebe04 45 }
geiineuville 0:9cf1d79ebe04 46 #ifdef MBED_OPERATORS
geiineuville 0:9cf1d79ebe04 47 using DigitalOut::operator = ;
geiineuville 0:9cf1d79ebe04 48 using DigitalOut::operator int;
geiineuville 0:9cf1d79ebe04 49 #endif
geiineuville 0:9cf1d79ebe04 50
geiineuville 0:9cf1d79ebe04 51 protected:
geiineuville 0:9cf1d79ebe04 52 void _write_delayed(void) { DigitalOut::write(_delay_value); }
geiineuville 0:9cf1d79ebe04 53 Timeout _timeout;
geiineuville 0:9cf1d79ebe04 54 int _delay_value;
geiineuville 0:9cf1d79ebe04 55 };
geiineuville 0:9cf1d79ebe04 56
geiineuville 0:9cf1d79ebe04 57 } // namespace mbed
geiineuville 0:9cf1d79ebe04 58
geiineuville 0:9cf1d79ebe04 59 class HTTPLinkStatus : public HTTPHandler {
geiineuville 0:9cf1d79ebe04 60 public:
geiineuville 0:9cf1d79ebe04 61 HTTPLinkStatus(const char *prefix, PinName link_led=NC, PinName act_led=NC, float poll_t = 0.1,
geiineuville 0:9cf1d79ebe04 62 bool do_urlfile = true, bool do_link_printf = true, bool do_log_printf = false, const char* log_file = NULL
geiineuville 0:9cf1d79ebe04 63 ) :
geiineuville 0:9cf1d79ebe04 64 HTTPHandler(prefix),
geiineuville 0:9cf1d79ebe04 65 _link_led(link_led),
geiineuville 0:9cf1d79ebe04 66 _act_led(act_led),
geiineuville 0:9cf1d79ebe04 67 _linkstate(-1),
geiineuville 0:9cf1d79ebe04 68 _first(true),
geiineuville 0:9cf1d79ebe04 69 _our_ip(0),
geiineuville 0:9cf1d79ebe04 70 _do_urlfile(do_urlfile),
geiineuville 0:9cf1d79ebe04 71 _do_link_printf(do_link_printf),
geiineuville 0:9cf1d79ebe04 72 _do_log_printf(do_log_printf),
geiineuville 0:9cf1d79ebe04 73 _log_file(log_file)
geiineuville 0:9cf1d79ebe04 74 {
geiineuville 0:9cf1d79ebe04 75 if (poll_t > 0) _ticker.attach(this, &HTTPLinkStatus::_link_poll, poll_t);
geiineuville 0:9cf1d79ebe04 76 }
geiineuville 0:9cf1d79ebe04 77 HTTPLinkStatus(HTTPServer *server, const char *prefix, PinName link_led=NC, PinName act_led=NC, float poll_t = 0.1,
geiineuville 0:9cf1d79ebe04 78 bool do_urlfile = true, bool do_link_printf = true, bool do_log_printf = false, const char* log_file = NULL
geiineuville 0:9cf1d79ebe04 79 ) :
geiineuville 0:9cf1d79ebe04 80 HTTPHandler(prefix),
geiineuville 0:9cf1d79ebe04 81 _link_led(link_led),
geiineuville 0:9cf1d79ebe04 82 _act_led(act_led),
geiineuville 0:9cf1d79ebe04 83 _linkstate(-1),
geiineuville 0:9cf1d79ebe04 84 _first(true),
geiineuville 0:9cf1d79ebe04 85 _our_ip(0),
geiineuville 0:9cf1d79ebe04 86 _do_urlfile(do_urlfile),
geiineuville 0:9cf1d79ebe04 87 _do_link_printf(do_link_printf),
geiineuville 0:9cf1d79ebe04 88 _do_log_printf(do_log_printf),
geiineuville 0:9cf1d79ebe04 89 _log_file(log_file)
geiineuville 0:9cf1d79ebe04 90 {
geiineuville 0:9cf1d79ebe04 91 server->addHandler(this);
geiineuville 0:9cf1d79ebe04 92 if (poll_t > 0) _ticker.attach(this, &HTTPLinkStatus::_link_poll, poll_t);
geiineuville 0:9cf1d79ebe04 93 }
geiineuville 0:9cf1d79ebe04 94 virtual ~HTTPLinkStatus() {
geiineuville 0:9cf1d79ebe04 95 _ticker.detach(); // Needeed?
geiineuville 0:9cf1d79ebe04 96 }
geiineuville 0:9cf1d79ebe04 97 void set_do_urlfile(bool val) { _do_urlfile = val; }
geiineuville 0:9cf1d79ebe04 98 void set_link_stdout(bool val) { _do_link_printf = val; }
geiineuville 0:9cf1d79ebe04 99 void set_log_stdout(bool val) { _do_log_printf = val; }
geiineuville 0:9cf1d79ebe04 100 void set_log_file(const char *file) {
geiineuville 0:9cf1d79ebe04 101 _log_file = file;
geiineuville 0:9cf1d79ebe04 102 if (_log_file) {
geiineuville 0:9cf1d79ebe04 103 FILE *fp = fopen(_log_file, "a");
geiineuville 0:9cf1d79ebe04 104 if (fp) {
geiineuville 0:9cf1d79ebe04 105 fprintf(fp, "======== HTTPLinkStatus NEW LOG OPENED ========\r\n");
geiineuville 0:9cf1d79ebe04 106 fclose(fp);
geiineuville 0:9cf1d79ebe04 107 } else {
geiineuville 0:9cf1d79ebe04 108 _log_file = NULL; // Error opening file. Reset file name so we won't waste our time trying to log to it.
geiineuville 0:9cf1d79ebe04 109 }
geiineuville 0:9cf1d79ebe04 110 }
geiineuville 0:9cf1d79ebe04 111 }
geiineuville 0:9cf1d79ebe04 112 private:
geiineuville 0:9cf1d79ebe04 113 void _link_poll() {
geiineuville 0:9cf1d79ebe04 114 int new_linkstate = eth.link();
geiineuville 0:9cf1d79ebe04 115 if (new_linkstate) {
geiineuville 0:9cf1d79ebe04 116 // From http://mbed.org/forum/post/909/
geiineuville 0:9cf1d79ebe04 117 NetServer *net = NetServer::get();
geiineuville 0:9cf1d79ebe04 118 struct ip_addr ip = net->getIPAddr();
geiineuville 0:9cf1d79ebe04 119 // struct ip_addr gw = net->getGateway();
geiineuville 0:9cf1d79ebe04 120 // struct ip_addr nm = net->getNetmask();
geiineuville 0:9cf1d79ebe04 121 // struct ip_addr dns = net->getDNS1();
geiineuville 0:9cf1d79ebe04 122 if (ip.addr != _our_ip) {
geiineuville 0:9cf1d79ebe04 123 if (!_first &&_do_link_printf) {
geiineuville 0:9cf1d79ebe04 124 printf("IP: %hhu.%hhu.%hhu.%hhu\r\n",
geiineuville 0:9cf1d79ebe04 125 (ip.addr)&0xFF, (ip.addr>>8)&0xFF, (ip.addr>>16)&0xFF, (ip.addr>>24)&0xFF);
geiineuville 0:9cf1d79ebe04 126
geiineuville 0:9cf1d79ebe04 127 }
geiineuville 0:9cf1d79ebe04 128
geiineuville 0:9cf1d79ebe04 129 _first = false;
geiineuville 0:9cf1d79ebe04 130 if (_do_urlfile) {
geiineuville 0:9cf1d79ebe04 131 // Create a link file to our IP.
geiineuville 0:9cf1d79ebe04 132 FILE *fp = fopen("/local/Start.url", "w"); // Create a link to own IP
geiineuville 0:9cf1d79ebe04 133 if (fp) {
geiineuville 0:9cf1d79ebe04 134 fprintf(fp, "[InternetShortcut]\r\nURL=http://%hhu.%hhu.%hhu.%hhu/\r\n",
geiineuville 0:9cf1d79ebe04 135 (ip.addr)&0xFF, (ip.addr>>8)&0xFF, (ip.addr>>16)&0xFF, (ip.addr>>24)&0xFF);
geiineuville 0:9cf1d79ebe04 136
geiineuville 0:9cf1d79ebe04 137 fclose(fp);
geiineuville 0:9cf1d79ebe04 138 }
geiineuville 0:9cf1d79ebe04 139 }
geiineuville 0:9cf1d79ebe04 140 _our_ip = ip.addr;
geiineuville 0:9cf1d79ebe04 141 }
geiineuville 0:9cf1d79ebe04 142 }
geiineuville 0:9cf1d79ebe04 143 else {
geiineuville 0:9cf1d79ebe04 144 if (_do_link_printf && _linkstate != new_linkstate) {
geiineuville 0:9cf1d79ebe04 145 printf("IP: <link down>\r\n");
geiineuville 0:9cf1d79ebe04 146 }
geiineuville 0:9cf1d79ebe04 147 }
geiineuville 0:9cf1d79ebe04 148 _link_led = new_linkstate;
geiineuville 0:9cf1d79ebe04 149 _linkstate = new_linkstate;
geiineuville 0:9cf1d79ebe04 150 }
geiineuville 0:9cf1d79ebe04 151
geiineuville 0:9cf1d79ebe04 152 virtual HTTPHandle action(HTTPConnection *con) const {
geiineuville 0:9cf1d79ebe04 153 _act_led = 1;
geiineuville 0:9cf1d79ebe04 154
geiineuville 0:9cf1d79ebe04 155 // struct ip_addr ip = con->_pcb()->remote_ip;
geiineuville 0:9cf1d79ebe04 156 struct ip_addr ip = con->get_remote_ip(); // This requires a patch to TCPConnection.h file in lwip/Core
geiineuville 0:9cf1d79ebe04 157 if (_do_log_printf) {
geiineuville 0:9cf1d79ebe04 158 printf("HTTPStatus IP: %hhu.%hhu.%hhu.%hhu %s %s\r\n",
geiineuville 0:9cf1d79ebe04 159 (ip.addr)&0xFF, (ip.addr>>8)&0xFF, (ip.addr>>16)&0xFF, (ip.addr>>24)&0xFF,
geiineuville 0:9cf1d79ebe04 160 (con->getType() == POST? "POST" : "GET "), con->getURL()
geiineuville 0:9cf1d79ebe04 161 );
geiineuville 0:9cf1d79ebe04 162 }
geiineuville 0:9cf1d79ebe04 163 if (_log_file) {
geiineuville 0:9cf1d79ebe04 164 FILE *fp = fopen(_log_file, "a");
geiineuville 0:9cf1d79ebe04 165 if (fp) {
geiineuville 0:9cf1d79ebe04 166 fprintf(fp, "HTTPStatus IP: %hhu.%hhu.%hhu.%hhu %s %s\r\n",
geiineuville 0:9cf1d79ebe04 167 (ip.addr)&0xFF, (ip.addr>>8)&0xFF, (ip.addr>>16)&0xFF, (ip.addr>>24)&0xFF,
geiineuville 0:9cf1d79ebe04 168 (con->getType() == POST? "POST" : "GET "), con->getURL()
geiineuville 0:9cf1d79ebe04 169 );
geiineuville 0:9cf1d79ebe04 170 fclose(fp);
geiineuville 0:9cf1d79ebe04 171 }
geiineuville 0:9cf1d79ebe04 172 }
geiineuville 0:9cf1d79ebe04 173 _act_led.write(0, 0.050); // Delayed write
geiineuville 0:9cf1d79ebe04 174 return HTTP_AddFields;
geiineuville 0:9cf1d79ebe04 175 }
geiineuville 0:9cf1d79ebe04 176
geiineuville 0:9cf1d79ebe04 177 DigitalOut _link_led; // Link status LED
geiineuville 0:9cf1d79ebe04 178 mutable DigitalOutDelayed _act_led; // Link activity LED. Need "mutable" keyword to let it be changed from within action() const function.
geiineuville 0:9cf1d79ebe04 179 Ticker _ticker; // State polling timer
geiineuville 0:9cf1d79ebe04 180 int _linkstate; // Last state of eth link
geiineuville 0:9cf1d79ebe04 181 bool _first; // Avoid duplicate IP report on the very first pass
geiineuville 0:9cf1d79ebe04 182 unsigned int _our_ip; // Our last IP address (used for _do_urlfile)
geiineuville 0:9cf1d79ebe04 183 bool _do_urlfile; // True for creating url (link) to self on local file system /local/Start.url
geiineuville 0:9cf1d79ebe04 184 bool _do_link_printf; // True for printing to stdout
geiineuville 0:9cf1d79ebe04 185 bool _do_log_printf; // True for printing activity log to stdout
geiineuville 0:9cf1d79ebe04 186 const char *_log_file; // Optional file for activity logging
geiineuville 0:9cf1d79ebe04 187 };
geiineuville 0:9cf1d79ebe04 188
geiineuville 0:9cf1d79ebe04 189 #endif