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 \
|
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 \
|
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 \
|
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
|
SRCDIR = src
|
||||||
OBJS := $(addprefix $(SRCDIR)/, $(OBJS))
|
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]);
|
// 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.
|
// 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.
|
// 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()
|
void UpdateScreen()
|
||||||
|
@ -665,7 +631,7 @@ void UpdateScreen()
|
||||||
//if (options.GetSupportUARTInput())
|
//if (options.GetSupportUARTInput())
|
||||||
// UpdateUartControls(refreshUartStatusDisplay, oldLED, oldMotor, oldATN, oldDATA, oldCLOCK, oldTrack, romIndex);
|
// UpdateUartControls(refreshUartStatusDisplay, oldLED, oldMotor, oldATN, oldDATA, oldCLOCK, oldTrack, romIndex);
|
||||||
|
|
||||||
updateNetwork();
|
Net::Update();
|
||||||
|
|
||||||
// Go back to sleep. The USB irq will wake us up again.
|
// Go back to sleep. The USB irq will wake us up again.
|
||||||
__asm ("WFE");
|
__asm ("WFE");
|
||||||
|
@ -1984,13 +1950,9 @@ extern "C"
|
||||||
inputMappings = new InputMappings();
|
inputMappings = new InputMappings();
|
||||||
//USPiMouseRegisterStatusHandler(MouseHandler);
|
//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();
|
CheckOptions();
|
||||||
|
Net::Initialize(options);
|
||||||
|
|
||||||
IEC_Bus::SetSplitIECLines(options.SplitIECLines());
|
IEC_Bus::SetSplitIECLines(options.SplitIECLines());
|
||||||
IEC_Bus::SetInvertIECInputs(options.InvertIECInputs());
|
IEC_Bus::SetInvertIECInputs(options.InvertIECInputs());
|
||||||
|
|
|
@ -166,24 +166,33 @@ namespace Net::Dhcp
|
||||||
USPiSendFrame(buffer, size);
|
USPiSendFrame(buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void discoverTimerHandler(unsigned int hTimer, void* nParam, void* nContext)
|
void discoverTimerHandler(unsigned int, void* callbackVoid, void*)
|
||||||
{
|
{
|
||||||
if (transactionId == 0 || offeredIpAddresses.empty())
|
if (transactionId == 0 || offeredIpAddresses.empty())
|
||||||
{
|
{
|
||||||
|
// TODO retry every minute or so?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select the first IP address
|
// Select the first IP address
|
||||||
const auto clientIpAddress = offeredIpAddresses[0];
|
Utils::Ipv4Address = offeredIpAddresses[0];
|
||||||
|
|
||||||
// Send DHCP Requests to every server with that IP address.
|
// Send DHCP Requests to every server with that IP address.
|
||||||
for (size_t i = 0; i < serverIpAddresses.size(); i++)
|
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();
|
transactionId = std::rand();
|
||||||
offeredIpAddresses.clear();
|
offeredIpAddresses.clear();
|
||||||
|
@ -216,9 +225,15 @@ namespace Net::Dhcp
|
||||||
assert(size <= sizeof(buffer));
|
assert(size <= sizeof(buffer));
|
||||||
|
|
||||||
USPiSendFrame(buffer, size);
|
USPiSendFrame(buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
// Wait a second for responses
|
void ObtainIp(std::function<void()>& callback)
|
||||||
StartKernelTimer(1 * HZ, discoverTimerHandler, nullptr, nullptr);
|
{
|
||||||
|
sendDiscover();
|
||||||
|
|
||||||
|
// Wait three seconds for responses
|
||||||
|
const auto callbackVoid = static_cast<void*>(&callback);
|
||||||
|
StartKernelTimer(3 * HZ, discoverTimerHandler, callbackVoid, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleOfferPacket(
|
static void handleOfferPacket(
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <functional>
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "net-ethernet.h"
|
#include "net-ethernet.h"
|
||||||
|
|
||||||
|
@ -88,7 +89,7 @@ namespace Net::Dhcp
|
||||||
Header& out, const uint8_t* buffer, const size_t size);
|
Header& out, const uint8_t* buffer, const size_t size);
|
||||||
};
|
};
|
||||||
|
|
||||||
void SendDiscover();
|
void ObtainIp(std::function<void()>& callback);
|
||||||
void HandlePacket(
|
void HandlePacket(
|
||||||
const Ethernet::Header& ethernetHeader,
|
const Ethernet::Header& ethernetHeader,
|
||||||
const uint8_t* buffer,
|
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
|
#pragma once
|
||||||
#include "net-arp.h"
|
#include "net-arp.h"
|
||||||
|
#include "net-dhcp.h"
|
||||||
#include "net-ethernet.h"
|
#include "net-ethernet.h"
|
||||||
#include "net-ipv4.h"
|
#include "net-ipv4.h"
|
||||||
#include "net-utils.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)
|
, buttonInsert(5)
|
||||||
, rotaryEncoderEnable(0) //ROTARY:
|
, rotaryEncoderEnable(0) //ROTARY:
|
||||||
, rotaryEncoderInvert(0) //ROTARY:
|
, rotaryEncoderInvert(0) //ROTARY:
|
||||||
|
, dhcpEnable(1)
|
||||||
|
, ipAddress{}
|
||||||
{
|
{
|
||||||
autoMountImageName[0] = 0;
|
autoMountImageName[0] = 0;
|
||||||
strcpy(ROMFontName, "chargen");
|
strcpy(ROMFontName, "chargen");
|
||||||
|
@ -252,6 +254,7 @@ void Options::Process(char* buffer)
|
||||||
ELSE_CHECK_DECIMAL_OPTION(buttonInsert)
|
ELSE_CHECK_DECIMAL_OPTION(buttonInsert)
|
||||||
ELSE_CHECK_DECIMAL_OPTION(rotaryEncoderEnable) //ROTARY:
|
ELSE_CHECK_DECIMAL_OPTION(rotaryEncoderEnable) //ROTARY:
|
||||||
ELSE_CHECK_DECIMAL_OPTION(rotaryEncoderInvert) //ROTARY:
|
ELSE_CHECK_DECIMAL_OPTION(rotaryEncoderInvert) //ROTARY:
|
||||||
|
ELSE_CHECK_DECIMAL_OPTION(dhcpEnable)
|
||||||
else if ((strcasecmp(pOption, "AutoBaseName") == 0))
|
else if ((strcasecmp(pOption, "AutoBaseName") == 0))
|
||||||
{
|
{
|
||||||
strncpy(autoBaseName, pValue, 255);
|
strncpy(autoBaseName, pValue, 255);
|
||||||
|
@ -314,10 +317,14 @@ void Options::Process(char* buffer)
|
||||||
{
|
{
|
||||||
strncpy(ROMNameSlot8, pValue, 255);
|
strncpy(ROMNameSlot8, pValue, 255);
|
||||||
}
|
}
|
||||||
else if ((strcasecmp(pOption, "NewDiskType") == 0))
|
else if (strcasecmp(pOption, "NewDiskType") == 0)
|
||||||
{
|
{
|
||||||
strncpy(newDiskType, pValue, 31);
|
strncpy(newDiskType, pValue, 31);
|
||||||
}
|
}
|
||||||
|
else if (strcasecmp(pOption, "IPAddress") == 0)
|
||||||
|
{
|
||||||
|
strncpy(ipAddress, pValue, sizeof(ipAddress) - 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SplitIECLines())
|
if (!SplitIECLines())
|
||||||
|
|
|
@ -2,17 +2,17 @@
|
||||||
// Copyright(C) 2018 Stephen White
|
// Copyright(C) 2018 Stephen White
|
||||||
//
|
//
|
||||||
// This file is part of Pi1541.
|
// This file is part of Pi1541.
|
||||||
//
|
//
|
||||||
// Pi1541 is free software : you can redistribute it and/or modify
|
// Pi1541 is free software : you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
//
|
//
|
||||||
// Pi1541 is distributed in the hope that it will be useful,
|
// Pi1541 is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Pi1541. If not, see <http://www.gnu.org/licenses/>.
|
// along with Pi1541. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
@ -123,6 +123,9 @@ public:
|
||||||
static unsigned GetDecimal(char* pString);
|
static unsigned GetDecimal(char* pString);
|
||||||
static float GetFloat(char* pString);
|
static float GetFloat(char* pString);
|
||||||
|
|
||||||
|
constexpr int GetDHCPEnable() const { return dhcpEnable; }
|
||||||
|
constexpr const char* GetIPAddress() const { return ipAddress; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int deviceID;
|
unsigned int deviceID;
|
||||||
unsigned int onResetChangeToStartingFolder;
|
unsigned int onResetChangeToStartingFolder;
|
||||||
|
@ -196,5 +199,8 @@ private:
|
||||||
//ROTARY: Added for rotary encoder inversion (Issue#185) - 08/13/2020 by Geo...
|
//ROTARY: Added for rotary encoder inversion (Issue#185) - 08/13/2020 by Geo...
|
||||||
unsigned int rotaryEncoderInvert;
|
unsigned int rotaryEncoderInvert;
|
||||||
|
|
||||||
|
int dhcpEnable;
|
||||||
|
char ipAddress[16];
|
||||||
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue