Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/Networking/MulticastDiscovery/fgmc_protocol.cpp')
-rw-r--r--src/Networking/MulticastDiscovery/fgmc_protocol.cpp497
1 files changed, 497 insertions, 0 deletions
diff --git a/src/Networking/MulticastDiscovery/fgmc_protocol.cpp b/src/Networking/MulticastDiscovery/fgmc_protocol.cpp
new file mode 100644
index 00000000..34d8e397
--- /dev/null
+++ b/src/Networking/MulticastDiscovery/fgmc_protocol.cpp
@@ -0,0 +1,497 @@
+// Implementation of MulticastDiscovery protocol
+
+#include "fgmc_protocol.h"
+
+#if SUPPORT_MULTICAST_DISCOVERY
+
+#include <Platform/RepRap.h>
+#include <Platform/Platform.h>
+#include <Networking/Network.h>
+#include <Networking/MulticastDiscovery/MulticastResponder.h>
+#include <CAN/CanInterface.h>
+#include <Version.h>
+#include <cstring>
+
+constexpr const char *NetworkConfigOverrideFileName = "network-override.g";
+
+// Disable gcc warning about strncpy not being able to include a terminating null.
+// We don't need a terminating null when filling in response fields (if we did then we would use SafeStrcpy instead).
+#pragma GCC diagnostic ignored "-Wstringop-truncation"
+
+FGMCProtocol::FGMCProtocol() noexcept
+ : iface_id_(0),
+ fgmc_device_id_(FGMCHwTypeId::FGMC_DEVICE_ID_ZERO),
+ fgmc_application_type_(0),
+ tx_netbuf_{0}
+{
+}
+
+// Build a unique ID from the MAC address
+void FGMCProtocol::macToString(uint32_t interface) noexcept
+{
+ InterfaceData& ifData = ifaceData[interface];
+
+ for (uint32_t i = 0; i < SIZE_FGMC_DEST_ID; i++)
+ {
+ ifData.unique_id_[i] = '\0';
+ }
+
+ const MacAddress& macAddress = reprap.GetNetwork().GetMacAddress(interface);
+ for (uint32_t i = 0; i < 6; i++)
+ {
+ const uint8_t byte = macAddress.bytes[i];
+ uint8_t lowValue = (byte & 0x0Fu);
+ if (lowValue < 0xA)
+ {
+ lowValue = lowValue + 48;
+ }
+ else
+ {
+ lowValue = lowValue + 55;
+ }
+
+ uint8_t highValue = (byte >> 4u) & 0x0Fu;
+ if (highValue < 0xA)
+ {
+ highValue = highValue + 48;
+ }
+ else
+ {
+ highValue = highValue + 55;
+ }
+ ifData.unique_id_[i * 2] = static_cast<char>(lowValue);
+ ifData.unique_id_[(i * 2) + 1] = static_cast<char>(highValue);
+ }
+}
+
+void FGMCProtocol::init() noexcept
+{
+#if 0
+
+ // check eeprom values available
+ if ((eeprom_noc_code_[0] == '\0')) { // || (eeprom_product_key_[0] == '\0')
+ // EEPROMs not described
+ eeprom_product_key_[0] = '1';
+ eeprom_product_key_[1] = '\0';
+ (void)memcpy(&eeprom_noc_code_[0], &INVALID_EEPROM_DATA_STRING, INVALID_EEPROM_DATA_STRING_LEN);
+ (void)memcpy(&deviceName[0], &INVALID_EEPROM_DATA_STRING, INVALID_EEPROM_DATA_STRING_LEN);
+ }
+
+#endif
+
+ for (uint32_t i = 0; i < IP_MAX_IFACES; i++)
+ {
+ macToString(i);
+ ifaceData[i].configuredIpAddress = reprap.GetNetwork().GetIPAddress(i);
+ ifaceData[i].configuredNetmask = reprap.GetNetwork().GetNetmask(i);
+ ifaceData[i].configuredGateway = reprap.GetNetwork().GetGateway(i);
+ }
+
+ fgmc_device_id_ = FGMCHwTypeId::FGMC_DEVICE_ID_DUET3;
+}
+
+void FGMCProtocol::handleStream(unsigned int iFaceId, uint8_t* inputBufferAddress, uint32_t rxLength) noexcept
+{
+ // backup sciopta connection handle
+ // if a null pointer received => plattform should execute a exception
+ this->iface_id_ = iFaceId;
+
+ if (rxLength >= static_cast<uint32_t>(sizeof(FGMC_GenericHeader)))
+ {
+ FGMC_GenericHeader* const pInGenericHeader = reinterpret_cast<FGMC_GenericHeader*>(inputBufferAddress);
+
+ // read incoming packetid
+ const uint32_t packetId = pInGenericHeader->fgmc_packet_id_;
+ InterfaceData& ifData = ifaceData[iface_id_];
+ if (!ifData.insertPacketId(packetId))
+ {
+ return;
+ }
+
+ switch (pInGenericHeader->fgmc_command_)
+ {
+ case FGMCCommand::MCD_COMMAND_UNETINF:
+ if (pInGenericHeader->fgmc_destination_id_[0] == '\0')
+ {
+ // fgmc command: upload network information
+ cmdUnetinf(packetId);
+ }
+ break;
+
+ case FGMCCommand::MCD_COMMAND_DNETINF:
+ if (strncmp(pInGenericHeader->fgmc_destination_id_, ifData.unique_id_, SIZE_FGMC_DEST_ID) == 0)
+ {
+ // fgmc command: download network information
+ FGMC_ReqDownloadNetInfoHeader* const pInCmdPointer =
+ reinterpret_cast<FGMC_ReqDownloadNetInfoHeader*>(reinterpret_cast<uint32_t>(inputBufferAddress) + static_cast<uint32_t>(sizeof(FGMC_GenericHeader)));
+ cmdDnetinf(pInCmdPointer, packetId);
+ }
+ break;
+
+ case FGMCCommand::MCD_COMMAND_REBOOT:
+ if (strncmp(pInGenericHeader->fgmc_destination_id_, ifData.unique_id_, SIZE_FGMC_DEST_ID) == 0)
+ {
+ // fgmc command: reboot
+ cmdReboot(packetId);
+ }
+ break;
+
+ case FGMCCommand::MCD_COMMAND_IDENTIFY:
+ if (strncmp(pInGenericHeader->fgmc_destination_id_, ifData.unique_id_, SIZE_FGMC_DEST_ID) == 0)
+ {
+ // fgmc command: identify
+ FGMC_ReqIdentify* pInCmdPointer =
+ reinterpret_cast<FGMC_ReqIdentify*>(reinterpret_cast<uint32_t>(inputBufferAddress) + static_cast<uint32_t>(sizeof(FGMC_GenericHeader)));
+ cmdIdentify(pInCmdPointer, packetId);
+ }
+ break;
+
+ case FGMCCommand::MCD_COMMAND_GET_FIRMWARE_VERSION:
+ if (strncmp(pInGenericHeader->fgmc_destination_id_, ifData.unique_id_, SIZE_FGMC_DEST_ID) == 0)
+ {
+ // fgmc command: get firmware version
+ cmdGetFirmwareVersion(packetId);
+ }
+ break;
+
+ case FGMCCommand::MCD_COMMAND_GET_SUPPORTED_COMMANDS:
+ if (strncmp(pInGenericHeader->fgmc_destination_id_, ifData.unique_id_, SIZE_FGMC_DEST_ID) == 0)
+ {
+ // fgmc command: get supported commands
+ cmdGetSupportedCommands(packetId);
+ }
+ break;
+
+ default:
+ // unknown command will be skipped
+ break;
+ }
+ }
+}
+
+void FGMCProtocol::sendGenericHeader(uint8_t* tx_netbuf, FGMCCommand cmd, uint32_t length, uint32_t packetId, uint32_t segmentIndex, uint32_t segmentCount) noexcept
+{
+ FGMC_GenericHeader* pOutGenericHeader = reinterpret_cast<FGMC_GenericHeader*>(tx_netbuf);
+
+ //-----------------------------------------------------------------------------------
+ // Generic Multicast Header
+ //-----------------------------------------------------------------------------------
+ memcpy(pOutGenericHeader->fgmc_name_, FGMC_NAME, SIZE_FGMC_NAME);
+ pOutGenericHeader->fgmc_length_ = length;
+ pOutGenericHeader->fgmc_hw_type_id_ = fgmc_device_id_;
+ // device unique fgmc destination id
+ strncpy(pOutGenericHeader->fgmc_destination_id_, ifaceData[iface_id_].unique_id_, SIZE_FGMC_DEST_ID);
+ pOutGenericHeader->fgmc_packet_id_ = packetId + 1;
+ pOutGenericHeader->fgmc_segment_index_ = segmentIndex;
+ pOutGenericHeader->fgmc_segment_count_ = segmentCount;
+ pOutGenericHeader->fgmc_command_ = cmd;
+ pOutGenericHeader->fgmc_command_version_ = FGMCCommandVersion::MCD_COMMAND_VERSION;
+ pOutGenericHeader->fgmc_error_code_ = FGMCErrorCode::FGMC_ERROR_CODE_NORMAL;
+
+ // Send Message
+ (void)ifaceData[iface_id_].insertPacketId(pOutGenericHeader->fgmc_packet_id_);
+
+ MulticastResponder::SendResponse(tx_netbuf, length);
+}
+
+void FGMCProtocol::cmdUnetinf(uint32_t inPacketId) noexcept
+{
+ FGMC_ResUploadNetInfoHeader* pOutCmdHeader = reinterpret_cast<FGMC_ResUploadNetInfoHeader*>(tx_netbuf_);
+ (void)memset(pOutCmdHeader, 0x00, sizeof(FGMC_ResUploadNetInfoHeader));
+
+ //-----------------------------------------------------------------------------------
+ // The Upload Netinformation Structure
+ //-----------------------------------------------------------------------------------
+
+ // ip address type
+ const bool dhcpEnable = reprap.GetNetwork().UsingDhcp(iface_id_);
+ if (dhcpEnable)
+ {
+ // dynamic
+ pOutCmdHeader->fgmc_ip_address_type_ = 1;
+ }
+ else
+ {
+ // static
+ pOutCmdHeader->fgmc_ip_address_type_ = 0;
+ }
+
+ // mac address
+ const MacAddress& macAddress = reprap.GetNetwork().GetMacAddress(iface_id_);
+ memcpy(pOutCmdHeader->fgmc_mac_address_, macAddress.bytes, 6);
+
+ // IPv4
+ const InterfaceData& ifData = ifaceData[iface_id_];
+ const uint32_t ipaddress = ifData.configuredIpAddress.GetV4LittleEndian();
+ (void)memcpy(&pOutCmdHeader->fgmc_ip_v4_static_address_[0], &ipaddress, SIZE_IP_V4);
+
+ const uint32_t subnetmask = ifData.configuredNetmask.GetV4LittleEndian();
+ (void)memcpy(&pOutCmdHeader->fgmc_ip_v4_static_netmask_[0], &subnetmask, SIZE_IP_V4);
+
+ const uint32_t gateway = ifData.configuredGateway.GetV4LittleEndian();
+ (void)memcpy(&pOutCmdHeader->fgmc_ip_v4_static_gateway_[0], &gateway, SIZE_IP_V4);
+
+ pOutCmdHeader->fgmc_ip_v4_static_dns_[0] = 0;
+ pOutCmdHeader->fgmc_ip_v4_static_dns_[1] = 0;
+ pOutCmdHeader->fgmc_ip_v4_static_dns_[2] = 0;
+ pOutCmdHeader->fgmc_ip_v4_static_dns_[3] = 0;
+
+ // IPv6
+ (void)memset(&pOutCmdHeader->fgmc_ip_v6_static_6_addr_[0], 0x00, SIZE_IP_V6);
+ (void)memset(&pOutCmdHeader->fgmc_ip_v6_static_netmask_[0], 0x00, SIZE_IP_V6);
+ (void)memset(&pOutCmdHeader->fgmc_ip_v6_static_gateway_[0], 0x00, SIZE_IP_V6);
+ (void)memset(&pOutCmdHeader->fgmc_ip_v6_static_dns_[0], 0x00, SIZE_IP_V6);
+
+ // IPv4 active
+ const uint32_t ipaddressActive = reprap.GetNetwork().GetIPAddress(iface_id_).GetV4LittleEndian();
+ (void)memcpy(&pOutCmdHeader->fgmc_ip_v4_address_[0], &ipaddressActive, SIZE_IP_V4);
+
+ const uint32_t subnetmaskActive = reprap.GetNetwork().GetNetmask(iface_id_).GetV4LittleEndian();
+ (void)memcpy(&pOutCmdHeader->fgmc_ip_v4_netmask_[0], &subnetmaskActive, SIZE_IP_V4);
+
+ const uint32_t gatewayActive = reprap.GetNetwork().GetGateway(iface_id_).GetV4LittleEndian();
+ (void)memcpy(&pOutCmdHeader->fgmc_ip_v4_gateway_[0], &gatewayActive, SIZE_IP_V4);
+
+ pOutCmdHeader->fgmc_ip_v4_dns_[0] = 0;
+ pOutCmdHeader->fgmc_ip_v4_dns_[1] = 0;
+ pOutCmdHeader->fgmc_ip_v4_dns_[2] = 0;
+ pOutCmdHeader->fgmc_ip_v4_dns_[3] = 0;
+
+ // NOC-CODE
+ (void)strncpy(pOutCmdHeader->fgmc_noc_code_, INVALID_EEPROM_DATA_STRING, SIZE_EEPROM_NOC_CODE);
+
+ // iTTL
+ pOutCmdHeader->fgmc_ttl_ = 255;
+
+ // Connection State
+ pOutCmdHeader->fgmc_connection_state_ = 0;
+
+ // Device Type
+ (void)strncpy(pOutCmdHeader->fgmc_device_type_, BOARD_NAME, SIZE_DEVICE_TYPE);
+
+ // Device Serial Number
+ memset(pOutCmdHeader->fgmc_serial_number_, 0, sizeof(pOutCmdHeader->fgmc_serial_number_));
+
+ // Application Type
+ pOutCmdHeader->fgmc_application_type_ = fgmc_application_type_;
+
+ // Application Version
+ pOutCmdHeader->fgmc_application_version_ = 0;
+
+ // Application Version Revision
+ pOutCmdHeader->fgmc_application_version_revision_ = 0;
+
+ // Generic Info
+ (void)memset(pOutCmdHeader->fgmc_generic_info_, 0x00, SIZE_GENERIC_INFO);
+
+ // Device Name
+ strncpy(pOutCmdHeader->fgmc_device_name_, reprap.GetName(), ARRAY_SIZE(pOutCmdHeader->fgmc_device_name_));
+
+ //-----------------------------------------------------------------------------------
+ // Generic Multicast Header
+ //-----------------------------------------------------------------------------------
+ sendGenericHeader(tx_netbuf_, FGMCCommand::MCD_COMMAND_UNETINF, sizeof(FGMC_ResUploadNetInfoHeader), inPacketId, 0, 1);
+}
+
+void FGMCProtocol::cmdDnetinf(FGMC_ReqDownloadNetInfoHeader* pInCmdHeader, uint32_t inPacketId) noexcept
+{
+ FGMC_ResDownloadNetInfoHeader* pOutCmdHeader = reinterpret_cast<FGMC_ResDownloadNetInfoHeader*>(tx_netbuf_);
+ (void)memset(pOutCmdHeader, 0x00, sizeof(FGMC_ResDownloadNetInfoHeader));
+
+ //-----------------------------------------------------------------------------------
+ // The Download Netinformation Structure
+ //-----------------------------------------------------------------------------------
+
+ // set new network settings
+ InterfaceData& ifData = ifaceData[iface_id_];
+ const bool dhcpEnable = static_cast<bool>(pInCmdHeader->fgmc_ip_address_type_);
+ if (dhcpEnable)
+ {
+ ifData.configuredIpAddress.SetNull();
+ }
+ else
+ {
+ ifData.configuredIpAddress.SetV4LittleEndian(LoadLE32(pInCmdHeader->fgmc_ip_v4_static_address_));
+ }
+
+ ifData.configuredNetmask.SetV4LittleEndian(LoadLE32(pInCmdHeader->fgmc_ip_v4_static_netmask_));
+ ifData.configuredGateway.SetV4LittleEndian(LoadLE32(pInCmdHeader->fgmc_ip_v4_static_gateway_));
+
+ // set new device name
+ // filter out " (X19) / (X18)
+ for (uint32_t i = 0; i < SIZE_DEVICE_NAME; i++)
+ {
+ if (pInCmdHeader->fgmc_device_name_[i] == '\0')
+ {
+ if (i > 6)
+ {
+ if ((pInCmdHeader->fgmc_device_name_[i - 6] == ' ') && (pInCmdHeader->fgmc_device_name_[i - 5] == '(') &&
+ (pInCmdHeader->fgmc_device_name_[i - 4] == 'X') && (pInCmdHeader->fgmc_device_name_[i - 3] == '1') &&
+ (pInCmdHeader->fgmc_device_name_[i - 1] == ')'))
+ {
+ for (uint32_t j = 1; j <= 6; j++)
+ {
+ pInCmdHeader->fgmc_device_name_[i - j] = '\0';
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ // Create a new network-override.g file
+ FileStore *const fs = reprap.GetPlatform().OpenSysFile(NetworkConfigOverrideFileName, OpenMode::write);
+ if (fs == nullptr)
+ {
+ reprap.GetPlatform().MessageF(ErrorMessage, "Unable to create file %s\n", NetworkConfigOverrideFileName);
+ }
+ else
+ {
+ String<StringLength256> buf;
+ buf.printf( "M550 P\"%s\"\n"
+ "M552 P%u.%u.%u.%u\n"
+ "M553 P%u.%u.%u.%u\n"
+ "M554 P%u.%u.%u.%u\n",
+ pInCmdHeader->fgmc_device_name_,
+ ifData.configuredIpAddress.GetQuad(0), ifData.configuredIpAddress.GetQuad(1), ifData.configuredIpAddress.GetQuad(2), ifData.configuredIpAddress.GetQuad(3),
+ ifData.configuredNetmask.GetQuad(0), ifData.configuredNetmask.GetQuad(1), ifData.configuredNetmask.GetQuad(2), ifData.configuredNetmask.GetQuad(3),
+ ifData.configuredGateway.GetQuad(0), ifData.configuredGateway.GetQuad(1), ifData.configuredGateway.GetQuad(2), ifData.configuredGateway.GetQuad(3)
+ );
+
+ if (!fs->Write(buf.c_str()))
+ {
+ reprap.GetPlatform().MessageF(ErrorMessage, "Unable to write file %s\n", NetworkConfigOverrideFileName);
+ }
+ if (!fs->Close())
+ {
+ reprap.GetPlatform().MessageF(ErrorMessage, "Unable to close file %s\n", NetworkConfigOverrideFileName);
+ }
+ }
+
+ //-----------------------------------------------------------------------------------
+ // Generic Multicast Header
+ //-----------------------------------------------------------------------------------
+ sendGenericHeader(tx_netbuf_, FGMCCommand::MCD_COMMAND_DNETINF, sizeof(FGMC_ResDownloadNetInfoHeader), inPacketId, 0, 1);
+}
+
+void FGMCProtocol::cmdReboot(uint32_t inPacketId) noexcept
+{
+ (void)memset(tx_netbuf_, 0x00, sizeof(FGMC_GenericHeader));
+
+ //-----------------------------------------------------------------------------------
+ // Generic Multicast Header
+ //-----------------------------------------------------------------------------------
+ sendGenericHeader(tx_netbuf_, FGMCCommand::MCD_COMMAND_REBOOT, sizeof(FGMC_GenericHeader), inPacketId, 0, 1);
+ MulticastResponder::ScheduleReboot();
+}
+
+void FGMCProtocol::cmdIdentify(FGMC_ReqIdentify* pInCmdHeader, uint32_t inPacketId) noexcept
+{
+ FGMC_ResIdentify* pOutCmdHeader = reinterpret_cast<FGMC_ResIdentify*>(tx_netbuf_);
+ (void)memset(pOutCmdHeader, 0x00, sizeof(FGMC_ResIdentify));
+
+ switch (pInCmdHeader->identification_type_)
+ {
+ case IDENTIFY_DEFAULT:
+ CanInterface::SetStatusLedIdentify(30); // identify for about 30 seconds
+ break;
+
+ case IDENTIFY_ON:
+ CanInterface::SetStatusLedIdentify(0); // identify until cancelled
+ break;
+
+ case IDENTIFY_OFF:
+ default:
+ CanInterface::SetStatusLedNormal(); // cancel identify
+ break;
+ }
+
+ //-----------------------------------------------------------------------------------
+ // Generic Multicast Header
+ //-----------------------------------------------------------------------------------
+ sendGenericHeader(tx_netbuf_, FGMCCommand::MCD_COMMAND_IDENTIFY, sizeof(FGMC_ResIdentify), inPacketId, 0, 1);
+}
+
+void FGMCProtocol::cmdGetFirmwareVersion(uint32_t inPacketId) noexcept
+{
+ FGMC_ResGetFwVersion* pOutCmdHeader = reinterpret_cast<FGMC_ResGetFwVersion*>(tx_netbuf_);
+ (void)memset(pOutCmdHeader, 0x00, sizeof(FGMC_ResGetFwVersion));
+
+ //-----------------------------------------------------------------------------------
+ // Get Firmware Version
+ //-----------------------------------------------------------------------------------
+ (void)strncpy(pOutCmdHeader->module_name_, BOARD_NAME, SIZE_DEVICE_TYPE);
+
+ SafeSnprintf(pOutCmdHeader->module_version_, SIZE_MODULE_VERSION, "%s version %s", FIRMWARE_NAME, VERSION);
+
+ //-----------------------------------------------------------------------------------
+ // Generic Multicast Header
+ //-----------------------------------------------------------------------------------
+ sendGenericHeader(tx_netbuf_, FGMCCommand::MCD_COMMAND_GET_FIRMWARE_VERSION, sizeof(FGMC_ResGetFwVersion), inPacketId, 0, 1);
+}
+
+void FGMCProtocol::cmdGetSupportedCommands(uint32_t inPacketId) noexcept
+{
+ uint32_t segmentIndex = 0;
+ uint32_t segmentCount = 0;
+
+ FGMCCommand supportedCommands[] =
+ {
+ FGMCCommand::MCD_COMMAND_UNETINF,
+ FGMCCommand::MCD_COMMAND_DNETINF,
+ FGMCCommand::MCD_COMMAND_REBOOT,
+ FGMCCommand::MCD_COMMAND_IDENTIFY,
+ FGMCCommand::MCD_COMMAND_GET_FIRMWARE_VERSION,
+ FGMCCommand::MCD_COMMAND_GET_SUPPORTED_COMMANDS,
+ };
+
+ for (uint8_t i = 0; i < ARRAY_SIZE(supportedCommands); i++)
+ {
+ FGMC_ResGetSupportedCommands* pOutCmdHeader = reinterpret_cast<FGMC_ResGetSupportedCommands*>(tx_netbuf_);
+ (void)memset(pOutCmdHeader, 0x00, sizeof(FGMC_ResGetSupportedCommands));
+
+ //-----------------------------------------------------------------------------------
+ // Get Supported Commands
+ //-----------------------------------------------------------------------------------
+ pOutCmdHeader->cmd_ = static_cast<uint32_t>(supportedCommands[i]);
+ pOutCmdHeader->cmd_version_ = 0;
+
+ //-----------------------------------------------------------------------------------
+ // Generic Multicast Header
+ //-----------------------------------------------------------------------------------
+ segmentIndex = static_cast<uint32_t>(i);
+ segmentCount = static_cast<uint32_t>(ARRAY_SIZE(supportedCommands));
+ sendGenericHeader(tx_netbuf_, FGMCCommand::MCD_COMMAND_GET_SUPPORTED_COMMANDS, sizeof(FGMC_ResGetSupportedCommands), inPacketId, segmentIndex, segmentCount);
+ }
+}
+
+FGMCProtocol::InterfaceData::InterfaceData() noexcept
+ : unique_id_{0},
+ packetIdBuffer{0},
+ packetIdIndex(0)
+{
+}
+
+// Insert packet ID into buffer, returning true if success, false if it was already there,
+bool FGMCProtocol::InterfaceData::insertPacketId(uint32_t packetId) noexcept
+{
+ for (uint32_t i = 0; i < InterfaceData::ringBufferSize; i++)
+ {
+ if (packetId == packetIdBuffer[i])
+ {
+ return false;
+ }
+ }
+
+ packetIdBuffer[packetIdIndex] = packetId;
+ packetIdIndex++;
+ if (packetIdIndex >= InterfaceData::ringBufferSize)
+ {
+ packetIdIndex = 0;
+ }
+ return true;
+}
+
+#endif
+
+// End