Merge branch 'develop' into issue_1311

This commit is contained in:
Uwe Seimet 2023-11-09 09:50:45 +01:00
commit 17bc4ebdbd
23 changed files with 261 additions and 91 deletions

View File

@ -32,6 +32,16 @@ jobs:
with:
connect-type: "STANDARD"
aibom:
uses: PiSCSI/piscsi/.github/workflows/arm_cross_compile.yml@develop
with:
connect-type: "AIBOM"
gamernium:
uses: PiSCSI/piscsi/.github/workflows/arm_cross_compile.yml@develop
with:
connect-type: "GAMERNIUM"
# The fullspec connection board is the most common
debug-fullspec:
uses: PiSCSI/piscsi/.github/workflows/arm_cross_compile.yml@develop

View File

@ -14,7 +14,7 @@ CXX = $(CROSS_COMPILE)g++
DEBUG ?= 0
ifeq ($(DEBUG), 1)
# Debug compiler flags
CXXFLAGS += -Og -g -Wall -Wextra -DDEBUG
CXXFLAGS += -O0 -g -Wall -Wextra -DDEBUG
else
# Release compiler flags
CXXFLAGS += -O3 -Wall -Werror -Wextra -DNDEBUG
@ -39,7 +39,7 @@ CXXFLAGS += $(EXTRA_FLAGS)
CONNECT_TYPE ?= FULLSPEC
ifdef CONNECT_TYPE
CXXFLAGS += -DCONNECT_TYPE_$(CONNECT_TYPE)
CXXFLAGS += -DCONNECT_TYPE_$(CONNECT_TYPE)
endif
PISCSI = piscsi
@ -67,9 +67,13 @@ BIN_ALL = \
$(BINDIR)/$(PISCSI) \
$(BINDIR)/$(SCSICTL) \
$(BINDIR)/$(SCSIMON) \
$(BINDIR)/$(SCSIDUMP) \
$(BINDIR)/$(SCSILOOP)
# scsidump requires initiator support
ifeq ($(CONNECT_TYPE), FULLSPEC)
BIN_ALL += $(BINDIR)/$(SCSIDUMP)
endif
SRC_PROTOC = piscsi_interface.proto
SRC_GENERATED = $(GENERATED_DIR)/piscsi_interface.pb.cpp
@ -128,6 +132,22 @@ OBJ_SHARED := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SHARED:%.cpp=%.o)))
OBJ_PROTOBUF := $(addprefix $(OBJDIR)/,$(notdir $(SRC_PROTOBUF:%.cpp=%.o)))
OBJ_GENERATED := $(addprefix $(OBJDIR)/,$(notdir $(SRC_GENERATED:%.cpp=%.o)))
BINARIES = $(USR_LOCAL_BIN)/$(SCSICTL) \
$(USR_LOCAL_BIN)/$(PISCSI) \
$(USR_LOCAL_BIN)/$(SCSIMON) \
$(USR_LOCAL_BIN)/$(SCSILOOP)
ifeq ($(CONNECT_TYPE), FULLSPEC)
BINARIES += $(USR_LOCAL_BIN)/$(SCSIDUMP)
endif
MAN_PAGES = $(MAN_PAGE_DIR)/piscsi.1 \
$(MAN_PAGE_DIR)/scsictl.1 \
$(MAN_PAGE_DIR)/scsimon.1 \
$(MAN_PAGE_DIR)/scsiloop.1
ifeq ($(CONNECT_TYPE), FULLSPEC)
MAN_PAGES += $(MAN_PAGE_DIR)/scsidump.1
endif
GENERATED_DIR := generated
# For the unit tests, the following functions will be "wrapped" by the linker, meaning the
@ -232,16 +252,8 @@ clean:
## * sudo systemctl start piscsi
.PHONY: install
install: \
$(MAN_PAGE_DIR)/piscsi.1 \
$(MAN_PAGE_DIR)/scsictl.1 \
$(MAN_PAGE_DIR)/scsimon.1 \
$(MAN_PAGE_DIR)/scsiloop.1 \
$(MAN_PAGE_DIR)/scsidump.1 \
$(USR_LOCAL_BIN)/$(SCSICTL) \
$(USR_LOCAL_BIN)/$(PISCSI) \
$(USR_LOCAL_BIN)/$(SCSIMON) \
$(USR_LOCAL_BIN)/$(SCSILOOP) \
$(USR_LOCAL_BIN)/$(SCSIDUMP) \
$(MAN_PAGES) \
$(BINARIES) \
$(SYSTEMD_CONF) \
$(RSYSLOG_CONF) \
$(RSYSLOG_LOG)

