Skip to content

Commit

Permalink
feat: add WIP C interface
Browse files Browse the repository at this point in the history
  • Loading branch information
willeccles committed May 15, 2024
1 parent caff705 commit 48c51df
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 0 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ add_library(bciabs_scpi
src/ScpiClient_AuxIO.cpp
src/Discovery.cpp
src/Errors.cpp
src/CInterface.cpp
)
add_library(bci::abs-scpi ALIAS bciabs_scpi)

Expand Down
27 changes: 27 additions & 0 deletions include/bci/abs/CInterface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef ABS_SCPI_DRIVER_INCLUDE_BCI_ABS_CINTERFACE_H
#define ABS_SCPI_DRIVER_INCLUDE_BCI_ABS_CINTERFACE_H

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

typedef void* AbsScpiClientHandle;

int AbsScpiClient_Init(AbsScpiClientHandle* handle_out);

void AbsScpiClient_Destroy(AbsScpiClientHandle* handle);

int ScpiClient_OpenUdp(AbsScpiClientHandle handle, const char* local_ip,
const char* target_ip);

int ScpiClient_SetCellVoltage(AbsScpiClientHandle handle, unsigned int cell,
float voltage);

int ScpiClient_GetCellVoltageTarget(AbsScpiClientHandle handle,
unsigned int cell, float* voltage_out);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* ABS_SCPI_DRIVER_INCLUDE_BCI_ABS_CINTERFACE_H */
88 changes: 88 additions & 0 deletions src/CInterface.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include <bci/abs/CInterface.h>
#include <bci/abs/ScpiClient.h>
#include <bci/abs/UdpDriver.h>

#include <memory>

using namespace bci::abs;
using ec = bci::abs::ErrorCode;

static ScpiClient& GetClient(AbsScpiClientHandle handle) {
return *(ScpiClient*)handle;
}

template <class... Args>
static int WrapSet(ErrorCode (ScpiClient::*func)(Args...) const,
AbsScpiClientHandle handle, Args... args) {
if (!handle || !func) {
return static_cast<int>(ec::kInvalidArgument);
}

return static_cast<int>((GetClient(handle).*func)(args...));
}

template <class T, class... Args>
static int WrapGet(Result<T> (ScpiClient::*func)(Args...) const,
AbsScpiClientHandle handle, T* res, Args... args) {
if (!handle || !func || !res) {
return static_cast<int>(ec::kInvalidArgument);
}

ec err = ec::kSuccess;
if (auto result = (GetClient(handle).*func)(args...)) {
*res = *result;
} else {
err = result.error();
}

return static_cast<int>(err);
}

int AbsScpiClient_Init(AbsScpiClientHandle* handle_out) {
if (!handle_out) {
return static_cast<int>(ec::kInvalidArgument);
}

ScpiClient*& client_ptr = *(ScpiClient**)handle_out;
if (client_ptr) {
// TODO
}

client_ptr = new ScpiClient();

return static_cast<int>(ec::kSuccess);
}

void AbsScpiClient_Destroy(AbsScpiClientHandle* handle) {
if (handle) {
delete (ScpiClient*)*handle;
*handle = nullptr;
}
}

int ScpiClient_OpenUdp(AbsScpiClientHandle handle, const char* local_ip,
const char* target_ip) {
if (!handle) {
return static_cast<int>(ec::kInvalidArgument);
}

// TODO: what's the behavior if it's already got an open driver and this
// fails?
auto driver = std::make_shared<drivers::UdpDriver>();
ec ret = driver->Open(local_ip, target_ip);
if (ret == ec::kSuccess) {
GetClient(handle).SetDriver(driver);
}

return static_cast<int>(ret);
}

int ScpiClient_SetCellVoltage(AbsScpiClientHandle handle, unsigned int cell,
float voltage) {
return WrapSet(&ScpiClient::SetCellVoltage, handle, cell, voltage);
}

int ScpiClient_GetCellVoltageTarget(AbsScpiClientHandle handle,
unsigned int cell, float* voltage_out) {
return WrapGet(&ScpiClient::GetCellVoltageTarget, handle, voltage_out, cell);
}

0 comments on commit 48c51df

Please sign in to comment.