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
Diff: DHCPOptions.cpp
- Revision:
- 0:a56239ae90c2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DHCPOptions.cpp Mon Sep 25 19:02:40 2017 +0000 @@ -0,0 +1,142 @@ + +#include "DHCPOptions.h" + +int DHCPOptions::getOptions(char* tftp_server, const char* mac_address, const uint32_t timeout) +{ + char mac_bin[DHCP_CHADDR_SIZE + 1] = {0}; // Initialize the hardware address array to zeros. + int bind_result; + DHCPPacket pkt, rec_pkt; + + // Generate binary version of the MAC string. + macStrToBin(mac_bin, mac_address); + + SocketAddress dhcp_addr(DHCP_BROADCAST_ADDRESS, DHCP_SERVER_PORT); + m_sock.open(m_eth); + m_sock.set_timeout(timeout); + bind_result = m_sock.bind(DHCP_CLIENT_PORT); + + if (bind_result < 0) + { + printf("DHCP Port Binding Failed: %d\n", bind_result); + return -1; // DHCP port bind failed. + } + + // Construct a DHCP DISCOVER packet + pkt.op = DHCP_OP_REQUEST; + pkt.htype = DHCP_HTYPE; + pkt.hlen = DHCP_HLEN; + pkt.hops = DHCP_HOPS; + pkt.xid = htonl(rand()); + pkt.secs = htons(DHCP_SECS); + pkt.flags = htons(DHCP_FLAGS); + pkt.ciaddr = htonl(DHCP_CIADDR); + pkt.yiaddr = htonl(DHCP_YIADDR); + pkt.siaddr = htonl(DHCP_SIADDR); + pkt.giaddr = htonl(DHCP_GIADDR); + // MAC address with padding - 16 bytes total + memcpy(pkt.chaddr, mac_bin, DHCP_CHADDR_SIZE); + memset(pkt.sname, 0, DHCP_SNAME_SIZE); + memset(pkt.file, 0, DHCP_FILE_SIZE); + // Options List + pkt.magic = htonl(DHCP_MAGIC_COOKIE); + pkt.op_mtype = 53; + pkt.mtype_len = 1; + pkt.mtype = 1; + char discover_options[] = {DHCP_PREQLIST, 1, DHCP_OPTION_TFTPSERVER, DHCP_OPTION_STOP}; + memcpy(pkt.options, discover_options, sizeof(discover_options)); + + // Send read request + int bytes_sent = m_sock.sendto(dhcp_addr, (char*)&pkt, sizeof(DHCPPacket)); + if (bytes_sent < 0) + { + printf("DHCP Discover Failed: %d\n", bytes_sent); + return -2; // DHCP Discover send failed. + } + else + { + //printf("Sent: %d\n", bytes_sent); + } + + // Get data packet from the DHCP server + int bytes_received = m_sock.recvfrom(&dhcp_addr, (char*)&rec_pkt, sizeof(DHCPPacket)); + if (bytes_received < 0) + { + printf("DHCP Offer Failed: %d\n", bytes_received); + return -3; // UDP packet recevie failed. + } + else + { + //printf("Received: %d\n", bytes_received); + } + + if (decodeOptions(tftp_server, rec_pkt) < 0) + { + printf("Failed to find the TFTP server option.\n"); + return -4; // Failed to find the TFTP server name option from the DHCP offer response packet. + } + + m_sock.close(); + return 0; +} + +int DHCPOptions::decodeOptions(char* tftp_server, DHCPPacket& pkt) +{ + char* dhcp_options = pkt.options; + int optionIndex = 0; + int optionLength = 0; + + while (optionIndex < DHCP_OPTIONS_SIZE && dhcp_options[optionIndex] != DHCP_OPTION_STOP) + { + // Get the length of the current DHCP option field. + optionLength = dhcp_options[optionIndex + 1]; + + // Check for the TFTP server option code. + if (dhcp_options[optionIndex] == DHCP_OPTION_TFTPSERVER) + { + // Copy the TFTP server string to the output string. + memcpy(tftp_server, dhcp_options + optionIndex + 2, optionLength); + return 0; + } + + // Move to the next option. + optionIndex += 2 + optionLength; + } + + return -1; // Failed to find the DHCP option. +} + +int DHCPOptions::macStrToBin(char* macBin, const char* macStr) +{ + if (strlen(macStr) != MAC_STRING_LENGTH) + { + return -1; // Invalid MAC string + } + else + { + for (int byteIndex = 0; byteIndex < 6; byteIndex++) + { + macBin[byteIndex] = (charToNum(macStr[byteIndex * 3]) * 16) + charToNum(macStr[(byteIndex * 3) + 1]); + } + } + + return 0; +} + +unsigned char DHCPOptions::charToNum(const char input) +{ + if(input >= '0' && input <= '9') + { + return input - '0'; + } + if(input >= 'A' && input <= 'F') + { + return input - 'A' + 10; + } + if(input >= 'a' && input <= 'f') + { + return input - 'a' + 10; + } + + return 0; +} + \ No newline at end of file