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 "TFTPClient.h"
acesrobertm 0:a56239ae90c2 3
acesrobertm 0:a56239ae90c2 4 bool TFTPClient::readFile(char* data, const char* host, const char* filename, const uint16_t port, const uint32_t timeout)
acesrobertm 0:a56239ae90c2 5 {
acesrobertm 0:a56239ae90c2 6 printf("TFTP read file\n");
acesrobertm 0:a56239ae90c2 7 m_data = data;
acesrobertm 0:a56239ae90c2 8
acesrobertm 0:a56239ae90c2 9 if (m_tftp_addr)
acesrobertm 0:a56239ae90c2 10 {
acesrobertm 0:a56239ae90c2 11 delete m_tftp_addr;
acesrobertm 0:a56239ae90c2 12 m_tftp_addr = NULL;
acesrobertm 0:a56239ae90c2 13 }
acesrobertm 0:a56239ae90c2 14 m_tftp_addr = new SocketAddress(host, port);
acesrobertm 0:a56239ae90c2 15
acesrobertm 0:a56239ae90c2 16 printf("IP: %d\n", m_eth);
acesrobertm 0:a56239ae90c2 17
acesrobertm 0:a56239ae90c2 18 m_sock.open(m_eth);
acesrobertm 0:a56239ae90c2 19 printf("TFTP before blocking\n");
acesrobertm 0:a56239ae90c2 20 m_sock.set_blocking(false);
acesrobertm 0:a56239ae90c2 21 printf("TFTP before bind\n");
acesrobertm 0:a56239ae90c2 22 m_sock.bind(0);
acesrobertm 0:a56239ae90c2 23
acesrobertm 0:a56239ae90c2 24 printf("TFTP port bound\n");
acesrobertm 0:a56239ae90c2 25
acesrobertm 0:a56239ae90c2 26 char chunk[TFTP_MAX_PACKET_SIZE];
acesrobertm 0:a56239ae90c2 27 uint16_t tftp_opcode = htons(RRQ);
acesrobertm 0:a56239ae90c2 28 char tftp_mode[] = "octet";
acesrobertm 0:a56239ae90c2 29
acesrobertm 0:a56239ae90c2 30 // Construct read request packet
acesrobertm 0:a56239ae90c2 31 memcpy(chunk, &tftp_opcode, 2);
acesrobertm 0:a56239ae90c2 32 memcpy(chunk + 2, filename, strlen(filename) + 1);
acesrobertm 0:a56239ae90c2 33 memcpy(chunk + 2 + (strlen(filename) + 1), tftp_mode, strlen(tftp_mode) + 1);
acesrobertm 0:a56239ae90c2 34 int packet_size = 2 + strlen(filename) + 1 + strlen(tftp_mode) + 1;
acesrobertm 0:a56239ae90c2 35
acesrobertm 0:a56239ae90c2 36 // Debug output request data.
acesrobertm 0:a56239ae90c2 37 printf("TFTP RRQ packet: ");
acesrobertm 0:a56239ae90c2 38 fwrite(chunk, 1, packet_size, stdout);
acesrobertm 0:a56239ae90c2 39 printf("\n");
acesrobertm 0:a56239ae90c2 40
acesrobertm 0:a56239ae90c2 41 // Send read request
acesrobertm 0:a56239ae90c2 42 m_bytes_received = 0;
acesrobertm 0:a56239ae90c2 43 m_block_number = 1;
acesrobertm 0:a56239ae90c2 44 m_bytes_sent = m_sock.sendto(*m_tftp_addr, chunk, packet_size);
acesrobertm 0:a56239ae90c2 45
acesrobertm 0:a56239ae90c2 46 if (m_bytes_sent == packet_size)
acesrobertm 0:a56239ae90c2 47 {
acesrobertm 0:a56239ae90c2 48 m_download_in_progress = true;
acesrobertm 0:a56239ae90c2 49 }
acesrobertm 0:a56239ae90c2 50 else
acesrobertm 0:a56239ae90c2 51 {
acesrobertm 0:a56239ae90c2 52 printf("TFTP read request failed. %d\n", m_bytes_sent);
acesrobertm 0:a56239ae90c2 53 }
acesrobertm 0:a56239ae90c2 54
acesrobertm 0:a56239ae90c2 55 m_next_data_byte_index = 0;
acesrobertm 0:a56239ae90c2 56
acesrobertm 0:a56239ae90c2 57 return m_download_in_progress;
acesrobertm 0:a56239ae90c2 58 }
acesrobertm 0:a56239ae90c2 59
acesrobertm 0:a56239ae90c2 60 int TFTPClient::update()
acesrobertm 0:a56239ae90c2 61 {
acesrobertm 0:a56239ae90c2 62 int return_value = -1;
acesrobertm 0:a56239ae90c2 63 char chunk[TFTP_MAX_PACKET_SIZE];
acesrobertm 0:a56239ae90c2 64
acesrobertm 0:a56239ae90c2 65 if (m_download_in_progress)
acesrobertm 0:a56239ae90c2 66 {
acesrobertm 0:a56239ae90c2 67 // Get data packet from the TFTP server
acesrobertm 0:a56239ae90c2 68 m_bytes_received = m_sock.recvfrom(m_tftp_addr, chunk, TFTP_MAX_PACKET_SIZE);
acesrobertm 0:a56239ae90c2 69 if (m_bytes_received <= 0)
acesrobertm 0:a56239ae90c2 70 {
acesrobertm 0:a56239ae90c2 71 return_value = m_bytes_received; // UDP packet recevie failed.
acesrobertm 0:a56239ae90c2 72 }
acesrobertm 0:a56239ae90c2 73 else
acesrobertm 0:a56239ae90c2 74 {
acesrobertm 0:a56239ae90c2 75 // Convert the opcode and block back into host endian format.
acesrobertm 0:a56239ae90c2 76 uint16_t temp_opcode, temp_block;
acesrobertm 0:a56239ae90c2 77 memcpy(&temp_opcode, chunk, 2);
acesrobertm 0:a56239ae90c2 78 memcpy(&temp_block, chunk + 2, 2);
acesrobertm 0:a56239ae90c2 79 temp_opcode = ntohs(temp_opcode);
acesrobertm 0:a56239ae90c2 80 temp_block = ntohs(temp_block);
acesrobertm 0:a56239ae90c2 81
acesrobertm 0:a56239ae90c2 82 if (temp_opcode == ERR)
acesrobertm 0:a56239ae90c2 83 {
acesrobertm 0:a56239ae90c2 84 printf(" TFTP Error: %u, %s\n", temp_block, chunk + 4);
acesrobertm 0:a56239ae90c2 85 return_value = -2; // Error response from server.
acesrobertm 0:a56239ae90c2 86 }
acesrobertm 0:a56239ae90c2 87 else if (temp_opcode == DATA)
acesrobertm 0:a56239ae90c2 88 {
acesrobertm 0:a56239ae90c2 89 if (temp_block == m_block_number)
acesrobertm 0:a56239ae90c2 90 {
acesrobertm 0:a56239ae90c2 91 int chunk_size = m_bytes_received - 4;
acesrobertm 0:a56239ae90c2 92 // Debug output for incoming chunks of data.
acesrobertm 0:a56239ae90c2 93 //printf(" TFTP Chunk Received: %u\n", chunk_size);
acesrobertm 0:a56239ae90c2 94 //fwrite(chunk, 1, m_bytes_received, stdout);
acesrobertm 0:a56239ae90c2 95
acesrobertm 0:a56239ae90c2 96 // Strip the TFTP info from the beginning of the data buffer.
acesrobertm 0:a56239ae90c2 97 memcpy(m_data + m_next_data_byte_index, chunk + 4, chunk_size);
acesrobertm 0:a56239ae90c2 98 m_next_data_byte_index += chunk_size;
acesrobertm 0:a56239ae90c2 99 // Terminate the data string.
acesrobertm 0:a56239ae90c2 100 m_data[m_next_data_byte_index] = 0;
acesrobertm 0:a56239ae90c2 101
acesrobertm 0:a56239ae90c2 102 // Send an ACK for the current data block
acesrobertm 0:a56239ae90c2 103 uint16_t tftp_opcode = htons(ACK);
acesrobertm 0:a56239ae90c2 104 temp_block = htons(temp_block);
acesrobertm 0:a56239ae90c2 105 memcpy(chunk, &tftp_opcode, 2);
acesrobertm 0:a56239ae90c2 106 memcpy(chunk + 2, &temp_block, 2);
acesrobertm 0:a56239ae90c2 107 int m_bytes_sent = m_sock.sendto(*m_tftp_addr, chunk, 4); // Send
acesrobertm 0:a56239ae90c2 108
acesrobertm 0:a56239ae90c2 109 m_block_number++;
acesrobertm 0:a56239ae90c2 110 }
acesrobertm 0:a56239ae90c2 111 else
acesrobertm 0:a56239ae90c2 112 {
acesrobertm 0:a56239ae90c2 113 return_value = -3; // Incorrect data block number.
acesrobertm 0:a56239ae90c2 114 m_download_in_progress = false;
acesrobertm 0:a56239ae90c2 115 }
acesrobertm 0:a56239ae90c2 116 }
acesrobertm 0:a56239ae90c2 117 else
acesrobertm 0:a56239ae90c2 118 {
acesrobertm 0:a56239ae90c2 119 return_value = -4; // Wrong opcode
acesrobertm 0:a56239ae90c2 120 m_download_in_progress = false;
acesrobertm 0:a56239ae90c2 121 }
acesrobertm 0:a56239ae90c2 122
acesrobertm 0:a56239ae90c2 123 if (m_bytes_received != TFTP_MAX_PACKET_SIZE)
acesrobertm 0:a56239ae90c2 124 {
acesrobertm 0:a56239ae90c2 125 m_download_in_progress = false;
acesrobertm 0:a56239ae90c2 126
acesrobertm 0:a56239ae90c2 127 if (m_bytes_received > 0)
acesrobertm 0:a56239ae90c2 128 {
acesrobertm 0:a56239ae90c2 129 // Finished download.
acesrobertm 0:a56239ae90c2 130 return_value = 1;
acesrobertm 0:a56239ae90c2 131 }
acesrobertm 0:a56239ae90c2 132 }
acesrobertm 0:a56239ae90c2 133 }
acesrobertm 0:a56239ae90c2 134 }
acesrobertm 0:a56239ae90c2 135
acesrobertm 0:a56239ae90c2 136 if (!m_download_in_progress)
acesrobertm 0:a56239ae90c2 137 {
acesrobertm 0:a56239ae90c2 138 m_sock.close();
acesrobertm 0:a56239ae90c2 139 }
acesrobertm 0:a56239ae90c2 140
acesrobertm 0:a56239ae90c2 141 return return_value;
acesrobertm 0:a56239ae90c2 142 }
acesrobertm 0:a56239ae90c2 143