View File

@ -337,7 +337,7 @@ bool CTapDriver::HasPendingPackets() const
fds.revents = 0;
poll(&fds, 1, 0);
spdlog::trace(to_string(fds.revents) + " revents");
return !(fds.revents & POLLIN);
return fds.revents & POLLIN;
}
// See https://stackoverflow.com/questions/21001659/crc32-algorithm-implementation-in-c-without-a-look-up-table-and-with-a-public-li

View File

@ -0,0 +1,56 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator PiSCSI
// for Raspberry Pi
//
// Powered by XM6 TypeG Technology.
// Copyright (C) 2016-2020 GIMONS
//
//---------------------------------------------------------------------------
#pragma once
#include <string>
//
// RaSCSI Adapter Aibom version
//
const std::string CONNECT_DESC = "AIBOM PRODUCTS version"; // Startup message
// Select signal control mode
const static int SIGNAL_CONTROL_MODE = 2; // SCSI positive logic specification
// Control signal output logic
#define ACT_ON ON // ACTIVE SIGNAL ON
#define ENB_ON ON // ENABLE SIGNAL ON
#define IND_IN OFF // INITIATOR SIGNAL INPUT
#define TAD_IN OFF // TARGET SIGNAL INPUT
#define DTD_IN OFF // DATA SIGNAL INPUT
// Control signal pin assignment (-1 means no control)
const static int PIN_ACT = 4; // ACTIVE
const static int PIN_ENB = 17; // ENABLE
const static int PIN_IND = 27; // INITIATOR CTRL DIRECTION
const static int PIN_TAD = -1; // TARGET CTRL DIRECTION
const static int PIN_DTD = 18; // DATA DIRECTION
// SCSI signal pin assignment
const static int PIN_DT0 = 6; // Data 0
const static int PIN_DT1 = 12; // Data 1
const static int PIN_DT2 = 13; // Data 2
const static int PIN_DT3 = 16; // Data 3
const static int PIN_DT4 = 19; // Data 4
const static int PIN_DT5 = 20; // Data 5
const static int PIN_DT6 = 26; // Data 6
const static int PIN_DT7 = 21; // Data 7
const static int PIN_DP = 5; // Data parity
const static int PIN_ATN = 22; // ATN
const static int PIN_RST = 25; // RST
const static int PIN_ACK = 10; // ACK
const static int PIN_REQ = 7; // REQ
const static int PIN_MSG = 9; // MSG
const static int PIN_CD = 11; // CD
const static int PIN_IO = 23; // IO
const static int PIN_BSY = 24; // BSY
const static int PIN_SEL = 8; // SEL

View File

@ -0,0 +1,56 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator PiSCSI
// for Raspberry Pi
//
// Powered by XM6 TypeG Technology.
// Copyright (C) 2016-2020 GIMONS
//
//---------------------------------------------------------------------------
#pragma once
#include <string>
//
// RaSCSI Adapter GAMERnium.com version
//
const std::string CONNECT_DESC = "GAMERnium.com version"; // Startup message
// Select signal control mode
const static int SIGNAL_CONTROL_MODE = 0; // SCSI logical specification
// Control signal output logic
#define ACT_ON ON // ACTIVE SIGNAL ON
#define ENB_ON ON // ENABLE SIGNAL ON
#define IND_IN OFF // INITIATOR SIGNAL INPUT
#define TAD_IN OFF // TARGET SIGNAL INPUT
#define DTD_IN ON // DATA SIGNAL INPUT
// Control signal pin assignment (-1 means no control)
const static int PIN_ACT = 14; // ACTIVE
const static int PIN_ENB = 6; // ENABLE
const static int PIN_IND = 7; // INITIATOR CTRL DIRECTION
const static int PIN_TAD = 8; // TARGET CTRL DIRECTION
const static int PIN_DTD = 5; // DATA DIRECTION
// SCSI signal pin assignment
const static int PIN_DT0 = 21; // Data 0
const static int PIN_DT1 = 26; // Data 1
const static int PIN_DT2 = 20; // Data 2
const static int PIN_DT3 = 19; // Data 3
const static int PIN_DT4 = 16; // Data 4
const static int PIN_DT5 = 13; // Data 5
const static int PIN_DT6 = 12; // Data 6
const static int PIN_DT7 = 11; // Data 7
const static int PIN_DP = 25; // Data parity
const static int PIN_ATN = 10; // ATN
const static int PIN_RST = 22; // RST
const static int PIN_ACK = 24; // ACK
const static int PIN_REQ = 15; // REQ
const static int PIN_MSG = 17; // MSG
const static int PIN_CD = 18; // CD
const static int PIN_IO = 4; // IO
const static int PIN_BSY = 27; // BSY
const static int PIN_SEL = 23; // SEL

