Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
HTTPLinkStatus.h@0:9cf1d79ebe04, 2011-09-08 (annotated)
- Committer:
- geiineuville
- Date:
- Thu Sep 08 08:57:21 2011 +0000
- Revision:
- 0:9cf1d79ebe04
v0 v1 v2 \"v3\"
Who changed what in which revision?
User | Revision | Line number | New 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 |