Skip to content

Commit

Permalink
add config_board_with_bytes method which is not recommended to use (#692
Browse files Browse the repository at this point in the history
)

Signed-off-by: Andrey Parfenov <a1994ndrey@gmail.com>
  • Loading branch information
Andrey1994 committed Dec 25, 2023
1 parent dd90d0f commit 1c2fde9
Show file tree
Hide file tree
Showing 18 changed files with 187 additions and 1 deletion.
9 changes: 9 additions & 0 deletions cpp_package/src/board_shim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,15 @@ std::string BoardShim::config_board (std::string config)
return resp;
}

void BoardShim::config_board_with_bytes (const char *bytes, int len)
{
int res = ::config_board_with_bytes (bytes, len, board_id, serialized_params.c_str ());
if (res != (int)BrainFlowExitCodes::STATUS_OK)
{
throw BrainFlowException ("failed to config board with bytes", res);
}
}

void BoardShim::insert_marker (double value, int preset)
{
int res = ::insert_marker (value, preset, board_id, serialized_params.c_str ());
Expand Down
2 changes: 2 additions & 0 deletions cpp_package/src/inc/board_shim.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,8 @@ class BoardShim
BrainFlowArray<double, 2> get_board_data (int num_datapoints, int preset);
/// send string to a board, use it carefully and only if you understand what you are doing
std::string config_board (std::string config);
/// send raw bytes to a board, not implemented for majority of devices, not recommended to use
void config_board_with_bytes (const char *bytes, int len);
/// insert marker in data stream
void insert_marker (double value, int preset = (int)BrainFlowPresets::DEFAULT_PRESET);
};
17 changes: 17 additions & 0 deletions csharp_package/brainflow/brainflow/board_controller_library.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ public static class BoardControllerLibrary64
[DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int config_board (string config, byte[] response, int[] len, int board_id, string input_json);
[DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int config_board_with_bytes (byte[] bytes, int len, int board_id, string input_json);
[DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int set_log_file_board_controller (string log_file);
[DllImport ("BoardController", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int get_sampling_rate (int board_id, int preset, int[] sampling_rate);
Expand Down Expand Up @@ -231,6 +233,8 @@ public static class BoardControllerLibrary32
[DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int config_board (string config, byte[] response, int[] len, int board_id, string input_json);
[DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int config_board_with_bytes (byte[] bytes, int len, int board_id, string input_json);
[DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int set_log_file_board_controller (string log_file);
[DllImport ("BoardController32", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int get_sampling_rate (int board_id, int preset, int[] sampling_rate);
Expand Down Expand Up @@ -456,6 +460,19 @@ public static int config_board (string config, byte[] str, int[] len, int board_
return (int)BrainFlowExitCodes.GENERAL_ERROR;
}

public static int config_board_with_bytes (byte[] bytes, int len, int board_id, string input_json)
{
switch (PlatformHelper.get_library_environment ())
{
case LibraryEnvironment.x64:
return BoardControllerLibrary64.config_board_with_bytes (bytes, len, board_id, input_json);
case LibraryEnvironment.x86:
return BoardControllerLibrary32.config_board_with_bytes (bytes, len, board_id, input_json);
}

return (int)BrainFlowExitCodes.GENERAL_ERROR;
}

public static int add_streamer (string streamer, int preset, int board_id, string input_json)
{
switch (PlatformHelper.get_library_environment ())
Expand Down
13 changes: 13 additions & 0 deletions csharp_package/brainflow/brainflow/board_shim.cs
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,19 @@ public string config_board (string config)
string response = System.Text.Encoding.UTF8.GetString (str, 0, len[0]);
return response;
}

/// <summary>
/// send raw bytes to device, dont use it
/// </summary>
/// <param name="bytes"></param>
public void config_board_with_bytes (byte[] bytes)
{
int res = BoardControllerLibrary.config_board_with_bytes (bytes, bytes.Length, board_id, input_json);
if (res != (int)BrainFlowExitCodes.STATUS_OK)
{
throw new BrainFlowError (res);
}
}

/// <summary>
/// add streamer
Expand Down
14 changes: 14 additions & 0 deletions java_package/brainflow/src/main/java/brainflow/BoardShim.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ private interface DllInterface extends Library

int config_board (String config, byte[] names, int[] len, int board_id, String params);

int config_board_with_bytes (byte[] bytes, int len, int board_id, String params);

int add_streamer (String streamer, int preset, int board_id, String params);

int delete_streamer (String streamer, int preset, int board_id, String params);
Expand Down Expand Up @@ -1417,6 +1419,18 @@ public String config_board (String config) throws BrainFlowError
return resp;
}

/**
* send string to a board, dont use it
*/
public void config_board_with_bytes (byte[] bytes) throws BrainFlowError
{
int ec = instance.config_board_with_bytes (bytes, bytes.length, board_id, input_json);
if (ec != BrainFlowExitCode.STATUS_OK.get_code ())
{
throw new BrainFlowError ("Error in config_board", ec);
}
}

/**
* start streaming thread, store data in internal ringbuffer and stream them
* from brainflow at the same time
Expand Down
5 changes: 5 additions & 0 deletions julia_package/brainflow/src/board_shim.jl
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,11 @@ end
return sub_string
end

@brainflow_rethrow function config_board_with_bytes(bytes::Vector{Cuchar}, len::Integer, board_shim::BoardShim)
ccall((:config_board_with_bytes, BOARD_CONTROLLER_INTERFACE), Cint, (Ptr{UInt8}, Cint, Cint, Ptr{UInt8}),
bytes, len, board_shim.board_id, board_shim.input_json)
end

@brainflow_rethrow function get_board_data(num_samples::Integer, board_shim::BoardShim, preset::PresetType=Integer(DEFAULT_PRESET))
data_size = get_board_data_count(board_shim, preset)
if num_samples < 0
Expand Down
8 changes: 8 additions & 0 deletions matlab_package/brainflow/BoardShim.m
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,14 @@ function prepare_session(obj)
[exit_code, tmp, response] = calllib(lib_name, task_name, config, blanks(4096), 4096, obj.board_id, obj.input_params_json);
BoardShim.check_ec(exit_code, task_name);
end

function config_board_with_bytes(obj, bytes)
% send bytes to the board, do not use it
task_name = 'config_board_with_bytes';
lib_name = BoardShim.load_lib();
exit_code = calllib(lib_name, task_name, bytes, size(bytes, 2), obj.board_id, obj.input_params_json);
BoardShim.check_ec(exit_code, task_name);
end

function add_streamer(obj, streamer, preset)
% add streamer
Expand Down
11 changes: 11 additions & 0 deletions nodejs_package/brainflow/board_shim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class BoardControllerDLL extends BoardControllerFunctions
this.prepareSession = this.lib.func(CLike.prepare_session);
this.startStream = this.lib.func(CLike.start_stream);
this.configBoard = this.lib.func(CLike.config_board);
this.configBoardWithBytes = this.lib.func(CLike.config_board_with_bytes);
this.getBoardDataCount = this.lib.func(CLike.get_board_data_count);
this.getBoardData = this.lib.func(CLike.get_board_data);
this.getCurrentBoardData = this.lib.func(CLike.get_current_board_data);
Expand Down Expand Up @@ -285,6 +286,16 @@ export class BoardShim
return out[0].substring(0, len[0]);
}

public configBoardWithBytes(config: string, len: number): void
{
const res = BoardControllerDLL.getInstance().configBoardWithBytes(
config, len, this.boardId, this.inputJson);
if (res !== BrainFlowExitCodes.STATUS_OK)
{
throw new BrainFlowError (res, 'Could not config board with bytes');
}
}

public getBoardDataCount(preset = BrainFlowPresets.DEFAULT_PRESET): number
{
const dataSize = [0];
Expand Down
8 changes: 8 additions & 0 deletions nodejs_package/brainflow/functions.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ export enum BoardControllerCLikeFunctions {
'int add_streamer (const char *streamer, int preset, int board_id, const char *json_brainflow_input_params)',
config_board =
'int config_board (const char *config, _Inout_ char *response, _Inout_ int *resp_len, int board_id, const char *json_brainflow_input_params)',
config_board_with_bytes =
'int config_board_with_bytes (const char *bytes, int len, int board_id, const char *json_brainflow_input_params)',
delete_streamer =
'int delete_streamer (const char *streamer, int preset, int board_id, const char *json_brainflow_input_params)',
insert_marker =
Expand Down Expand Up @@ -139,6 +141,12 @@ export class BoardControllerFunctions
boardId: BoardIds,
inputJson: string,
) => BrainFlowExitCodes;
configBoardWithBytes!: (
config: string,
len: number,
boardId: BoardIds,
inputJson: string,
) => BrainFlowExitCodes;
getBoardDataCount!: (
preset: BrainFlowPresets,
dataSize: number[],
Expand Down
21 changes: 20 additions & 1 deletion python_package/brainflow/board_shim.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,15 @@ def __init__(self):
ctypes.c_char_p
]

self.config_board_with_bytes = self.lib.config_board_with_bytes
self.config_board_with_bytes.restype = ctypes.c_int
self.config_board_with_bytes.argtypes = [
ndpointer(ctypes.c_ubyte),
ctypes.c_int,
ctypes.c_int,
ctypes.c_char_p
]

self.get_sampling_rate = self.lib.get_sampling_rate
self.get_sampling_rate.restype = ctypes.c_int
self.get_sampling_rate.argtypes = [
Expand Down Expand Up @@ -1360,7 +1369,7 @@ def get_board_data(self, num_samples=None, preset: int = BrainFlowPresets.DEFAUL

return data_arr.reshape(package_length, data_size)

def config_board(self, config) -> None:
def config_board(self, config) -> str:
"""Use this method carefully and only if you understand what you are doing, do NOT use it to start or stop streaming
:param config: string to send to a board
Expand All @@ -1380,3 +1389,13 @@ def config_board(self, config) -> None:
if res != BrainFlowExitCodes.STATUS_OK.value:
raise BrainFlowError('unable to config board', res)
return string.tobytes().decode('utf-8')[0:string_len[0]]

def config_board_with_bytes(self, bytes_to_send) -> None:
"""Use this method carefully and only if you understand what you are doing
:param bytes_to_send: bytes to send
:type config: ndarray astype(numpy.ubyte)
"""
res = BoardControllerDLL.get_instance().config_board_with_bytes(bytes_to_send, len(bytes_to_send), self.board_id, self.input_json)
if res != BrainFlowExitCodes.STATUS_OK.value:
raise BrainFlowError('unable to config board', res)
19 changes: 19 additions & 0 deletions python_package/examples/tests/config_board_with_bytes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import numpy

from brainflow.board_shim import BoardShim, BrainFlowInputParams, BoardIds


def main():
BoardShim.enable_dev_board_logger()

params = BrainFlowInputParams()
board = BoardShim(BoardIds.SYNTHETIC_BOARD, params)
board.prepare_session()
config = numpy.zeros(4).astype(numpy.ubyte)
config[1] = 3
board.config_board_with_bytes(config)
board.release_session()


if __name__ == "__main__":
main()
13 changes: 13 additions & 0 deletions rust_package/brainflow/src/board_shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,19 @@ impl BoardShim {
.to_string())
}

/// Use this method carefully and only if you understand what you are doing.
pub fn config_board_with_bytes(&self, bytes: Vec<i8>) -> Result<()> {
let res = unsafe {
board_controller::config_board_with_bytes(
bytes.as_ptr(),
bytes.len() as c_int,
self.board_id as c_int,
self.json_brainflow_input_params.as_ptr(),
)
};
Ok(check_brainflow_exit_code(res)?)
}

/// Insert Marker to Data Stream.
pub fn insert_marker(&self, value: f64, preset: BrainFlowPresets) -> Result<()> {
let res = unsafe {
Expand Down
8 changes: 8 additions & 0 deletions rust_package/brainflow/src/ffi/board_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,14 @@ extern "C" {
json_brainflow_input_params: *const ::std::os::raw::c_char,
) -> ::std::os::raw::c_int;
}
extern "C" {
pub fn config_board_with_bytes(
bytes: *const ::std::os::raw::c_char,
len: ::std::os::raw::c_int,
board_id: ::std::os::raw::c_int,
json_brainflow_input_params: *const ::std::os::raw::c_char,
) -> ::std::os::raw::c_int;
}
extern "C" {
pub fn is_prepared(
prepared: *mut ::std::os::raw::c_int,
Expand Down
19 changes: 19 additions & 0 deletions src/board_controller/board_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,25 @@ int config_board (const char *config, char *response, int *response_len, int boa
return res;
}

int config_board_with_bytes (
const char *bytes, int len, int board_id, const char *json_brainflow_input_params)
{
std::lock_guard<std::mutex> lock (mutex);
if ((bytes == NULL) || (len < 1))
{
return (int)BrainFlowExitCodes::INVALID_ARGUMENTS_ERROR;
}

std::pair<int, struct BrainFlowInputParams> key;
int res = check_board_session (board_id, json_brainflow_input_params, key, false);
if (res != (int)BrainFlowExitCodes::STATUS_OK)
{
return res;
}
auto board_it = boards.find (key);
return board_it->second->config_board_with_bytes (bytes, len);
}

int add_streamer (
const char *streamer, int preset, int board_id, const char *json_brainflow_input_params)
{
Expand Down
7 changes: 7 additions & 0 deletions src/board_controller/inc/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ class Board
virtual int release_session () = 0;
virtual int config_board (std::string config, std::string &response) = 0;

// some devices may implement it but there is no requirement to have this method and we do not
// recommend anybody to use it
virtual int config_board_with_bytes (const char *bytes, int len)
{
return (int)BrainFlowExitCodes::UNSUPPORTED_BOARD_ERROR;
}

int get_current_board_data (
int num_samples, int preset, double *data_buf, int *returned_samples);
int get_board_data_count (int preset, int *result);
Expand Down
2 changes: 2 additions & 0 deletions src/board_controller/inc/board_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ extern "C"
double *data_buf, int board_id, const char *json_brainflow_input_params);
SHARED_EXPORT int CALLING_CONVENTION config_board (const char *config, char *response,
int *response_len, int board_id, const char *json_brainflow_input_params);
SHARED_EXPORT int CALLING_CONVENTION config_board_with_bytes (
const char *bytes, int len, int board_id, const char *json_brainflow_input_params);
SHARED_EXPORT int CALLING_CONVENTION is_prepared (
int *prepared, int board_id, const char *json_brainflow_input_params);
SHARED_EXPORT int CALLING_CONVENTION insert_marker (
Expand Down
1 change: 1 addition & 0 deletions src/board_controller/inc/synthetic_board.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ class SyntheticBoard : public Board
int stop_stream ();
int release_session ();
int config_board (std::string config, std::string &response);
int config_board_with_bytes (const char *bytes, int len);
};
11 changes: 11 additions & 0 deletions src/board_controller/synthetic_board.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,3 +258,14 @@ int SyntheticBoard::config_board (std::string config, std::string &response)
response = "Config:" + config;
return (int)BrainFlowExitCodes::STATUS_OK;
}

// if you use this board as a reference, more likely you dont need to implement this method
int SyntheticBoard::config_board_with_bytes (const char *bytes, int len)
{
safe_logger (spdlog::level::info, "config_board_with_bytes for len: {}", len);
for (int i = 0; i < len; i++)
{
safe_logger (spdlog::level::trace, "byte: {} value: {}", i, (int)bytes[i]);
}
return (int)BrainFlowExitCodes::STATUS_OK;
}

0 comments on commit 1c2fde9

Please sign in to comment.