From bae37b902864a3c73779026f0e45bee3cd7721cb Mon Sep 17 00:00:00 2001 From: Andreas Karlsson Date: Fri, 14 Aug 2020 15:04:46 +0200 Subject: [PATCH 1/2] Don't always include optional IP parameter lengths Obvious fix, the optional IP parameters length should only be included in total length if they are included. fixes #421 --- soem/ethercateoe.c | 32 +++++++++++++------------------- soem/ethercateoe.h | 2 ++ 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/soem/ethercateoe.c b/soem/ethercateoe.c index 5a40b13..a444565 100644 --- a/soem/ethercateoe.c +++ b/soem/ethercateoe.c @@ -94,45 +94,43 @@ int ecx_EOEsetIp(ecx_contextt *context, uint16 slave, uint8 port, eoe_param_t * EOE_HDR_LAST_FRAGMENT); EOEp->frameinfo2 = 0; - /* The EoE frame will include "empty" IP/DNS entries, makes wireshark happy. - * Specification say they are optional, TwinCAT include empty entries. - */ if (ipparam->mac_set) { flags |= EOE_PARAM_MAC_INCLUDE; memcpy(&EOEp->data[data_offset], ipparam->mac.addr, EOE_ETHADDR_LENGTH); + data_offset += EOE_ETHADDR_LENGTH; } - data_offset += EOE_ETHADDR_LENGTH; if (ipparam->ip_set) { flags |= EOE_PARAM_IP_INCLUDE; EOE_ip_uint32_to_byte(&ipparam->ip, &EOEp->data[data_offset]); + data_offset += EOE_IP4_LENGTH; } - data_offset += 4; if (ipparam->subnet_set) { flags |= EOE_PARAM_SUBNET_IP_INCLUDE; EOE_ip_uint32_to_byte(&ipparam->subnet, &EOEp->data[data_offset]); + data_offset += EOE_IP4_LENGTH; } - data_offset += 4; if (ipparam->default_gateway_set) { flags |= EOE_PARAM_DEFAULT_GATEWAY_INCLUDE; EOE_ip_uint32_to_byte(&ipparam->default_gateway, &EOEp->data[data_offset]); + data_offset += EOE_IP4_LENGTH; } - data_offset += 4; if (ipparam->dns_ip_set) { flags |= EOE_PARAM_DNS_IP_INCLUDE; EOE_ip_uint32_to_byte(&ipparam->dns_ip, &EOEp->data[data_offset]); + data_offset += EOE_IP4_LENGTH; } - data_offset += 4; if (ipparam->dns_name_set) { + /* TwinCAT include EOE_DNS_NAME_LENGTH chars even if name is shorter */ flags |= EOE_PARAM_DNS_NAME_INCLUDE; memcpy(&EOEp->data[data_offset], (void *)ipparam->dns_name, EOE_DNS_NAME_LENGTH); + data_offset += EOE_DNS_NAME_LENGTH; } - data_offset += EOE_DNS_NAME_LENGTH; EOEp->mbxheader.length = htoes(EOE_PARAM_OFFSET + data_offset); EOEp->data[0] = flags; @@ -231,10 +229,6 @@ int ecx_EOEgetIp(ecx_contextt *context, uint16 slave, uint8 port, eoe_param_t * } else { - /* The EoE frame will include "empty" IP/DNS entries, makes - * wireshark happy. Specification say they are optional, TwinCAT - * include empty entries. - */ flags = aEOEp->data[0]; if (flags & EOE_PARAM_MAC_INCLUDE) { @@ -242,36 +236,36 @@ int ecx_EOEgetIp(ecx_contextt *context, uint16 slave, uint8 port, eoe_param_t * &aEOEp->data[data_offset], EOE_ETHADDR_LENGTH); ipparam->mac_set = 1; + data_offset += EOE_ETHADDR_LENGTH; } - data_offset += EOE_ETHADDR_LENGTH; if (flags & EOE_PARAM_IP_INCLUDE) { EOE_ip_byte_to_uint32(&aEOEp->data[data_offset], &ipparam->ip); ipparam->ip_set = 1; + data_offset += EOE_IP4_LENGTH; } - data_offset += 4; if (flags & EOE_PARAM_SUBNET_IP_INCLUDE) { EOE_ip_byte_to_uint32(&aEOEp->data[data_offset], &ipparam->subnet); ipparam->subnet_set = 1; + data_offset += EOE_IP4_LENGTH; } - data_offset += 4; if (flags & EOE_PARAM_DEFAULT_GATEWAY_INCLUDE) { EOE_ip_byte_to_uint32(&aEOEp->data[data_offset], &ipparam->default_gateway); ipparam->default_gateway_set = 1; + data_offset += EOE_IP4_LENGTH; } - data_offset += 4; if (flags & EOE_PARAM_DNS_IP_INCLUDE) { EOE_ip_byte_to_uint32(&aEOEp->data[data_offset], &ipparam->dns_ip); ipparam->dns_ip_set = 1; + data_offset += EOE_IP4_LENGTH; } - data_offset += 4; if (flags & EOE_PARAM_DNS_NAME_INCLUDE) { uint16_t dns_len; @@ -286,8 +280,8 @@ int ecx_EOEgetIp(ecx_contextt *context, uint16 slave, uint8 port, eoe_param_t * /* Assume ZERO terminated string */ memcpy(ipparam->dns_name, &aEOEp->data[data_offset], dns_len); ipparam->dns_name_set = 1; + data_offset += EOE_DNS_NAME_LENGTH; } - data_offset += EOE_DNS_NAME_LENGTH; /* Something os not correct, flag the error */ if(data_offset > eoedatasize) { diff --git a/soem/ethercateoe.h b/soem/ethercateoe.h index b517398..a4c2c73 100644 --- a/soem/ethercateoe.h +++ b/soem/ethercateoe.h @@ -22,6 +22,8 @@ extern "C" #define EOE_DNS_NAME_LENGTH 32 /** Ethernet address length not including VLAN */ #define EOE_ETHADDR_LENGTH 6 +/** IPv4 address length */ +#define EOE_IP4_LENGTH sizeof(uint32_t) #define EOE_MAKEU32(a,b,c,d) (((uint32_t)((a) & 0xff) << 24) | \ ((uint32_t)((b) & 0xff) << 16) | \ From 33aa7a3c579935a0c61af07bb2b7324af80e18f0 Mon Sep 17 00:00:00 2001 From: Andreas Karlsson Date: Fri, 14 Aug 2020 15:35:45 +0200 Subject: [PATCH 2/2] Correct unit for dc mastertime calulcation to (ns) The correct factor for seconds should be 1000000000 fixes #432 --- soem/ethercatdc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soem/ethercatdc.c b/soem/ethercatdc.c index b6220b1..a64b1ae 100644 --- a/soem/ethercatdc.c +++ b/soem/ethercatdc.c @@ -270,7 +270,7 @@ boolean ecx_configdc(ecx_contextt *context) ecx_BWR(context->port, 0, ECT_REG_DCTIME0, sizeof(ht), &ht, EC_TIMEOUTRET); /* latch DCrecvTimeA of all slaves */ mastertime = osal_current_time(); mastertime.sec -= 946684800UL; /* EtherCAT uses 2000-01-01 as epoch start instead of 1970-01-01 */ - mastertime64 = (((uint64)mastertime.sec * 1000000) + (uint64)mastertime.usec) * 1000; + mastertime64 = (((uint64)mastertime.sec * 1000000000) + (uint64)mastertime.usec) * 1000; for (i = 1; i <= *(context->slavecount); i++) { context->slavelist[i].consumedports = context->slavelist[i].activeports;