An access controller for man doors at our facility. It receives Wiegand signals from a keypad/card reader and activates a relay to open the door. Access codes are stored in EEPROM. The active code list is updated from TFTP on a local server.
Dependencies: 24LCxx_I2C CardReader USBHOST
main.cpp@0:a56239ae90c2, 2017-09-25 (annotated)
- Committer:
- acesrobertm
- Date:
- Mon Sep 25 19:02:40 2017 +0000
- Revision:
- 0:a56239ae90c2
in process of moving networking code to non-blocking format
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
acesrobertm | 0:a56239ae90c2 | 1 | #if !FEATURE_LWIP |
acesrobertm | 0:a56239ae90c2 | 2 | #error [NOT_SUPPORTED] LWIP not supported for this target |
acesrobertm | 0:a56239ae90c2 | 3 | #endif |
acesrobertm | 0:a56239ae90c2 | 4 | |
acesrobertm | 0:a56239ae90c2 | 5 | #include <sstream> // std::istringstream |
acesrobertm | 0:a56239ae90c2 | 6 | #include <string> |
acesrobertm | 0:a56239ae90c2 | 7 | #include "mbed.h" |
acesrobertm | 0:a56239ae90c2 | 8 | #include "EthernetInterface.h" |
acesrobertm | 0:a56239ae90c2 | 9 | #include "TCPServer.h" |
acesrobertm | 0:a56239ae90c2 | 10 | #include "TCPSocket.h" |
acesrobertm | 0:a56239ae90c2 | 11 | #include "CardReader/ReaderWiegand.h" |
acesrobertm | 0:a56239ae90c2 | 12 | #include "CodeMemory.h" |
acesrobertm | 0:a56239ae90c2 | 13 | #include "ConfigurationManager.h" |
acesrobertm | 0:a56239ae90c2 | 14 | |
acesrobertm | 0:a56239ae90c2 | 15 | #define MAX_TCP_CONNECTIONS 5 |
acesrobertm | 0:a56239ae90c2 | 16 | #define HTTP_SERVER_PORT 80 |
acesrobertm | 0:a56239ae90c2 | 17 | #define DATA_SERVER_PORT 500 |
acesrobertm | 0:a56239ae90c2 | 18 | #define RELAY_PULSE_MS 2000 |
acesrobertm | 0:a56239ae90c2 | 19 | #define UNLATCH_FLASH_MS 50 |
acesrobertm | 0:a56239ae90c2 | 20 | #define UNLATCH_NUM_BEEPS 5 |
acesrobertm | 0:a56239ae90c2 | 21 | |
acesrobertm | 0:a56239ae90c2 | 22 | #define HTTP_STATUS_LINE "HTTP/1.0 200 OK" |
acesrobertm | 0:a56239ae90c2 | 23 | #define HTTP_HEADER_FIELDS "Content-Type: text/html; charset=utf-8" |
acesrobertm | 0:a56239ae90c2 | 24 | #define HTTP_MESSAGE_BODY "" \ |
acesrobertm | 0:a56239ae90c2 | 25 | "<html>" "\r\n" \ |
acesrobertm | 0:a56239ae90c2 | 26 | " <body style=\"display:flex;text-align:center\">" "\r\n" \ |
acesrobertm | 0:a56239ae90c2 | 27 | " <div style=\"margin:auto\">" "\r\n" \ |
acesrobertm | 0:a56239ae90c2 | 28 | " <h1>East Center Carport Door</h1>" "\r\n" \ |
acesrobertm | 0:a56239ae90c2 | 29 | " <p>Data Server Port: %d</p>" "\r\n" \ |
acesrobertm | 0:a56239ae90c2 | 30 | " <p>Number of button presses: %d</p>" "\r\n" \ |
acesrobertm | 0:a56239ae90c2 | 31 | " </div>" "\r\n" \ |
acesrobertm | 0:a56239ae90c2 | 32 | " </body>" "\r\n" \ |
acesrobertm | 0:a56239ae90c2 | 33 | "</html>" |
acesrobertm | 0:a56239ae90c2 | 34 | |
acesrobertm | 0:a56239ae90c2 | 35 | #define HTTP_RESPONSE HTTP_STATUS_LINE "\r\n" \ |
acesrobertm | 0:a56239ae90c2 | 36 | HTTP_HEADER_FIELDS "\r\n" \ |
acesrobertm | 0:a56239ae90c2 | 37 | "\r\n" \ |
acesrobertm | 0:a56239ae90c2 | 38 | HTTP_MESSAGE_BODY "\r\n" |
acesrobertm | 0:a56239ae90c2 | 39 | |
acesrobertm | 0:a56239ae90c2 | 40 | using namespace std; |
acesrobertm | 0:a56239ae90c2 | 41 | |
acesrobertm | 0:a56239ae90c2 | 42 | DigitalOut qx_led1(LED1); |
acesrobertm | 0:a56239ae90c2 | 43 | DigitalOut qx_led2(LED2); |
acesrobertm | 0:a56239ae90c2 | 44 | DigitalOut qx_relay(D12); |
acesrobertm | 0:a56239ae90c2 | 45 | DigitalOut qx_redReaderLed(D6); |
acesrobertm | 0:a56239ae90c2 | 46 | DigitalOut qx_greenReaderLed(D7); |
acesrobertm | 0:a56239ae90c2 | 47 | DigitalOut qx_readerBuzzer(D8); |
acesrobertm | 0:a56239ae90c2 | 48 | |
acesrobertm | 0:a56239ae90c2 | 49 | InterruptIn ix_usrBtn(USER_BUTTON); |
acesrobertm | 0:a56239ae90c2 | 50 | InterruptIn ix_tamper(D5); |
acesrobertm | 0:a56239ae90c2 | 51 | InterruptIn ix_doorLatched(D13); |
acesrobertm | 0:a56239ae90c2 | 52 | |
acesrobertm | 0:a56239ae90c2 | 53 | EthernetInterface* _eth; |
acesrobertm | 0:a56239ae90c2 | 54 | char* _mac_addr; |
acesrobertm | 0:a56239ae90c2 | 55 | char* _ip_addr; |
acesrobertm | 0:a56239ae90c2 | 56 | |
acesrobertm | 0:a56239ae90c2 | 57 | int button_presses = 0; |
acesrobertm | 0:a56239ae90c2 | 58 | |
acesrobertm | 0:a56239ae90c2 | 59 | char httpReq[100]; |
acesrobertm | 0:a56239ae90c2 | 60 | char httpResponse[100]; |
acesrobertm | 0:a56239ae90c2 | 61 | |
acesrobertm | 0:a56239ae90c2 | 62 | ReaderWiegand wgReader(D2, D4); |
acesrobertm | 0:a56239ae90c2 | 63 | CodeMemory codeMem; |
acesrobertm | 0:a56239ae90c2 | 64 | ConfigurationManager configManager(_eth, &codeMem); |
acesrobertm | 0:a56239ae90c2 | 65 | |
acesrobertm | 0:a56239ae90c2 | 66 | Timeout mRelayTimer; |
acesrobertm | 0:a56239ae90c2 | 67 | Timeout unlatchFlashTimer; |
acesrobertm | 0:a56239ae90c2 | 68 | |
acesrobertm | 0:a56239ae90c2 | 69 | RawSerial usbUART(USBTX, USBRX); |
acesrobertm | 0:a56239ae90c2 | 70 | volatile int rx_idx = 0; |
acesrobertm | 0:a56239ae90c2 | 71 | char usb_rx_buffer[USB_RX_MAX_LENGTH + 1]; |
acesrobertm | 0:a56239ae90c2 | 72 | |
acesrobertm | 0:a56239ae90c2 | 73 | // Interupt Routine to read in data from serial port |
acesrobertm | 0:a56239ae90c2 | 74 | void Rx_interrupt() { |
acesrobertm | 0:a56239ae90c2 | 75 | while ((usbUART.readable()) && rx_idx < USB_RX_MAX_LENGTH) { |
acesrobertm | 0:a56239ae90c2 | 76 | usb_rx_buffer[rx_idx] = usbUART.getc(); |
acesrobertm | 0:a56239ae90c2 | 77 | rx_idx++; |
acesrobertm | 0:a56239ae90c2 | 78 | } |
acesrobertm | 0:a56239ae90c2 | 79 | |
acesrobertm | 0:a56239ae90c2 | 80 | return; |
acesrobertm | 0:a56239ae90c2 | 81 | } |
acesrobertm | 0:a56239ae90c2 | 82 | |
acesrobertm | 0:a56239ae90c2 | 83 | void relayTimeout() |
acesrobertm | 0:a56239ae90c2 | 84 | { |
acesrobertm | 0:a56239ae90c2 | 85 | qx_led2 = 0; |
acesrobertm | 0:a56239ae90c2 | 86 | qx_relay = 0; |
acesrobertm | 0:a56239ae90c2 | 87 | } |
acesrobertm | 0:a56239ae90c2 | 88 | |
acesrobertm | 0:a56239ae90c2 | 89 | void relayTimerRestart() |
acesrobertm | 0:a56239ae90c2 | 90 | { |
acesrobertm | 0:a56239ae90c2 | 91 | mRelayTimer.detach(); |
acesrobertm | 0:a56239ae90c2 | 92 | mRelayTimer.attach_us(&relayTimeout, RELAY_PULSE_MS * 1000); |
acesrobertm | 0:a56239ae90c2 | 93 | } |
acesrobertm | 0:a56239ae90c2 | 94 | |
acesrobertm | 0:a56239ae90c2 | 95 | void usr_btn_pressed() |
acesrobertm | 0:a56239ae90c2 | 96 | { |
acesrobertm | 0:a56239ae90c2 | 97 | button_presses++; |
acesrobertm | 0:a56239ae90c2 | 98 | |
acesrobertm | 0:a56239ae90c2 | 99 | // Manual strike release |
acesrobertm | 0:a56239ae90c2 | 100 | relayTimerRestart(); |
acesrobertm | 0:a56239ae90c2 | 101 | qx_led2 = 1; |
acesrobertm | 0:a56239ae90c2 | 102 | qx_relay = 1; |
acesrobertm | 0:a56239ae90c2 | 103 | } |
acesrobertm | 0:a56239ae90c2 | 104 | |
acesrobertm | 0:a56239ae90c2 | 105 | void handle_tamper() |
acesrobertm | 0:a56239ae90c2 | 106 | { |
acesrobertm | 0:a56239ae90c2 | 107 | qx_greenReaderLed = !qx_greenReaderLed; |
acesrobertm | 0:a56239ae90c2 | 108 | qx_led2 = !qx_led2; |
acesrobertm | 0:a56239ae90c2 | 109 | } |
acesrobertm | 0:a56239ae90c2 | 110 | |
acesrobertm | 0:a56239ae90c2 | 111 | void handle_latch() |
acesrobertm | 0:a56239ae90c2 | 112 | { |
acesrobertm | 0:a56239ae90c2 | 113 | qx_redReaderLed = !qx_redReaderLed; |
acesrobertm | 0:a56239ae90c2 | 114 | } |
acesrobertm | 0:a56239ae90c2 | 115 | |
acesrobertm | 0:a56239ae90c2 | 116 | void unlatch_flash() |
acesrobertm | 0:a56239ae90c2 | 117 | { |
acesrobertm | 0:a56239ae90c2 | 118 | static int flash_count = 0; |
acesrobertm | 0:a56239ae90c2 | 119 | |
acesrobertm | 0:a56239ae90c2 | 120 | if (qx_relay) |
acesrobertm | 0:a56239ae90c2 | 121 | { |
acesrobertm | 0:a56239ae90c2 | 122 | if (qx_redReaderLed) |
acesrobertm | 0:a56239ae90c2 | 123 | { |
acesrobertm | 0:a56239ae90c2 | 124 | qx_redReaderLed = 0; |
acesrobertm | 0:a56239ae90c2 | 125 | qx_greenReaderLed = 1; |
acesrobertm | 0:a56239ae90c2 | 126 | |
acesrobertm | 0:a56239ae90c2 | 127 | if (flash_count++ < UNLATCH_NUM_BEEPS) |
acesrobertm | 0:a56239ae90c2 | 128 | { |
acesrobertm | 0:a56239ae90c2 | 129 | qx_readerBuzzer = 0; |
acesrobertm | 0:a56239ae90c2 | 130 | } |
acesrobertm | 0:a56239ae90c2 | 131 | } |
acesrobertm | 0:a56239ae90c2 | 132 | else |
acesrobertm | 0:a56239ae90c2 | 133 | { |
acesrobertm | 0:a56239ae90c2 | 134 | qx_redReaderLed = 1; |
acesrobertm | 0:a56239ae90c2 | 135 | qx_greenReaderLed = 0; |
acesrobertm | 0:a56239ae90c2 | 136 | qx_readerBuzzer = 1; |
acesrobertm | 0:a56239ae90c2 | 137 | } |
acesrobertm | 0:a56239ae90c2 | 138 | |
acesrobertm | 0:a56239ae90c2 | 139 | // Delay and call this function again. |
acesrobertm | 0:a56239ae90c2 | 140 | unlatchFlashTimer.detach(); |
acesrobertm | 0:a56239ae90c2 | 141 | unlatchFlashTimer.attach_us(&unlatch_flash, UNLATCH_FLASH_MS * 1000); |
acesrobertm | 0:a56239ae90c2 | 142 | } |
acesrobertm | 0:a56239ae90c2 | 143 | else |
acesrobertm | 0:a56239ae90c2 | 144 | { |
acesrobertm | 0:a56239ae90c2 | 145 | qx_redReaderLed = 1; |
acesrobertm | 0:a56239ae90c2 | 146 | qx_greenReaderLed = 1; |
acesrobertm | 0:a56239ae90c2 | 147 | qx_readerBuzzer = 1; |
acesrobertm | 0:a56239ae90c2 | 148 | flash_count = 0; |
acesrobertm | 0:a56239ae90c2 | 149 | } |
acesrobertm | 0:a56239ae90c2 | 150 | } |
acesrobertm | 0:a56239ae90c2 | 151 | |
acesrobertm | 0:a56239ae90c2 | 152 | void unlatchStrike() |
acesrobertm | 0:a56239ae90c2 | 153 | { |
acesrobertm | 0:a56239ae90c2 | 154 | relayTimerRestart(); |
acesrobertm | 0:a56239ae90c2 | 155 | |
acesrobertm | 0:a56239ae90c2 | 156 | qx_led2 = 1; |
acesrobertm | 0:a56239ae90c2 | 157 | qx_relay = 1; |
acesrobertm | 0:a56239ae90c2 | 158 | |
acesrobertm | 0:a56239ae90c2 | 159 | unlatch_flash(); |
acesrobertm | 0:a56239ae90c2 | 160 | |
acesrobertm | 0:a56239ae90c2 | 161 | return; |
acesrobertm | 0:a56239ae90c2 | 162 | } |
acesrobertm | 0:a56239ae90c2 | 163 | |
acesrobertm | 0:a56239ae90c2 | 164 | bool commandHasArg(string testString, string commandName) |
acesrobertm | 0:a56239ae90c2 | 165 | { |
acesrobertm | 0:a56239ae90c2 | 166 | int commandLength = commandName.length(); |
acesrobertm | 0:a56239ae90c2 | 167 | return ((testString.length() >= (commandLength + 2)) && (testString.find(" ") == commandLength) && testString.compare(0, commandLength, commandName) == 0); |
acesrobertm | 0:a56239ae90c2 | 168 | } |
acesrobertm | 0:a56239ae90c2 | 169 | |
acesrobertm | 0:a56239ae90c2 | 170 | unsigned short stringToCode(string codeStr) |
acesrobertm | 0:a56239ae90c2 | 171 | { |
acesrobertm | 0:a56239ae90c2 | 172 | unsigned short codeValue; |
acesrobertm | 0:a56239ae90c2 | 173 | istringstream iss(codeStr); |
acesrobertm | 0:a56239ae90c2 | 174 | |
acesrobertm | 0:a56239ae90c2 | 175 | iss >> codeValue; |
acesrobertm | 0:a56239ae90c2 | 176 | |
acesrobertm | 0:a56239ae90c2 | 177 | return codeValue; |
acesrobertm | 0:a56239ae90c2 | 178 | } |
acesrobertm | 0:a56239ae90c2 | 179 | |
acesrobertm | 0:a56239ae90c2 | 180 | void submitSerialCommand(string command) |
acesrobertm | 0:a56239ae90c2 | 181 | { |
acesrobertm | 0:a56239ae90c2 | 182 | command = command.substr(0, command.length() - 1); // Remove the new line character from the end of the command. |
acesrobertm | 0:a56239ae90c2 | 183 | |
acesrobertm | 0:a56239ae90c2 | 184 | // Remote access code commands |
acesrobertm | 0:a56239ae90c2 | 185 | if (!command.compare("help")) |
acesrobertm | 0:a56239ae90c2 | 186 | { |
acesrobertm | 0:a56239ae90c2 | 187 | //printProgStr(helpMessage); |
acesrobertm | 0:a56239ae90c2 | 188 | printf("This is the help command.\n"); |
acesrobertm | 0:a56239ae90c2 | 189 | } |
acesrobertm | 0:a56239ae90c2 | 190 | |
acesrobertm | 0:a56239ae90c2 | 191 | else if (!command.compare("list")) |
acesrobertm | 0:a56239ae90c2 | 192 | { |
acesrobertm | 0:a56239ae90c2 | 193 | codeMem.PrintAllAccessCodes(); |
acesrobertm | 0:a56239ae90c2 | 194 | } |
acesrobertm | 0:a56239ae90c2 | 195 | |
acesrobertm | 0:a56239ae90c2 | 196 | else if (!command.compare("log")) |
acesrobertm | 0:a56239ae90c2 | 197 | { |
acesrobertm | 0:a56239ae90c2 | 198 | codeMem.PrintRecentEvents(); |
acesrobertm | 0:a56239ae90c2 | 199 | } |
acesrobertm | 0:a56239ae90c2 | 200 | else if (commandHasArg(command, "log")) |
acesrobertm | 0:a56239ae90c2 | 201 | { |
acesrobertm | 0:a56239ae90c2 | 202 | string arg = command.substr(command.find(" ") + 1); |
acesrobertm | 0:a56239ae90c2 | 203 | |
acesrobertm | 0:a56239ae90c2 | 204 | if (!arg.compare("full")) |
acesrobertm | 0:a56239ae90c2 | 205 | { |
acesrobertm | 0:a56239ae90c2 | 206 | codeMem.PrintEventLog(); |
acesrobertm | 0:a56239ae90c2 | 207 | } |
acesrobertm | 0:a56239ae90c2 | 208 | } |
acesrobertm | 0:a56239ae90c2 | 209 | |
acesrobertm | 0:a56239ae90c2 | 210 | else if (!command.compare("clear eeprom")) |
acesrobertm | 0:a56239ae90c2 | 211 | { |
acesrobertm | 0:a56239ae90c2 | 212 | printf("Clearing EEPROM...\n"); |
acesrobertm | 0:a56239ae90c2 | 213 | codeMem.EEPROMClear(); |
acesrobertm | 0:a56239ae90c2 | 214 | printf("EEPROM Erased\n"); |
acesrobertm | 0:a56239ae90c2 | 215 | } |
acesrobertm | 0:a56239ae90c2 | 216 | |
acesrobertm | 0:a56239ae90c2 | 217 | else if (commandHasArg(command, "activate")) |
acesrobertm | 0:a56239ae90c2 | 218 | { |
acesrobertm | 0:a56239ae90c2 | 219 | unsigned short code = stringToCode(command.substr(command.find(" ") + 1)); |
acesrobertm | 0:a56239ae90c2 | 220 | int address = codeMem.ActivateAccessCode(code); |
acesrobertm | 0:a56239ae90c2 | 221 | |
acesrobertm | 0:a56239ae90c2 | 222 | if (address >= 0) |
acesrobertm | 0:a56239ae90c2 | 223 | { |
acesrobertm | 0:a56239ae90c2 | 224 | printf("Code Activated: Address %d\n", address); |
acesrobertm | 0:a56239ae90c2 | 225 | } |
acesrobertm | 0:a56239ae90c2 | 226 | else if (address == -1) |
acesrobertm | 0:a56239ae90c2 | 227 | { |
acesrobertm | 0:a56239ae90c2 | 228 | printf("Failed to Activate: Code Already Exists\n"); |
acesrobertm | 0:a56239ae90c2 | 229 | } |
acesrobertm | 0:a56239ae90c2 | 230 | else if (address == -2) |
acesrobertm | 0:a56239ae90c2 | 231 | { |
acesrobertm | 0:a56239ae90c2 | 232 | printf("Failed to Activate: Code Table Full\n"); |
acesrobertm | 0:a56239ae90c2 | 233 | } |
acesrobertm | 0:a56239ae90c2 | 234 | else |
acesrobertm | 0:a56239ae90c2 | 235 | { |
acesrobertm | 0:a56239ae90c2 | 236 | printf("Unknown Error\n"); |
acesrobertm | 0:a56239ae90c2 | 237 | } |
acesrobertm | 0:a56239ae90c2 | 238 | } |
acesrobertm | 0:a56239ae90c2 | 239 | |
acesrobertm | 0:a56239ae90c2 | 240 | else if (commandHasArg(command, "revoke")) |
acesrobertm | 0:a56239ae90c2 | 241 | { |
acesrobertm | 0:a56239ae90c2 | 242 | unsigned short code = stringToCode(command.substr(command.find(" ") + 1)); |
acesrobertm | 0:a56239ae90c2 | 243 | int address = codeMem.DeactivateAccessCode(code); |
acesrobertm | 0:a56239ae90c2 | 244 | |
acesrobertm | 0:a56239ae90c2 | 245 | if (address < 0) |
acesrobertm | 0:a56239ae90c2 | 246 | { |
acesrobertm | 0:a56239ae90c2 | 247 | printf("Failed to Revoke: Code Not Found\n"); |
acesrobertm | 0:a56239ae90c2 | 248 | } |
acesrobertm | 0:a56239ae90c2 | 249 | else |
acesrobertm | 0:a56239ae90c2 | 250 | { |
acesrobertm | 0:a56239ae90c2 | 251 | printf("Code Revoked: Address %d\n", address); |
acesrobertm | 0:a56239ae90c2 | 252 | } |
acesrobertm | 0:a56239ae90c2 | 253 | } |
acesrobertm | 0:a56239ae90c2 | 254 | |
acesrobertm | 0:a56239ae90c2 | 255 | else if (commandHasArg(command, "setsc")) |
acesrobertm | 0:a56239ae90c2 | 256 | { |
acesrobertm | 0:a56239ae90c2 | 257 | int afterFirstSpace = command.find(" ") + 1; |
acesrobertm | 0:a56239ae90c2 | 258 | int afterSecondSpace = command.find_last_of(" ") + 1; |
acesrobertm | 0:a56239ae90c2 | 259 | unsigned short specialIndex = stringToCode(command.substr(afterFirstSpace, afterSecondSpace - 1)); |
acesrobertm | 0:a56239ae90c2 | 260 | unsigned short specialCode = stringToCode(command.substr(afterSecondSpace)); |
acesrobertm | 0:a56239ae90c2 | 261 | |
acesrobertm | 0:a56239ae90c2 | 262 | // Ensure that there are at least two arguments |
acesrobertm | 0:a56239ae90c2 | 263 | if (afterSecondSpace > afterFirstSpace) |
acesrobertm | 0:a56239ae90c2 | 264 | { |
acesrobertm | 0:a56239ae90c2 | 265 | codeMem.SetSpecialCode(specialIndex, specialCode); |
acesrobertm | 0:a56239ae90c2 | 266 | } |
acesrobertm | 0:a56239ae90c2 | 267 | } |
acesrobertm | 0:a56239ae90c2 | 268 | |
acesrobertm | 0:a56239ae90c2 | 269 | // Remote door commands |
acesrobertm | 0:a56239ae90c2 | 270 | else if (commandHasArg(command, "door")) |
acesrobertm | 0:a56239ae90c2 | 271 | { |
acesrobertm | 0:a56239ae90c2 | 272 | string arg = command.substr(command.find(" ") + 1); |
acesrobertm | 0:a56239ae90c2 | 273 | |
acesrobertm | 0:a56239ae90c2 | 274 | if (!arg.compare("status")) |
acesrobertm | 0:a56239ae90c2 | 275 | { |
acesrobertm | 0:a56239ae90c2 | 276 | if (ix_doorLatched) |
acesrobertm | 0:a56239ae90c2 | 277 | { |
acesrobertm | 0:a56239ae90c2 | 278 | printf("Door Closed\n"); |
acesrobertm | 0:a56239ae90c2 | 279 | } |
acesrobertm | 0:a56239ae90c2 | 280 | else |
acesrobertm | 0:a56239ae90c2 | 281 | { |
acesrobertm | 0:a56239ae90c2 | 282 | printf("Door Open\n"); |
acesrobertm | 0:a56239ae90c2 | 283 | } |
acesrobertm | 0:a56239ae90c2 | 284 | } |
acesrobertm | 0:a56239ae90c2 | 285 | else if (!arg.compare("open")) |
acesrobertm | 0:a56239ae90c2 | 286 | { |
acesrobertm | 0:a56239ae90c2 | 287 | unlatchStrike(); |
acesrobertm | 0:a56239ae90c2 | 288 | printf("Unlatching Strike...\n"); |
acesrobertm | 0:a56239ae90c2 | 289 | } |
acesrobertm | 0:a56239ae90c2 | 290 | } |
acesrobertm | 0:a56239ae90c2 | 291 | |
acesrobertm | 0:a56239ae90c2 | 292 | return; |
acesrobertm | 0:a56239ae90c2 | 293 | } |
acesrobertm | 0:a56239ae90c2 | 294 | |
acesrobertm | 0:a56239ae90c2 | 295 | int main() |
acesrobertm | 0:a56239ae90c2 | 296 | { |
acesrobertm | 0:a56239ae90c2 | 297 | char mac_addr[MAC_STRING_LENGTH + 1] = ""; |
acesrobertm | 0:a56239ae90c2 | 298 | char ip_addr[IP_STRING_MAX_LENGTH + 1] = ""; |
acesrobertm | 0:a56239ae90c2 | 299 | _mac_addr = mac_addr; |
acesrobertm | 0:a56239ae90c2 | 300 | _ip_addr = ip_addr; |
acesrobertm | 0:a56239ae90c2 | 301 | |
acesrobertm | 0:a56239ae90c2 | 302 | usbUART.attach(&Rx_interrupt, Serial::RxIrq); |
acesrobertm | 0:a56239ae90c2 | 303 | |
acesrobertm | 0:a56239ae90c2 | 304 | // I/O Setup |
acesrobertm | 0:a56239ae90c2 | 305 | qx_redReaderLed = 1; |
acesrobertm | 0:a56239ae90c2 | 306 | qx_greenReaderLed = 1; |
acesrobertm | 0:a56239ae90c2 | 307 | qx_readerBuzzer = 1; |
acesrobertm | 0:a56239ae90c2 | 308 | |
acesrobertm | 0:a56239ae90c2 | 309 | ix_tamper.mode(PullUp); |
acesrobertm | 0:a56239ae90c2 | 310 | ix_tamper.fall(&handle_tamper); |
acesrobertm | 0:a56239ae90c2 | 311 | ix_doorLatched.mode(PullDown); |
acesrobertm | 0:a56239ae90c2 | 312 | ix_doorLatched.rise(&handle_latch); |
acesrobertm | 0:a56239ae90c2 | 313 | ix_usrBtn.fall(&usr_btn_pressed); |
acesrobertm | 0:a56239ae90c2 | 314 | |
acesrobertm | 0:a56239ae90c2 | 315 | printf("+------------------------------------------------+\n"); |
acesrobertm | 0:a56239ae90c2 | 316 | printf("| American Control & Engineering Service, Inc. |\n"); |
acesrobertm | 0:a56239ae90c2 | 317 | printf("| Door Access Controller |\n"); |
acesrobertm | 0:a56239ae90c2 | 318 | printf("+------------------------------------------------+\n"); |
acesrobertm | 0:a56239ae90c2 | 319 | |
acesrobertm | 0:a56239ae90c2 | 320 | // Print some art to the debug terminal, because America |
acesrobertm | 0:a56239ae90c2 | 321 | //printf("\n"); |
acesrobertm | 0:a56239ae90c2 | 322 | //asciiAces(); |
acesrobertm | 0:a56239ae90c2 | 323 | //asciiFlag(); |
acesrobertm | 0:a56239ae90c2 | 324 | |
acesrobertm | 0:a56239ae90c2 | 325 | TCPServer srv; |
acesrobertm | 0:a56239ae90c2 | 326 | TCPSocket clt_sock; |
acesrobertm | 0:a56239ae90c2 | 327 | SocketAddress clt_addr; |
acesrobertm | 0:a56239ae90c2 | 328 | |
acesrobertm | 0:a56239ae90c2 | 329 | srv.open(_eth); |
acesrobertm | 0:a56239ae90c2 | 330 | srv.bind(_eth->get_ip_address(), HTTP_SERVER_PORT); |
acesrobertm | 0:a56239ae90c2 | 331 | srv.listen(MAX_TCP_CONNECTIONS); |
acesrobertm | 0:a56239ae90c2 | 332 | |
acesrobertm | 0:a56239ae90c2 | 333 | printf("Beginning Main Loop\n"); |
acesrobertm | 0:a56239ae90c2 | 334 | |
acesrobertm | 0:a56239ae90c2 | 335 | while (true) { |
acesrobertm | 0:a56239ae90c2 | 336 | if (wgReader.isNew()) |
acesrobertm | 0:a56239ae90c2 | 337 | { |
acesrobertm | 0:a56239ae90c2 | 338 | uint16_t code = wgReader.card(); |
acesrobertm | 0:a56239ae90c2 | 339 | |
acesrobertm | 0:a56239ae90c2 | 340 | printf("RAW: %llu COUNT: %d CARD: %u\n", wgReader.bits(), wgReader.bitCount(), code); |
acesrobertm | 0:a56239ae90c2 | 341 | wgReader.old(); |
acesrobertm | 0:a56239ae90c2 | 342 | |
acesrobertm | 0:a56239ae90c2 | 343 | if (config_enableAccess && codeMem.FindAccessCode(code) >= 0) |
acesrobertm | 0:a56239ae90c2 | 344 | { |
acesrobertm | 0:a56239ae90c2 | 345 | unlatchStrike(); |
acesrobertm | 0:a56239ae90c2 | 346 | codeMem.WriteEvent(EVENT_KEYPAD_ACCESS_GRANTED, code); |
acesrobertm | 0:a56239ae90c2 | 347 | } |
acesrobertm | 0:a56239ae90c2 | 348 | } |
acesrobertm | 0:a56239ae90c2 | 349 | |
acesrobertm | 0:a56239ae90c2 | 350 | // Check for commands from the USB port. |
acesrobertm | 0:a56239ae90c2 | 351 | if (usb_rx_buffer[rx_idx - 1] == '\n') |
acesrobertm | 0:a56239ae90c2 | 352 | { |
acesrobertm | 0:a56239ae90c2 | 353 | usb_rx_buffer[rx_idx] = 0; |
acesrobertm | 0:a56239ae90c2 | 354 | string serial_command = usb_rx_buffer; |
acesrobertm | 0:a56239ae90c2 | 355 | |
acesrobertm | 0:a56239ae90c2 | 356 | submitSerialCommand(serial_command); |
acesrobertm | 0:a56239ae90c2 | 357 | |
acesrobertm | 0:a56239ae90c2 | 358 | rx_idx = 0; |
acesrobertm | 0:a56239ae90c2 | 359 | } |
acesrobertm | 0:a56239ae90c2 | 360 | |
acesrobertm | 0:a56239ae90c2 | 361 | configManager.update(); |
acesrobertm | 0:a56239ae90c2 | 362 | |
acesrobertm | 0:a56239ae90c2 | 363 | //srv.accept(&clt_sock, &clt_addr); |
acesrobertm | 0:a56239ae90c2 | 364 | //printf("accept %s:%d\n", clt_addr.get_ip_address(), clt_addr.get_port()); |
acesrobertm | 0:a56239ae90c2 | 365 | |
acesrobertm | 0:a56239ae90c2 | 366 | // Get browser request. |
acesrobertm | 0:a56239ae90c2 | 367 | //clt_sock.recv(httpReq, 100); |
acesrobertm | 0:a56239ae90c2 | 368 | //printf(httpReq); |
acesrobertm | 0:a56239ae90c2 | 369 | |
acesrobertm | 0:a56239ae90c2 | 370 | // Send status page to the browser. |
acesrobertm | 0:a56239ae90c2 | 371 | //sprintf(httpResponse, HTTP_RESPONSE, DATA_SERVER_PORT, button_presses); |
acesrobertm | 0:a56239ae90c2 | 372 | //clt_sock.send(httpResponse, strlen(httpResponse)); |
acesrobertm | 0:a56239ae90c2 | 373 | //clt_sock.close(); |
acesrobertm | 0:a56239ae90c2 | 374 | |
acesrobertm | 0:a56239ae90c2 | 375 | wait(0.01); |
acesrobertm | 0:a56239ae90c2 | 376 | } |
acesrobertm | 0:a56239ae90c2 | 377 | |
acesrobertm | 0:a56239ae90c2 | 378 | delete _eth; |
acesrobertm | 0:a56239ae90c2 | 379 | |
acesrobertm | 0:a56239ae90c2 | 380 | return 0; |
acesrobertm | 0:a56239ae90c2 | 381 | } |