Compare commits
4 Commits
b0575fe658
...
1ca9f0fdb4
| Author | SHA1 | Date |
|---|---|---|
|
|
1ca9f0fdb4 | |
|
|
bfd8a023c6 | |
|
|
76fd1177de | |
|
|
7e616536ef |
|
|
@ -55,6 +55,41 @@ typedef struct icsneo_event_t {
|
|||
static std::vector<std::shared_ptr<icsneo_device_t>> g_devices;
|
||||
static std::vector<icsneo_event_t> g_events;
|
||||
|
||||
/**
|
||||
* Safely copies a std::string to a char array.
|
||||
*
|
||||
* @param dest The buffer to copy the string into
|
||||
* @param dest_size* The size of the buffer. Will be modified to the length of the string
|
||||
* @param src The string to copy
|
||||
*
|
||||
* @return true if the string was successfully copied, false otherwise
|
||||
*
|
||||
* @note This function always null terminates the buffer, even if the string is too long.
|
||||
* This is done for security reasons, not performance.
|
||||
*/
|
||||
bool safe_str_copy(const char* dest, uint32_t* const dest_size, std::string src) {
|
||||
if (!dest || !dest_size) {
|
||||
return false;
|
||||
}
|
||||
// zero terminate the entire string, this is done for security not for performance
|
||||
memset(const_cast<char*>(dest), 0, *dest_size);
|
||||
// Need to save room for the null terminator
|
||||
*dest_size -= 1;
|
||||
try {
|
||||
auto copied = src.copy(const_cast<char*>(dest), static_cast<size_t>(*dest_size), 0);
|
||||
*dest_size = static_cast<uint32_t>(copied);
|
||||
// Somehow we didn't copy the number of bytes we needed to? This check probably isn't needed.
|
||||
if (copied != src.length()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (std::out_of_range& ex) {
|
||||
// if pos > size()
|
||||
(void)ex;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ICSNEO_API icsneo_error_t icsneo_get_error_code(icsneo_error_t error_code, const char* value, uint32_t* value_length) {
|
||||
if (!value || !value_length) {
|
||||
return icsneo_error_invalid_parameters;
|
||||
|
|
@ -89,15 +124,13 @@ ICSNEO_API icsneo_error_t icsneo_get_error_code(icsneo_error_t error_code, const
|
|||
case icsneo_error_transmit_messages_failed:
|
||||
error = "Transmitting messages failed";
|
||||
break;
|
||||
case icsneo_error_string_copy_failed:
|
||||
error = "String copy failed";
|
||||
break;
|
||||
// Don't default, let the compiler warn us if we forget to handle an error code
|
||||
}
|
||||
// Find the minimum length of the error string and set value_length
|
||||
auto min_length = std::minmax(static_cast<uint32_t>(error.length()), *value_length).first;
|
||||
*value_length = min_length;
|
||||
// Copy the string into value
|
||||
strncpy(const_cast<char *>(value), error.c_str(), min_length);
|
||||
|
||||
return icsneo_error_success;
|
||||
return safe_str_copy(value, value_length, error) ? icsneo_error_success : icsneo_error_string_copy_failed;
|
||||
}
|
||||
|
||||
ICSNEO_API icsneo_error_t icsneo_device_type_from_type(icsneo_devicetype_t device_type, const char* value, uint32_t* value_length) {
|
||||
|
|
@ -106,16 +139,12 @@ ICSNEO_API icsneo_error_t icsneo_device_type_from_type(icsneo_devicetype_t devic
|
|||
}
|
||||
|
||||
auto device_type_str = DeviceType::getGenericProductName(device_type);
|
||||
// Find the minimum length of the device type string and set value_length
|
||||
auto min_length = std::minmax(static_cast<uint32_t>(device_type_str.length()), *value_length).first;
|
||||
*value_length = min_length;
|
||||
// Copy the string into value
|
||||
strncpy(const_cast<char *>(value), device_type_str.c_str(), min_length);
|
||||
|
||||
return icsneo_error_success;
|
||||
return safe_str_copy(value, value_length, device_type_str) ? icsneo_error_success : icsneo_error_string_copy_failed;
|
||||
}
|
||||
|
||||
ICSNEO_API icsneo_error_t icsneo_device_find_all(icsneo_device_t** devices, uint32_t* devices_count, void* reserved) {
|
||||
(void)reserved;
|
||||
if (!devices || !devices_count) {
|
||||
return icsneo_error_invalid_parameters;
|
||||
}
|
||||
|
|
@ -231,13 +260,8 @@ ICSNEO_API icsneo_error_t icsneo_device_get_description(icsneo_device_t* device,
|
|||
return icsneo_error_invalid_parameters;
|
||||
}
|
||||
auto dev = device->device;
|
||||
// Get and set the length
|
||||
auto min_length = std::minmax(static_cast<uint32_t>(dev->describe().length()), *value_length).first;
|
||||
*value_length = min_length;
|
||||
// Copy the string into value
|
||||
strncpy(const_cast<char *>(value), dev->describe().c_str(), min_length);
|
||||
|
||||
return icsneo_error_success;
|
||||
return safe_str_copy(value, value_length, dev->describe()) ? icsneo_error_success : icsneo_error_string_copy_failed;
|
||||
}
|
||||
|
||||
ICSNEO_API icsneo_error_t icsneo_device_get_type(icsneo_device_t* device, icsneo_devicetype_t* value) {
|
||||
|
|
@ -255,13 +279,8 @@ ICSNEO_API icsneo_error_t icsneo_device_get_serial(icsneo_device_t* device, cons
|
|||
return icsneo_error_invalid_parameters;
|
||||
}
|
||||
auto dev = device->device;
|
||||
// Get and set the length
|
||||
auto min_length = std::minmax(static_cast<uint32_t>(dev->getSerial().length()), *value_length).first;
|
||||
*value_length = min_length;
|
||||
// Copy the string into value
|
||||
strncpy(const_cast<char *>(value), dev->getSerial().c_str(), min_length);
|
||||
|
||||
return icsneo_error_success;
|
||||
return safe_str_copy(value, value_length, dev->getSerial()) ? icsneo_error_success : icsneo_error_string_copy_failed;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -472,6 +491,40 @@ ICSNEO_API icsneo_error_t icsneo_message_get_bus_type(icsneo_device_t* device, i
|
|||
return icsneo_error_success;
|
||||
}
|
||||
|
||||
ICSNEO_API icsneo_error_t icsneo_get_bus_type_name(icsneo_msg_bus_type_t* bus_type, const char* value, uint32_t* value_length) {
|
||||
if (!bus_type || !value || !value_length) {
|
||||
return icsneo_error_invalid_parameters;
|
||||
}
|
||||
auto bus_type_str = std::string(Network::GetTypeString(*bus_type));
|
||||
// Copy the string into value
|
||||
return safe_str_copy(value, value_length, bus_type_str) ? icsneo_error_success : icsneo_error_string_copy_failed;
|
||||
}
|
||||
|
||||
ICSNEO_API icsneo_error_t icsneo_message_get_netid(icsneo_device_t* device, icsneo_message_t* message, icsneo_netid_t* netid) {
|
||||
if (!device || !message || !netid) {
|
||||
return icsneo_error_invalid_parameters;
|
||||
}
|
||||
// TODO: Check if message is valid
|
||||
|
||||
// Make sure the message is a bus message
|
||||
if (message->message->getMsgType() != icsneo_msg_type_bus) {
|
||||
return icsneo_error_invalid_type;
|
||||
}
|
||||
// We can static cast here because we are relying on the type being correct at this point
|
||||
auto bus_message = static_cast<BusMessage*>(message->message.get());
|
||||
*netid = static_cast<icsneo_netid_t>(bus_message->network.getNetID());
|
||||
return icsneo_error_success;
|
||||
}
|
||||
|
||||
ICSNEO_API icsneo_error_t icsneo_get_netid_name(icsneo_netid_t netid, const char* value, uint32_t* value_length) {
|
||||
if (!netid || !value || !value_length) {
|
||||
return icsneo_error_invalid_parameters;
|
||||
}
|
||||
auto netid_str = std::string(Network::GetNetIDString(static_cast<_icsneo_netid_t>(netid), true));
|
||||
// Copy the string into value
|
||||
return safe_str_copy(value, value_length, netid_str) ? icsneo_error_success : icsneo_error_string_copy_failed;
|
||||
}
|
||||
|
||||
ICSNEO_API icsneo_error_t icsneo_message_get_data(icsneo_device_t* device, icsneo_message_t* message, uint8_t* data, uint32_t* data_length) {
|
||||
if (!device || !message || !data || !data_length) {
|
||||
return icsneo_error_invalid_parameters;
|
||||
|
|
@ -689,14 +742,8 @@ ICSNEO_API icsneo_error_t icsneo_event_get_description(icsneo_event_t* event, co
|
|||
}
|
||||
// TODO: Check if event is valid
|
||||
auto ev = event->event;
|
||||
|
||||
// Get and set the length
|
||||
auto min_length = std::minmax(static_cast<uint32_t>(ev.describe().length()), *value_length).first;
|
||||
*value_length = min_length;
|
||||
// Copy the string into value
|
||||
strncpy(const_cast<char *>(value), ev.describe().c_str(), min_length);
|
||||
|
||||
return icsneo_error_success;
|
||||
return safe_str_copy(value, value_length, ev.describe()) ? icsneo_error_success : icsneo_error_string_copy_failed;
|
||||
}
|
||||
|
||||
ICSNEO_API icsneo_error_t icsneo_device_get_rtc(icsneo_device_t* device, int64_t* unix_epoch) {
|
||||
|
|
|
|||
|
|
@ -206,16 +206,28 @@ int process_messages(icsneo_device_t* device, icsneo_message_t** messages, uint3
|
|||
if (res != icsneo_error_success) {
|
||||
return print_error_code("Failed to get message bus type", res);
|
||||
}
|
||||
printf("\t%d) Message type: %u bus type: %u\n", i, msg_type, bus_type);
|
||||
const char bus_name[128] = {0};
|
||||
uint32_t bus_name_length = 128;
|
||||
res = icsneo_get_bus_type_name(&bus_type, bus_name, &bus_name_length);
|
||||
if (res != icsneo_error_success) {
|
||||
return print_error_code("Failed to get message bus type name", res);
|
||||
}
|
||||
|
||||
printf("\t%d) Message type: %u bus type: %s (%u)\n", i, msg_type, bus_name, bus_type);
|
||||
if (bus_type == icsneo_msg_bus_type_can) {
|
||||
uint32_t arbid = 0;
|
||||
uint32_t dlc = 0;
|
||||
icsneo_netid_t netid = 0;
|
||||
bool is_remote = false;
|
||||
bool is_canfd = false;
|
||||
bool is_extended = false;
|
||||
uint8_t data[64] = {0};
|
||||
uint32_t data_length = 64;
|
||||
uint32_t result = icsneo_can_message_get_arbid(device, message, &arbid);
|
||||
const char netid_name[128] = {0};
|
||||
uint32_t netid_name_length = 128;
|
||||
uint32_t result = icsneo_message_get_netid(device, message, &netid);
|
||||
result += icsneo_get_netid_name(netid, netid_name, &netid_name_length);
|
||||
result += icsneo_can_message_get_arbid(device, message, &arbid);
|
||||
result += icsneo_can_message_get_dlc_on_wire(device, message, &dlc);
|
||||
result += icsneo_can_message_is_remote(device, message, &is_remote);
|
||||
result += icsneo_can_message_is_canfd(device, message, &is_canfd);
|
||||
|
|
@ -225,7 +237,7 @@ int process_messages(icsneo_device_t* device, icsneo_message_t** messages, uint3
|
|||
printf("\tFailed get get CAN parameters (error: %u) for index %u\n", result, i);
|
||||
continue;
|
||||
}
|
||||
printf("\t ArbID: 0x%x\t DLC: %u\t Remote: %d\t CANFD: %d\t Extended: %d\t Data length: %u\n", arbid, dlc, is_remote, is_canfd, is_extended, data_length);
|
||||
printf("\t NetID: %s (0x%x)\tArbID: 0x%x\t DLC: %u\t Remote: %d\t CANFD: %d\t Extended: %d\t Data length: %u\n", netid_name, netid, arbid, dlc, is_remote, is_canfd, is_extended, data_length);
|
||||
printf("\t Data: [");
|
||||
for (uint32_t x = 0; x < data_length; x++) {
|
||||
printf(" 0x%x", data[x]);
|
||||
|
|
|
|||
|
|
@ -88,6 +88,8 @@ typedef enum _icsneo_error_t {
|
|||
icsneo_error_set_settings_failure,
|
||||
// Failed to transmit messages
|
||||
icsneo_error_transmit_messages_failed,
|
||||
// Failed to copy string to buffer
|
||||
icsneo_error_string_copy_failed
|
||||
} _icsneo_error_t;
|
||||
|
||||
/** @brief Integer representation of _icsneo_error_t enum.
|
||||
|
|
@ -349,10 +351,43 @@ ICSNEO_API icsneo_error_t icsneo_message_get_type(icsneo_device_t* device, icsne
|
|||
*
|
||||
* @return icsneo_error_t icsneo_error_success if successful, icsneo_error_invalid_parameters or icsneo_error_invalid_type otherwise.
|
||||
*
|
||||
* @see icsneo_msg_bus_type_t
|
||||
* @see icsneo_msg_bus_type_t, icsneo_get_bus_type_name
|
||||
*/
|
||||
ICSNEO_API icsneo_error_t icsneo_message_get_bus_type(icsneo_device_t* device, icsneo_message_t* message, icsneo_msg_bus_type_t* bus_type);
|
||||
|
||||
/** @brief Get the bus type string for a icsneo_msg_bus_type_t.
|
||||
*
|
||||
* @param[in] icsneo_msg_bus_type_t* bus_type The bus type to get the description of.
|
||||
* @param[out] const char* value Pointer to a buffer to copy the description into. Null terminated.
|
||||
* @param[in,out] uint32_t* value_length Size of the value buffer. Modified with the length of the description.
|
||||
*
|
||||
* @return icsneo_error_t icsneo_error_success if successful, icsneo_error_invalid_parameters otherwise.
|
||||
*/
|
||||
ICSNEO_API icsneo_error_t icsneo_get_bus_type_name(icsneo_msg_bus_type_t* bus_type, const char* value, uint32_t* value_length);
|
||||
|
||||
/** @brief Get the Network ID (netid) of a bus message
|
||||
*
|
||||
* @param[in] icsneo_device_t* device The device to check against.
|
||||
* @param[in] icsneo_message_t* message The message to check.
|
||||
* @param[out] icsneo_netid_t* netid Pointer to a icsneo_netid_t to copy the type of the value into.
|
||||
*
|
||||
* @return icsneo_error_t icsneo_error_success if successful, icsneo_error_invalid_parameters or icsneo_error_invalid_type otherwise.
|
||||
*
|
||||
* @see icsneo_netid_t, icsneo_get_netid_name
|
||||
*/
|
||||
ICSNEO_API icsneo_error_t icsneo_message_get_netid(icsneo_device_t* device, icsneo_message_t* message, icsneo_netid_t* netid);
|
||||
|
||||
/** @brief Get the netid string for a icsneo_netid_t.
|
||||
*
|
||||
* @param[in] icsneo_netid_t netid The network id to get the description of.
|
||||
* @param[out] const char* value Pointer to a buffer to copy the description into. Null terminated.
|
||||
* @param[in,out] uint32_t* value_length Size of the value buffer. Modified with the length of the description.
|
||||
*
|
||||
* @return icsneo_error_t icsneo_error_success if successful, icsneo_error_invalid_parameters otherwise.
|
||||
*/
|
||||
ICSNEO_API icsneo_error_t icsneo_get_netid_name(icsneo_netid_t netid, const char* value, uint32_t* value_length);
|
||||
|
||||
|
||||
/** @brief Get the data bytes of a message
|
||||
*
|
||||
* @param[in] icsneo_device_t* device The device to check against.
|
||||
|
|
|
|||
Loading…
Reference in New Issue