C2: Add icsneoc2_device_reconnect
parent
97a6b4a04f
commit
5b553b63d3
|
|
@ -43,7 +43,7 @@ bool safe_str_copy(char* dest, size_t* dest_size, std::string_view src) {
|
||||||
}
|
}
|
||||||
|
|
||||||
icsneoc2_error_t icsneoc2_error_code_get(icsneoc2_error_t error_code, char* value, size_t* value_length) {
|
icsneoc2_error_t icsneoc2_error_code_get(icsneoc2_error_t error_code, char* value, size_t* value_length) {
|
||||||
static const char* error_strings[icsneoc2_error_maxsize] = {
|
static const char* error_strings[] = {
|
||||||
"Success", // icsneoc2_error_success
|
"Success", // icsneoc2_error_success
|
||||||
"Invalid function parameters", // icsneoc2_error_invalid_parameters
|
"Invalid function parameters", // icsneoc2_error_invalid_parameters
|
||||||
"Open failed", // icsneoc2_error_open_failed
|
"Open failed", // icsneoc2_error_open_failed
|
||||||
|
|
@ -66,6 +66,8 @@ icsneoc2_error_t icsneoc2_error_code_get(icsneoc2_error_t error_code, char* valu
|
||||||
"Script clear failed", // icsneoc2_error_script_clear_failed
|
"Script clear failed", // icsneoc2_error_script_clear_failed
|
||||||
"Script upload failed", // icsneoc2_error_script_upload_failed
|
"Script upload failed", // icsneoc2_error_script_upload_failed
|
||||||
"Script load prepare failed", // icsneoc2_error_script_load_prepare_failed
|
"Script load prepare failed", // icsneoc2_error_script_load_prepare_failed
|
||||||
|
"Close failed", // icsneoc2_error_close_failed
|
||||||
|
"Reconnect failed", // icsneoc2_error_reconnect_failed
|
||||||
};
|
};
|
||||||
static_assert(std::size(error_strings) == icsneoc2_error_maxsize,
|
static_assert(std::size(error_strings) == icsneoc2_error_maxsize,
|
||||||
"error_strings is out of sync with _icsneoc2_error_t enum - update both together");
|
"error_strings is out of sync with _icsneoc2_error_t enum - update both together");
|
||||||
|
|
@ -194,37 +196,27 @@ icsneoc2_error_t icsneoc2_device_is_open(const icsneoc2_device_t* device, bool*
|
||||||
return icsneoc2_error_success;
|
return icsneoc2_error_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
icsneoc2_error_t icsneoc2_device_is_disconnected(const icsneoc2_device_t* device, bool* is_disconnected) {
|
icsneoc2_error_t icsneoc2_device_create(const icsneoc2_device_info_t* device_info, icsneoc2_device_t** device) {
|
||||||
auto res = icsneoc2_device_is_valid(device);
|
if(!device_info || !device_info->device || !device) {
|
||||||
if(res != icsneoc2_error_success) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
if(!is_disconnected) {
|
|
||||||
return icsneoc2_error_invalid_parameters;
|
return icsneoc2_error_invalid_parameters;
|
||||||
}
|
}
|
||||||
auto dev = device->device;
|
auto* new_device = new (std::nothrow) icsneoc2_device_t;
|
||||||
*is_disconnected = dev->isDisconnected();
|
if(!new_device) {
|
||||||
|
|
||||||
return icsneoc2_error_success;
|
|
||||||
}
|
|
||||||
|
|
||||||
static icsneoc2_error_t open_device_with_options(std::shared_ptr<Device> dev, icsneoc2_open_options_t options, icsneoc2_device_t** device) {
|
|
||||||
if(!dev) {
|
|
||||||
return icsneoc2_error_invalid_device;
|
|
||||||
}
|
|
||||||
// Nothing to do if already open
|
|
||||||
if(dev->isOpen()) {
|
|
||||||
*device = new (std::nothrow) icsneoc2_device_t;
|
|
||||||
if(!*device) {
|
|
||||||
return icsneoc2_error_out_of_memory;
|
return icsneoc2_error_out_of_memory;
|
||||||
}
|
}
|
||||||
(*device)->device = dev;
|
new_device->device = device_info->device;
|
||||||
|
*device = new_device;
|
||||||
return icsneoc2_error_success;
|
return icsneoc2_error_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static icsneoc2_error_t open_device_with_options(std::shared_ptr<Device> dev, icsneoc2_open_options_t options) {
|
||||||
|
if(!dev) {
|
||||||
|
return icsneoc2_error_invalid_device;
|
||||||
|
}
|
||||||
if(!dev->enableMessagePolling(std::make_optional<MessageFilter>())) {
|
if(!dev->enableMessagePolling(std::make_optional<MessageFilter>())) {
|
||||||
return icsneoc2_error_enable_message_polling_failed;
|
return icsneoc2_error_enable_message_polling_failed;
|
||||||
}
|
}
|
||||||
if(!dev->open()) {
|
if(!dev->isOpen() && !dev->open()) {
|
||||||
return icsneoc2_error_open_failed;
|
return icsneoc2_error_open_failed;
|
||||||
}
|
}
|
||||||
if((options & ICSNEOC2_OPEN_OPTIONS_SYNC_RTC) && !dev->setRTC(std::chrono::system_clock::now())) {
|
if((options & ICSNEOC2_OPEN_OPTIONS_SYNC_RTC) && !dev->setRTC(std::chrono::system_clock::now())) {
|
||||||
|
|
@ -235,23 +227,15 @@ static icsneoc2_error_t open_device_with_options(std::shared_ptr<Device> dev, ic
|
||||||
dev->close();
|
dev->close();
|
||||||
return icsneoc2_error_go_online_failed;
|
return icsneoc2_error_go_online_failed;
|
||||||
}
|
}
|
||||||
*device = new (std::nothrow) icsneoc2_device_t;
|
|
||||||
if(!*device) {
|
|
||||||
dev->close();
|
|
||||||
return icsneoc2_error_out_of_memory;
|
|
||||||
}
|
|
||||||
(*device)->device = dev;
|
|
||||||
return icsneoc2_error_success;
|
return icsneoc2_error_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
icsneoc2_error_t icsneoc2_device_open(const icsneoc2_device_info_t* device_info, icsneoc2_open_options_t options, icsneoc2_device_t** device) {
|
icsneoc2_error_t icsneoc2_device_open(const icsneoc2_device_t* device, icsneoc2_open_options_t options) {
|
||||||
if(!device_info || !device) {
|
auto res = icsneoc2_device_is_valid(device);
|
||||||
return icsneoc2_error_invalid_parameters;
|
if(res != icsneoc2_error_success) {
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
if(!device_info->device) {
|
return open_device_with_options(device->device, options);
|
||||||
return icsneoc2_error_invalid_device;
|
|
||||||
}
|
|
||||||
return open_device_with_options(device_info->device, options, device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
icsneoc2_error_t icsneoc2_device_open_serial(const char* serial, icsneoc2_open_options_t options, icsneoc2_device_t** device) {
|
icsneoc2_error_t icsneoc2_device_open_serial(const char* serial, icsneoc2_open_options_t options, icsneoc2_device_t** device) {
|
||||||
|
|
@ -266,7 +250,15 @@ icsneoc2_error_t icsneoc2_device_open_serial(const char* serial, icsneoc2_open_o
|
||||||
std::string_view target(serial);
|
std::string_view target(serial);
|
||||||
for(auto* cur = devs; cur; cur = cur->next) {
|
for(auto* cur = devs; cur; cur = cur->next) {
|
||||||
if(cur->device && cur->device->getSerial() == target) {
|
if(cur->device && cur->device->getSerial() == target) {
|
||||||
res = open_device_with_options(cur->device, options, device);
|
if (res = icsneoc2_device_create(cur, device); res != icsneoc2_error_success) {
|
||||||
|
icsneoc2_enumeration_free(devs);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
res = open_device_with_options((*device)->device, options);
|
||||||
|
if (res != icsneoc2_error_success) {
|
||||||
|
icsneoc2_device_free(*device);
|
||||||
|
*device = nullptr;
|
||||||
|
}
|
||||||
icsneoc2_enumeration_free(devs);
|
icsneoc2_enumeration_free(devs);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
@ -286,7 +278,15 @@ icsneoc2_error_t icsneoc2_device_open_first(icsneoc2_devicetype_t device_type, i
|
||||||
}
|
}
|
||||||
for(auto* cur = devs; cur; cur = cur->next) {
|
for(auto* cur = devs; cur; cur = cur->next) {
|
||||||
if(cur->device && !cur->device->isOpen()) {
|
if(cur->device && !cur->device->isOpen()) {
|
||||||
res = open_device_with_options(cur->device, options, device);
|
if (res = icsneoc2_device_create(cur, device); res != icsneoc2_error_success) {
|
||||||
|
icsneoc2_enumeration_free(devs);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
res = open_device_with_options((*device)->device, options);
|
||||||
|
if (res != icsneoc2_error_success) {
|
||||||
|
icsneoc2_device_free(*device);
|
||||||
|
*device = nullptr;
|
||||||
|
}
|
||||||
icsneoc2_enumeration_free(devs);
|
icsneoc2_enumeration_free(devs);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
@ -295,6 +295,34 @@ icsneoc2_error_t icsneoc2_device_open_first(icsneoc2_devicetype_t device_type, i
|
||||||
return icsneoc2_error_invalid_device;
|
return icsneoc2_error_invalid_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
icsneoc2_error_t icsneoc2_device_reconnect(icsneoc2_device_t* device, icsneoc2_open_options_t options, uint32_t timeout_ms) {
|
||||||
|
auto res = icsneoc2_device_is_valid(device);
|
||||||
|
if(res != icsneoc2_error_success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
// If the device is currently open, close it first before trying to reconnect
|
||||||
|
if (device->device->isOpen()) {
|
||||||
|
res = icsneoc2_device_close(device);
|
||||||
|
if(res != icsneoc2_error_success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(timeout_ms);
|
||||||
|
while(std::chrono::steady_clock::now() < timeout) {
|
||||||
|
icsneoc2_device_t* new_device = nullptr;
|
||||||
|
res = icsneoc2_device_open_serial(device->device->getSerial().c_str(), options, &new_device);
|
||||||
|
if(res == icsneoc2_error_success) {
|
||||||
|
device->device = new_device->device;
|
||||||
|
delete new_device;
|
||||||
|
return icsneoc2_error_success;
|
||||||
|
}
|
||||||
|
// Avoid busy looping
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
}
|
||||||
|
return icsneoc2_error_reconnect_failed;
|
||||||
|
}
|
||||||
|
|
||||||
icsneoc2_error_t icsneoc2_device_close(icsneoc2_device_t* device) {
|
icsneoc2_error_t icsneoc2_device_close(icsneoc2_device_t* device) {
|
||||||
auto res = icsneoc2_device_is_valid(device);
|
auto res = icsneoc2_device_is_valid(device);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
|
|
@ -304,7 +332,21 @@ icsneoc2_error_t icsneoc2_device_close(icsneoc2_device_t* device) {
|
||||||
if(!dev->isOpen()) {
|
if(!dev->isOpen()) {
|
||||||
return icsneoc2_error_success;
|
return icsneoc2_error_success;
|
||||||
}
|
}
|
||||||
dev->close();
|
|
||||||
|
return dev->close() ? icsneoc2_error_success : icsneoc2_error_close_failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
icsneoc2_error_t icsneoc2_device_free(icsneoc2_device_t* device) {
|
||||||
|
auto res = icsneoc2_device_is_valid(device);
|
||||||
|
if(res != icsneoc2_error_success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
if (device->device->isOpen()) {
|
||||||
|
res = icsneoc2_device_close(device);
|
||||||
|
if(res != icsneoc2_error_success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
delete device;
|
delete device;
|
||||||
return icsneoc2_error_success;
|
return icsneoc2_error_success;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -395,7 +395,7 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
||||||
if(heartbeatCV.wait_for(recvLk, std::chrono::milliseconds(3500), [&](){ return receivedMessage; })) {
|
if(heartbeatCV.wait_for(recvLk, std::chrono::milliseconds(3500), [&](){ return receivedMessage; })) {
|
||||||
receivedMessage = false;
|
receivedMessage = false;
|
||||||
} else {
|
} else {
|
||||||
if(!stopHeartbeatThread && !isDisconnected()) {
|
if(!stopHeartbeatThread) {
|
||||||
close();
|
close();
|
||||||
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ option(LIBICSNEO_BUILD_C_LEGACY_EXAMPLE "Build the command-line simple C example
|
||||||
option(LIBICSNEO_BUILD_C2_SIMPLE_EXAMPLE "Build the simple C2 example." ON)
|
option(LIBICSNEO_BUILD_C2_SIMPLE_EXAMPLE "Build the simple C2 example." ON)
|
||||||
option(LIBICSNEO_BUILD_C2_READ_MESSAGES_EXAMPLE "Build the C2 read messages example." ON)
|
option(LIBICSNEO_BUILD_C2_READ_MESSAGES_EXAMPLE "Build the C2 read messages example." ON)
|
||||||
option(LIBICSNEO_BUILD_C2_DISKFORMAT_EXAMPLE "Build the C2 disk format example." ON)
|
option(LIBICSNEO_BUILD_C2_DISKFORMAT_EXAMPLE "Build the C2 disk format example." ON)
|
||||||
|
option(LIBICSNEO_BUILD_C2_RECONNECT_EXAMPLE "Build the C2 reconnect example." ON)
|
||||||
option(LIBICSNEO_BUILD_CPP_SIMPLE_EXAMPLE "Build the simple C++ example." ON)
|
option(LIBICSNEO_BUILD_CPP_SIMPLE_EXAMPLE "Build the simple C++ example." ON)
|
||||||
option(LIBICSNEO_BUILD_CPP_INTERACTIVE_EXAMPLE "Build the command-line interactive C++ example." ON)
|
option(LIBICSNEO_BUILD_CPP_INTERACTIVE_EXAMPLE "Build the command-line interactive C++ example." ON)
|
||||||
option(LIBICSNEO_BUILD_CPP_A2B_EXAMPLE "Build the A2B example." ON)
|
option(LIBICSNEO_BUILD_CPP_A2B_EXAMPLE "Build the A2B example." ON)
|
||||||
|
|
@ -47,6 +48,10 @@ if(LIBICSNEO_BUILD_C2_DISKFORMAT_EXAMPLE)
|
||||||
add_subdirectory(c2/diskformat)
|
add_subdirectory(c2/diskformat)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(LIBICSNEO_BUILD_C2_RECONNECT_EXAMPLE)
|
||||||
|
add_subdirectory(c2/reconnect)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(LIBICSNEO_BUILD_CPP_SIMPLE_EXAMPLE)
|
if(LIBICSNEO_BUILD_CPP_SIMPLE_EXAMPLE)
|
||||||
add_subdirectory(cpp/simple)
|
add_subdirectory(cpp/simple)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ int main() {
|
||||||
size_t description_length = sizeof(description);
|
size_t description_length = sizeof(description);
|
||||||
res = icsneoc2_device_description_get(device, description, &description_length);
|
res = icsneoc2_device_description_get(device, description, &description_length);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
|
icsneoc2_device_free(device);
|
||||||
return print_error_code("\tFailed to get device description", res);
|
return print_error_code("\tFailed to get device description", res);
|
||||||
}
|
}
|
||||||
printf("\tOpened device: %s\n", description);
|
printf("\tOpened device: %s\n", description);
|
||||||
|
|
@ -58,11 +59,13 @@ int main() {
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
print_error_code("\tFailed to check disk formatting support", res);
|
print_error_code("\tFailed to check disk formatting support", res);
|
||||||
icsneoc2_device_close(device);
|
icsneoc2_device_close(device);
|
||||||
|
icsneoc2_device_free(device);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(!supported) {
|
if(!supported) {
|
||||||
printf("\terror: %s does not support disk formatting\n", description);
|
printf("\terror: %s does not support disk formatting\n", description);
|
||||||
icsneoc2_device_close(device);
|
icsneoc2_device_close(device);
|
||||||
|
icsneoc2_device_free(device);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,6 +82,7 @@ int main() {
|
||||||
printf("FAIL\n");
|
printf("FAIL\n");
|
||||||
print_error_code("\tFailed to get disk details", res);
|
print_error_code("\tFailed to get disk details", res);
|
||||||
icsneoc2_device_close(device);
|
icsneoc2_device_close(device);
|
||||||
|
icsneoc2_device_free(device);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
printf("OK\n");
|
printf("OK\n");
|
||||||
|
|
@ -122,6 +126,7 @@ int main() {
|
||||||
printf("\n\terror: no disks are present in the device\n");
|
printf("\n\terror: no disks are present in the device\n");
|
||||||
icsneoc2_disk_details_free(details);
|
icsneoc2_disk_details_free(details);
|
||||||
icsneoc2_device_close(device);
|
icsneoc2_device_close(device);
|
||||||
|
icsneoc2_device_free(device);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -133,6 +138,7 @@ int main() {
|
||||||
printf("\tAborted.\n");
|
printf("\tAborted.\n");
|
||||||
icsneoc2_disk_details_free(details);
|
icsneoc2_disk_details_free(details);
|
||||||
icsneoc2_device_close(device);
|
icsneoc2_device_close(device);
|
||||||
|
icsneoc2_device_free(device);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,6 +151,7 @@ int main() {
|
||||||
print_error_code("\tFormat failed", res);
|
print_error_code("\tFormat failed", res);
|
||||||
icsneoc2_disk_details_free(details);
|
icsneoc2_disk_details_free(details);
|
||||||
icsneoc2_device_close(device);
|
icsneoc2_device_close(device);
|
||||||
|
icsneoc2_device_free(device);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
printf("\tFormat complete!\n");
|
printf("\tFormat complete!\n");
|
||||||
|
|
@ -171,5 +178,6 @@ int main() {
|
||||||
|
|
||||||
printf("\tClosing device: %s...\n", description);
|
printf("\tClosing device: %s...\n", description);
|
||||||
icsneoc2_device_close(device);
|
icsneoc2_device_close(device);
|
||||||
|
icsneoc2_device_free(device);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,7 @@ int main() {
|
||||||
size_t description_length = 255;
|
size_t description_length = 255;
|
||||||
res = icsneoc2_device_description_get(open_device, description, &description_length);
|
res = icsneoc2_device_description_get(open_device, description, &description_length);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
return print_error_code("\tFailed to get device description", res);
|
return print_error_code("\tFailed to get device description", res);
|
||||||
};
|
};
|
||||||
printf("\tOpened device: %s\n", description);
|
printf("\tOpened device: %s\n", description);
|
||||||
|
|
@ -96,6 +97,7 @@ int main() {
|
||||||
res = icsneoc2_device_message_get(open_device, &messages[i], 0);
|
res = icsneoc2_device_message_get(open_device, &messages[i], 0);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
print_events(description);
|
print_events(description);
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
return print_error_code("\tFailed to get messages from device", res);
|
return print_error_code("\tFailed to get messages from device", res);
|
||||||
};
|
};
|
||||||
if(messages[i] == NULL) {
|
if(messages[i] == NULL) {
|
||||||
|
|
@ -106,6 +108,7 @@ int main() {
|
||||||
}
|
}
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
print_events(description);
|
print_events(description);
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
return print_error_code("\tFailed to get messages from device", res);
|
return print_error_code("\tFailed to get messages from device", res);
|
||||||
}
|
}
|
||||||
time_t end_time = time(NULL);
|
time_t end_time = time(NULL);
|
||||||
|
|
@ -114,6 +117,7 @@ int main() {
|
||||||
res = process_message(messages, message_count);
|
res = process_message(messages, message_count);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
print_events(description);
|
print_events(description);
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
return print_error_code("\tFailed to process messages", res);
|
return print_error_code("\tFailed to process messages", res);
|
||||||
}
|
}
|
||||||
// Finally, close the device.
|
// Finally, close the device.
|
||||||
|
|
@ -121,8 +125,10 @@ int main() {
|
||||||
res = icsneoc2_device_close(open_device);
|
res = icsneoc2_device_close(open_device);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
print_events(description);
|
print_events(description);
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
return print_error_code("\tFailed to close device", res);
|
return print_error_code("\tFailed to close device", res);
|
||||||
};
|
};
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
add_executable(libicsneoc2-reconnect-example src/main.c)
|
||||||
|
target_link_libraries(libicsneoc2-reconnect-example icsneoc2-static)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
target_compile_definitions(libicsneoc2-reconnect-example PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||||
|
endif()
|
||||||
|
|
@ -0,0 +1,132 @@
|
||||||
|
#include <icsneo/icsneoc2.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void sleep_ms(uint32_t ms) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
Sleep(ms);
|
||||||
|
#else
|
||||||
|
usleep(ms * 1000);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_error_code(const char* message, icsneoc2_error_t error) {
|
||||||
|
char error_str[64];
|
||||||
|
size_t error_str_len = sizeof(error_str);
|
||||||
|
icsneoc2_error_t res = icsneoc2_error_code_get(error, error_str, &error_str_len);
|
||||||
|
if(res != icsneoc2_error_success) {
|
||||||
|
printf("%s: Failed to get string for error code %d with error code %d\n", message, error, res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
printf("%s: \"%s\" (%u)\n", message, error_str, error);
|
||||||
|
return (int)error;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_events(void) {
|
||||||
|
icsneoc2_event_t* events[256] = {0};
|
||||||
|
size_t events_count = 256;
|
||||||
|
for(size_t i = 0; i < events_count; ++i) {
|
||||||
|
icsneoc2_error_t res = icsneoc2_event_get(&events[i], NULL);
|
||||||
|
if(res != icsneoc2_error_success) {
|
||||||
|
(void)print_error_code("\tFailed to get events", res);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(events[i] == NULL) {
|
||||||
|
events_count = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(size_t i = 0; i < events_count; i++) {
|
||||||
|
char description[255] = {0};
|
||||||
|
size_t description_length = 255;
|
||||||
|
icsneoc2_error_t res = icsneoc2_event_description_get(events[i], description, &description_length);
|
||||||
|
if(res != icsneoc2_error_success) {
|
||||||
|
print_error_code("\tFailed to get event description", res);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf("\tEvent %zu: %s\n", i, description);
|
||||||
|
}
|
||||||
|
for(size_t i = 0; i < events_count; i++) {
|
||||||
|
icsneoc2_event_free(events[i]);
|
||||||
|
}
|
||||||
|
if(events_count > 0) {
|
||||||
|
printf("\tReceived %zu events\n", events_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
/* Open the first available device */
|
||||||
|
printf("Opening first available device...\n");
|
||||||
|
icsneoc2_device_t* device = NULL;
|
||||||
|
icsneoc2_error_t res = icsneoc2_device_open_first(0, icsneoc2_open_options_default, &device);
|
||||||
|
if(res != icsneoc2_error_success) {
|
||||||
|
return print_error_code("Failed to open first device", res);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a description of the opened device */
|
||||||
|
char description[255] = {0};
|
||||||
|
size_t description_length = 255;
|
||||||
|
res = icsneoc2_device_description_get(device, description, &description_length);
|
||||||
|
if(res != icsneoc2_error_success) {
|
||||||
|
icsneoc2_device_free(device);
|
||||||
|
return print_error_code("Failed to get device description", res);
|
||||||
|
}
|
||||||
|
printf("Opened device: %s\n", description);
|
||||||
|
|
||||||
|
/* Wait for the device to disconnect */
|
||||||
|
printf("Waiting for device to disconnect (unplug device from PC)...\n");
|
||||||
|
for(;;) {
|
||||||
|
bool is_open = true;
|
||||||
|
res = icsneoc2_device_is_open(device, &is_open);
|
||||||
|
if(res != icsneoc2_error_success) {
|
||||||
|
print_events();
|
||||||
|
icsneoc2_device_free(device);
|
||||||
|
return print_error_code("Failed to check open status", res);
|
||||||
|
}
|
||||||
|
if(!is_open) {
|
||||||
|
printf("Device disconnected!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sleep_ms(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attempt to reconnect */
|
||||||
|
uint32_t timeout_ms = 20000; // 20 second timeout
|
||||||
|
printf("Attempting to reconnect (%u second timeout)...\n", timeout_ms / 1000);
|
||||||
|
res = icsneoc2_device_reconnect(device, icsneoc2_open_options_default, timeout_ms);
|
||||||
|
if(res != icsneoc2_error_success) {
|
||||||
|
print_events();
|
||||||
|
icsneoc2_device_free(device);
|
||||||
|
return print_error_code("Failed to reconnect", res);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Reconnected successfully!\n");
|
||||||
|
|
||||||
|
/* Verify by getting the description again */
|
||||||
|
description_length = 255;
|
||||||
|
res = icsneoc2_device_description_get(device, description, &description_length);
|
||||||
|
if(res == icsneoc2_error_success) {
|
||||||
|
printf("Device: %s\n", description);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print any events */
|
||||||
|
print_events();
|
||||||
|
|
||||||
|
/* Close the device */
|
||||||
|
printf("Closing device...\n");
|
||||||
|
res = icsneoc2_device_close(device);
|
||||||
|
if(res != icsneoc2_error_success) {
|
||||||
|
icsneoc2_device_free(device);
|
||||||
|
return print_error_code("Failed to close device", res);
|
||||||
|
}
|
||||||
|
icsneoc2_device_free(device);
|
||||||
|
|
||||||
|
printf("Done.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -116,6 +116,7 @@ int main() {
|
||||||
size_t description_length = 255;
|
size_t description_length = 255;
|
||||||
res = icsneoc2_device_info_description_get(cur, description, &description_length);
|
res = icsneoc2_device_info_description_get(cur, description, &description_length);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
|
icsneoc2_enumeration_free(found_devices);
|
||||||
return print_error_code("\tFailed to get device description", res);
|
return print_error_code("\tFailed to get device description", res);
|
||||||
};
|
};
|
||||||
printf("%.*s\n", (int)description_length, description);
|
printf("%.*s\n", (int)description_length, description);
|
||||||
|
|
@ -126,8 +127,15 @@ int main() {
|
||||||
printf("\tDevice open options: 0x%x\n", options);
|
printf("\tDevice open options: 0x%x\n", options);
|
||||||
printf("\tOpening device: %s...\n", description);
|
printf("\tOpening device: %s...\n", description);
|
||||||
icsneoc2_device_t* open_device = NULL;
|
icsneoc2_device_t* open_device = NULL;
|
||||||
res = icsneoc2_device_open(cur, options, &open_device);
|
res = icsneoc2_device_create(cur, &open_device);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
|
icsneoc2_enumeration_free(found_devices);
|
||||||
|
return print_error_code("\tFailed to create device", res);
|
||||||
|
}
|
||||||
|
res = icsneoc2_device_open(open_device, options);
|
||||||
|
if(res != icsneoc2_error_success) {
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
|
icsneoc2_enumeration_free(found_devices);
|
||||||
return print_error_code("\tFailed to open device", res);
|
return print_error_code("\tFailed to open device", res);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -137,6 +145,8 @@ int main() {
|
||||||
res = icsneoc2_device_timestamp_resolution_get(open_device, ×tamp_resolution);
|
res = icsneoc2_device_timestamp_resolution_get(open_device, ×tamp_resolution);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
print_events(description);
|
print_events(description);
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
|
icsneoc2_enumeration_free(found_devices);
|
||||||
return print_error_code("\tFailed to get timestamp resolution", res);
|
return print_error_code("\tFailed to get timestamp resolution", res);
|
||||||
}
|
}
|
||||||
printf("%uns\n", timestamp_resolution);
|
printf("%uns\n", timestamp_resolution);
|
||||||
|
|
@ -146,6 +156,8 @@ int main() {
|
||||||
res = icsneoc2_settings_baudrate_get(open_device, icsneoc2_netid_dwcan_01, &baudrate);
|
res = icsneoc2_settings_baudrate_get(open_device, icsneoc2_netid_dwcan_01, &baudrate);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
print_events(description);
|
print_events(description);
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
|
icsneoc2_enumeration_free(found_devices);
|
||||||
return print_error_code("\tFailed to get baudrate", res);
|
return print_error_code("\tFailed to get baudrate", res);
|
||||||
};
|
};
|
||||||
printf("%" PRIu64 "mbit/s\n", baudrate);
|
printf("%" PRIu64 "mbit/s\n", baudrate);
|
||||||
|
|
@ -155,6 +167,8 @@ int main() {
|
||||||
res = icsneoc2_settings_canfd_baudrate_get(open_device, icsneoc2_netid_dwcan_01, &fd_baudrate);
|
res = icsneoc2_settings_canfd_baudrate_get(open_device, icsneoc2_netid_dwcan_01, &fd_baudrate);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
print_events(description);
|
print_events(description);
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
|
icsneoc2_enumeration_free(found_devices);
|
||||||
return print_error_code("\tFailed to get FD baudrate", res);
|
return print_error_code("\tFailed to get FD baudrate", res);
|
||||||
};
|
};
|
||||||
printf("%" PRIu64 "mbit/s\n", fd_baudrate);
|
printf("%" PRIu64 "mbit/s\n", fd_baudrate);
|
||||||
|
|
@ -165,6 +179,8 @@ int main() {
|
||||||
res = icsneoc2_settings_baudrate_set(open_device, icsneoc2_netid_dwcan_01, baudrate);
|
res = icsneoc2_settings_baudrate_set(open_device, icsneoc2_netid_dwcan_01, baudrate);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
print_events(description);
|
print_events(description);
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
|
icsneoc2_enumeration_free(found_devices);
|
||||||
return print_error_code("\tFailed to set baudrate", res);
|
return print_error_code("\tFailed to set baudrate", res);
|
||||||
};
|
};
|
||||||
printf("Ok\n");
|
printf("Ok\n");
|
||||||
|
|
@ -173,6 +189,8 @@ int main() {
|
||||||
res = icsneoc2_settings_canfd_baudrate_set(open_device, icsneoc2_netid_dwcan_01, fd_baudrate);
|
res = icsneoc2_settings_canfd_baudrate_set(open_device, icsneoc2_netid_dwcan_01, fd_baudrate);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
print_events(description);
|
print_events(description);
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
|
icsneoc2_enumeration_free(found_devices);
|
||||||
return print_error_code("\tFailed to set FD baudrate", res);
|
return print_error_code("\tFailed to set FD baudrate", res);
|
||||||
};
|
};
|
||||||
printf("Ok\n");
|
printf("Ok\n");
|
||||||
|
|
@ -181,6 +199,8 @@ int main() {
|
||||||
res = get_and_print_rtc(open_device);
|
res = get_and_print_rtc(open_device);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
print_events(description);
|
print_events(description);
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
|
icsneoc2_enumeration_free(found_devices);
|
||||||
return print_error_code("\tFailed to get RTC", res);
|
return print_error_code("\tFailed to get RTC", res);
|
||||||
}
|
}
|
||||||
// Set RTC
|
// Set RTC
|
||||||
|
|
@ -189,6 +209,8 @@ int main() {
|
||||||
res = icsneoc2_device_rtc_set(open_device, current_time);
|
res = icsneoc2_device_rtc_set(open_device, current_time);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
print_events(description);
|
print_events(description);
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
|
icsneoc2_enumeration_free(found_devices);
|
||||||
return print_error_code("\tFailed to set RTC", res);
|
return print_error_code("\tFailed to set RTC", res);
|
||||||
}
|
}
|
||||||
printf("Ok\n");
|
printf("Ok\n");
|
||||||
|
|
@ -197,6 +219,8 @@ int main() {
|
||||||
res = get_and_print_rtc(open_device);
|
res = get_and_print_rtc(open_device);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
print_events(description);
|
print_events(description);
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
|
icsneoc2_enumeration_free(found_devices);
|
||||||
return print_error_code("\tFailed to get RTC", res);
|
return print_error_code("\tFailed to get RTC", res);
|
||||||
}
|
}
|
||||||
// Go online, start acking traffic
|
// Go online, start acking traffic
|
||||||
|
|
@ -204,6 +228,8 @@ int main() {
|
||||||
res = icsneoc2_device_go_online(open_device, true);
|
res = icsneoc2_device_go_online(open_device, true);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
print_events(description);
|
print_events(description);
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
|
icsneoc2_enumeration_free(found_devices);
|
||||||
return print_error_code("\tFailed to go online", res);
|
return print_error_code("\tFailed to go online", res);
|
||||||
}
|
}
|
||||||
// Redundant check to show how to check if the device is online, if the previous
|
// Redundant check to show how to check if the device is online, if the previous
|
||||||
|
|
@ -212,6 +238,8 @@ int main() {
|
||||||
res = icsneoc2_device_is_online(open_device, &is_online);
|
res = icsneoc2_device_is_online(open_device, &is_online);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
print_events(description);
|
print_events(description);
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
|
icsneoc2_enumeration_free(found_devices);
|
||||||
return print_error_code("\tFailed to check if online", res);
|
return print_error_code("\tFailed to check if online", res);
|
||||||
}
|
}
|
||||||
printf("%s\n", is_online ? "Online" : "Offline");
|
printf("%s\n", is_online ? "Online" : "Offline");
|
||||||
|
|
@ -219,6 +247,8 @@ int main() {
|
||||||
res = transmit_can_messages(open_device);
|
res = transmit_can_messages(open_device);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
print_events(description);
|
print_events(description);
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
|
icsneoc2_enumeration_free(found_devices);
|
||||||
return print_error_code("\tFailed to transmit CAN messages", res);
|
return print_error_code("\tFailed to transmit CAN messages", res);
|
||||||
}
|
}
|
||||||
// Wait for the bus to collect some messages, requires an active bus to get messages
|
// Wait for the bus to collect some messages, requires an active bus to get messages
|
||||||
|
|
@ -231,7 +261,12 @@ int main() {
|
||||||
for(size_t i = 0; i < message_count; ++i) {
|
for(size_t i = 0; i < message_count; ++i) {
|
||||||
res = icsneoc2_device_message_get(open_device, &messages[i], 0);
|
res = icsneoc2_device_message_get(open_device, &messages[i], 0);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
|
for(size_t j = 0; j < i; ++j) {
|
||||||
|
icsneoc2_message_free(messages[j]);
|
||||||
|
}
|
||||||
print_events(description);
|
print_events(description);
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
|
icsneoc2_enumeration_free(found_devices);
|
||||||
return print_error_code("\tFailed to get messages from device", res);
|
return print_error_code("\tFailed to get messages from device", res);
|
||||||
};
|
};
|
||||||
if(messages[i] == NULL) {
|
if(messages[i] == NULL) {
|
||||||
|
|
@ -243,7 +278,12 @@ int main() {
|
||||||
// Process the messages
|
// Process the messages
|
||||||
res = process_messages(messages, message_count);
|
res = process_messages(messages, message_count);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
|
for(size_t i = 0; i < message_count; ++i) {
|
||||||
|
icsneoc2_message_free(messages[i]);
|
||||||
|
}
|
||||||
print_events(description);
|
print_events(description);
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
|
icsneoc2_enumeration_free(found_devices);
|
||||||
return print_error_code("\tFailed to process messages", res);
|
return print_error_code("\tFailed to process messages", res);
|
||||||
}
|
}
|
||||||
for(size_t i = 0; i < message_count; ++i) {
|
for(size_t i = 0; i < message_count; ++i) {
|
||||||
|
|
@ -254,11 +294,13 @@ int main() {
|
||||||
res = icsneoc2_device_close(open_device);
|
res = icsneoc2_device_close(open_device);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
print_events(description);
|
print_events(description);
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
|
icsneoc2_enumeration_free(found_devices);
|
||||||
return print_error_code("\tFailed to close device", res);
|
return print_error_code("\tFailed to close device", res);
|
||||||
};
|
};
|
||||||
// Print device events
|
// Print device events
|
||||||
print_events(description);
|
print_events(description);
|
||||||
|
icsneoc2_device_free(open_device);
|
||||||
}
|
}
|
||||||
icsneoc2_enumeration_free(found_devices);
|
icsneoc2_enumeration_free(found_devices);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
@ -285,6 +327,9 @@ void print_events(const char* device_description) {
|
||||||
// no device filter, get all events
|
// no device filter, get all events
|
||||||
icsneoc2_error_t res = icsneoc2_event_get(&events[i], NULL);
|
icsneoc2_error_t res = icsneoc2_event_get(&events[i], NULL);
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
|
for(size_t j = 0; j < i; ++j) {
|
||||||
|
icsneoc2_event_free(events[j]);
|
||||||
|
}
|
||||||
(void)print_error_code("\tFailed to get device events", res);
|
(void)print_error_code("\tFailed to get device events", res);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -397,6 +442,7 @@ int transmit_can_messages(icsneoc2_device_t* device) {
|
||||||
res += icsneoc2_message_can_props_set(message, &arb_id, &flags);
|
res += icsneoc2_message_can_props_set(message, &arb_id, &flags);
|
||||||
res += icsneoc2_message_data_set(message, (uint8_t*)&counter, sizeof(counter));
|
res += icsneoc2_message_data_set(message, (uint8_t*)&counter, sizeof(counter));
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
|
icsneoc2_message_free(message);
|
||||||
return print_error_code("\tFailed to modify message", res);
|
return print_error_code("\tFailed to modify message", res);
|
||||||
}
|
}
|
||||||
res = icsneoc2_device_message_transmit(device, message);
|
res = icsneoc2_device_message_transmit(device, message);
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,8 @@ typedef enum _icsneoc2_error_t {
|
||||||
icsneoc2_error_script_clear_failed, // Failed to clear script
|
icsneoc2_error_script_clear_failed, // Failed to clear script
|
||||||
icsneoc2_error_script_upload_failed, // Failed to upload coremini script
|
icsneoc2_error_script_upload_failed, // Failed to upload coremini script
|
||||||
icsneoc2_error_script_load_prepare_failed, // Failed to prepare script load
|
icsneoc2_error_script_load_prepare_failed, // Failed to prepare script load
|
||||||
|
icsneoc2_error_close_failed, // Failed to close device
|
||||||
|
icsneoc2_error_reconnect_failed, // Failed to reconnect to device
|
||||||
// NOTE: Any new values added here should be updated in icsneoc2_error_code_get
|
// NOTE: Any new values added here should be updated in icsneoc2_error_code_get
|
||||||
icsneoc2_error_maxsize
|
icsneoc2_error_maxsize
|
||||||
} _icsneoc2_error_t;
|
} _icsneoc2_error_t;
|
||||||
|
|
@ -166,29 +168,31 @@ icsneoc2_error_t icsneoc2_device_is_valid(const icsneoc2_device_t* device);
|
||||||
icsneoc2_error_t icsneoc2_device_is_open(const icsneoc2_device_t* device, bool* is_open);
|
icsneoc2_error_t icsneoc2_device_is_open(const icsneoc2_device_t* device, bool* is_open);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a device is disconnected.
|
* Create a device handle from an enumeration node without opening it. Need to call icsneoc2_device_free() to free the handle when finished.
|
||||||
|
* The device can then be opened with icsneoc2_device_open().
|
||||||
*
|
*
|
||||||
* @param[in] device The device to check.
|
* @param[in] device_info The device info node to create from.
|
||||||
* @param[out] is_disconnected true if the device is disconnected, false otherwise
|
* @param[out] device Pointer to receive the created device handle.
|
||||||
*
|
*
|
||||||
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
|
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_invalid_device otherwise.
|
||||||
|
*
|
||||||
|
* @see icsneoc2_device_open icsneoc2_device_free
|
||||||
*/
|
*/
|
||||||
icsneoc2_error_t icsneoc2_device_is_disconnected(const icsneoc2_device_t* device, bool* is_disconnected);
|
icsneoc2_error_t icsneoc2_device_create(const icsneoc2_device_info_t* device_info, icsneoc2_device_t** device);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open a device from an enumeration node.
|
* Open a device from an enumeration node.
|
||||||
*
|
*
|
||||||
* After a successful call, icsneoc2_device_close() must be called to close the device.
|
* After a successful call, icsneoc2_device_close() must be called to close the device.
|
||||||
*
|
*
|
||||||
* @param[in] device_info The device info node to open.
|
* @param[in] device Pointer to the device to open.
|
||||||
* @param[in] options Open options (e.g. icsneoc2_open_options_default).
|
* @param[in] options Open options (e.g. icsneoc2_open_options_default).
|
||||||
* @param[out] device Pointer to receive the opened device handle.
|
|
||||||
*
|
*
|
||||||
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_open_failed otherwise.
|
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_open_failed otherwise.
|
||||||
*
|
*
|
||||||
* @see icsneoc2_device_close
|
* @see icsneoc2_device_close icsneoc2_device_free
|
||||||
*/
|
*/
|
||||||
icsneoc2_error_t icsneoc2_device_open(const icsneoc2_device_info_t* device_info, icsneoc2_open_options_t options, icsneoc2_device_t** device);
|
icsneoc2_error_t icsneoc2_device_open(const icsneoc2_device_t* device, icsneoc2_open_options_t options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience: enumerate, find by serial, open, and free enumeration.
|
* Convenience: enumerate, find by serial, open, and free enumeration.
|
||||||
|
|
@ -199,7 +203,7 @@ icsneoc2_error_t icsneoc2_device_open(const icsneoc2_device_info_t* device_info,
|
||||||
*
|
*
|
||||||
* @return icsneoc2_error_t icsneoc2_error_success if successful.
|
* @return icsneoc2_error_t icsneoc2_error_success if successful.
|
||||||
*
|
*
|
||||||
* @see icsneoc2_device_close
|
* @see icsneoc2_device_close icsneoc2_device_free
|
||||||
*/
|
*/
|
||||||
icsneoc2_error_t icsneoc2_device_open_serial(const char* serial, icsneoc2_open_options_t options, icsneoc2_device_t** device);
|
icsneoc2_error_t icsneoc2_device_open_serial(const char* serial, icsneoc2_open_options_t options, icsneoc2_device_t** device);
|
||||||
|
|
||||||
|
|
@ -207,30 +211,53 @@ icsneoc2_error_t icsneoc2_device_open_serial(const char* serial, icsneoc2_open_o
|
||||||
* Convenience: enumerate, find first available device (optionally filtered by type), open, and free enumeration.
|
* Convenience: enumerate, find first available device (optionally filtered by type), open, and free enumeration.
|
||||||
* Pass 0 for device_type to match any device.
|
* Pass 0 for device_type to match any device.
|
||||||
*
|
*
|
||||||
|
*
|
||||||
* @param[in] device_type The device type to match, or 0 for any.
|
* @param[in] device_type The device type to match, or 0 for any.
|
||||||
* @param[in] options Open options (e.g. icsneoc2_open_options_default).
|
* @param[in] options Open options (e.g. icsneoc2_open_options_default).
|
||||||
* @param[out] device Pointer to receive the opened device handle.
|
* @param[out] device Pointer to receive the opened device handle.
|
||||||
*
|
*
|
||||||
* @return icsneoc2_error_t icsneoc2_error_success if successful.
|
* @return icsneoc2_error_t icsneoc2_error_success if successful.
|
||||||
*
|
*
|
||||||
* @see icsneoc2_device_close
|
* @see icsneoc2_device_close icsneoc2_device_free
|
||||||
*/
|
*/
|
||||||
icsneoc2_error_t icsneoc2_device_open_first(icsneoc2_devicetype_t device_type, icsneoc2_open_options_t options, icsneoc2_device_t** device);
|
icsneoc2_error_t icsneoc2_device_open_first(icsneoc2_devicetype_t device_type, icsneoc2_open_options_t options, icsneoc2_device_t** device);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reconnect to a device. This is useful if the device was disconnected and reconnected, or if the connection was lost for some reason.
|
||||||
|
*
|
||||||
|
* @param[in] device The device to reconnect.
|
||||||
|
* @param[in] options Open options (e.g. icsneoc2_open_options_default).
|
||||||
|
* @param[in] timeout_ms The timeout in milliseconds to keep trying to reconnect before giving up.
|
||||||
|
*
|
||||||
|
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_reconnect_failed if the timeout was reached without reconnecting, or icsneoc2_device_is_valid() errors otherwise.
|
||||||
|
*/
|
||||||
|
icsneoc2_error_t icsneoc2_device_reconnect(icsneoc2_device_t* device, icsneoc2_open_options_t options, uint32_t timeout_ms);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close a connection to a previously opened device.
|
* Close a connection to a previously opened device.
|
||||||
*
|
*
|
||||||
* After a successful call to icsneoc2_device_open(), this function must be called to close the device.
|
* After a successful call to icsneoc2_device_open(), this function must be called to close the device.
|
||||||
* An already closed device will still succeed. All messages and events related to the device will be freed.
|
* An already closed device will still succeed. The device handle must be freed with icsneoc2_device_free() when finished.
|
||||||
*
|
*
|
||||||
* @param[in,out] device Pointer to the device to close.
|
* @param[in,out] device Pointer to the device to close.
|
||||||
*
|
*
|
||||||
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_device_is_valid() errors otherwise.
|
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_device_is_valid() errors otherwise.
|
||||||
*
|
*
|
||||||
* @see icsneoc2_device_open icsneoc2_device_is_valid
|
* @see icsneoc2_device_open icsneoc2_device_is_valid icsneoc2_device_free
|
||||||
*/
|
*/
|
||||||
icsneoc2_error_t icsneoc2_device_close(icsneoc2_device_t* device);
|
icsneoc2_error_t icsneoc2_device_close(icsneoc2_device_t* device);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free a device handle created by icsneoc2_device_create(). Device should be closed before freeing.
|
||||||
|
*
|
||||||
|
* @param[in] device The device handle to free.
|
||||||
|
*
|
||||||
|
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_device_is_valid() errors otherwise.
|
||||||
|
*
|
||||||
|
* @see icsneoc2_device_create icsneoc2_device_close
|
||||||
|
*/
|
||||||
|
icsneoc2_error_t icsneoc2_device_free(icsneoc2_device_t* device);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the description of a device
|
* Get the description of a device
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,10 @@ TEST(icsneoc2, test_icsneoc2_error_invalid_parameters_and_invalid_device)
|
||||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_info_description_get(NULL, placeholderStr, &placeholderSizeT));
|
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_info_description_get(NULL, placeholderStr, &placeholderSizeT));
|
||||||
|
|
||||||
// Test open/close with NULL parameters
|
// Test open/close with NULL parameters
|
||||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_open(NULL, 0, NULL));
|
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_create(NULL, NULL));
|
||||||
|
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_free(NULL));
|
||||||
|
|
||||||
|
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_open(NULL, 0));
|
||||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_open_serial(NULL, 0, NULL));
|
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_open_serial(NULL, 0, NULL));
|
||||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_open_first(0, 0, NULL));
|
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_open_first(0, 0, NULL));
|
||||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_close(NULL));
|
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_close(NULL));
|
||||||
|
|
@ -154,7 +157,6 @@ TEST(icsneoc2, test_icsneoc2_error_invalid_parameters_and_invalid_device)
|
||||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_is_online_supported(NULL, &placeholderBool));
|
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_is_online_supported(NULL, &placeholderBool));
|
||||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_is_valid(NULL));
|
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_is_valid(NULL));
|
||||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_is_open(NULL, &placeholderBool));
|
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_is_open(NULL, &placeholderBool));
|
||||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_is_disconnected(NULL, &placeholderBool));
|
|
||||||
|
|
||||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_rtc_get(NULL, (int64_t *)&placeholderUnsignedInteger64));
|
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_rtc_get(NULL, (int64_t *)&placeholderUnsignedInteger64));
|
||||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_rtc_set(NULL, 0));
|
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_device_rtc_set(NULL, 0));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue