C2: Add message timestamp support
parent
00b7b4a6de
commit
eded388b83
|
|
@ -126,6 +126,28 @@ icsneoc2_error_t icsneoc2_message_data_get(icsneoc2_message_t* message, uint8_t*
|
||||||
return icsneoc2_error_success;
|
return icsneoc2_error_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
icsneoc2_error_t icsneoc2_message_timestamp_set(icsneoc2_message_t* message, uint64_t timestamp) {
|
||||||
|
if(!message) {
|
||||||
|
return icsneoc2_error_invalid_parameters;
|
||||||
|
}
|
||||||
|
if(!message->message) {
|
||||||
|
return icsneoc2_error_invalid_message;
|
||||||
|
}
|
||||||
|
message->message->timestamp = timestamp;
|
||||||
|
return icsneoc2_error_success;
|
||||||
|
}
|
||||||
|
|
||||||
|
icsneoc2_error_t icsneoc2_message_timestamp_get(icsneoc2_message_t* message, uint64_t* timestamp) {
|
||||||
|
if(!message || !timestamp) {
|
||||||
|
return icsneoc2_error_invalid_parameters;
|
||||||
|
}
|
||||||
|
if(!message->message) {
|
||||||
|
return icsneoc2_error_invalid_message;
|
||||||
|
}
|
||||||
|
*timestamp = message->message->timestamp;
|
||||||
|
return icsneoc2_error_success;
|
||||||
|
}
|
||||||
|
|
||||||
icsneoc2_error_t icsneoc2_message_can_create(icsneoc2_message_t** message) {
|
icsneoc2_error_t icsneoc2_message_can_create(icsneoc2_message_t** message) {
|
||||||
if(!message) {
|
if(!message) {
|
||||||
return icsneoc2_error_invalid_parameters;
|
return icsneoc2_error_invalid_parameters;
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ void print_mac(const char* label, const uint8_t* mac) {
|
||||||
|
|
||||||
int process_ethernet_message(icsneoc2_message_t* message, size_t index) {
|
int process_ethernet_message(icsneoc2_message_t* message, size_t index) {
|
||||||
icsneoc2_netid_t netid = 0;
|
icsneoc2_netid_t netid = 0;
|
||||||
|
uint64_t timestamp = 0;
|
||||||
char netid_name[128] = {0};
|
char netid_name[128] = {0};
|
||||||
size_t netid_name_length = 128;
|
size_t netid_name_length = 128;
|
||||||
|
|
||||||
|
|
@ -79,6 +80,10 @@ int process_ethernet_message(icsneoc2_message_t* message, size_t index) {
|
||||||
if(res != icsneoc2_error_success) {
|
if(res != icsneoc2_error_success) {
|
||||||
return print_error_code("\tFailed to get netid name", res);
|
return print_error_code("\tFailed to get netid name", res);
|
||||||
}
|
}
|
||||||
|
res = icsneoc2_message_timestamp_get(message, ×tamp);
|
||||||
|
if(res != icsneoc2_error_success) {
|
||||||
|
return print_error_code("\tFailed to get timestamp", res);
|
||||||
|
}
|
||||||
|
|
||||||
/* Get data length first */
|
/* Get data length first */
|
||||||
size_t data_length = 0;
|
size_t data_length = 0;
|
||||||
|
|
@ -88,6 +93,7 @@ int process_ethernet_message(icsneoc2_message_t* message, size_t index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\t%zu) Ethernet Frame on %s (0x%x) - %zu bytes\n", index, netid_name, netid, data_length);
|
printf("\t%zu) Ethernet Frame on %s (0x%x) - %zu bytes\n", index, netid_name, netid, data_length);
|
||||||
|
printf("\t Timestamp: %" PRIu64 " ns since 2007-01-01 UTC\n", timestamp);
|
||||||
|
|
||||||
/* Get MAC addresses and EtherType if we have enough data */
|
/* Get MAC addresses and EtherType if we have enough data */
|
||||||
uint8_t dst_mac[6] = {0};
|
uint8_t dst_mac[6] = {0};
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,8 @@ void process_lin_messages(icsneoc2_message_t** messages, size_t count) {
|
||||||
|
|
||||||
icsneoc2_netid_t netid = 0;
|
icsneoc2_netid_t netid = 0;
|
||||||
icsneoc2_message_netid_get(messages[i], &netid);
|
icsneoc2_message_netid_get(messages[i], &netid);
|
||||||
|
uint64_t timestamp = 0;
|
||||||
|
icsneoc2_message_timestamp_get(messages[i], ×tamp);
|
||||||
char netid_name[128] = {0};
|
char netid_name[128] = {0};
|
||||||
size_t netid_name_length = 128;
|
size_t netid_name_length = 128;
|
||||||
icsneoc2_netid_name_get(netid, netid_name, &netid_name_length);
|
icsneoc2_netid_name_get(netid, netid_name, &netid_name_length);
|
||||||
|
|
@ -98,6 +100,7 @@ void process_lin_messages(icsneoc2_message_t** messages, size_t count) {
|
||||||
icsneoc2_message_lin_err_flags_get(messages[i], &err_flags);
|
icsneoc2_message_lin_err_flags_get(messages[i], &err_flags);
|
||||||
|
|
||||||
printf("\t%s RX | ID: 0x%02x | Protected ID: 0x%02x\n", netid_name, id, protected_id);
|
printf("\t%s RX | ID: 0x%02x | Protected ID: 0x%02x\n", netid_name, id, protected_id);
|
||||||
|
printf("\tTimestamp: %" PRIu64 " ns since 2007-01-01 UTC\n", timestamp);
|
||||||
printf("\tData: [");
|
printf("\tData: [");
|
||||||
for(size_t x = 0; x < data_length; x++) {
|
for(size_t x = 0; x < data_length; x++) {
|
||||||
printf(" 0x%02x", data[x]);
|
printf(" 0x%02x", data[x]);
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,7 @@ int process_message(icsneoc2_message_t** messages, size_t messages_count) {
|
||||||
|
|
||||||
printf("\t%zd) network type: %s (%u)\n", i, network_type_name, network_type);
|
printf("\t%zd) network type: %s (%u)\n", i, network_type_name, network_type);
|
||||||
if(network_type == icsneoc2_network_type_can) {
|
if(network_type == icsneoc2_network_type_can) {
|
||||||
|
uint64_t timestamp = 0;
|
||||||
uint64_t arbid = 0;
|
uint64_t arbid = 0;
|
||||||
int32_t dlc = 0;
|
int32_t dlc = 0;
|
||||||
icsneoc2_netid_t netid = 0;
|
icsneoc2_netid_t netid = 0;
|
||||||
|
|
@ -256,6 +257,7 @@ int process_message(icsneoc2_message_t** messages, size_t messages_count) {
|
||||||
bool is_tx = false;
|
bool is_tx = false;
|
||||||
icsneoc2_error_t result = icsneoc2_message_netid_get(message, &netid);
|
icsneoc2_error_t result = icsneoc2_message_netid_get(message, &netid);
|
||||||
result += icsneoc2_netid_name_get(netid, netid_name, &netid_name_length);
|
result += icsneoc2_netid_name_get(netid, netid_name, &netid_name_length);
|
||||||
|
result += icsneoc2_message_timestamp_get(message, ×tamp);
|
||||||
result += icsneoc2_message_can_props_get(message, &arbid, &can_flags);
|
result += icsneoc2_message_can_props_get(message, &arbid, &can_flags);
|
||||||
result += icsneoc2_message_data_get(message, data, &data_length);
|
result += icsneoc2_message_data_get(message, data, &data_length);
|
||||||
result += icsneoc2_message_is_transmit(message, &is_tx);
|
result += icsneoc2_message_is_transmit(message, &is_tx);
|
||||||
|
|
@ -276,6 +278,7 @@ int process_message(icsneoc2_message_t** messages, size_t messages_count) {
|
||||||
dlc = (int32_t)data_length;
|
dlc = (int32_t)data_length;
|
||||||
|
|
||||||
printf("\t %s%s\n", is_tx ? "TX" : "RX", is_error ? " [Error]" : "");
|
printf("\t %s%s\n", is_tx ? "TX" : "RX", is_error ? " [Error]" : "");
|
||||||
|
printf("\t Timestamp: %" PRIu64 " ns since 2007-01-01 UTC\n", timestamp);
|
||||||
printf("\t NetID: %s (0x%x)\tArbID: 0x%llx\tDLC: %u\tLen: %zu\n", netid_name, netid, (unsigned long long)arbid, dlc, data_length);
|
printf("\t NetID: %s (0x%x)\tArbID: 0x%llx\tDLC: %u\tLen: %zu\n", netid_name, netid, (unsigned long long)arbid, dlc, data_length);
|
||||||
printf("\t Flags:%s%s%s%s%s%s%s%s\n",
|
printf("\t Flags:%s%s%s%s%s%s%s%s\n",
|
||||||
is_remote ? " RTR" : "",
|
is_remote ? " RTR" : "",
|
||||||
|
|
|
||||||
|
|
@ -426,6 +426,7 @@ int process_messages(icsneoc2_message_t** messages, size_t messages_count) {
|
||||||
printf("\t%zd) network type: %s (%u)\n", i, network_type_name, network_type);
|
printf("\t%zd) network type: %s (%u)\n", i, network_type_name, network_type);
|
||||||
|
|
||||||
if(network_type == icsneoc2_network_type_can) {
|
if(network_type == icsneoc2_network_type_can) {
|
||||||
|
uint64_t timestamp = 0;
|
||||||
uint64_t arbid = 0;
|
uint64_t arbid = 0;
|
||||||
int32_t dlc = 0;
|
int32_t dlc = 0;
|
||||||
icsneoc2_netid_t netid = 0;
|
icsneoc2_netid_t netid = 0;
|
||||||
|
|
@ -436,6 +437,7 @@ int process_messages(icsneoc2_message_t** messages, size_t messages_count) {
|
||||||
size_t netid_name_length = 128;
|
size_t netid_name_length = 128;
|
||||||
icsneoc2_error_t result = icsneoc2_message_netid_get(message, &netid);
|
icsneoc2_error_t result = icsneoc2_message_netid_get(message, &netid);
|
||||||
result += icsneoc2_netid_name_get(netid, netid_name, &netid_name_length);
|
result += icsneoc2_netid_name_get(netid, netid_name, &netid_name_length);
|
||||||
|
result += icsneoc2_message_timestamp_get(message, ×tamp);
|
||||||
result += icsneoc2_message_can_props_get(message, &arbid, &can_flags);
|
result += icsneoc2_message_can_props_get(message, &arbid, &can_flags);
|
||||||
result += icsneoc2_message_data_get(message, data, &data_length);
|
result += icsneoc2_message_data_get(message, data, &data_length);
|
||||||
if(result != icsneoc2_error_success) {
|
if(result != icsneoc2_error_success) {
|
||||||
|
|
@ -452,6 +454,7 @@ int process_messages(icsneoc2_message_t** messages, size_t messages_count) {
|
||||||
bool tx_error = (can_flags & ICSNEOC2_MESSAGE_CAN_FLAGS_TX_ERROR) != 0;
|
bool tx_error = (can_flags & ICSNEOC2_MESSAGE_CAN_FLAGS_TX_ERROR) != 0;
|
||||||
dlc = (int32_t)data_length;
|
dlc = (int32_t)data_length;
|
||||||
|
|
||||||
|
printf("\t Timestamp: %" PRIu64 " ns since 2007-01-01 UTC\n", timestamp);
|
||||||
printf("\t NetID: %s (0x%x)\tArbID: 0x%llx\tDLC: %u\tLen: %zu\n", netid_name, netid, (unsigned long long)arbid, dlc, data_length);
|
printf("\t NetID: %s (0x%x)\tArbID: 0x%llx\tDLC: %u\tLen: %zu\n", netid_name, netid, (unsigned long long)arbid, dlc, data_length);
|
||||||
printf("\t Flags:%s%s%s%s%s%s%s%s\n",
|
printf("\t Flags:%s%s%s%s%s%s%s%s\n",
|
||||||
is_remote ? " RTR" : "",
|
is_remote ? " RTR" : "",
|
||||||
|
|
|
||||||
|
|
@ -468,6 +468,7 @@ static int message_matches_loopback_frame(icsneoc2_message_t* message, const uin
|
||||||
|
|
||||||
static int print_ethernet_message(icsneoc2_message_t* message, const char* direction_label) {
|
static int print_ethernet_message(icsneoc2_message_t* message, const char* direction_label) {
|
||||||
icsneoc2_netid_t netid = 0;
|
icsneoc2_netid_t netid = 0;
|
||||||
|
uint64_t timestamp = 0;
|
||||||
char netid_name[64] = {0};
|
char netid_name[64] = {0};
|
||||||
uint8_t dst_mac[6] = {0};
|
uint8_t dst_mac[6] = {0};
|
||||||
uint8_t src_mac[6] = {0};
|
uint8_t src_mac[6] = {0};
|
||||||
|
|
@ -483,11 +484,14 @@ static int print_ethernet_message(icsneoc2_message_t* message, const char* direc
|
||||||
res = icsneoc2_message_netid_get(message, &netid);
|
res = icsneoc2_message_netid_get(message, &netid);
|
||||||
if(res != icsneoc2_error_success) return print_error_code("Failed to get message netid", res);
|
if(res != icsneoc2_error_success) return print_error_code("Failed to get message netid", res);
|
||||||
if(get_netid_name(netid, netid_name, sizeof(netid_name)) != 0) return 1;
|
if(get_netid_name(netid, netid_name, sizeof(netid_name)) != 0) return 1;
|
||||||
|
res = icsneoc2_message_timestamp_get(message, ×tamp);
|
||||||
|
if(res != icsneoc2_error_success) return print_error_code("Failed to get message timestamp", res);
|
||||||
|
|
||||||
res = icsneoc2_message_data_get(message, data, &data_length);
|
res = icsneoc2_message_data_get(message, data, &data_length);
|
||||||
if(res != icsneoc2_error_success) return print_error_code("Failed to get Ethernet data", res);
|
if(res != icsneoc2_error_success) return print_error_code("Failed to get Ethernet data", res);
|
||||||
|
|
||||||
printf("%s on %s: %zu bytes\n", direction_label, netid_name, data_length);
|
printf("%s on %s: %zu bytes\n", direction_label, netid_name, data_length);
|
||||||
|
printf(" Timestamp: %" PRIu64 " ns since 2007-01-01 UTC\n", timestamp);
|
||||||
|
|
||||||
res = icsneoc2_message_eth_mac_get(message, dst_mac, src_mac);
|
res = icsneoc2_message_eth_mac_get(message, dst_mac, src_mac);
|
||||||
if(res == icsneoc2_error_success) {
|
if(res == icsneoc2_error_success) {
|
||||||
|
|
@ -640,4 +644,4 @@ static int poll_for_loopback_messages(icsneoc2_device_t* device,
|
||||||
|
|
||||||
printf("Loopback complete: TX echo on %s and RX frame on %s were both observed.\n", tx_name, rx_name);
|
printf("Loopback complete: TX echo on %s and RX frame on %s were both observed.\n", tx_name, rx_name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -118,9 +118,33 @@ icsneoc2_error_t icsneoc2_message_data_set(icsneoc2_message_t* message, uint8_t*
|
||||||
*
|
*
|
||||||
* @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 otherwise.
|
||||||
*/
|
*/
|
||||||
icsneoc2_error_t icsneoc2_message_data_get(icsneoc2_message_t* message, uint8_t* data, size_t* data_length);
|
icsneoc2_error_t icsneoc2_message_data_get(icsneoc2_message_t* message, uint8_t* data, size_t* data_length);
|
||||||
|
|
||||||
#define ICSNEOC2_MESSAGE_CAN_FLAGS_RTR 0x01 // Remote Transmission Request
|
/**
|
||||||
|
* Set the timestamp of a message.
|
||||||
|
*
|
||||||
|
* Timestamps are in nanoseconds since 2007-01-01 UTC.
|
||||||
|
*
|
||||||
|
* @param[in] message The message to modify.
|
||||||
|
* @param[in] timestamp The timestamp value to set.
|
||||||
|
*
|
||||||
|
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_invalid_message otherwise.
|
||||||
|
*/
|
||||||
|
icsneoc2_error_t icsneoc2_message_timestamp_set(icsneoc2_message_t* message, uint64_t timestamp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the timestamp of a message.
|
||||||
|
*
|
||||||
|
* Timestamps are in nanoseconds since 2007-01-01 UTC.
|
||||||
|
*
|
||||||
|
* @param[in] message The message to check.
|
||||||
|
* @param[out] timestamp Pointer to a uint64_t to copy the timestamp into.
|
||||||
|
*
|
||||||
|
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters or icsneoc2_error_invalid_message otherwise.
|
||||||
|
*/
|
||||||
|
icsneoc2_error_t icsneoc2_message_timestamp_get(icsneoc2_message_t* message, uint64_t* timestamp);
|
||||||
|
|
||||||
|
#define ICSNEOC2_MESSAGE_CAN_FLAGS_RTR 0x01 // Remote Transmission Request
|
||||||
#define ICSNEOC2_MESSAGE_CAN_FLAGS_IDE 0x02 // Identifier Extension
|
#define ICSNEOC2_MESSAGE_CAN_FLAGS_IDE 0x02 // Identifier Extension
|
||||||
#define ICSNEOC2_MESSAGE_CAN_FLAGS_FDF 0x04 // FD Format Indicator
|
#define ICSNEOC2_MESSAGE_CAN_FLAGS_FDF 0x04 // FD Format Indicator
|
||||||
#define ICSNEOC2_MESSAGE_CAN_FLAGS_BRS 0x08 // Bit Rate Switch (FD only)
|
#define ICSNEOC2_MESSAGE_CAN_FLAGS_BRS 0x08 // Bit Rate Switch (FD only)
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,8 @@ TEST(icsneoc2, test_icsneoc2_error_invalid_parameters_and_invalid_device)
|
||||||
|
|
||||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_data_get(NULL, NULL, NULL));
|
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_data_get(NULL, NULL, NULL));
|
||||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_data_set(NULL, NULL, 0));
|
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_data_set(NULL, NULL, 0));
|
||||||
|
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_timestamp_get(NULL, NULL));
|
||||||
|
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_timestamp_set(NULL, 0));
|
||||||
|
|
||||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_netid_get(NULL, NULL));
|
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_netid_get(NULL, NULL));
|
||||||
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_netid_set(NULL, 0));
|
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_netid_set(NULL, 0));
|
||||||
|
|
@ -1152,6 +1154,29 @@ TEST(icsneoc2, test_icsneoc2_message_can_props_get_can_tx_flags)
|
||||||
ICSNEOC2_MESSAGE_CAN_FLAGS_TX_ERROR);
|
ICSNEOC2_MESSAGE_CAN_FLAGS_TX_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(icsneoc2, test_icsneoc2_message_timestamp_accessors)
|
||||||
|
{
|
||||||
|
icsneoc2_message_t* message = nullptr;
|
||||||
|
ASSERT_EQ(icsneoc2_error_success, icsneoc2_message_can_create(&message));
|
||||||
|
|
||||||
|
uint64_t timestamp = 1;
|
||||||
|
ASSERT_EQ(icsneoc2_error_success, icsneoc2_message_timestamp_get(message, ×tamp));
|
||||||
|
ASSERT_EQ(0u, timestamp);
|
||||||
|
|
||||||
|
const uint64_t expected_timestamp = 1234567890123ULL;
|
||||||
|
ASSERT_EQ(icsneoc2_error_success, icsneoc2_message_timestamp_set(message, expected_timestamp));
|
||||||
|
ASSERT_EQ(icsneoc2_error_success, icsneoc2_message_timestamp_get(message, ×tamp));
|
||||||
|
ASSERT_EQ(expected_timestamp, timestamp);
|
||||||
|
|
||||||
|
ASSERT_EQ(icsneoc2_error_invalid_parameters, icsneoc2_message_timestamp_get(message, nullptr));
|
||||||
|
|
||||||
|
icsneoc2_message_free(message);
|
||||||
|
|
||||||
|
icsneoc2_message_t invalid_message;
|
||||||
|
ASSERT_EQ(icsneoc2_error_invalid_message, icsneoc2_message_timestamp_set(&invalid_message, expected_timestamp));
|
||||||
|
ASSERT_EQ(icsneoc2_error_invalid_message, icsneoc2_message_timestamp_get(&invalid_message, ×tamp));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(icsneoc2, test_icsneoc2_message_can_error_props_get_invalid_type_for_can_message)
|
TEST(icsneoc2, test_icsneoc2_message_can_error_props_get_invalid_type_for_can_message)
|
||||||
{
|
{
|
||||||
icsneoc2_message_t message;
|
icsneoc2_message_t message;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue