Add options for networking and move networking in main to net.cpp
This commit is contained in:
parent
adf5172e94
commit
4cd1682c4c
9 changed files with 164 additions and 52 deletions
18
.clang-format
Normal file
18
.clang-format
Normal file
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
AlignAfterOpenBracket: AlwaysBreak
|
||||
AllowShortBlocksOnASingleLine: 'false'
|
||||
BinPackArguments: 'false'
|
||||
BinPackParameters: 'false'
|
||||
BreakBeforeBraces: Allman
|
||||
BreakConstructorInitializers: AfterColon
|
||||
ColumnLimit: '100'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: 'true'
|
||||
IndentWidth: '4'
|
||||
MaxEmptyLinesToKeep: '1'
|
||||
NamespaceIndentation: All
|
||||
PointerAlignment: Left
|
||||
SortIncludes: 'true'
|
||||
TabWidth: '4'
|
||||
UseTab: Always
|
||||
|
||||
...
|
2
Makefile
2
Makefile
|
@ -4,7 +4,7 @@ OBJS = armc-start.o armc-cstartup.o armc-cstubs.o armc-cppstubs.o \
|
|||
Drive.o Pi1541.o DiskImage.o iec_bus.o iec_commands.o m6502.o m6522.o \
|
||||
gcr.o prot.o lz.o emmc.o diskio.o options.o Screen.o SSD1306.o ScreenLCD.o \
|
||||
Timer.o FileBrowser.o DiskCaddy.o ROMs.o InputMappings.o xga_font_data.o m8520.o wd177x.o Pi1581.o SpinLock.o \
|
||||
net-tftp.o net-arp.o net-ethernet.o net-icmp.o net-ipv4.o net-udp.o net-dhcp.o net-utils.o
|
||||
net.o net-tftp.o net-arp.o net-ethernet.o net-icmp.o net-ipv4.o net-udp.o net-dhcp.o net-utils.o
|
||||
|
||||
SRCDIR = src
|
||||
OBJS := $(addprefix $(SRCDIR)/, $(OBJS))
|
||||
|
|
42
src/main.cpp
42
src/main.cpp
|
@ -367,40 +367,6 @@ void InitialiseLCD()
|
|||
// printf("\E[1ALED %s%d\E[0m Motor %d Track %0d.%d ATN %d DAT %d CLK %d %s\r\n", LED ? termainalTextRed : termainalTextNormal, LED, Motor, Track >> 1, Track & 1 ? 5 : 0, ATN, DATA, CLOCK, roms.ROMNames[romIndex]);
|
||||
//}
|
||||
|
||||
void updateNetwork()
|
||||
{
|
||||
unsigned int frameSize = 0;
|
||||
uint8_t ipBuffer[USPI_FRAME_BUFFER_SIZE];
|
||||
if (!USPiEthernetAvailable() || !USPiReceiveFrame(ipBuffer, &frameSize))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Net::Ethernet::Header ethernetHeader;
|
||||
auto headerSize = Net::Ethernet::Header::Deserialize(
|
||||
ethernetHeader, ipBuffer, frameSize);
|
||||
assert(headerSize != 0);
|
||||
|
||||
static bool arpAnnouncementSent = false;
|
||||
if (!arpAnnouncementSent)
|
||||
{
|
||||
Net::Arp::SendAnnouncement(
|
||||
Net::Utils::GetMacAddress(), Net::Utils::Ipv4Address);
|
||||
arpAnnouncementSent = true;
|
||||
}
|
||||
|
||||
switch (ethernetHeader.type)
|
||||
{
|
||||
case Net::Ethernet::EtherType::Arp:
|
||||
Net::Arp::HandlePacket(ethernetHeader, ipBuffer + headerSize);
|
||||
break;
|
||||
case Net::Ethernet::EtherType::Ipv4:
|
||||
Net::Ipv4::HandlePacket(
|
||||
ethernetHeader, ipBuffer + headerSize, frameSize - headerSize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// This runs on core0 and frees up core1 to just run the emulator.
|
||||
// Care must be taken not to crowd out the shared cache with core1 as this could slow down core1 so that it no longer can perform its duties in the 1us timings it requires.
|
||||
void UpdateScreen()
|
||||
|
@ -665,7 +631,7 @@ void UpdateScreen()
|
|||
//if (options.GetSupportUARTInput())
|
||||
// UpdateUartControls(refreshUartStatusDisplay, oldLED, oldMotor, oldATN, oldDATA, oldCLOCK, oldTrack, romIndex);
|
||||
|
||||
updateNetwork();
|
||||
Net::Update();
|
||||
|
||||
// Go back to sleep. The USB irq will wake us up again.
|
||||
__asm ("WFE");
|
||||
|
@ -1984,13 +1950,9 @@ extern "C"
|
|||
inputMappings = new InputMappings();
|
||||
//USPiMouseRegisterStatusHandler(MouseHandler);
|
||||
|
||||
while (!USPiEthernetAvailable()) {
|
||||
snprintf(tempBuffer, tempBufferSize, "Waiting for ethernet...");
|
||||
screen.PrintText(false, 0, y_pos+=16, tempBuffer, COLOUR_WHITE, COLOUR_BLACK);
|
||||
MsDelay(500);
|
||||
}
|
||||
|
||||
CheckOptions();
|
||||
Net::Initialize(options);
|
||||
|
||||
IEC_Bus::SetSplitIECLines(options.SplitIECLines());
|
||||
IEC_Bus::SetInvertIECInputs(options.InvertIECInputs());
|
||||
|
|
|
@ -166,24 +166,33 @@ namespace Net::Dhcp
|
|||
USPiSendFrame(buffer, size);
|
||||
}
|
||||
|
||||
void discoverTimerHandler(unsigned int hTimer, void* nParam, void* nContext)
|
||||
void discoverTimerHandler(unsigned int, void* callbackVoid, void*)
|
||||
{
|
||||
if (transactionId == 0 || offeredIpAddresses.empty())
|
||||
{
|
||||
// TODO retry every minute or so?
|
||||
return;
|
||||
}
|
||||
|
||||
// Select the first IP address
|
||||
const auto clientIpAddress = offeredIpAddresses[0];
|
||||
Utils::Ipv4Address = offeredIpAddresses[0];
|
||||
|
||||
// Send DHCP Requests to every server with that IP address.
|
||||
for (size_t i = 0; i < serverIpAddresses.size(); i++)
|
||||
{
|
||||
sendRequest(clientIpAddress, serverMacAddresses[i], serverIpAddresses[i]);
|
||||
sendRequest(
|
||||
Utils::Ipv4Address, serverMacAddresses[i], serverIpAddresses[i]);
|
||||
}
|
||||
|
||||
// Run the callback indicating an IP has been obtained
|
||||
if (callbackVoid != nullptr)
|
||||
{
|
||||
const auto& callback = *static_cast<std::function<void()>*>(callbackVoid);
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
void SendDiscover()
|
||||
void sendDiscover()
|
||||
{
|
||||
transactionId = std::rand();
|
||||
offeredIpAddresses.clear();
|
||||
|
@ -216,9 +225,15 @@ namespace Net::Dhcp
|
|||
assert(size <= sizeof(buffer));
|
||||
|
||||
USPiSendFrame(buffer, size);
|
||||
}
|
||||
|
||||
// Wait a second for responses
|
||||
StartKernelTimer(1 * HZ, discoverTimerHandler, nullptr, nullptr);
|
||||
void ObtainIp(std::function<void()>& callback)
|
||||
{
|
||||
sendDiscover();
|
||||
|
||||
// Wait three seconds for responses
|
||||
const auto callbackVoid = static_cast<void*>(&callback);
|
||||
StartKernelTimer(3 * HZ, discoverTimerHandler, callbackVoid, nullptr);
|
||||
}
|
||||
|
||||
static void handleOfferPacket(
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include <functional>
|
||||
#include "net.h"
|
||||
#include "net-ethernet.h"
|
||||
|
||||
|
@ -88,7 +89,7 @@ namespace Net::Dhcp
|
|||
Header& out, const uint8_t* buffer, const size_t size);
|
||||
};
|
||||
|
||||
void SendDiscover();
|
||||
void ObtainIp(std::function<void()>& callback);
|
||||
void HandlePacket(
|
||||
const Ethernet::Header& ethernetHeader,
|
||||
const uint8_t* buffer,
|
||||
|
|
94
src/net.cpp
Normal file
94
src/net.cpp
Normal file
|
@ -0,0 +1,94 @@
|
|||
#include "net.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "options.h"
|
||||
#include "types.h"
|
||||
#include <uspi.h>
|
||||
#include <uspios.h>
|
||||
|
||||
namespace Net
|
||||
{
|
||||
static void postInitialize(unsigned int, void* parameter, void*);
|
||||
static void ipObtained();
|
||||
|
||||
void Initialize(Options& options)
|
||||
{
|
||||
// Wait for ethernet to become available.
|
||||
while (!USPiEthernetAvailable())
|
||||
{
|
||||
MsDelay(500);
|
||||
}
|
||||
|
||||
// Wait 3 seconds, then run postInitialize
|
||||
const auto optionsVoid = static_cast<void*>(&options);
|
||||
StartKernelTimer(3 * HZ, postInitialize, optionsVoid, nullptr);
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
unsigned int bufferSize = 0;
|
||||
uint8_t buffer[USPI_FRAME_BUFFER_SIZE];
|
||||
if (!USPiEthernetAvailable() || !USPiReceiveFrame(buffer, &bufferSize))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Ethernet::Header ethernetHeader;
|
||||
auto headerSize = Ethernet::Header::Deserialize(ethernetHeader, buffer, bufferSize);
|
||||
if (headerSize == 0 || headerSize != Ethernet::Header::SerializedLength())
|
||||
{
|
||||
DEBUG_LOG(
|
||||
"Dropped ethernet packet (invalid buffer size %lu, expected at least %lu)\r\n",
|
||||
headerSize,
|
||||
Ethernet::Header::SerializedLength());
|
||||
return;
|
||||
}
|
||||
|
||||
switch (ethernetHeader.type)
|
||||
{
|
||||
case Ethernet::EtherType::Arp:
|
||||
Arp::HandlePacket(ethernetHeader, buffer + headerSize, bufferSize - headerSize);
|
||||
break;
|
||||
case Ethernet::EtherType::Ipv4:
|
||||
Ipv4::HandlePacket(ethernetHeader, buffer + headerSize, bufferSize - headerSize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void postInitialize(unsigned int, void* parameter, void*)
|
||||
{
|
||||
DEBUG_LOG("Running network post-init\r\n");
|
||||
const auto options = static_cast<const Options*>(parameter);
|
||||
|
||||
if (options->GetDHCPEnable())
|
||||
{
|
||||
std::function<void()> callback = ipObtained;
|
||||
Dhcp::ObtainIp(callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try parsing the IP address in the options.
|
||||
uint8_t ip[4];
|
||||
int scanned = sscanf(
|
||||
options->GetIPAddress(), "%hhu.%hhu.%hhu.%hhu", &ip[3], &ip[2], &ip[1], &ip[0]);
|
||||
|
||||
if (scanned == 4)
|
||||
{
|
||||
DEBUG_LOG("Setting IP address %d.%d.%d.%d\r\n", ip[3], ip[2], ip[1], ip[0]);
|
||||
Utils::Ipv4Address = *reinterpret_cast<uint32_t*>(ip);
|
||||
}
|
||||
|
||||
ipObtained();
|
||||
}
|
||||
}
|
||||
|
||||
static void ipObtained()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
uint8_t* ip = reinterpret_cast<uint8_t*>(Utils::Ipv4Address);
|
||||
DEBUG_LOG("Obtained IP address %d.%d.%d.%d\r\n", ip[3], ip[2], ip[1], ip[0]);
|
||||
#endif
|
||||
|
||||
Arp::SendAnnouncement(Utils::GetMacAddress(), Utils::Ipv4Address);
|
||||
}
|
||||
} // namespace Net
|
|
@ -1,5 +1,14 @@
|
|||
#pragma once
|
||||
#include "net-arp.h"
|
||||
#include "net-dhcp.h"
|
||||
#include "net-ethernet.h"
|
||||
#include "net-ipv4.h"
|
||||
#include "net-utils.h"
|
||||
|
||||
#include "options.h"
|
||||
|
||||
namespace Net
|
||||
{
|
||||
void Initialize(Options& options);
|
||||
void Update();
|
||||
} // namespace Net
|
||||
|
|
|
@ -160,6 +160,8 @@ Options::Options(void)
|
|||
, buttonInsert(5)
|
||||
, rotaryEncoderEnable(0) //ROTARY:
|
||||
, rotaryEncoderInvert(0) //ROTARY:
|
||||
, dhcpEnable(1)
|
||||
, ipAddress{}
|
||||
{
|
||||
autoMountImageName[0] = 0;
|
||||
strcpy(ROMFontName, "chargen");
|
||||
|
@ -252,6 +254,7 @@ void Options::Process(char* buffer)
|
|||
ELSE_CHECK_DECIMAL_OPTION(buttonInsert)
|
||||
ELSE_CHECK_DECIMAL_OPTION(rotaryEncoderEnable) //ROTARY:
|
||||
ELSE_CHECK_DECIMAL_OPTION(rotaryEncoderInvert) //ROTARY:
|
||||
ELSE_CHECK_DECIMAL_OPTION(dhcpEnable)
|
||||
else if ((strcasecmp(pOption, "AutoBaseName") == 0))
|
||||
{
|
||||
strncpy(autoBaseName, pValue, 255);
|
||||
|
@ -314,10 +317,14 @@ void Options::Process(char* buffer)
|
|||
{
|
||||
strncpy(ROMNameSlot8, pValue, 255);
|
||||
}
|
||||
else if ((strcasecmp(pOption, "NewDiskType") == 0))
|
||||
else if (strcasecmp(pOption, "NewDiskType") == 0)
|
||||
{
|
||||
strncpy(newDiskType, pValue, 31);
|
||||
}
|
||||
else if (strcasecmp(pOption, "IPAddress") == 0)
|
||||
{
|
||||
strncpy(ipAddress, pValue, sizeof(ipAddress) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!SplitIECLines())
|
||||
|
|
|
@ -123,6 +123,9 @@ public:
|
|||
static unsigned GetDecimal(char* pString);
|
||||
static float GetFloat(char* pString);
|
||||
|
||||
constexpr int GetDHCPEnable() const { return dhcpEnable; }
|
||||
constexpr const char* GetIPAddress() const { return ipAddress; }
|
||||
|
||||
private:
|
||||
unsigned int deviceID;
|
||||
unsigned int onResetChangeToStartingFolder;
|
||||
|
@ -196,5 +199,8 @@ private:
|
|||
//ROTARY: Added for rotary encoder inversion (Issue#185) - 08/13/2020 by Geo...
|
||||
unsigned int rotaryEncoderInvert;
|
||||
|
||||
int dhcpEnable;
|
||||
char ipAddress[16];
|
||||
|
||||
};
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue