Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
Revision 184:ad80a63e3002, committed 2021-01-14
- Comitter:
- andrewboyson
- Date:
- Thu Jan 14 13:41:02 2021 +0000
- Parent:
- 183:ee809769bf89
- Child:
- 185:e8f516e142c4
- Commit message:
- Modified TFTP to not start if the network wasn't ready in IPv4; Made changes to DHCP including making the first timeout 4 seconds rather than 1.
Changed in this revision
--- a/udp/dhcp/dhcp.c Tue Jan 12 19:10:22 2021 +0000
+++ b/udp/dhcp/dhcp.c Thu Jan 14 13:41:02 2021 +0000
@@ -30,8 +30,8 @@
#define COOKIE 0x63825363
-#define MAX_REPEAT_DELAY_TIME_MS 60000
-#define MIN_REPEAT_DELAY_TIME_MS 900
+#define MAX_REPEAT_DELAY_TIME_MS 64000
+#define MIN_REPEAT_DELAY_TIME_MS 4000
#define STATE_NONE 0
#define STATE_DISCOVER 1
@@ -45,12 +45,9 @@
static int _state = STATE_NONE;
static uint32_t _offeredIp = 0;
static uint32_t _serverId = 0;
-static bool _awaitResponse = false;
+static bool _awaitingResponse = false;
-static uint32_t _repeatDelayMsTimer = (uint32_t)-MIN_REPEAT_DELAY_TIME_MS; //Initial value ensures no delay at startup
-static uint32_t _delayMs = MIN_REPEAT_DELAY_TIME_MS; //Doubles on failure up to max; reset to min whenever an IP address request has been acknowledged
-
-static uint32_t _elapsedLifeMsTimer = 0; //Started whenever an IP address request has been acknowledged
+static uint32_t _elapsedLifeMsTimer = 0; //Started whenever an IP address request has been acknowledged
uint32_t DhcpGetElapsedLife()
{
@@ -88,6 +85,7 @@
DhcpHostName [0] = 0;
_offeredIp = 0;
_serverId = 0;
+ _awaitingResponse = false;
}
bool DhcpIpNeedsToBeRouted(uint32_t ip)
@@ -243,49 +241,9 @@
*pp += *pLength + 2;
}
-int sendRequest(void* pPacket)
+int makeRequest(void* pPacket, uint8_t type, uint32_t ciaddr, uint32_t requestedIp, uint32_t serverId)
{
- uint8_t type = 0;
- uint32_t currentIp = 0; //goes in ciaddr
- uint32_t requestedIp = 0; //goes in option 54
- uint32_t serverIp = 0; //goes in option 50 and is the server id for the accepted offer
-
- switch (_state)
- {
- case STATE_DISCOVER:
- if (DhcpTrace) LogTimeF("DHCP -> discover\r\n");
- type = DHCPDISCOVER;
- currentIp = 0;
- requestedIp = 0;
- serverIp = 0;
- break;
- case STATE_SELECT:
- if (DhcpTrace) LogTimeF("DHCP -> select "); Ip4AddressLog(_offeredIp); Log(" from server "); Ip4AddressLog(_serverId); Log("\r\n");
- type = DHCPREQUEST;
- currentIp = 0;
- requestedIp = _offeredIp;
- serverIp = _serverId;
- break;
- case STATE_RENEW:
- if (DhcpTrace) LogTimeF("DHCP -> renew (T1)\r\n");
- type = DHCPREQUEST;
- currentIp = DhcpLocalIp;
- requestedIp = 0;
- serverIp = 0;
- break;
- case STATE_REBIND:
- if (DhcpTrace) LogTimeF("DHCP -> rebind (T2)\r\n");
- type = DHCPREQUEST;
- currentIp = 0;
- requestedIp = 0;
- serverIp = 0;
- break;
- default:
- LogTimeF("DHCP -> unknown state %d\r\n", _state);
- return 0;
- }
-
- bool broadcast = currentIp == 0;
+ bool broadcast = ciaddr == 0;
uint16_t flags = 0;
if (broadcast) flags |= 0x8000;
DhcpHdrSetOp (pPacket, REQUEST );
@@ -295,7 +253,7 @@
DhcpHdrSetXid (pPacket, _xid ); //Randomly chosed transaction id used to associate messages to responses
DhcpHdrSetSecs (pPacket, 0 ); //Seconds since started to boot
DhcpHdrSetFlags (pPacket, flags ); //Broadcast (1) Unicast (0)
- DhcpHdrSetCiaddr(pPacket, currentIp ); //'Client' address set by client or 0 if don't know address
+ DhcpHdrSetCiaddr(pPacket, ciaddr ); //'Client' address set by client or 0 if don't know address
DhcpHdrSetYiaddr(pPacket, 0 ); //'Your' address returned by server
DhcpHdrSetSiaddr(pPacket, 0 ); //'Server' address to use if required
DhcpHdrSetGiaddr(pPacket, 0 ); //'Gateway' address
@@ -307,14 +265,9 @@
char* p = pOptions;
*p++ = 53; *p++ = 1; *p++ = type; //DHCP message type
if (requestedIp) writeIp(50, requestedIp, &p); //Requested IP
- if ( serverIp) writeIp(54, serverIp, &p); //Server ip
+ if ( serverId) writeIp(54, serverId, &p); //Server ip
writeText(12, NET_NAME, &p); //Host name
*p++ = 255; //End of options
-
- _awaitResponse = true;
- _delayMs <<= 1; //Backoff (double) the delay time after each attempt
- if (_delayMs > MAX_REPEAT_DELAY_TIME_MS) _delayMs = MAX_REPEAT_DELAY_TIME_MS; //Don't go beyond a maximum
- _repeatDelayMsTimer = MsTimerCount; //Start the delay timer
return DHCP_HEADER_LENGTH + p - pOptions;
}
@@ -347,8 +300,7 @@
_offeredIp = yiaddr;
readOptionServerId(sizeRx - DHCP_HEADER_LENGTH, pOptions);
if (DhcpTrace) { LogTime("DHCP <- offer "); Ip4AddressLog(_offeredIp); Log(" from server "); Ip4AddressLog(_serverId); Log("\r\n"); }
- _awaitResponse = false;
- _delayMs = MIN_REPEAT_DELAY_TIME_MS; //Set the delay time back to minimum
+ _awaitingResponse = false;
}
else
{
@@ -363,8 +315,7 @@
DhcpServerIp = _serverId;
if (DhcpTrace) { LogTime("DHCP <- ack "); Ip4AddressLog(DhcpLocalIp); Log(" from server "); Ip4AddressLog(_serverId); Log("\r\n"); }
_elapsedLifeMsTimer = MsTimerCount; //Start the life timer
- _awaitResponse = false;
- _delayMs = MIN_REPEAT_DELAY_TIME_MS; //Set the delay time back to minimum
+ _awaitingResponse = false;
}
else
{
@@ -377,8 +328,7 @@
readOptionServerId(sizeRx - DHCP_HEADER_LENGTH, pOptions);
if (DhcpTrace) { LogTime("DHCP <- nack "); Ip4AddressLog(yiaddr); Log(" from server "); Ip4AddressLog(_serverId); Log("\r\n"); }
clearAll();
- _awaitResponse = false;
- _delayMs = MIN_REPEAT_DELAY_TIME_MS; //Set the delay time back to minimum
+ _awaitingResponse = false;
}
else
{
@@ -438,33 +388,94 @@
bool stateHasChanged = _state != stateLastScan;
stateLastScan = _state;
- bool needToResendRequest = _awaitResponse && MsTimerRelative(_repeatDelayMsTimer, _delayMs);
+ static uint32_t delayMs;
+ static uint32_t repeatDelayMsTimer;
+
+ bool responseTimeout = _awaitingResponse && MsTimerRelative(repeatDelayMsTimer, delayMs);
- bool need = stateHasChanged || needToResendRequest;
+ bool send = stateHasChanged || responseTimeout;
- if (!need) return DO_NOTHING;
+ if (!send) return DO_NOTHING;
+
+ int dest = DO_NOTHING;
+ uint8_t type = 0; //DISCOVER or REQUEST
+ uint32_t ciaddr = 0; //goes in ciaddr only for BOUND/RENEW/REBIND
+ uint32_t requestedIp = 0; //goes in option 54 only for SELECTING
+ uint32_t serverId = 0; //goes in option 50 and is the server id for the accepted offer
//Send the renewal request
*pSize = 0;
- int dest = DO_NOTHING;
+
+
switch (_state)
{
- case STATE_NONE: clearAll(); return DO_NOTHING;
- case STATE_DISCOVER: dest = BROADCAST; break;
- case STATE_SELECT: dest = BROADCAST; break;
- case STATE_BOUND: return DO_NOTHING;
- case STATE_RENEW: dest = UNICAST_DHCP; break;
- case STATE_REBIND: dest = BROADCAST; break;
- case STATE_EXPIRED:
- if (DhcpTrace) LogTimeF("DHCP lease has expired\r\n");
+ case STATE_NONE:
+ if (DhcpTrace) { LogTimeF("DHCP -- none\r\n"); }
clearAll();
return DO_NOTHING;
+
+ case STATE_DISCOVER:
+ if (DhcpTrace) { LogTimeF("DHCP -> discover\r\n"); }
+ type = DHCPDISCOVER;
+ ciaddr = 0;
+ requestedIp = 0;
+ serverId = 0;
+ dest = BROADCAST;
+ break;
+
+ case STATE_SELECT:
+ if (DhcpTrace) { LogTimeF("DHCP -> select "); Ip4AddressLog(_offeredIp); Log(" from server "); Ip4AddressLog(_serverId); Log("\r\n"); }
+ type = DHCPREQUEST;
+ ciaddr = 0;
+ requestedIp = _offeredIp;
+ serverId = _serverId;
+ dest = BROADCAST;
+ break;
+
+ case STATE_BOUND:
+ if (DhcpTrace) { LogTimeF("DHCP -- bound "); Ip4AddressLog(DhcpLocalIp); Log("\r\n"); }
+ return DO_NOTHING;
+
+ case STATE_RENEW:
+ if (DhcpTrace) { LogTimeF("DHCP -> renew (T1) "); Ip4AddressLog(DhcpLocalIp); Log("\r\n"); }
+ type = DHCPREQUEST;
+ ciaddr = DhcpLocalIp;
+ requestedIp = 0;
+ serverId = 0;
+ dest = UNICAST_DHCP;
+ break;
+
+ case STATE_REBIND:
+ if (DhcpTrace) { LogTimeF("DHCP -> rebind (T2) "); Ip4AddressLog(DhcpLocalIp); Log("\r\n"); }
+ type = DHCPREQUEST;
+ ciaddr = DhcpLocalIp;
+ requestedIp = 0;
+ serverId = 0;
+ dest = BROADCAST;
+ break;
+
+ case STATE_EXPIRED:
+ if (DhcpTrace) { LogTimeF("DHCP -- expired "); Ip4AddressLog(DhcpLocalIp); Log("\r\n"); }
+ clearAll();
+ return DO_NOTHING;
+
default:
- LogTimeF("DHCP -> unknown state %d", _state);
- return DO_NOTHING;
+ LogTimeF("DHCP -- unknown state %d\r\n", _state);
+ return 0;
}
- *pSize = sendRequest(pPacket);
+ if (!_awaitingResponse)
+ {
+ delayMs = MIN_REPEAT_DELAY_TIME_MS;
+ }
+ else
+ {
+ delayMs <<= 1; //Backoff (double) the delay time after each attempt
+ if (delayMs > MAX_REPEAT_DELAY_TIME_MS) delayMs = MAX_REPEAT_DELAY_TIME_MS; //Don't go beyond a maximum
+ }
+ _awaitingResponse = true;
+ repeatDelayMsTimer = MsTimerCount; //Start the repeat delay timer
+ *pSize = makeRequest(pPacket, type, ciaddr, requestedIp, serverId);
return ActionMakeFromDestAndTrace(dest, DhcpTrace && NetTraceStack);
}
\ No newline at end of file
--- a/udp/tftp/tftp.c Tue Jan 12 19:10:22 2021 +0000
+++ b/udp/tftp/tftp.c Thu Jan 14 13:41:02 2021 +0000
@@ -4,6 +4,8 @@
#include "log.h"
#include "net.h"
#include "action.h"
+#include "eth.h"
+#include "dhcp.h"
#include "udp.h"
#include "dns.h"
#include "tftp.h"
@@ -65,7 +67,7 @@
bool TftpSendRequestsViaIp4 = false;
uint32_t TftpServerIp4;
char TftpServerIp6[16];
-int TftpWriteStatus = TFTP_WRITE_STATUS_NONE;
+int TftpWriteStatus = TFTP_WRITE_STATUS_UNAVAILABLE;
char TftpServerName[DNS_MAX_LABEL_LENGTH+1];
char TftpFileName [DNS_MAX_LABEL_LENGTH+1];
@@ -200,7 +202,7 @@
{
static uint32_t writeStartMs = 0;
- if (TftpWriteStatus == TFTP_WRITE_STATUS_NONE) writeStartMs = MsTimerCount;
+ if (TftpWriteStatus == TFTP_WRITE_STATUS_NONE || TftpWriteStatus == TFTP_WRITE_STATUS_UNAVAILABLE) writeStartMs = MsTimerCount;
if (MsTimerRelative(writeStartMs, WRITE_TIMEOUT_MS))
{
@@ -227,6 +229,17 @@
}
int TftpPollForPacketToSend(int type, void* pPacket, int* pSize)
{
+ if (type == ETH_IPV4)
+ {
+ if (!DhcpLocalIp)
+ {
+ TftpWriteStatus = TFTP_WRITE_STATUS_UNAVAILABLE;
+ }
+ else
+ {
+ if (TftpWriteStatus == TFTP_WRITE_STATUS_UNAVAILABLE) TftpWriteStatus = TFTP_WRITE_STATUS_NONE;
+ }
+ }
if (isTimedOut() ) { TftpWriteStatus = TFTP_WRITE_STATUS_NONE; return DO_NOTHING; }
if (TftpWriteStatus != TFTP_WRITE_STATUS_REQUEST ) { return DO_NOTHING; }
if (!isOkToGo() ) { TftpWriteStatus = TFTP_WRITE_STATUS_NONE; return DO_NOTHING; }
--- a/udp/tftp/tftp.h Tue Jan 12 19:10:22 2021 +0000 +++ b/udp/tftp/tftp.h Thu Jan 14 13:41:02 2021 +0000 @@ -7,9 +7,10 @@ extern char TftpFileName[]; extern int TftpWriteStatus; -#define TFTP_WRITE_STATUS_NONE 0 -#define TFTP_WRITE_STATUS_REQUEST 1 -#define TFTP_WRITE_STATUS_IN_PROGRESS 2 +#define TFTP_WRITE_STATUS_UNAVAILABLE -1 +#define TFTP_WRITE_STATUS_NONE 0 +#define TFTP_WRITE_STATUS_REQUEST 1 +#define TFTP_WRITE_STATUS_IN_PROGRESS 2 extern bool TftpSendRequestsViaIp4; extern uint32_t TftpServerIp4;