Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Wed Mar 20 11:20:44 2019 +0000
Revision:
133:a37eb35a03f1
Parent:
132:db2174b36a6d
Child:
160:6a1d1d368f80
Updated clock library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 115:5c003909bcf3 1 #include <stdint.h>
andrewboyson 115:5c003909bcf3 2 #include <stdbool.h>
andrewboyson 115:5c003909bcf3 3
andrewboyson 115:5c003909bcf3 4 #include "log.h"
andrewboyson 115:5c003909bcf3 5 #include "net.h"
andrewboyson 115:5c003909bcf3 6 #include "action.h"
andrewboyson 115:5c003909bcf3 7 #include "udp.h"
andrewboyson 115:5c003909bcf3 8 #include "dns.h"
andrewboyson 115:5c003909bcf3 9 #include "tftp.h"
andrewboyson 115:5c003909bcf3 10 #include "mstimer.h"
andrewboyson 116:60521b29e4c9 11 #include "resolve.h"
andrewboyson 128:79052cb4a41c 12 #include "dnslabel.h"
andrewboyson 115:5c003909bcf3 13
andrewboyson 115:5c003909bcf3 14 bool TftpTrace = false;
andrewboyson 115:5c003909bcf3 15
andrewboyson 116:60521b29e4c9 16 #define WRITE_TIMEOUT_MS 6000 //Make this longer than the resolve time which is up to 3 seconds
andrewboyson 115:5c003909bcf3 17
andrewboyson 115:5c003909bcf3 18 #define TFTP_RRQ 1
andrewboyson 115:5c003909bcf3 19 #define TFTP_WRQ 2
andrewboyson 115:5c003909bcf3 20 #define TFTP_DATA 3
andrewboyson 115:5c003909bcf3 21 #define TFTP_ACK 4
andrewboyson 115:5c003909bcf3 22 #define TFTP_ERROR 5
andrewboyson 115:5c003909bcf3 23
andrewboyson 115:5c003909bcf3 24 static void logOp(char* p)
andrewboyson 115:5c003909bcf3 25 {
andrewboyson 115:5c003909bcf3 26 if (*p)
andrewboyson 115:5c003909bcf3 27 {
andrewboyson 115:5c003909bcf3 28 LogF("Unknown op code %02x%02x", *p, *++p);
andrewboyson 115:5c003909bcf3 29 return;
andrewboyson 115:5c003909bcf3 30 }
andrewboyson 115:5c003909bcf3 31 p++;
andrewboyson 115:5c003909bcf3 32 switch (*p)
andrewboyson 115:5c003909bcf3 33 {
andrewboyson 115:5c003909bcf3 34 case TFTP_RRQ: Log ("RRQ") ; break;
andrewboyson 115:5c003909bcf3 35 case TFTP_WRQ: Log ("WRQ") ; break;
andrewboyson 115:5c003909bcf3 36 case TFTP_DATA: Log ("DATA") ; break;
andrewboyson 115:5c003909bcf3 37 case TFTP_ACK: Log ("ACK") ; break;
andrewboyson 115:5c003909bcf3 38 case TFTP_ERROR: Log ("ERROR") ; break;
andrewboyson 115:5c003909bcf3 39 default: LogF("Unknown op code 00%02x", *p); break;
andrewboyson 115:5c003909bcf3 40 }
andrewboyson 115:5c003909bcf3 41 }
andrewboyson 115:5c003909bcf3 42
andrewboyson 115:5c003909bcf3 43 static void logError(char* p)
andrewboyson 115:5c003909bcf3 44 {
andrewboyson 115:5c003909bcf3 45 if (*p)
andrewboyson 115:5c003909bcf3 46 {
andrewboyson 115:5c003909bcf3 47 LogF("Unknown error code %02x%02x", *p, *++p);
andrewboyson 115:5c003909bcf3 48 return;
andrewboyson 115:5c003909bcf3 49 }
andrewboyson 115:5c003909bcf3 50 p++;
andrewboyson 115:5c003909bcf3 51 switch (*p)
andrewboyson 115:5c003909bcf3 52 {
andrewboyson 115:5c003909bcf3 53 case 0: Log ("Not defined, see error message." ); break;
andrewboyson 115:5c003909bcf3 54 case 1: Log ("File not found." ); break;
andrewboyson 115:5c003909bcf3 55 case 2: Log ("Access violation." ); break;
andrewboyson 115:5c003909bcf3 56 case 3: Log ("Disk full or allocation exceeded."); break;
andrewboyson 115:5c003909bcf3 57 case 4: Log ("Illegal TFTP operation." ); break;
andrewboyson 115:5c003909bcf3 58 case 5: Log ("Unknown transfer ID." ); break;
andrewboyson 115:5c003909bcf3 59 case 6: Log ("File already exists." ); break;
andrewboyson 115:5c003909bcf3 60 case 7: Log ("No such user." ); break;
andrewboyson 115:5c003909bcf3 61 default: LogF("Unknown error code 00%02x", *p ); break;
andrewboyson 115:5c003909bcf3 62 }
andrewboyson 115:5c003909bcf3 63 }
andrewboyson 115:5c003909bcf3 64 bool TftpSendRequestsViaIp4 = false;
andrewboyson 115:5c003909bcf3 65 uint32_t TftpServerIp4;
andrewboyson 115:5c003909bcf3 66 char TftpServerIp6[16];
andrewboyson 115:5c003909bcf3 67 int TftpWriteStatus = TFTP_WRITE_STATUS_NONE;
andrewboyson 115:5c003909bcf3 68 char TftpServerName[DNS_MAX_LABEL_LENGTH+1];
andrewboyson 115:5c003909bcf3 69 char TftpFileName [DNS_MAX_LABEL_LENGTH+1];
andrewboyson 115:5c003909bcf3 70
andrewboyson 115:5c003909bcf3 71 int (*TftpGetNextByteFunction)();
andrewboyson 115:5c003909bcf3 72
andrewboyson 115:5c003909bcf3 73 static void logHeader(int size, char* p)
andrewboyson 115:5c003909bcf3 74 {
andrewboyson 115:5c003909bcf3 75 if (NetTraceVerbose)
andrewboyson 115:5c003909bcf3 76 {
andrewboyson 115:5c003909bcf3 77 Log ("TFTP header\r\n");
andrewboyson 115:5c003909bcf3 78 Log (" Op code "); logOp(p); Log("\r\n");
andrewboyson 115:5c003909bcf3 79 Log (" Size "); LogF("%d", size); Log("\r\n");
andrewboyson 115:5c003909bcf3 80 }
andrewboyson 115:5c003909bcf3 81 else
andrewboyson 115:5c003909bcf3 82 {
andrewboyson 115:5c003909bcf3 83 Log ("TFTP header");
andrewboyson 115:5c003909bcf3 84 Log (": Op "); logOp(p);
andrewboyson 115:5c003909bcf3 85 LogF(", %d bytes", size);
andrewboyson 115:5c003909bcf3 86 Log ("\r\n");
andrewboyson 115:5c003909bcf3 87 }
andrewboyson 115:5c003909bcf3 88 }
andrewboyson 115:5c003909bcf3 89 static int sendBlock(uint16_t block, int* pSize, char* pHeader)
andrewboyson 115:5c003909bcf3 90 {
andrewboyson 115:5c003909bcf3 91 /*2 bytes 2 bytes n bytes
andrewboyson 115:5c003909bcf3 92 ----------------------------------
andrewboyson 115:5c003909bcf3 93 | Opcode | Block # | Data |
andrewboyson 115:5c003909bcf3 94 ---------------------------------- */
andrewboyson 115:5c003909bcf3 95 char* p = pHeader;
andrewboyson 115:5c003909bcf3 96 *p++ = 0;
andrewboyson 115:5c003909bcf3 97 *p++ = TFTP_DATA;
andrewboyson 115:5c003909bcf3 98 *p++ = block >> 8;
andrewboyson 115:5c003909bcf3 99 *p++ = block & 0xFF;
andrewboyson 115:5c003909bcf3 100
andrewboyson 115:5c003909bcf3 101 int len = 0;
andrewboyson 115:5c003909bcf3 102 while (len < 512)
andrewboyson 115:5c003909bcf3 103 {
andrewboyson 115:5c003909bcf3 104 int c = TftpGetNextByteFunction();
andrewboyson 115:5c003909bcf3 105 if (c == -1) break;
andrewboyson 115:5c003909bcf3 106 *p++ = c;
andrewboyson 115:5c003909bcf3 107 len++;
andrewboyson 115:5c003909bcf3 108 }
andrewboyson 115:5c003909bcf3 109 if (len < 512) TftpWriteStatus = TFTP_WRITE_STATUS_NONE;
andrewboyson 115:5c003909bcf3 110 *pSize = p - pHeader;
andrewboyson 115:5c003909bcf3 111 return UNICAST_TFTP;
andrewboyson 115:5c003909bcf3 112 }
andrewboyson 115:5c003909bcf3 113 static void handleError(char* p)
andrewboyson 115:5c003909bcf3 114 {
andrewboyson 115:5c003909bcf3 115 /*2 bytes 2 bytes string 1 byte
andrewboyson 115:5c003909bcf3 116 -----------------------------------------
andrewboyson 115:5c003909bcf3 117 | ERROR | ErrorCode | ErrMsg | 0 |
andrewboyson 115:5c003909bcf3 118 ----------------------------------------- */
andrewboyson 115:5c003909bcf3 119 p += 2; //Skip the op code which we already know
andrewboyson 115:5c003909bcf3 120 if (NetTraceNewLine) Log("\r\n");
andrewboyson 115:5c003909bcf3 121 LogTime("TFTP error - ");
andrewboyson 115:5c003909bcf3 122 logError(p); p += 2;
andrewboyson 115:5c003909bcf3 123 Log(p);
andrewboyson 115:5c003909bcf3 124 Log("\r\n");
andrewboyson 115:5c003909bcf3 125 TftpWriteStatus = TFTP_WRITE_STATUS_NONE;
andrewboyson 115:5c003909bcf3 126 }
andrewboyson 115:5c003909bcf3 127 static int handleAck(char* pHeaderRx, int* pSizeTx, char* pHeaderTx)
andrewboyson 115:5c003909bcf3 128 {
andrewboyson 115:5c003909bcf3 129 /* 2 bytes 2 bytes
andrewboyson 115:5c003909bcf3 130 -----------------------
andrewboyson 115:5c003909bcf3 131 | ACK | Block # |
andrewboyson 115:5c003909bcf3 132 ----------------------- */
andrewboyson 115:5c003909bcf3 133 char* p = pHeaderRx;
andrewboyson 115:5c003909bcf3 134 p += 2; //Skip the op code which we already know
andrewboyson 115:5c003909bcf3 135 uint16_t block = *p++;
andrewboyson 115:5c003909bcf3 136 block <<= 8;
andrewboyson 115:5c003909bcf3 137 block += *p++;
andrewboyson 115:5c003909bcf3 138
andrewboyson 115:5c003909bcf3 139 return sendBlock(block + 1, pSizeTx, pHeaderTx);
andrewboyson 115:5c003909bcf3 140 }
andrewboyson 115:5c003909bcf3 141 static int sendRequest(int* pSize, char* pHeader)
andrewboyson 115:5c003909bcf3 142 {
andrewboyson 115:5c003909bcf3 143 /*2 bytes string 1 byte string 1 byte
andrewboyson 115:5c003909bcf3 144 -----------------------------------------------
andrewboyson 115:5c003909bcf3 145 | WRQ | Filename | 0 | Mode | 0 |
andrewboyson 115:5c003909bcf3 146 ----------------------------------------------- */
andrewboyson 115:5c003909bcf3 147 char* p = pHeader;
andrewboyson 115:5c003909bcf3 148 *p++ = 0;
andrewboyson 115:5c003909bcf3 149 *p++ = TFTP_WRQ;
andrewboyson 115:5c003909bcf3 150 char* pName = TftpFileName;
andrewboyson 115:5c003909bcf3 151 while (*pName) *p++ = *pName++;
andrewboyson 115:5c003909bcf3 152 *p++ = 0;
andrewboyson 115:5c003909bcf3 153 const char* pMode = "octet";
andrewboyson 115:5c003909bcf3 154 while (*pMode) *p++ = *pMode++;
andrewboyson 115:5c003909bcf3 155 *p++ = 0;
andrewboyson 115:5c003909bcf3 156 *pSize = p - pHeader;
andrewboyson 115:5c003909bcf3 157 return UNICAST_TFTP;
andrewboyson 115:5c003909bcf3 158 }
andrewboyson 115:5c003909bcf3 159 int TftpHandlePacketReceived(void (*traceback)(void), int sizeRx, void * pPacketRx, int* pSizeTx, void* pPacketTx)
andrewboyson 115:5c003909bcf3 160 {
andrewboyson 115:5c003909bcf3 161 char* pHeaderRx = (char*)pPacketRx;
andrewboyson 115:5c003909bcf3 162 char* pHeaderTx = (char*)pPacketTx;
andrewboyson 115:5c003909bcf3 163
andrewboyson 115:5c003909bcf3 164 char* p = pHeaderRx;
andrewboyson 115:5c003909bcf3 165
andrewboyson 115:5c003909bcf3 166 if (*p)
andrewboyson 115:5c003909bcf3 167 {
andrewboyson 115:5c003909bcf3 168 LogTimeF("Expected high byte of op code to be zero not %u\r\n", *p);
andrewboyson 115:5c003909bcf3 169 return DO_NOTHING;
andrewboyson 115:5c003909bcf3 170 }
andrewboyson 115:5c003909bcf3 171 if (TftpTrace)
andrewboyson 115:5c003909bcf3 172 {
andrewboyson 115:5c003909bcf3 173 if (NetTraceNewLine) Log("\r\n");
andrewboyson 115:5c003909bcf3 174 LogTimeF("TFTP received packet\r\n");
andrewboyson 115:5c003909bcf3 175 if (NetTraceStack) traceback();
andrewboyson 115:5c003909bcf3 176 logHeader(sizeRx, pHeaderRx);
andrewboyson 115:5c003909bcf3 177 }
andrewboyson 115:5c003909bcf3 178 p++;
andrewboyson 115:5c003909bcf3 179 int dest = DO_NOTHING;
andrewboyson 115:5c003909bcf3 180 switch (*p)
andrewboyson 115:5c003909bcf3 181 {
andrewboyson 115:5c003909bcf3 182 case TFTP_ACK:
andrewboyson 115:5c003909bcf3 183 if (TftpWriteStatus == TFTP_WRITE_STATUS_NONE) return DO_NOTHING;
andrewboyson 115:5c003909bcf3 184 dest = handleAck(pHeaderRx, pSizeTx, pHeaderTx);
andrewboyson 115:5c003909bcf3 185 break;
andrewboyson 115:5c003909bcf3 186 case TFTP_ERROR:
andrewboyson 115:5c003909bcf3 187 handleError(pHeaderRx);
andrewboyson 115:5c003909bcf3 188 return DO_NOTHING;
andrewboyson 115:5c003909bcf3 189 default:
andrewboyson 115:5c003909bcf3 190 LogTimeF("\r\nTFTP packet unknown mode %d\r\n", *p);
andrewboyson 115:5c003909bcf3 191 return DO_NOTHING;
andrewboyson 115:5c003909bcf3 192 }
andrewboyson 115:5c003909bcf3 193
andrewboyson 115:5c003909bcf3 194 if (TftpTrace) logHeader(*pSizeTx, pHeaderTx);
andrewboyson 115:5c003909bcf3 195
andrewboyson 115:5c003909bcf3 196 return ActionMakeFromDestAndTrace(dest, TftpTrace && NetTraceStack);
andrewboyson 115:5c003909bcf3 197 }
andrewboyson 115:5c003909bcf3 198 static bool isTimedOut()
andrewboyson 115:5c003909bcf3 199 {
andrewboyson 115:5c003909bcf3 200 static uint32_t writeStartMs = 0;
andrewboyson 115:5c003909bcf3 201
andrewboyson 115:5c003909bcf3 202 if (TftpWriteStatus == TFTP_WRITE_STATUS_NONE) writeStartMs = MsTimerCount;
andrewboyson 115:5c003909bcf3 203
andrewboyson 133:a37eb35a03f1 204 if (MsTimerRelative(writeStartMs, WRITE_TIMEOUT_MS))
andrewboyson 115:5c003909bcf3 205 {
andrewboyson 115:5c003909bcf3 206 LogTime("TFTP - write operation timed out so reset\r\n");
andrewboyson 115:5c003909bcf3 207 writeStartMs = MsTimerCount;
andrewboyson 115:5c003909bcf3 208 return true;
andrewboyson 115:5c003909bcf3 209 }
andrewboyson 115:5c003909bcf3 210 return false;
andrewboyson 115:5c003909bcf3 211 }
andrewboyson 115:5c003909bcf3 212 static bool isOkToGo()
andrewboyson 115:5c003909bcf3 213 {
andrewboyson 115:5c003909bcf3 214 if (!TftpServerName[0])
andrewboyson 115:5c003909bcf3 215 {
andrewboyson 115:5c003909bcf3 216 LogTimeF("TftpPollForRequestToSend - A request to send a client message has been made but no server name has been specified\r\n");
andrewboyson 115:5c003909bcf3 217 return false;
andrewboyson 115:5c003909bcf3 218 }
andrewboyson 115:5c003909bcf3 219
andrewboyson 115:5c003909bcf3 220 if (!TftpGetNextByteFunction)
andrewboyson 115:5c003909bcf3 221 {
andrewboyson 115:5c003909bcf3 222 LogTimeF("TftpPollForRequestToSend - A request to send a client message has been made but TFTP has not been plumbed into a file stream\r\n");
andrewboyson 115:5c003909bcf3 223 return false;
andrewboyson 115:5c003909bcf3 224 }
andrewboyson 115:5c003909bcf3 225 return true;
andrewboyson 115:5c003909bcf3 226 }
andrewboyson 115:5c003909bcf3 227 int TftpPollForPacketToSend(int type, void* pPacket, int* pSize)
andrewboyson 115:5c003909bcf3 228 {
andrewboyson 116:60521b29e4c9 229 if (isTimedOut() ) { TftpWriteStatus = TFTP_WRITE_STATUS_NONE; return DO_NOTHING; }
andrewboyson 116:60521b29e4c9 230 if (TftpWriteStatus != TFTP_WRITE_STATUS_REQUEST ) { return DO_NOTHING; }
andrewboyson 116:60521b29e4c9 231 if (!isOkToGo() ) { TftpWriteStatus = TFTP_WRITE_STATUS_NONE; return DO_NOTHING; }
andrewboyson 116:60521b29e4c9 232 if (!Resolve(TftpServerName, type, &TftpServerIp4, TftpServerIp6)) { return DO_NOTHING; }
andrewboyson 115:5c003909bcf3 233
andrewboyson 115:5c003909bcf3 234 //Have IP and MAC so send request
andrewboyson 115:5c003909bcf3 235 TftpWriteStatus = TFTP_WRITE_STATUS_IN_PROGRESS;
andrewboyson 115:5c003909bcf3 236 int dest = sendRequest(pSize, (char*)pPacket);
andrewboyson 115:5c003909bcf3 237 if (TftpTrace)
andrewboyson 115:5c003909bcf3 238 {
andrewboyson 115:5c003909bcf3 239 if (NetTraceNewLine) Log("\r\n");
andrewboyson 115:5c003909bcf3 240 LogTimeF("TFTP Sending request\r\n");
andrewboyson 115:5c003909bcf3 241 logHeader(*pSize, (char*)pPacket);
andrewboyson 115:5c003909bcf3 242 }
andrewboyson 115:5c003909bcf3 243 return ActionMakeFromDestAndTrace(dest, TftpTrace && NetTraceStack);
andrewboyson 115:5c003909bcf3 244 }