All: Switch to Servd default on

See README for details on how to install Servd.
pull/86/head
Thomas Stoddard 2026-05-08 17:28:49 +00:00 committed by Kyle Schwarz
parent d45b72ef68
commit 7cca96dcfb
5 changed files with 30 additions and 3 deletions

View File

@ -4,6 +4,14 @@ libicsneo is the [Intrepid Control Systems](https://intrepidcs.com/) device
communication library. Installation and usage documentation can be found within communication library. Installation and usage documentation can be found within
each of the respective APIs. each of the respective APIs.
## Installation
libicsneo relies on Servd, IntrepidCS's device communication server.
Servd can be installed for all platforms from https://cdn.intrepidcs.net/servd/.
Instructions for installing each API can be found in its respective documentation.
## Documentation ## Documentation
- [C++](https://libicsneo.readthedocs.io/en/latest/icsneocpp/) - [C++](https://libicsneo.readthedocs.io/en/latest/icsneocpp/)

View File

@ -166,6 +166,8 @@ static constexpr const char* SERVD_RECV_ERROR = "Error receiving from Servd";
static constexpr const char* SERVD_POLL_ERROR = "Error polling on Servd socket"; static constexpr const char* SERVD_POLL_ERROR = "Error polling on Servd socket";
static constexpr const char* SERVD_NODATA_ERROR = "No data received from Servd"; static constexpr const char* SERVD_NODATA_ERROR = "No data received from Servd";
static constexpr const char* SERVD_JOIN_MULTICAST_ERROR = "Error joining Servd multicast group"; static constexpr const char* SERVD_JOIN_MULTICAST_ERROR = "Error joining Servd multicast group";
static constexpr const char* SERVD_NOT_REACHABLE = "Could not reach Servd; ensure it is installed and running";
static constexpr const char* SERVD_NO_DEVICES_FOUND = "Servd is running but no devices found";
// DXX // DXX
static constexpr const char* DXX_ERROR_SYS = "System error, check errno/GetLastError()"; static constexpr const char* DXX_ERROR_SYS = "System error, check errno/GetLastError()";
@ -438,6 +440,10 @@ const char* APIEvent::DescriptionForType(Type type) {
return SERVD_NODATA_ERROR; return SERVD_NODATA_ERROR;
case Type::ServdJoinMulticastError: case Type::ServdJoinMulticastError:
return SERVD_JOIN_MULTICAST_ERROR; return SERVD_JOIN_MULTICAST_ERROR;
case Type::ServdNotReachable:
return SERVD_NOT_REACHABLE;
case Type::ServdNoDevicesFound:
return SERVD_NO_DEVICES_FOUND;
// DXX // DXX
case Type::DXXErrorSys: case Type::DXXErrorSys:

View File

@ -126,6 +126,8 @@ void init_event(pybind11::module_& m) {
.value("ServdPollError", APIEvent::Type::ServdPollError) .value("ServdPollError", APIEvent::Type::ServdPollError)
.value("ServdNoDataError", APIEvent::Type::ServdNoDataError) .value("ServdNoDataError", APIEvent::Type::ServdNoDataError)
.value("ServdJoinMulticastError", APIEvent::Type::ServdJoinMulticastError) .value("ServdJoinMulticastError", APIEvent::Type::ServdJoinMulticastError)
.value("ServdNotReachable", APIEvent::Type::ServdNotReachable)
.value("ServdNoDevicesFound", APIEvent::Type::ServdNoDevicesFound)
.value("DXXErrorSys", APIEvent::Type::DXXErrorSys) .value("DXXErrorSys", APIEvent::Type::DXXErrorSys)
.value("DXXErrorInt", APIEvent::Type::DXXErrorInt) .value("DXXErrorInt", APIEvent::Type::DXXErrorInt)
.value("DXXErrorOverflow", APIEvent::Type::DXXErrorOverflow) .value("DXXErrorOverflow", APIEvent::Type::DXXErrorOverflow)

View File

@ -165,6 +165,8 @@ public:
ServdPollError = ServdBindError + 8, ServdPollError = ServdBindError + 8,
ServdNoDataError = ServdBindError + 9, ServdNoDataError = ServdBindError + 9,
ServdJoinMulticastError = ServdBindError + 10, ServdJoinMulticastError = ServdBindError + 10,
ServdNotReachable = ServdBindError + 11,
ServdNoDevicesFound = ServdBindError + 12,
// DXX // DXX
DXXErrorSys = 0x6100, DXXErrorSys = 0x6100,

View File

@ -20,7 +20,7 @@ bool Servd::Enabled() {
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)
#endif #endif
return enabled ? enabled[0] == '1' : false; return enabled ? enabled[0] == '1' : true;
} }
std::vector<std::string> split(const std::string_view& str, char delim = ' ') { std::vector<std::string> split(const std::string_view& str, char delim = ' ') {
@ -52,7 +52,7 @@ void Servd::Find(std::vector<FoundDevice>& found) {
response.resize(512); response.resize(512);
const std::string version_request = SERVD_VERSION_STR + " version"; const std::string version_request = SERVD_VERSION_STR + " version";
if(!socket.transceive(version_request, response, std::chrono::milliseconds(5000))) { if(!socket.transceive(version_request, response, std::chrono::milliseconds(5000))) {
EventManager::GetInstance().add(APIEvent::Type::ServdTransceiveError, APIEvent::Severity::Error); EventManager::GetInstance().add(APIEvent::Type::ServdNotReachable, APIEvent::Severity::Error);
return; return;
} }
@ -67,11 +67,16 @@ void Servd::Find(std::vector<FoundDevice>& found) {
EventManager::GetInstance().add(APIEvent::Type::ServdTransceiveError, APIEvent::Severity::Error); EventManager::GetInstance().add(APIEvent::Type::ServdTransceiveError, APIEvent::Severity::Error);
return; return;
} }
const size_t preCount = found.size();
bool parseError = false;
const auto lines = split(response, '\n'); const auto lines = split(response, '\n');
for(auto&& line : lines) { for(auto&& line : lines) {
const auto cols = split(line, ' '); const auto cols = split(line, ' ');
if(cols.size() < 3) { if(cols.size() < 3) {
EventManager::GetInstance().add(APIEvent::Type::ServdInvalidResponseError, APIEvent::Severity::Error); if(!line.empty()) {
EventManager::GetInstance().add(APIEvent::Type::ServdInvalidResponseError, APIEvent::Severity::Error);
parseError = true;
}
continue; continue;
} }
const auto& serial = cols[0]; const auto& serial = cols[0];
@ -81,6 +86,7 @@ void Servd::Find(std::vector<FoundDevice>& found) {
port = static_cast<uint16_t>(std::stoi(cols[2])); port = static_cast<uint16_t>(std::stoi(cols[2]));
} catch (const std::exception&) { } catch (const std::exception&) {
EventManager::GetInstance().add(APIEvent::Type::ServdInvalidResponseError, APIEvent::Severity::Error); EventManager::GetInstance().add(APIEvent::Type::ServdInvalidResponseError, APIEvent::Severity::Error);
parseError = true;
continue; continue;
} }
Address address(ip.c_str(), port); Address address(ip.c_str(), port);
@ -90,6 +96,9 @@ void Servd::Find(std::vector<FoundDevice>& found) {
return std::make_unique<Servd>(err, forDevice, address); return std::make_unique<Servd>(err, forDevice, address);
}; };
} }
if(!parseError && found.size() == preCount) {
EventManager::GetInstance().add(APIEvent::Type::ServdNoDevicesFound, APIEvent::Severity::EventInfo);
}
} }
Servd::Servd(const device_eventhandler_t& err, neodevice_t& forDevice, const Address& address) : Servd::Servd(const device_eventhandler_t& err, neodevice_t& forDevice, const Address& address) :