Skip to content

Commit

Permalink
scpiclient: add IP address functions
Browse files Browse the repository at this point in the history
  • Loading branch information
willeccles committed May 14, 2024
1 parent 56284e1 commit 795aa77
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 0 deletions.
5 changes: 5 additions & 0 deletions include/bci/abs/CommonTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ struct DeviceInfo {
std::string version;
};

struct EthernetConfig {
std::string ip;
std::string netmask;
};

struct ScpiError {
std::int16_t err_code;
std::string err_msg;
Expand Down
4 changes: 4 additions & 0 deletions include/bci/abs/ScpiClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ class ScpiClient {

Result<std::uint8_t> GetDeviceId() const;

Result<EthernetConfig> GetIPAddress() const;

ErrorCode SetIPAddress(std::string_view ip, std::string_view netmask) const;

Result<std::string> GetCalibrationDate() const;

Result<int> GetErrorCount() const;
Expand Down
26 changes: 26 additions & 0 deletions src/ScpiClient_System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,32 @@ Result<std::uint8_t> ScpiClient::GetDeviceId() const {
.and_then(scpi::ParseIntResponse<std::uint8_t>);
}

Result<EthernetConfig> ScpiClient::GetIPAddress() const {
auto resp = SendAndRecv("CONF:COMM:SOCK:ADDR?\r\n")
.and_then(scpi::ParseStringArrayResponse<2>);
if (!resp) {
return Err(resp.error());
}
return EthernetConfig{std::move(resp->at(0)), std::move(resp->at(1))};
}

ErrorCode ScpiClient::SetIPAddress(std::string_view ip,
std::string_view netmask) const {
if (ip.size() > 15 || netmask.size() > 15) {
return ec::kInvalidIPAddress;
}

if (ip.find('"') != ip.npos || netmask.find('"') != ip.npos) {
return ec::kInvalidIPAddress;
}

char buf[128]{};
fmt::format_to_n(buf, sizeof(buf) - 1,
"CONF:COMM:SOCK:ADDR \"{}\",\"{}\"\r\n", ip, netmask);

return Send(buf);
}

Result<std::string> ScpiClient::GetCalibrationDate() const {
return SendAndRecv("CAL:DATE?\r\n").and_then(scpi::ParseStringResponse);
}
Expand Down
38 changes: 38 additions & 0 deletions src/ScpiUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,44 @@ std::optional<std::string> ParseQuotedString(std::string_view str) {
return ret;
}

std::optional<std::string> ParseQuotedStringUntil(std::string_view str,
std::string_view& suffix) {
str = util::Trim(str);
if (str.size() < 2) {
return std::nullopt;
}

const char delim = str[0];
if (delim != '"' && delim != '\'') {
return std::nullopt;
}

str.remove_prefix(1);

std::string ret;

for (std::size_t i = 0; i < str.size(); ++i) {
if (str[i] != delim) {
ret += str[i];
} else {
if (i < str.size() - 1) {
if (str[i + 1] == delim) {
ret += str[i];
++i;
} else {
suffix = str.substr(i + 1);
break;
}
} else {
suffix = {};
break;
}
}
}

return ret;
}

Result<std::string> ParseStringResponse(std::string_view str) {
auto e = ParseQuotedString(util::Trim(str));
if (e) {
Expand Down
28 changes: 28 additions & 0 deletions src/ScpiUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,10 +318,38 @@ constexpr Result<std::array<CellMode, kLen>> ParseCellOperatingModeArray(
// Parse quoted SCPI <String> data.
std::optional<std::string> ParseQuotedString(std::string_view str);

// Parse a quoted string, but return a string view containing the rest of the
// string, if any.
std::optional<std::string> ParseQuotedStringUntil(std::string_view str,
std::string_view& suffix);

Result<std::string> ParseStringResponse(std::string_view str);

Result<ScpiError> ParseScpiError(std::string_view str);

template <std::size_t kLen>
static Result<std::array<std::string, kLen>> ParseStringArrayResponse(
std::string_view str) {
std::array<std::string, kLen> res{};
for (std::size_t i = 0; i < kLen; ++i) {
std::string_view suffix;
if (auto s = ParseQuotedStringUntil(str, suffix)) {
res[i] = *std::move(s);
if (i < kLen - 1) {
suffix = util::Trim(suffix);
if (suffix.empty() || suffix[0] != ',') {
return util::Err(ErrorCode::kInvalidResponse);
}
suffix.remove_prefix(1);
str = suffix;
}
} else {
return util::Err(ErrorCode::kInvalidResponse);
}
}
return res;
}

} // namespace bci::abs::scpi

#endif /* ABS_SCPI_DRIVER_SRC_SCPIUTIL_H */

0 comments on commit 795aa77

Please sign in to comment.