RFID Cat Door Project

Dependencies:   EthernetNetIf TextLCD mbed HTTPServer ID12RFID

Committer:
sbobyr
Date:
Tue Aug 30 04:59:24 2011 +0000
Revision:
2:9cc95c486c7b
Parent:
1:25a4acc15210
Final commented version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sbobyr 0:de1f8e99ef60 1 // RFID Cat Door Project
sbobyr 2:9cc95c486c7b 2 // The code runs on mbed and implements RFID Cat Door system. System comprises 3 sensors (RFID Reader, Proximity sensor, Reed sensor)
sbobyr 2:9cc95c486c7b 3 // and 1 actuator (Solenoid door lock). System operates either in offline or online mode (if IP address is acquired). In online mode
sbobyr 2:9cc95c486c7b 4 // a web page is created describing system's state. A lockdown override is available in online mode locking down the system.
sbobyr 2:9cc95c486c7b 5 // The system is controlled by a state machine and provides RFID-based entry control. Exit is allowed without authorization.
sbobyr 1:25a4acc15210 6
sbobyr 2:9cc95c486c7b 7 //#define NO_HW // uncomment if there's no HW attached to mbed
sbobyr 2:9cc95c486c7b 8
sbobyr 2:9cc95c486c7b 9 #include "mbed.h" // mbed library
sbobyr 2:9cc95c486c7b 10 #include "ID12RFID.h" // ID12 RFID Reader library
sbobyr 2:9cc95c486c7b 11 #include "TextLCD.h" // OrangeBoard LCD library
sbobyr 2:9cc95c486c7b 12 #include "EthernetNetIf.h" // Ethernet library
sbobyr 2:9cc95c486c7b 13 #include "HTTPServer.h" // HTTP Server library
sbobyr 2:9cc95c486c7b 14 #include "HTTPRequestHandler.h" // HTTP Request Handler library
sbobyr 0:de1f8e99ef60 15 #include <string>
sbobyr 0:de1f8e99ef60 16
sbobyr 2:9cc95c486c7b 17 EthernetNetIf eth;
sbobyr 0:de1f8e99ef60 18 HTTPServer svr;
sbobyr 1:25a4acc15210 19 class CatDoorHandler;
sbobyr 0:de1f8e99ef60 20
sbobyr 2:9cc95c486c7b 21 // State Machine Events
sbobyr 1:25a4acc15210 22 enum Event { DoorOpenEvent, DoorClosedEvent, ProximityEvent, AuthTagReadEvent, DoorUnlockedTimeoutEvent, None };
sbobyr 1:25a4acc15210 23 string eventNames[] = { "DoorOpen", "DoorClosed", "Proximity", "AuthTagRead", "DoorUnlockedTimeout", "None" };
sbobyr 1:25a4acc15210 24 Event event = None;
sbobyr 0:de1f8e99ef60 25
sbobyr 2:9cc95c486c7b 26 // State Machine States
sbobyr 1:25a4acc15210 27 enum State { DoorLockedClosed, DoorUnlockedClosed, DoorUnlockedOpen };
sbobyr 1:25a4acc15210 28 string stateNames[] = { "Door Locked & Closed", "Door Unlocked & Closed", "Door Unlocked & Open" };
sbobyr 1:25a4acc15210 29 State state = DoorLockedClosed;
sbobyr 0:de1f8e99ef60 30
sbobyr 2:9cc95c486c7b 31 bool bLockdown = false; // variable indicating a lockdown from the web page
sbobyr 0:de1f8e99ef60 32
sbobyr 2:9cc95c486c7b 33 // Cat's possible locations
sbobyr 1:25a4acc15210 34 enum Location { Inside, Outside, Unknown };
sbobyr 1:25a4acc15210 35 string locationNames[] = { "Inside", "Outside", "Unknown" };
sbobyr 0:de1f8e99ef60 36
sbobyr 2:9cc95c486c7b 37 // Each cat has tag, name, and location
sbobyr 1:25a4acc15210 38 struct cat { int tag; string name; Location location; };
sbobyr 2:9cc95c486c7b 39 // List of authorized cats
sbobyr 1:25a4acc15210 40 cat cats[] = {
sbobyr 1:25a4acc15210 41 5454121, "Yellow", Unknown,
sbobyr 1:25a4acc15210 42 //9733970, "Blue", Unknown,
sbobyr 1:25a4acc15210 43 //463733, "Red", Unknown
sbobyr 1:25a4acc15210 44 };
sbobyr 1:25a4acc15210 45 int catsN = sizeof(cats)/sizeof(cat);
sbobyr 2:9cc95c486c7b 46 int catId = 0; // current cat ID
sbobyr 0:de1f8e99ef60 47
sbobyr 2:9cc95c486c7b 48 TextLCD lcd(p24, p26, p27, p28, p29, p30); // OrangeBoard LCD
sbobyr 2:9cc95c486c7b 49 ID12RFID rfid(p14); // uart rx for ID12 RFID reader
sbobyr 2:9cc95c486c7b 50 DigitalIn _door_open(p17); // reed sensor, 0 indicates door open
sbobyr 2:9cc95c486c7b 51 DigitalIn _proximity(p16); // proximity sensor, 0 indicates an object within 10 cm
sbobyr 2:9cc95c486c7b 52 DigitalOut unlock_door(p21); // solenoid, 1 will unlock the door
sbobyr 0:de1f8e99ef60 53
sbobyr 2:9cc95c486c7b 54 DigitalOut door_unlocked_led(LED1); // ON when door is unlocked
sbobyr 2:9cc95c486c7b 55 DigitalOut door_open_led(LED2); // ON when door is open
sbobyr 2:9cc95c486c7b 56 DigitalOut proximity_led(LED3); // ON when proximity sensor is triggered
sbobyr 2:9cc95c486c7b 57 PwmOut rfid_read_led(LED4); // DIM = unauthorized tag read; BRIGHT = authorized tag read
sbobyr 0:de1f8e99ef60 58
sbobyr 0:de1f8e99ef60 59 const float LED_DIM = 0.05;
sbobyr 0:de1f8e99ef60 60 const float LED_BRIGHT = 1;
sbobyr 1:25a4acc15210 61
sbobyr 2:9cc95c486c7b 62 // Authorized RFID Tag Read Event
sbobyr 1:25a4acc15210 63 Timer tagReadTimer;
sbobyr 0:de1f8e99ef60 64 bool IsAuthTagReadEvent() {
sbobyr 0:de1f8e99ef60 65 if(rfid.readable()) {
sbobyr 2:9cc95c486c7b 66 int tag = rfid.read(); // read the tag
sbobyr 1:25a4acc15210 67 tagReadTimer.reset();
sbobyr 2:9cc95c486c7b 68 tagReadTimer.start(); // start 5 sec timer
sbobyr 0:de1f8e99ef60 69
sbobyr 1:25a4acc15210 70 lcd.cls(); lcd.locate(0, 0); lcd.printf("Tag: %08d", tag);
sbobyr 2:9cc95c486c7b 71 for (int i = 0; i < catsN; ++i) { // find if tag is authorized
sbobyr 1:25a4acc15210 72 if (cats[i].tag == tag) {
sbobyr 1:25a4acc15210 73 catId = i;
sbobyr 1:25a4acc15210 74 lcd.locate(0, 1); lcd.printf("Cat: %s", cats[i].name.c_str());
sbobyr 0:de1f8e99ef60 75 rfid_read_led = LED_BRIGHT;
sbobyr 0:de1f8e99ef60 76 return true;
sbobyr 0:de1f8e99ef60 77 }
sbobyr 0:de1f8e99ef60 78 }
sbobyr 1:25a4acc15210 79
sbobyr 2:9cc95c486c7b 80 lcd.locate(0, 1); lcd.printf("Cat: Unknown"); // unknown tag
sbobyr 1:25a4acc15210 81 rfid_read_led = LED_DIM;
sbobyr 1:25a4acc15210 82 }
sbobyr 2:9cc95c486c7b 83 if (tagReadTimer.read() > 5.0) { // each tag is shown for 5 sec
sbobyr 1:25a4acc15210 84 tagReadTimer.stop();
sbobyr 1:25a4acc15210 85 tagReadTimer.reset();
sbobyr 1:25a4acc15210 86 rfid_read_led = 0;
sbobyr 1:25a4acc15210 87 lcd.cls();
sbobyr 0:de1f8e99ef60 88 }
sbobyr 0:de1f8e99ef60 89 return false;
sbobyr 0:de1f8e99ef60 90 }
sbobyr 0:de1f8e99ef60 91
sbobyr 2:9cc95c486c7b 92 // Proximity Event
sbobyr 0:de1f8e99ef60 93 bool IsProximityEvent() {
sbobyr 0:de1f8e99ef60 94 bool result = false;
sbobyr 2:9cc95c486c7b 95 static bool wasProximity = false; // last state
sbobyr 2:9cc95c486c7b 96 bool bProximity = !_proximity.read(); // 0 indicates an object within 10 cm
sbobyr 0:de1f8e99ef60 97 proximity_led = bProximity;
sbobyr 2:9cc95c486c7b 98 if (bProximity & !wasProximity) // create event on transition only
sbobyr 0:de1f8e99ef60 99 result = true;
sbobyr 0:de1f8e99ef60 100 wasProximity = bProximity;
sbobyr 0:de1f8e99ef60 101 return result;
sbobyr 0:de1f8e99ef60 102 }
sbobyr 0:de1f8e99ef60 103
sbobyr 2:9cc95c486c7b 104 // Door Open Event
sbobyr 0:de1f8e99ef60 105 bool IsDoorOpenEvent() {
sbobyr 0:de1f8e99ef60 106 bool result = false;
sbobyr 2:9cc95c486c7b 107 static bool wasOpen = false; // last state
sbobyr 2:9cc95c486c7b 108 bool bDoorOpen = !_door_open.read(); // 0 indicates door open
sbobyr 0:de1f8e99ef60 109 door_open_led = bDoorOpen;
sbobyr 2:9cc95c486c7b 110 if (bDoorOpen & !wasOpen) // create event on transition only
sbobyr 0:de1f8e99ef60 111 result = true;
sbobyr 0:de1f8e99ef60 112 wasOpen = bDoorOpen;
sbobyr 0:de1f8e99ef60 113 return result;
sbobyr 0:de1f8e99ef60 114 }
sbobyr 0:de1f8e99ef60 115
sbobyr 2:9cc95c486c7b 116 // Door Closed Event
sbobyr 0:de1f8e99ef60 117 Timer doorClosedTimer;
sbobyr 0:de1f8e99ef60 118 bool IsDoorClosedEvent() {
sbobyr 0:de1f8e99ef60 119 bool result = false;
sbobyr 2:9cc95c486c7b 120 static bool wasClosed = true; // last state
sbobyr 0:de1f8e99ef60 121 bool bDoorClosed = _door_open.read();
sbobyr 2:9cc95c486c7b 122 if (bDoorClosed & !wasClosed) { // start timer when door closes
sbobyr 0:de1f8e99ef60 123 doorClosedTimer.reset();
sbobyr 0:de1f8e99ef60 124 doorClosedTimer.start();
sbobyr 0:de1f8e99ef60 125 }
sbobyr 2:9cc95c486c7b 126 // event is only created if door has been closed for more than 1.2 sec
sbobyr 1:25a4acc15210 127 if (bDoorClosed & doorClosedTimer.read() > 1.2) {
sbobyr 0:de1f8e99ef60 128 doorClosedTimer.stop();
sbobyr 0:de1f8e99ef60 129 doorClosedTimer.reset();
sbobyr 0:de1f8e99ef60 130 result = true;
sbobyr 0:de1f8e99ef60 131 }
sbobyr 0:de1f8e99ef60 132 wasClosed = bDoorClosed;
sbobyr 0:de1f8e99ef60 133 return result;
sbobyr 0:de1f8e99ef60 134 }
sbobyr 0:de1f8e99ef60 135
sbobyr 2:9cc95c486c7b 136 // Door locking/unlocking code
sbobyr 0:de1f8e99ef60 137 Timer doorUnlockedTimer;
sbobyr 0:de1f8e99ef60 138 void UnlockDoor(bool req) {
sbobyr 0:de1f8e99ef60 139 unlock_door = (req) ? 1 : 0;
sbobyr 0:de1f8e99ef60 140 door_unlocked_led = unlock_door;
sbobyr 0:de1f8e99ef60 141 if (req) {
sbobyr 0:de1f8e99ef60 142 doorUnlockedTimer.reset();
sbobyr 0:de1f8e99ef60 143 doorUnlockedTimer.start();
sbobyr 0:de1f8e99ef60 144 }
sbobyr 0:de1f8e99ef60 145 }
sbobyr 0:de1f8e99ef60 146
sbobyr 2:9cc95c486c7b 147 // Door Unlocked Timeout Event
sbobyr 0:de1f8e99ef60 148 bool IsDoorUnlockedTimeoutEvent() {
sbobyr 2:9cc95c486c7b 149 if (doorUnlockedTimer.read() > 5.0) { // fires if door has been unlocked for more than 5 sec
sbobyr 0:de1f8e99ef60 150 doorUnlockedTimer.stop();
sbobyr 0:de1f8e99ef60 151 doorUnlockedTimer.reset();
sbobyr 0:de1f8e99ef60 152 return true;
sbobyr 0:de1f8e99ef60 153 }
sbobyr 0:de1f8e99ef60 154 return false;
sbobyr 0:de1f8e99ef60 155 }
sbobyr 0:de1f8e99ef60 156
sbobyr 2:9cc95c486c7b 157 // State Machine Logic
sbobyr 0:de1f8e99ef60 158 void CatDoorStateMachine(Event event) {
sbobyr 2:9cc95c486c7b 159 static Location destination = Outside; // destination variable helps determine location of a cat
sbobyr 2:9cc95c486c7b 160 printf("State: %s\t Event: %s\n", stateNames[state].c_str(), eventNames[event].c_str());
sbobyr 0:de1f8e99ef60 161
sbobyr 0:de1f8e99ef60 162 switch(state)
sbobyr 0:de1f8e99ef60 163 {
sbobyr 0:de1f8e99ef60 164 case DoorLockedClosed :
sbobyr 2:9cc95c486c7b 165 if (bLockdown) break; // bLockdown doesn't let state machine exit DoorLockedClosed state
sbobyr 0:de1f8e99ef60 166 switch(event)
sbobyr 0:de1f8e99ef60 167 {
sbobyr 0:de1f8e99ef60 168 case ProximityEvent :
sbobyr 2:9cc95c486c7b 169 UnlockDoor(true); // unlock door
sbobyr 0:de1f8e99ef60 170 state = DoorUnlockedClosed;
sbobyr 2:9cc95c486c7b 171 destination = Outside; // cat's coming outside
sbobyr 0:de1f8e99ef60 172 break;
sbobyr 0:de1f8e99ef60 173 case AuthTagReadEvent :
sbobyr 2:9cc95c486c7b 174 UnlockDoor(true); // unlock door
sbobyr 0:de1f8e99ef60 175 state = DoorUnlockedClosed;
sbobyr 2:9cc95c486c7b 176 destination = Inside; // cat's coming inside
sbobyr 0:de1f8e99ef60 177 break;
sbobyr 0:de1f8e99ef60 178 default :
sbobyr 0:de1f8e99ef60 179 break;
sbobyr 0:de1f8e99ef60 180 }
sbobyr 0:de1f8e99ef60 181 break;
sbobyr 0:de1f8e99ef60 182 case DoorUnlockedClosed :
sbobyr 0:de1f8e99ef60 183 switch(event)
sbobyr 0:de1f8e99ef60 184 {
sbobyr 2:9cc95c486c7b 185 case DoorUnlockedTimeoutEvent : // lock door after 5 sec
sbobyr 2:9cc95c486c7b 186 UnlockDoor(false); // lock door
sbobyr 0:de1f8e99ef60 187 state = DoorLockedClosed;
sbobyr 0:de1f8e99ef60 188 break;
sbobyr 0:de1f8e99ef60 189 case DoorOpenEvent :
sbobyr 0:de1f8e99ef60 190 state = DoorUnlockedOpen;
sbobyr 0:de1f8e99ef60 191 break;
sbobyr 0:de1f8e99ef60 192 default :
sbobyr 0:de1f8e99ef60 193 break;
sbobyr 0:de1f8e99ef60 194 }
sbobyr 0:de1f8e99ef60 195 break;
sbobyr 0:de1f8e99ef60 196 case DoorUnlockedOpen :
sbobyr 0:de1f8e99ef60 197 switch(event)
sbobyr 0:de1f8e99ef60 198 {
sbobyr 2:9cc95c486c7b 199 case DoorClosedEvent : // door closed, can lock it now
sbobyr 2:9cc95c486c7b 200 UnlockDoor(false); // lock door
sbobyr 0:de1f8e99ef60 201 state = DoorLockedClosed;
sbobyr 2:9cc95c486c7b 202 cats[catId].location = destination; // cat's location determined
sbobyr 0:de1f8e99ef60 203 break;
sbobyr 0:de1f8e99ef60 204 default :
sbobyr 0:de1f8e99ef60 205 break;
sbobyr 0:de1f8e99ef60 206 }
sbobyr 0:de1f8e99ef60 207 break;
sbobyr 0:de1f8e99ef60 208 default :
sbobyr 0:de1f8e99ef60 209 break;
sbobyr 0:de1f8e99ef60 210 }
sbobyr 0:de1f8e99ef60 211 }
sbobyr 0:de1f8e99ef60 212
sbobyr 0:de1f8e99ef60 213 int main() {
sbobyr 2:9cc95c486c7b 214 bool bEthPresent = true; // online/offline mode variable
sbobyr 1:25a4acc15210 215 lcd.cls(); lcd.locate(0, 0); lcd.printf("RFID Cat Door");
sbobyr 1:25a4acc15210 216 lcd.locate(0, 1); lcd.printf("Setting up ^..^");
sbobyr 1:25a4acc15210 217 printf("RFID Cat Door\n");
sbobyr 1:25a4acc15210 218 printf("Setting up Ethernet ^..^\n");
sbobyr 2:9cc95c486c7b 219 EthernetErr ethErr = eth.setup(); // Ethernet setup
sbobyr 0:de1f8e99ef60 220 if (ethErr) {
sbobyr 1:25a4acc15210 221 printf("Error %d in Ethernet setup\n", ethErr);
sbobyr 1:25a4acc15210 222 printf("Operating in offline mode ^..^\n");
sbobyr 1:25a4acc15210 223 lcd.cls(); lcd.printf("Offline mode");
sbobyr 2:9cc95c486c7b 224 bEthPresent = false; // offline mode set
sbobyr 0:de1f8e99ef60 225 }
sbobyr 1:25a4acc15210 226 else {
sbobyr 1:25a4acc15210 227 printf("Ethernet setup OK\n");
sbobyr 1:25a4acc15210 228 printf("Operating in online mode ^..^\n");
sbobyr 2:9cc95c486c7b 229 IpAddr ip = eth.getIp(); // IP address
sbobyr 1:25a4acc15210 230 lcd.cls(); lcd.locate(0, 0); lcd.printf("Online mode, IP:");
sbobyr 1:25a4acc15210 231 lcd.locate(0, 1); lcd.printf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
sbobyr 1:25a4acc15210 232
sbobyr 2:9cc95c486c7b 233 svr.addHandler<CatDoorHandler>("/"); // our HTTP handler added
sbobyr 2:9cc95c486c7b 234 svr.bind(80); // port 80 bound
sbobyr 1:25a4acc15210 235 }
sbobyr 0:de1f8e99ef60 236
sbobyr 0:de1f8e99ef60 237 while(1) {
sbobyr 1:25a4acc15210 238 if (bEthPresent)
sbobyr 2:9cc95c486c7b 239 Net::poll(); // service HTTP requests
sbobyr 1:25a4acc15210 240
sbobyr 1:25a4acc15210 241 #ifndef NO_HW
sbobyr 0:de1f8e99ef60 242 if (IsAuthTagReadEvent()) {
sbobyr 2:9cc95c486c7b 243 event = AuthTagReadEvent; // Authorized Tag Read Event
sbobyr 0:de1f8e99ef60 244 CatDoorStateMachine(event);
sbobyr 0:de1f8e99ef60 245 }
sbobyr 1:25a4acc15210 246 #endif
sbobyr 0:de1f8e99ef60 247 if (IsProximityEvent()) {
sbobyr 2:9cc95c486c7b 248 event = ProximityEvent; // Proximity Event
sbobyr 0:de1f8e99ef60 249 CatDoorStateMachine(event);
sbobyr 0:de1f8e99ef60 250 }
sbobyr 0:de1f8e99ef60 251
sbobyr 0:de1f8e99ef60 252 if (IsDoorOpenEvent()) {
sbobyr 2:9cc95c486c7b 253 event = DoorOpenEvent; // Door Open Event
sbobyr 0:de1f8e99ef60 254 CatDoorStateMachine(event);
sbobyr 0:de1f8e99ef60 255 }
sbobyr 0:de1f8e99ef60 256
sbobyr 0:de1f8e99ef60 257 if (IsDoorClosedEvent()) {
sbobyr 2:9cc95c486c7b 258 event = DoorClosedEvent; // Door Closed Event
sbobyr 0:de1f8e99ef60 259 CatDoorStateMachine(event);
sbobyr 0:de1f8e99ef60 260 }
sbobyr 0:de1f8e99ef60 261
sbobyr 0:de1f8e99ef60 262 if (IsDoorUnlockedTimeoutEvent()) {
sbobyr 2:9cc95c486c7b 263 event = DoorUnlockedTimeoutEvent; // Door Unlocked Timeout Event
sbobyr 0:de1f8e99ef60 264 CatDoorStateMachine(event);
sbobyr 0:de1f8e99ef60 265 }
sbobyr 0:de1f8e99ef60 266 }
sbobyr 0:de1f8e99ef60 267 }
sbobyr 1:25a4acc15210 268
sbobyr 2:9cc95c486c7b 269 // Cat Door HTTP Handler will handle HTTP GET requests
sbobyr 1:25a4acc15210 270 class CatDoorHandler : public HTTPRequestHandler
sbobyr 1:25a4acc15210 271 {
sbobyr 1:25a4acc15210 272 public:
sbobyr 1:25a4acc15210 273 CatDoorHandler(const char* rootPath, const char* path, TCPSocket* pTCPSocket) :
sbobyr 1:25a4acc15210 274 HTTPRequestHandler(rootPath, path, pTCPSocket){}
sbobyr 1:25a4acc15210 275
sbobyr 1:25a4acc15210 276 virtual ~CatDoorHandler(){}
sbobyr 1:25a4acc15210 277
sbobyr 1:25a4acc15210 278 static inline HTTPRequestHandler* inst(const char* rootPath, const char* path, TCPSocket* pTCPSocket)
sbobyr 1:25a4acc15210 279 { return new CatDoorHandler(rootPath, path, pTCPSocket); }
sbobyr 1:25a4acc15210 280
sbobyr 2:9cc95c486c7b 281 virtual void doGet() // handles HTTP GET requests
sbobyr 1:25a4acc15210 282 {
sbobyr 2:9cc95c486c7b 283 string _path = path(); // path will have "lockdown=yes" if lockdown checkbox was checked
sbobyr 1:25a4acc15210 284 printf("doGet path: %s\n", _path.c_str());
sbobyr 1:25a4acc15210 285 bLockdown = (_path.find("lockdown=yes") == string::npos) ? false : true;
sbobyr 1:25a4acc15210 286 if (bLockdown) {
sbobyr 1:25a4acc15210 287 lcd.cls(); lcd.printf("System Lockdown!");
sbobyr 1:25a4acc15210 288 }
sbobyr 1:25a4acc15210 289 else {
sbobyr 1:25a4acc15210 290 lcd.cls();
sbobyr 1:25a4acc15210 291 }
sbobyr 1:25a4acc15210 292
sbobyr 2:9cc95c486c7b 293 // Create HTML page with status information, lockdown checkbox, and submit/refresh button
sbobyr 1:25a4acc15210 294 string rs = "<html><head><title>RFID Cat Door</title></head><body><h3>RFID Cat Door</h3>";
sbobyr 1:25a4acc15210 295 string ds = "Door Status: <i>" + stateNames[state] + "</i><br>";
sbobyr 1:25a4acc15210 296 string cs = "Cat Status: <i>" + locationNames[cats[catId].location] + "</i><p>";
sbobyr 2:9cc95c486c7b 297 string ld = (bLockdown) ? " checked" : ""; // lockdownn checkbox reflects system lockdown state
sbobyr 1:25a4acc15210 298 string fr = "<form method='get' action=''>"
sbobyr 1:25a4acc15210 299 "<input type='checkbox' name='lockdown' value='yes'" + ld + "> Lockdown System <p>"
sbobyr 1:25a4acc15210 300 "<input type='submit' value='Submit/Refresh Data'></form></body></html>";
sbobyr 1:25a4acc15210 301 rs += ds + cs + fr;
sbobyr 1:25a4acc15210 302 setContentLen(rs.length());
sbobyr 1:25a4acc15210 303 respHeaders()["Connection"] = "close";
sbobyr 2:9cc95c486c7b 304 writeData(rs.c_str(), rs.length());
sbobyr 1:25a4acc15210 305 }
sbobyr 1:25a4acc15210 306
sbobyr 1:25a4acc15210 307 virtual void doPost() {}
sbobyr 1:25a4acc15210 308 virtual void doHead() {}
sbobyr 1:25a4acc15210 309 virtual void onReadable() {}
sbobyr 1:25a4acc15210 310 virtual void onWriteable() {}
sbobyr 1:25a4acc15210 311 virtual void onClose() {}
sbobyr 1:25a4acc15210 312 };