mirror of
https://github.com/akuker/RASCSI.git
synced 2026-10-25 12:02:59 +00:00
Restore the SCBR device as an X68000 Host Bridge, including the Human68k-compatible host file-system service and the bridge-specific SCSI message handlers. Back its Ethernet path with the TAP driver, derive a stable locally administered MAC address, preserve the driver minimum-frame/FCS expectations, and restrict received traffic to its own unicast frames and broadcasts. Match the RASCTL/RASETHER/RASDRV bridge protocol that originated in the parent RaSCSI project: dispatch its non-standard message format on READ(10)/WRITE(10) (0x28/0x2a), with type, function, phase, and a three-byte byte count carried in the CDB. Advertise the legacy control channel required by RASCTL, translate its list and device-management commands to PiSCSI operations, and defer stop or system-shutdown requests until after the response is sent, while gating this insecure interface behind a new '-c disabled|media|full' runtime option. Preserve the type-1 Ethernet exchange used by RASETHER and the type-2, phased filesystem exchange used by RASDRV. Register the device in the factory, protobuf API, controller transfer path, command-line tooling, device listings, and web UI. Share the explicit bridge and proxy-ARP topology workflow with DaynaPort so both adapters validate and use the same mode/interface pair. Add build support for iconv where needed, extend unit coverage for device creation, RAS* protocol handling, CLI parsing, web attachment, and topology selection, and update the man pages and network-profile documentation for Host Bridge operation and its networking limits.
63 lines
2.4 KiB
C++
63 lines
2.4 KiB
C++
//---------------------------------------------------------------------------
|
|
//
|
|
// SCSI Target Emulator PiSCSI
|
|
//---------------------------------------------------------------------------
|
|
|
|
#include "devices/scsi_host_bridge.h"
|
|
#include "mocks.h"
|
|
|
|
TEST(ScsiHostBridgeTest, GetDefaultParams)
|
|
{
|
|
const auto [controller, bridge] = CreateDevice(SCBR);
|
|
const auto params = bridge->GetDefaultParams();
|
|
EXPECT_EQ(2, params.size());
|
|
}
|
|
|
|
TEST(ScsiHostBridgeTest, DeriveMac)
|
|
{
|
|
const array<uint8_t, 6> uplink_mac = { 0xb8, 0x27, 0xeb, 0xb5, 0xa3, 0x15 };
|
|
const auto mac = SCSIBR::DeriveMac(uplink_mac);
|
|
EXPECT_EQ(0x02, mac[0]);
|
|
EXPECT_NE(uplink_mac, mac);
|
|
EXPECT_EQ(mac, SCSIBR::DeriveMac(uplink_mac));
|
|
|
|
const array<uint8_t, 5> invalid_mac = { 0, 1, 2, 3, 4 };
|
|
EXPECT_EQ((array<uint8_t, 6> {}), SCSIBR::DeriveMac(invalid_mac));
|
|
}
|
|
|
|
TEST(ScsiHostBridgeTest, InquiryDisablesRasctlControlByDefault)
|
|
{
|
|
const auto [controller, bridge] = CreateDevice(SCBR);
|
|
const auto inquiry = std::dynamic_pointer_cast<SCSIBR>(bridge)->InquiryInternal();
|
|
EXPECT_EQ(0, inquiry[36]);
|
|
EXPECT_EQ('1', inquiry[38]);
|
|
}
|
|
|
|
TEST(ScsiHostBridgeTest, RasctlControlUsesRasctlMessageFormat)
|
|
{
|
|
const auto [controller, device] = CreateDevice(SCBR);
|
|
const auto bridge = std::dynamic_pointer_cast<SCSIBR>(device);
|
|
const array<int, 10> write_cdb = { 0x2a, 0, 0, 0, 0, 0, 0, 4, 0, 0 };
|
|
const array<int, 10> read_cdb = { 0x28, 0, 0, 0, 0, 0, 0, 4, 0, 0 };
|
|
vector<uint8_t> buffer(1024);
|
|
EXPECT_FALSE(bridge->ReadWrite(write_cdb, buffer));
|
|
EXPECT_EQ(0, bridge->GetMessage10(read_cdb, buffer));
|
|
bridge->SetRasctlControlMode(SCSIBR::rasctl_control_mode::media);
|
|
EXPECT_EQ('1', bridge->InquiryInternal()[36]);
|
|
|
|
memcpy(buffer.data(), "list\n", 5);
|
|
EXPECT_TRUE(bridge->ReadWrite(write_cdb, buffer));
|
|
const auto command = bridge->TakeRasctlControlRequest();
|
|
ASSERT_TRUE(command.has_value());
|
|
EXPECT_EQ("list\n", *command);
|
|
|
|
bridge->SetRasctlControlResponse("No devices currently attached.\n");
|
|
buffer.assign(buffer.size(), 0xff);
|
|
EXPECT_EQ(1024, bridge->GetMessage10(read_cdb, buffer));
|
|
EXPECT_STREQ("No devices currently attached.\n", reinterpret_cast<const char *>(buffer.data()));
|
|
|
|
bridge->SetRasctlControlResponse("PiSCSI shutdown requested\n", SCSIBR::rasctl_shutdown_mode::stop_piscsi);
|
|
EXPECT_EQ(1024, bridge->GetMessage10(read_cdb, buffer));
|
|
EXPECT_EQ(SCSIBR::rasctl_shutdown_mode::stop_piscsi, bridge->TakeRasctlShutdownMode());
|
|
}
|