From cbcbcbdc5d322e584df5e57ce6a412b73c8b6cc5 Mon Sep 17 00:00:00 2001 From: Kyle Johannes Date: Tue, 11 Jun 2024 22:04:09 +0000 Subject: [PATCH 01/47] System Test: FIRE 3 and VCAN 4-2EL --- .gitlab-ci.yml | 89 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 22 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1d01c64..154fefd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -319,56 +319,101 @@ unit_test linux/fedora/39/amd64/clang: after_script: - /opt/libvirt-driver/cleanup.sh -hardware_test system-test-fedora38-red2: - <<: *hw_test - variables: - GUEST_OS_TAG: fedora38 - DEVICE_PORT: ETH_A +.fedora38_needs: &fedora38_needs needs: - job: build linux/fedora/38/amd64/clang artifacts: true -hardware_test system-test-fedora38-vcan42: +hardware_test fedora38-red2: <<: *hw_test + <<: *fedora38_needs + variables: + GUEST_OS_TAG: fedora38 + DEVICE_PORT: ETH_A + +hardware_test fedora38-vcan42: + <<: *hw_test + <<: *fedora38_needs variables: GUEST_OS_TAG: fedora38 DEVICE_PORT: USB_D - needs: - - job: build linux/fedora/38/amd64/clang - artifacts: true -hardware_test system-test-ubuntu2204-red2: +hardware_test fedora38-fire3: <<: *hw_test + <<: *fedora38_needs variables: - GUEST_OS_TAG: ubuntu22.04 - DEVICE_PORT: ETH_A + GUEST_OS_TAG: fedora38 + DEVICE_PORT: ETH_B + +hardware_test fedora38-vcan42-EL: + <<: *hw_test + <<: *fedora38_needs + variables: + GUEST_OS_TAG: fedora38 + DEVICE_PORT: USB_C + +.ubuntu2204_needs: &ubuntu2204_needs needs: - job: build linux/ubuntu/2204/amd64/clang artifacts: true -hardware_test system-test-ubuntu2204-vcan42: +hardware_test ubuntu2204-red2: <<: *hw_test + <<: *ubuntu2204_needs + variables: + GUEST_OS_TAG: ubuntu22.04 + DEVICE_PORT: ETH_A + +hardware_test ubuntu2204-vcan42: + <<: *hw_test + <<: *ubuntu2204_needs variables: GUEST_OS_TAG: ubuntu22.04 DEVICE_PORT: USB_D + +hardware_test ubuntu2204-fire3: + <<: *hw_test + <<: *ubuntu2204_needs + variables: + GUEST_OS_TAG: ubuntu22.04 + DEVICE_PORT: ETH_B + +hardware_test ubuntu2204-vcan42-EL: + <<: *hw_test + <<: *ubuntu2204_needs + variables: + GUEST_OS_TAG: ubuntu22.04 + DEVICE_PORT: USB_C + +.win10_needs: &win10_needs needs: - - job: build linux/ubuntu/2204/amd64/clang + - job: build windows/x64 artifacts: true -hardware_test system-test-win10-red2: +hardware_test win10-red2: <<: *hw_test + <<: *win10_needs variables: GUEST_OS_TAG: win10 DEVICE_PORT: ETH_A - needs: - - job: build windows/x64 - artifacts: true -hardware_test system-test-win10-vcan42: +hardware_test win10-vcan42: <<: *hw_test + <<: *win10_needs variables: GUEST_OS_TAG: win10 DEVICE_PORT: USB_D - needs: - - job: build windows/x64 - artifacts: true \ No newline at end of file + +hardware_test win10-fire3: + <<: *hw_test + <<: *win10_needs + variables: + GUEST_OS_TAG: win10 + DEVICE_PORT: ETH_B + +hardware_test win10-vcan42-EL: + <<: *hw_test + <<: *win10_needs + variables: + GUEST_OS_TAG: win10 + DEVICE_PORT: USB_C \ No newline at end of file From 14588591e5c8c0830f7c77e17f41ea528b9659c4 Mon Sep 17 00:00:00 2001 From: Bryant Jones Date: Mon, 8 Jul 2024 14:00:24 +0000 Subject: [PATCH 02/47] Device: Comet2/Comet3: Add support for TC10 API --- include/icsneo/device/tree/radcomet3/radcomet3.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/icsneo/device/tree/radcomet3/radcomet3.h b/include/icsneo/device/tree/radcomet3/radcomet3.h index 1edf454..476d8f2 100644 --- a/include/icsneo/device/tree/radcomet3/radcomet3.h +++ b/include/icsneo/device/tree/radcomet3/radcomet3.h @@ -44,6 +44,8 @@ public: bool getEthPhyRegControlSupported() const override { return true; } + bool supportsTC10() const override { return true; } + protected: RADComet3(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); From 4476bd8b713e52ae698371ee5db71ab79103ba9d Mon Sep 17 00:00:00 2001 From: Kyle Schwarz Date: Tue, 30 Jul 2024 02:09:24 +0000 Subject: [PATCH 03/47] Platform: TCP: Add poll function to Socket --- include/icsneo/platform/tcp.h | 1 + platform/tcp.cpp | 56 ++++++++++++++--------------------- 2 files changed, 24 insertions(+), 33 deletions(-) diff --git a/include/icsneo/platform/tcp.h b/include/icsneo/platform/tcp.h index e8446ee..3757475 100644 --- a/include/icsneo/platform/tcp.h +++ b/include/icsneo/platform/tcp.h @@ -38,6 +38,7 @@ private: ~Socket(); explicit operator bool() const { return fd != -1; } operator SocketFileDescriptor() const { return fd; } + void poll(uint16_t event, uint32_t msTimeout); private: SocketFileDescriptor fd; }; diff --git a/platform/tcp.cpp b/platform/tcp.cpp index 91dca55..6e39ee1 100644 --- a/platform/tcp.cpp +++ b/platform/tcp.cpp @@ -6,6 +6,7 @@ #else #include #include +#include #include #include #include @@ -72,6 +73,20 @@ TCP::Socket::~Socket() { #endif } +void TCP::Socket::poll(uint16_t event, uint32_t msTimeout) { + #ifdef _WIN32 + WSAPOLLFD pfd; + pfd.fd = fd; + pfd.events = event; + ::WSAPoll(&pfd, 1, msTimeout); + #else + struct pollfd pfd; + pfd.fd = fd; + pfd.events = event; + ::poll(&pfd, 1, msTimeout); + #endif +} + void TCP::Find(std::vector& found) { static const auto MDNS_PORT = htons((unsigned short)5353); static const auto MDNS_IP = htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U)); @@ -256,16 +271,13 @@ void TCP::Find(std::vector& found) { continue; } - timeval timeout = {}; - timeout.tv_usec = 50000; - fd_set readfs; - FD_ZERO(&readfs); - int nfds = WIN_INT(socket) + 1; - FD_SET(socket, &readfs); - while(true) { + const auto rxTill = std::chrono::steady_clock::now() + std::chrono::milliseconds(100); + while(std::chrono::steady_clock::now() < rxTill) { static constexpr size_t bufferLen = 2048; uint8_t buffer[bufferLen]; - ::select(nfds, &readfs, 0, 0, &timeout); // timeout is intentially not reset, we want timeout.tv_usec _total_ + // keep trying till the timeout + const auto msWait = std::chrono::duration_cast(rxTill - std::chrono::steady_clock::now()).count(); + socket.poll(POLLIN, static_cast(msWait)); const auto recvRet = ::recv(socket, (char*)buffer, bufferLen, 0); static constexpr auto headerLength = 12; if(recvRet < headerLength) { @@ -460,13 +472,7 @@ bool TCP::open() { } #endif - timeval timeout = {}; - timeout.tv_sec = 1; - fd_set writefs; - FD_ZERO(&writefs); - int nfds = WIN_INT(*partiallyOpenSocket) + 1; - FD_SET(*partiallyOpenSocket, &writefs); - ::select(nfds, 0, &writefs, 0, &timeout); + partiallyOpenSocket->poll(POLLOUT, 1000); if(::connect(*partiallyOpenSocket, (sockaddr*)&addr, sizeof(addr)) < 0) { #ifdef _WIN32 @@ -523,21 +529,13 @@ bool TCP::close() { void TCP::readTask() { EventManager::GetInstance().downgradeErrorsOnCurrentThread(); - const int nfds = WIN_INT(*socket) + 1; - fd_set readfs; - FD_ZERO(&readfs); - FD_SET(*socket, &readfs); - timeval timeout; - constexpr size_t READ_BUFFER_SIZE = 2048; uint8_t readbuf[READ_BUFFER_SIZE]; while(!closing) { if(const auto received = ::recv(*socket, (char*)readbuf, READ_BUFFER_SIZE, 0); received > 0) { pushRx(readbuf, received); } else { - timeout.tv_sec = 0; - timeout.tv_usec = 50'000; - ::select(nfds, &readfs, 0, 0, &timeout); + socket->poll(POLLIN, 100); } } } @@ -545,12 +543,6 @@ void TCP::readTask() { void TCP::writeTask() { EventManager::GetInstance().downgradeErrorsOnCurrentThread(); - const int nfds = WIN_INT(*socket) + 1; - fd_set writefs; - FD_ZERO(&writefs); - FD_SET(*socket, &writefs); - timeval timeout; - WriteOperation writeOp; while(!closing) { if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100))) @@ -559,9 +551,7 @@ void TCP::writeTask() { while(!closing) { if(::send(*socket, (char*)writeOp.bytes.data(), WIN_INT(writeOp.bytes.size()), 0) > 0) break; - timeout.tv_sec = 0; - timeout.tv_usec = 100'000; - ::select(nfds, 0, &writefs, 0, &timeout); + socket->poll(POLLOUT, 100); } } } From 387c39d3a0ccaf89ea49d7cd24e9e2ac8a5b5e1a Mon Sep 17 00:00:00 2001 From: Kyle Schwarz Date: Mon, 29 Jul 2024 22:50:16 -0400 Subject: [PATCH 04/47] Platform: TCP: Guard against negative duration --- platform/tcp.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/tcp.cpp b/platform/tcp.cpp index 6e39ee1..ed68ebb 100644 --- a/platform/tcp.cpp +++ b/platform/tcp.cpp @@ -277,6 +277,9 @@ void TCP::Find(std::vector& found) { uint8_t buffer[bufferLen]; // keep trying till the timeout const auto msWait = std::chrono::duration_cast(rxTill - std::chrono::steady_clock::now()).count(); + if(msWait < 0) { + break; + } socket.poll(POLLIN, static_cast(msWait)); const auto recvRet = ::recv(socket, (char*)buffer, bufferLen, 0); static constexpr auto headerLength = 12; From f25a0a4a814f17a6afaa0303e8d562be8d88ae1b Mon Sep 17 00:00:00 2001 From: Kyle Schwarz Date: Fri, 2 Aug 2024 11:10:20 -0400 Subject: [PATCH 05/47] Device: Remove const from bool return type --- device/device.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/device.cpp b/device/device.cpp index 2b689ef..a1d61a2 100644 --- a/device/device.cpp +++ b/device/device.cpp @@ -2116,7 +2116,7 @@ bool Device::readVSA(const VSAExtractionSettings& extractionSettings) { if(isOnline()) { goOffline(); } - auto innerReadVSA = [&](uint64_t diskSize) -> const bool { + auto innerReadVSA = [&](uint64_t diskSize) -> bool { // Adjust driver to offset to start of VSA file const auto& offset = getVSAOffsetInLogicalDisk(); if(!offset) { From 75af3220b0aa97e66eb01a015fcda5ef3b10fa39 Mon Sep 17 00:00:00 2001 From: Kurt Wachowski Date: Tue, 13 Aug 2024 13:55:12 +0000 Subject: [PATCH 06/47] Driver: Block between read attempts Driver: * Refactored to limit accessibility of member fields; Communication: * readTask() now calls for a blocking wait; --- communication/communication.cpp | 2 +- communication/driver.cpp | 24 +++++++++++--------- include/icsneo/communication/communication.h | 3 +++ include/icsneo/communication/driver.h | 20 +++++++++------- include/icsneo/platform/ftd3xx.h | 6 +++-- include/icsneo/platform/posix/cdcacm.h | 6 +++-- include/icsneo/platform/posix/firmio.h | 7 ++++-- include/icsneo/platform/posix/ftdi.h | 3 +++ include/icsneo/platform/posix/pcap.h | 6 +++-- include/icsneo/platform/tcp.h | 6 +++-- include/icsneo/platform/windows/pcap.h | 1 + include/icsneo/platform/windows/vcp.h | 1 + platform/ftd3xx.cpp | 24 +++++++++----------- platform/posix/cdcacm.cpp | 20 ++++++++-------- platform/posix/firmio.cpp | 10 ++++---- platform/posix/ftdi.cpp | 20 ++++++++-------- platform/posix/pcap.cpp | 12 ++++------ platform/tcp.cpp | 16 ++++++------- platform/windows/pcap.cpp | 17 +++++++------- platform/windows/vcp.cpp | 16 ++++++------- 20 files changed, 116 insertions(+), 104 deletions(-) diff --git a/communication/communication.cpp b/communication/communication.cpp index 54a0ee6..45c448e 100644 --- a/communication/communication.cpp +++ b/communication/communication.cpp @@ -276,7 +276,7 @@ void Communication::readTask() { std::unique_lock lk(pauseReadTaskMutex); pauseReadTaskCv.wait(lk, [this]() { return !pauseReadTask; }); } - if(driver->readAvailable()) { + if(driver->waitForRx(readTaskWakeLimit, readTaskWakeTimeout)) { if(pauseReadTask) { /** * Reads could have paused while the driver was not available diff --git a/communication/driver.cpp b/communication/driver.cpp index 243b3ef..c50dec5 100644 --- a/communication/driver.cpp +++ b/communication/driver.cpp @@ -11,13 +11,21 @@ using namespace icsneo; bool Driver::pushRx(const uint8_t* buf, size_t numReceived) { bool ret = readBuffer.write(buf, numReceived); - if(hasRxWaitRequest) { - rxWaitRequestCv.notify_one(); - } + rxWaitCv.notify_all(); return ret; } +void Driver::clearBuffers() +{ + WriteOperation flushop; + + readBuffer.clear(); + rxWaitCv.notify_all(); + + while (writeQueue.try_dequeue(flushop)) {} +} + bool Driver::waitForRx(size_t limit, std::chrono::milliseconds timeout) { return waitForRx([limit, this]() { return readBuffer.size() >= limit; @@ -26,13 +34,7 @@ bool Driver::waitForRx(size_t limit, std::chrono::milliseconds timeout) { bool Driver::waitForRx(std::function predicate, std::chrono::milliseconds timeout) { std::unique_lock lk(rxWaitMutex); - hasRxWaitRequest = true; - - auto ret = rxWaitRequestCv.wait_for(lk, timeout, predicate); - - hasRxWaitRequest = false; - - return ret; + return rxWaitCv.wait_for(lk, timeout, predicate); } bool Driver::readWait(std::vector& bytes, std::chrono::milliseconds timeout, size_t limit) { @@ -92,4 +94,4 @@ bool Driver::write(const std::vector& bytes) { report(APIEvent::Type::Unknown, APIEvent::Severity::Error); return ret; -} \ No newline at end of file +} diff --git a/include/icsneo/communication/communication.h b/include/icsneo/communication/communication.h index 9f4b9f9..bde7a2e 100644 --- a/include/icsneo/communication/communication.h +++ b/include/icsneo/communication/communication.h @@ -87,6 +87,9 @@ public: std::unique_ptr driver; device_eventhandler_t report; + size_t readTaskWakeLimit = 1; + std::chrono::milliseconds readTaskWakeTimeout = std::chrono::milliseconds(1000); + protected: static int messageCallbackIDCounter; std::mutex messageCallbacksLock; diff --git a/include/icsneo/communication/driver.h b/include/icsneo/communication/driver.h index d92e37e..2bf82e8 100644 --- a/include/icsneo/communication/driver.h +++ b/include/icsneo/communication/driver.h @@ -24,9 +24,11 @@ public: virtual bool isOpen() = 0; virtual void modeChangeIncoming() {} virtual void awaitModeChangeComplete() {} - virtual bool isDisconnected() { return disconnected; }; virtual bool close() = 0; + inline bool isDisconnected() const { return disconnected; }; + inline bool isClosing() const { return closing; } + bool waitForRx(size_t limit, std::chrono::milliseconds timeout); bool waitForRx(std::function predicate, std::chrono::milliseconds timeout); bool readWait(std::vector& bytes, std::chrono::milliseconds timeout = std::chrono::milliseconds(100), size_t limit = 0); @@ -52,8 +54,8 @@ protected: WAIT }; - virtual void readTask() = 0; - virtual void writeTask() = 0; + inline void setIsClosing(bool isClosing) { closing = isClosing; } + inline void setIsDisconnected(bool isDisconnected) { disconnected = isDisconnected; } // Overridable in case the driver doesn't want to use writeTask and writeQueue virtual bool writeQueueFull() { return writeQueue.size_approx() > writeQueueSize; } @@ -61,13 +63,15 @@ protected: virtual bool writeInternal(const std::vector& b) { return writeQueue.enqueue(WriteOperation(b)); } bool pushRx(const uint8_t* buf, size_t numReceived); - RingBuffer readBuffer = RingBuffer(ICSNEO_DRIVER_RINGBUFFER_SIZE); - std::atomic hasRxWaitRequest = false; - std::condition_variable rxWaitRequestCv; - std::mutex rxWaitMutex; + void clearBuffers(); moodycamel::BlockingConcurrentQueue writeQueue; - std::thread readThread, writeThread; + +private: + RingBuffer readBuffer = RingBuffer(ICSNEO_DRIVER_RINGBUFFER_SIZE); + std::condition_variable rxWaitCv; + std::mutex rxWaitMutex; + std::atomic closing{false}; std::atomic disconnected{false}; }; diff --git a/include/icsneo/platform/ftd3xx.h b/include/icsneo/platform/ftd3xx.h index 24fe29d..e662921 100644 --- a/include/icsneo/platform/ftd3xx.h +++ b/include/icsneo/platform/ftd3xx.h @@ -22,8 +22,10 @@ public: private: neodevice_t& device; std::optional handle; - void readTask() override; - void writeTask() override; + + std::thread readThread, writeThread; + void readTask(); + void writeTask(); }; } diff --git a/include/icsneo/platform/posix/cdcacm.h b/include/icsneo/platform/posix/cdcacm.h index ff14917..9d978ca 100644 --- a/include/icsneo/platform/posix/cdcacm.h +++ b/include/icsneo/platform/posix/cdcacm.h @@ -47,8 +47,10 @@ private: static std::string HandleToTTY(neodevice_handle_t handle); - void readTask() override; - void writeTask() override; + std::thread readThread, writeThread; + void readTask(); + void writeTask(); + bool fdIsValid(); }; diff --git a/include/icsneo/platform/posix/firmio.h b/include/icsneo/platform/posix/firmio.h index 6fcaf5d..cf2cdb2 100644 --- a/include/icsneo/platform/posix/firmio.h +++ b/include/icsneo/platform/posix/firmio.h @@ -25,8 +25,11 @@ public: bool isOpen() override; bool close() override; private: - void readTask() override; - void writeTask() override; + std::thread readThread, writeThread; + + void readTask(); + void writeTask(); + bool writeQueueFull() override; bool writeQueueAlmostFull() override; bool writeInternal(const std::vector& bytes) override; diff --git a/include/icsneo/platform/posix/ftdi.h b/include/icsneo/platform/posix/ftdi.h index 1e1eb54..a200191 100644 --- a/include/icsneo/platform/posix/ftdi.h +++ b/include/icsneo/platform/posix/ftdi.h @@ -57,8 +57,11 @@ private: static std::vector handles; static bool ErrorIsDisconnection(int errorCode); + std::thread readThread, writeThread; + void readTask(); void writeTask(); + bool openable; // Set to false in the constructor if the object has not been found in searchResultDevices neodevice_t& device; diff --git a/include/icsneo/platform/posix/pcap.h b/include/icsneo/platform/posix/pcap.h index 3167578..223df13 100644 --- a/include/icsneo/platform/posix/pcap.h +++ b/include/icsneo/platform/posix/pcap.h @@ -30,8 +30,10 @@ private: uint8_t deviceMAC[6]; bool openable = true; EthernetPacketizer ethPacketizer; - void readTask() override; - void writeTask() override; + + std::thread readThread, writeThread; + void readTask(); + void writeTask(); class NetworkInterface { public: diff --git a/include/icsneo/platform/tcp.h b/include/icsneo/platform/tcp.h index 3757475..7d4f1af 100644 --- a/include/icsneo/platform/tcp.h +++ b/include/icsneo/platform/tcp.h @@ -47,8 +47,10 @@ private: uint32_t dstIP; uint16_t dstPort; std::unique_ptr socket; - void readTask() override; - void writeTask() override; + + std::thread readThread, writeThread; + void readTask(); + void writeTask(); }; } diff --git a/include/icsneo/platform/windows/pcap.h b/include/icsneo/platform/windows/pcap.h index f9a3cc8..a672ddf 100644 --- a/include/icsneo/platform/windows/pcap.h +++ b/include/icsneo/platform/windows/pcap.h @@ -32,6 +32,7 @@ private: bool openable = true; EthernetPacketizer ethPacketizer; + std::thread readThread, writeThread; std::thread transmitThread; pcap_send_queue* transmitQueue = nullptr; std::condition_variable transmitQueueCV; diff --git a/include/icsneo/platform/windows/vcp.h b/include/icsneo/platform/windows/vcp.h index 612afb6..5dca6b9 100644 --- a/include/icsneo/platform/windows/vcp.h +++ b/include/icsneo/platform/windows/vcp.h @@ -37,6 +37,7 @@ private: std::shared_ptr detail; std::vector> threads; + std::thread readThread, writeThread; void readTask(); void writeTask(); }; diff --git a/platform/ftd3xx.cpp b/platform/ftd3xx.cpp index 0446eb7..cd4ee98 100644 --- a/platform/ftd3xx.cpp +++ b/platform/ftd3xx.cpp @@ -64,7 +64,7 @@ bool FTD3XX::open() { } handle.emplace(tmpHandle); - closing = false; + setIsClosing(false); readThread = std::thread(&FTD3XX::readTask, this); writeThread = std::thread(&FTD3XX::writeTask, this); @@ -81,23 +81,21 @@ bool FTD3XX::close() { return false; } - closing = true; - disconnected = false; + setIsClosing(true); + setIsDisconnected(false); if(readThread.joinable()) readThread.join(); if(writeThread.joinable()) writeThread.join(); - WriteOperation flushop; - readBuffer.pop(readBuffer.size()); - while(writeQueue.try_dequeue(flushop)) {} + clearBuffers(); if(const auto ret = FT_Close(*handle); ret != FT_OK) { addEvent(ret, APIEvent::Severity::EventWarning); } - closing = false; + setIsClosing(false); return true; } @@ -110,7 +108,7 @@ void FTD3XX::readTask() { FT_SetStreamPipe(*handle, false, false, READ_PIPE_ID, bufferSize); FT_SetPipeTimeout(*handle, READ_PIPE_ID, 1); - while(!closing && !isDisconnected()) { + while(!isClosing() && !isDisconnected()) { ULONG received = 0; OVERLAPPED overlap = {}; FT_InitializeOverlapped(*handle, &overlap); @@ -119,13 +117,13 @@ void FTD3XX::readTask() { #else FT_ReadPipeAsync(*handle, 0, buffer, bufferSize, &received, &overlap); #endif - while(!closing) { + while(!isClosing()) { const auto ret = FT_GetOverlappedResult(*handle, &overlap, &received, true); if(ret == FT_IO_PENDING) continue; if(ret != FT_OK) { if(ret == FT_IO_ERROR) { - disconnected = true; + setIsDisconnected(true); report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error); } else { addEvent(ret, APIEvent::Severity::Error); @@ -146,7 +144,7 @@ void FTD3XX::writeTask() { FT_SetPipeTimeout(*handle, WRITE_PIPE_ID, 100); WriteOperation writeOp; - while(!closing && !isDisconnected()) { + while(!isClosing() && !isDisconnected()) { if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100))) continue; @@ -160,13 +158,13 @@ void FTD3XX::writeTask() { #else FT_WritePipeAsync(*handle, 0, writeOp.bytes.data(), size, &sent, &overlap); #endif - while(!closing) { + while(!isClosing()) { const auto ret = FT_GetOverlappedResult(*handle, &overlap, &sent, true); if(ret == FT_IO_PENDING) continue; if(ret != FT_OK) { if(ret == FT_IO_ERROR) { - disconnected = true; + setIsDisconnected(true); report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error); } else { addEvent(ret, APIEvent::Severity::Error); diff --git a/platform/posix/cdcacm.cpp b/platform/posix/cdcacm.cpp index 3239b2a..cd21682 100644 --- a/platform/posix/cdcacm.cpp +++ b/platform/posix/cdcacm.cpp @@ -117,7 +117,7 @@ bool CDCACM::close() { return false; } - closing = true; + setIsClosing(true); if(readThread.joinable()) readThread.join(); @@ -125,8 +125,8 @@ bool CDCACM::close() { if(writeThread.joinable()) writeThread.join(); - closing = false; - disconnected = false; + setIsClosing(false); + setIsDisconnected(false); if(modeChanging) { // We're expecting this inode to go away after we close the device @@ -140,9 +140,7 @@ bool CDCACM::close() { int ret = ::close(fd); fd = -1; - WriteOperation flushop; - readBuffer.clear(); - while (writeQueue.try_dequeue(flushop)) {} + clearBuffers(); if(modeChanging) { modeChanging = false; @@ -173,7 +171,7 @@ void CDCACM::readTask() { constexpr size_t READ_BUFFER_SIZE = 2048; uint8_t readbuf[READ_BUFFER_SIZE]; EventManager::GetInstance().downgradeErrorsOnCurrentThread(); - while(!closing && !isDisconnected()) { + while(!isClosing() && !isDisconnected()) { fd_set rfds = {0}; struct timeval tv = {0}; FD_SET(fd, &rfds); @@ -199,8 +197,8 @@ void CDCACM::readTask() { // Requesting thread is responsible for calling close. This allows for more flexibility }); break; - } else if(!closing && !fdIsValid() && !isDisconnected()) { - disconnected = true; + } else if(!isClosing() && !fdIsValid() && !isDisconnected()) { + setIsDisconnected(true); report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error); } } @@ -210,7 +208,7 @@ void CDCACM::readTask() { void CDCACM::writeTask() { WriteOperation writeOp; EventManager::GetInstance().downgradeErrorsOnCurrentThread(); - while(!closing && !isDisconnected()) { + while(!isClosing() && !isDisconnected()) { if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100))) continue; @@ -233,7 +231,7 @@ void CDCACM::writeTask() { } else if (actualWritten < 0) { if(!fdIsValid()) { if(!isDisconnected()) { - disconnected = true; + setIsDisconnected(true); report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error); } } else diff --git a/platform/posix/firmio.cpp b/platform/posix/firmio.cpp index 690cad4..6752358 100644 --- a/platform/posix/firmio.cpp +++ b/platform/posix/firmio.cpp @@ -166,13 +166,13 @@ bool FirmIO::close() { return false; } - closing = true; + setIsClosing(true); if(readThread.joinable()) readThread.join(); - closing = false; - disconnected = false; + setIsClosing(false); + setIsDisconnected(false); int ret = 0; if(vbase != nullptr) { @@ -202,7 +202,7 @@ void FirmIO::readTask() { std::cerr << "FirmIO::readTask setpriority failed : " << strerror(errno) << std::endl; } - while(!closing && !isDisconnected()) { + while(!isClosing() && !isDisconnected()) { fd_set rfds = {0}; struct timeval tv = {0}; FD_SET(fd, &rfds); @@ -244,7 +244,7 @@ void FirmIO::readTask() { uint8_t* addr = reinterpret_cast(msg.payload.data.addr - PHY_ADDR_BASE + vbase); while (!pushRx(addr, msg.payload.data.len)) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); // back-off so reading thread can empty the buffer - if (closing || isDisconnected()) { + if (isClosing() || isDisconnected()) { break; } } diff --git a/platform/posix/ftdi.cpp b/platform/posix/ftdi.cpp index 2fd0ca6..b10a1aa 100644 --- a/platform/posix/ftdi.cpp +++ b/platform/posix/ftdi.cpp @@ -81,7 +81,7 @@ bool FTDI::open() { ftdi.flush(); // Create threads - closing = false; + setIsClosing(false); readThread = std::thread(&FTDI::readTask, this); writeThread = std::thread(&FTDI::writeTask, this); @@ -94,7 +94,7 @@ bool FTDI::close() { return false; } - closing = true; + setIsClosing(true); if(readThread.joinable()) readThread.join(); @@ -109,12 +109,10 @@ bool FTDI::close() { report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error); } - WriteOperation flushop; - readBuffer.clear(); - while(writeQueue.try_dequeue(flushop)) {} + clearBuffers(); - closing = false; - disconnected = false; + setIsClosing(false); + setIsDisconnected(false); return ret; } @@ -202,12 +200,12 @@ void FTDI::readTask() { constexpr size_t READ_BUFFER_SIZE = 8; uint8_t readbuf[READ_BUFFER_SIZE]; EventManager::GetInstance().downgradeErrorsOnCurrentThread(); - while(!closing && !isDisconnected()) { + while(!isClosing() && !isDisconnected()) { auto readBytes = ftdi.read(readbuf, READ_BUFFER_SIZE); if(readBytes < 0) { if(ErrorIsDisconnection(readBytes)) { if(!isDisconnected()) { - disconnected = true; + setIsDisconnected(true); report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error); } } else @@ -220,7 +218,7 @@ void FTDI::readTask() { void FTDI::writeTask() { WriteOperation writeOp; EventManager::GetInstance().downgradeErrorsOnCurrentThread(); - while(!closing && !isDisconnected()) { + while(!isClosing() && !isDisconnected()) { if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100))) continue; @@ -230,7 +228,7 @@ void FTDI::writeTask() { if(writeBytes < 0) { if(ErrorIsDisconnection(writeBytes)) { if(!isDisconnected()) { - disconnected = true; + setIsDisconnected(true); report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error); } break; diff --git a/platform/posix/pcap.cpp b/platform/posix/pcap.cpp index ed045f0..c10146c 100644 --- a/platform/posix/pcap.cpp +++ b/platform/posix/pcap.cpp @@ -258,28 +258,26 @@ bool PCAP::close() { if(!isOpen()) return false; - closing = true; // Signal the threads that we are closing + setIsClosing(true); // Signal the threads that we are closing pcap_breakloop(iface.fp); #ifndef __linux__ pthread_cancel(readThread.native_handle()); #endif readThread.join(); writeThread.join(); - closing = false; + setIsClosing(false); pcap_close(iface.fp); iface.fp = nullptr; - WriteOperation flushop; - readBuffer.clear(); - while(writeQueue.try_dequeue(flushop)) {} + clearBuffers(); return true; } void PCAP::readTask() { EventManager::GetInstance().downgradeErrorsOnCurrentThread(); - while (!closing) { + while (!isClosing()) { pcap_dispatch(iface.fp, -1, [](uint8_t* obj, const struct pcap_pkthdr* header, const uint8_t* data) { PCAP* driver = reinterpret_cast(obj); if(driver->ethPacketizer.inputUp({data, data + header->caplen})) { @@ -294,7 +292,7 @@ void PCAP::writeTask() { WriteOperation writeOp; EventManager::GetInstance().downgradeErrorsOnCurrentThread(); - while(!closing) { + while(!isClosing()) { if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100))) continue; diff --git a/platform/tcp.cpp b/platform/tcp.cpp index ed68ebb..85bddcc 100644 --- a/platform/tcp.cpp +++ b/platform/tcp.cpp @@ -511,20 +511,18 @@ bool TCP::close() { return false; } - closing = true; - disconnected = false; + setIsClosing(true); + setIsDisconnected(false); if(readThread.joinable()) readThread.join(); if(writeThread.joinable()) writeThread.join(); - WriteOperation flushop; - readBuffer.pop(readBuffer.size()); - while(writeQueue.try_dequeue(flushop)) {} + clearBuffers(); socket.reset(); - closing = false; + setIsClosing(false); return true; } @@ -534,7 +532,7 @@ void TCP::readTask() { constexpr size_t READ_BUFFER_SIZE = 2048; uint8_t readbuf[READ_BUFFER_SIZE]; - while(!closing) { + while(!isClosing()) { if(const auto received = ::recv(*socket, (char*)readbuf, READ_BUFFER_SIZE, 0); received > 0) { pushRx(readbuf, received); } else { @@ -547,11 +545,11 @@ void TCP::writeTask() { EventManager::GetInstance().downgradeErrorsOnCurrentThread(); WriteOperation writeOp; - while(!closing) { + while(!isClosing()) { if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100))) continue; - while(!closing) { + while(!isClosing()) { if(::send(*socket, (char*)writeOp.bytes.data(), WIN_INT(writeOp.bytes.size()), 0) > 0) break; socket->poll(POLLOUT, 100); diff --git a/platform/windows/pcap.cpp b/platform/windows/pcap.cpp index 3b9e716..198af09 100644 --- a/platform/windows/pcap.cpp +++ b/platform/windows/pcap.cpp @@ -246,18 +246,17 @@ bool PCAP::close() { return false; } - closing = true; // Signal the threads that we are closing + setIsClosing(true); // Signal the threads that we are closing readThread.join(); writeThread.join(); transmitThread.join(); - closing = false; + setIsClosing(false); pcap.close(iface.fp); iface.fp = nullptr; - WriteOperation flushop; - readBuffer.clear(); - while(writeQueue.try_dequeue(flushop)) {} + clearBuffers(); + transmitQueue = nullptr; return true; @@ -267,7 +266,7 @@ void PCAP::readTask() { struct pcap_pkthdr* header; const uint8_t* data; EventManager::GetInstance().downgradeErrorsOnCurrentThread(); - while(!closing) { + while(!isClosing()) { auto readBytes = pcap.next_ex(iface.fp, &header, &data); if(readBytes < 0) { report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error); @@ -291,7 +290,7 @@ void PCAP::writeTask() { pcap_send_queue* queue2 = pcap.sendqueue_alloc(128000); pcap_send_queue* queue = queue1; - while(!closing) { + while(!isClosing()) { // Potentially, we added frames to a second queue faster than the other thread was able to hand the first // off to the kernel. In that case, wait for a minimal amount of time before checking whether we can // transmit it again. @@ -342,9 +341,9 @@ void PCAP::writeTask() { } void PCAP::transmitTask() { - while(!closing) { + while(!isClosing()) { std::unique_lock lk(transmitQueueMutex); - if(transmitQueueCV.wait_for(lk, std::chrono::milliseconds(100), [this] { return !!transmitQueue; }) && !closing && transmitQueue) { + if(transmitQueueCV.wait_for(lk, std::chrono::milliseconds(100), [this] { return !!transmitQueue; }) && !isClosing() && transmitQueue) { pcap_send_queue* current = transmitQueue; lk.unlock(); pcap.sendqueue_transmit(iface.fp, current, 0); diff --git a/platform/windows/vcp.cpp b/platform/windows/vcp.cpp index 8f41eca..c9cff53 100644 --- a/platform/windows/vcp.cpp +++ b/platform/windows/vcp.cpp @@ -326,12 +326,12 @@ bool VCP::close() { return false; } - closing = true; // Signal the threads that we are closing + setIsClosing(true); // Signal the threads that we are closing for(auto& t : threads) t->join(); // Wait for the threads to close readThread.join(); writeThread.join(); - closing = false; + setIsClosing(false); if(!CloseHandle(detail->handle)) { report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error); @@ -357,9 +357,7 @@ bool VCP::close() { detail->overlappedWait.hEvent = INVALID_HANDLE_VALUE; } - WriteOperation flushop; - readBuffer.clear(); - while(writeQueue.try_dequeue(flushop)) {} + clearBuffers(); if(!ret) report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error); @@ -379,7 +377,7 @@ void VCP::readTask() { IOTaskState state = LAUNCH; DWORD bytesRead = 0; EventManager::GetInstance().downgradeErrorsOnCurrentThread(); - while(!closing && !isDisconnected()) { + while(!isClosing() && !isDisconnected()) { switch(state) { case LAUNCH: { COMSTAT comStatus; @@ -401,7 +399,7 @@ void VCP::readTask() { else if(lastError != ERROR_SUCCESS) { if(lastError == ERROR_ACCESS_DENIED) { if(!isDisconnected()) { - disconnected = true; + setIsDisconnected(true); report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error); } } else @@ -432,7 +430,7 @@ void VCP::writeTask() { VCP::WriteOperation writeOp; DWORD bytesWritten = 0; EventManager::GetInstance().downgradeErrorsOnCurrentThread(); - while(!closing && !isDisconnected()) { + while(!isClosing() && !isDisconnected()) { switch(state) { case LAUNCH: { if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100))) @@ -448,7 +446,7 @@ void VCP::writeTask() { } else if(winerr == ERROR_ACCESS_DENIED) { if(!isDisconnected()) { - disconnected = true; + setIsDisconnected(true); report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error); } } else From cac8d760b086650f2dec82f0f4508dec3e99bf0a Mon Sep 17 00:00:00 2001 From: Kyle Johannes Date: Thu, 15 Aug 2024 16:47:35 +0000 Subject: [PATCH 07/47] Communication: Add AppErrorMessage support App errors are responses from the device indicating internal runtime errors. --- CMakeLists.txt | 2 + communication/decoder.cpp | 9 ++ communication/message/apperrormessage.cpp | 143 ++++++++++++++++++ examples/CMakeLists.txt | 5 + examples/cpp/apperror/CMakeLists.txt | 2 + examples/cpp/apperror/src/AppErrorExample.cpp | 85 +++++++++++ include/icsneo/api/event.h | 1 + .../communication/message/apperrormessage.h | 80 ++++++++++ .../icsneo/communication/message/message.h | 1 + include/icsneo/communication/network.h | 1 + test/unit/apperrordecodertest.cpp | 101 +++++++++++++ 11 files changed, 430 insertions(+) create mode 100644 communication/message/apperrormessage.cpp create mode 100644 examples/cpp/apperror/CMakeLists.txt create mode 100644 examples/cpp/apperror/src/AppErrorExample.cpp create mode 100644 include/icsneo/communication/message/apperrormessage.h create mode 100644 test/unit/apperrordecodertest.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d769479..0d5c7ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -238,6 +238,7 @@ set(SRC_FILES communication/message/flexray/control/flexraycontrolmessage.cpp communication/message/callback/streamoutput/a2bwavoutput.cpp communication/message/a2bmessage.cpp + communication/message/apperrormessage.cpp communication/message/neomessage.cpp communication/message/ethphymessage.cpp communication/message/linmessage.cpp @@ -519,6 +520,7 @@ if(LIBICSNEO_BUILD_UNIT_TESTS) test/unit/mdioencoderdecodertest.cpp test/unit/livedataencoderdecodertest.cpp test/unit/ringbuffertest.cpp + test/unit/apperrordecodertest.cpp ) target_link_libraries(libicsneo-unit-tests gtest gtest_main) diff --git a/communication/decoder.cpp b/communication/decoder.cpp index 9825e0c..1400c9c 100644 --- a/communication/decoder.cpp +++ b/communication/decoder.cpp @@ -18,6 +18,7 @@ #include "icsneo/communication/message/diskdatamessage.h" #include "icsneo/communication/message/hardwareinfo.h" #include "icsneo/communication/message/tc10statusmessage.h" +#include "icsneo/communication/message/apperrormessage.h" #include "icsneo/communication/command.h" #include "icsneo/device/device.h" #include "icsneo/communication/packet/canpacket.h" @@ -398,6 +399,14 @@ bool Decoder::decode(std::shared_ptr& result, const std::shared_ptrdata.resize(length); return decode(result, packet); } + case Network::NetID::RED_App_Error: { + result = AppErrorMessage::DecodeToMessage(packet->data, report); + if(!result) { + report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::EventWarning); + return false; + } + return true; + } case Network::NetID::ReadSettings: { auto msg = std::make_shared(); msg->response = ReadSettingsMessage::Response(packet->data[0]); diff --git a/communication/message/apperrormessage.cpp b/communication/message/apperrormessage.cpp new file mode 100644 index 0000000..5486940 --- /dev/null +++ b/communication/message/apperrormessage.cpp @@ -0,0 +1,143 @@ +#include + +namespace icsneo { + +#pragma pack(push, 2) + +typedef struct { + uint16_t error_type; + uint16_t network_id; + uint32_t uiTimeStamp10uS; + uint32_t uiTimeStamp10uSMSB; +} AppErrorData; + +#pragma pack(pop) + +std::shared_ptr AppErrorMessage::DecodeToMessage(const std::vector& bytestream, const device_eventhandler_t& report) { + const AppErrorData* data = reinterpret_cast(bytestream.data()); + if(!data) { + report(APIEvent::Type::AppErrorParsingFailed, APIEvent::Severity::Error); + return nullptr; + } + auto appErr = std::make_shared(); + appErr->errorType = data->error_type; + appErr->errorNetID = static_cast(data->network_id); + appErr->timestamp10us = data->uiTimeStamp10uS; + appErr->timestamp10usMSB = data->uiTimeStamp10uSMSB; + appErr->network = Network::NetID::RED_App_Error; + return appErr; +} + +AppErrorType AppErrorMessage::getAppErrorType() { + AppErrorType errType = static_cast(errorType); + if(errType > AppErrorType::AppNoError) { + return AppErrorType::AppNoError; + } + return errType; +} + +std::string AppErrorMessage::getAppErrorString() { + auto netIDString = Network::GetNetIDString(errorNetID); + AppErrorType errType = static_cast(errorType); + switch (errType) { + case AppErrorType::AppErrorRxMessagesFull: + return std::string(netIDString) + ": RX message buffer full"; + case AppErrorType::AppErrorTxMessagesFull: + return std::string(netIDString) + ": TX message buffer full"; + case AppErrorType::AppErrorTxReportMessagesFull: + return std::string(netIDString) + ": TX report buffer full"; + case AppErrorType::AppErrorBadCommWithDspIC: + return "Received bad packet from DSP IC"; + case AppErrorType::AppErrorDriverOverflow: + return std::string(netIDString) + ": Driver overflow"; + case AppErrorType::AppErrorPCBuffOverflow: + return "PC buffer overflow"; + case AppErrorType::AppErrorPCChksumError: + return "PC checksum error"; + case AppErrorType::AppErrorPCMissedByte: + return "PC missed byte"; + case AppErrorType::AppErrorPCOverrunError: + return "PC overrun error"; + case AppErrorType::AppErrorSettingFailure: + return std::string(netIDString) + ": Settings incorrectly set"; + case AppErrorType::AppErrorTooManySelectedNetworks: + return "Too many selected networks"; + case AppErrorType::AppErrorNetworkNotEnabled: + return std::string(netIDString) + ": Network not enabled"; + case AppErrorType::AppErrorRtcNotCorrect: + return "RTC not correct"; + case AppErrorType::AppErrorLoadedDefaultSettings: + return "Loaded default settings"; + case AppErrorType::AppErrorFeatureNotUnlocked: + return "Feature not unlocked"; + case AppErrorType::AppErrorFeatureRtcCmdDropped: + return "RTC command dropped"; + case AppErrorType::AppErrorTxMessagesFlushed: + return "TX message buffer flushed"; + case AppErrorType::AppErrorTxMessagesHalfFull: + return "TX message buffer half full"; + case AppErrorType::AppErrorNetworkNotValid: + return "Network is not valid"; + case AppErrorType::AppErrorTxInterfaceNotImplemented: + return "TX interface is not implemented"; + case AppErrorType::AppErrorTxMessagesCommEnableIsOff: + return "TX message communication is disabled"; + case AppErrorType::AppErrorRxFilterMatchCountExceeded: + return "RX filter match count exceeded"; + case AppErrorType::AppErrorEthPreemptionNotEnabled: + return std::string(netIDString) + ": Ethernet preemption not enabled"; + case AppErrorType::AppErrorTxNotSupportedInMode: + return std::string(netIDString) + ": Transmit is not supported in this mode"; + case AppErrorType::AppErrorJumboFramesNotSupported: + return std::string(netIDString) + ": Jumbo frames not supported"; + case AppErrorType::AppErrorEthernetIpFragment: + return "Ethernet IP fragment received"; + case AppErrorType::AppErrorTxMessagesUnderrun: + return std::string(netIDString) + ": Transmit buffer underrun"; + case AppErrorType::AppErrorDeviceFanFailure: + return "Device fan failure"; + case AppErrorType::AppErrorDeviceOvertemperature: + return "Device overtemperature"; + case AppErrorType::AppErrorTxMessageIndexOutOfRange: + return "Transmit message index out of range"; + case AppErrorType::AppErrorUndersizedFrameDropped: + return std::string(netIDString) + ": Undersized frame dropped"; + case AppErrorType::AppErrorOversizedFrameDropped: + return std::string(netIDString) + ": Oversized frame dropped"; + case AppErrorType::AppErrorWatchdogEvent: + return "Watchdog event occured"; + case AppErrorType::AppErrorSystemClockFailure: + return "Device clock failed"; + case AppErrorType::AppErrorSystemClockRecovered: + return "Device clock recovered"; + case AppErrorType::AppErrorSystemPeripheralReset: + return "Device peripheral reset"; + case AppErrorType::AppErrorSystemCommunicationFailure: + return "Device communication failure"; + case AppErrorType::AppErrorTxMessagesUnsupportedSourceOrPacketId: + return std::string(netIDString) + ": Transmit unsupported source or packet ID"; + case AppErrorType::AppErrorWbmsManagerConnectFailed: + return std::string(netIDString) + ": Failed to connect to managers with settings"; + case AppErrorType::AppErrorWbmsManagerConnectBadState: + return std::string(netIDString) + ": Connected to managers in a invalid state"; + case AppErrorType::AppErrorWbmsManagerConnectTimeout: + return std::string(netIDString) + ": Timeout while attempting to connect to managers"; + case AppErrorType::AppErrorFailedToInitializeLoggerDisk: + return "Device failed to initialize storage disk"; + case AppErrorType::AppErrorInvalidSetting: + return std::string(netIDString) + ": Invalid settings"; + case AppErrorType::AppErrorSystemFailureRequestedReset: + return "Device rebooted to recover from an unexpected error condition"; + case AppErrorType::AppErrorPortKeyMistmatch: + return std::string(netIDString) + ": Mismatch between key in manager and stored key"; + case AppErrorType::AppErrorErrorBufferOverflow: + return "Device error buffer overflow"; + case AppErrorType::AppNoError: + return "No error"; + default: + return "Unknown error"; + } + return "Unknown error"; +} + +} // namespace icsneo \ No newline at end of file diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index a127c94..6379bdb 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -9,6 +9,7 @@ option(LIBICSNEO_BUILD_CPP_LIVEDATA_EXAMPLE "Build the Live Data example." ON) option(LIBICSNEO_BUILD_CPP_COREMINI_EXAMPLE "Build the Coremini example." ON) option(LIBICSNEO_BUILD_CPP_MDIO_EXAMPLE "Build the MDIO example." ON) option(LIBICSNEO_BUILD_CPP_VSA_EXAMPLE "Build the VSA example." ON) +option(LIBICSNEO_BUILD_CPP_APP_ERROR_EXAMPLE "Build the app error example." ON) # Disabled until we properly build these in-tree # option(LIBICSNEO_BUILD_CSHARP_INTERACTIVE_EXAMPLE "Build the command-line interactive C# example." OFF) @@ -58,6 +59,10 @@ if(LIBICSNEO_BUILD_CPP_VSA_EXAMPLE) add_subdirectory(cpp/vsa) endif() +if(LIBICSNEO_BUILD_CPP_APP_ERROR_EXAMPLE) + add_subdirectory(cpp/apperror) +endif() + # if(LIBICSNEO_BUILD_CSHARP_INTERACTIVE_EXAMPLE) # add_subdirectory(csharp) # endif() diff --git a/examples/cpp/apperror/CMakeLists.txt b/examples/cpp/apperror/CMakeLists.txt new file mode 100644 index 0000000..1a810a2 --- /dev/null +++ b/examples/cpp/apperror/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(libicsneocpp-app-error src/AppErrorExample.cpp) +target_link_libraries(libicsneocpp-app-error icsneocpp) \ No newline at end of file diff --git a/examples/cpp/apperror/src/AppErrorExample.cpp b/examples/cpp/apperror/src/AppErrorExample.cpp new file mode 100644 index 0000000..2854a87 --- /dev/null +++ b/examples/cpp/apperror/src/AppErrorExample.cpp @@ -0,0 +1,85 @@ +#include +#include +#include +#include + +#include "icsneo/icsneocpp.h" +#include "icsneo/communication/message/apperrormessage.h" +#include "icsneo/communication/message/message.h" +/* + * App errors are responses from the device indicating internal runtime errors + * NOTE: To trigger the app error in this example, disable the HSCAN network on the device + * (e.g. with neoVI Explorer) + */ +int main() { + std::cout << "Running libicsneo " << icsneo::GetVersion() << std::endl; + std::cout << "\nFinding devices... " << std::flush; + auto devices = icsneo::FindAllDevices(); + std::cout << "OK, " << devices.size() << " device" << (devices.size() == 1 ? "" : "s") << " found" << std::endl; + + // List off the devices + for(auto& device : devices) + std::cout << '\t' << device->describe() << " @ Handle " << device->getNeoDevice().handle << std::endl; + std::cout << std::endl; + + for(auto device : devices) { + std::cout << "Connecting to " << device->describe() << "... "; + bool ret = device->open(); + if(!ret) { // Failed to open + std::cout << "FAIL" << std::endl; + std::cout << icsneo::GetLastError() << std::endl << std::endl; + continue; + } + std::cout << "OK" << std::endl << std::endl; + + // Create an app error message filter, including "internal" messages + auto filter = std::make_shared(icsneo::Message::Type::AppError); + filter->includeInternalInAny = true; + + // ...and register a callback with it. + // Add your error handling here + auto handler = device->addMessageCallback(std::make_shared(filter, [](std::shared_ptr message) { + auto msg = std::static_pointer_cast(message); + if(icsneo::Network::NetID::RED_App_Error == msg->network.getNetID()) { + std::cout << std::endl << "App error reported:" << std::endl; + std::cout << msg->getAppErrorString() << std::endl << std::endl; + } + })); + + std::cout << "Going online... "; + ret = device->goOnline(); + if(!ret) { + std::cout << "FAIL" << std::endl; + device->close(); + continue; + } + std::cout << "OK" << std::endl; + + // Prepare a CAN message + std::cout << std::endl << "Transmitting a CAN frame... "; + auto txMessage = std::make_shared(); + txMessage->network = icsneo::Network::NetID::HSCAN; + txMessage->arbid = 0x22; + txMessage->data.insert(txMessage->data.end(), {0xaa, 0xbb, 0xcc}); + // The DLC will come from the length of the data vector + txMessage->isExtended = false; + txMessage->isCANFD = false; + + // Transmit a CAN message on HSCAN, even though HSCAN is disabled on the device! + // Expect to see an app error caught in the callback defined above + ret = device->transmit(txMessage); + std::cout << (ret ? "OK" : "FAIL") << std::endl; + + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + + // Go offline, stop sending and receiving traffic + device->removeMessageCallback(handler); + std::cout << "Going offline... "; + ret = device->goOffline(); + std::cout << (ret ? "OK" : "FAIL") << std::endl; + std::cout << "Disconnecting... "; + ret = device->close(); + std::cout << (ret ? "OK\n" : "FAIL\n") << std::endl; + } + return 0; +} \ No newline at end of file diff --git a/include/icsneo/api/event.h b/include/icsneo/api/event.h index bfc3da2..f8c1539 100644 --- a/include/icsneo/api/event.h +++ b/include/icsneo/api/event.h @@ -108,6 +108,7 @@ public: LiveDataNotSupported = 0x2052, LINSettingsNotAvailable = 0x2053, ModeNotFound = 0x2054, + AppErrorParsingFailed = 0x2055, // Transport Events FailedToRead = 0x3000, diff --git a/include/icsneo/communication/message/apperrormessage.h b/include/icsneo/communication/message/apperrormessage.h new file mode 100644 index 0000000..ba8ceef --- /dev/null +++ b/include/icsneo/communication/message/apperrormessage.h @@ -0,0 +1,80 @@ +#ifndef __APPERRORMESSAGE_H_ +#define __APPERRORMESSAGE_H_ + +#ifdef __cplusplus + +#include "icsneo/communication/message/message.h" +#include +#include +#include "icsneo/api/eventmanager.h" + + +namespace icsneo { + +enum class AppErrorType : uint16_t { + AppErrorRxMessagesFull = 0, + AppErrorTxMessagesFull = 1, + AppErrorTxReportMessagesFull = 2, + AppErrorBadCommWithDspIC = 3, + AppErrorDriverOverflow = 4, + AppErrorPCBuffOverflow = 5, + AppErrorPCChksumError = 6, + AppErrorPCMissedByte = 7, + AppErrorPCOverrunError = 8, + AppErrorSettingFailure = 9, + AppErrorTooManySelectedNetworks = 10, + AppErrorNetworkNotEnabled = 11, + AppErrorRtcNotCorrect = 12, + AppErrorLoadedDefaultSettings = 13, + AppErrorFeatureNotUnlocked = 14, + AppErrorFeatureRtcCmdDropped = 15, + AppErrorTxMessagesFlushed = 16, + AppErrorTxMessagesHalfFull = 17, + AppErrorNetworkNotValid = 18, + AppErrorTxInterfaceNotImplemented = 19, + AppErrorTxMessagesCommEnableIsOff = 20, + AppErrorRxFilterMatchCountExceeded = 21, + AppErrorEthPreemptionNotEnabled = 22, + AppErrorTxNotSupportedInMode = 23, + AppErrorJumboFramesNotSupported = 24, + AppErrorEthernetIpFragment = 25, + AppErrorTxMessagesUnderrun = 26, + AppErrorDeviceFanFailure = 27, + AppErrorDeviceOvertemperature = 28, + AppErrorTxMessageIndexOutOfRange = 29, + AppErrorUndersizedFrameDropped = 30, + AppErrorOversizedFrameDropped = 31, + AppErrorWatchdogEvent = 32, + AppErrorSystemClockFailure = 33, + AppErrorSystemClockRecovered = 34, + AppErrorSystemPeripheralReset = 35, + AppErrorSystemCommunicationFailure = 36, + AppErrorTxMessagesUnsupportedSourceOrPacketId = 37, + AppErrorWbmsManagerConnectFailed = 38, + AppErrorWbmsManagerConnectBadState = 39, + AppErrorWbmsManagerConnectTimeout = 40, + AppErrorFailedToInitializeLoggerDisk = 41, + AppErrorInvalidSetting = 42, + AppErrorSystemFailureRequestedReset = 43, + AppErrorPortKeyMistmatch = 45, + AppErrorErrorBufferOverflow = 254, + AppNoError = 255 +}; + +class AppErrorMessage : public RawMessage { +public: + AppErrorMessage() : RawMessage(Message::Type::AppError, Network::NetID::RED_App_Error) {} + uint16_t errorType; + Network::NetID errorNetID; + uint32_t timestamp10us; + uint32_t timestamp10usMSB; + + static std::shared_ptr DecodeToMessage(const std::vector& bytestream, const device_eventhandler_t& report); + AppErrorType getAppErrorType(); + std::string getAppErrorString(); +}; + +} // namespace icsneo + +#endif // __cplusplus +#endif \ No newline at end of file diff --git a/include/icsneo/communication/message/message.h b/include/icsneo/communication/message/message.h index 7c5be97..259ce7a 100644 --- a/include/icsneo/communication/message/message.h +++ b/include/icsneo/communication/message/message.h @@ -40,6 +40,7 @@ public: LiveData = 0x800f, HardwareInfo = 0x8010, TC10Status = 0x8011, + AppError = 0x8012, }; Message(Type t) : type(t) {} diff --git a/include/icsneo/communication/network.h b/include/icsneo/communication/network.h index 2bc4596..613d3fc 100644 --- a/include/icsneo/communication/network.h +++ b/include/icsneo/communication/network.h @@ -537,6 +537,7 @@ public: case NetID::NeoMemoryWriteDone: case NetID::RED_GET_RTC: case NetID::DiskData: + case NetID::RED_App_Error: return Type::Internal; case NetID::Invalid: case NetID::Any: diff --git a/test/unit/apperrordecodertest.cpp b/test/unit/apperrordecodertest.cpp new file mode 100644 index 0000000..f0919ce --- /dev/null +++ b/test/unit/apperrordecodertest.cpp @@ -0,0 +1,101 @@ +#include "icsneo/icsneocpp.h" +#include "icsneo/communication/encoder.h" +#include "icsneo/communication/message/apperrormessage.h" +#include "icsneo/communication/packetizer.h" +#include "icsneo/device/tree/neovired2/neovired2.h" +#include "icsneo/api/eventmanager.h" +#include "gtest/gtest.h" +#include +#include + +using namespace icsneo; + +class REDAppErrorDecoderTest : public ::testing::Test { +protected: + void SetUp() override { + report = [](APIEvent::Type, APIEvent::Severity) { + // Unless caught by the test, the packetizer should not throw errors + EXPECT_TRUE(false); + }; + + packetizer.emplace([this](APIEvent::Type t, APIEvent::Severity s) { report(t, s); }); + packetEncoder.emplace([this](APIEvent::Type t, APIEvent::Severity s) { report(t, s); }); + packetDecoder.emplace([this](APIEvent::Type t, APIEvent::Severity s) { report(t, s); }); + } + + device_eventhandler_t report; + std::optional packetEncoder; + std::optional packetizer; + std::optional packetDecoder; + + RingBuffer ringBuffer = RingBuffer(128); + + std::vector testErrorData = + {0xaa, 0x0c, + 0x12, 0x00, //size + 0x34, 0x00, //netID + 0x0b, 0x00, //error_type + 0x01, 0x00, //network_id + 0x33, 0x44, 0x55, 0x66, //uiTime10us + 0x77, 0x88, 0x99, 0xAA, //uiTime10usMSB + }; +}; + +TEST_F(REDAppErrorDecoderTest, PacketDecoderTest) { + std::shared_ptr decodeMsg; + + auto msg1 = std::make_shared(); + msg1->errorType = static_cast(AppErrorType::AppErrorNetworkNotEnabled); + msg1->errorNetID = Network::NetID::HSCAN; + msg1->timestamp10us = 0x66554433; + msg1->timestamp10usMSB = 0xAA998877; + msg1->network = icsneo::Network::NetID::RED_App_Error; + + ringBuffer.clear(); + ringBuffer.write(testErrorData); + + EXPECT_TRUE(packetizer->input(ringBuffer)); + auto packets = packetizer->output(); + + EXPECT_TRUE(packetDecoder->decode(decodeMsg, packets.back())); + EXPECT_NE(decodeMsg, nullptr); + auto testMessage = std::dynamic_pointer_cast(decodeMsg); + EXPECT_EQ(msg1->network, testMessage->network); + EXPECT_EQ(msg1->errorType, testMessage->errorType); + EXPECT_EQ(msg1->errorNetID, testMessage->errorNetID); + EXPECT_EQ(msg1->timestamp10us, testMessage->timestamp10us); + EXPECT_EQ(msg1->timestamp10usMSB, testMessage->timestamp10usMSB); + packets.pop_back(); +} + +TEST_F(REDAppErrorDecoderTest, GetErrorStringTest) { + std::shared_ptr decodeMsg; + + ringBuffer.clear(); + ringBuffer.write(testErrorData); + + EXPECT_TRUE(packetizer->input(ringBuffer)); + auto packets = packetizer->output(); + + EXPECT_TRUE(packetDecoder->decode(decodeMsg, packets.back())); + EXPECT_NE(decodeMsg, nullptr); + auto testMessage = std::dynamic_pointer_cast(decodeMsg); + EXPECT_EQ("HSCAN: Network not enabled", testMessage->getAppErrorString()); + packets.pop_back(); +} + +TEST_F(REDAppErrorDecoderTest, GetTypeTest) { + std::shared_ptr decodeMsg; + + ringBuffer.clear(); + ringBuffer.write(testErrorData); + + EXPECT_TRUE(packetizer->input(ringBuffer)); + auto packets = packetizer->output(); + + EXPECT_TRUE(packetDecoder->decode(decodeMsg, packets.back())); + EXPECT_NE(decodeMsg, nullptr); + auto testMessage = std::dynamic_pointer_cast(decodeMsg); + EXPECT_EQ(AppErrorType::AppErrorNetworkNotEnabled, testMessage->getAppErrorType()); + packets.pop_back(); +} From 564933cb41a5673ae6d813aba5f6e43ce4acabad Mon Sep 17 00:00:00 2001 From: Kyle Schwarz Date: Wed, 21 Aug 2024 10:42:04 -0400 Subject: [PATCH 08/47] Device: Add readCoreminiHeader() - Fixes NeoMemoryDiskDriver::readLogicalDiskAligned() for flash - Adds FlashMemoryMessage --- communication/decoder.cpp | 13 +++ device/device.cpp | 79 +++++++++++++++++++ disk/neomemorydiskdriver.cpp | 28 ++++--- .../message/flashmemorymessage.h | 20 +++++ include/icsneo/communication/network.h | 1 + include/icsneo/device/coremini.h | 28 +++++++ include/icsneo/device/device.h | 3 + 7 files changed, 163 insertions(+), 9 deletions(-) create mode 100644 include/icsneo/communication/message/flashmemorymessage.h create mode 100644 include/icsneo/device/coremini.h diff --git a/communication/decoder.cpp b/communication/decoder.cpp index 1400c9c..ac00464 100644 --- a/communication/decoder.cpp +++ b/communication/decoder.cpp @@ -5,6 +5,7 @@ #include "icsneo/communication/message/readsettingsmessage.h" #include "icsneo/communication/message/canerrorcountmessage.h" #include "icsneo/communication/message/neoreadmemorysdmessage.h" +#include "icsneo/communication/message/flashmemorymessage.h" #include "icsneo/communication/message/extendedresponsemessage.h" #include "icsneo/communication/message/wiviresponsemessage.h" #include "icsneo/communication/message/scriptstatusmessage.h" @@ -257,6 +258,18 @@ bool Decoder::decode(std::shared_ptr& result, const std::shared_ptr(packet->network, packet->data); return true; } + case Network::NetID::RED_INT_MEMORYREAD: { + if(packet->data.size() != 512 + sizeof(uint16_t)) { + report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error); + return false; // Should get enough data for a start address and sector + } + + const auto msg = std::make_shared(); + result = msg; + msg->startAddress = *reinterpret_cast(packet->data.data()); + msg->data.insert(msg->data.end(), packet->data.begin() + 2, packet->data.end()); + return true; + } case Network::NetID::NeoMemorySDRead: { if(packet->data.size() != 512 + sizeof(uint32_t)) { report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error); diff --git a/device/device.cpp b/device/device.cpp index a1d61a2..cfdec32 100644 --- a/device/device.cpp +++ b/device/device.cpp @@ -656,6 +656,85 @@ bool Device::clearScript(Disk::MemoryType memType) return true; } +std::optional Device::readCoreminiHeader(Disk::MemoryType memType) { + if(!isOpen()) { + report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error); + return std::nullopt; + } + + auto startAddress = getCoreminiStartAddress(memType); + if(!startAddress) { + return std::nullopt; + } + + auto connected = isLogicalDiskConnected(); + + if(!connected) { + return std::nullopt; // Already added an API error + } + + #pragma pack(push, 2) + struct RawCoreminiHeader { + uint16_t fileType; + uint16_t fileVersion; + uint32_t storedFileSize; + uint32_t fileChecksum; + union + { + struct + { + uint32_t skipDecompression : 1; + uint32_t encryptedMode : 1; + uint32_t reserved : 30; + } bits; + uint32_t word; + } flags; + uint8_t fileHash[32]; + union + { + struct + { + uint32_t lsb; + uint32_t msb; + } words; + uint64_t time64; + } createTime; + uint8_t reserved[8]; + }; + #pragma pack(pop) + + RawCoreminiHeader header = {}; + auto numRead = readLogicalDisk(*startAddress, (uint8_t*)&header, sizeof(header), std::chrono::milliseconds(2000), memType); + + if(!numRead) { + return std::nullopt; // Already added an API error + } + + if(*numRead != sizeof(header)) { + report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error); + return std::nullopt; + } + + if(header.fileType != 0x0907) { + report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error); + return std::nullopt; + } + + std::optional ret; + ret.emplace(); + ret->coreminiVersion = header.fileVersion; + ret->storedFileSize = header.storedFileSize; + ret->fileChecksum = header.fileChecksum; + ret->skipDecompression = static_cast(header.flags.bits.skipDecompression); + ret->encryptedMode = static_cast(header.flags.bits.encryptedMode); + std::copy(std::begin(header.fileHash), std::end(header.fileHash), ret->fileHash.begin()); + static constexpr std::chrono::seconds icsEpochDelta(1167609600); + static constexpr uint8_t timestampResolution = 25; + static constexpr uint16_t nsInUs = 1'000; + ret->timestamp += icsEpochDelta + std::chrono::microseconds(header.createTime.time64 * timestampResolution / nsInUs); + return ret; +} + bool Device::transmit(std::shared_ptr frame) { if(!isOpen()) { report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error); diff --git a/disk/neomemorydiskdriver.cpp b/disk/neomemorydiskdriver.cpp index b5474cb..fa75819 100644 --- a/disk/neomemorydiskdriver.cpp +++ b/disk/neomemorydiskdriver.cpp @@ -1,5 +1,6 @@ #include "icsneo/disk/neomemorydiskdriver.h" #include "icsneo/communication/message/neoreadmemorysdmessage.h" +#include "icsneo/communication/message/flashmemorymessage.h" #include #include @@ -8,7 +9,8 @@ using namespace icsneo::Disk; std::optional NeoMemoryDiskDriver::readLogicalDiskAligned(Communication& com, device_eventhandler_t report, uint64_t pos, uint8_t* into, uint64_t amount, std::chrono::milliseconds timeout, MemoryType memType) { - static std::shared_ptr NeoMemorySDRead = std::make_shared(Network::NetID::NeoMemorySDRead); + const auto filter = std::make_shared((memType == MemoryType::SD ? Network::NetID::NeoMemorySDRead : Network::NetID::RED_INT_MEMORYREAD)); + filter->includeInternalInAny = true; if(pos % SectorSize != 0) return std::nullopt; @@ -20,7 +22,7 @@ std::optional NeoMemoryDiskDriver::readLogicalDiskAligned(Communicatio const uint8_t memLocation = (uint8_t)memType; uint64_t numWords = amount / 2; - + auto msg = com.waitForMessageSync([¤tSector, &memLocation, &com, &numWords] { return com.sendCommand(Command::NeoReadMemory, { memLocation, @@ -33,18 +35,26 @@ std::optional NeoMemoryDiskDriver::readLogicalDiskAligned(Communicatio uint8_t((numWords >> 16) & 0xFF), uint8_t((numWords >> 24) & 0xFF) }); - }, NeoMemorySDRead, timeout); + }, filter, timeout); if(!msg) return 0; - const auto sdmsg = std::dynamic_pointer_cast(msg); - if(!sdmsg || sdmsg->data.size() != SectorSize) { - report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error); - return std::nullopt; + if(memType == MemoryType::SD) { + const auto mem = std::dynamic_pointer_cast(msg); + if(!mem || mem->data.size() != SectorSize) { + report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error); + return std::nullopt; + } + memcpy(into, mem->data.data(), SectorSize); + } else { // flash + const auto mem = std::dynamic_pointer_cast(msg); + if(!mem || mem->data.size() != SectorSize) { + report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error); + return std::nullopt; + } + memcpy(into, mem->data.data(), SectorSize); } - - memcpy(into, sdmsg->data.data(), SectorSize); return SectorSize; } diff --git a/include/icsneo/communication/message/flashmemorymessage.h b/include/icsneo/communication/message/flashmemorymessage.h new file mode 100644 index 0000000..4ac2e6b --- /dev/null +++ b/include/icsneo/communication/message/flashmemorymessage.h @@ -0,0 +1,20 @@ +#ifndef __FLASHMEMORYMESSAGE_H_ +#define __FLASHMEMORYMESSAGE_H_ + +#ifdef __cplusplus + +#include "icsneo/communication/message/message.h" + +namespace icsneo { + +class FlashMemoryMessage : public RawMessage { +public: + FlashMemoryMessage() : RawMessage(Message::Type::RawMessage, Network::NetID::RED_INT_MEMORYREAD) {} + uint16_t startAddress = 0; +}; + +} + +#endif // __cplusplus + +#endif \ No newline at end of file diff --git a/include/icsneo/communication/network.h b/include/icsneo/communication/network.h index 613d3fc..55688d3 100644 --- a/include/icsneo/communication/network.h +++ b/include/icsneo/communication/network.h @@ -533,6 +533,7 @@ public: case NetID::CoreMiniPreLoad: case NetID::ExtendedCommand: case NetID::ExtendedData: + case NetID::RED_INT_MEMORYREAD: case NetID::NeoMemorySDRead: case NetID::NeoMemoryWriteDone: case NetID::RED_GET_RTC: diff --git a/include/icsneo/device/coremini.h b/include/icsneo/device/coremini.h new file mode 100644 index 0000000..05bd8c3 --- /dev/null +++ b/include/icsneo/device/coremini.h @@ -0,0 +1,28 @@ +#ifndef __COREMINI_H_ +#define __COREMINI_H_ + +#ifdef __cplusplus + +#include +#include +#include + +namespace icsneo { + +struct CoreminiHeader { + uint16_t coreminiVersion; + uint32_t storedFileSize; + // 32-bit word checksum on the entire (decompressed) binary, with the checksum and hash fields set to 0 + uint32_t fileChecksum; + // SHA256 hash of the entire (decompressed) binary, with the checksum, hash, and create time fields set to 0 + bool skipDecompression; + bool encryptedMode; + std::array fileHash; + std::chrono::time_point timestamp; +}; + +} + +#endif // __cplusplus + +#endif \ No newline at end of file diff --git a/include/icsneo/device/device.h b/include/icsneo/device/device.h index dc1ce01..169cbc1 100644 --- a/include/icsneo/device/device.h +++ b/include/icsneo/device/device.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "icsneo/api/eventmanager.h" #include "icsneo/api/lifetime.h" #include "icsneo/device/neodevice.h" @@ -21,6 +22,7 @@ #include "icsneo/device/devicetype.h" #include "icsneo/device/deviceversion.h" #include "icsneo/device/founddevice.h" +#include "icsneo/device/coremini.h" #include "icsneo/disk/diskreaddriver.h" #include "icsneo/disk/diskwritedriver.h" #include "icsneo/disk/nulldiskdriver.h" @@ -163,6 +165,7 @@ public: bool stopScript(); bool clearScript(Disk::MemoryType memType = Disk::MemoryType::SD); bool uploadCoremini(std::istream& stream, Disk::MemoryType memType = Disk::MemoryType::SD); + std::optional readCoreminiHeader(Disk::MemoryType memType = Disk::MemoryType::SD); bool eraseScriptMemory(Disk::MemoryType memType, uint64_t amount); From ca370a13100e9002ad32e40509a9e35efb8170f3 Mon Sep 17 00:00:00 2001 From: Bryant Jones Date: Thu, 22 Aug 2024 16:06:13 +0000 Subject: [PATCH 09/47] Device: Comet2: Enable TC10 --- include/icsneo/device/tree/radcomet/radcomet2.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/icsneo/device/tree/radcomet/radcomet2.h b/include/icsneo/device/tree/radcomet/radcomet2.h index 1d4be52..8b6b0da 100644 --- a/include/icsneo/device/tree/radcomet/radcomet2.h +++ b/include/icsneo/device/tree/radcomet/radcomet2.h @@ -27,6 +27,8 @@ public: return supportedNetworks; } + bool supportsTC10() const override { return true; } + protected: RADComet2(neodevice_t neodevice, const driver_factory_t& makeDriver) : RADCometBase(neodevice) { initialize(makeDriver); From 39bcef0230bf2b937736fad21d3c783a9f981818 Mon Sep 17 00:00:00 2001 From: Kyle Johannes Date: Thu, 29 Aug 2024 15:01:34 +0000 Subject: [PATCH 10/47] Communication: warning fix --- communication/message/apperrormessage.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/communication/message/apperrormessage.cpp b/communication/message/apperrormessage.cpp index 5486940..59e8f5a 100644 --- a/communication/message/apperrormessage.cpp +++ b/communication/message/apperrormessage.cpp @@ -137,7 +137,6 @@ std::string AppErrorMessage::getAppErrorString() { default: return "Unknown error"; } - return "Unknown error"; } } // namespace icsneo \ No newline at end of file From 7f30179cc493f33fea9e70c98674d10e8446d786 Mon Sep 17 00:00:00 2001 From: Kyle Schwarz Date: Wed, 21 Aug 2024 01:30:48 -0400 Subject: [PATCH 11/47] Build: Update D3XX libraries --- CMakeLists.txt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d5c7ba..a65ae4a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -172,27 +172,27 @@ if(LIBICSNEO_ENABLE_FTD3XX) if(NOT FTD3XX_ROOT) # allow system override include(FetchContent) if(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 8) - set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/23.28.0/libftd3xx-1.3.0.4-win-x64.zip") - set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=ee1289cdd5023de67275aaa1712e8e32e73e825a8392efb0a76f161e357fbdc9") + set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/24.34.0/libftd3xx-1.3.0.10-win-x64.zip") + set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=459e635496ab47d6069c9d3515fdd6d82cba3d95e7ae34f794d66ffdf336e9d1") elseif(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 4) - set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/23.28.0/libftd3xx-1.3.0.4-win-i686.zip") - set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=bcd31f5c3cb39ecb9b09db5ce722bd79de6e0f813130e7b8f2c86879a60d8ff0") + set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/24.34.0/libftd3xx-1.3.0.10-win-i686.zip") + set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=ce4259ae11772d6ede7d217172156fa392f329b29d9455131f4126a2fb89dad1") elseif(APPLE AND CMAKE_SIZEOF_VOID_P EQUAL 8) - set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/23.28.0/libftd3xx-1.0.14-macos-universal2.zip") - set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=74c0d35f04242d0841532c6325eb2932b8f627e3c395382a15d9f39974d27a90") + set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/24.34.0/libftd3xx-1.0.16-macos-universal2.zip") + set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=0904ac5eda8e1dc4b5aac3714383bcc7792b42dfeb585dce6cbfb8b67b8c0c51") elseif(UNIX) if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64") if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/23.28.0/libftd3xx-1.0.14-linux-x64.zip") - set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=a9dc7eb6948c8977fbd79f6700bec6f882d3da5667aea8f2175b8d1f6f08e456") + set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/24.34.0/libftd3xx-1.0.16-linux-x64.zip") + set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=cf66bf299fc722f050cdd3c36998a670f1df69f7c0df18afa73707277067114b") endif() elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm.*|aarch64") if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/23.28.0/libftd3xx-1.0.14-linux-aarch64.zip") - set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=da4b90ea1cbb905874cd159ad2ab8c1bdde65cc22b3aa55bf2b5fd85ca6efd22") + set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/24.34.0/libftd3xx-1.0.16-linux-aarch64.zip") + set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=66341b5112b9841e959e81400b51711be96fec91894477c5cbfc29b10a0c00a6") elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) - set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/23.28.0/libftd3xx-1.0.14-linux-armhf.zip") - set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=d813008117422cae958f7c71a065cdac0d31dca3b24809d3ab5e13604a9c3fb1") + set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/24.34.0/libftd3xx-1.0.16-linux-armhf.zip") + set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=cec1f959b48a11eb6b829ed43c81b6ba1c0bcf3e797bafcc84a6376e5ffc3c47") endif() endif() endif() From 99183a89f98dc6cc2ce5599ea003f77e2f5b3d06 Mon Sep 17 00:00:00 2001 From: Bryant Jones Date: Thu, 29 Aug 2024 11:36:47 -0400 Subject: [PATCH 12/47] Communication: Add new app errors --- communication/message/apperrormessage.cpp | 6 ++++++ include/icsneo/communication/message/apperrormessage.h | 3 +++ 2 files changed, 9 insertions(+) diff --git a/communication/message/apperrormessage.cpp b/communication/message/apperrormessage.cpp index 59e8f5a..038a389 100644 --- a/communication/message/apperrormessage.cpp +++ b/communication/message/apperrormessage.cpp @@ -130,6 +130,12 @@ std::string AppErrorMessage::getAppErrorString() { return "Device rebooted to recover from an unexpected error condition"; case AppErrorType::AppErrorPortKeyMistmatch: return std::string(netIDString) + ": Mismatch between key in manager and stored key"; + case AppErrorType::AppErrorBusFailure: + return std::string(netIDString) + ": Bus failure"; + case AppErrorType::AppErrorTapOverflow: + return std::string(netIDString) + ": Tap overflow"; + case AppErrorType::AppErrorEthTxNoLink: + return std::string(netIDString) + ": Attempted Ethernet transmit without link"; case AppErrorType::AppErrorErrorBufferOverflow: return "Device error buffer overflow"; case AppErrorType::AppNoError: diff --git a/include/icsneo/communication/message/apperrormessage.h b/include/icsneo/communication/message/apperrormessage.h index ba8ceef..8c81b54 100644 --- a/include/icsneo/communication/message/apperrormessage.h +++ b/include/icsneo/communication/message/apperrormessage.h @@ -57,6 +57,9 @@ enum class AppErrorType : uint16_t { AppErrorInvalidSetting = 42, AppErrorSystemFailureRequestedReset = 43, AppErrorPortKeyMistmatch = 45, + AppErrorBusFailure = 46, + AppErrorTapOverflow = 47, + AppErrorEthTxNoLink = 48, AppErrorErrorBufferOverflow = 254, AppNoError = 255 }; From ee7b66625a2161627ac860a8192009c73e3fee5f Mon Sep 17 00:00:00 2001 From: Bryant Jones Date: Wed, 25 Sep 2024 14:09:38 -0400 Subject: [PATCH 13/47] Network: Add support for new networks on LIN, SPI, and OP Eth --- include/icsneo/communication/network.h | 162 +++++++++++++++++++++++++ 1 file changed, 162 insertions(+) diff --git a/include/icsneo/communication/network.h b/include/icsneo/communication/network.h index 55688d3..2c4a11d 100644 --- a/include/icsneo/communication/network.h +++ b/include/icsneo/communication/network.h @@ -166,6 +166,24 @@ public: MDIO6 = 550, MDIO7 = 551, MDIO8 = 552, + OP_Ethernet13 = 553, + OP_Ethernet14 = 554, + OP_Ethernet15 = 555, + OP_Ethernet16 = 556, + SPI3 = 557, + SPI4 = 558, + SPI5 = 559, + SPI6 = 560, + SPI7 = 561, + SPI8 = 562, + LIN9 = 563, + LIN10 = 564, + LIN11 = 565, + LIN12 = 566, + LIN13 = 567, + LIN14 = 568, + LIN15 = 569, + LIN16 = 570, Any = 0xfffe, // Never actually set as type, but used as flag for filtering Invalid = 0xffff }; @@ -270,6 +288,24 @@ public: MDIO6 = 80, MDIO7 = 81, MDIO8 = 82, + OP_Ethernet13 = 83, + OP_Ethernet14 = 84, + OP_Ethernet15 = 85, + OP_Ethernet16 = 86, + SPI3 = 87, + SPI4 = 88, + SPI5 = 89, + SPI6 = 90, + SPI7 = 91, + SPI8 = 92, + LIN9 = 93, + LIN10 = 94, + LIN11 = 95, + LIN12 = 96, + LIN13 = 97, + LIN14 = 98, + LIN15 = 99, + LIN16 = 100, }; static const char* GetTypeString(Type type) { switch(type) { @@ -506,6 +542,14 @@ public: case NetID::LIN6: case NetID::LIN7: case NetID::LIN8: + case NetID::LIN9: + case NetID::LIN10: + case NetID::LIN11: + case NetID::LIN12: + case NetID::LIN13: + case NetID::LIN14: + case NetID::LIN15: + case NetID::LIN16: return Type::LIN; case NetID::FlexRay: case NetID::FlexRay1a: @@ -559,6 +603,10 @@ public: case NetID::OP_Ethernet10: case NetID::OP_Ethernet11: case NetID::OP_Ethernet12: + case NetID::OP_Ethernet13: + case NetID::OP_Ethernet14: + case NetID::OP_Ethernet15: + case NetID::OP_Ethernet16: return Type::Ethernet; case NetID::LSFTCAN: case NetID::LSFTCAN2: @@ -581,6 +629,12 @@ public: return Type::A2B; case NetID::SPI1: case NetID::SPI2: + case NetID::SPI3: + case NetID::SPI4: + case NetID::SPI5: + case NetID::SPI6: + case NetID::SPI7: + case NetID::SPI8: return Type::SPI; case NetID::MDIO1: case NetID::MDIO2: @@ -770,6 +824,14 @@ public: return "FlexRay 2"; case NetID::OP_Ethernet12: return "OP (BR) Ethernet 12"; + case NetID::OP_Ethernet13: + return "OP (BR) Ethernet 13"; + case NetID::OP_Ethernet14: + return "OP (BR) Ethernet 14"; + case NetID::OP_Ethernet15: + return "OP (BR) Ethernet 15"; + case NetID::OP_Ethernet16: + return "OP (BR) Ethernet 16"; case NetID::I2C: return "I2C"; case NetID::MOST25: @@ -850,12 +912,40 @@ public: return "LIN 07"; case NetID::LIN8: return "LIN 08"; + case NetID::LIN9: + return "LIN 09"; + case NetID::LIN10: + return "LIN 10"; + case NetID::LIN11: + return "LIN 11"; + case NetID::LIN12: + return "LIN 12"; + case NetID::LIN13: + return "LIN 13"; + case NetID::LIN14: + return "LIN 14"; + case NetID::LIN15: + return "LIN 15"; + case NetID::LIN16: + return "LIN 16"; case NetID::WBMS: return "WBMS"; case NetID::SPI1: return "SPI 1"; case NetID::SPI2: return "SPI 2"; + case NetID::SPI3: + return "SPI 3"; + case NetID::SPI4: + return "SPI 4"; + case NetID::SPI5: + return "SPI 5"; + case NetID::SPI6: + return "SPI 6"; + case NetID::SPI7: + return "SPI 7"; + case NetID::SPI8: + return "SPI 8"; case NetID::MDIO1: return "MDIO 1"; case NetID::MDIO2: @@ -976,6 +1066,14 @@ public: return CoreMini::OP_Ethernet11; case NetID::OP_Ethernet12: return CoreMini::OP_Ethernet12; + case NetID::OP_Ethernet13: + return CoreMini::OP_Ethernet13; + case NetID::OP_Ethernet14: + return CoreMini::OP_Ethernet14; + case NetID::OP_Ethernet15: + return CoreMini::OP_Ethernet15; + case NetID::OP_Ethernet16: + return CoreMini::OP_Ethernet16; case NetID::TCP: return CoreMini::TCPVirtual; case NetID::UDP: @@ -1024,10 +1122,38 @@ public: return CoreMini::LIN7; case NetID::LIN8: return CoreMini::LIN8; + case NetID::LIN9: + return CoreMini::LIN9; + case NetID::LIN10: + return CoreMini::LIN10; + case NetID::LIN11: + return CoreMini::LIN11; + case NetID::LIN12: + return CoreMini::LIN12; + case NetID::LIN13: + return CoreMini::LIN13; + case NetID::LIN14: + return CoreMini::LIN14; + case NetID::LIN15: + return CoreMini::LIN15; + case NetID::LIN16: + return CoreMini::LIN16; case NetID::SPI1: return CoreMini::SPI1; case NetID::SPI2: return CoreMini::SPI2; + case NetID::SPI3: + return CoreMini::SPI3; + case NetID::SPI4: + return CoreMini::SPI4; + case NetID::SPI5: + return CoreMini::SPI5; + case NetID::SPI6: + return CoreMini::SPI6; + case NetID::SPI7: + return CoreMini::SPI7; + case NetID::SPI8: + return CoreMini::SPI8; case NetID::MDIO1: return CoreMini::MDIO1; case NetID::MDIO2: @@ -1146,6 +1272,14 @@ public: return NetID::OP_Ethernet11; case CoreMini::OP_Ethernet12: return NetID::OP_Ethernet12; + case CoreMini::OP_Ethernet13: + return NetID::OP_Ethernet13; + case CoreMini::OP_Ethernet14: + return NetID::OP_Ethernet14; + case CoreMini::OP_Ethernet15: + return NetID::OP_Ethernet15; + case CoreMini::OP_Ethernet16: + return NetID::OP_Ethernet16; case CoreMini::TCPVirtual: return NetID::TCP; case CoreMini::UDPVirtual: @@ -1194,10 +1328,38 @@ public: return NetID::LIN7; case CoreMini::LIN8: return NetID::LIN8; + case CoreMini::LIN9: + return NetID::LIN9; + case CoreMini::LIN10: + return NetID::LIN10; + case CoreMini::LIN11: + return NetID::LIN11; + case CoreMini::LIN12: + return NetID::LIN12; + case CoreMini::LIN13: + return NetID::LIN13; + case CoreMini::LIN14: + return NetID::LIN14; + case CoreMini::LIN15: + return NetID::LIN15; + case CoreMini::LIN16: + return NetID::LIN16; case CoreMini::SPI1: return NetID::SPI1; case CoreMini::SPI2: return NetID::SPI2; + case CoreMini::SPI3: + return NetID::SPI3; + case CoreMini::SPI4: + return NetID::SPI4; + case CoreMini::SPI5: + return NetID::SPI5; + case CoreMini::SPI6: + return NetID::SPI6; + case CoreMini::SPI7: + return NetID::SPI7; + case CoreMini::SPI8: + return NetID::SPI8; case CoreMini::MDIO1: return NetID::MDIO1; case CoreMini::MDIO2: From 24f291dc8372ed7aa0d538422e6faee5b2143f43 Mon Sep 17 00:00:00 2001 From: Bryant Jones Date: Thu, 26 Sep 2024 20:42:41 +0000 Subject: [PATCH 14/47] Device: Comet: Update settings --- include/icsneo/device/idevicesettings.h | 10 ++++++++++ include/icsneo/device/tree/radcomet/radcometsettings.h | 5 ++++- .../icsneo/device/tree/radcomet3/radcomet3settings.h | 9 +++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/include/icsneo/device/idevicesettings.h b/include/icsneo/device/idevicesettings.h index d2b7ce3..968f362 100644 --- a/include/icsneo/device/idevicesettings.h +++ b/include/icsneo/device/idevicesettings.h @@ -395,6 +395,16 @@ typedef struct ETHERNET10T1S_SETTINGS_t #define ETHERNET10T1S_SETTINGS_FLAG_ENABLE_PLCA 0x01 #define ETHERNET10T1S_SETTINGS_FLAG_TERMINATION 0x02 +#define ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_BEACONS 0x04 +#define ETHERNET10T1S_SETTINGS_FLAG_BUS_DECODING_ALL 0x08 + +typedef struct ETHERNET10T1S_SETTINGS_EXT_t +{ + uint8_t enable_multi_id; // Mask representing whether ID at corresponding bit enabled or not + uint8_t multi_id[7]; + uint8_t rsvd[8]; +} ETHERNET10T1S_SETTINGS_EXT; +#define ETHERNET10T1S_SETTINGS_EXT_SIZE 16 #define ETHERNET_SETTINGS10G_FLAG_FULL_DUPLEX 0x01 #define ETHERNET_SETTINGS10G_FLAG_AUTO_NEG 0x02 diff --git a/include/icsneo/device/tree/radcomet/radcometsettings.h b/include/icsneo/device/tree/radcomet/radcometsettings.h index 5cb44b5..f673603 100644 --- a/include/icsneo/device/tree/radcomet/radcometsettings.h +++ b/include/icsneo/device/tree/radcomet/radcometsettings.h @@ -71,6 +71,9 @@ typedef struct { ETHERNET10T1S_SETTINGS t1s2; uint64_t network_enables_5; LIN_SETTINGS lin1; + // 10T1S Extended settings + ETHERNET10T1S_SETTINGS_EXT t1s1Ext; + ETHERNET10T1S_SETTINGS_EXT t1s2Ext; } radcomet_settings_t; #pragma pack(pop) @@ -80,7 +83,7 @@ typedef struct { #ifdef __cplusplus -static_assert(sizeof(radcomet_settings_t) == 466, "RADComet settings size mismatch"); +static_assert(sizeof(radcomet_settings_t) == 498, "RADComet settings size mismatch"); #include diff --git a/include/icsneo/device/tree/radcomet3/radcomet3settings.h b/include/icsneo/device/tree/radcomet3/radcomet3settings.h index ddc4ec0..3476aac 100644 --- a/include/icsneo/device/tree/radcomet3/radcomet3settings.h +++ b/include/icsneo/device/tree/radcomet3/radcomet3settings.h @@ -68,11 +68,20 @@ typedef struct { ETHERNET_SETTINGS2 ethT1s6; ETHERNET10T1S_SETTINGS t1s6; LIN_SETTINGS lin1; + // 10T1S Extended Settings + ETHERNET10T1S_SETTINGS_EXT t1s1Ext; + ETHERNET10T1S_SETTINGS_EXT t1s2Ext; + ETHERNET10T1S_SETTINGS_EXT t1s3Ext; + ETHERNET10T1S_SETTINGS_EXT t1s4Ext; + ETHERNET10T1S_SETTINGS_EXT t1s5Ext; + ETHERNET10T1S_SETTINGS_EXT t1s6Ext; } radcomet3_settings_t; #pragma pack(pop) #ifdef __cplusplus +static_assert(sizeof(radcomet3_settings_t) == 674, "RADComet3 settings size mismatch"); + #include class RADComet3Settings : public IDeviceSettings { From e2bd0b5a3e09b30d12d6ae368d66f6119a15227b Mon Sep 17 00:00:00 2001 From: Kyle Schwarz Date: Wed, 2 Oct 2024 22:19:54 +0000 Subject: [PATCH 15/47] Device: Fix getHardwareInfo() timeout --- include/icsneo/device/device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/icsneo/device/device.h b/include/icsneo/device/device.h index 169cbc1..84856ea 100644 --- a/include/icsneo/device/device.h +++ b/include/icsneo/device/device.h @@ -229,7 +229,7 @@ public: virtual size_t getNetworkCountByType(Network::Type) const; virtual Network getNetworkByNumber(Network::Type, size_t) const; - std::shared_ptr getHardwareInfo(std::chrono::milliseconds timeout = std::chrono::milliseconds(2)); + std::shared_ptr getHardwareInfo(std::chrono::milliseconds timeout = std::chrono::milliseconds(100)); /** From 80904dd84cf42041ec6261b00bad1bb14b893455 Mon Sep 17 00:00:00 2001 From: Vedant Naik Date: Thu, 3 Oct 2024 19:14:33 +0000 Subject: [PATCH 16/47] Device: Gigastar: Add TC10 --- include/icsneo/device/tree/radgigastar/radgigastar.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/icsneo/device/tree/radgigastar/radgigastar.h b/include/icsneo/device/tree/radgigastar/radgigastar.h index 04dddbb..debed94 100644 --- a/include/icsneo/device/tree/radgigastar/radgigastar.h +++ b/include/icsneo/device/tree/radgigastar/radgigastar.h @@ -21,7 +21,8 @@ public: size_t getEthernetActivationLineCount() const override { return 1; } bool getEthPhyRegControlSupported() const override { return true; } - + bool supportsTC10() const override { return true; } + protected: RADGigastar(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); From f552df372b92b35d3ef673239acf126bc6488453 Mon Sep 17 00:00:00 2001 From: Yaroslav Stetsyk Date: Fri, 18 Oct 2024 18:23:58 +0000 Subject: [PATCH 17/47] Device: Add RADMoonT1S --- HARDWARE.md | 2 + device/devicefinder.cpp | 8 ++ include/icsneo/device/devicetype.h | 4 + .../device/tree/radmoont1s/radmoont1s.h | 73 +++++++++++++++++++ .../tree/radmoont1s/radmoont1ssettings.h | 51 +++++++++++++ include/icsneo/platform/posix/devices.h | 1 + include/icsneo/platform/windows/devices.h | 1 + 7 files changed, 140 insertions(+) create mode 100644 include/icsneo/device/tree/radmoont1s/radmoont1s.h create mode 100644 include/icsneo/device/tree/radmoont1s/radmoont1ssettings.h diff --git a/HARDWARE.md b/HARDWARE.md index e5a1c33..ee0d5bf 100644 --- a/HARDWARE.md +++ b/HARDWARE.md @@ -58,3 +58,5 @@ - RADComet3 - CAN works - Ethernet works + - RADMoonT1S + - Ethernet works diff --git a/device/devicefinder.cpp b/device/devicefinder.cpp index bb11b46..c02dc85 100644 --- a/device/devicefinder.cpp +++ b/device/devicefinder.cpp @@ -185,6 +185,10 @@ std::vector> DeviceFinder::FindAll() { makeIfSerialMatches(dev, newFoundDevices); #endif + #ifdef __RADMOONT1S_H_ + makeIfSerialMatches(dev, newFoundDevices); + #endif + #ifdef __RADEPSILON_H_ makeIfSerialMatches(dev, newFoundDevices); #endif @@ -332,6 +336,10 @@ const std::vector& DeviceFinder::GetSupportedDevices() { RADComet3::DEVICE_TYPE, #endif + #ifdef __RADMOONT1S_H_ + RADMoonT1S::DEVICE_TYPE, + #endif + #ifdef __RADEPSILON_H_ RADEpsilon::DEVICE_TYPE, #endif diff --git a/include/icsneo/device/devicetype.h b/include/icsneo/device/devicetype.h index a02cdc8..3e68df9 100644 --- a/include/icsneo/device/devicetype.h +++ b/include/icsneo/device/devicetype.h @@ -52,6 +52,7 @@ public: FIRE3_FlexRay = (0x00000025), Connect = (0x00000026), RADComet3 = (0x00000027), + RADMoonT1S = (0x00000028), RED = (0x00000040), ECU = (0x00000080), IEVB = (0x00000100), @@ -190,6 +191,8 @@ public: return "neoVI FIRE3 FlexRay"; case RADComet3: return "RAD-Comet 3"; + case RADMoonT1S: + return "RAD-Moon T1S"; case Connect: return "neoVI Connect"; case DONT_REUSE0: @@ -247,6 +250,7 @@ private: #define ICSNEO_DEVICETYPE_FIRE3FLEXRAY ((devicetype_t)0x00000025) #define ICSNEO_DEVICETYPE_CONNECT ((devicetype_t)0x00000026) #define ICSNEO_DEVICETYPE_RADCOMET3 ((devicetype_t)0x00000027) +#define ICSNEO_DEVICETYPE_RADMOONT1S ((devicetype_t)0x00000028) #define ICSNEO_DEVICETYPE_RED ((devicetype_t)0x00000040) #define ICSNEO_DEVICETYPE_ECU ((devicetype_t)0x00000080) #define ICSNEO_DEVICETYPE_IEVB ((devicetype_t)0x00000100) diff --git a/include/icsneo/device/tree/radmoont1s/radmoont1s.h b/include/icsneo/device/tree/radmoont1s/radmoont1s.h new file mode 100644 index 0000000..cf17294 --- /dev/null +++ b/include/icsneo/device/tree/radmoont1s/radmoont1s.h @@ -0,0 +1,73 @@ +#ifndef __RADMOONT1S_H_ +#define __RADMOONT1S_H_ + +#ifdef __cplusplus + +#include "icsneo/device/device.h" +#include "icsneo/device/tree/radmoont1s/radmoont1ssettings.h" + +namespace icsneo { + +class RADMoonT1S : public Device { +public: + + // Serial numbers start with MS + // USB PID is 0x1209, standard driver is FTDI3 + // Ethernet MAC allocation is 0x21, standard driver is Raw + ICSNEO_FINDABLE_DEVICE(RADMoonT1S, DeviceType::RADMoonT1S, "MS"); + + static const std::vector& GetSupportedNetworks() { + static std::vector supportedNetworks = { + Network::NetID::Ethernet, + + Network::NetID::OP_Ethernet1, + + Network::NetID::MDIO1, + + Network::NetID::SPI1, + }; + return supportedNetworks; + } + + + bool getEthPhyRegControlSupported() const override { return true; } + + bool supportsTC10() const override { return true; } + +protected: + RADMoonT1S(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { + initialize(makeDriver); + } + + void setupPacketizer(Packetizer& packetizer) override { + Device::setupPacketizer(packetizer); + packetizer.disableChecksum = true; + packetizer.align16bit = false; + } + + void setupEncoder(Encoder& encoder) override { + Device::setupEncoder(encoder); + encoder.supportEthPhy = true; + } + + void setupDecoder(Decoder& decoder) override { + Device::setupDecoder(decoder); + decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns + } + + void setupSupportedRXNetworks(std::vector& rxNetworks) override { + for(auto& netid : GetSupportedNetworks()) + rxNetworks.emplace_back(netid); + } + + // The supported TX networks are the same as the supported RX networks for this device + void setupSupportedTXNetworks(std::vector& txNetworks) override { + setupSupportedRXNetworks(txNetworks); + } +}; + +} + +#endif // __cplusplus + +#endif // __RADMOONT1S_H_ diff --git a/include/icsneo/device/tree/radmoont1s/radmoont1ssettings.h b/include/icsneo/device/tree/radmoont1s/radmoont1ssettings.h new file mode 100644 index 0000000..455b2af --- /dev/null +++ b/include/icsneo/device/tree/radmoont1s/radmoont1ssettings.h @@ -0,0 +1,51 @@ +#ifndef __RADMOONT1SSETTINGS_H_ +#define __RADMOONT1SSETTINGS_H_ + +#include +#include "icsneo/device/idevicesettings.h" + +#ifdef __cplusplus + +namespace icsneo { + +#endif + +#pragma pack(push, 2) +typedef struct { + uint16_t perf_en; + struct + { + uint16_t hwComLatencyTestEn : 1; + uint16_t disableUsbCheckOnBoot : 1; + uint16_t reserved : 14; + } flags; + uint16_t network_enabled_on_boot; + uint64_t network_enables; + uint64_t network_enables_2; + RAD_REPORTING_SETTINGS reporting; + uint32_t pwr_man_timeout; + uint16_t pwr_man_enable; + // Ethernet 10/100/1000 + ETHERNET_SETTINGS2 ethernet; + // Ethernet General + OP_ETH_GENERAL_SETTINGS opEthGen; + // 10T1S + ETHERNET_SETTINGS2 ethT1s; + ETHERNET10T1S_SETTINGS t1s; +} radmoont1s_settings_t; +#pragma pack(pop) + +#ifdef __cplusplus + +#include + +class RADMoonT1SSettings : public IDeviceSettings { +public: + RADMoonT1SSettings(std::shared_ptr com) : IDeviceSettings(com, sizeof(radmoont1s_settings_t)) {} +}; + +} + +#endif // __cplusplus + +#endif // __RADMOONT1SSETTINGS_H_ diff --git a/include/icsneo/platform/posix/devices.h b/include/icsneo/platform/posix/devices.h index 54ec9bf..20fae50 100644 --- a/include/icsneo/platform/posix/devices.h +++ b/include/icsneo/platform/posix/devices.h @@ -16,6 +16,7 @@ #include "icsneo/device/tree/radcomet/radcomet.h" #include "icsneo/device/tree/radcomet/radcomet2.h" #include "icsneo/device/tree/radcomet3/radcomet3.h" +#include "icsneo/device/tree/radmoont1s/radmoont1s.h" #include "icsneo/device/tree/radepsilon/radepsilon.h" #include "icsneo/device/tree/radgalaxy/radgalaxy.h" #include "icsneo/device/tree/radgigastar/radgigastar.h" diff --git a/include/icsneo/platform/windows/devices.h b/include/icsneo/platform/windows/devices.h index a00ee3c..2542db2 100644 --- a/include/icsneo/platform/windows/devices.h +++ b/include/icsneo/platform/windows/devices.h @@ -16,6 +16,7 @@ #include "icsneo/device/tree/radcomet/radcomet.h" #include "icsneo/device/tree/radcomet/radcomet2.h" #include "icsneo/device/tree/radcomet3/radcomet3.h" +#include "icsneo/device/tree/radmoont1s/radmoont1s.h" #include "icsneo/device/tree/radepsilon/radepsilon.h" #include "icsneo/device/tree/radgalaxy/radgalaxy.h" #include "icsneo/device/tree/radgigastar/radgigastar.h" From e73f61bfcca8c2ba34eb026016f77676f8403179 Mon Sep 17 00:00:00 2001 From: Bryant Jones Date: Mon, 21 Oct 2024 20:00:29 +0000 Subject: [PATCH 18/47] Device: Add RADGigastar2 --- HARDWARE.md | 2 + device/devicefinder.cpp | 8 + include/icsneo/device/devicetype.h | 6 +- .../device/tree/radgigastar2/radgigastar2.h | 139 ++++++++++ .../tree/radgigastar2/radgigastar2settings.h | 243 ++++++++++++++++++ include/icsneo/platform/posix/devices.h | 1 + include/icsneo/platform/windows/devices.h | 1 + 7 files changed, 399 insertions(+), 1 deletion(-) create mode 100644 include/icsneo/device/tree/radgigastar2/radgigastar2.h create mode 100644 include/icsneo/device/tree/radgigastar2/radgigastar2settings.h diff --git a/HARDWARE.md b/HARDWARE.md index ee0d5bf..6948011 100644 --- a/HARDWARE.md +++ b/HARDWARE.md @@ -28,6 +28,7 @@ - CAN works - CAN FD works - Ethernet works + - RADGigastar2 - Connecting over USB - ValueCAN 4 series @@ -60,3 +61,4 @@ - Ethernet works - RADMoonT1S - Ethernet works + - RADGigastar2 diff --git a/device/devicefinder.cpp b/device/devicefinder.cpp index c02dc85..17770ab 100644 --- a/device/devicefinder.cpp +++ b/device/devicefinder.cpp @@ -204,6 +204,10 @@ std::vector> DeviceFinder::FindAll() { #ifdef __RADGIGASTAR_H_ makeIfSerialMatches(dev, newFoundDevices); #endif + + #ifdef __RADGIGASTAR2_H_ + makeIfSerialMatches(dev, newFoundDevices); + #endif #ifdef __RADJUPITER_H_ makeIfSerialMatches(dev, newFoundDevices); @@ -356,6 +360,10 @@ const std::vector& DeviceFinder::GetSupportedDevices() { RADGigastar::DEVICE_TYPE, #endif + #ifdef __RADGIGASTAR2_H_ + RADGigastar2::DEVICE_TYPE, + #endif + #if defined __RADMOON2_H_ || defined __RADMOON2ZL_H_ RADMoon2::DEVICE_TYPE, #endif diff --git a/include/icsneo/device/devicetype.h b/include/icsneo/device/devicetype.h index 3e68df9..c6d377e 100644 --- a/include/icsneo/device/devicetype.h +++ b/include/icsneo/device/devicetype.h @@ -53,6 +53,7 @@ public: Connect = (0x00000026), RADComet3 = (0x00000027), RADMoonT1S = (0x00000028), + RADGigastar2 = (0x00000029), RED = (0x00000040), ECU = (0x00000080), IEVB = (0x00000100), @@ -195,6 +196,8 @@ public: return "RAD-Moon T1S"; case Connect: return "neoVI Connect"; + case RADGigastar2: + return "RAD-Gigastar 2"; case DONT_REUSE0: case DONT_REUSE1: case DONT_REUSE2: @@ -251,6 +254,7 @@ private: #define ICSNEO_DEVICETYPE_CONNECT ((devicetype_t)0x00000026) #define ICSNEO_DEVICETYPE_RADCOMET3 ((devicetype_t)0x00000027) #define ICSNEO_DEVICETYPE_RADMOONT1S ((devicetype_t)0x00000028) +#define ICSNEO_DEVICETYPE_RADGIGASTAR2 ((devicetype_t)0x00000029) #define ICSNEO_DEVICETYPE_RED ((devicetype_t)0x00000040) #define ICSNEO_DEVICETYPE_ECU ((devicetype_t)0x00000080) #define ICSNEO_DEVICETYPE_IEVB ((devicetype_t)0x00000100) @@ -279,4 +283,4 @@ private: #define ICSNEO_DEVICETYPE_OBD2_SIM ((devicetype_t)0x80000000) #endif -#endif \ No newline at end of file +#endif diff --git a/include/icsneo/device/tree/radgigastar2/radgigastar2.h b/include/icsneo/device/tree/radgigastar2/radgigastar2.h new file mode 100644 index 0000000..700e168 --- /dev/null +++ b/include/icsneo/device/tree/radgigastar2/radgigastar2.h @@ -0,0 +1,139 @@ +#ifndef __RADGIGASTAR2_H_ +#define __RADGIGASTAR2_H_ + +#ifdef __cplusplus + +#include "icsneo/device/device.h" +#include "icsneo/device/devicetype.h" +#include "icsneo/disk/extextractordiskreaddriver.h" +#include "icsneo/disk/neomemorydiskdriver.h" +#include "icsneo/device/tree/radgigastar2/radgigastar2settings.h" + +namespace icsneo +{ + + class RADGigastar2 : public Device + { + public: + // Serial numbers start with GT + // USB PID is 0x1210, standard driver is FTDI3 + // Ethernet MAC allocation is 0x22, standard driver is Raw + ICSNEO_FINDABLE_DEVICE(RADGigastar2, DeviceType::RADGigastar2, "GT"); + + static const std::vector &GetSupportedNetworks() + { + static std::vector supportedNetworks = { + Network::NetID::HSCAN, + Network::NetID::HSCAN2, + Network::NetID::HSCAN3, + Network::NetID::HSCAN4, + + Network::NetID::Ethernet, + Network::NetID::Ethernet2, + + Network::NetID::OP_Ethernet1, + Network::NetID::OP_Ethernet2, + Network::NetID::OP_Ethernet3, + Network::NetID::OP_Ethernet4, + Network::NetID::OP_Ethernet5, + Network::NetID::OP_Ethernet6, + Network::NetID::OP_Ethernet7, + Network::NetID::OP_Ethernet8, + Network::NetID::OP_Ethernet9, + Network::NetID::OP_Ethernet10, + + Network::NetID::LIN, + Network::NetID::LIN2, + Network::NetID::LIN3, + Network::NetID::LIN4, + Network::NetID::LIN5, + Network::NetID::LIN6, + Network::NetID::LIN7, + Network::NetID::LIN8, + Network::NetID::LIN9, + Network::NetID::LIN10, + + Network::NetID::I2C, + Network::NetID::I2C2, + + Network::NetID::MDIO1, + Network::NetID::MDIO2, + + Network::NetID::SPI1, + Network::NetID::SPI2, + Network::NetID::SPI3, + Network::NetID::SPI4, + Network::NetID::SPI5, + Network::NetID::SPI6, + Network::NetID::SPI7, + Network::NetID::SPI8, + }; + return supportedNetworks; + } + + size_t getEthernetActivationLineCount() const override { return 1; } + + bool getEthPhyRegControlSupported() const override { return true; } + + bool supportsTC10() const override { return true; } + + protected: + RADGigastar2(neodevice_t neodevice, const driver_factory_t &makeDriver) : Device(neodevice) + { + initialize(makeDriver); + } + + void setupPacketizer(Packetizer &packetizer) override + { + Device::setupPacketizer(packetizer); + packetizer.disableChecksum = true; + packetizer.align16bit = false; + } + + void setupDecoder(Decoder &decoder) override + { + Device::setupDecoder(decoder); + decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns + } + + void setupEncoder(Encoder &encoder) override + { + Device::setupEncoder(encoder); + encoder.supportCANFD = true; + encoder.supportEthPhy = true; + } + + void setupSupportedRXNetworks(std::vector &rxNetworks) override + { + for (auto &netid : GetSupportedNetworks()) + rxNetworks.emplace_back(netid); + } + + // The supported TX networks are the same as the supported RX networks for this device + void setupSupportedTXNetworks(std::vector &txNetworks) override { setupSupportedRXNetworks(txNetworks); } + + void handleDeviceStatus(const std::shared_ptr &message) override + { + if (message->data.size() < sizeof(radgigastar2_status_t)) + return; + std::lock_guard lk(ioMutex); + const radgigastar2_status_t *status = reinterpret_cast(message->data.data()); + ethActivationStatus = status->ethernetActivationLineEnabled; + } + + std::optional getCoreminiStartAddressFlash() const override + { + return 512 * 4; + } + + std::optional getCoreminiStartAddressSD() const override + { + return 0; + } + }; + +} + +#endif // __cplusplus + +#endif \ No newline at end of file diff --git a/include/icsneo/device/tree/radgigastar2/radgigastar2settings.h b/include/icsneo/device/tree/radgigastar2/radgigastar2settings.h new file mode 100644 index 0000000..db31512 --- /dev/null +++ b/include/icsneo/device/tree/radgigastar2/radgigastar2settings.h @@ -0,0 +1,243 @@ +#ifndef __RADGIGASTAR2SETTINGS_H_ +#define __RADGIGASTAR2SETTINGS_H_ + +#include +#include "icsneo/device/idevicesettings.h" + +#ifdef __cplusplus + +namespace icsneo +{ + +#endif + +#pragma pack(push, 2) + typedef struct + { + uint32_t ecu_id; + uint16_t perf_en; + struct + { + uint16_t hwComLatencyTestEn : 1; + uint16_t disableUsbCheckOnBoot : 1; + uint16_t reserved : 14; + } flags; + uint16_t network_enabled_on_boot; + CAN_SETTINGS can1; + CANFD_SETTINGS canfd1; + CAN_SETTINGS can2; + CANFD_SETTINGS canfd2; + CAN_SETTINGS can3; + CANFD_SETTINGS canfd3; + CAN_SETTINGS can4; + CANFD_SETTINGS canfd4; + + ISO9141_KEYWORD2000_SETTINGS iso9141_kwp_settings_1; + uint16_t iso_parity_1; + uint16_t iso_msg_termination_1; + ISO9141_KEYWORD2000_SETTINGS iso9141_kwp_settings_2; + uint16_t iso_parity_2; + uint16_t iso_msg_termination_2; + ISO9141_KEYWORD2000_SETTINGS iso9141_kwp_settings_3; + uint16_t iso_parity_3; + uint16_t iso_msg_termination_3; + ISO9141_KEYWORD2000_SETTINGS iso9141_kwp_settings_4; + uint16_t iso_parity_4; + uint16_t iso_msg_termination_4; + ISO9141_KEYWORD2000_SETTINGS iso9141_kwp_settings_5; + uint16_t iso_parity_5; + uint16_t iso_msg_termination_5; + ISO9141_KEYWORD2000_SETTINGS iso9141_kwp_settings_6; + uint16_t iso_parity_6; + uint16_t iso_msg_termination_6; + ISO9141_KEYWORD2000_SETTINGS iso9141_kwp_settings_7; + uint16_t iso_parity_7; + uint16_t iso_msg_termination_7; + ISO9141_KEYWORD2000_SETTINGS iso9141_kwp_settings_8; + uint16_t iso_parity_8; + uint16_t iso_msg_termination_8; + ISO9141_KEYWORD2000_SETTINGS iso9141_kwp_settings_9; + uint16_t iso_parity_9; + uint16_t iso_msg_termination_9; + ISO9141_KEYWORD2000_SETTINGS iso9141_kwp_settings_10; + uint16_t iso_parity_10; + uint16_t iso_msg_termination_10; + uint64_t network_enables; + uint64_t network_enables_2; + uint64_t termination_enables; + TIMESYNC_ICSHARDWARE_SETTINGS timeSyncSettings; + RAD_REPORTING_SETTINGS reporting; + int16_t iso15765_separation_time_offset; + uint32_t pwr_man_timeout; + uint16_t pwr_man_enable; + RAD_GPTP_SETTINGS gPTP; + STextAPISettings text_api; + DISK_SETTINGS disk; + LOGGER_SETTINGS logger; + LIN_SETTINGS lin1; + LIN_SETTINGS lin2; + LIN_SETTINGS lin3; + LIN_SETTINGS lin4; + LIN_SETTINGS lin5; + LIN_SETTINGS lin6; + LIN_SETTINGS lin7; + LIN_SETTINGS lin8; + LIN_SETTINGS lin9; + LIN_SETTINGS lin10; + // TODO more LIN + // Ethernet SFP + ETHERNET_SETTINGS2 ethernet1; + ETHERNET_SETTINGS2 ethernet2; + // Ethernet General + OP_ETH_GENERAL_SETTINGS opEthGen; + // 100/1000T1 + ETHERNET_SETTINGS2 ethT1; + OP_ETH_SETTINGS opEth1; + ETHERNET_SETTINGS2 ethT12; + OP_ETH_SETTINGS opEth2; + // 10T1S + ETHERNET_SETTINGS2 ethT1s1; + ETHERNET10T1S_SETTINGS t1s1; + ETHERNET10T1S_SETTINGS_EXT t1s1Ext; + // 10T1S + ETHERNET_SETTINGS2 ethT1s2; + ETHERNET10T1S_SETTINGS t1s2; + ETHERNET10T1S_SETTINGS_EXT t1s2Ext; + // 10T1S + ETHERNET_SETTINGS2 ethT1s3; + ETHERNET10T1S_SETTINGS t1s3; + ETHERNET10T1S_SETTINGS_EXT t1s3Ext; + // 10T1S + ETHERNET_SETTINGS2 ethT1s4; + ETHERNET10T1S_SETTINGS t1s4; + ETHERNET10T1S_SETTINGS_EXT t1s4Ext; + // 10T1S + ETHERNET_SETTINGS2 ethT1s5; + ETHERNET10T1S_SETTINGS t1s5; + ETHERNET10T1S_SETTINGS_EXT t1s5Ext; + // 10T1S + ETHERNET_SETTINGS2 ethT1s6; + ETHERNET10T1S_SETTINGS t1s6; + ETHERNET10T1S_SETTINGS_EXT t1s6Ext; + // 10T1S + ETHERNET_SETTINGS2 ethT1s7; + ETHERNET10T1S_SETTINGS t1s7; + ETHERNET10T1S_SETTINGS_EXT t1s7Ext; + // 10T1S + ETHERNET_SETTINGS2 ethT1s8; + ETHERNET10T1S_SETTINGS t1s8; + ETHERNET10T1S_SETTINGS_EXT t1s8Ext; + } radgigastar2_settings_t; +#pragma pack(pop) + +#ifdef __cplusplus + + static_assert(sizeof(radgigastar2_settings_t) == 2024, "RADGigastar2 settings size mismatch"); + +#include + + class RADGigastar2Settings : public IDeviceSettings + { + public: + RADGigastar2Settings(std::shared_ptr com) : IDeviceSettings(com, sizeof(radgigastar2_settings_t)) {} + const CAN_SETTINGS *getCANSettingsFor(Network net) const override + { + auto cfg = getStructurePointer(); + if (cfg == nullptr) + return nullptr; + switch (net.getNetID()) + { + case Network::NetID::HSCAN: + return &(cfg->can1); + case Network::NetID::HSCAN2: + return &(cfg->can2); + case Network::NetID::HSCAN3: + return &(cfg->can3); + case Network::NetID::HSCAN4: + return &(cfg->can4); + default: + return nullptr; + } + } + const CANFD_SETTINGS *getCANFDSettingsFor(Network net) const override + { + auto cfg = getStructurePointer(); + if (cfg == nullptr) + return nullptr; + switch (net.getNetID()) + { + case Network::NetID::HSCAN: + return &(cfg->canfd1); + case Network::NetID::HSCAN2: + return &(cfg->canfd2); + case Network::NetID::HSCAN3: + return &(cfg->canfd3); + case Network::NetID::HSCAN4: + return &(cfg->canfd4); + default: + return nullptr; + } + } + + virtual std::vector getTerminationGroups() const override + { + return { + {Network(Network::NetID::HSCAN)}, + {Network(Network::NetID::HSCAN2)}, + {Network(Network::NetID::HSCAN3)}, + {Network(Network::NetID::HSCAN4)}}; + } + + const LIN_SETTINGS *getLINSettingsFor(Network net) const override + { + auto cfg = getStructurePointer(); + if (cfg == nullptr) + return nullptr; + switch (net.getNetID()) + { + case Network::NetID::LIN: + return &(cfg->lin1); + case Network::NetID::LIN2: + return &(cfg->lin2); + case Network::NetID::LIN3: + return &(cfg->lin3); + case Network::NetID::LIN4: + return &(cfg->lin4); + case Network::NetID::LIN5: + return &(cfg->lin5); + case Network::NetID::LIN6: + return &(cfg->lin6); + case Network::NetID::LIN7: + return &(cfg->lin7); + case Network::NetID::LIN8: + return &(cfg->lin8); + case Network::NetID::LIN9: + return &(cfg->lin9); + case Network::NetID::LIN10: + return &(cfg->lin10); + default: + return nullptr; + } + } + + protected: + ICSNEO_UNALIGNED(const uint64_t *) + getTerminationEnables() const override + { + auto cfg = getStructurePointer(); + if (cfg == nullptr) + return nullptr; + return &cfg->termination_enables; + } + }; + + typedef struct + { + uint8_t unused[3]; + uint8_t ethernetActivationLineEnabled; + } radgigastar2_status_t; +} + +#endif // __cplusplus + +#endif \ No newline at end of file diff --git a/include/icsneo/platform/posix/devices.h b/include/icsneo/platform/posix/devices.h index 20fae50..a637600 100644 --- a/include/icsneo/platform/posix/devices.h +++ b/include/icsneo/platform/posix/devices.h @@ -20,6 +20,7 @@ #include "icsneo/device/tree/radepsilon/radepsilon.h" #include "icsneo/device/tree/radgalaxy/radgalaxy.h" #include "icsneo/device/tree/radgigastar/radgigastar.h" +#include "icsneo/device/tree/radgigastar2/radgigastar2.h" #include "icsneo/device/tree/radjupiter/radjupiter.h" #include "icsneo/device/tree/radmars/radmars.h" #include "icsneo/device/tree/radmoon2/radmoon2.h" diff --git a/include/icsneo/platform/windows/devices.h b/include/icsneo/platform/windows/devices.h index 2542db2..6c41fb3 100644 --- a/include/icsneo/platform/windows/devices.h +++ b/include/icsneo/platform/windows/devices.h @@ -20,6 +20,7 @@ #include "icsneo/device/tree/radepsilon/radepsilon.h" #include "icsneo/device/tree/radgalaxy/radgalaxy.h" #include "icsneo/device/tree/radgigastar/radgigastar.h" +#include "icsneo/device/tree/radgigastar2/radgigastar2.h" #include "icsneo/device/tree/radjupiter/radjupiter.h" #include "icsneo/device/tree/radmars/radmars.h" #include "icsneo/device/tree/radmoon2/radmoon2.h" From 3787bc27a26c1cc65b9f5cffd179315de95251f1 Mon Sep 17 00:00:00 2001 From: Kyle Schwarz Date: Sat, 2 Nov 2024 01:14:15 +0000 Subject: [PATCH 19/47] Add Python bindings and the icsneopy package --- .gitignore | 2 +- .gitlab-ci.yml | 93 +++++++++- CMakeLists.txt | 4 + bindings/CMakeLists.txt | 3 + bindings/python/CMakeLists.txt | 24 +++ bindings/python/icsneopy/api/event.cpp | 170 +++++++++++++++++ .../python/icsneopy/api/eventcallback.cpp | 16 ++ bindings/python/icsneopy/api/eventmanager.cpp | 18 ++ bindings/python/icsneopy/api/version.cpp | 28 +++ .../message/callback/messagecallback.cpp | 15 ++ .../communication/message/canmessage.cpp | 22 +++ .../communication/message/ethernetmessage.cpp | 27 +++ .../message/filter/messagefilter.cpp | 15 ++ .../communication/message/message.cpp | 51 +++++ .../message/tc10statusmessage.cpp | 25 +++ .../python/icsneopy/communication/network.cpp | 174 ++++++++++++++++++ bindings/python/icsneopy/device/device.cpp | 43 +++++ .../python/icsneopy/device/devicetype.cpp | 75 ++++++++ bindings/python/icsneopy/icsneocpp.cpp | 45 +++++ ci/bootstrap-libpcap.sh | 18 ++ ci/bootstrap-libusb.sh | 21 +++ ci/build-wheel-posix.sh | 7 + ci/build-wheel-windows.bat | 9 + pyproject.toml | 49 +++++ 24 files changed, 952 insertions(+), 2 deletions(-) create mode 100644 bindings/CMakeLists.txt create mode 100644 bindings/python/CMakeLists.txt create mode 100644 bindings/python/icsneopy/api/event.cpp create mode 100644 bindings/python/icsneopy/api/eventcallback.cpp create mode 100644 bindings/python/icsneopy/api/eventmanager.cpp create mode 100644 bindings/python/icsneopy/api/version.cpp create mode 100644 bindings/python/icsneopy/communication/message/callback/messagecallback.cpp create mode 100644 bindings/python/icsneopy/communication/message/canmessage.cpp create mode 100644 bindings/python/icsneopy/communication/message/ethernetmessage.cpp create mode 100644 bindings/python/icsneopy/communication/message/filter/messagefilter.cpp create mode 100644 bindings/python/icsneopy/communication/message/message.cpp create mode 100644 bindings/python/icsneopy/communication/message/tc10statusmessage.cpp create mode 100644 bindings/python/icsneopy/communication/network.cpp create mode 100644 bindings/python/icsneopy/device/device.cpp create mode 100644 bindings/python/icsneopy/device/devicetype.cpp create mode 100644 bindings/python/icsneopy/icsneocpp.cpp create mode 100644 ci/bootstrap-libpcap.sh create mode 100644 ci/bootstrap-libusb.sh create mode 100644 ci/build-wheel-posix.sh create mode 100644 ci/build-wheel-windows.bat create mode 100644 pyproject.toml diff --git a/.gitignore b/.gitignore index ff4efa3..0c58819 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,4 @@ third-party/concurrentqueue/tests *.orig examples/csharp/bin examples/csharp/obj -test/system \ No newline at end of file +test/system diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 154fefd..5d9839d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,6 +5,7 @@ stages: - build - unit_test - hardware_test + - deploy #------------------------------------------------------------------------------- # Windows @@ -416,4 +417,94 @@ hardware_test win10-vcan42-EL: <<: *win10_needs variables: GUEST_OS_TAG: win10 - DEVICE_PORT: USB_C \ No newline at end of file + DEVICE_PORT: USB_C + +#------------------------------------------------------------------------------- +# Python Module +#------------------------------------------------------------------------------- + +build python/linux/amd64: + stage: build + tags: + - linux-build + image: python:3.12 + services: + - name: docker:dind + entrypoint: ["env", "-u", "DOCKER_HOST"] + command: ["dockerd-entrypoint.sh"] + variables: + CIBW_BEFORE_ALL: yum install -y flex && sh ci/bootstrap-libpcap.sh && sh ci/bootstrap-libusb.sh + CIBW_BUILD: "*manylinux*" # no musl + CIBW_ARCHS: x86_64 + DOCKER_HOST: tcp://docker:2375/ + DOCKER_DRIVER: overlay2 + DOCKER_TLS_CERTDIR: "" + CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=/project/libpcap/install:/project/libusb/install + script: + - curl -sSL https://get.docker.com/ | sh + - sh ci/build-wheel-posix.sh + artifacts: + paths: + - wheelhouse + +build python/linux/arm64: + stage: build + tags: + - arm64-linux-build + variables: + CIBW_BEFORE_ALL: yum install -y flex && sh ci/bootstrap-libpcap.sh && sh ci/bootstrap-libusb.sh + CIBW_BUILD: "*manylinux*" # no musl + CIBW_ARCHS: aarch64 + CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=/project/libpcap/install:/project/libusb/install + script: + - sh ci/build-wheel-posix.sh + artifacts: + paths: + - wheelhouse + +build python/macos: + stage: build + tags: + - macos-arm64 + variables: + CIBW_BEFORE_ALL: sh ci/bootstrap-libpcap.sh && sh ci/bootstrap-libusb.sh + CIBW_ARCHS: arm64 + CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=$CI_PROJECT_DIR/libpcap/install:$CI_PROJECT_DIR/libusb/install + MACOSX_DEPLOYMENT_TARGET: 10.14 + script: + - sh ci/build-wheel-posix.sh + artifacts: + paths: + - wheelhouse + +build python/windows: + stage: build + tags: + - libicsneo-win-x64 + variables: + CIBW_ARCHS: AMD64 + CIBW_ENVIRONMENT: CMAKE_GENERATOR=Ninja + script: + - cmd /c ci\build-wheel-windows.bat + artifacts: + paths: + - wheelhouse + +deploy python/pypi: + stage: deploy + variables: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: $PYPI_TOKEN + tags: + - linux-build + image: python:3.12 + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + script: + - python3 -m pip install -U twine + - twine upload wheelhouse/* + dependencies: + - build python/linux/amd64 + - build python/linux/arm64 + - build python/macos + - build python/windows diff --git a/CMakeLists.txt b/CMakeLists.txt index a65ae4a..4f4351c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,8 @@ option(LIBICSNEO_ENABLE_FTDI "Enable devices which communicate over USB FTDI2XX" option(LIBICSNEO_ENABLE_TCP "Enable devices which communicate over TCP" OFF) option(LIBICSNEO_ENABLE_FTD3XX "Enable devices which communicate over USB FTD3XX" ON) +option(LIBICSNEO_ENABLE_BINDINGS_PYTHON "Enable Python library" OFF) + if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 17) endif() @@ -494,6 +496,8 @@ if(LIBICSNEO_BUILD_ICSNEOLEGACY_STATIC) target_compile_definitions(icsneolegacy-static PUBLIC ICSNEOC_BUILD_STATIC) endif() +add_subdirectory(bindings) + # googletest if(LIBICSNEO_BUILD_UNIT_TESTS) if(WIN32) diff --git a/bindings/CMakeLists.txt b/bindings/CMakeLists.txt new file mode 100644 index 0000000..d243d3b --- /dev/null +++ b/bindings/CMakeLists.txt @@ -0,0 +1,3 @@ +if(LIBICSNEO_ENABLE_BINDINGS_PYTHON) + add_subdirectory(python) +endif() \ No newline at end of file diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt new file mode 100644 index 0000000..58b90d5 --- /dev/null +++ b/bindings/python/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.20) + +set(PYBIND11_FINDPYTHON ON) +find_package(pybind11 CONFIG REQUIRED) + +pybind11_add_module(icsneopy + icsneopy/api/event.cpp + icsneopy/api/eventcallback.cpp + icsneopy/api/eventmanager.cpp + icsneopy/api/version.cpp + icsneopy/device/devicetype.cpp + icsneopy/communication/network.cpp + icsneopy/communication/message/message.cpp + icsneopy/communication/message/canmessage.cpp + icsneopy/communication/message/ethernetmessage.cpp + icsneopy/communication/message/tc10statusmessage.cpp + icsneopy/communication/message/callback/messagecallback.cpp + icsneopy/communication/message/filter/messagefilter.cpp + icsneopy/device/device.cpp + icsneopy/icsneocpp.cpp +) +target_link_libraries(icsneopy PRIVATE icsneocpp) + +install(TARGETS icsneopy LIBRARY DESTINATION .) diff --git a/bindings/python/icsneopy/api/event.cpp b/bindings/python/icsneopy/api/event.cpp new file mode 100644 index 0000000..2789651 --- /dev/null +++ b/bindings/python/icsneopy/api/event.cpp @@ -0,0 +1,170 @@ +#include +#include +#include + +#include "icsneo/api/event.h" + +namespace icsneo { + +void init_event(pybind11::module_& m) { + pybind11::class_> apiEvent(m, "APIEvent"); + pybind11::enum_(apiEvent, "Type") + .value("Any", APIEvent::Type::Any) + .value("InvalidNeoDevice", APIEvent::Type::InvalidNeoDevice) + .value("RequiredParameterNull", APIEvent::Type::RequiredParameterNull) + .value("BufferInsufficient", APIEvent::Type::BufferInsufficient) + .value("OutputTruncated", APIEvent::Type::OutputTruncated) + .value("ParameterOutOfRange", APIEvent::Type::ParameterOutOfRange) + .value("DeviceCurrentlyOpen", APIEvent::Type::DeviceCurrentlyOpen) + .value("DeviceCurrentlyClosed", APIEvent::Type::DeviceCurrentlyClosed) + .value("DeviceCurrentlyOnline", APIEvent::Type::DeviceCurrentlyOnline) + .value("DeviceCurrentlyOffline", APIEvent::Type::DeviceCurrentlyOffline) + .value("DeviceCurrentlyPolling", APIEvent::Type::DeviceCurrentlyPolling) + .value("DeviceNotCurrentlyPolling", APIEvent::Type::DeviceNotCurrentlyPolling) + .value("UnsupportedTXNetwork", APIEvent::Type::UnsupportedTXNetwork) + .value("MessageMaxLengthExceeded", APIEvent::Type::MessageMaxLengthExceeded) + .value("ValueNotYetPresent", APIEvent::Type::ValueNotYetPresent) + .value("Timeout", APIEvent::Type::Timeout) + .value("WiVINotSupported", APIEvent::Type::WiVINotSupported) + .value("RestrictedEntryFlag", APIEvent::Type::RestrictedEntryFlag) + .value("NotSupported", APIEvent::Type::NotSupported) + .value("PollingMessageOverflow", APIEvent::Type::PollingMessageOverflow) + .value("NoSerialNumber", APIEvent::Type::NoSerialNumber) + .value("IncorrectSerialNumber", APIEvent::Type::IncorrectSerialNumber) + .value("SettingsReadError", APIEvent::Type::SettingsReadError) + .value("SettingsVersionError", APIEvent::Type::SettingsVersionError) + .value("SettingsLengthError", APIEvent::Type::SettingsLengthError) + .value("SettingsChecksumError", APIEvent::Type::SettingsChecksumError) + .value("SettingsNotAvailable", APIEvent::Type::SettingsNotAvailable) + .value("SettingsReadOnly", APIEvent::Type::SettingsReadOnly) + .value("CANSettingsNotAvailable", APIEvent::Type::CANSettingsNotAvailable) + .value("CANFDSettingsNotAvailable", APIEvent::Type::CANFDSettingsNotAvailable) + .value("LSFTCANSettingsNotAvailable", APIEvent::Type::LSFTCANSettingsNotAvailable) + .value("SWCANSettingsNotAvailable", APIEvent::Type::SWCANSettingsNotAvailable) + .value("BaudrateNotFound", APIEvent::Type::BaudrateNotFound) + .value("UnexpectedNetworkType", APIEvent::Type::UnexpectedNetworkType) + .value("DeviceFirmwareOutOfDate", APIEvent::Type::DeviceFirmwareOutOfDate) + .value("SettingsStructureMismatch", APIEvent::Type::SettingsStructureMismatch) + .value("SettingsStructureTruncated", APIEvent::Type::SettingsStructureTruncated) + .value("NoDeviceResponse", APIEvent::Type::NoDeviceResponse) + .value("MessageFormattingError", APIEvent::Type::MessageFormattingError) + .value("CANFDNotSupported", APIEvent::Type::CANFDNotSupported) + .value("RTRNotSupported", APIEvent::Type::RTRNotSupported) + .value("DeviceDisconnected", APIEvent::Type::DeviceDisconnected) + .value("OnlineNotSupported", APIEvent::Type::OnlineNotSupported) + .value("TerminationNotSupportedDevice", APIEvent::Type::TerminationNotSupportedDevice) + .value("TerminationNotSupportedNetwork", APIEvent::Type::TerminationNotSupportedNetwork) + .value("AnotherInTerminationGroupEnabled", APIEvent::Type::AnotherInTerminationGroupEnabled) + .value("NoSerialNumberFW", APIEvent::Type::NoSerialNumberFW) + .value("NoSerialNumber12V", APIEvent::Type::NoSerialNumber12V) + .value("NoSerialNumberFW12V", APIEvent::Type::NoSerialNumberFW12V) + .value("EthPhyRegisterControlNotAvailable", APIEvent::Type::EthPhyRegisterControlNotAvailable) + .value("DiskNotSupported", APIEvent::Type::DiskNotSupported) + .value("EOFReached", APIEvent::Type::EOFReached) + .value("SettingsDefaultsUsed", APIEvent::Type::SettingsDefaultsUsed) + .value("AtomicOperationRetried", APIEvent::Type::AtomicOperationRetried) + .value("AtomicOperationCompletedNonatomically", APIEvent::Type::AtomicOperationCompletedNonatomically) + .value("WiVIStackRefreshFailed", APIEvent::Type::WiVIStackRefreshFailed) + .value("WiVIUploadStackOverflow", APIEvent::Type::WiVIUploadStackOverflow) + .value("I2CMessageExceedsMaxLength", APIEvent::Type::I2CMessageExceedsMaxLength) + .value("A2BMessageIncompleteFrame", APIEvent::Type::A2BMessageIncompleteFrame) + .value("CoreminiUploadVersionMismatch", APIEvent::Type::CoreminiUploadVersionMismatch) + .value("DiskNotConnected", APIEvent::Type::DiskNotConnected) + .value("UnexpectedResponse", APIEvent::Type::UnexpectedResponse) + .value("LiveDataInvalidHandle", APIEvent::Type::LiveDataInvalidHandle) + .value("LiveDataInvalidCommand", APIEvent::Type::LiveDataInvalidCommand) + .value("LiveDataInvalidArgument", APIEvent::Type::LiveDataInvalidArgument) + .value("LiveDataVersionMismatch", APIEvent::Type::LiveDataVersionMismatch) + .value("LiveDataNoDeviceResponse", APIEvent::Type::LiveDataNoDeviceResponse) + .value("LiveDataMaxSignalsReached", APIEvent::Type::LiveDataMaxSignalsReached) + .value("LiveDataCommandFailed", APIEvent::Type::LiveDataCommandFailed) + .value("LiveDataEncoderError", APIEvent::Type::LiveDataEncoderError) + .value("LiveDataDecoderError", APIEvent::Type::LiveDataDecoderError) + .value("LiveDataNotSupported", APIEvent::Type::LiveDataNotSupported) + .value("LINSettingsNotAvailable", APIEvent::Type::LINSettingsNotAvailable) + .value("ModeNotFound", APIEvent::Type::ModeNotFound) + .value("AppErrorParsingFailed", APIEvent::Type::AppErrorParsingFailed) + .value("FailedToRead", APIEvent::Type::FailedToRead) + .value("FailedToWrite", APIEvent::Type::FailedToWrite) + .value("DriverFailedToOpen", APIEvent::Type::DriverFailedToOpen) + .value("DriverFailedToClose", APIEvent::Type::DriverFailedToClose) + .value("PacketChecksumError", APIEvent::Type::PacketChecksumError) + .value("TransmitBufferFull", APIEvent::Type::TransmitBufferFull) + .value("DeviceInUse", APIEvent::Type::DeviceInUse) + .value("PCAPCouldNotStart", APIEvent::Type::PCAPCouldNotStart) + .value("PCAPCouldNotFindDevices", APIEvent::Type::PCAPCouldNotFindDevices) + .value("PacketDecodingError", APIEvent::Type::PacketDecodingError) + .value("SocketFailedToOpen", APIEvent::Type::SocketFailedToOpen) + .value("FailedToBind", APIEvent::Type::FailedToBind) + .value("ErrorSettingSocketOption", APIEvent::Type::ErrorSettingSocketOption) + .value("GetIfAddrsError", APIEvent::Type::GetIfAddrsError) + .value("SendToError", APIEvent::Type::SendToError) + .value("MDIOMessageExceedsMaxLength", APIEvent::Type::MDIOMessageExceedsMaxLength) + .value("FTOK", APIEvent::Type::FTOK) + .value("FTInvalidHandle", APIEvent::Type::FTInvalidHandle) + .value("FTDeviceNotFound", APIEvent::Type::FTDeviceNotFound) + .value("FTDeviceNotOpened", APIEvent::Type::FTDeviceNotOpened) + .value("FTIOError", APIEvent::Type::FTIOError) + .value("FTInsufficientResources", APIEvent::Type::FTInsufficientResources) + .value("FTInvalidParameter", APIEvent::Type::FTInvalidParameter) + .value("FTInvalidBaudRate", APIEvent::Type::FTInvalidBaudRate) + .value("FTDeviceNotOpenedForErase", APIEvent::Type::FTDeviceNotOpenedForErase) + .value("FTDeviceNotOpenedForWrite", APIEvent::Type::FTDeviceNotOpenedForWrite) + .value("FTFailedToWriteDevice", APIEvent::Type::FTFailedToWriteDevice) + .value("FTEEPROMReadFailed", APIEvent::Type::FTEEPROMReadFailed) + .value("FTEEPROMWriteFailed", APIEvent::Type::FTEEPROMWriteFailed) + .value("FTEEPROMEraseFailed", APIEvent::Type::FTEEPROMEraseFailed) + .value("FTEEPROMNotPresent", APIEvent::Type::FTEEPROMNotPresent) + .value("FTEEPROMNotProgrammed", APIEvent::Type::FTEEPROMNotProgrammed) + .value("FTInvalidArgs", APIEvent::Type::FTInvalidArgs) + .value("FTNotSupported", APIEvent::Type::FTNotSupported) + .value("FTNoMoreItems", APIEvent::Type::FTNoMoreItems) + .value("FTTimeout", APIEvent::Type::FTTimeout) + .value("FTOperationAborted", APIEvent::Type::FTOperationAborted) + .value("FTReservedPipe", APIEvent::Type::FTReservedPipe) + .value("FTInvalidControlRequestDirection", APIEvent::Type::FTInvalidControlRequestDirection) + .value("FTInvalidControlRequestType", APIEvent::Type::FTInvalidControlRequestType) + .value("FTIOPending", APIEvent::Type::FTIOPending) + .value("FTIOIncomplete", APIEvent::Type::FTIOIncomplete) + .value("FTHandleEOF", APIEvent::Type::FTHandleEOF) + .value("FTBusy", APIEvent::Type::FTBusy) + .value("FTNoSystemResources", APIEvent::Type::FTNoSystemResources) + .value("FTDeviceListNotReady", APIEvent::Type::FTDeviceListNotReady) + .value("FTDeviceNotConnected", APIEvent::Type::FTDeviceNotConnected) + .value("FTIncorrectDevicePath", APIEvent::Type::FTIncorrectDevicePath) + .value("FTOtherError", APIEvent::Type::FTOtherError) + .value("VSABufferCorrupted", APIEvent::Type::VSABufferCorrupted) + .value("VSATimestampNotFound", APIEvent::Type::VSATimestampNotFound) + .value("VSABufferFormatError", APIEvent::Type::VSABufferFormatError) + .value("VSAMaxReadAttemptsReached", APIEvent::Type::VSAMaxReadAttemptsReached) + .value("VSAByteParseFailure", APIEvent::Type::VSAByteParseFailure) + .value("VSAExtendedMessageError", APIEvent::Type::VSAExtendedMessageError) + .value("VSAOtherError", APIEvent::Type::VSAOtherError) + .value("NoErrorFound", APIEvent::Type::NoErrorFound) + .value("TooManyEvents", APIEvent::Type::TooManyEvents) + .value("Unknown", APIEvent::Type::Unknown); + + pybind11::enum_(apiEvent, "Severity") + .value("Any", APIEvent::Severity::Any) + .value("EventInfo", APIEvent::Severity::EventInfo) + .value("EventWarning", APIEvent::Severity::EventWarning) + .value("Error", APIEvent::Severity::Error); + + apiEvent + .def("get_type", &APIEvent::getType) + .def("get_severity", &APIEvent::getSeverity) + .def("get_description", &APIEvent::getDescription) + .def("describe", &APIEvent::describe) + .def("__repr__", &APIEvent::describe); + + pybind11::class_>(m, "EventFilter") + .def(pybind11::init()) + .def(pybind11::init()) + .def(pybind11::init()) + .def_readwrite("type", &EventFilter::type) + .def_readwrite("severity", &EventFilter::severity) + .def_readwrite("serial", &EventFilter::serial); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/api/eventcallback.cpp b/bindings/python/icsneopy/api/eventcallback.cpp new file mode 100644 index 0000000..855c43b --- /dev/null +++ b/bindings/python/icsneopy/api/eventcallback.cpp @@ -0,0 +1,16 @@ +#include +#include +#include + +#include "icsneo/api/eventcallback.h" + +namespace icsneo { + +void init_eventcallback(pybind11::module_& m) { + pybind11::class_(m, "EventCallback") + .def(pybind11::init()) + .def(pybind11::init()); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/api/eventmanager.cpp b/bindings/python/icsneopy/api/eventmanager.cpp new file mode 100644 index 0000000..4be9237 --- /dev/null +++ b/bindings/python/icsneopy/api/eventmanager.cpp @@ -0,0 +1,18 @@ +#include +#include +#include + +#include "icsneo/api/eventmanager.h" + +namespace icsneo { + +void init_eventmanager(pybind11::module_& m) { + pybind11::class_(m, "EventManager") + .def_static("get_instance", &EventManager::GetInstance, pybind11::return_value_policy::reference) + .def("add_event_callback", &EventManager::addEventCallback) + .def("remove_event_callback", &EventManager::removeEventCallback) + .def("get_last_error", &EventManager::getLastError); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/api/version.cpp b/bindings/python/icsneopy/api/version.cpp new file mode 100644 index 0000000..f580fd3 --- /dev/null +++ b/bindings/python/icsneopy/api/version.cpp @@ -0,0 +1,28 @@ +#include +#include +#include + +#include "icsneo/api/version.h" + +#include + +namespace icsneo { + +void init_version(pybind11::module_& m) { + pybind11::class_(m, "NeoVersion") + .def_readonly("major", &neoversion_t::major) + .def_readonly("minor", &neoversion_t::minor) + .def_readonly("patch", &neoversion_t::patch) + .def_readonly("metadata", &neoversion_t::metadata) + .def_readonly("buildBranch", &neoversion_t::buildBranch) + .def_readonly("buildTag", &neoversion_t::buildTag) + .def("__repr__", [](const neoversion_t& self) -> std::string { + std::stringstream ss; + ss << self; + return ss.str(); + }); + m.def("get_version", &GetVersion); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/communication/message/callback/messagecallback.cpp b/bindings/python/icsneopy/communication/message/callback/messagecallback.cpp new file mode 100644 index 0000000..656dc39 --- /dev/null +++ b/bindings/python/icsneopy/communication/message/callback/messagecallback.cpp @@ -0,0 +1,15 @@ +#include +#include +#include + +#include "icsneo/communication/message/callback/messagecallback.h" + +namespace icsneo { + +void init_messagecallback(pybind11::module_& m) { + pybind11::class_>(m, "MessageCallback") + .def(pybind11::init>()); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/communication/message/canmessage.cpp b/bindings/python/icsneopy/communication/message/canmessage.cpp new file mode 100644 index 0000000..68d36ed --- /dev/null +++ b/bindings/python/icsneopy/communication/message/canmessage.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +#include "icsneo/communication/message/canmessage.h" + +namespace icsneo { + +void init_canmessage(pybind11::module_& m) { + pybind11::class_, Frame>(m, "CANMessage") + .def(pybind11::init()) + .def_readwrite("arbid", &CANMessage::arbid) + .def_readwrite("dlcOnWire", &CANMessage::dlcOnWire) + .def_readwrite("isRemote", &CANMessage::isRemote) + .def_readwrite("isExtended", &CANMessage::isExtended) + .def_readwrite("isCANFD", &CANMessage::isCANFD) + .def_readwrite("baudrateSwitch", &CANMessage::baudrateSwitch) + .def_readwrite("errorStateIndicator", &CANMessage::errorStateIndicator); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/communication/message/ethernetmessage.cpp b/bindings/python/icsneopy/communication/message/ethernetmessage.cpp new file mode 100644 index 0000000..87a9cc6 --- /dev/null +++ b/bindings/python/icsneopy/communication/message/ethernetmessage.cpp @@ -0,0 +1,27 @@ +#include +#include +#include + +#include "icsneo/communication/message/ethernetmessage.h" + +namespace icsneo { + +void init_ethernetmessage(pybind11::module_& m) { + pybind11::class_(m, "MACAddress") + .def("to_string", &MACAddress::toString) + .def("__repr__", &MACAddress::toString); + + pybind11::class_, Frame>(m, "EthernetMessage") + .def(pybind11::init()) + .def_readwrite("preemptionEnabled", &EthernetMessage::preemptionEnabled) + .def_readwrite("preemptionFlags", &EthernetMessage::preemptionFlags) + .def_readwrite("fcsAvailable", &EthernetMessage::fcsAvailable) + .def_readwrite("frameTooShort", &EthernetMessage::frameTooShort) + .def_readwrite("noPadding", &EthernetMessage::noPadding) + .def("get_destination_mac", &EthernetMessage::getDestinationMAC, pybind11::return_value_policy::reference) + .def("get_source_mac", &EthernetMessage::getSourceMAC, pybind11::return_value_policy::reference) + .def("get_ether_type", &EthernetMessage::getEtherType); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/communication/message/filter/messagefilter.cpp b/bindings/python/icsneopy/communication/message/filter/messagefilter.cpp new file mode 100644 index 0000000..33c49c3 --- /dev/null +++ b/bindings/python/icsneopy/communication/message/filter/messagefilter.cpp @@ -0,0 +1,15 @@ +#include +#include +#include + +#include "icsneo/communication/message/filter/messagefilter.h" + +namespace icsneo { + +void init_messagefilter(pybind11::module_& m) { + pybind11::class_>(m, "MessageFilter") + .def(pybind11::init()); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/communication/message/message.cpp b/bindings/python/icsneopy/communication/message/message.cpp new file mode 100644 index 0000000..627a7e6 --- /dev/null +++ b/bindings/python/icsneopy/communication/message/message.cpp @@ -0,0 +1,51 @@ +#include +#include +#include + +#include "icsneo/communication/message/message.h" + +namespace icsneo { + +void init_message(pybind11::module_& m) { + pybind11::class_> message(m, "Message"); + pybind11::enum_(message, "Type") + .value("Frame", Message::Type::Frame) + .value("CANErrorCount", Message::Type::CANErrorCount) + .value("LINHeaderOnly", Message::Type::LINHeaderOnly) + .value("LINBreak", Message::Type::LINBreak) + .value("Invalid", Message::Type::Invalid) + .value("RawMessage", Message::Type::RawMessage) + .value("ReadSettings", Message::Type::ReadSettings) + .value("ResetStatus", Message::Type::ResetStatus) + .value("DeviceVersion", Message::Type::DeviceVersion) + .value("Main51", Message::Type::Main51) + .value("FlexRayControl", Message::Type::FlexRayControl) + .value("EthernetPhyRegister", Message::Type::EthernetPhyRegister) + .value("LogicalDiskInfo", Message::Type::LogicalDiskInfo) + .value("ExtendedResponse", Message::Type::ExtendedResponse) + .value("WiVICommandResponse", Message::Type::WiVICommandResponse) + .value("ScriptStatus", Message::Type::ScriptStatus) + .value("ComponentVersions", Message::Type::ComponentVersions) + .value("SupportedFeatures", Message::Type::SupportedFeatures) + .value("GenericBinaryStatus", Message::Type::GenericBinaryStatus) + .value("LiveData", Message::Type::LiveData) + .value("HardwareInfo", Message::Type::HardwareInfo) + .value("TC10Status", Message::Type::TC10Status) + .value("AppError", Message::Type::AppError); + + message.def(pybind11::init()); + message.def_readonly("type", &Message::type); + message.def_readwrite("timestamp", &Message::timestamp); + + pybind11::class_, Message>(m, "RawMessage") + .def_readwrite("network", &RawMessage::network) + .def_readwrite("data", &RawMessage::data); + + pybind11::class_, RawMessage>(m, "Frame") + .def_readwrite("description", &Frame::description) + .def_readwrite("transmitted", &Frame::transmitted) + .def_readwrite("error", &Frame::error); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/communication/message/tc10statusmessage.cpp b/bindings/python/icsneopy/communication/message/tc10statusmessage.cpp new file mode 100644 index 0000000..a3920b3 --- /dev/null +++ b/bindings/python/icsneopy/communication/message/tc10statusmessage.cpp @@ -0,0 +1,25 @@ +#include +#include +#include + +#include "icsneo/communication/message/tc10statusmessage.h" + +namespace icsneo { + +void init_tc10statusmessage(pybind11::module_& m) { + pybind11::enum_(m, "TC10WakeStatus") + .value("NoWakeReceived", TC10WakeStatus::NoWakeReceived) + .value("WakeReceived", TC10WakeStatus::WakeReceived); + + pybind11::enum_(m, "TC10SleepStatus") + .value("NoSleepReceived", TC10SleepStatus::NoSleepReceived) + .value("SleepReceived", TC10SleepStatus::SleepReceived) + .value("SleepFailed", TC10SleepStatus::SleepFailed) + .value("SleepAborted", TC10SleepStatus::SleepAborted); + + pybind11::class_, Message>(m, "TC10StatusMessage") + .def_readonly("wakeStatus", &TC10StatusMessage::wakeStatus) + .def_readonly("sleepStatus", &TC10StatusMessage::sleepStatus); +} + +} // namespace icsneo diff --git a/bindings/python/icsneopy/communication/network.cpp b/bindings/python/icsneopy/communication/network.cpp new file mode 100644 index 0000000..2decc05 --- /dev/null +++ b/bindings/python/icsneopy/communication/network.cpp @@ -0,0 +1,174 @@ +#include +#include +#include + +#include "icsneo/communication/network.h" + +namespace icsneo { + +void init_network(pybind11::module_& m) { + pybind11::class_ network(m, "Network"); + + pybind11::enum_(network, "NetID") + .value("Device", Network::NetID::Device) + .value("HSCAN", Network::NetID::HSCAN) + .value("MSCAN", Network::NetID::MSCAN) + .value("SWCAN", Network::NetID::SWCAN) + .value("LSFTCAN", Network::NetID::LSFTCAN) + .value("FordSCP", Network::NetID::FordSCP) + .value("J1708", Network::NetID::J1708) + .value("Aux", Network::NetID::Aux) + .value("J1850VPW", Network::NetID::J1850VPW) + .value("ISO9141", Network::NetID::ISO9141) + .value("DiskData", Network::NetID::DiskData) + .value("Main51", Network::NetID::Main51) + .value("RED", Network::NetID::RED) + .value("SCI", Network::NetID::SCI) + .value("ISO9141_2", Network::NetID::ISO9141_2) + .value("ISO14230", Network::NetID::ISO14230) + .value("LIN", Network::NetID::LIN) + .value("OP_Ethernet1", Network::NetID::OP_Ethernet1) + .value("OP_Ethernet2", Network::NetID::OP_Ethernet2) + .value("OP_Ethernet3", Network::NetID::OP_Ethernet3) + .value("RED_EXT_MEMORYREAD", Network::NetID::RED_EXT_MEMORYREAD) + .value("RED_INT_MEMORYREAD", Network::NetID::RED_INT_MEMORYREAD) + .value("RED_DFLASH_READ", Network::NetID::RED_DFLASH_READ) + .value("NeoMemorySDRead", Network::NetID::NeoMemorySDRead) + .value("CAN_ERRBITS", Network::NetID::CAN_ERRBITS) + .value("NeoMemoryWriteDone", Network::NetID::NeoMemoryWriteDone) + .value("RED_WAVE_CAN1_LOGICAL", Network::NetID::RED_WAVE_CAN1_LOGICAL) + .value("RED_WAVE_CAN2_LOGICAL", Network::NetID::RED_WAVE_CAN2_LOGICAL) + .value("RED_WAVE_LIN1_LOGICAL", Network::NetID::RED_WAVE_LIN1_LOGICAL) + .value("RED_WAVE_LIN2_LOGICAL", Network::NetID::RED_WAVE_LIN2_LOGICAL) + .value("RED_WAVE_LIN1_ANALOG", Network::NetID::RED_WAVE_LIN1_ANALOG) + .value("RED_WAVE_LIN2_ANALOG", Network::NetID::RED_WAVE_LIN2_ANALOG) + .value("RED_WAVE_MISC_ANALOG", Network::NetID::RED_WAVE_MISC_ANALOG) + .value("RED_WAVE_MISCDIO2_LOGICAL", Network::NetID::RED_WAVE_MISCDIO2_LOGICAL) + .value("RED_NETWORK_COM_ENABLE_EX", Network::NetID::RED_NETWORK_COM_ENABLE_EX) + .value("RED_NEOVI_NETWORK", Network::NetID::RED_NEOVI_NETWORK) + .value("RED_READ_BAUD_SETTINGS", Network::NetID::RED_READ_BAUD_SETTINGS) + .value("RED_OLDFORMAT", Network::NetID::RED_OLDFORMAT) + .value("RED_SCOPE_CAPTURE", Network::NetID::RED_SCOPE_CAPTURE) + .value("RED_HARDWARE_EXCEP", Network::NetID::RED_HARDWARE_EXCEP) + .value("RED_GET_RTC", Network::NetID::RED_GET_RTC) + .value("ISO9141_3", Network::NetID::ISO9141_3) + .value("HSCAN2", Network::NetID::HSCAN2) + .value("HSCAN3", Network::NetID::HSCAN3) + .value("OP_Ethernet4", Network::NetID::OP_Ethernet4) + .value("OP_Ethernet5", Network::NetID::OP_Ethernet5) + .value("ISO9141_4", Network::NetID::ISO9141_4) + .value("LIN2", Network::NetID::LIN2) + .value("LIN3", Network::NetID::LIN3) + .value("LIN4", Network::NetID::LIN4) + .value("RED_App_Error", Network::NetID::RED_App_Error) + .value("CGI", Network::NetID::CGI) + .value("Reset_Status", Network::NetID::Reset_Status) + .value("FB_Status", Network::NetID::FB_Status) + .value("App_Signal_Status", Network::NetID::App_Signal_Status) + .value("Read_Datalink_Cm_Tx_Msg", Network::NetID::Read_Datalink_Cm_Tx_Msg) + .value("Read_Datalink_Cm_Rx_Msg", Network::NetID::Read_Datalink_Cm_Rx_Msg) + .value("Logging_Overflow", Network::NetID::Logging_Overflow) + .value("ReadSettings", Network::NetID::ReadSettings) + .value("HSCAN4", Network::NetID::HSCAN4) + .value("HSCAN5", Network::NetID::HSCAN5) + .value("RS232", Network::NetID::RS232) + .value("UART", Network::NetID::UART) + .value("UART2", Network::NetID::UART2) + .value("UART3", Network::NetID::UART3) + .value("UART4", Network::NetID::UART4) + .value("SWCAN2", Network::NetID::SWCAN2) + .value("Ethernet_DAQ", Network::NetID::Ethernet_DAQ) + .value("Data_To_Host", Network::NetID::Data_To_Host) + .value("TextAPI_To_Host", Network::NetID::TextAPI_To_Host) + .value("SPI1", Network::NetID::SPI1) + .value("OP_Ethernet6", Network::NetID::OP_Ethernet6) + .value("Red_VBat", Network::NetID::Red_VBat) + .value("OP_Ethernet7", Network::NetID::OP_Ethernet7) + .value("OP_Ethernet8", Network::NetID::OP_Ethernet8) + .value("OP_Ethernet9", Network::NetID::OP_Ethernet9) + .value("OP_Ethernet10", Network::NetID::OP_Ethernet10) + .value("OP_Ethernet11", Network::NetID::OP_Ethernet11) + .value("FlexRay1a", Network::NetID::FlexRay1a) + .value("FlexRay1b", Network::NetID::FlexRay1b) + .value("FlexRay2a", Network::NetID::FlexRay2a) + .value("FlexRay2b", Network::NetID::FlexRay2b) + .value("LIN5", Network::NetID::LIN5) + .value("FlexRay", Network::NetID::FlexRay) + .value("FlexRay2", Network::NetID::FlexRay2) + .value("OP_Ethernet12", Network::NetID::OP_Ethernet12) + .value("I2C", Network::NetID::I2C) + .value("MOST25", Network::NetID::MOST25) + .value("MOST50", Network::NetID::MOST50) + .value("MOST150", Network::NetID::MOST150) + .value("Ethernet", Network::NetID::Ethernet) + .value("GMFSA", Network::NetID::GMFSA) + .value("TCP", Network::NetID::TCP) + .value("HSCAN6", Network::NetID::HSCAN6) + .value("HSCAN7", Network::NetID::HSCAN7) + .value("LIN6", Network::NetID::LIN6) + .value("LSFTCAN2", Network::NetID::LSFTCAN2) + .value("LogicalDiskInfo", Network::NetID::LogicalDiskInfo) + .value("WiVICommand", Network::NetID::WiVICommand) + .value("ScriptStatus", Network::NetID::ScriptStatus) + .value("EthPHYControl", Network::NetID::EthPHYControl) + .value("ExtendedCommand", Network::NetID::ExtendedCommand) + .value("ExtendedData", Network::NetID::ExtendedData) + .value("FlexRayControl", Network::NetID::FlexRayControl) + .value("CoreMiniPreLoad", Network::NetID::CoreMiniPreLoad) + .value("HW_COM_Latency_Test", Network::NetID::HW_COM_Latency_Test) + .value("DeviceStatus", Network::NetID::DeviceStatus) + .value("UDP", Network::NetID::UDP) + .value("ForwardedMessage", Network::NetID::ForwardedMessage) + .value("I2C2", Network::NetID::I2C2) + .value("I2C3", Network::NetID::I2C3) + .value("I2C4", Network::NetID::I2C4) + .value("Ethernet2", Network::NetID::Ethernet2) + .value("A2B1", Network::NetID::A2B1) + .value("A2B2", Network::NetID::A2B2) + .value("Ethernet3", Network::NetID::Ethernet3) + .value("WBMS", Network::NetID::WBMS) + .value("DWCAN9", Network::NetID::DWCAN9) + .value("DWCAN10", Network::NetID::DWCAN10) + .value("DWCAN11", Network::NetID::DWCAN11) + .value("DWCAN12", Network::NetID::DWCAN12) + .value("DWCAN13", Network::NetID::DWCAN13) + .value("DWCAN14", Network::NetID::DWCAN14) + .value("DWCAN15", Network::NetID::DWCAN15) + .value("DWCAN16", Network::NetID::DWCAN16) + .value("LIN7", Network::NetID::LIN7) + .value("LIN8", Network::NetID::LIN8) + .value("SPI2", Network::NetID::SPI2) + .value("MDIO1", Network::NetID::MDIO1) + .value("MDIO2", Network::NetID::MDIO2) + .value("MDIO3", Network::NetID::MDIO3) + .value("MDIO4", Network::NetID::MDIO4) + .value("MDIO5", Network::NetID::MDIO5) + .value("MDIO6", Network::NetID::MDIO6) + .value("MDIO7", Network::NetID::MDIO7) + .value("MDIO8", Network::NetID::MDIO8) + .value("OP_Ethernet13", Network::NetID::OP_Ethernet13) + .value("OP_Ethernet14", Network::NetID::OP_Ethernet14) + .value("OP_Ethernet15", Network::NetID::OP_Ethernet15) + .value("OP_Ethernet16", Network::NetID::OP_Ethernet16) + .value("SPI3", Network::NetID::SPI3) + .value("SPI4", Network::NetID::SPI4) + .value("SPI5", Network::NetID::SPI5) + .value("SPI6", Network::NetID::SPI6) + .value("SPI7", Network::NetID::SPI7) + .value("SPI8", Network::NetID::SPI8) + .value("LIN9", Network::NetID::LIN9) + .value("LIN10", Network::NetID::LIN10) + .value("LIN11", Network::NetID::LIN11) + .value("LIN12", Network::NetID::LIN12) + .value("LIN13", Network::NetID::LIN13) + .value("LIN14", Network::NetID::LIN14) + .value("LIN15", Network::NetID::LIN15) + .value("LIN16", Network::NetID::LIN16) + .value("Any", Network::NetID::Any) + .value("Invalid", Network::NetID::Invalid); + + network.def(pybind11::init()); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/device/device.cpp b/bindings/python/icsneopy/device/device.cpp new file mode 100644 index 0000000..0f3ef50 --- /dev/null +++ b/bindings/python/icsneopy/device/device.cpp @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "icsneo/device/device.h" + +namespace icsneo { + +void init_device(pybind11::module_& m) { + pybind11::class_>(m, "Device") + .def("get_type", &Device::getType) + .def("get_serial", &Device::getSerial) + .def("get_serial_number", &Device::getSerialNumber) + .def("get_product_name", &Device::getProductName) + .def("open", [](Device& device) { return device.open(); }) + .def("close", &Device::close) + .def("is_open", &Device::isOpen) + .def("go_online", &Device::goOnline) + .def("go_offline", &Device::goOffline) + .def("is_online", &Device::isOnline).def("enable_message_polling", &Device::enableMessagePolling) + .def("disable_message_polling", &Device::disableMessagePolling) + .def("is_message_polling_enabled", &Device::isMessagePollingEnabled) + .def("get_messages", [](Device& device) { return device.getMessages(); }) + .def("get_current_message_count", &Device::getCurrentMessageCount) + .def("get_polling_message_limit", &Device::getPollingMessageLimit) + .def("set_polling_message_limit", &Device::setPollingMessageLimit) + .def("add_message_callback", &Device::addMessageCallback) + .def("remove_message_callback", &Device::removeMessageCallback) + .def("transmit", pybind11::overload_cast>(&Device::transmit)) + .def("get_supported_rx_networks", &Device::getSupportedRXNetworks, pybind11::return_value_policy::reference) + .def("get_supported_tx_networks", &Device::getSupportedTXNetworks, pybind11::return_value_policy::reference) + .def("get_rtc", &Device::getRTC) + .def("set_rtc", &Device::setRTC) + .def("describe", &Device::describe) + .def("is_online_supported", &Device::isOnlineSupported) + .def("supports_tc10", &Device::supportsTC10) + .def("request_tc10_wake", &Device::requestTC10Wake) + .def("request_tc10_sleep", &Device::requestTC10Sleep) + .def("__repr__", &Device::describe); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/device/devicetype.cpp b/bindings/python/icsneopy/device/devicetype.cpp new file mode 100644 index 0000000..931aa7f --- /dev/null +++ b/bindings/python/icsneopy/device/devicetype.cpp @@ -0,0 +1,75 @@ +#include +#include +#include + +#include "icsneo/device/devicetype.h" + +namespace icsneo { + +void init_devicetype(pybind11::module_& m) { + pybind11::class_ deviceType(m, "DeviceType"); + pybind11::enum_(deviceType, "Enum") + .value("Unknown", DeviceType::Enum::Unknown) + .value("BLUE", DeviceType::Enum::BLUE) + .value("ECU_AVB", DeviceType::Enum::ECU_AVB) + .value("RADSupermoon", DeviceType::Enum::RADSupermoon) + .value("DW_VCAN", DeviceType::Enum::DW_VCAN) + .value("RADMoon2", DeviceType::Enum::RADMoon2) + .value("RADMars", DeviceType::Enum::RADMars) + .value("VCAN4_1", DeviceType::Enum::VCAN4_1) + .value("FIRE", DeviceType::Enum::FIRE) + .value("RADPluto", DeviceType::Enum::RADPluto) + .value("VCAN4_2EL", DeviceType::Enum::VCAN4_2EL) + .value("RADIO_CANHUB", DeviceType::Enum::RADIO_CANHUB) + .value("NEOECU12", DeviceType::Enum::NEOECU12) + .value("OBD2_LCBADGE", DeviceType::Enum::OBD2_LCBADGE) + .value("RADMoonDuo", DeviceType::Enum::RADMoonDuo) + .value("FIRE3", DeviceType::Enum::FIRE3) + .value("VCAN3", DeviceType::Enum::VCAN3) + .value("RADJupiter", DeviceType::Enum::RADJupiter) + .value("VCAN4_IND", DeviceType::Enum::VCAN4_IND) + .value("RADGigastar", DeviceType::Enum::RADGigastar) + .value("RED2", DeviceType::Enum::RED2) + .value("EtherBADGE", DeviceType::Enum::EtherBADGE) + .value("RAD_A2B", DeviceType::Enum::RAD_A2B) + .value("RADEpsilon", DeviceType::Enum::RADEpsilon) + .value("RADMoon3", DeviceType::Enum::RADMoon3) + .value("RADComet", DeviceType::Enum::RADComet) + .value("FIRE3_FlexRay", DeviceType::Enum::FIRE3_FlexRay) + .value("Connect", DeviceType::Enum::Connect) + .value("RADComet3", DeviceType::Enum::RADComet3) + .value("RADMoonT1S", DeviceType::Enum::RADMoonT1S) + .value("RADGigastar2", DeviceType::Enum::RADGigastar2) + .value("RED", DeviceType::Enum::RED) + .value("ECU", DeviceType::Enum::ECU) + .value("IEVB", DeviceType::Enum::IEVB) + .value("Pendant", DeviceType::Enum::Pendant) + .value("OBD2_PRO", DeviceType::Enum::OBD2_PRO) + .value("ECUChip_UART", DeviceType::Enum::ECUChip_UART) + .value("PLASMA", DeviceType::Enum::PLASMA) + .value("DONT_REUSE0", DeviceType::Enum::DONT_REUSE0) + .value("NEOAnalog", DeviceType::Enum::NEOAnalog) + .value("CT_OBD", DeviceType::Enum::CT_OBD) + .value("DONT_REUSE1", DeviceType::Enum::DONT_REUSE1) + .value("DONT_REUSE2", DeviceType::Enum::DONT_REUSE2) + .value("ION", DeviceType::Enum::ION) + .value("RADStar", DeviceType::Enum::RADStar) + .value("DONT_REUSE3", DeviceType::Enum::DONT_REUSE3) + .value("VCAN4_4", DeviceType::Enum::VCAN4_4) + .value("VCAN4_2", DeviceType::Enum::VCAN4_2) + .value("CMProbe", DeviceType::Enum::CMProbe) + .value("EEVB", DeviceType::Enum::EEVB) + .value("VCANrf", DeviceType::Enum::VCANrf) + .value("FIRE2", DeviceType::Enum::FIRE2) + .value("Flex", DeviceType::Enum::Flex) + .value("RADGalaxy", DeviceType::Enum::RADGalaxy) + .value("RADStar2", DeviceType::Enum::RADStar2) + .value("VividCAN", DeviceType::Enum::VividCAN) + .value("OBD2_SIM", DeviceType::Enum::OBD2_SIM); + deviceType.def(pybind11::init()); + deviceType.def("get_device_type", &DeviceType::getDeviceType); + deviceType.def("get_generic_product_name", &DeviceType::getGenericProductName); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/icsneocpp.cpp b/bindings/python/icsneopy/icsneocpp.cpp new file mode 100644 index 0000000..9633067 --- /dev/null +++ b/bindings/python/icsneopy/icsneocpp.cpp @@ -0,0 +1,45 @@ +#include +#include +#include + +#include "icsneo/icsneocpp.h" + +namespace icsneo { + +void init_event(pybind11::module_&); +void init_eventcallback(pybind11::module_&); +void init_eventmanager(pybind11::module_&); +void init_network(pybind11::module_&); +void init_devicetype(pybind11::module_&); +void init_message(pybind11::module_&); +void init_canmessage(pybind11::module_&); +void init_ethernetmessage(pybind11::module_&); +void init_tc10statusmessage(pybind11::module_&); +void init_device(pybind11::module_&); +void init_messagefilter(pybind11::module_&); +void init_messagecallback(pybind11::module_&); +void init_version(pybind11::module_&); + +PYBIND11_MODULE(icsneopy, m) { + m.doc() = "libicsneo Python module"; + + init_event(m); + init_eventcallback(m); + init_eventmanager(m); + init_version(m); + init_devicetype(m); + init_network(m); + init_message(m); + init_canmessage(m); + init_ethernetmessage(m); + init_tc10statusmessage(m); + init_messagefilter(m); + init_messagecallback(m); + init_device(m); + + m.def("find_all_devices", &FindAllDevices); + m.def("get_supported_devices", &GetSupportedDevices); + m.def("get_last_error", &GetLastError); +} + +} // namespace icsneo diff --git a/ci/bootstrap-libpcap.sh b/ci/bootstrap-libpcap.sh new file mode 100644 index 0000000..8e812e5 --- /dev/null +++ b/ci/bootstrap-libpcap.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +VERSION="1.10.5" +ROOT="$PWD/libpcap" +SOURCE="$ROOT/source" +BUILD="$ROOT/build" +INSTALL="$ROOT/install" + +mkdir -p "$ROOT" +cd "$ROOT" || exit 1 + +curl -LO "https://www.tcpdump.org/release/libpcap-$VERSION.tar.xz" || exit 1 +tar -xf "libpcap-$VERSION.tar.xz" || exit 1 +mv "libpcap-$VERSION" "$SOURCE" || exit 1 + +cmake -D CMAKE_POSITION_INDEPENDENT_CODE=ON -D CMAKE_INSTALL_PREFIX="$INSTALL" -D BUILD_SHARED_LIBS=OFF -D BUILD_WITH_LIBNL=OFF -D DISABLE_DBUS=ON -D DISABLE_LINUX_USBMON=ON -D DISABLE_BLUETOOTH=ON -D DISABLE_NETMAP=ON -D DISABLE_DPDK=ON -D DISABLE_RDMA=ON -D DISABLE_DAG=ON -D DISABLE_SEPTEL=ON -D DISABLE_SNF=ON -D DISABLE_TC=ON -B "$BUILD" -S "$SOURCE" || exit 1 +cmake --build "$BUILD" || exit 1 +cmake --install "$BUILD" || exit 1 diff --git a/ci/bootstrap-libusb.sh b/ci/bootstrap-libusb.sh new file mode 100644 index 0000000..9e9987f --- /dev/null +++ b/ci/bootstrap-libusb.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +VERSION="1.0.27" +ROOT="$PWD/libusb" +SOURCE="$ROOT/source" +BUILD="$ROOT/build" +INSTALL="$ROOT/install" + +mkdir -p "$ROOT" +cd "$ROOT" || exit 1 + +curl -LO "https://github.com/libusb/libusb/releases/download/v$VERSION/libusb-$VERSION.tar.bz2" || exit 1 +tar -xf "libusb-$VERSION.tar.bz2" || exit 1 +mv "libusb-$VERSION" "$SOURCE" || exit 1 + +mkdir "$BUILD" || exit 1 +cd "$BUILD" || exit 1 +"$SOURCE/configure" --prefix="$INSTALL" --disable-shared --disable-udev --disable-eventfd --disable-timerfd --with-pic || exit 1 +make || exit 1 +make install || exit 1 + diff --git a/ci/build-wheel-posix.sh b/ci/build-wheel-posix.sh new file mode 100644 index 0000000..46d157e --- /dev/null +++ b/ci/build-wheel-posix.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +python3 -m venv env || exit 1 +. env/bin/activate || exit 1 +python3 -m pip install cibuildwheel || exit 1 +python3 -m cibuildwheel --output-dir wheelhouse || exit 1 + diff --git a/ci/build-wheel-windows.bat b/ci/build-wheel-windows.bat new file mode 100644 index 0000000..80b4c0f --- /dev/null +++ b/ci/build-wheel-windows.bat @@ -0,0 +1,9 @@ +@setlocal +@echo off + +call "%VCVARS64_2022%" + +python.exe -m venv env || exit /b 1 +call env\Scripts\Activate.bat || exit /b 1 +python.exe -m pip install cibuildwheel || exit /b 1 +python.exe -m cibuildwheel --output-dir wheelhouse --platform windows || exit /b 1 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..8f33408 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,49 @@ +[build-system] +requires = ["scikit-build-core", "pybind11", "setuptools>=64", "setuptools-scm>=8"] +build-backend = "scikit_build_core.build" + +[project] +name = "icsneopy" +dynamic = ["version"] +requires-python = ">=3.9" +readme = "README.md" +authors = [{name = "Intrepid Control Systems, Inc."}] +maintainers = [ + {name = "Kyle Schwarz", email="kschwarz@intrepidcs.com"}, +] +license = {file = "LICENSE"} +classifiers = [ + 'Development Status :: 5 - Production/Stable', + 'Intended Audience :: Developers', + 'Programming Language :: C', + 'Programming Language :: Python', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', + 'Programming Language :: Python :: 3 :: Only', + 'Programming Language :: Python :: Implementation :: CPython', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: POSIX', + 'Operating System :: Unix', + 'Operating System :: MacOS', +] + +[project.urls] +homepage = "https://github.com/intrepidcs/libicsneo" +documentation = "https://libicsneo.readthedocs.io" +source = "https://github.com/intrepidcs/libicsneo" +tracker = "https://github.com/intrepidcs/libicsneo/issues" + +[tool.scikit-build] +metadata.version.provider = "scikit_build_core.metadata.setuptools_scm" + +[tool.setuptools_scm] +version_scheme = "no-guess-dev" +local_scheme = "no-local-version" + +[tool.scikit-build.cmake.define] +LIBICSNEO_ENABLE_BINDINGS_PYTHON = true +LIBICSNEO_ENABLE_TCP = true From 008a0e4057ada3cb9f1825c3c2adf6622866ad45 Mon Sep 17 00:00:00 2001 From: Kyle Schwarz Date: Fri, 1 Nov 2024 21:26:45 -0400 Subject: [PATCH 20/47] CI: Add needs section --- .gitlab-ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5d9839d..2efe6ea 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -319,6 +319,7 @@ unit_test linux/fedora/39/amd64/clang: - /opt/libvirt-driver/run.sh after_script: - /opt/libvirt-driver/cleanup.sh + allow_failure: true .fedora38_needs: &fedora38_needs needs: @@ -508,3 +509,8 @@ deploy python/pypi: - build python/linux/arm64 - build python/macos - build python/windows + needs: + - build python/linux/amd64 + - build python/linux/arm64 + - build python/macos + - build python/windows From 648fb2502f441c2daf2a76b188fd7f9c22d2139f Mon Sep 17 00:00:00 2001 From: Kyle Schwarz Date: Mon, 4 Nov 2024 18:01:28 -0500 Subject: [PATCH 21/47] Docs: Refactor --- .readthedocs.yaml | 15 + HARDWARE.md | 64 - README.md | 202 +- docs/conf.py | 190 +- docs/conf.py.template | 188 -- docs/icsneoc.rst | 44 - docs/{ => icsneoc}/Doxyfile | 1000 ++++-- docs/icsneoc/api.rst | 14 + docs/icsneoc/examples.rst | 43 + docs/icsneoc/index.rst | 9 + docs/icsneoc/installation.rst | 7 + docs/icsneocpp.rst | 31 - docs/icsneocpp/Doxyfile | 2862 +++++++++++++++++ docs/icsneocpp/api.rst | 8 + docs/icsneocpp/apiconcepts.rst | 55 + .../deviceconcepts.rst} | 62 +- docs/icsneocpp/examples.rst | 52 + docs/icsneocpp/index.rst | 11 + docs/icsneocpp/installation.rst | 39 + docs/icsneopy/api.rst | 9 + docs/icsneopy/examples.rst | 52 + docs/icsneopy/index.rst | 9 + docs/index.rst | 14 +- docs/requirements.txt | 5 +- 24 files changed, 3941 insertions(+), 1044 deletions(-) create mode 100644 .readthedocs.yaml delete mode 100644 HARDWARE.md delete mode 100644 docs/conf.py.template delete mode 100644 docs/icsneoc.rst rename docs/{ => icsneoc}/Doxyfile (72%) create mode 100644 docs/icsneoc/api.rst create mode 100644 docs/icsneoc/examples.rst create mode 100644 docs/icsneoc/index.rst create mode 100644 docs/icsneoc/installation.rst delete mode 100644 docs/icsneocpp.rst create mode 100644 docs/icsneocpp/Doxyfile create mode 100644 docs/icsneocpp/api.rst create mode 100644 docs/icsneocpp/apiconcepts.rst rename docs/{Usage.rst => icsneocpp/deviceconcepts.rst} (55%) create mode 100644 docs/icsneocpp/examples.rst create mode 100644 docs/icsneocpp/index.rst create mode 100644 docs/icsneocpp/installation.rst create mode 100644 docs/icsneopy/api.rst create mode 100644 docs/icsneopy/examples.rst create mode 100644 docs/icsneopy/index.rst diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..63bcdf0 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,15 @@ +version: 2 + +build: + os: "ubuntu-24.04" + tools: + python: "3.12" + apt_packages: + - doxygen + +python: + install: + - requirements: docs/icsneopy/requirements.txt + +sphinx: + configuration: docs/conf.py diff --git a/HARDWARE.md b/HARDWARE.md deleted file mode 100644 index 6948011..0000000 --- a/HARDWARE.md +++ /dev/null @@ -1,64 +0,0 @@ -# Hardware Support - -- Connecting over Ethernet - - neoVI FIRE 2 - - CAN works - - CAN FD works - - ValueCAN 4-2EL - - CAN works - - CAN FD works - - Ethernet works - - RADGalaxy - - CAN works - - Ethernet works - - RADStar 2 - - CAN works - - Ethernet works - - RADA2B - - CAN works - - Ethernet works - - RADComet - - CAN works - - CAN FD works - - Ethernet works - - RADComet3 - - CAN works - - Ethernet works - - neoVI Connect - - CAN works - - CAN FD works - - Ethernet works - - RADGigastar2 - -- Connecting over USB - - ValueCAN 4 series - - CAN works - - CAN FD works - - Ethernet works (on 4-2EL) - - neoOBD2 PRO - - CAN works - - neoVI FIRE - - CAN works - - neoVI FIRE 2 - - CAN works - - CAN FD works - - Ethernet works - - ValueCAN 3 - - CAN works - - RADStar 2 - - CAN works - - Ethernet works - - neoVI PLASMA - - CAN works - - neoVI ION - - CAN works - - RADA2B - - CAN works - - Ethernet works - - RADMoon3 - - RADComet3 - - CAN works - - Ethernet works - - RADMoonT1S - - Ethernet works - - RADGigastar2 diff --git a/README.md b/README.md index ea2b915..f0275ed 100644 --- a/README.md +++ b/README.md @@ -1,176 +1,42 @@ # libicsneo -### The Intrepid Control Systems Open Source Cross-Platform Device Communication API -An open source solution to integrate Intrepid Control Systems vehicle networking hardware with your application. +libicsneo is the [Intrepid Control Systems](https://intrepidcs.com/) device +communication library. Installation and usage documentation can be found within +each of the respective APIs. -[Read the Full Documentation](https://libicsneo.readthedocs.io/) +## Documentation -## Getting Started -There are two major ways to write a new application using libicsneo. You can use the C++ interface, which will be compiled with your project and statically linked, or you can use the C interface, which can be either statically or dynamically linked. -### Integration with CMake (Static Linking) -Integrating the library with your current CMake project is extremely easy. -1. Checkout the library (or add as a submodule) into a subdirectory of your project. -2. Within your `CMakeLists.txt` you can add the line `add_subdirectory("third-party/libicsneo")` to bring in the libicsneo targets. Replace `third-party` with any subdirectory you choose. -3. The libicsneo library include paths should automatically be added to your include path. -4. Link the library with your target by adding `target_link_libraries(libicsneocpp-example icsneocpp)` after your target, substituting `libicsneocpp-example` with your target application. +- [C++](https://libicsneo.readthedocs.io/en/latest/icsneocpp/) +- [Python](https://libicsneo.readthedocs.io/en/latest/icsneopy/) +- [C](https://libicsneo.readthedocs.io/en/latest/icsneoc/) -You can now include either the C++ API with `#include ` or the C API with `#include ` +## Hardware Support -### DLL / SO / DYLIB Releases (Dynamic Linking) -It is also possible to use the precompiled binaries with runtime linking. It is not recommended or supported to attempt to use the C++ interface with dynamic linking due to the complexities of C++ compilers. -1. Add this repository's `/include` to your include path -2. Add `#define ICSNEOC_DYNAMICLOAD` to the top of your source file -2. Add `#import ` below that line -3. Call `icsneo_init();` to import the library before using any other libicsneo functions. -4. Use the library as normal. -5. Call `icsneo_close();` to unload the library. +- EtherBADGE +- neoVI Connect +- neoVI FIRE +- neoVI FIRE 2 +- neoVI FIRE 3 +- neoVI ION +- neoVI PLASMA +- neoVI RED 2 +- RAD-A2B +- RAD-Comet 2 +- RAD-Comet 3 +- RAD-Galaxy +- RAD-Gigastar +- RAD-Gigastar 2 +- RAD-Moon 2 +- RAD-Moon 3 +- RAD-Moon T1S +- RAD-Pluto +- RAD-Star 2 +- RAD-SuperMoon +- RADComet +- ValueCAN 3 +- ValueCAN 4 -## Usage -### Using the C++ API -The C++ API is designed to be modern and easy to use. All library functions and classes are in the namespace `icsneo`. Most applications will start by calling `icsneo::FindAllDevices()`. This will return an `std::vector` of `std::shared_ptr` objects. You will want to keep a copy of the `shared_ptr` to any devices you want to use, as allowing it to go out of scope will automatically close the device and free all memory associated with it. +## License -Any time you get bus traffic from the API, you will receive it as an `std::shared_ptr`. The message will be valid as long as the `shared_ptr` stays in scope. Checking the type of the message allows you to cast it accordingly and access extra data for certain protocols. For instance, casting an `icsneo::Message` to an `icsneo::CANMessage` allows you to access the arbitration ID. - -A barebones example is provided. For a more complete example, check the included `examples`. -``` c++ -std::vector> devices = icsneo::FindAllDevices(); -std::cout << devices.size() << " found!" << std::endl; -for(auto& device : devices) - std::cout << "Found " << device->describe() << std::endl; // "Found neoVI FIRE 2 CY2345" -std::shared_ptr myDevice = devices[0]; - -if(!myDevice->open()) // Device tried and failed to open, print the last error - std::cout << icsneo::GetLastError() << std::endl; - -myDevice->goOnline(); // Start receiving messages -myDevice->enableMessagePolling(); // Allow the use of myDevice->getMessages() later -// Alternatively, assign a callback for new messages -std::this_thread::wait_for(std::chrono::seconds(5)); -std::vector> messages = myDevice->getMessages(); -std::cout << "We got " << messages.size() << " messages!" << std::endl; -for(auto& msg : messages) { - switch(msg->network.getType()) { - case icsneo::Network::Type::CAN: - case icsneo::Network::Type::SWCAN: - case icsneo::Network::Type::LSFTCAN: { - // A message of type CAN is guaranteed to be a CANMessage, so we can static cast safely - auto canmsg = std::static_pointer_cast(msg); - // canmsg->arbid is valid here - // canmsg->data is an std::vector, you can check .size() for the DLC of the message - // canmsg->timestamp is the time recorded by the hardware in nanoseconds since (1/1/2007 12:00:00 GMT) - } - default: - // Handle others - } -} -myDevice->close(); -``` - -### Using the C API -The C API is designed to be a robust and fault tolerant interface which allows easy integration with other languages as well as existing C applications. When calling `icsneo_findAllDevices()` you will provide a buffer of `neodevice_t` structures, which will be written with the found devices. These `neodevice_t` structures can be uses to interface with the API from then on. Once you call `icsneo_close()` with a device, that device and all associated memory will be freed. You will need to run `icsneo_findAllDevices()` again to reconnect. - -Messages are passed in the form of `neomessage_t` structures when calling `icsneo_getMessages()`. These structures contain a `uint8_t*` to the payload data, and this pointer will be valid until the next call to `icsneo_getMessages()` or the device is closed. - -A barebones example is provided. For a more complete example, check the included `examples`. -``` c -size_t deviceCount = 10; // Pre-set to the size of your buffer before the icsneo_findAllDevices() call -neodevice_t devices[10]; -icsneo_findAllDevices(devices, &deviceCount); -printf("We found %ull devices\n", deviceCount); -for(size_t i = 0; i < deviceCount; i++) { - neodevice_t* myDevice = &devices[i]; - char desc[ICSNEO_DEVICETYPE_LONGEST_DESCRIPTION]; - size_t sz = ICSNEO_DEVICETYPE_LONGEST_DESCRIPTION; - icsneo_describeDevice(myDevice, desc, &sz); - printf("Found %s\n", desc); // "Found neoVI FIRE 2 CY2345" -} - -neodevice_t* myDevice = &devices[0]; -if(!icsneo_openDevice(myDevice)) { - neoevent_t error; - if(icsneo_getLastError(&error)) - printf("Error! %s\n", error.description); -} -icsneo_goOnline(myDevice); // Start receiving messages -icsneo_enableMessagePolling(myDevice); // Allow the use of icsneo_getMessages() later -sleep(5); -neomessage_t messages[50]; -size_t messageCount = 50; -icsneo_getMessages(myDevice, messages, &messageCount, 0 /* non-blocking */); -printf("We got %ull messages!\n", messageCount); -for(size_t i = 0; i < messageCount; i++) { - if(messages[i].type == ICSNEO_NETWORK_TYPE_CAN) { - // A message of type CAN should be interperated a neomessage_can_t, so we can cast safely - neomessage_can_t* canmsg = (neomessage_can_t*)&messages[i]; - // canmsg->arbid is valid here - // canmsg->data is an uint8_t*, you can check canmsg->length for the length of the payload - // canmsg->timestamp is the time recorded by the hardware in nanoseconds since (1/1/2007 12:00:00 GMT) - } -} -icsneo_closeDevice(myDevice); -``` - -### Debugging - -To enable debug printing set the `LIBICSNEO_PRINT_EVENTS` environmental variable to the desired `APIEvent::Severity` level, all `Event`s greater than or equal to that level will be printed to stderr. For example, to print all warnings and errors: `LIBICSNEO_PRINT_EVENTS=32`. - -## Building from Source -### FTD3XX -Some devices require FTD3XX for USB communication so the [FTDI D3XX library](https://ftdichip.com/drivers/d3xx-drivers/) will be automatically downloaded and included. If you would like to use a system copy of D3XX instead you can set `FTD3XX_ROOT` to the path containing `f3d3xx.h` (`-DFTD3XX_ROOT=`). -### Windows - -- Open a terminal and install the following: -``` -winget install Microsoft.VisualStudio.2022.Community -winget install Kitware.CMake -winget install Git.Git -winget install Ninja-build.Ninja -``` -- Reboot so cmake is in the system path -- Open a developer Powershell for VS2022 and run the following: -``` -git clone https://github.com/intrepidcs/libicsneo -cd libicsneo -cmake -S . -B build -G "Ninja" -cmake --build build -# All dlls and libs are now inside the build directory -``` - - -Building will require MSVC 2017 version 15.7 or newer and CMake to be installed. -### macOS -Getting the dependencies is easiest with the Homebrew package manager. You will also need XCode installed. You can then install CMake, an up-to-date version of GCC or Clang, and `libusb-1.0`. -### Linux -#### General Dependencies - - CMake 3.12 or above - - GCC 7 or above - - `libusb-1.0-0-dev` - - `libpcap0.8-dev` - - `build-essential` is recommended - -#### Fedora -``` -dnf install git @development-tools gcc-c++ libpcap-devel libusb1-devel cmake -``` -#### Debian/Ubuntu -``` -apt install git build-essential libpcap0.8-dev libusb-1.0-0-dev cmake -``` - -#### Building -``` -git clone https://github.com/intrepidcs/libicsneo -cd libicsneo -cmake -S . -B build -cmake --build build -# Optional: Install globally: -cp *.so /usr/local/lib/ -``` - -#### udev -If you'd like to be able to run programs that use this library without being root, consider using the included udev rules: - -``` -cp 99-intrepidcs.rules /etc/udev/rules.d/ -udevadm control --reload-rules && udevadm trigger -``` +libicsneo is licensed as BSD-3 with an extra clause, see [LICENSE](LICENSE) +for more details. diff --git a/docs/conf.py b/docs/conf.py index bc4cd5e..6e4ec71 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,188 +1,36 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- +# Configuration file for the Sphinx documentation builder. # -# NOTE: The conf.py file is automatically updated by CMake when there are -# changes to the version. Update the conf.py.template and then build to -# propagate changes here. This file should be committed so that -# ReadTheDocs can use it. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -import os import subprocess -# import sys -# sys.path.insert(0, os.path.abspath('.')) +subprocess.call('cd ..; doxygen docs/icsneocpp/Doxyfile', shell=True) +subprocess.call('cd ..; doxygen docs/icsneoc/Doxyfile', shell=True) -# -- General configuration ------------------------------------------------ +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information -# If your documentation needs a minimal Sphinx version, state it here. -# -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = ['sphinx.ext.imgmath', 'sphinx.ext.todo', 'breathe' ] - -breathe_projects = { "libicsneo": "build/doxygen/xml" } -breathe_default_project = "libicsneo" - -try: - os.makedirs('build/sphinx') -except FileExistsError: - pass -try: - os.makedirs('build/doxygen') -except FileExistsError: - pass - -subprocess.call('cd ..; doxygen docs/Doxyfile', shell=True) - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. project = 'libicsneo' -copyright = '2018-2024, Intrepid Control Systems, Inc.' +copyright = '2024, Intrepid Control Systems, Inc.' author = 'Intrepid Control Systems, Inc.' -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '0.2.0' -# The full version, including alpha/beta/rc tags. -release = '0.2.0 ' +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None +extensions = ['breathe', 'sphinx.ext.autodoc'] -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path +templates_path = ['_templates'] exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +breathe_projects = { + 'icsneocpp': 'icsneocpp/doxygen/xml', + 'icsneoc': 'icsneoc/doxygen/xml', +} -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = False +breathe_default_project = 'icsneocpp' +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# html_theme = 'sphinx_rtd_theme' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# -html_theme_options = { - -} - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Custom sidebar templates, must be a dictionary that maps document names -# to template names. -# -# This is required for the alabaster theme -# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars -html_sidebars = { - '**': [ - 'relations.html', # needs 'show_related': True theme option to display - 'searchbox.html', - ] -} - - -# -- Options for HTMLHelp output ------------------------------------------ - -# Output file base name for HTML help builder. -htmlhelp_basename = 'libicsneodoc' - - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'libicsneo.tex', 'libicsneo Documentation', - 'Intrepid Control Systems, Inc.', 'manual'), -] - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'libicsneo', 'libicsneo Documentation', - [author], 1) -] - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'libicsneo', 'libicsneo Documentation', - author, 'libicsneo', 'One line description of project.', - 'Miscellaneous'), -] - - - diff --git a/docs/conf.py.template b/docs/conf.py.template deleted file mode 100644 index 8fd938e..0000000 --- a/docs/conf.py.template +++ /dev/null @@ -1,188 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# NOTE: The conf.py file is automatically updated by CMake when there are -# changes to the version. Update the conf.py.template and then build to -# propagate changes here. This file should be committed so that -# ReadTheDocs can use it. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -import os -import subprocess -# import sys -# sys.path.insert(0, os.path.abspath('.')) - - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -# -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = ['sphinx.ext.imgmath', 'sphinx.ext.todo', 'breathe' ] - -breathe_projects = { "libicsneo": "build/doxygen/xml" } -breathe_default_project = "libicsneo" - -try: - os.makedirs('build/sphinx') -except FileExistsError: - pass -try: - os.makedirs('build/doxygen') -except FileExistsError: - pass - -subprocess.call('cd ..; doxygen docs/Doxyfile', shell=True) - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = 'libicsneo' -copyright = '2018-2024, Intrepid Control Systems, Inc.' -author = 'Intrepid Control Systems, Inc.' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@' -# The full version, including alpha/beta/rc tags. -release = '@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@ @BUILD_METADATA@' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'sphinx_rtd_theme' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# -html_theme_options = { - -} - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Custom sidebar templates, must be a dictionary that maps document names -# to template names. -# -# This is required for the alabaster theme -# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars -html_sidebars = { - '**': [ - 'relations.html', # needs 'show_related': True theme option to display - 'searchbox.html', - ] -} - - -# -- Options for HTMLHelp output ------------------------------------------ - -# Output file base name for HTML help builder. -htmlhelp_basename = 'libicsneodoc' - - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'libicsneo.tex', 'libicsneo Documentation', - 'Intrepid Control Systems, Inc.', 'manual'), -] - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'libicsneo', 'libicsneo Documentation', - [author], 1) -] - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'libicsneo', 'libicsneo Documentation', - author, 'libicsneo', 'One line description of project.', - 'Miscellaneous'), -] - - - diff --git a/docs/icsneoc.rst b/docs/icsneoc.rst deleted file mode 100644 index 43eb282..0000000 --- a/docs/icsneoc.rst +++ /dev/null @@ -1,44 +0,0 @@ -******************** -**C API** (icsneoc) -******************** - -.. Usage -.. ====== - -.. Finding Devices -.. ~~~~~~~~~~~~~~~~ -.. Finding a device is simple - -.. Connecting to Devices -.. ~~~~~~~~~~~~~~~~~~~~~~ - -Reference -========== - -Typedefs -~~~~~~~~~ -.. doxygentypedef:: devicehandle_t -.. doxygentypedef:: neodevice_handle_t -.. doxygentypedef:: devicetype_t - -Structures -~~~~~~~~~~~ -.. doxygenstruct:: neoversion_t - :members: - :undoc-members: - -.. doxygenstruct:: neodevice_t - :members: - :undoc-members: - -.. doxygenstruct:: neomessage_t - :members: - :undoc-members: - -.. doxygenstruct:: neomessage_can_t - :members: - :undoc-members: - -Functions -~~~~~~~~~~ -.. doxygenfile:: icsneoc.h diff --git a/docs/Doxyfile b/docs/icsneoc/Doxyfile similarity index 72% rename from docs/Doxyfile rename to docs/icsneoc/Doxyfile index eb1d79a..76949b7 100644 --- a/docs/Doxyfile +++ b/docs/icsneoc/Doxyfile @@ -1,4 +1,4 @@ -# Doxyfile 1.8.14 +# Doxyfile 1.11.0 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -12,15 +12,25 @@ # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables or CMake type +# replacement variables: +# doxygen -x_noenv [configFile] #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all text -# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv -# built into libc) for the transcoding. See +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See # https://www.gnu.org/software/libiconv/ for the list of possible encodings. # The default value is: UTF-8. @@ -32,19 +42,19 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = "libicsneo" +PROJECT_NAME = "icsneoc" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = "" +PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. -PROJECT_BRIEF = "Intrepid Control Systems Device Communication API" +PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 @@ -53,23 +63,41 @@ PROJECT_BRIEF = "Intrepid Control Systems Device Communication API" PROJECT_LOGO = +# With the PROJECT_ICON tag one can specify an icon that is included in the tabs +# when the HTML document is shown. Doxygen will copy the logo to the output +# directory. + +PROJECT_ICON = + # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. -OUTPUT_DIRECTORY = docs/build/doxygen +OUTPUT_DIRECTORY = docs/icsneoc/doxygen -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 +# sub-directories (in 2 levels) under the output directory of each output format +# and will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes -# performance problems for the file system. +# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# control the number of sub-directories. # The default value is: NO. CREATE_SUBDIRS = NO +# Controls the number of sub-directories that will be created when +# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every +# level increment doubles the number of directories, resulting in 4096 +# directories at level 8 which is the default and also the maximum value. The +# sub-directories are organized in 2 levels, the first level always has a fixed +# number of 16 directories. +# Minimum value: 0, maximum value: 8, default value: 8. +# This tag requires that the tag CREATE_SUBDIRS is set to YES. + +CREATE_SUBDIRS_LEVEL = 8 + # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode @@ -81,14 +109,14 @@ ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, +# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English +# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, +# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with +# English messages), Korean, Korean-en (Korean with English messages), Latvian, +# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, +# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, +# Swedish, Turkish, Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English @@ -189,6 +217,16 @@ SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus @@ -209,6 +247,14 @@ QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO +# By default Python docstrings are displayed as preformatted text and doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. @@ -232,21 +278,19 @@ TAB_SIZE = 4 # the documentation. An alias has the form: # name=value # For example adding -# "sideeffect=@par Side Effects:\n" +# "sideeffect=@par Side Effects:^^" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines (in the resulting output). You can put ^^ in the value part of an -# alias to insert a newline as if a physical newline was in the original file. +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) ALIASES = -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding "class=itcl::class" -# will allow you to use the command class in the itcl::class meaning. - -TCL_SUBST = - # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all @@ -275,28 +319,40 @@ OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: -# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: -# Fortran. In the later case the parser tries to guess whether the code is fixed -# or free formatted code, this is the default for Fortran type files), VHDL. For -# instance to make doxygen treat .inc files as Fortran files (default is PHP), -# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. +# the files are not read by doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. +# documentation. See https://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. @@ -308,10 +364,21 @@ MARKDOWN_SUPPORT = YES # to that level are automatically included in the table of contents, even if # they do not have an id attribute. # Note: This feature currently applies only to Markdown headings. -# Minimum value: 0, maximum value: 99, default value: 0. +# Minimum value: 0, maximum value: 99, default value: 6. # This tag requires that the tag MARKDOWN_SUPPORT is set to YES. -TOC_INCLUDE_HEADINGS = 0 +TOC_INCLUDE_HEADINGS = 6 + +# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to +# generate identifiers for the Markdown headings. Note: Every identifier is +# unique. +# Possible values are: DOXYGEN use a fixed 'autotoc_md' string followed by a +# sequence number starting at 0 and GITHUB use the lower case version of title +# with any whitespace replaced by '-' and punctuation characters removed. +# The default value is: DOXYGEN. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +MARKDOWN_ID_STYLE = DOXYGEN # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can @@ -325,11 +392,11 @@ AUTOLINK_SUPPORT = YES # to include (a tag file for) the STL sources as input, then you should set this # tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); -# versus func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. +# versus func(std::string) {}). This also makes the inheritance and +# collaboration diagrams that involve STL classes more complete and accurate. # The default value is: NO. -BUILTIN_STL_SUPPORT = NO +BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. @@ -338,9 +405,9 @@ BUILTIN_STL_SUPPORT = NO CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen -# will parse them like normal C++ but will assume all classes use public instead -# of private inheritance when no explicit protection keyword is present. +# https://www.riverbankcomputing.com/software) sources only. Doxygen will parse +# them like normal C++ but will assume all classes use public instead of private +# inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO @@ -424,6 +491,27 @@ TYPEDEF_HIDES_STRUCT = NO LOOKUP_CACHE_SIZE = 0 +# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use +# during processing. When set to 0 doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which effectively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + +# If the TIMESTAMP tag is set different from NO then each generated page will +# contain the date or date and time when the page was generated. Setting this to +# NO can help when comparing the output of multiple runs. +# Possible values are: YES, NO, DATETIME and DATE. +# The default value is: NO. + +TIMESTAMP = NO + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- @@ -444,6 +532,12 @@ EXTRACT_ALL = YES EXTRACT_PRIVATE = NO +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. @@ -462,7 +556,7 @@ EXTRACT_STATIC = NO # for Java sources. # The default value is: YES. -EXTRACT_LOCAL_CLASSES = NO +EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. If set to YES, local methods, # which are defined in the implementation section but not in the interface are @@ -481,6 +575,13 @@ EXTRACT_LOCAL_METHODS = NO EXTRACT_ANON_NSPACES = NO +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation @@ -492,14 +593,15 @@ HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. +# will also hide undocumented C++ concepts if enabled. This option has no effect +# if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO, these declarations will be -# included in the documentation. +# declarations. If set to NO, these declarations will be included in the +# documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO @@ -518,14 +620,22 @@ HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO -# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES, upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. -# The default value is: system dependent. +# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and MacOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# Possible values are: SYSTEM, NO and YES. +# The default value is: SYSTEM. -CASE_SENSE_NAMES = NO +CASE_SENSE_NAMES = SYSTEM # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES, the @@ -541,6 +651,12 @@ HIDE_SCOPE_NAMES = NO HIDE_COMPOUND_REFERENCE= NO +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = YES + # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. @@ -698,7 +814,8 @@ FILE_VERSION_FILTER = # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE @@ -744,23 +861,50 @@ WARNINGS = YES WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES +# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete +# function parameter documentation. If set to NO, doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. +# value. If set to NO, doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC # The default value is: NO. WARN_NO_PARAMDOC = NO +# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about +# undocumented enumeration values. If set to NO, doxygen will accept +# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: NO. + +WARN_IF_UNDOC_ENUM_VAL = NO + # If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when -# a warning is encountered. +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the doxygen process doxygen will return with a non-zero status. +# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then doxygen behaves +# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined doxygen will not +# write the warning messages in between other messages but write them at the end +# of a run, in case a WARN_LOGFILE is defined the warning messages will be +# besides being in the defined file also be shown at the end of a run, unless +# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case +# the behavior will remain as with the setting FAIL_ON_WARNINGS. +# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT. # The default value is: NO. WARN_AS_ERROR = NO @@ -771,13 +915,27 @@ WARN_AS_ERROR = NO # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) +# See also: WARN_LINE_FORMAT # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" +# In the $text part of the WARN_FORMAT command it is possible that a reference +# to a more specific place is given. To make it easier to jump to this place +# (outside of doxygen) the user can define a custom "cut" / "paste" string. +# Example: +# WARN_LINE_FORMAT = "'vi $file +$line'" +# See also: WARN_FORMAT +# The default value is: at line $line of file $file. + +WARN_LINE_FORMAT = "at line $line of file $file" + # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard -# error (stderr). +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). WARN_LOGFILE = @@ -791,17 +949,28 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = include/icsneo/icsneoc.h include/icsneo/icsneocpp.h include/icsneo/api include/icsneo/communication/network.h include/icsneo/communication/message include/icsneo/communication/message/callback include/icsneo/communication/message/filter include/icsneo/device/device.h include/icsneo/device/devicefinder.h include/icsneo/device/devicetype.h include/icsneo/device/idevicesettings.h include/icsneo/device/neodevice.h +INPUT = include # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: https://www.gnu.org/software/libiconv/) for the list of -# possible encodings. +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# See also: INPUT_FILE_ENCODING # The default value is: UTF-8. INPUT_ENCODING = UTF-8 +# This tag can be used to specify the character encoding of the source files +# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify +# character encoding on a per file pattern basis. Doxygen will compare the file +# name with each pattern and apply the encoding instead of the default +# INPUT_ENCODING) if there is a match. The character encodings are a list of the +# form: pattern=encoding (like *.php=ISO-8859-1). +# See also: INPUT_ENCODING for further information on supported encodings. + +INPUT_FILE_ENCODING = + # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. @@ -810,17 +979,25 @@ INPUT_ENCODING = UTF-8 # need to set EXTENSION_MAPPING for the extension otherwise the files are not # read by doxygen. # -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, -# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cxxm, +# *.cpp, *.cppm, *.ccm, *.c++, *.c++m, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, +# *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, *.h++, *.ixx, *.l, *.cs, *.d, +# *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to +# be provided as doxygen C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f18, *.f, *.for, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. FILE_PATTERNS = *.c \ *.cc \ *.cxx \ + *.cxxm \ *.cpp \ + *.cppm \ + *.ccm \ *.c++ \ + *.c++m \ *.java \ *.ii \ *.ixx \ @@ -835,6 +1012,8 @@ FILE_PATTERNS = *.c \ *.hxx \ *.hpp \ *.h++ \ + *.ixx \ + *.l \ *.cs \ *.d \ *.php \ @@ -853,19 +1032,20 @@ FILE_PATTERNS = *.c \ *.f95 \ *.f03 \ *.f08 \ + *.f18 \ *.f \ *.for \ - *.tcl \ *.vhd \ *.vhdl \ *.ucf \ - *.qsf + *.qsf \ + *.ice # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. -RECURSIVE = NO +RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a @@ -874,7 +1054,7 @@ RECURSIVE = NO # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = include/icsneo/third-party include/icsneo/icsneolegacy.h include/icsneo/icsnVC40.h +EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -890,16 +1070,13 @@ EXCLUDE_SYMLINKS = NO # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = */third-party/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* +# ANamespace::AClass, ANamespace::*Test EXCLUDE_SYMBOLS = @@ -944,6 +1121,11 @@ IMAGE_PATH = # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. # +# Note that doxygen will use the data processed and written to standard output +# for further processing, therefore nothing else, like debug statements or used +# commands (so in case of a Windows batch file always use @echo OFF), should be +# written to standard output. +# # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. @@ -985,6 +1167,15 @@ FILTER_SOURCE_PATTERNS = USE_MDFILE_AS_MAINPAGE = +# The Fortran standard specifies that for fixed formatted Fortran code all +# characters from position 72 are to be considered as comment. A common +# extension is to allow longer lines before the automatic comment starts. The +# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can +# be processed before the automatic comment starts. +# Minimum value: 7, maximum value: 10000, default value: 72. + +FORTRAN_COMMENT_AFTER = 72 + #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- @@ -999,7 +1190,8 @@ USE_MDFILE_AS_MAINPAGE = SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body of functions, -# classes and enums directly into the documentation. +# multi-line macros, enums or list initialized variables directly into the +# documentation. # The default value is: NO. INLINE_SOURCES = NO @@ -1012,7 +1204,7 @@ INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# function all documented functions referencing it will be listed. +# entity all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = NO @@ -1049,7 +1241,7 @@ SOURCE_TOOLTIPS = YES # # To use it do the following: # - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # @@ -1082,17 +1274,11 @@ VERBATIM_HEADERS = YES ALPHABETICAL_INDEX = YES -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. +# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes) +# that should be ignored while generating the index headers. The IGNORE_PREFIX +# tag works for classes, function and member names. The entity will be placed in +# the alphabetical list under the first letter of the entity name that remains +# after removing the prefix. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = @@ -1171,7 +1357,12 @@ HTML_STYLESHEET = # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. +# list). +# Note: Since the styling of scrollbars can currently not be overruled in +# Webkit/Chromium, the styling will be left out of the default doxygen.css if +# one or more extra stylesheets have been specified. So if scrollbar +# customization is desired it has to be added explicitly. For an example see the +# documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = @@ -1186,9 +1377,22 @@ HTML_EXTRA_STYLESHEET = HTML_EXTRA_FILES = +# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output +# should be rendered with a dark or light theme. +# Possible values are: LIGHT always generates light mode output, DARK always +# generates dark mode output, AUTO_LIGHT automatically sets the mode according +# to the user preference, uses light mode if no preference is set (the default), +# AUTO_DARK automatically sets the mode according to the user preference, uses +# dark mode if no preference is set and TOGGLE allows a user to switch between +# light and dark mode via a button. +# The default value is: AUTO_LIGHT. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE = AUTO_LIGHT + # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a colorwheel, see +# this color. Hue is specified as an angle on a color-wheel, see # https://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. @@ -1198,7 +1402,7 @@ HTML_EXTRA_FILES = HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A +# in the HTML output. For a value of 0 the output will use gray-scales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1216,20 +1420,11 @@ HTML_COLORSTYLE_SAT = 100 HTML_COLORSTYLE_GAMMA = 80 -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = NO - # If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML # documentation will contain a main index with vertical navigation menus that -# are dynamically created via Javascript. If disabled, the navigation index will +# are dynamically created via JavaScript. If disabled, the navigation index will # consists of multiple levels of tabs that are statically embedded in every HTML -# page. Disable this option to support browsers that do not have Javascript, +# page. Disable this option to support browsers that do not have JavaScript, # like the Qt help browser. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1244,6 +1439,33 @@ HTML_DYNAMIC_MENUS = YES HTML_DYNAMIC_SECTIONS = NO +# If the HTML_CODE_FOLDING tag is set to YES then classes and functions can be +# dynamically folded and expanded in the generated HTML source code. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_CODE_FOLDING = YES + +# If the HTML_COPY_CLIPBOARD tag is set to YES then doxygen will show an icon in +# the top right corner of code and text fragments that allows the user to copy +# its content to the clipboard. Note this only works if supported by the browser +# and the web page is served via a secure context (see: +# https://www.w3.org/TR/secure-contexts/), i.e. using the https: or file: +# protocol. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COPY_CLIPBOARD = YES + +# Doxygen stores a couple of settings persistently in the browser (via e.g. +# cookies). By default these settings apply to all HTML pages generated by +# doxygen across all projects. The HTML_PROJECT_COOKIE tag can be used to store +# the settings under a project specific key, such that the user preferences will +# be stored separately. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_PROJECT_COOKIE = + # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to @@ -1259,13 +1481,14 @@ HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: https://developer.apple.com/tools/xcode/), introduced with -# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a -# Makefile in the HTML output directory. Running make will produce the docset in -# that directory and running make install will install the docset in +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See https://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1279,6 +1502,13 @@ GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. @@ -1304,8 +1534,12 @@ DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on -# Windows. +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline the HTML help workshop was already many years +# in maintenance mode). You can download the HTML help workshop from the web +# archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML @@ -1335,7 +1569,7 @@ CHM_FILE = HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the master .chm file (NO). +# (YES) or that it should be included in the main .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. @@ -1362,6 +1596,16 @@ BINARY_TOC = NO TOC_EXPAND = NO +# The SITEMAP_URL tag is used to specify the full URL of the place where the +# generated documentation will be placed on the server by the user during the +# deployment of the documentation. The generated sitemap is called sitemap.xml +# and placed on the directory specified by HTML_OUTPUT. In case no SITEMAP_URL +# is specified no sitemap is generated. For information about the sitemap +# protocol see https://www.sitemaps.org +# This tag requires that the tag GENERATE_HTML is set to YES. + +SITEMAP_URL = + # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help @@ -1380,7 +1624,8 @@ QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace -# (see: http://doc.qt.io/qt-4.8/qthelpproject.html#namespace). +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1388,7 +1633,8 @@ QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: http://doc.qt.io/qt-4.8/qthelpproject.html#virtual-folders). +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1396,28 +1642,30 @@ QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: -# http://doc.qt.io/qt-4.8/qthelpproject.html#filter-attributes). +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = -# The QHG_LOCATION tag can be used to specify the location of Qt's -# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the -# generated .qhp file. +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# run qhelpgenerator on the generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = @@ -1460,16 +1708,28 @@ DISABLE_INDEX = NO # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = NO +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FULL_SIDEBAR = NO + # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # @@ -1494,6 +1754,24 @@ TREEVIEW_WIDTH = 250 EXT_LINKS_IN_WINDOW = NO +# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email +# addresses. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +OBFUSCATE_EMAILS = YES + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML @@ -1503,19 +1781,14 @@ EXT_LINKS_IN_WINDOW = NO FORMULA_FONTSIZE = 10 -# Use the FORMULA_TRANSPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. -FORMULA_TRANSPARENT = YES +FORMULA_MACROFILE = # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# https://www.mathjax.org) which uses client side Javascript for the rendering +# https://www.mathjax.org) which uses client side JavaScript for the rendering # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path @@ -1525,11 +1798,29 @@ FORMULA_TRANSPARENT = YES USE_MATHJAX = NO +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + # When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/latest/output.html) for more details. +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). # Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for MathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. @@ -1542,22 +1833,29 @@ MATHJAX_FORMAT = HTML-CSS # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of -# MathJax from https://www.mathjax.org before deployment. -# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/. +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 # This tag requires that the tag USE_MATHJAX is set to YES. -MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/ +MATHJAX_RELPATH = # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see +# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site -# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. @@ -1585,7 +1883,7 @@ MATHJAX_CODEFILE = SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a web server instead of a web client using Javascript. There +# implemented using a web server instead of a web client using JavaScript. There # are two flavors of web server based searching depending on the EXTERNAL_SEARCH # setting. When disabled, doxygen will generate a PHP script for searching and # an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing @@ -1604,7 +1902,8 @@ SERVER_BASED_SEARCH = NO # # Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: https://xapian.org/). +# Xapian (see: +# https://xapian.org/). # # See the section "External Indexing and Searching" for details. # The default value is: NO. @@ -1617,8 +1916,9 @@ EXTERNAL_SEARCH = NO # # Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: https://xapian.org/). See the section "External Indexing and -# Searching" for details. +# Xapian (see: +# https://xapian.org/). See the section "External Indexing and Searching" for +# details. # This tag requires that the tag SEARCHENGINE is set to YES. SEARCHENGINE_URL = @@ -1656,7 +1956,7 @@ EXTRA_SEARCH_MAPPINGS = # If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. # The default value is: YES. -GENERATE_LATEX = YES +GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of @@ -1669,21 +1969,35 @@ LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. # -# Note that when enabling USE_PDFLATEX this option is only used for generating -# bitmaps for formulas in the HTML output, but not in the Makefile that is -# written to the output directory. -# The default file is: latex. +# Note that when not enabling USE_PDFLATEX the default is latex when enabling +# USE_PDFLATEX the default is pdflatex and when in the later case latex is +# chosen this is overwritten by pdflatex. For specific output languages the +# default can have been set differently, this depends on the implementation of +# the output language. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_CMD_NAME = latex +LATEX_CMD_NAME = # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate # index for LaTeX. +# Note: This tag is used in the Makefile / make.bat. +# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file +# (.tex). # The default file is: makeindex. # This tag requires that the tag GENERATE_LATEX is set to YES. MAKEINDEX_CMD_NAME = makeindex +# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to +# generate index for LaTeX. In case there is no backslash (\) as first character +# it will be automatically added in the LaTeX code. +# Note: This tag is used in the generated output file (.tex). +# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat. +# The default value is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_MAKEINDEX_CMD = makeindex + # If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX # documents. This may be useful for small projects and may help to save some # trees in general. @@ -1713,29 +2027,31 @@ PAPER_TYPE = a4 EXTRA_PACKAGES = -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the -# generated LaTeX document. The header should contain everything until the first -# chapter. If it is left blank doxygen will generate a standard header. See -# section "Doxygen usage" for information on how to let doxygen write the -# default header to a separate file. +# The LATEX_HEADER tag can be used to specify a user-defined LaTeX header for +# the generated LaTeX document. The header should contain everything until the +# first chapter. If it is left blank doxygen will generate a standard header. It +# is highly recommended to start with a default header using +# doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty +# and then modify the file new_header.tex. See also section "Doxygen usage" for +# information on how to generate the default header that doxygen normally uses. # -# Note: Only use a user-defined header if you know what you are doing! The -# following commands have a special meaning inside the header: $title, -# $datetime, $date, $doxygenversion, $projectname, $projectnumber, -# $projectbrief, $projectlogo. Doxygen will replace $title with the empty -# string, for the replacement values of the other commands the user is referred -# to HTML_HEADER. +# Note: Only use a user-defined header if you know what you are doing! +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. The following +# commands have a special meaning inside the header (and footer): For a +# description of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HEADER = -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the -# generated LaTeX document. The footer should contain everything after the last -# chapter. If it is left blank doxygen will generate a standard footer. See +# The LATEX_FOOTER tag can be used to specify a user-defined LaTeX footer for +# the generated LaTeX document. The footer should contain everything after the +# last chapter. If it is left blank doxygen will generate a standard footer. See # LATEX_HEADER for more information on how to generate a default footer and what -# special commands can be used inside the footer. -# -# Note: Only use a user-defined footer if you know what you are doing! +# special commands can be used inside the footer. See also section "Doxygen +# usage" for information on how to generate the default footer that doxygen +# normally uses. Note: Only use a user-defined footer if you know what you are +# doing! # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_FOOTER = @@ -1768,18 +2084,26 @@ LATEX_EXTRA_FILES = PDF_HYPERLINKS = YES -# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate -# the PDF file directly from the LaTeX files. Set this option to YES, to get a -# higher quality PDF documentation. +# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as +# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX +# files. Set this option to YES, to get a higher quality PDF documentation. +# +# See also section LATEX_CMD_NAME for selecting the engine. # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. USE_PDFLATEX = YES -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode -# command to the generated LaTeX files. This will instruct LaTeX to keep running -# if errors occur, instead of asking the user for help. This option is also used -# when generating formulas in HTML. +# The LATEX_BATCHMODE tag signals the behavior of LaTeX in case of an error. +# Possible values are: NO same as ERROR_STOP, YES same as BATCH, BATCH In batch +# mode nothing is printed on the terminal, errors are scrolled as if is +# hit at every error; missing files that TeX tries to input or request from +# keyboard input (\read on a not open input stream) cause the job to abort, +# NON_STOP In nonstop mode the diagnostic message will appear on the terminal, +# but there is no possibility of user interaction just like in batch mode, +# SCROLL In scroll mode, TeX will stop only for missing files to input or if +# keyboard input is necessary and ERROR_STOP In errorstop mode, TeX will stop at +# each error, asking for user intervention. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1792,16 +2116,6 @@ LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO -# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source -# code with syntax highlighting in the LaTeX output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_SOURCE_CODE = NO - # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. See # https://en.wikipedia.org/wiki/BibTeX and \cite for more info. @@ -1810,13 +2124,13 @@ LATEX_SOURCE_CODE = NO LATEX_BIB_STYLE = plain -# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated -# page will contain the date and time when the page was generated. Setting this -# to NO can help when comparing the output of multiple runs. -# The default value is: NO. +# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) +# path from which the emoji images will be read. If a relative path is entered, +# it will be relative to the LATEX_OUTPUT directory. If left blank the +# LATEX_OUTPUT directory will be used. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_TIMESTAMP = NO +LATEX_EMOJI_DIRECTORY = #--------------------------------------------------------------------------- # Configuration options related to the RTF output @@ -1857,9 +2171,9 @@ COMPACT_RTF = NO RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's config -# file, i.e. a series of assignments. You only have to provide replacements, -# missing definitions are set to their default value. +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# configuration file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. # # See also section "Doxygen usage" for information on how to generate the # default style sheet that doxygen normally uses. @@ -1868,21 +2182,19 @@ RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an RTF document. Syntax is -# similar to doxygen's config file. A template extensions file can be generated -# using doxygen -e rtf extensionFile. +# similar to doxygen's configuration file. A template extensions file can be +# generated using doxygen -e rtf extensionFile. # This tag requires that the tag GENERATE_RTF is set to YES. RTF_EXTENSIONS_FILE = -# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code -# with syntax highlighting in the RTF output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. +# The RTF_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the RTF_OUTPUT output directory. +# Note that the files will be copied as-is; there are no commands or markers +# available. # This tag requires that the tag GENERATE_RTF is set to YES. -RTF_SOURCE_CODE = NO +RTF_EXTRA_FILES = #--------------------------------------------------------------------------- # Configuration options related to the man page output @@ -1955,6 +2267,13 @@ XML_OUTPUT = xml XML_PROGRAMLISTING = YES +# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include +# namespace members in file scope as well, matching the HTML output. +# The default value is: NO. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_NS_MEMB_FILE_SCOPE = NO + #--------------------------------------------------------------------------- # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- @@ -1973,27 +2292,44 @@ GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook -# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the -# program listings (including syntax highlighting and cross-referencing -# information) to the DOCBOOK output. Note that enabling this will significantly -# increase the size of the DOCBOOK output. -# The default value is: NO. -# This tag requires that the tag GENERATE_DOCBOOK is set to YES. - -DOCBOOK_PROGRAMLISTING = NO - #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an -# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures +# AutoGen Definitions (see https://autogen.sourceforge.net/) file that captures # the structure of the code including all documentation. Note that this feature # is still experimental and incomplete at the moment. # The default value is: NO. GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# Configuration options related to Sqlite3 output +#--------------------------------------------------------------------------- + +# If the GENERATE_SQLITE3 tag is set to YES doxygen will generate a Sqlite3 +# database with symbols found by doxygen stored in tables. +# The default value is: NO. + +GENERATE_SQLITE3 = NO + +# The SQLITE3_OUTPUT tag is used to specify where the Sqlite3 database will be +# put. If a relative path is entered the value of OUTPUT_DIRECTORY will be put +# in front of it. +# The default directory is: sqlite3. +# This tag requires that the tag GENERATE_SQLITE3 is set to YES. + +SQLITE3_OUTPUT = sqlite3 + +# The SQLITE3_RECREATE_DB tag is set to YES, the existing doxygen_sqlite3.db +# database file will be recreated with each doxygen run. If set to NO, doxygen +# will warn if a database file is already found and not modify it. +# The default value is: YES. +# This tag requires that the tag GENERATE_SQLITE3 is set to YES. + +SQLITE3_RECREATE_DB = YES + #--------------------------------------------------------------------------- # Configuration options related to the Perl module output #--------------------------------------------------------------------------- @@ -2049,7 +2385,7 @@ ENABLE_PREPROCESSING = YES # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -MACRO_EXPANSION = YES +MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then # the macro expansion is limited to the macros specified with the PREDEFINED and @@ -2068,7 +2404,8 @@ SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by the -# preprocessor. +# preprocessor. Note that the INCLUDE_PATH is not recursive, so the setting of +# RECURSIVE has no effect here. # This tag requires that the tag SEARCH_INCLUDES is set to YES. INCLUDE_PATH = @@ -2089,7 +2426,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = DLLExport= +PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The @@ -2135,15 +2472,15 @@ TAGFILES = GENERATE_TAGFILE = -# If the ALLEXTERNALS tag is set to YES, all external class will be listed in -# the class index. If set to NO, only the inherited external classes will be -# listed. +# If the ALLEXTERNALS tag is set to YES, all external classes and namespaces +# will be listed in the class and namespace index. If set to NO, only the +# inherited external classes will be listed. # The default value is: NO. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will be +# in the topic index. If set to NO, only the current project's groups will be # listed. # The default value is: YES. @@ -2156,41 +2493,10 @@ EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of 'which perl'). -# The default file (with absolute path) is: /usr/bin/perl. - -PERL_PATH = /usr/bin/perl - #--------------------------------------------------------------------------- -# Configuration options related to the dot tool +# Configuration options related to diagram generator tools #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram -# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to -# NO turns the diagrams off. Note that this option also works with HAVE_DOT -# disabled, but it is recommended to install and use dot, since it yields more -# powerful graphs. -# The default value is: YES. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see: -# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# You can include diagrams made with dia in doxygen documentation. Doxygen will -# then run dia to produce the diagram and insert it in the documentation. The -# DIA_PATH tag allows you to specify the directory where the dia binary resides. -# If left empty dia is assumed to be found in the default search path. - -DIA_PATH = - # If set to YES the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. # The default value is: YES. @@ -2199,7 +2505,7 @@ HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz (see: -# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent +# https://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent # Bell Labs. The other options in this section have no effect if this option is # set to NO # The default value is: NO. @@ -2216,49 +2522,77 @@ HAVE_DOT = NO DOT_NUM_THREADS = 0 -# When you want a differently looking font in the dot files that doxygen -# generates you can specify the font name using DOT_FONTNAME. You need to make -# sure dot is able to find the font, which can be done by putting it in a -# standard location or by setting the DOTFONTPATH environment variable or by -# setting DOT_FONTPATH to the directory containing the font. -# The default value is: Helvetica. +# DOT_COMMON_ATTR is common attributes for nodes, edges and labels of +# subgraphs. When you want a differently looking font in the dot files that +# doxygen generates you can specify fontname, fontcolor and fontsize attributes. +# For details please see Node, +# Edge and Graph Attributes specification You need to make sure dot is able +# to find the font, which can be done by putting it in a standard location or by +# setting the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. Default graphviz fontsize is 14. +# The default value is: fontname=Helvetica,fontsize=10. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTNAME = Helvetica +DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10" -# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of -# dot graphs. -# Minimum value: 4, maximum value: 24, default value: 10. +# DOT_EDGE_ATTR is concatenated with DOT_COMMON_ATTR. For elegant style you can +# add 'arrowhead=open, arrowtail=open, arrowsize=0.5'. Complete documentation about +# arrows shapes. +# The default value is: labelfontname=Helvetica,labelfontsize=10. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTSIZE = 10 +DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10" -# By default doxygen will tell dot to use the default font as specified with -# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set -# the path where dot can find it using this tag. +# DOT_NODE_ATTR is concatenated with DOT_COMMON_ATTR. For view without boxes +# around nodes set 'shape=plain' or 'shape=plaintext' Shapes specification +# The default value is: shape=box,height=0.2,width=0.4. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4" + +# You can set the path where dot can find font specified with fontname in +# DOT_COMMON_ATTR and others dot attributes. # This tag requires that the tag HAVE_DOT is set to YES. DOT_FONTPATH = -# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for -# each documented class showing the direct and indirect inheritance relations. -# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. +# If the CLASS_GRAPH tag is set to YES or GRAPH or BUILTIN then doxygen will +# generate a graph for each documented class showing the direct and indirect +# inheritance relations. In case the CLASS_GRAPH tag is set to YES or GRAPH and +# HAVE_DOT is enabled as well, then dot will be used to draw the graph. In case +# the CLASS_GRAPH tag is set to YES and HAVE_DOT is disabled or if the +# CLASS_GRAPH tag is set to BUILTIN, then the built-in generator will be used. +# If the CLASS_GRAPH tag is set to TEXT the direct and indirect inheritance +# relations will be shown as texts / links. Explicit enabling an inheritance +# graph or choosing a different representation for an inheritance graph of a +# specific class, can be accomplished by means of the command \inheritancegraph. +# Disabling an inheritance graph can be accomplished by means of the command +# \hideinheritancegraph. +# Possible values are: NO, YES, TEXT, GRAPH and BUILTIN. # The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a # graph for each documented class showing the direct and indirect implementation # dependencies (inheritance, containment, and class references variables) of the -# class with other documented classes. +# class with other documented classes. Explicit enabling a collaboration graph, +# when COLLABORATION_GRAPH is set to NO, can be accomplished by means of the +# command \collaborationgraph. Disabling a collaboration graph can be +# accomplished by means of the command \hidecollaborationgraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for -# groups, showing the direct groups dependencies. +# groups, showing the direct groups dependencies. Explicit enabling a group +# dependency graph, when GROUP_GRAPHS is set to NO, can be accomplished by means +# of the command \groupgraph. Disabling a directory graph can be accomplished by +# means of the command \hidegroupgraph. See also the chapter Grouping in the +# manual. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2281,10 +2615,32 @@ UML_LOOK = NO # but if the number exceeds 15, the total amount of fields shown is limited to # 10. # Minimum value: 0, maximum value: 100, default value: 10. -# This tag requires that the tag HAVE_DOT is set to YES. +# This tag requires that the tag UML_LOOK is set to YES. UML_LIMIT_NUM_FIELDS = 10 +# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and +# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS +# tag is set to YES, doxygen will add type and arguments for attributes and +# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen +# will not generate fields with class member information in the UML graphs. The +# class diagrams will look similar to the default class diagrams but using UML +# notation for the relationships. +# Possible values are: NO, YES and NONE. +# The default value is: NO. +# This tag requires that the tag UML_LOOK is set to YES. + +DOT_UML_DETAILS = NO + +# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters +# to display on a single line. If the actual line length exceeds this threshold +# significantly it will be wrapped across multiple lines. Some heuristics are +# applied to avoid ugly line breaks. +# Minimum value: 0, maximum value: 1000, default value: 17. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_WRAP_THRESHOLD = 17 + # If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and # collaboration graphs will show the relations between templates and their # instances. @@ -2296,7 +2652,9 @@ TEMPLATE_RELATIONS = NO # If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to # YES then doxygen will generate a graph for each documented file showing the # direct and indirect include dependencies of the file with other documented -# files. +# files. Explicit enabling an include graph, when INCLUDE_GRAPH is is set to NO, +# can be accomplished by means of the command \includegraph. Disabling an +# include graph can be accomplished by means of the command \hideincludegraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2305,7 +2663,10 @@ INCLUDE_GRAPH = YES # If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are # set to YES then doxygen will generate a graph for each documented file showing # the direct and indirect include dependencies of the file with other documented -# files. +# files. Explicit enabling an included by graph, when INCLUDED_BY_GRAPH is set +# to NO, can be accomplished by means of the command \includedbygraph. Disabling +# an included by graph can be accomplished by means of the command +# \hideincludedbygraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2345,16 +2706,26 @@ GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the # dependencies a directory has on other directories in a graphical way. The # dependency relations are determined by the #include relations between the -# files in the directories. +# files in the directories. Explicit enabling a directory graph, when +# DIRECTORY_GRAPH is set to NO, can be accomplished by means of the command +# \directorygraph. Disabling a directory graph can be accomplished by means of +# the command \hidedirectorygraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. DIRECTORY_GRAPH = YES +# The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels +# of child directories generated in directory dependency graphs by dot. +# Minimum value: 1, maximum value: 25, default value: 1. +# This tag requires that the tag DIRECTORY_GRAPH is set to YES. + +DIR_GRAPH_MAX_DEPTH = 1 + # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. For an explanation of the image formats see the section # output formats in the documentation of the dot tool (Graphviz (see: -# http://www.graphviz.org/)). +# https://www.graphviz.org/)). # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). @@ -2391,11 +2762,12 @@ DOT_PATH = DOTFILE_DIRS = -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the \mscfile -# command). +# You can include diagrams made with dia in doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. -MSCFILE_DIRS = +DIA_PATH = # The DIAFILE_DIRS tag can be used to specify one or more directories that # contain dia files that are included in the documentation (see the \diafile @@ -2404,10 +2776,10 @@ MSCFILE_DIRS = DIAFILE_DIRS = # When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the -# path where java can find the plantuml.jar file. If left blank, it is assumed -# PlantUML is not used or called during a preprocessing step. Doxygen will -# generate a warning when it encounters a \startuml command in this case and -# will not generate output for the diagram. +# path where java can find the plantuml.jar file or to the filename of jar file +# to be used. If left blank, it is assumed PlantUML is not used or called during +# a preprocessing step. Doxygen will generate a warning when it encounters a +# \startuml command in this case and will not generate output for the diagram. PLANTUML_JAR_PATH = @@ -2424,7 +2796,7 @@ PLANTUML_INCLUDE_PATH = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes # that will be shown in the graph. If the number of nodes in a graph becomes # larger than this value, doxygen will truncate the graph, which is visualized -# by representing a node as a red box. Note that doxygen if the number of direct +# by representing a node as a red box. Note that if the number of direct # children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that # the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. @@ -2445,18 +2817,6 @@ DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not seem -# to support this out of the box. -# -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_TRANSPARENT = NO - # Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) support @@ -2469,14 +2829,34 @@ DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page # explaining the meaning of the various boxes and arrows in the dot generated # graphs. +# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal +# graphical representation for inheritance and collaboration diagrams is used. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate # files that are used to generate the various graphs. +# +# Note: This setting is not only used for dot files but also for msc temporary +# files. # The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. DOT_CLEANUP = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. If the MSCGEN_TOOL tag is left empty (the default), then doxygen will +# use a built-in version of mscgen tool to produce the charts. Alternatively, +# the MSCGEN_TOOL tag can also specify the name an external tool. For instance, +# specifying prog as the value, doxygen will call the tool as prog -T +# -o . The external tool should support +# output file formats "png", "eps", "svg", and "ismap". + +MSCGEN_TOOL = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the \mscfile +# command). + +MSCFILE_DIRS = diff --git a/docs/icsneoc/api.rst b/docs/icsneoc/api.rst new file mode 100644 index 0000000..7e6fae9 --- /dev/null +++ b/docs/icsneoc/api.rst @@ -0,0 +1,14 @@ +===== +C API +===== + +.. doxygenfile:: icsneoc.h + :project: icsneoc +.. doxygenfile:: device/neodevice.h + :project: icsneoc +.. doxygenfile:: communication/message/neomessage.h + :project: icsneoc +.. doxygenfile:: api/version.h + :project: icsneoc +.. doxygenfile:: api/event.h + :project: icsneoc diff --git a/docs/icsneoc/examples.rst b/docs/icsneoc/examples.rst new file mode 100644 index 0000000..b94a0e9 --- /dev/null +++ b/docs/icsneoc/examples.rst @@ -0,0 +1,43 @@ +========== +C Examples +========== + +A variety of examples can be found within ``examples/c``, see below for an +example that uses the polling API to receive CAN frames. + +.. code-block:: c + + size_t deviceCount = 10; // Pre-set to the size of your buffer before the icsneo_findAllDevices() call + neodevice_t devices[10]; + icsneo_findAllDevices(devices, &deviceCount); + printf("We found %ull devices\n", deviceCount); + for(size_t i = 0; i < deviceCount; i++) { + neodevice_t* myDevice = &devices[i]; + char desc[ICSNEO_DEVICETYPE_LONGEST_DESCRIPTION]; + size_t sz = ICSNEO_DEVICETYPE_LONGEST_DESCRIPTION; + icsneo_describeDevice(myDevice, desc, &sz); + printf("Found %s\n", desc); // "Found neoVI FIRE 2 CY2345" + } + neodevice_t* myDevice = &devices[0]; + if(!icsneo_openDevice(myDevice)) { + neoevent_t error; + if(icsneo_getLastError(&error)) + printf("Error! %s\n", error.description); + } + icsneo_goOnline(myDevice); // Start receiving messages + icsneo_enableMessagePolling(myDevice); // Allow the use of icsneo_getMessages() later + sleep(5); + neomessage_t messages[50]; + size_t messageCount = 50; + icsneo_getMessages(myDevice, messages, &messageCount, 0 /* non-blocking */); + printf("We got %ull messages!\n", messageCount); + for(size_t i = 0; i < messageCount; i++) { + if(messages[i].type == ICSNEO_NETWORK_TYPE_CAN) { + // A message of type CAN should be interperated a neomessage_can_t, so we can cast safely + neomessage_can_t* canmsg = (neomessage_can_t*)&messages[i]; + // canmsg->arbid is valid here + // canmsg->data is an uint8_t*, you can check canmsg->length for the length of the payload + // canmsg->timestamp is the time recorded by the hardware in nanoseconds since (1/1/2007 12:00:00 GMT) + } + } + icsneo_closeDevice(myDevice); \ No newline at end of file diff --git a/docs/icsneoc/index.rst b/docs/icsneoc/index.rst new file mode 100644 index 0000000..4e028a5 --- /dev/null +++ b/docs/icsneoc/index.rst @@ -0,0 +1,9 @@ +icsneoc +======= + +.. toctree:: + :maxdepth: 2 + + installation + examples + api diff --git a/docs/icsneoc/installation.rst b/docs/icsneoc/installation.rst new file mode 100644 index 0000000..69eda1b --- /dev/null +++ b/docs/icsneoc/installation.rst @@ -0,0 +1,7 @@ +============ +Installation +============ + +The installation steps for the C API are the same as the C++ API as the C API is +a wrapper for the C++ library. The ``LIBICSNEO_BUILD_ICSNEOC`` CMake option is +default ``ON`` but note that the C API depends on this flag to build. diff --git a/docs/icsneocpp.rst b/docs/icsneocpp.rst deleted file mode 100644 index 9eb52cf..0000000 --- a/docs/icsneocpp.rst +++ /dev/null @@ -1,31 +0,0 @@ -************************ -**C++ API** (icsneocpp) -************************ - -.. Usage -.. ====== - -.. Finding Devices -.. ~~~~~~~~~~~~~~~~ -.. Finding a device is simple - -.. Connecting to Devices -.. ~~~~~~~~~~~~~~~~~~~~~~ - -Reference -========== - -.. Classes -.. ~~~~~~~~ - -.. Structures -.. ~~~~~~~~~~~ - -.. Functions -.. ~~~~~~~~~~ - -.. doxygennamespace:: icsneo - -.. doxygenclass:: icsneo::Device - :members: - :undoc-members: diff --git a/docs/icsneocpp/Doxyfile b/docs/icsneocpp/Doxyfile new file mode 100644 index 0000000..589035f --- /dev/null +++ b/docs/icsneocpp/Doxyfile @@ -0,0 +1,2862 @@ +# Doxyfile 1.11.0 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables or CMake type +# replacement variables: +# doxygen -x_noenv [configFile] + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "icsneocpp" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# With the PROJECT_ICON tag one can specify an icon that is included in the tabs +# when the HTML document is shown. Doxygen will copy the logo to the output +# directory. + +PROJECT_ICON = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = docs/icsneocpp/doxygen + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 +# sub-directories (in 2 levels) under the output directory of each output format +# and will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# control the number of sub-directories. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# Controls the number of sub-directories that will be created when +# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every +# level increment doubles the number of directories, resulting in 4096 +# directories at level 8 which is the default and also the maximum value. The +# sub-directories are organized in 2 levels, the first level always has a fixed +# number of 16 directories. +# Minimum value: 0, maximum value: 8, default value: 8. +# This tag requires that the tag CREATE_SUBDIRS is set to YES. + +CREATE_SUBDIRS_LEVEL = 8 + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, +# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English +# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, +# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with +# English messages), Korean, Korean-en (Korean with English messages), Latvian, +# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, +# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, +# Swedish, Turkish, Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# By default Python docstrings are displayed as preformatted text and doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:^^" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 6. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 6 + +# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to +# generate identifiers for the Markdown headings. Note: Every identifier is +# unique. +# Possible values are: DOXYGEN use a fixed 'autotoc_md' string followed by a +# sequence number starting at 0 and GITHUB use the lower case version of title +# with any whitespace replaced by '-' and punctuation characters removed. +# The default value is: DOXYGEN. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +MARKDOWN_ID_STYLE = DOXYGEN + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also makes the inheritance and +# collaboration diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = YES + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software) sources only. Doxygen will parse +# them like normal C++ but will assume all classes use public instead of private +# inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use +# during processing. When set to 0 doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which effectively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + +# If the TIMESTAMP tag is set different from NO then each generated page will +# contain the date or date and time when the page was generated. Setting this to +# NO can help when comparing the output of multiple runs. +# Possible values are: YES, NO, DATETIME and DATE. +# The default value is: NO. + +TIMESTAMP = NO + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# will also hide undocumented C++ concepts if enabled. This option has no effect +# if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# declarations. If set to NO, these declarations will be included in the +# documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and MacOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# Possible values are: SYSTEM, NO and YES. +# The default value is: SYSTEM. + +CASE_SENSE_NAMES = SYSTEM + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete +# function parameter documentation. If set to NO, doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about +# undocumented enumeration values. If set to NO, doxygen will accept +# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: NO. + +WARN_IF_UNDOC_ENUM_VAL = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the doxygen process doxygen will return with a non-zero status. +# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then doxygen behaves +# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined doxygen will not +# write the warning messages in between other messages but write them at the end +# of a run, in case a WARN_LOGFILE is defined the warning messages will be +# besides being in the defined file also be shown at the end of a run, unless +# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case +# the behavior will remain as with the setting FAIL_ON_WARNINGS. +# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# See also: WARN_LINE_FORMAT +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# In the $text part of the WARN_FORMAT command it is possible that a reference +# to a more specific place is given. To make it easier to jump to this place +# (outside of doxygen) the user can define a custom "cut" / "paste" string. +# Example: +# WARN_LINE_FORMAT = "'vi $file +$line'" +# See also: WARN_FORMAT +# The default value is: at line $line of file $file. + +WARN_LINE_FORMAT = "at line $line of file $file" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = include + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# See also: INPUT_FILE_ENCODING +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify +# character encoding on a per file pattern basis. Doxygen will compare the file +# name with each pattern and apply the encoding instead of the default +# INPUT_ENCODING) if there is a match. The character encodings are a list of the +# form: pattern=encoding (like *.php=ISO-8859-1). +# See also: INPUT_ENCODING for further information on supported encodings. + +INPUT_FILE_ENCODING = + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cxxm, +# *.cpp, *.cppm, *.ccm, *.c++, *.c++m, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, +# *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, *.h++, *.ixx, *.l, *.cs, *.d, +# *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to +# be provided as doxygen C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f18, *.f, *.for, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cxxm \ + *.cpp \ + *.cppm \ + *.ccm \ + *.c++ \ + *.c++m \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.ixx \ + *.l \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f18 \ + *.f \ + *.for \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf \ + *.ice + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = */third-party/* + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# ANamespace::AClass, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that doxygen will use the data processed and written to standard output +# for further processing, therefore nothing else, like debug statements or used +# commands (so in case of a Windows batch file always use @echo OFF), should be +# written to standard output. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +# The Fortran standard specifies that for fixed formatted Fortran code all +# characters from position 72 are to be considered as comment. A common +# extension is to allow longer lines before the automatic comment starts. The +# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can +# be processed before the automatic comment starts. +# Minimum value: 7, maximum value: 10000, default value: 72. + +FORTRAN_COMMENT_AFTER = 72 + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# multi-line macros, enums or list initialized variables directly into the +# documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes) +# that should be ignored while generating the index headers. The IGNORE_PREFIX +# tag works for classes, function and member names. The entity will be placed in +# the alphabetical list under the first letter of the entity name that remains +# after removing the prefix. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# Note: Since the styling of scrollbars can currently not be overruled in +# Webkit/Chromium, the styling will be left out of the default doxygen.css if +# one or more extra stylesheets have been specified. So if scrollbar +# customization is desired it has to be added explicitly. For an example see the +# documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output +# should be rendered with a dark or light theme. +# Possible values are: LIGHT always generates light mode output, DARK always +# generates dark mode output, AUTO_LIGHT automatically sets the mode according +# to the user preference, uses light mode if no preference is set (the default), +# AUTO_DARK automatically sets the mode according to the user preference, uses +# dark mode if no preference is set and TOGGLE allows a user to switch between +# light and dark mode via a button. +# The default value is: AUTO_LIGHT. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE = AUTO_LIGHT + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a color-wheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use gray-scales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# If the HTML_CODE_FOLDING tag is set to YES then classes and functions can be +# dynamically folded and expanded in the generated HTML source code. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_CODE_FOLDING = YES + +# If the HTML_COPY_CLIPBOARD tag is set to YES then doxygen will show an icon in +# the top right corner of code and text fragments that allows the user to copy +# its content to the clipboard. Note this only works if supported by the browser +# and the web page is served via a secure context (see: +# https://www.w3.org/TR/secure-contexts/), i.e. using the https: or file: +# protocol. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COPY_CLIPBOARD = YES + +# Doxygen stores a couple of settings persistently in the browser (via e.g. +# cookies). By default these settings apply to all HTML pages generated by +# doxygen across all projects. The HTML_PROJECT_COOKIE tag can be used to store +# the settings under a project specific key, such that the user preferences will +# be stored separately. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_PROJECT_COOKIE = + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline the HTML help workshop was already many years +# in maintenance mode). You can download the HTML help workshop from the web +# archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the main .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# The SITEMAP_URL tag is used to specify the full URL of the place where the +# generated documentation will be placed on the server by the user during the +# deployment of the documentation. The generated sitemap is called sitemap.xml +# and placed on the directory specified by HTML_OUTPUT. In case no SITEMAP_URL +# is specified no sitemap is generated. For information about the sitemap +# protocol see https://www.sitemaps.org +# This tag requires that the tag GENERATE_HTML is set to YES. + +SITEMAP_URL = + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# run qhelpgenerator on the generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FULL_SIDEBAR = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email +# addresses. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +OBFUSCATE_EMAILS = YES + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. + +FORMULA_MACROFILE = + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side JavaScript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for MathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see +# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /