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

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?

UserRevisionLine numberNew contents of line
acesrobertm 0:a56239ae90c2 1
acesrobertm 0:a56239ae90c2 2 #include "DHCPOptions.h"
acesrobertm 0:a56239ae90c2 3
acesrobertm 0:a56239ae90c2 4 int DHCPOptions::getOptions(char* tftp_server, const char* mac_address, const uint32_t timeout)
acesrobertm 0:a56239ae90c2 5 {
acesrobertm 0:a56239ae90c2 6 char mac_bin[DHCP_CHADDR_SIZE + 1] = {0}; // Initialize the hardware address array to zeros.
acesrobertm 0:a56239ae90c2 7 int bind_result;
acesrobertm 0:a56239ae90c2 8 DHCPPacket pkt, rec_pkt;
acesrobertm 0:a56239ae90c2 9
acesrobertm 0:a56239ae90c2 10 // Generate binary version of the MAC string.
acesrobertm 0:a56239ae90c2 11 macStrToBin(mac_bin, mac_address);
acesrobertm 0:a56239ae90c2 12
acesrobertm 0:a56239ae90c2 13 SocketAddress dhcp_addr(DHCP_BROADCAST_ADDRESS, DHCP_SERVER_PORT);
acesrobertm 0:a56239ae90c2 14 m_sock.open(m_eth);
acesrobertm 0:a56239ae90c2 15 m_sock.set_timeout(timeout);
acesrobertm 0:a56239ae90c2 16 bind_result = m_sock.bind(DHCP_CLIENT_PORT);
acesrobertm 0:a56239ae90c2 17
acesrobertm 0:a56239ae90c2 18 if (bind_result < 0)
acesrobertm 0:a56239ae90c2 19 {
acesrobertm 0:a56239ae90c2 20 printf("DHCP Port Binding Failed: %d\n", bind_result);
acesrobertm 0:a56239ae90c2 21 return -1; // DHCP port bind failed.
acesrobertm 0:a56239ae90c2 22 }
acesrobertm 0:a56239ae90c2 23
acesrobertm 0:a56239ae90c2 24 // Construct a DHCP DISCOVER packet
acesrobertm 0:a56239ae90c2 25 pkt.op = DHCP_OP_REQUEST;
acesrobertm 0:a56239ae90c2 26 pkt.htype = DHCP_HTYPE;
acesrobertm 0:a56239ae90c2 27 pkt.hlen = DHCP_HLEN;
acesrobertm 0:a56239ae90c2 28 pkt.hops = DHCP_HOPS;
acesrobertm 0:a56239ae90c2 29 pkt.xid = htonl(rand());
acesrobertm 0:a56239ae90c2 30 pkt.secs = htons(DHCP_SECS);
acesrobertm 0:a56239ae90c2 31 pkt.flags = htons(DHCP_FLAGS);
acesrobertm 0:a56239ae90c2 32 pkt.ciaddr = htonl(DHCP_CIADDR);
acesrobertm 0:a56239ae90c2 33 pkt.yiaddr = htonl(DHCP_YIADDR);
acesrobertm 0:a56239ae90c2 34 pkt.siaddr = htonl(DHCP_SIADDR);
acesrobertm 0:a56239ae90c2 35 pkt.giaddr = htonl(DHCP_GIADDR);
acesrobertm 0:a56239ae90c2 36 // MAC address with padding - 16 bytes total
acesrobertm 0:a56239ae90c2 37 memcpy(pkt.chaddr, mac_bin, DHCP_CHADDR_SIZE);
acesrobertm 0:a56239ae90c2 38 memset(pkt.sname, 0, DHCP_SNAME_SIZE);
acesrobertm 0:a56239ae90c2 39 memset(pkt.file, 0, DHCP_FILE_SIZE);
acesrobertm 0:a56239ae90c2 40 // Options List
acesrobertm 0:a56239ae90c2 41 pkt.magic = htonl(DHCP_MAGIC_COOKIE);
acesrobertm 0:a56239ae90c2 42 pkt.op_mtype = 53;
acesrobertm 0:a56239ae90c2 43 pkt.mtype_len = 1;
acesrobertm 0:a56239ae90c2 44 pkt.mtype = 1;
acesrobertm 0:a56239ae90c2 45 char discover_options[] = {DHCP_PREQLIST, 1, DHCP_OPTION_TFTPSERVER, DHCP_OPTION_STOP};
acesrobertm 0:a56239ae90c2 46 memcpy(pkt.options, discover_options, sizeof(discover_options));
acesrobertm 0:a56239ae90c2 47
acesrobertm 0:a56239ae90c2 48 // Send read request
acesrobertm 0:a56239ae90c2 49 int bytes_sent = m_sock.sendto(dhcp_addr, (char*)&pkt, sizeof(DHCPPacket));
acesrobertm 0:a56239ae90c2 50 if (bytes_sent < 0)
acesrobertm 0:a56239ae90c2 51 {
acesrobertm 0:a56239ae90c2 52 printf("DHCP Discover Failed: %d\n", bytes_sent);
acesrobertm 0:a56239ae90c2 53 return -2; // DHCP Discover send failed.
acesrobertm 0:a56239ae90c2 54 }
acesrobertm 0:a56239ae90c2 55 else
acesrobertm 0:a56239ae90c2 56 {
acesrobertm 0:a56239ae90c2 57 //printf("Sent: %d\n", bytes_sent);
acesrobertm 0:a56239ae90c2 58 }
acesrobertm 0:a56239ae90c2 59
acesrobertm 0:a56239ae90c2 60 // Get data packet from the DHCP server
acesrobertm 0:a56239ae90c2 61 int bytes_received = m_sock.recvfrom(&dhcp_addr, (char*)&rec_pkt, sizeof(DHCPPacket));
acesrobertm 0:a56239ae90c2 62 if (bytes_received < 0)
acesrobertm 0:a56239ae90c2 63 {
acesrobertm 0:a56239ae90c2 64 printf("DHCP Offer Failed: %d\n", bytes_received);
acesrobertm 0:a56239ae90c2 65 return -3; // UDP packet recevie failed.
acesrobertm 0:a56239ae90c2 66 }
acesrobertm 0:a56239ae90c2 67 else
acesrobertm 0:a56239ae90c2 68 {
acesrobertm 0:a56239ae90c2 69 //printf("Received: %d\n", bytes_received);
acesrobertm 0:a56239ae90c2 70 }
acesrobertm 0:a56239ae90c2 71
acesrobertm 0:a56239ae90c2 72 if (decodeOptions(tftp_server, rec_pkt) < 0)
acesrobertm 0:a56239ae90c2 73 {
acesrobertm 0:a56239ae90c2 74 printf("Failed to find the TFTP server option.\n");
acesrobertm 0:a56239ae90c2 75 return -4; // Failed to find the TFTP server name option from the DHCP offer response packet.
acesrobertm 0:a56239ae90c2 76 }
acesrobertm 0:a56239ae90c2 77
acesrobertm 0:a56239ae90c2 78 m_sock.close();
acesrobertm 0:a56239ae90c2 79 return 0;
acesrobertm 0:a56239ae90c2 80 }
acesrobertm 0:a56239ae90c2 81
acesrobertm 0:a56239ae90c2 82 int DHCPOptions::decodeOptions(char* tftp_server, DHCPPacket& pkt)
acesrobertm 0:a56239ae90c2 83 {
acesrobertm 0:a56239ae90c2 84 char* dhcp_options = pkt.options;
acesrobertm 0:a56239ae90c2 85 int optionIndex = 0;
acesrobertm 0:a56239ae90c2 86 int optionLength = 0;
acesrobertm 0:a56239ae90c2 87
acesrobertm 0:a56239ae90c2 88 while (optionIndex < DHCP_OPTIONS_SIZE && dhcp_options[optionIndex] != DHCP_OPTION_STOP)
acesrobertm 0:a56239ae90c2 89 {
acesrobertm 0:a56239ae90c2 90 // Get the length of the current DHCP option field.
acesrobertm 0:a56239ae90c2 91 optionLength = dhcp_options[optionIndex + 1];
acesrobertm 0:a56239ae90c2 92
acesrobertm 0:a56239ae90c2 93 // Check for the TFTP server option code.
acesrobertm 0:a56239ae90c2 94 if (dhcp_options[optionIndex] == DHCP_OPTION_TFTPSERVER)
acesrobertm 0:a56239ae90c2 95 {
acesrobertm 0:a56239ae90c2 96 // Copy the TFTP server string to the output string.
acesrobertm 0:a56239ae90c2 97 memcpy(tftp_server, dhcp_options + optionIndex + 2, optionLength);
acesrobertm 0:a56239ae90c2 98 return 0;
acesrobertm 0:a56239ae90c2 99 }
acesrobertm 0:a56239ae90c2 100
acesrobertm 0:a56239ae90c2 101 // Move to the next option.
acesrobertm 0:a56239ae90c2 102 optionIndex += 2 + optionLength;
acesrobertm 0:a56239ae90c2 103 }
acesrobertm 0:a56239ae90c2 104
acesrobertm 0:a56239ae90c2 105 return -1; // Failed to find the DHCP option.
acesrobertm 0:a56239ae90c2 106 }
acesrobertm 0:a56239ae90c2 107
acesrobertm 0:a56239ae90c2 108 int DHCPOptions::macStrToBin(char* macBin, const char* macStr)
acesrobertm 0:a56239ae90c2 109 {
acesrobertm 0:a56239ae90c2 110 if (strlen(macStr) != MAC_STRING_LENGTH)
acesrobertm 0:a56239ae90c2 111 {
acesrobertm 0:a56239ae90c2 112 return -1; // Invalid MAC string
acesrobertm 0:a56239ae90c2 113 }
acesrobertm 0:a56239ae90c2 114 else
acesrobertm 0:a56239ae90c2 115 {
acesrobertm 0:a56239ae90c2 116 for (int byteIndex = 0; byteIndex < 6; byteIndex++)
acesrobertm 0:a56239ae90c2 117 {
acesrobertm 0:a56239ae90c2 118 macBin[byteIndex] = (charToNum(macStr[byteIndex * 3]) * 16) + charToNum(macStr[(byteIndex * 3) + 1]);
acesrobertm 0:a56239ae90c2 119 }
acesrobertm 0:a56239ae90c2 120 }
acesrobertm 0:a56239ae90c2 121
acesrobertm 0:a56239ae90c2 122 return 0;
acesrobertm 0:a56239ae90c2 123 }
acesrobertm 0:a56239ae90c2 124
acesrobertm 0:a56239ae90c2 125 unsigned char DHCPOptions::charToNum(const char input)
acesrobertm 0:a56239ae90c2 126 {
acesrobertm 0:a56239ae90c2 127 if(input >= '0' && input <= '9')
acesrobertm 0:a56239ae90c2 128 {
acesrobertm 0:a56239ae90c2 129 return input - '0';
acesrobertm 0:a56239ae90c2 130 }
acesrobertm 0:a56239ae90c2 131 if(input >= 'A' && input <= 'F')
acesrobertm 0:a56239ae90c2 132 {
acesrobertm 0:a56239ae90c2 133 return input - 'A' + 10;
acesrobertm 0:a56239ae90c2 134 }
acesrobertm 0:a56239ae90c2 135 if(input >= 'a' && input <= 'f')
acesrobertm 0:a56239ae90c2 136 {
acesrobertm 0:a56239ae90c2 137 return input - 'a' + 10;
acesrobertm 0:a56239ae90c2 138 }
acesrobertm 0:a56239ae90c2 139
acesrobertm 0:a56239ae90c2 140 return 0;
acesrobertm 0:a56239ae90c2 141 }
acesrobertm 0:a56239ae90c2 142