View File

@ -18,6 +18,10 @@
#include "hal/connection_type/connection_standard.h"
#elif defined CONNECT_TYPE_FULLSPEC
#include "hal/connection_type/connection_fullspec.h"
#elif defined CONNECT_TYPE_AIBOM
#include "hal/connection_type/connection_aibom.h"
#elif defined CONNECT_TYPE_GAMERNIUM
#include "hal/connection_type/connection_gamernium.h"
#else
#error Invalid connection type or none specified
#endif
@ -102,4 +106,4 @@ class DataSample_Raspberry final : public DataSample
private:
uint32_t data = 0;
};
};

View File

@ -26,11 +26,17 @@
//---------------------------------------------------------------------------
//#define CONNECT_TYPE_STANDARD // Standard (SCSI logic, standard pin assignment)
//#define CONNECT_TYPE_FULLSPEC // Full spec (SCSI logic, standard pin assignment)
//#define CONNECT_TYPE_AIBOM // AIBOM version (positive logic, unique pin assignment)
//#define CONNECT_TYPE_GAMERNIUM // GAMERnium.com version (standard logic, unique pin assignment)
#if defined CONNECT_TYPE_STANDARD
#include "hal/connection_type/connection_standard.h"
#elif defined CONNECT_TYPE_FULLSPEC
#include "hal/connection_type/connection_fullspec.h"
#elif defined CONNECT_TYPE_AIBOM
#include "hal/connection_type/connection_aibom.h"
#elif defined CONNECT_TYPE_GAMERNIUM
#include "hal/connection_type/connection_gamernium.h"
#else
#error Invalid connection type or none specified
#endif

View File

@ -18,6 +18,10 @@
#include "hal/connection_type/connection_standard.h"
#elif defined CONNECT_TYPE_FULLSPEC
#include "hal/connection_type/connection_fullspec.h"
#elif defined CONNECT_TYPE_AIBOM
#include "hal/connection_type/connection_aibom.h"
#elif defined CONNECT_TYPE_GAMERNIUM
#include "hal/connection_type/connection_gamernium.h"
#else
#error Invalid connection type or none specified
#endif

View File

