LRSD stephane / Mbed 2 deprecated WEBserverv1

Dependencies:   mbed

Committer:
geiineuville
Date:
Sat Sep 03 09:42:32 2011 +0000
Revision:
0:4570f87afab6
v1

Who changed what in which revision?

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