Add options for networking and move networking in main to net.cpp

This commit is contained in:
Sijmen 2020-12-29 13:28:23 +01:00
parent adf5172e94
commit 4cd1682c4c
Signed by: vijfhoek
GPG key ID: DAF7821E067D9C48
9 changed files with 164 additions and 52 deletions

18
.clang-format Normal file
View 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
...

View file

@ -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))

View file

@ -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());

View file

@ -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(

View file

@ -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
View 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

View file

@ -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

View file

@ -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())

View file

@ -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