@ -948,6 +948,7 @@ function installSamba() {
# Installs and configures Webmin
function installWebmin() {
WEBMIN_PATH="/usr/share/webmin"
WEBMIN_MODULE_CONFIG="/etc/webmin/netatalk2/config"
WEBMIN_MODULE_VERSION="1.0"
if [ -d "$WEBMIN_PATH" ]; then
@ -968,14 +969,23 @@ function installWebmin() {
curl -o setup-repos.sh https://raw.githubusercontent.com/webmin/webmin/master/setup-repos.sh
sudo sh setup-repos.sh
rm setup-repos.sh
sudo apt-get install webmin --install-recommends
sudo apt-get install webmin --install-recommends </dev/null
echo
echo "Downloading and installing Webmin module..."
rm netatalk2-wbm.tgz || true
if [[ -f "$WEBMIN_MODULE_CONFIG" ]]; then
echo "$WEBMIN_MODULE_CONFIG already exists; will not modify..."
WEBMIN_MODULE_FLAG=1
fi
rm netatalk2-wbm.tgz 2> /dev/null || true
wget -O netatalk2-wbm.tgz "https://github.com/Netatalk/netatalk-webmin/releases/download/netatalk2-$WEBMIN_MODULE_VERSION/netatalk2-wbm-$WEBMIN_MODULE_VERSION.tgz" </dev/null
sudo /usr/share/webmin/install-module.pl netatalk2-wbm.tgz
sudo sed -i 's@/sbin@/local/sbin@' /etc/webmin/netatalk2/config
rm netatalk2-wbm.tgz
sudo "$WEBMIN_PATH/install-module.pl" netatalk2-wbm.tgz
if [[ ! $WEBMIN_MODULE_FLAG ]]; then
echo "Modifying $WEBMIN_MODULE_CONFIG..."
sudo sed -i 's@/usr/sbin@/usr/local/sbin@' "$WEBMIN_MODULE_CONFIG"
fi
rm netatalk2-wbm.tgz || true
}
# updates configuration files and installs packages needed for the OLED screen script

View File

@ -21,6 +21,11 @@ td {
margin: none;
}
th {
color: white;
background-color: black;
}
h1 {
color: white;
font-size: 20px;
@ -97,6 +102,10 @@ div.flash div.info {
background-color: #0d6efd;
}
div.flash > div a {
display: none;
}
td.inactive {
text-align: center;
background-color: tan;

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-book"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-home"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg>

Before

Width:  |  Height:  |  Size: 345 B

After

Width:  |  Height:  |  Size: 332 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-book"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path></svg>

Before

Width:  |  Height:  |  Size: 345 B

View File

@ -545,7 +545,7 @@ div.flash > div {
}
div.flash > div a {
display: inline-block !important;
display: inline-block;
padding: 0.25rem 0.75rem;
margin-left: auto;
color: #fff;
@ -948,27 +948,6 @@ section#system div.power-control {
}
}
/*
------------------------------------------------------------------------------
Index > Section: Manual
------------------------------------------------------------------------------
*/
section#manual {
margin: 2rem 0 1rem;
}
section#manual a {
margin: auto;
display: block;
padding: 0.25rem 0 0.25rem 2rem;
background: url("icons/manual.svg") no-repeat left center;
font-weight: bold;
}
section#manual a p {
margin: 0;
}
/*
------------------------------------------------------------------------------
Admin > Section: Services
@ -1072,3 +1051,18 @@ body.page-manpage div.content p.home {
margin-top: 2rem;
font-weight: bold;
}
/*
------------------------------------------------------------------------------
Base > Back
------------------------------------------------------------------------------
*/
a.back {
padding: 0.25rem 0 0.25rem 2rem;
font-weight: bold;
background: url("icons/home.svg") no-repeat left center;
}
a.back span.separator {
display: none;
}

View File

@ -189,6 +189,5 @@
</div>
</section>
<p class="home"><a href="/">{{ _("Go to Home") }}</a></p>
<hr/>
{% endblock content %}

View File

@ -95,7 +95,7 @@
{% else %}
<div>{{ message }}</div>
{% endif %}
<a style="display: none;" href="/"></a>
<a href="/"></a>
</div>
{% endfor %}
{% endif %}
@ -105,7 +105,15 @@
{{ content_class }}
{% block content %}{% endblock content %}
</div>
{% if not is_root_page %}
<div class="content">
<a class="back" href="/"><span class="separator">&lt;&lt; </span>{{ _("Go to Home") }}</a>
</div>
{% endif %}
<div align="center" class="footer">
<div>
<a href="/sys/manpage?app=piscsi">{{ _("Read the PiSCSI Manual") }}</a>
</div>
<div>
{{ _("PiSCSI software version:") }} <b>{{ env["version"] }}</b>
</div>

View File

@ -2,56 +2,38 @@
{% block content %}
<h2>{{ _("Detailed Info for Attached Devices") }}</h2>
{% for device in devices %}
<p>
<table border="black" cellpadding="3" summary="Detailed information for attached devices">
<tr>
<th scope="row">{{ _("SCSI ID") }}</th>
<td>{{ device["id"] }}</td>
</tr>
<tr>
<th scope="row">{{ _("LUN") }}</th>
<td>{{ device["unit"] }}</td>
</tr>
<tr>
<th scope="row">{{ _("Type") }}</th>
<td>{{ device["device_type"] }}</td>
</tr>
<tr>
<th scope="row">{{ _("Status") }}</th>
<td>{{ device["status"] }}</td>
</tr>
<tr>
<th scope="row">{{ _("File") }}</th>
<td>{{ device["image"] }}</td>
</tr>
<tr>
<th scope="row">{{ _("Parameters") }}</th>
<td>{{ device["params"] }}</td>
</tr>
<tr>
<th scope="row">{{ _("Vendor") }}</th>
<td>{{ device["vendor"] }}</td>
</tr>
<tr>
<th scope="row">{{ _("Product") }}</th>
<td>{{ device["product"] }}</td>
</tr>
<tr>
<th scope="row">{{ _("Revision") }}</th>
<td>{{ device["revision"] }}</td>
</tr>
<tr>
<th scope="row">{{ _("Block Size") }}</th>
<td>{{ device["block_size"] }}</td>
</tr>
<tr>
<th scope="row">{{ _("Image Size") }}</th>
</tr>
{% for device in devices %}
<tr>
<td>{{ device["id"] }}</td>
<td>{{ device["unit"] }}</td>
<td>{{ device["device_type"] }}</td>
<td>{{ device["status"] }}</td>
<td>{{ device["image"] }}</td>
<td>{{ device["params"] }}</td>
<td>{{ device["vendor"] }}</td>
<td>{{ device["product"] }}</td>
<td>{{ device["revision"] }}</td>
<td>{{ device["block_size"] }}</td>
<td>{{ device["size"] }}</td>
</tr>
{% endfor %}
</table>
</p>
{% endfor %}
<p class="home"><a href="/">{{ _("Go to Home") }}</a></p>
<hr/>
{% endblock content %}

