From cfd18b0e2c15cc45c748859be4abcfdada5be686 Mon Sep 17 00:00:00 2001 From: David Crocker Date: Thu, 14 Jul 2022 08:39:13 +0100 Subject: Added MulticastDiscovery folder and multicast protocol header --- .../LwipEthernet/LwipEthernetInterface.cpp | 2 +- .../MulticastDiscovery/MulticastResponder.cpp | 118 ++++++++++++++ .../MulticastDiscovery/MulticastResponder.h | 27 ++++ src/Networking/MulticastDiscovery/fgmc_header.h | 175 +++++++++++++++++++++ src/Networking/MulticastResponder.cpp | 116 -------------- src/Networking/MulticastResponder.h | 27 ---- src/Networking/Network.cpp | 2 +- 7 files changed, 322 insertions(+), 145 deletions(-) create mode 100644 src/Networking/MulticastDiscovery/MulticastResponder.cpp create mode 100644 src/Networking/MulticastDiscovery/MulticastResponder.h create mode 100644 src/Networking/MulticastDiscovery/fgmc_header.h delete mode 100644 src/Networking/MulticastResponder.cpp delete mode 100644 src/Networking/MulticastResponder.h diff --git a/src/Networking/LwipEthernet/LwipEthernetInterface.cpp b/src/Networking/LwipEthernet/LwipEthernetInterface.cpp index 027c4daa..69049406 100644 --- a/src/Networking/LwipEthernet/LwipEthernetInterface.cpp +++ b/src/Networking/LwipEthernet/LwipEthernetInterface.cpp @@ -21,7 +21,7 @@ #include #include #if SUPPORT_MULTICAST_DISCOVERY -# include +# include #endif #include diff --git a/src/Networking/MulticastDiscovery/MulticastResponder.cpp b/src/Networking/MulticastDiscovery/MulticastResponder.cpp new file mode 100644 index 00000000..16ac0ba3 --- /dev/null +++ b/src/Networking/MulticastDiscovery/MulticastResponder.cpp @@ -0,0 +1,118 @@ +/* + * MulticastResponder.cpp + * + * Created on: 12 Jul 2022 + * Author: David + */ + +#include "MulticastResponder.h" + +#if SUPPORT_MULTICAST_DISCOVERY + +#include +#include +#include "fgmc_header.h" + +extern "C" { +#include "LwipEthernet/Lwip/src/include/lwip/udp.h" +#include "LwipEthernet/Lwip/src/include/lwip/igmp.h" +extern struct netif gs_net_if; +} + +static udp_pcb *ourPcb = nullptr; +static pbuf * volatile receivedPbuf = nullptr; +static volatile uint32_t receivedIpAddr; +static volatile uint16_t receivedPort; +static unsigned int messagesProcessed = 0; + +static bool active = false; + +static constexpr ip_addr_t ourGroup = IPADDR4_INIT_BYTES(239, 255, 2, 3); + +// Receive callback function +extern "C" void rcvFunc(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) noexcept +{ + if (active && receivedPbuf == nullptr) + { + receivedIpAddr = addr->addr; + receivedPort = port; + receivedPbuf = p; + } + else + { + pbuf_free(p); + } +} + +void MulticastResponder::Init() noexcept +{ + // Nothing needed here yet +} + +// Do some work, returning true if we did anything significant +void MulticastResponder::Spin() noexcept +{ + pbuf *rxPbuf = receivedPbuf; + if (rxPbuf != nullptr) + { + debugPrintf("Rx UDP: addr %u.%u.%u.%u port %u data", + (unsigned int)(receivedIpAddr & 0xFF), (unsigned int)((receivedIpAddr >> 8) & 0xFF), (unsigned int)((receivedIpAddr >> 16) & 0xFF), (unsigned int)((receivedIpAddr >> 24) & 0xFF), receivedPort); + for (size_t i = 0; i < rxPbuf->len; ++i) + { + debugPrintf(" %02x", ((const uint8_t*)(rxPbuf->payload))[i]); + } + debugPrintf("\n"); + pbuf_free(rxPbuf); + receivedPbuf = nullptr; + ++messagesProcessed; + } +} + +void MulticastResponder::Diagnostics(MessageType mtype) noexcept +{ + reprap.GetPlatform().MessageF(mtype, "=== Multicast handler ===\nResponder is %s, messages processed %u\n", (active) ? "active" : "inactive", messagesProcessed); +} + +void MulticastResponder::Start(TcpPort port) noexcept +{ + if (ourPcb == nullptr) + { + ourPcb = udp_new_ip_type(IPADDR_TYPE_ANY); + if (ourPcb == nullptr) + { + reprap.GetPlatform().Message(ErrorMessage, "unable to allocate a pcb\n"); + } + else + { + udp_set_multicast_ttl(ourPcb, 255); + if (igmp_joingroup_netif(&gs_net_if, ip_2_ip4(&ourGroup)) != ERR_OK) // without this call, multicast packets to this IP address get discarded + { + reprap.GetPlatform().Message(ErrorMessage, "igmp_joingroup failed\n"); + } + else if (udp_bind(ourPcb, &ourGroup, port) != ERR_OK) + { + reprap.GetPlatform().Message(ErrorMessage, "udp_bind call failed\n"); + } + else + { + udp_recv(ourPcb, rcvFunc, nullptr); + } + } + } + active = true; + messagesProcessed = 0; +} + +void MulticastResponder::Stop() noexcept +{ + if (ourPcb != nullptr) + { + udp_remove(ourPcb); + ourPcb = nullptr; + } + active = false; +} + +#endif + +// End diff --git a/src/Networking/MulticastDiscovery/MulticastResponder.h b/src/Networking/MulticastDiscovery/MulticastResponder.h new file mode 100644 index 00000000..2d57581e --- /dev/null +++ b/src/Networking/MulticastDiscovery/MulticastResponder.h @@ -0,0 +1,27 @@ +/* + * MulricastResponder.h + * + * Created on: 12 Jul 2022 + * Author: David + */ + +#ifndef SRC_NETWORKING_MULTICASTRESPONDER_H_ +#define SRC_NETWORKING_MULTICASTRESPONDER_H_ + +#include +#include + +#if SUPPORT_MULTICAST_DISCOVERY + +namespace MulticastResponder +{ + void Init() noexcept; + void Spin() noexcept; + void Start(TcpPort port) noexcept; + void Stop() noexcept; + void Diagnostics(MessageType mtype) noexcept; +} + +#endif + +#endif /* SRC_NETWORKING_MULTICASTRESPONDER_H_ */ diff --git a/src/Networking/MulticastDiscovery/fgmc_header.h b/src/Networking/MulticastDiscovery/fgmc_header.h new file mode 100644 index 00000000..5f48f91a --- /dev/null +++ b/src/Networking/MulticastDiscovery/fgmc_header.h @@ -0,0 +1,175 @@ +/// \file +/// \copyright Festo SE & Co. KG, Esslingen. All rights reserved. +/// \author erfe +/// \brief +/// + +#ifndef FGMC_HEADER_H +#define FGMC_HEADER_H + +namespace engp { + +/// fgmc device id for platform family cmmt +enum class FGMCHwTypeId : uint32_t { FGMC_DEVICE_ID_ZERO = 0, FGMC_DEVICE_ID_CMMT_AS = 23, FGMC_DEVICE_ID_CMMT_ST = 33 }; + +/// fgmc error codes +enum class FGMCErrorCode : int16_t { + FGMC_ERROR_CODE_NORMAL = 0, + FGMC_ERROR_CODE_CMD_NOT_KNOWN = -1, + FGMC_ERROR_CODE_CMD_VERSION_NOT_SUPPORTED = -2, + FGMC_ERROR_CODE_CMD_FAILED = -3, + FGMC_ERROR_CODE_CMD_SEGMENT_INDEX_MISS = -4 +}; + +/// fgmc commands +enum class FGMCCommand : int32_t { + MCD_COMMAND_UNKNOWN = 0, + MCD_COMMAND_UNETINF = 1, + MCD_COMMAND_DNETINF = 2, + MCD_COMMAND_DNETINF_REBOOT = 3, + MCD_COMMAND_REBOOT = 4, + MCD_COMMAND_UPDATE_FIRMWARE = 5, + MCD_COMMAND_IDENTIFY = 6, + MCD_COMMAND_GET_VERSIONS = 7, + MCD_COMMAND_READFILE = 8, + MCD_COMMAND_GET_FIRMWARE_VERSION = 9, + MCD_COMMAND_GET_SUPPORTED_COMMANDS = 10 +}; + +/// fgmc command version +enum class FGMCCommandVersion : uint16_t { MCD_COMMAND_VERSION = 0 }; + +// +#define INVALID_EEPROM_DATA_STRING "invalid eeprom data" +#define INVALID_EEPROM_DATA_STRING_LEN sizeof(INVALID_EEPROM_DATA_STRING) - 1 + +/// array size definitions +#define FGMC_NAME "FESTOMULTICAST" + +constexpr size_t SIZE_FGMC_NAME = 14; +constexpr size_t SIZE_FGMC_DEST_ID = 16; + +constexpr size_t SIZE_FGMC_RES_MAX = 464; // 461 Bytes for FGMC_ResUploadNetInfoHeader + +/// fgmc protocol header +struct __attribute__((packed)) FGMC_GenericHeader +{ + char fgmc_name_[SIZE_FGMC_NAME]; + uint32_t fgmc_length_; + FGMCHwTypeId fgmc_hw_type_id_; + char fgmc_destination_id_[SIZE_FGMC_DEST_ID]; + uint32_t fgmc_packet_id_; + uint32_t fgmc_segment_index_; + uint32_t fgmc_segment_count_; + FGMCCommand fgmc_command_; + FGMCCommandVersion fgmc_command_version_; + FGMCErrorCode fgmc_error_code_; +}; + +/// array size definitions +constexpr size_t SIZE_MAC_ADDRESS = 6; +constexpr size_t SIZE_IP_V4 = 4; +constexpr size_t SIZE_IP_V6 = 16; +constexpr size_t SIZE_DEVICE_TYPE = 12; +constexpr size_t SIZE_NOC_CODE = 64; +constexpr size_t SIZE_SERIAL_NUMBER = 64; +constexpr size_t SIZE_GENERIC_INFO = 12; +constexpr size_t SIZE_DEVICE_NAME = 128; + +/// fgmc command response header upload network informations +struct __attribute__((packed)) FGMC_ResUploadNetInfoHeader +{ + FGMC_GenericHeader fgmc_header_; + char fgmc_mac_address_[SIZE_MAC_ADDRESS]; + uint32_t fgmc_ip_address_type_; + uint8_t fgmc_ip_v4_static_address_[SIZE_IP_V4]; + uint8_t fgmc_ip_v4_static_netmask_[SIZE_IP_V4]; + uint8_t fgmc_ip_v4_static_gateway_[SIZE_IP_V4]; + uint8_t fgmc_ip_v4_static_dns_[SIZE_IP_V4]; + uint8_t fgmc_ip_v6_static_6_addr_[SIZE_IP_V6]; + uint8_t fgmc_ip_v6_static_netmask_[SIZE_IP_V6]; + uint8_t fgmc_ip_v6_static_gateway_[SIZE_IP_V6]; + uint8_t fgmc_ip_v6_static_dns_[SIZE_IP_V6]; + uint8_t fgmc_ip_v4_address_[SIZE_IP_V4]; + uint8_t fgmc_ip_v4_netmask_[SIZE_IP_V4]; + uint8_t fgmc_ip_v4_gateway_[SIZE_IP_V4]; + uint8_t fgmc_ip_v4_dns_[SIZE_IP_V4]; + char fgmc_noc_code_[SIZE_NOC_CODE]; + int32_t fgmc_ttl_; + uint8_t fgmc_connection_state_; + char fgmc_device_type_[SIZE_DEVICE_TYPE]; + char fgmc_serial_number_[SIZE_SERIAL_NUMBER]; + uint32_t fgmc_application_type_; + uint32_t fgmc_application_version_; + uint32_t fgmc_application_version_revision_; + uint8_t fgmc_generic_info_[SIZE_GENERIC_INFO]; + char fgmc_device_name_[SIZE_DEVICE_NAME]; +}; + +/// array size definitions +constexpr size_t SIZE_PASSWORD = 12; + +/// fgmc command request header "download network informations" +struct __attribute__((packed)) FGMC_ReqDownloadNetInfoHeader +{ + uint32_t fgmc_ip_address_type_; + uint8_t fgmc_ip_v4_static_address_[SIZE_IP_V4]; + uint8_t fgmc_ip_v4_static_netmask_[SIZE_IP_V4]; + uint8_t fgmc_ip_v4_static_gateway_[SIZE_IP_V4]; + uint8_t fgmc_ip_v4_static_dns_[SIZE_IP_V4]; + uint8_t fgmc_ip_v6_static_6_addr_[SIZE_IP_V6]; + uint8_t fgmc_ip_v6_static_netmask_[SIZE_IP_V6]; + uint8_t fgmc_ip_v6_static_gateway_[SIZE_IP_V6]; + uint8_t fgmc_ip_v6_static_dns_[SIZE_IP_V6]; + int32_t fgmc_ttl_; + char fgmc_device_name_[SIZE_DEVICE_NAME]; + char fgmc_password_[SIZE_PASSWORD]; +}; + +/// fgmc command response header "download network informations" +struct __attribute__((packed)) FGMC_ResDownloadNetInfoHeader +{ + FGMC_GenericHeader fgmc_header_; +}; + +/// array size definitions +constexpr uint32_t IDENTIFY_DEFAULT = 0; +constexpr uint32_t IDENTIFY_ON = 1; +constexpr uint32_t IDENTIFY_OFF = 2; + +/// fgmc command request header "identify" +struct __attribute__((packed)) FGMC_ReqIdentify +{ + int32_t identification_type_; + int32_t reserved_; +}; + +/// fgmc command response header "identify" +struct __attribute__((packed)) FGMC_ResIdentify +{ + FGMC_GenericHeader fgmc_header_; +}; + +/// array size definitions +constexpr size_t SIZE_MODULE_NAME = 192; +constexpr size_t SIZE_MODULE_VERSION = 64; + +/// fgmc command response header "get firmware version" +struct __attribute__((packed)) FGMC_ResGetFwVersion +{ + FGMC_GenericHeader fgmc_header_; + char module_name_[SIZE_MODULE_NAME]; + char module_version_[SIZE_MODULE_VERSION]; +}; + +/// fgmc command response header "get supported commands" +struct __attribute__((packed)) FGMC_ResGetSupportedCommands +{ + FGMC_GenericHeader fgmc_header_; + uint32_t cmd_; + uint16_t cmd_version_; +}; + +} // namespace engp + +#endif // #ifndef FGMC_HEADER_H diff --git a/src/Networking/MulticastResponder.cpp b/src/Networking/MulticastResponder.cpp deleted file mode 100644 index b040f1dd..00000000 --- a/src/Networking/MulticastResponder.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * MulricastResponder.cpp - * - * Created on: 12 Jul 2022 - * Author: David - */ - -#include "MulticastResponder.h" -#include -#include - -extern "C" { -#include "LwipEthernet/Lwip/src/include/lwip/udp.h" -#include "LwipEthernet/Lwip/src/include/lwip/igmp.h" -extern struct netif gs_net_if; -} - -#if SUPPORT_MULTICAST_DISCOVERY - -static udp_pcb *ourPcb = nullptr; -static pbuf * volatile receivedPbuf = nullptr; -static volatile uint32_t receivedIpAddr; -static volatile uint16_t receivedPort; -static unsigned int messagesProcessed = 0; - -static bool active = false; - -static constexpr ip_addr_t ourGroup = IPADDR4_INIT_BYTES(239, 255, 2, 3); - -// Receive callback function -extern "C" void rcvFunc(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) noexcept -{ - if (active && receivedPbuf == nullptr) - { - receivedIpAddr = addr->addr; - receivedPort = port; - receivedPbuf = p; - } - else - { - pbuf_free(p); - } -} - -void MulticastResponder::Init() noexcept -{ - // Nothing needed here yet -} - -// Do some work, returning true if we did anything significant -void MulticastResponder::Spin() noexcept -{ - pbuf *rxPbuf = receivedPbuf; - if (rxPbuf != nullptr) - { - debugPrintf("Rx UDP: addr %u.%u.%u.%u port %u data", - (unsigned int)(receivedIpAddr & 0xFF), (unsigned int)((receivedIpAddr >> 8) & 0xFF), (unsigned int)((receivedIpAddr >> 16) & 0xFF), (unsigned int)((receivedIpAddr >> 24) & 0xFF), receivedPort); - for (size_t i = 0; i < rxPbuf->len; ++i) - { - debugPrintf(" %02x", ((const uint8_t*)(rxPbuf->payload))[i]); - } - debugPrintf("\n"); - pbuf_free(rxPbuf); - receivedPbuf = nullptr; - ++messagesProcessed; - } -} - -void MulticastResponder::Diagnostics(MessageType mtype) noexcept -{ - reprap.GetPlatform().MessageF(mtype, "=== Multicast handler ===\nResponder is %s, messages processed %u\n", (active) ? "active" : "inactive", messagesProcessed); -} - -void MulticastResponder::Start(TcpPort port) noexcept -{ - if (ourPcb == nullptr) - { - ourPcb = udp_new_ip_type(IPADDR_TYPE_ANY); - if (ourPcb == nullptr) - { - reprap.GetPlatform().Message(ErrorMessage, "unable to allocate a pcb\n"); - } - else - { - udp_set_multicast_ttl(ourPcb, 255); - if (igmp_joingroup_netif(&gs_net_if, ip_2_ip4(&ourGroup)) != ERR_OK) // without this call, multicast packets to this IP address get discarded - { - reprap.GetPlatform().Message(ErrorMessage, "igmp_joingroup failed\n"); - } - else if (udp_bind(ourPcb, &ourGroup, port) != ERR_OK) - { - reprap.GetPlatform().Message(ErrorMessage, "udp_bind call failed\n"); - } - else - { - udp_recv(ourPcb, rcvFunc, nullptr); - } - } - } - active = true; - messagesProcessed = 0; -} - -void MulticastResponder::Stop() noexcept -{ - if (ourPcb != nullptr) - { - udp_remove(ourPcb); - ourPcb = nullptr; - } - active = false; -} - -#endif - -// End diff --git a/src/Networking/MulticastResponder.h b/src/Networking/MulticastResponder.h deleted file mode 100644 index 2d57581e..00000000 --- a/src/Networking/MulticastResponder.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * MulricastResponder.h - * - * Created on: 12 Jul 2022 - * Author: David - */ - -#ifndef SRC_NETWORKING_MULTICASTRESPONDER_H_ -#define SRC_NETWORKING_MULTICASTRESPONDER_H_ - -#include -#include - -#if SUPPORT_MULTICAST_DISCOVERY - -namespace MulticastResponder -{ - void Init() noexcept; - void Spin() noexcept; - void Start(TcpPort port) noexcept; - void Stop() noexcept; - void Diagnostics(MessageType mtype) noexcept; -} - -#endif - -#endif /* SRC_NETWORKING_MULTICASTRESPONDER_H_ */ diff --git a/src/Networking/Network.cpp b/src/Networking/Network.cpp index 0b6f60fe..7a000675 100644 --- a/src/Networking/Network.cpp +++ b/src/Networking/Network.cpp @@ -46,7 +46,7 @@ # include "TelnetResponder.h" #endif #if SUPPORT_MULTICAST_DISCOVERY -# include "MulticastResponder.h" +# include "MulticastDiscovery/MulticastResponder.h" #endif #ifdef __LPC17xx__ -- cgit v1.2.3