From 23c3cc376324a9782cde9454ba8f53ba973fba98 Mon Sep 17 00:00:00 2001 From: David Rebbe Date: Fri, 5 Apr 2019 19:04:49 -0400 Subject: [PATCH 1/2] Implemented legacy icsneoGetTimeStampForMsg() function call. Signed-off-by: David Rebbe --- api/icsneoc/icsneoc.cpp | 13 ++++++++- api/icsneolegacy/icsneolegacy.cpp | 28 +++++++++++++++++-- communication/decoder.cpp | 2 ++ communication/message/neomessage.cpp | 1 + device/device.cpp | 4 +++ .../icsneo/communication/message/message.h | 1 + .../icsneo/communication/message/neomessage.h | 3 +- include/icsneo/device/device.h | 1 + include/icsneo/icsneoc.h | 12 ++++++++ 9 files changed, 61 insertions(+), 4 deletions(-) diff --git a/api/icsneoc/icsneoc.cpp b/api/icsneoc/icsneoc.cpp index 93ac522..f57bd78 100644 --- a/api/icsneoc/icsneoc.cpp +++ b/api/icsneoc/icsneoc.cpp @@ -597,4 +597,15 @@ bool icsneo_getSupportedDevices(devicetype_t* devices, size_t* count) { *count = len; return true; -} \ No newline at end of file +} + +extern bool DLLExport icsneo_getTimestampMultiplier(const neodevice_t* device, int* multiplier) +{ + if (!icsneo_isValidNeoDevice(device)) { + ErrorManager::GetInstance().add(APIError::InvalidNeoDevice); + return false; + } + + *multiplier = device->device->getTimestampMultiplier(); + return true; +} diff --git a/api/icsneolegacy/icsneolegacy.cpp b/api/icsneolegacy/icsneolegacy.cpp index fbcf679..25a17d6 100644 --- a/api/icsneolegacy/icsneolegacy.cpp +++ b/api/icsneolegacy/icsneolegacy.cpp @@ -60,6 +60,12 @@ static void NeoMessageToSpyMessage(const neomessage_t& newmsg, icsSpyMessage& ol oldmsg.Protocol = SPY_PROTOCOL_ETHERNET; break; } + // Timestamp - epoch = 1/1/2007 - 25ns per tick most of the time + uint64_t t = newmsg.timestamp; + if (newmsg.timestampMultiplier) + t /= newmsg.timestampMultiplier; + oldmsg.TimeHardware2 = (unsigned long)(t >> 32); + oldmsg.TimeHardware = (unsigned long)(t & 0xFFFFFFFF); } //Basic Functions @@ -241,8 +247,26 @@ int icsneoEnableNetworkRXQueue(void* hObject, int iEnable) { } int icsneoGetTimeStampForMsg(void* hObject, icsSpyMessage* pMsg, double* pTimeStamp) { - // TODO Implement - return false; + if(!icsneoValidateHObject(hObject)) + return false; + neodevice_t* device = (neodevice_t*)hObject; + + int multiplier = 0; + if (!icsneo_getTimestampMultiplier(device, &multiplier)) + return false; + + // Convert back to ticks + uint64_t ticks = pMsg->TimeHardware2; + ticks <<= 32; + ticks += pMsg->TimeHardware; + + // convert to ns + ticks *= multiplier; + + // icsneoGetTimeStampForMsg() expects pTimeStamp to be in seconds + *pTimeStamp = ticks / (double)1000000000; + + return true; } void icsneoGetISO15765Status(void* hObject, int lNetwork, int lClearTxStatus, int lClearRxStatus, int*lTxStatus, int*lRxStatus) { diff --git a/communication/decoder.cpp b/communication/decoder.cpp index 863d2fa..15c0062 100644 --- a/communication/decoder.cpp +++ b/communication/decoder.cpp @@ -28,6 +28,7 @@ bool Decoder::decode(std::shared_ptr& result, const std::shared_ptrtimestamp *= timestampMultiplier; + result->timestampMultiplier = timestampMultiplier; result->network = packet->network; return true; case Network::Type::CAN: @@ -43,6 +44,7 @@ bool Decoder::decode(std::shared_ptr& result, const std::shared_ptrtimestamp *= timestampMultiplier; + result->timestampMultiplier = timestampMultiplier; result->network = packet->network; return true; } diff --git a/communication/message/neomessage.cpp b/communication/message/neomessage.cpp index 1774997..d189983 100644 --- a/communication/message/neomessage.cpp +++ b/communication/message/neomessage.cpp @@ -14,6 +14,7 @@ neomessage_t icsneo::CreateNeoMessage(const std::shared_ptr message) { neomsg.length = message->data.size(); neomsg.data = message->data.data(); neomsg.timestamp = message->timestamp; + neomsg.timestampMultiplier = message->timestampMultiplier; neomsg.status.globalError = message->error; neomsg.status.transmitMessage = message->transmitted; diff --git a/device/device.cpp b/device/device.cpp index 04ec6e8..34cb678 100644 --- a/device/device.cpp +++ b/device/device.cpp @@ -67,6 +67,10 @@ bool Device::SerialStringIsNumeric(const std::string& serial) { return isdigit(serial[0]) && isdigit(serial[1]); } +int Device::getTimestampMultiplier() const { + return com->decoder->timestampMultiplier; +} + std::string Device::describe() const { std::stringstream ss; ss << getType() << ' ' << getSerial(); diff --git a/include/icsneo/communication/message/message.h b/include/icsneo/communication/message/message.h index 3ed805c..6aa2522 100644 --- a/include/icsneo/communication/message/message.h +++ b/include/icsneo/communication/message/message.h @@ -12,6 +12,7 @@ public: Network network; std::vector data; uint64_t timestamp = 0; + int timestampMultiplier = 0; uint16_t description = 0; bool transmitted = false; bool error = false; diff --git a/include/icsneo/communication/message/neomessage.h b/include/icsneo/communication/message/neomessage.h index 28892c1..e093a76 100644 --- a/include/icsneo/communication/message/neomessage.h +++ b/include/icsneo/communication/message/neomessage.h @@ -108,7 +108,8 @@ typedef struct { uint8_t header[4]; uint16_t netid; uint8_t type; - uint8_t reserved[17]; + uint8_t reserved[15]; + uint16_t timestampMultiplier; } neomessage_t; // 72 bytes total // Any time you add another neomessage_*_t type, make sure to add it to the static_asserts below! diff --git a/include/icsneo/device/device.h b/include/icsneo/device/device.h index 5a1a252..8910f06 100644 --- a/include/icsneo/device/device.h +++ b/include/icsneo/device/device.h @@ -29,6 +29,7 @@ public: static uint32_t SerialStringToNum(const std::string& serial); static bool SerialStringIsNumeric(const std::string& serial); + int getTimestampMultiplier() const; DeviceType getType() const { return DeviceType(data.type); } uint16_t getProductId() const { return productId; } std::string getSerial() const { return data.serial; } diff --git a/include/icsneo/icsneoc.h b/include/icsneo/icsneoc.h index 3a5e7f2..b7380a1 100644 --- a/include/icsneo/icsneoc.h +++ b/include/icsneo/icsneoc.h @@ -626,6 +626,18 @@ extern size_t DLLExport icsneo_getErrorLimit(void); */ extern bool DLLExport icsneo_getSupportedDevices(devicetype_t* devices, size_t* count); +/** + * \brief Get the devices timestamp multiplier + * \param[out] device A pointer to a buffer of devicetype_t structures which will be written to. + * \param[inout] multiplier A pointer to an int, for legacy tick rate to ns + + * \returns True unless device is invalid + */ +extern bool DLLExport icsneo_getTimestampMultiplier(const neodevice_t* device, int* multiplier); + + + + #ifdef __cplusplus } // extern "C" #endif From 7cf0ec5f4f1ecaac079521fc80c0dff3bbaf0f94 Mon Sep 17 00:00:00 2001 From: Paul Hollinsky Date: Mon, 6 May 2019 12:32:04 -0400 Subject: [PATCH 2/2] Rename timestampMultiplier to timestampResolution We've also decided to leave it out of the message structures since, for most uses going forward, it will not be needed. Anyone who wants the timestamp resolution can always make the inexpensive device call to get it. --- api/icsneoc/icsneoc.cpp | 9 ++++-- api/icsneolegacy/icsneolegacy.cpp | 31 +++++++++++++------ communication/decoder.cpp | 14 ++++----- communication/message/neomessage.cpp | 1 - communication/packet/canpacket.cpp | 4 +-- communication/packet/ethernetpacket.cpp | 4 +-- device/device.cpp | 4 +-- include/icsneo/communication/decoder.h | 2 +- .../icsneo/communication/message/message.h | 1 - .../icsneo/communication/message/neomessage.h | 3 +- include/icsneo/device/device.h | 2 +- include/icsneo/device/radgalaxy/radgalaxy.h | 2 +- include/icsneo/device/radstar2/radstar2.h | 2 +- .../icsneo/device/radsupermoon/radsupermoon.h | 2 +- include/icsneo/icsnVC40.h | 12 +++++++ include/icsneo/icsneoc.h | 10 +++--- 16 files changed, 64 insertions(+), 39 deletions(-) diff --git a/api/icsneoc/icsneoc.cpp b/api/icsneoc/icsneoc.cpp index f57bd78..29eb4e6 100644 --- a/api/icsneoc/icsneoc.cpp +++ b/api/icsneoc/icsneoc.cpp @@ -599,13 +599,18 @@ bool icsneo_getSupportedDevices(devicetype_t* devices, size_t* count) { return true; } -extern bool DLLExport icsneo_getTimestampMultiplier(const neodevice_t* device, int* multiplier) +extern bool DLLExport icsneo_getTimestampResolution(const neodevice_t* device, uint16_t* resolution) { if (!icsneo_isValidNeoDevice(device)) { ErrorManager::GetInstance().add(APIError::InvalidNeoDevice); return false; } - *multiplier = device->device->getTimestampMultiplier(); + if (resolution == nullptr) { + ErrorManager::GetInstance().add(APIError::RequiredParameterNull); + return false; + } + + *resolution = device->device->getTimestampResolution(); return true; } diff --git a/api/icsneolegacy/icsneolegacy.cpp b/api/icsneolegacy/icsneolegacy.cpp index 3adc2ec..59ec2d0 100644 --- a/api/icsneolegacy/icsneolegacy.cpp +++ b/api/icsneolegacy/icsneolegacy.cpp @@ -37,7 +37,7 @@ static NeoDevice OldNeoDeviceFromNew(const neodevice_t* newnd) { return oldnd; } -static void NeoMessageToSpyMessage(const neomessage_t& newmsg, icsSpyMessage& oldmsg) { +static void NeoMessageToSpyMessage(const neodevice_t* device, const neomessage_t& newmsg, icsSpyMessage& oldmsg) { memset(&oldmsg, 0, sizeof(icsSpyMessage)); oldmsg.NumberBytesData = (uint8_t)std::min(newmsg.length, (size_t)255); oldmsg.NumberBytesHeader = 4; @@ -59,12 +59,25 @@ static void NeoMessageToSpyMessage(const neomessage_t& newmsg, icsSpyMessage& ol oldmsg.Protocol = SPY_PROTOCOL_ETHERNET; break; } + // Timestamp - epoch = 1/1/2007 - 25ns per tick most of the time uint64_t t = newmsg.timestamp; - if (newmsg.timestampMultiplier) - t /= newmsg.timestampMultiplier; - oldmsg.TimeHardware2 = (unsigned long)(t >> 32); - oldmsg.TimeHardware = (unsigned long)(t & 0xFFFFFFFF); + uint16_t res = 0; + if (icsneo_getTimestampResolution(device, &res)) { + t /= res; + oldmsg.TimeHardware2 = (unsigned long)(t >> 32); + oldmsg.TimeHardware = (unsigned long)(t & 0xFFFFFFFF); + switch (res) { + case 25: + oldmsg.TimeStampHardwareID = HARDWARE_TIMESTAMP_ID_NEORED_25NS; + break; + case 10: + oldmsg.TimeStampHardwareID = HARDWARE_TIMESTAMP_ID_NEORED_10NS; + break; + default: + oldmsg.TimeStampHardwareID = HARDWARE_TIMESTAMP_ID_NONE; + } + } } //Basic Functions @@ -186,7 +199,7 @@ int icsneoGetMessages(void* hObject, icsSpyMessage* pMsg, int* pNumberOfMessages *pNumberOfErrors = 0; for(size_t i = 0; i < messageCount; i++) - NeoMessageToSpyMessage(messages[i], pMsg[i]); + NeoMessageToSpyMessage(device, messages[i], pMsg[i]); return true; } @@ -236,8 +249,8 @@ int icsneoGetTimeStampForMsg(void* hObject, icsSpyMessage* pMsg, double* pTimeSt return false; neodevice_t* device = (neodevice_t*)hObject; - int multiplier = 0; - if (!icsneo_getTimestampMultiplier(device, &multiplier)) + uint16_t resolution = 0; + if (!icsneo_getTimestampResolution(device, &resolution)) return false; // Convert back to ticks @@ -246,7 +259,7 @@ int icsneoGetTimeStampForMsg(void* hObject, icsSpyMessage* pMsg, double* pTimeSt ticks += pMsg->TimeHardware; // convert to ns - ticks *= multiplier; + ticks *= resolution; // icsneoGetTimeStampForMsg() expects pTimeStamp to be in seconds *pTimeStamp = ticks / (double)1000000000; diff --git a/communication/decoder.cpp b/communication/decoder.cpp index 15c0062..3bb8edd 100644 --- a/communication/decoder.cpp +++ b/communication/decoder.cpp @@ -25,10 +25,9 @@ bool Decoder::decode(std::shared_ptr& result, const std::shared_ptrtimestamp *= timestampMultiplier; - result->timestampMultiplier = timestampMultiplier; + // Timestamps are in (resolution) ns increments since 1/1/2007 GMT 00:00:00.0000 + // The resolution depends on the device + result->timestamp *= timestampResolution; result->network = packet->network; return true; case Network::Type::CAN: @@ -41,10 +40,9 @@ bool Decoder::decode(std::shared_ptr& result, const std::shared_ptrtimestamp *= timestampMultiplier; - result->timestampMultiplier = timestampMultiplier; + // Timestamps are in (resolution) ns increments since 1/1/2007 GMT 00:00:00.0000 + // The resolution depends on the device + result->timestamp *= timestampResolution; result->network = packet->network; return true; } diff --git a/communication/message/neomessage.cpp b/communication/message/neomessage.cpp index 98fced3..191eb7c 100644 --- a/communication/message/neomessage.cpp +++ b/communication/message/neomessage.cpp @@ -14,7 +14,6 @@ neomessage_t icsneo::CreateNeoMessage(const std::shared_ptr message) { neomsg.length = message->data.size(); neomsg.data = message->data.data(); neomsg.timestamp = message->timestamp; - neomsg.timestampMultiplier = message->timestampMultiplier; neomsg.status.globalError = message->error; neomsg.status.transmitMessage = message->transmitted; diff --git a/communication/packet/canpacket.cpp b/communication/packet/canpacket.cpp index 2bb57c8..9ec41b6 100644 --- a/communication/packet/canpacket.cpp +++ b/communication/packet/canpacket.cpp @@ -17,8 +17,8 @@ std::shared_ptr HardwareCANPacket::DecodeToMessage(const std::vector msg->arbid = data->header.SID; } - // This timestamp is raw off the device (in timestampMultiplier increments) - // Decoder will fix as it has information about the timestampMultiplier increments + // This timestamp is raw off the device (in timestampResolution increments) + // Decoder will fix as it has information about the timestampResolution increments msg->timestamp = data->timestamp.TS; // DLC diff --git a/communication/packet/ethernetpacket.cpp b/communication/packet/ethernetpacket.cpp index e380f9f..4d1f6bd 100644 --- a/communication/packet/ethernetpacket.cpp +++ b/communication/packet/ethernetpacket.cpp @@ -40,8 +40,8 @@ std::shared_ptr HardwareEthernetPacket::DecodeToMessage(const s if(message.frameTooShort) message.error = true; - // This timestamp is raw off the device (in timestampMultiplier increments) - // Decoder will fix as it has information about the timestampMultiplier increments + // This timestamp is raw off the device (in timestampResolution increments) + // Decoder will fix as it has information about the timestampResolution increments message.timestamp = packet->timestamp.TS; // Network ID is also not set, this will be fixed in the Decoder as well diff --git a/device/device.cpp b/device/device.cpp index 34cb678..741286e 100644 --- a/device/device.cpp +++ b/device/device.cpp @@ -67,8 +67,8 @@ bool Device::SerialStringIsNumeric(const std::string& serial) { return isdigit(serial[0]) && isdigit(serial[1]); } -int Device::getTimestampMultiplier() const { - return com->decoder->timestampMultiplier; +uint16_t Device::getTimestampResolution() const { + return com->decoder->timestampResolution; } std::string Device::describe() const { diff --git a/include/icsneo/communication/decoder.h b/include/icsneo/communication/decoder.h index 792cd37..bdeab9d 100644 --- a/include/icsneo/communication/decoder.h +++ b/include/icsneo/communication/decoder.h @@ -19,7 +19,7 @@ public: Decoder(device_errorhandler_t err) : err(err) {} bool decode(std::shared_ptr& result, const std::shared_ptr& packet); - int timestampMultiplier = 25; + uint16_t timestampResolution = 25; private: device_errorhandler_t err; diff --git a/include/icsneo/communication/message/message.h b/include/icsneo/communication/message/message.h index 6aa2522..3ed805c 100644 --- a/include/icsneo/communication/message/message.h +++ b/include/icsneo/communication/message/message.h @@ -12,7 +12,6 @@ public: Network network; std::vector data; uint64_t timestamp = 0; - int timestampMultiplier = 0; uint16_t description = 0; bool transmitted = false; bool error = false; diff --git a/include/icsneo/communication/message/neomessage.h b/include/icsneo/communication/message/neomessage.h index e093a76..28892c1 100644 --- a/include/icsneo/communication/message/neomessage.h +++ b/include/icsneo/communication/message/neomessage.h @@ -108,8 +108,7 @@ typedef struct { uint8_t header[4]; uint16_t netid; uint8_t type; - uint8_t reserved[15]; - uint16_t timestampMultiplier; + uint8_t reserved[17]; } neomessage_t; // 72 bytes total // Any time you add another neomessage_*_t type, make sure to add it to the static_asserts below! diff --git a/include/icsneo/device/device.h b/include/icsneo/device/device.h index 8910f06..410d391 100644 --- a/include/icsneo/device/device.h +++ b/include/icsneo/device/device.h @@ -29,7 +29,7 @@ public: static uint32_t SerialStringToNum(const std::string& serial); static bool SerialStringIsNumeric(const std::string& serial); - int getTimestampMultiplier() const; + uint16_t getTimestampResolution() const; DeviceType getType() const { return DeviceType(data.type); } uint16_t getProductId() const { return productId; } std::string getSerial() const { return data.serial; } diff --git a/include/icsneo/device/radgalaxy/radgalaxy.h b/include/icsneo/device/radgalaxy/radgalaxy.h index 43ec2d8..9b8319b 100644 --- a/include/icsneo/device/radgalaxy/radgalaxy.h +++ b/include/icsneo/device/radgalaxy/radgalaxy.h @@ -99,7 +99,7 @@ protected: virtual void setupDecoder(Decoder& decoder) override { Device::setupDecoder(decoder); - decoder.timestampMultiplier = 10; // Timestamps are in 10ns increments instead of the usual 25ns + decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns } virtual void setupSupportedRXNetworks(std::vector& rxNetworks) override { diff --git a/include/icsneo/device/radstar2/radstar2.h b/include/icsneo/device/radstar2/radstar2.h index dea0e17..19450bf 100644 --- a/include/icsneo/device/radstar2/radstar2.h +++ b/include/icsneo/device/radstar2/radstar2.h @@ -41,7 +41,7 @@ protected: virtual void setupDecoder(Decoder& decoder) override { Device::setupDecoder(decoder); - decoder.timestampMultiplier = 10; // Timestamps are in 10ns increments instead of the usual 25ns + decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns } virtual void setupSupportedRXNetworks(std::vector& rxNetworks) override { diff --git a/include/icsneo/device/radsupermoon/radsupermoon.h b/include/icsneo/device/radsupermoon/radsupermoon.h index 22cdfd5..75af958 100644 --- a/include/icsneo/device/radsupermoon/radsupermoon.h +++ b/include/icsneo/device/radsupermoon/radsupermoon.h @@ -23,7 +23,7 @@ public: protected: virtual void setupDecoder(Decoder& decoder) override { - decoder.timestampMultiplier = 10; // Timestamps are in 10ns increments instead of the usual 25ns + decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns } private: diff --git a/include/icsneo/icsnVC40.h b/include/icsneo/icsnVC40.h index ce89fe1..6548e78 100644 --- a/include/icsneo/icsnVC40.h +++ b/include/icsneo/icsnVC40.h @@ -398,6 +398,18 @@ typedef unsigned __int64 uint64_t; #define NEOVI_RED_TIMESTAMP_2_10NS 429.4967296 #define NEOVI_RED_TIMESTAMP_1_10NS 0.000000010 +#define HARDWARE_TIMESTAMP_ID_NONE (unsigned char)0 +#define HARDWARE_TIMESTAMP_ID_VSI (unsigned char)1 +#define HARDWARE_TIMESTAMP_ID_AVT_716 (unsigned char)2 +#define HARDWARE_TIMESTAMP_ID_NI_CAN (unsigned char)3 +#define HARDWARE_TIMESTAMP_ID_NEOVI (unsigned char)4 +#define HARDWARE_TIMESTAMP_ID_AVT_717 (unsigned char)5 +#define HARDWARE_TIMESTAMP_ID_NEOv6_VCAN (unsigned char)6 +#define HARDWARE_TIMESTAMP_ID_DOUBLE_SEC (unsigned char)7 +#define HARDWARE_TIMESTAMP_ID_NEORED_10US (unsigned char)8 +#define HARDWARE_TIMESTAMP_ID_NEORED_25NS (unsigned char)9 +#define HARDWARE_TIMESTAMP_ID_NEORED_10NS (unsigned char)10 + typedef struct { uint32_t DeviceType; diff --git a/include/icsneo/icsneoc.h b/include/icsneo/icsneoc.h index b7380a1..4d9cd1b 100644 --- a/include/icsneo/icsneoc.h +++ b/include/icsneo/icsneoc.h @@ -627,13 +627,13 @@ extern size_t DLLExport icsneo_getErrorLimit(void); extern bool DLLExport icsneo_getSupportedDevices(devicetype_t* devices, size_t* count); /** - * \brief Get the devices timestamp multiplier - * \param[out] device A pointer to a buffer of devicetype_t structures which will be written to. - * \param[inout] multiplier A pointer to an int, for legacy tick rate to ns + * \brief Get the timestamp resolution for the given device + * \param[out] device A pointer to the neodevice_t structure specifying the device to read out the timestamp for. + * \param[out] resolution A pointer to a uint16_t where the resolution will be stored. This value is in nanoseconds. - * \returns True unless device is invalid + * \returns True if the resolution was written */ -extern bool DLLExport icsneo_getTimestampMultiplier(const neodevice_t* device, int* multiplier); +extern bool DLLExport icsneo_getTimestampResolution(const neodevice_t* device, uint16_t* resolution);