View File

@ -3,6 +3,6 @@
{% block content %}
<h2>{{ _("Disk Image Details: %(file_name)s", file_name=file_name) }}</h2>
<p><pre>{{ diskinfo }}</pre></p>
<p class="home"><a href="/">{{ _("Go to Home") }}</a></p>
<hr/>
{% endblock content %}

View File

@ -112,6 +112,6 @@
</tbody>
</table>
<p><small>{{ _("%(disk_space)s MiB disk space remaining on the Pi", disk_space=env["free_disk_space"]) }}</small></p>
<p class="home"><a href="/">{{ _("Go to Home") }}</a></p>
<hr/>
{% endblock content %}

View File

@ -669,9 +669,4 @@
</section>
<hr/>
<section id="manual">
<a href="/sys/manpage?app=piscsi"><p>{{ _("Read the PiSCSI Manual") }}</p></a>
</section>
{% endblock content %}

View File

@ -2,7 +2,32 @@
{% block content %}
<h2>{{ _("System Logs: %(scope)s %(lines)s lines", scope=scope, lines=lines) }}</h2>
<div>
<form action="/logs/show" method="post">
<label for="log_lines">{{ _("Log Lines:") }}</label>
<input name="lines" id="log_lines" type="number" value="200" min="0" max="99999" step="100">
<label for="log_scope">{{ _("Scope:") }}</label>
<select name="scope" id="log_scope">
<option value="">
{{ _("All logs") }}
</option>
<option value="piscsi">
piscsi
</option>
<option value="piscsi-web">
piscsi-web
</option>
<option value="piscsi-oled">
piscsi-oled
</option>
<option value="piscsi-ctrlboard">
piscsi-ctrlboard
</option>
</select>
<input type="submit" value="{{ _("Show Logs") }}">
</form>
</div>
<p><pre>{{ logs }}</pre></p>
<p class="home"><a href="/">{{ _("Go to Home") }}</a></p>
<hr/>
{% endblock content %}

View File

@ -7,5 +7,5 @@
{{ manpage | safe }}
</div>
<p class="home"><a href="/">{{ _("Go to Home") }}</a></p>
<hr/>
{% endblock content %}

View File

@ -261,6 +261,7 @@ def index():
return response(
template="index.html",
page_title=_("PiSCSI Control Page"),
is_root_page=True,
netinfo=piscsi_cmd.get_network_info(),
bridge_configured=sys_cmd.is_bridge_setup(),
devices=formatted_devices,
@ -347,6 +348,7 @@ def upload_page():
return response(
template="upload.html",
page_title=_("PiSCSI File Upload"),
is_root_page=True,
images_subdirs=file_cmd.list_subdirs(server_info["image_dir"]),
shared_subdirs=file_cmd.list_subdirs(FILE_SERVER_DIR),
file_server_dir_exists=Path(FILE_SERVER_DIR).exists(),

View File

@ -298,9 +298,8 @@ def is_bridge_configured(interface):
return_msg = _(
"Configure the network bridge for %(interface)s first: ", interface=interface
)
return {"status": False, "msg": return_msg + ", ".join(to_configure)}
return {"status": True, "msg": return_msg}
return {"status": True, "msg": return_msg + ", ".join(to_configure)}
def is_safe_path(file_name):