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.
Diff: HTTPLinkStatus.h
- Revision:
- 0:4570f87afab6
diff -r 000000000000 -r 4570f87afab6 HTTPLinkStatus.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPLinkStatus.h Sat Sep 03 09:42:32 2011 +0000
@@ -0,0 +1,188 @@
+// 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