From f16d9700fa639b494b7ab9cffba9653f576668b7 Mon Sep 17 00:00:00 2001 From: Clovis Durand Date: Sat, 4 Apr 2020 16:47:58 +0200 Subject: [PATCH 1/5] [#13] Added FileInfo, DeviceInfo, DummyUsage & Comments sections to OSCOOD Signed-off-by: Clovis Durand --- generator/inc/OSCOOD.hpp | 210 ++++++++++++++++- generator/src/OSCOOD.cpp | 490 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 699 insertions(+), 1 deletion(-) diff --git a/generator/inc/OSCOOD.hpp b/generator/inc/OSCOOD.hpp index db5ef68..2eecbb1 100644 --- a/generator/inc/OSCOOD.hpp +++ b/generator/inc/OSCOOD.hpp @@ -15,9 +15,11 @@ #include #include #include +#include /* C System */ #include +#include /* Defines --------------------------------------------- */ @@ -48,13 +50,219 @@ class API_EXPORT OSCOOD { /* Getters */ std::map indexes(void) const; + std::string name(void) const; + + std::string fileName(void) const; + uint8_t fileVersion(void) const; + uint8_t fileRevision(void) const; + std::string EDSVersion(void) const; + std::string description(void) const; + std::string creationDate(const bool &pFormat = false) const; + std::string creationTime(const bool &pFormat = false) const; + std::string createdBy(void) const; + std::string modificationDate(const bool &pFormat = false) const; + std::string modificationTime(const bool &pFormat = false) const; + std::string modifiedBy(void) const; + + std::string vendorName(void) const; + uint32_t vendorNumber(void) const; + std::string productName(void) const; + uint32_t productNumber(void) const; + uint32_t revisionNumber(void) const; + std::string orderCode(void) const; + bool baudrate10Supported(void) const; + bool baudrate20Supported(void) const; + bool baudrate50Supported(void) const; + bool baudrate125Supported(void) const; + bool baudrate250Supported(void) const; + bool baudrate500Supported(void) const; + bool baudrate800Supported(void) const; + bool baudrate1000Supported(void) const; + bool simpleBootUpMaster(void) const; + bool simpleBootUpSlave(void) const; + uint8_t granularity(void) const; + uint8_t dynamicChannelsSupported(void) const; + bool groupMessaging(void) const; + uint16_t nrOfRPDOs(void) const; + uint16_t nrOfTPDOs(void) const; + bool LSSSupported(void) const; + + std::string comments(void) const; + std::string commentLine(const uint32_t &pLine) const; + uint32_t commentLineCount(void) const; + + bool dummy0001Supported(void) const; + bool dummy0002Supported(void) const; + bool dummy0003Supported(void) const; + bool dummy0004Supported(void) const; + bool dummy0005Supported(void) const; + bool dummy0006Supported(void) const; + bool dummy0007Supported(void) const; + /* Setters */ bool addIndex(OSCOODIndex *pIndex); bool removeIndex(const OSCOODIndex * const pIndex); bool removeIndex(const uint16_t &pIndex); + + void setName(const std::string &pName); + + void setFileName(const std::string &pFileName); + void setFileVersion(const uint8_t &pVersion); + void setFileRevision(const uint8_t &pRevision); + void setEDSVersion(const std::string &pVersion); + void setDescription(const std::string &pDescription); + bool setCreationDate(const std::string &pDate); + bool setCreationTime(const std::string &pTime); + void setCreatedBy(const std::string &pCreatedBy); + bool setModificationDate(const std::string &pDate); + bool setModificationTime(const std::string &pTime); + void setModifiedBy(const std::string &pModifiedBy); + + void setVendorName(const std::string &pName); + void setVendorNumber(const uint32_t &pNumber); + void setProductName(const std::string &pName); + void setProductNumber(const uint32_t &pNumber); + void setRevisionNumber(const uint32_t &pRevision); + void setOrderCode(const std::string &pOrderCode); + void setBaudrate10Supported(const bool &pSupport); + void setBaudrate20Supported(const bool &pSupport); + void setBaudrate50Supported(const bool &pSupport); + void setBaudrate125Supported(const bool &pSupport); + void setBaudrate250Supported(const bool &pSupport); + void setBaudrate500Supported(const bool &pSupport); + void setBaudrate800Supported(const bool &pSupport); + void setBaudrate1000Supported(const bool &pSupport); + void setSimpleBootUpMaster(const bool &pSupport); + void setSimpleBootUpSlave(const bool &pSupport); + void setGranularity(const uint8_t &pGranularity); + void setDynamicChannelsSupported(const uint8_t &pChannelCount); + void setGroupMessaging(const bool &pSupport); + void setNrOfRPDOs(const uint16_t &pRPDONb); + void setNrOfTPDOs(const uint16_t &pTPDONb); + void setLSSSupported(const bool &pSupport); + + void setComments(const std::string &pComments); + + void setDummy0001Supported(const bool &pSupport); + void setDummy0002Supported(const bool &pSupport); + void setDummy0003Supported(const bool &pSupport); + void setDummy0004Supported(const bool &pSupport); + void setDummy0005Supported(const bool &pSupport); + void setDummy0006Supported(const bool &pSupport); + void setDummy0007Supported(const bool &pSupport); protected: private: - std::map mObjects; + std::map mObjects; /**< Contents of the Object Dictionary */ + + std::string mName; /**< Name of the Object Dictionary */ + + /* FileInfo -------------------------- */ + + std::string mFileName; /**< Shall indicate the file name (according to OS restrictions) */ + uint8_t mFileVersion; /**< Shall indicate the actual file version (Unsigned8) */ + uint8_t mFileRevision; /**< Shall indicate the actual file revision (Unsigned8) */ + + /** + * @brief Shall indicate the version of the specification (3 characters) in the format “x.y”. + * If the entry is missing, this is equal to “3.0”. + * + * @warning EDS files should use at least “4.0", as it's the specification version + * used for the development of this project. + */ + std::string mEDSVersion; + + std::string mDesription; /**< Shall provide a file description (max 243 characters) */ + + /** + * @brief Shall provide the file creation time (24-hour "hh:mm:ss" format) + * and date (DD/MM/YYYY format) + * + * @warning The specification actually specifies the "hh:mm (AP|PM)" 12-hour format, + * but it is less used than the european 24-hour format. + * + * @details This will hold both the CreationTime and CreationDate attributes. + */ + std::time_t mCreationDateTime; + + std::string mCreatedBy; /**< shall provide the name or a description of the file creator (max. 245 characters) */ + + /** + * @brief Shall provide the file modification time (24-hour "hh:mm:ss" format) + * and date (DD/MM/YYYY format) + * + * @warning The specification actually specifies the "hh:mm (AP|PM)" 12-hour format, + * but it is less used than the european 24-hour format. + * + * @details This will hold both the ModificationTime and ModificationDate attributes. + */ + std::time_t mModificationDateTime; + + std::string mModifiedBy; /**< shall provide the name or a description of the file updator (max. 245 characters) */ + + /* DeviceInfo ------------------------ */ + std::string mVendorName; /**< shall provide the vendor name (max. 244 characters) */ + uint32_t mVendorNumber; /**< shall provide the unique vendor ID according to identity object sub-index 01h (Unsigned32) */ + + std::string mProductName; /**< shall provide the product name (max. 243 characters) */ + uint32_t mProductNumber; /**< shall provide the product code according to identity object sub-index 02h (Unsigned32) */ + + uint32_t mRevisionNumber; /**< shall provide the product revision number according to identity object sub-index 03h (Unsigned32) */ + + std::string mOrderCode; /**< shall provide the order code for this product (max. 245 characters) */ + + bool mBaudRate_10; /**< Shall indicate if the 10kbps baudrate is supported (Boolean, 0 = not supported, 1=supported) */ + bool mBaudRate_20; /**< Shall indicate if the 20kbps baudrate is supported (Boolean, 0 = not supported, 1=supported) */ + bool mBaudRate_50; /**< Shall indicate if the 50kbps baudrate is supported (Boolean, 0 = not supported, 1=supported) */ + bool mBaudRate_125; /**< Shall indicate if the 125kbps baudrate is supported (Boolean, 0 = not supported, 1=supported) */ + bool mBaudRate_250; /**< Shall indicate if the 250kbps baudrate is supported (Boolean, 0 = not supported, 1=supported) */ + bool mBaudRate_500; /**< Shall indicate if the 500kbps baudrate is supported (Boolean, 0 = not supported, 1=supported) */ + bool mBaudRate_800; /**< Shall indicate if the 800kbps baudrate is supported (Boolean, 0 = not supported, 1=supported) */ + bool mBaudRate_1000; /**< Shall indicate if the 1000kbps baudrate is supported (Boolean, 0 = not supported, 1=supported) */ + + bool mSimpleBootUpMaster; /**< Shall indicate the simple boot-up master functionality */ + bool mSimpleBootUpSlave; /**< Shall indicate the simple boot-up slave functionality */ + + /** + * @breif Shall provide the granularity allowed for the mapping on this device. + * + * @details Most of the existing devices support a granularity of 8 + * - 0 - mapping not modifiable + * - [1; 64] mapping granularity + * + * TODO : ??? + * Default is 8 for now + */ + uint8_t mGranularity; + + /** + * @breif Indicates the facility of dynamic variable generation. + * If the value is unequal to 0, the additional section DynamicChannels exists. + * + * TODO : ??? + * Default is 0 for now + */ + uint8_t mDynamicChannelsSupported; + + bool mGroupMessaging; /**< 1 : MPDOs are supported, 0 : MPDOs are not supported */ + + uint16_t mNrOfRXPDO; /**< Number of supported RPDOs */ + uint16_t mNrOfTXPDO; /**< Number of supported TPDOs */ + + bool mLSSSupported; /**< Indicate if the LSS feature is supported */ + + /* Comments -------------------------- */ + std::string mComments; /**< EDS Comments */ + uint32_t mCommentLineCount; /**< Number of comment lines */ + + /* DummyUsage ------------------------ */ + /* TODO : Which mapping dummy for which basic type ? */ + bool mDummy0001; /**< Indicated if the usage of Dummy0001 is supported */ + bool mDummy0002; /**< Indicated if the usage of Dummy0002 is supported */ + bool mDummy0003; /**< Indicated if the usage of Dummy0003 is supported */ + bool mDummy0004; /**< Indicated if the usage of Dummy0004 is supported */ + bool mDummy0005; /**< Indicated if the usage of Dummy0005 is supported */ + bool mDummy0006; /**< Indicated if the usage of Dummy0006 is supported */ + bool mDummy0007; /**< Indicated if the usage of Dummy0007 is supported */ }; #endif /* OSCOOD_HPP */ \ No newline at end of file diff --git a/generator/src/OSCOOD.cpp b/generator/src/OSCOOD.cpp index 5dc9ddc..26438c9 100644 --- a/generator/src/OSCOOD.cpp +++ b/generator/src/OSCOOD.cpp @@ -15,6 +15,7 @@ #include #include #include +#include /* C System */ #include @@ -61,6 +62,221 @@ std::map OSCOOD::indexes(void) const { return mObjects; } +std::string OSCOOD::name(void) const { + return mName; +} + +std::string OSCOOD::fileName(void) const { + return mFileName; +} + +uint8_t OSCOOD::fileVersion(void) const { + return mFileVersion; +} + +uint8_t OSCOOD::fileRevision(void) const { + return mFileRevision; +} + +std::string OSCOOD::EDSVersion(void) const { + return mEDSVersion; +} + +std::string OSCOOD::description(void) const { + return mDesription; +} + +std::string OSCOOD::creationDate(const bool &pFormat) const { + char lDateStr[20U]; + struct tm *lDateTimeStruct = std::gmtime(&mCreationDateTime); + if(pFormat) + (void)strftime(lDateStr, 20U, "%d/%m/%Y", lDateTimeStruct); + else + (void)strftime(lDateStr, 20U, "%Y-%m-%d", lDateTimeStruct); + return std::string(lDateStr); +} + +std::string OSCOOD::creationTime(const bool &pFormat) const { + char lTimeStr[20U]; + struct tm *lDateTimeStruct = std::gmtime(&mCreationDateTime); + if(pFormat) + (void)strftime(lTimeStr, 20U, "%H:%M:%S", lDateTimeStruct); + else + (void)strftime(lTimeStr, 20U, "%I:%M%p", lDateTimeStruct); + return std::string(lTimeStr); +} + +std::string OSCOOD::createdBy(void) const { + return mCreatedBy; +} + +std::string OSCOOD::modificationDate(const bool &pFormat) const { + char lDateStr[20U]; + struct tm *lDateTimeStruct = std::gmtime(&mModificationDateTime); + if(pFormat) + (void)strftime(lDateStr, 20U, "%d/%m/%Y", lDateTimeStruct); + else + (void)strftime(lDateStr, 20U, "%Y-%m-%d", lDateTimeStruct); + return std::string(lDateStr); +} + +std::string OSCOOD::modificationTime(const bool &pFormat) const { + char lTimeStr[20U]; + struct tm *lDateTimeStruct = std::gmtime(&mModificationDateTime); + if(pFormat) + (void)strftime(lTimeStr, 20U, "%H:%M:%S", lDateTimeStruct); + else + (void)strftime(lTimeStr, 20U, "%I:%M%p", lDateTimeStruct); + return std::string(lTimeStr); +} + +std::string OSCOOD::modifiedBy(void) const { + return mModifiedBy; +} + +std::string OSCOOD::vendorName(void) const { + return mVendorName; +} + +uint32_t OSCOOD::vendorNumber(void) const { + return mVendorNumber; +} + +std::string OSCOOD::productName(void) const { + return mProductName; +} + +uint32_t OSCOOD::productNumber(void) const { + return mProductNumber; +} + +uint32_t OSCOOD::revisionNumber(void) const { + return mRevisionNumber; +} + +std::string OSCOOD::orderCode(void) const { + return mOrderCode; +} + +bool OSCOOD::baudrate10Supported(void) const { + return mBaudRate_10; +} + +bool OSCOOD::baudrate20Supported(void) const { + return mBaudRate_20; +} + +bool OSCOOD::baudrate50Supported(void) const { + return mBaudRate_50; +} + +bool OSCOOD::baudrate125Supported(void) const { + return mBaudRate_125; +} + +bool OSCOOD::baudrate250Supported(void) const { + return mBaudRate_250; +} + +bool OSCOOD::baudrate500Supported(void) const { + return mBaudRate_500; +} + +bool OSCOOD::baudrate800Supported(void) const { + return mBaudRate_800; +} + +bool OSCOOD::baudrate1000Supported(void) const { + return mBaudRate_1000; +} + +bool OSCOOD::simpleBootUpMaster(void) const { + return mSimpleBootUpMaster; +} + +bool OSCOOD::simpleBootUpSlave(void) const { + return mSimpleBootUpSlave; +} + +uint8_t OSCOOD::granularity(void) const { + return mGranularity; +} + +uint8_t OSCOOD::dynamicChannelsSupported(void) const { + return mDynamicChannelsSupported; +} + +bool OSCOOD::groupMessaging(void) const { + return mGroupMessaging; +} + +uint16_t OSCOOD::nrOfRPDOs(void) const { + return mNrOfRXPDO; +} + +uint16_t OSCOOD::nrOfTPDOs(void) const { + return mNrOfTXPDO; +} + +bool OSCOOD::LSSSupported(void) const { + return mLSSSupported; +} + +std::string OSCOOD::comments(void) const { + return mComments; +} + +std::string OSCOOD::commentLine(const uint32_t &pLine) const { + if(mCommentLineCount <= pLine) { + std::cerr << "[ERROR] Line arg out of bounds (bound : " << mCommentLineCount << " <= arg : " << pLine << ")" << std::endl; + return "[ERROR OCCURED]"; + } + + std::istringstream lISS(mComments); + for(uint32_t i = 0U; i < mCommentLineCount; i++) { + std::string lLine = ""; + (void)std::getline(lISS, lLine); + if(pLine == i) { + return lLine; + } + } + + /* Line not found, shouldn't happen */ + return "[ERROR OCCURED]"; +} + +uint32_t OSCOOD::commentLineCount(void) const { + return mCommentLineCount; +} + +bool OSCOOD::dummy0001Supported(void) const { + return mDummy0001; +} + +bool OSCOOD::dummy0002Supported(void) const { + return mDummy0002; +} + +bool OSCOOD::dummy0003Supported(void) const { + return mDummy0003; +} + +bool OSCOOD::dummy0004Supported(void) const { + return mDummy0004; +} + +bool OSCOOD::dummy0005Supported(void) const { + return mDummy0005; +} + +bool OSCOOD::dummy0006Supported(void) const { + return mDummy0006; +} + +bool OSCOOD::dummy0007Supported(void) const { + return mDummy0007; +} + /* Setters */ bool OSCOOD::addIndex(OSCOODIndex *pIndex) { /* Check if the index already exists */ @@ -99,3 +315,277 @@ bool OSCOOD::removeIndex(const uint16_t &pIndex) { std::cerr << "[ERROR] Index not found" << std::endl; return false; } + +void OSCOOD::setName(const std::string &pName) { + mName = pName; +} + +void OSCOOD::setFileName(const std::string &pFileName) { + mFileName = pFileName; +} + +void OSCOOD::setFileVersion(const uint8_t &pVersion) { + mFileVersion = pVersion; +} + +void OSCOOD::setFileRevision(const uint8_t &pRevision) { + mFileRevision = pRevision; +} + +void OSCOOD::setEDSVersion(const std::string &pVersion) { + mEDSVersion = pVersion; +} + +void OSCOOD::setDescription(const std::string &pDescription) { + mDesription = pDescription; +} + +bool OSCOOD::setCreationDate(const std::string &pDate) { + struct tm lDateTimeStruct; + memset(&lDateTimeStruct, 0, sizeof(struct tm)); + + /* The input string should only contain the date + * in either the YYYY-MM-DD format + * or the DD/MM/YYYY format. + * + * Both are 10 chars long (+ 1 for the NULL terminator) + */ + + if(strptime(pDate.c_str(), "%Y-%m-%d", &lDateTimeStruct)) { + /* Do nothing */ + } else if(strptime(pDate.c_str(), "%d/%m/%Y", &lDateTimeStruct)) { + /* Do nothing */ + } else { + std::cerr << "[ERROR] Wrong date format" << std::endl; + return false; + } + + struct tm *lCreationDateTimeStruct = gmtime(&mCreationDateTime); + lCreationDateTimeStruct->tm_mday = lDateTimeStruct.tm_mday; + lCreationDateTimeStruct->tm_mon = lDateTimeStruct.tm_mon; + lCreationDateTimeStruct->tm_year = lDateTimeStruct.tm_year; + mCreationDateTime = mktime(lCreationDateTimeStruct); + + return true; +} + +bool OSCOOD::setCreationTime(const std::string &pTime) { + struct tm lDateTimeStruct; + memset(&lDateTimeStruct, 0, sizeof(struct tm)); + + /* The input string should only contain the time + * in either the AM/PM format + * or the 24-hour format + */ + + if(strptime(pTime.c_str(), "%I:%M%p", &lDateTimeStruct)) { + /* Do nothing */ + } else if (strptime(pTime.c_str(), "%H:%M:%S", &lDateTimeStruct)) { + /* Do nothing */ + } else if (strptime(pTime.c_str(), "%H:%M", &lDateTimeStruct)) { + /* Do nothing */ + } else { + std::cerr << "[ERROR] Wrong time format" << std::endl; + return false; + } + + struct tm *lCreationDateTimeStruct = gmtime(&mCreationDateTime); + lCreationDateTimeStruct->tm_hour = lDateTimeStruct.tm_hour; + lCreationDateTimeStruct->tm_min = lDateTimeStruct.tm_min; + lCreationDateTimeStruct->tm_sec = lDateTimeStruct.tm_sec; + mCreationDateTime = mktime(lCreationDateTimeStruct); + + return true; +} + +void OSCOOD::setCreatedBy(const std::string &pCreatedBy) { + mCreatedBy = pCreatedBy; +} + +bool OSCOOD::setModificationDate(const std::string &pDate) { + struct tm lDateTimeStruct; + memset(&lDateTimeStruct, 0, sizeof(struct tm)); + + /* The input string should only contain the date + * in either the YYYY-MM-DD format + * or the DD/MM/YYYY format. + * + * Both are 10 chars long (+ 1 for the NULL terminator) + */ + + if(strptime(pDate.c_str(), "%Y-%m-%d", &lDateTimeStruct)) { + /* Do nothing */ + } else if(strptime(pDate.c_str(), "%d/%m/%Y", &lDateTimeStruct)) { + /* Do nothing */ + } else { + std::cerr << "[ERROR] Wrong date format" << std::endl; + return false; + } + + struct tm *lModificationDateTimeStruct = gmtime(&mModificationDateTime); + lModificationDateTimeStruct->tm_mday = lDateTimeStruct.tm_mday; + lModificationDateTimeStruct->tm_mon = lDateTimeStruct.tm_mon; + lModificationDateTimeStruct->tm_year = lDateTimeStruct.tm_year; + mModificationDateTime = mktime(lModificationDateTimeStruct); + + return true; +} + +bool OSCOOD::setModificationTime(const std::string &pTime) { + struct tm lDateTimeStruct; + memset(&lDateTimeStruct, 0, sizeof(struct tm)); + + /* The input string should only contain the time + * in either the AM/PM format + * or the 24-hour format + */ + + if(strptime(pTime.c_str(), "%I:%M%p", &lDateTimeStruct)) { + /* Do nothing */ + } else if (strptime(pTime.c_str(), "%H:%M:%S", &lDateTimeStruct)) { + /* Do nothing */ + } else if (strptime(pTime.c_str(), "%H:%M", &lDateTimeStruct)) { + /* Do nothing */ + } else { + std::cerr << "[ERROR] Wrong time format" << std::endl; + return false; + } + + struct tm *lModificationDateTimeStruct = gmtime(&mModificationDateTime); + lModificationDateTimeStruct->tm_hour = lDateTimeStruct.tm_hour; + lModificationDateTimeStruct->tm_min = lDateTimeStruct.tm_min; + lModificationDateTimeStruct->tm_sec = lDateTimeStruct.tm_sec; + mModificationDateTime = mktime(lModificationDateTimeStruct); + + return true; +} + +void OSCOOD::setModifiedBy(const std::string &pModifiedBy) { + mModifiedBy = pModifiedBy; +} + +void OSCOOD::setVendorName(const std::string &pName) { + mVendorName = pName; +} + +void OSCOOD::setVendorNumber(const uint32_t &pNumber) { + mVendorNumber = pNumber; +} + +void OSCOOD::setProductName(const std::string &pName) { + mProductName = pName; +} + +void OSCOOD::setProductNumber(const uint32_t &pNumber) { + mProductNumber = pNumber; +} + +void OSCOOD::setRevisionNumber(const uint32_t &pRevision) { + mRevisionNumber = pRevision; +} + +void OSCOOD::setOrderCode(const std::string &pOrderCode) { + mOrderCode = pOrderCode; +} + +void OSCOOD::setBaudrate10Supported(const bool &pSupport) { + mBaudRate_10 = pSupport; +} + +void OSCOOD::setBaudrate20Supported(const bool &pSupport) { + mBaudRate_20 = pSupport; +} + +void OSCOOD::setBaudrate50Supported(const bool &pSupport) { + mBaudRate_50 = pSupport; +} + +void OSCOOD::setBaudrate125Supported(const bool &pSupport) { + mBaudRate_125 = pSupport; +} + +void OSCOOD::setBaudrate250Supported(const bool &pSupport) { + mBaudRate_250 = pSupport; +} + +void OSCOOD::setBaudrate500Supported(const bool &pSupport) { + mBaudRate_500 = pSupport; +} + +void OSCOOD::setBaudrate800Supported(const bool &pSupport) { + mBaudRate_800 = pSupport; +} + +void OSCOOD::setBaudrate1000Supported(const bool &pSupport) { + mBaudRate_1000 = pSupport; +} + +void OSCOOD::setSimpleBootUpMaster(const bool &pSupport) { + mBaudRate_10 = pSupport; +} + +void OSCOOD::setSimpleBootUpSlave(const bool &pSupport) { + mBaudRate_10 = pSupport; +} + +void OSCOOD::setGranularity(const uint8_t &pGranularity) { + mGranularity = pGranularity; +} + +void OSCOOD::setDynamicChannelsSupported(const uint8_t &pChannelCount) { + mDynamicChannelsSupported = pChannelCount; +} + +void OSCOOD::setGroupMessaging(const bool &pSupport) { + mGroupMessaging = pSupport; +} + +void OSCOOD::setNrOfRPDOs(const uint16_t &pRPDONb) { + mNrOfRXPDO = pRPDONb; +} + +void OSCOOD::setNrOfTPDOs(const uint16_t &pTPDONb) { + mNrOfTXPDO = pTPDONb; +} + +void OSCOOD::setLSSSupported(const bool &pSupport) { + mLSSSupported = pSupport; +} + +void OSCOOD::setComments(const std::string &pComments) { + mComments = pComments; + + std::istringstream lISS(mComments); + uint32_t lLineCount = 0U; + for(std::string lLine; std::getline(lISS, lLine);) { + ++lLineCount; + } +} + +void OSCOOD::setDummy0001Supported(const bool &pSupport) { + mDummy0001 = pSupport; +} + +void OSCOOD::setDummy0002Supported(const bool &pSupport) { + mDummy0002 = pSupport; +} + +void OSCOOD::setDummy0003Supported(const bool &pSupport) { + mDummy0003 = pSupport; +} + +void OSCOOD::setDummy0004Supported(const bool &pSupport) { + mDummy0004 = pSupport; +} + +void OSCOOD::setDummy0005Supported(const bool &pSupport) { + mDummy0005 = pSupport; +} + +void OSCOOD::setDummy0006Supported(const bool &pSupport) { + mDummy0006 = pSupport; +} + +void OSCOOD::setDummy0007Supported(const bool &pSupport) { + mDummy0007 = pSupport; +} From 91368f47444eaae37d84b2c07b1b06918c60d5a3 Mon Sep 17 00:00:00 2001 From: Clovis Durand Date: Sat, 4 Apr 2020 18:08:41 +0200 Subject: [PATCH 2/5] [#2] Updated initools Signed-off-by: Clovis Durand --- generator/deps/initools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generator/deps/initools b/generator/deps/initools index a927cf6..79b85f9 160000 --- a/generator/deps/initools +++ b/generator/deps/initools @@ -1 +1 @@ -Subproject commit a927cf688534f187dd5ec607033f9b18e2d0374f +Subproject commit 79b85f9541d9a5db4993f1877692eace0b2775ee From 0be729ce47d81b0802518dbb24e09e67456e34d0 Mon Sep 17 00:00:00 2001 From: Clovis Durand Date: Sat, 4 Apr 2020 18:50:32 +0200 Subject: [PATCH 3/5] [#13, #14] Updated OSCOOD & OSCOODFactory t fill FileInfo, DeviceInfo, Comments & DummyUsage data Signed-off-by: Clovis Durand --- generator/inc/OSCOOD.hpp | 2 + generator/src/OSCOOD.cpp | 67 +++ generator/src/OSCOODFactory.cpp | 713 +++++++++++++++++++++++++++++++- generator/src/main.cpp | 2 + 4 files changed, 782 insertions(+), 2 deletions(-) diff --git a/generator/inc/OSCOOD.hpp b/generator/inc/OSCOOD.hpp index 2eecbb1..6fc217e 100644 --- a/generator/inc/OSCOOD.hpp +++ b/generator/inc/OSCOOD.hpp @@ -98,6 +98,7 @@ class API_EXPORT OSCOOD { bool dummy0005Supported(void) const; bool dummy0006Supported(void) const; bool dummy0007Supported(void) const; + bool dummySupported(const uint8_t &pDummy, bool &pSupported) const; /* Setters */ bool addIndex(OSCOODIndex *pIndex); @@ -150,6 +151,7 @@ class API_EXPORT OSCOOD { void setDummy0005Supported(const bool &pSupport); void setDummy0006Supported(const bool &pSupport); void setDummy0007Supported(const bool &pSupport); + bool setDummySupported(const uint8_t &pDummy, const bool &pSupport); protected: private: std::map mObjects; /**< Contents of the Object Dictionary */ diff --git a/generator/src/OSCOOD.cpp b/generator/src/OSCOOD.cpp index 26438c9..ce64775 100644 --- a/generator/src/OSCOOD.cpp +++ b/generator/src/OSCOOD.cpp @@ -277,6 +277,37 @@ bool OSCOOD::dummy0007Supported(void) const { return mDummy0007; } +bool OSCOOD::dummySupported(const uint8_t &pDummy, bool &pSupported) const { + switch(pDummy) { + case 1U: + pSupported = dummy0001Supported(); + break; + case 2U: + pSupported = dummy0002Supported(); + break; + case 3U: + pSupported = dummy0003Supported(); + break; + case 4U: + pSupported = dummy0004Supported(); + break; + case 5U: + pSupported = dummy0005Supported(); + break; + case 6U: + pSupported = dummy0006Supported(); + break; + case 7U: + pSupported = dummy0007Supported(); + break; + default: + std::cerr << "[ERROR] pDummy out of bounds" << std::endl; + return false; + } + + return true; +} + /* Setters */ bool OSCOOD::addIndex(OSCOODIndex *pIndex) { /* Check if the index already exists */ @@ -589,3 +620,39 @@ void OSCOOD::setDummy0006Supported(const bool &pSupport) { void OSCOOD::setDummy0007Supported(const bool &pSupport) { mDummy0007 = pSupport; } + +bool OSCOOD::setDummySupported(const uint8_t &pDummy, const bool &pSupport) { + if(1U > pDummy || 7 < pDummy) { + std::cerr << "[ERROR] pDummy out of bounds" << std::endl; + return false; + } + + switch(pDummy) { + case 1U: + setDummy0001Supported(pSupport); + break; + case 2U: + setDummy0002Supported(pSupport); + break; + case 3U: + setDummy0003Supported(pSupport); + break; + case 4U: + setDummy0004Supported(pSupport); + break; + case 5U: + setDummy0005Supported(pSupport); + break; + case 6U: + setDummy0006Supported(pSupport); + break; + case 7U: + setDummy0007Supported(pSupport); + break; + default: + std::cerr << "[ERROR] pDummy out of bounds" << std::endl; + return false; + } + + return true; +} diff --git a/generator/src/OSCOODFactory.cpp b/generator/src/OSCOODFactory.cpp index 8e448ef..2fca12d 100644 --- a/generator/src/OSCOODFactory.cpp +++ b/generator/src/OSCOODFactory.cpp @@ -17,6 +17,7 @@ /* C++ System */ #include #include +#include /* Defines --------------------------------------------- */ #define NB_GENERIC_KEYS 11U /**< Number of accepted keys for OSCOODObjects */ @@ -232,6 +233,682 @@ static bool fillObjectAtrributes(OSCOODObject * const pObj, const std::string pK return true; } +static bool fillOSCOODFileInfo(const INI * const pINI, OSCOOD * const pOD) { + /* Check arguments */ + if(nullptr == pINI) { + std::cerr << "[ERROR] INI file arg is nullptr" << std::endl; + return false; + } + + if(nullptr == pOD) { + std::cerr << "[ERROR] OSCO OD arg is nullptr" << std::endl; + return false; + } + + /* check that the INI file has a FileInfo section */ + if(!pINI->sectionExists("FileInfo")) { + std::cerr << "[ERROR] INI file has no FileInfo section" << std::endl; + return false; + } + + /* Get the FileInfo */ + std::string lTempVal = ""; + if(0 == pINI->getValue("FileName", lTempVal, "FileInfo")) { + pOD->setFileName(lTempVal); + } else { + /* Mandatory */ + std::cerr << "[ERROR] Missing mandatory FileInfo key : FileName" << std::endl; + return false; + } + + if(0 == pINI->getValue("FileVersion", lTempVal, "FileInfo")) { + /* Convert string to uint */ + unsigned long lFileVersion = 0U; + try { + lFileVersion = stoul(lTempVal); + if(0xFFU < lFileVersion) { + std::cerr << "[ERROR] FileVersion is out of bounds" << std::endl; + return false; + } + } catch (std::exception &e) { + std::cerr << "[ERROR] FileVersion value invalid" << std::endl; + return false; + } + + pOD->setFileVersion((uint8_t)lFileVersion); + } else { + /* Mandatory */ + std::cerr << "[ERROR] Missing mandatory FileInfo key : FileVersion" << std::endl; + return false; + } + + if(0 == pINI->getValue("FileRevision", lTempVal, "FileInfo")) { + /* Convert string to uint */ + unsigned long lFileRevision = 0U; + try { + lFileRevision = stoul(lTempVal); + if(0xFFU < lFileRevision) { + std::cerr << "[ERROR] FileRevision is out of bounds" << std::endl; + return false; + } + } catch (std::exception &e) { + std::cerr << "[ERROR] FileRevision value invalid" << std::endl; + return false; + } + + pOD->setFileRevision((uint8_t)lFileRevision); + } else { + /* Mandatory */ + std::cerr << "[ERROR] Missing mandatory FileInfo key : FileRevision" << std::endl; + return false; + } + + if(0 == pINI->getValue("EDSVersion", lTempVal, "FileInfo")) { + pOD->setEDSVersion(lTempVal); + } else { + /* Optional : If this entry is missing, value is "3.0" */ + pOD->setEDSVersion("3.0"); + } + + if(0 == pINI->getValue("Description", lTempVal, "FileInfo")) { + if(243U < lTempVal.size()) { + std::cerr << "[ERROR] Description string is too long" << std::endl; + return false; + } + pOD->setDescription(lTempVal); + } else { + /* Mandatory */ + std::cerr << "[ERROR] Missing mandatory FileInfo key : Description" << std::endl; + return false; + } + + if(0 == pINI->getValue("CreationTime", lTempVal, "FileInfo")) { + if(!pOD->setCreationTime(lTempVal)) { + std::cerr << "[ERROR] setCreationTime failed" << std::endl; + return false; + } + } else { + /* Mandatory */ + std::cerr << "[ERROR] Missing mandatory FileInfo key : CreationTime" << std::endl; + return false; + } + + if(0 == pINI->getValue("CreationDate", lTempVal, "FileInfo")) { + if(!pOD->setCreationDate(lTempVal)) { + std::cerr << "[ERROR] setCreationDate failed" << std::endl; + return false; + } + } else { + /* Mandatory */ + std::cerr << "[ERROR] Missing mandatory FileInfo key : CreationDate" << std::endl; + return false; + } + + if(0 == pINI->getValue("CreatedBy", lTempVal, "FileInfo")) { + pOD->setCreatedBy(lTempVal); + } else { + /* Mandatory */ + std::cerr << "[ERROR] Missing mandatory FileInfo key : CreatedBy" << std::endl; + return false; + } + + if(0 == pINI->getValue("ModificationTime", lTempVal, "FileInfo")) { + if(!pOD->setModificationTime(lTempVal)) { + std::cerr << "[ERROR] setModificationTime failed" << std::endl; + return false; + } + } else { + /* Optional */ + std::cerr << "[WARN ] Missing optional FileInfo key : ModificationTime" << std::endl; + } + + if(0 == pINI->getValue("ModificationDate", lTempVal, "FileInfo")) { + if(!pOD->setModificationDate(lTempVal)) { + std::cerr << "[ERROR] setModificationDate failed" << std::endl; + return false; + } + } else { + /* Optional */ + std::cerr << "[WARN ] Missing optional FileInfo key : ModificationDate" << std::endl; + } + + if(0 == pINI->getValue("ModifiedBy", lTempVal, "FileInfo")) { + pOD->setModifiedBy(lTempVal); + } else { + /* Optional */ + std::cerr << "[WARN ] Missing optional FileInfo key : ModifiedBy" << std::endl; + } + + return true; +} + +static bool fillOSCOODDeviceInfo(const INI * const pINI, OSCOOD * const pOD) { + /* Check arguments */ + if(nullptr == pINI) { + std::cerr << "[ERROR] INI file arg is nullptr" << std::endl; + return false; + } + + if(nullptr == pOD) { + std::cerr << "[ERROR] OSCO OD arg is nullptr" << std::endl; + return false; + } + + /* check that the INI file has a FileInfo section */ + if(!pINI->sectionExists("DeviceInfo")) { + std::cerr << "[ERROR] INI file has no DeviceInfo section" << std::endl; + return false; + } + + /* Get the DeviceInfo */ + std::string lTempVal = ""; + if(0 == pINI->getValue("VendorName", lTempVal, "DeviceInfo")) { + pOD->setVendorName(lTempVal); + } else { + /* Mandatory */ + std::cerr << "[ERROR] Missing mandatory DeviceInfo key : VendorName" << std::endl; + return false; + } + + if(0 == pINI->getValue("VendorNumber", lTempVal, "DeviceInfo")) { + /* Convert string to uint */ + unsigned long lVendorNumber = 0U; + + try { + lVendorNumber = stoul(lTempVal); + } catch (std::exception &e) { + std::cerr << "[ERROR] VendorNumber value invalid" << std::endl; + return false; + } + + pOD->setVendorNumber((uint8_t)lVendorNumber); + } else { + /* Mandatory */ + std::cerr << "[ERROR] Missing mandatory DeviceInfo key : VendorNumber" << std::endl; + return false; + } + + if(0 == pINI->getValue("ProductName", lTempVal, "DeviceInfo")) { + pOD->setProductName(lTempVal); + } else { + /* Mandatory */ + std::cerr << "[ERROR] Missing mandatory DeviceInfo key : ProductName" << std::endl; + return false; + } + + if(0 == pINI->getValue("ProductNumber", lTempVal, "DeviceInfo")) { + /* Convert string to uint */ + unsigned long lProductNumber = 0U; + + try { + lProductNumber = stoul(lTempVal); + } catch (std::exception &e) { + std::cerr << "[ERROR] ProductNumber value invalid" << std::endl; + return false; + } + + pOD->setProductNumber((uint8_t)lProductNumber); + } else { + /* Mandatory */ + std::cerr << "[ERROR] Missing mandatory DeviceInfo key : ProductNumber" << std::endl; + return false; + } + + if(0 == pINI->getValue("RevisionNumber", lTempVal, "DeviceInfo")) { + /* Convert string to uint */ + unsigned long lRevisionNumber = 0U; + + try { + lRevisionNumber = stoul(lTempVal); + } catch (std::exception &e) { + std::cerr << "[ERROR] RevisionNumber value invalid" << std::endl; + return false; + } + + pOD->setRevisionNumber((uint8_t)lRevisionNumber); + } else { + /* Mandatory */ + std::cerr << "[ERROR] Missing mandatory DeviceInfo key : RevisionNumber" << std::endl; + return false; + } + + + if(0 == pINI->getValue("OrderCode", lTempVal, "DeviceInfo")) { + pOD->setOrderCode(lTempVal); + } else { + /* Optional */ + std::cerr << "[WARN ] Missing optional DeviceInfo key : OrderCode" << std::endl; + pOD->setOrderCode(""); + } + + if(0 == pINI->getValue("BaudRate_10", lTempVal, "DeviceInfo")) { + if((lTempVal == "true") + || (lTempVal == "True") + || (lTempVal == "1")) + { + pOD->setBaudrate10Supported(true); + } else if ((lTempVal == "false") + || (lTempVal == "False") + || (lTempVal == "0")) + { + pOD->setBaudrate10Supported(false); + } else { + std::cerr << "[ERROR] Invalid BaudRate_10 value" << std::endl; + return false; + } + } else { + std::cerr << "[ERROR] INI file has no BaudRate_10 key" << std::endl; + pOD->setBaudrate10Supported(false); + } + + if(0 == pINI->getValue("BaudRate_20", lTempVal, "DeviceInfo")) { + if((lTempVal == "true") + || (lTempVal == "True") + || (lTempVal == "1")) + { + pOD->setBaudrate20Supported(true); + } else if ((lTempVal == "false") + || (lTempVal == "False") + || (lTempVal == "0")) + { + pOD->setBaudrate20Supported(false); + } else { + std::cerr << "[ERROR] Invalid BaudRate_20 value" << std::endl; + return false; + } + } else { + std::cerr << "[ERROR] INI file has no BaudRate_20 key" << std::endl; + pOD->setBaudrate20Supported(false); + } + + if(0 == pINI->getValue("BaudRate_50", lTempVal, "DeviceInfo")) { + if((lTempVal == "true") + || (lTempVal == "True") + || (lTempVal == "1")) + { + pOD->setBaudrate50Supported(true); + } else if ((lTempVal == "false") + || (lTempVal == "False") + || (lTempVal == "0")) + { + pOD->setBaudrate50Supported(false); + } else { + std::cerr << "[ERROR] Invalid BaudRate_50 value" << std::endl; + return false; + } + } else { + std::cerr << "[ERROR] INI file has no BaudRate_50 key" << std::endl; + pOD->setBaudrate50Supported(false); + } + + if(0 == pINI->getValue("BaudRate_125", lTempVal, "DeviceInfo")) { + if((lTempVal == "true") + || (lTempVal == "True") + || (lTempVal == "1")) + { + pOD->setBaudrate125Supported(true); + } else if ((lTempVal == "false") + || (lTempVal == "False") + || (lTempVal == "0")) + { + pOD->setBaudrate125Supported(false); + } else { + std::cerr << "[ERROR] Invalid BaudRate_125 value" << std::endl; + return false; + } + } else { + std::cerr << "[ERROR] INI file has no BaudRate_125 key" << std::endl; + pOD->setBaudrate125Supported(false); + } + + if(0 == pINI->getValue("BaudRate_250", lTempVal, "DeviceInfo")) { + if((lTempVal == "true") + || (lTempVal == "True") + || (lTempVal == "1")) + { + pOD->setBaudrate250Supported(true); + } else if ((lTempVal == "false") + || (lTempVal == "False") + || (lTempVal == "0")) + { + pOD->setBaudrate250Supported(false); + } else { + std::cerr << "[ERROR] Invalid BaudRate_250 value" << std::endl; + return false; + } + } else { + std::cerr << "[ERROR] INI file has no BaudRate_250 key" << std::endl; + pOD->setBaudrate250Supported(false); + } + + if(0 == pINI->getValue("BaudRate_500", lTempVal, "DeviceInfo")) { + if((lTempVal == "true") + || (lTempVal == "True") + || (lTempVal == "1")) + { + pOD->setBaudrate500Supported(true); + } else if ((lTempVal == "false") + || (lTempVal == "False") + || (lTempVal == "0")) + { + pOD->setBaudrate500Supported(false); + } else { + std::cerr << "[ERROR] Invalid BaudRate_500 value" << std::endl; + return false; + } + } else { + std::cerr << "[ERROR] INI file has no BaudRate_500 key" << std::endl; + pOD->setBaudrate500Supported(false); + } + + if(0 == pINI->getValue("BaudRate_800", lTempVal, "DeviceInfo")) { + if((lTempVal == "true") + || (lTempVal == "True") + || (lTempVal == "1")) + { + pOD->setBaudrate800Supported(true); + } else if ((lTempVal == "false") + || (lTempVal == "False") + || (lTempVal == "0")) + { + pOD->setBaudrate800Supported(false); + } else { + std::cerr << "[ERROR] Invalid BaudRate_800 value" << std::endl; + return false; + } + } else { + std::cerr << "[ERROR] INI file has no BaudRate_800 key" << std::endl; + pOD->setBaudrate800Supported(false); + } + + if(0 == pINI->getValue("BaudRate_1000", lTempVal, "DeviceInfo")) { + if((lTempVal == "true") + || (lTempVal == "True") + || (lTempVal == "1")) + { + pOD->setBaudrate1000Supported(true); + } else if ((lTempVal == "false") + || (lTempVal == "False") + || (lTempVal == "0")) + { + pOD->setBaudrate1000Supported(false); + } else { + std::cerr << "[ERROR] Invalid BaudRate_1000 value" << std::endl; + return false; + } + } else { + std::cerr << "[ERROR] INI file has no BaudRate_1000 key" << std::endl; + pOD->setBaudrate1000Supported(false); + } + + if(0 == pINI->getValue("SimpleBootUpMaster", lTempVal, "DeviceInfo")) { + if((lTempVal == "true") + || (lTempVal == "True") + || (lTempVal == "1")) + { + pOD->setSimpleBootUpMaster(true); + } else if ((lTempVal == "false") + || (lTempVal == "False") + || (lTempVal == "0")) + { + pOD->setSimpleBootUpMaster(false); + } else { + std::cerr << "[ERROR] Invalid SimpleBootUpMaster value" << std::endl; + return false; + } + } else { + std::cerr << "[ERROR] INI file has no SimpleBootUpMaster key" << std::endl; + pOD->setSimpleBootUpMaster(false); + } + + if(0 == pINI->getValue("SimpleBootUpSlave", lTempVal, "DeviceInfo")) { + if((lTempVal == "true") + || (lTempVal == "True") + || (lTempVal == "1")) + { + pOD->setSimpleBootUpSlave(true); + } else if ((lTempVal == "false") + || (lTempVal == "False") + || (lTempVal == "0")) + { + pOD->setSimpleBootUpSlave(false); + } else { + std::cerr << "[ERROR] Invalid SimpleBootUpSlave value" << std::endl; + return false; + } + } else { + std::cerr << "[ERROR] INI file has no SimpleBootUpSlave key" << std::endl; + pOD->setSimpleBootUpSlave(false); + } + + if(0 == pINI->getValue("Granularity", lTempVal, "DeviceInfo")) { + /* Convert string to uint */ + unsigned long lGranularity = 0U; + try { + lGranularity = stoul(lTempVal); + if(0xFFU < lGranularity) { + std::cerr << "[ERROR] Granularity is out of bounds" << std::endl; + return false; + } + } catch (std::exception &e) { + std::cerr << "[ERROR] Granularity value invalid" << std::endl; + return false; + } + + pOD->setGranularity((uint8_t)lGranularity); + } else { + /* Mandatory */ + std::cerr << "[ERROR] Missing mandatory DeviceInfo key : Granularity" << std::endl; + return false; + } + + if(0 == pINI->getValue("DynamicChannelsSupported", lTempVal, "DeviceInfo")) { + if((lTempVal == "true") + || (lTempVal == "True") + || (lTempVal == "1")) + { + pOD->setDynamicChannelsSupported(true); + } else if ((lTempVal == "false") + || (lTempVal == "False") + || (lTempVal == "0")) + { + pOD->setDynamicChannelsSupported(false); + } else { + std::cerr << "[ERROR] Invalid DynamicChannelsSupported value" << std::endl; + return false; + } + } else { + std::cerr << "[ERROR] INI file has no DynamicChannelsSupported key" << std::endl; + pOD->setDynamicChannelsSupported(false); + } + + if(0 == pINI->getValue("GroupMessaging", lTempVal, "DeviceInfo")) { + if((lTempVal == "true") + || (lTempVal == "True") + || (lTempVal == "1")) + { + pOD->setGroupMessaging(true); + } else if ((lTempVal == "false") + || (lTempVal == "False") + || (lTempVal == "0")) + { + pOD->setGroupMessaging(false); + } else { + std::cerr << "[ERROR] Invalid GroupMessaging value" << std::endl; + return false; + } + } else { + std::cerr << "[ERROR] INI file has no GroupMessaging key" << std::endl; + pOD->setGroupMessaging(false); + } + + if(0 == pINI->getValue("NrOfRXPDO", lTempVal, "DeviceInfo")) { + /* Convert string to uint */ + unsigned long lNrOfRXPDO = 0U; + try { + lNrOfRXPDO = stoul(lTempVal); + if(0xFFFFU < lNrOfRXPDO) { + std::cerr << "[ERROR] NrOfRXPDO is out of bounds" << std::endl; + return false; + } + } catch (std::exception &e) { + std::cerr << "[ERROR] NrOfRXPDO value invalid" << std::endl; + return false; + } + + pOD->setNrOfRPDOs((uint16_t)lNrOfRXPDO); + } else { + /* Mandatory */ + std::cerr << "[ERROR] Missing mandatory DeviceInfo key : NrOfRXPDO" << std::endl; + return false; + } + + if(0 == pINI->getValue("NrOfTXPDO", lTempVal, "DeviceInfo")) { + /* Convert string to uint */ + unsigned long lNrOfTXPDO = 0U; + try { + lNrOfTXPDO = stoul(lTempVal); + if(0xFFFFU < lNrOfTXPDO) { + std::cerr << "[ERROR] NrOfTXPDO is out of bounds" << std::endl; + return false; + } + } catch (std::exception &e) { + std::cerr << "[ERROR] NrOfTXPDO value invalid" << std::endl; + return false; + } + + pOD->setNrOfTPDOs((uint16_t)lNrOfTXPDO); + } else { + /* Mandatory */ + std::cerr << "[ERROR] Missing mandatory DeviceInfo key : NrOfTXPDO" << std::endl; + return false; + } + + if(0 == pINI->getValue("LSS_Supported", lTempVal, "DeviceInfo")) { + if((lTempVal == "true") + || (lTempVal == "True") + || (lTempVal == "1")) + { + pOD->setLSSSupported(true); + } else if ((lTempVal == "false") + || (lTempVal == "False") + || (lTempVal == "0")) + { + pOD->setLSSSupported(false); + } else { + std::cerr << "[ERROR] Invalid LSS_Supported value" << std::endl; + return false; + } + } else { + std::cerr << "[ERROR] INI file has no LSS_Supported key" << std::endl; + pOD->setLSSSupported(false); + } + + return true; +} + +static bool fillOSCOODDummyUsage(const INI * const pINI, OSCOOD * const pOD) { + /* Check arguments */ + if(nullptr == pINI) { + std::cerr << "[ERROR] INI file arg is nullptr" << std::endl; + return false; + } + + if(nullptr == pOD) { + std::cerr << "[ERROR] OSCO OD arg is nullptr" << std::endl; + return false; + } + + pOD->setDummy0001Supported(false); + pOD->setDummy0002Supported(false); + pOD->setDummy0003Supported(false); + pOD->setDummy0004Supported(false); + pOD->setDummy0005Supported(false); + pOD->setDummy0006Supported(false); + pOD->setDummy0007Supported(false); + + /* check that the INI file has a FileInfo section */ + if(!pINI->sectionExists("FileInfo")) { + std::cerr << "[ERROR] INI file has no DummyUsage section" << std::endl; + return true; + } + + static const std::string lDummyKeyBase = "Dummy000"; + std::string lTempVal = ""; + for(uint8_t i = 1U; i < 8U; i++) { + std::string lDummyKey = lDummyKeyBase + (char)(i + 48U); /* ASCII Offset */ + if(0 == pINI->getValue(lDummyKey, lTempVal, "DummyUsage")) { + if((lTempVal == "true") + || (lTempVal == "True") + || (lTempVal == "1")) + { + pOD->setDummySupported(i, true); + } else if ((lTempVal == "false") + || (lTempVal == "False") + || (lTempVal == "0")) + { + pOD->setDummySupported(i, false); + } else { + std::cerr << "[ERROR] Invalid " << lDummyKey << " value" << std::endl; + return false; + } + } else { + std::cerr << "[ERROR] INI file has no " << lDummyKey << " key" << std::endl; + pOD->setDummySupported(i, false); + } + } + + return true; +} + +static bool fillOSCOODComments(const INI * const pINI, OSCOOD * const pOD) { + /* Check arguments */ + if(nullptr == pINI) { + std::cerr << "[ERROR] INI file arg is nullptr" << std::endl; + return false; + } + + if(nullptr == pOD) { + std::cerr << "[ERROR] OSCO OD arg is nullptr" << std::endl; + return false; + } + + /* check that the INI file has a Comments section */ + if(!pINI->sectionExists("Comments")) { + std::cerr << "[ERROR] INI file has no Comments section" << std::endl; + return false; + } + + /* Get line count */ + static const std::string lLineKeyBase = "Line"; + std::string lLineCountStr = ""; + if(!pINI->getValue("Lines", lLineCountStr, "Comments")) { + /* "Lines" key not found, assuming zero */ + pOD->setComments(""); + } else { + std::string lTempVal = "", lLine = 0U; + uint32_t lLineCount = 0U; + std::stringstream lCommentSS; + std::istringstream(lLineCountStr) >> lLineCount; + for(uint32_t i = 1U; i <= lLineCount; i++) { + std::ostringstream lOSS; + lOSS << i; + lLine = lOSS.str(); + if(!pINI->getValue("lLineKeyBase" + lLine, lTempVal, "Comments")) { + std::cerr << "[ERROR] Inconsistent data/linecount in Comments section" << std::endl; + } else { + lCommentSS << lTempVal << std::endl; + } + } + + /* Set the comments */ + pOD->setComments(lCommentSS.str()); + } + + return true; +} + + /* OSCOODFactory class implementation ------------------ */ /* Builders */ OSCOOD *OSCOODFactory::buildOSCOOD(const std::string &pFile) { @@ -276,8 +953,34 @@ OSCOOD *OSCOODFactory::OSCOODFromEDS(const std::string &pFile) { /* Create an OSCO Object Dictionary */ OSCOOD *lOD = new OSCOOD; + /* Fill in the FileInfo */ + if(!fillOSCOODFileInfo(&lEDS, lOD)) { + std::cerr << "[ERROR] Failed to fill in FileInfo data" << std::endl; + delete lOD; + return nullptr; + } + + /* Fill in the DeviceInfo */ + if(!fillOSCOODDeviceInfo(&lEDS, lOD)) { + std::cerr << "[ERROR] Failed to fill in DeviceInfo data" << std::endl; + delete lOD; + return nullptr; + } + + /* Fill in the DummyUsage */ + if(!fillOSCOODDummyUsage(&lEDS, lOD)) { + std::cerr << "[WARN ] Failed to fill in DummyUsage data" << std::endl; + std::cerr << " Assuming NONE" << std::endl; + } + + /* Fill in the Comments */ + if(!fillOSCOODComments(&lEDS, lOD)) { + std::cerr << "[WARN ] Failed to fill in Comments data" << std::endl; + std::cerr << " Assuming NONE" << std::endl; + } + /* Set indexes */ - const std::map>> * lEntries; + const std::map>> *lEntries = nullptr; lEntries = lEDS.odEntries(); for(const auto &lEntry : *lEntries) { /* Temporary variables */ @@ -365,15 +1068,21 @@ OSCOOD *OSCOODFactory::OSCOODFromEDS(const std::string &pFile) { OSCOOD *OSCOODFactory::OSCOODFromDCF(const std::string &pFile) { /* TODO : Implement the DCF factory */ (void)pFile; + + return nullptr; } /* OSCONode builders */ OSCONode *OSCOODFactory::OSCONodeFromEDS(const std::string &pFile) { - // + /* TODO : Implement the EDS to OSCONode factory */ (void)pFile; + + return nullptr; } OSCONode *OSCOODFactory::OSCONodeFromDCF(const std::string &pFile) { /* TODO : Implement the DCF factory */ (void)pFile; + + return nullptr; } diff --git a/generator/src/main.cpp b/generator/src/main.cpp index 925cfc3..70e8b38 100644 --- a/generator/src/main.cpp +++ b/generator/src/main.cpp @@ -81,6 +81,8 @@ int main(const int argc, const char * const * const argv) { delete lOD; return EXIT_FAILURE; + } else { + std::cout << "[INFO ] OSCOODFactory::buildOSCOOD successfully created an Object Dictionary" << std::endl; } //delete lEDS; From 4521139d07b695aa712a33b86a58fe632ad91569 Mon Sep 17 00:00:00 2001 From: Clovis Durand Date: Sat, 4 Apr 2020 18:51:23 +0200 Subject: [PATCH 4/5] Fixed FileVersion in IO.eds Signed-off-by: Clovis Durand --- generator/examples/od/IO.eds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generator/examples/od/IO.eds b/generator/examples/od/IO.eds index 612d4bf..8c7d6b4 100644 --- a/generator/examples/od/IO.eds +++ b/generator/examples/od/IO.eds @@ -6,7 +6,7 @@ [FileInfo] FileName=IO Example -FileVersion=- +FileVersion=0 FileRevision=0 EDSVersion=4.0 Description=Open Source CANopen implementation From ed2c07e9de2766305f12d47374b199f35b235c19 Mon Sep 17 00:00:00 2001 From: Clovis Durand Date: Sat, 4 Apr 2020 18:56:38 +0200 Subject: [PATCH 5/5] [#13] Fixed memset calls in OSCOOD.cpp Signed-off-by: Clovis Durand --- generator/src/OSCOOD.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/generator/src/OSCOOD.cpp b/generator/src/OSCOOD.cpp index ce64775..b46208d 100644 --- a/generator/src/OSCOOD.cpp +++ b/generator/src/OSCOOD.cpp @@ -19,6 +19,7 @@ /* C System */ #include +#include /* Defines --------------------------------------------- */ @@ -373,7 +374,7 @@ void OSCOOD::setDescription(const std::string &pDescription) { bool OSCOOD::setCreationDate(const std::string &pDate) { struct tm lDateTimeStruct; - memset(&lDateTimeStruct, 0, sizeof(struct tm)); + std::memset(&lDateTimeStruct, 0, sizeof(struct tm)); /* The input string should only contain the date * in either the YYYY-MM-DD format @@ -402,7 +403,7 @@ bool OSCOOD::setCreationDate(const std::string &pDate) { bool OSCOOD::setCreationTime(const std::string &pTime) { struct tm lDateTimeStruct; - memset(&lDateTimeStruct, 0, sizeof(struct tm)); + std::memset(&lDateTimeStruct, 0, sizeof(struct tm)); /* The input string should only contain the time * in either the AM/PM format @@ -435,7 +436,7 @@ void OSCOOD::setCreatedBy(const std::string &pCreatedBy) { bool OSCOOD::setModificationDate(const std::string &pDate) { struct tm lDateTimeStruct; - memset(&lDateTimeStruct, 0, sizeof(struct tm)); + std::memset(&lDateTimeStruct, 0, sizeof(struct tm)); /* The input string should only contain the date * in either the YYYY-MM-DD format @@ -464,7 +465,7 @@ bool OSCOOD::setModificationDate(const std::string &pDate) { bool OSCOOD::setModificationTime(const std::string &pTime) { struct tm lDateTimeStruct; - memset(&lDateTimeStruct, 0, sizeof(struct tm)); + std::memset(&lDateTimeStruct, 0, sizeof(struct tm)); /* The input string should only contain the time * in either the AM/PM format