Hi Guys,
This is the feature of RTCS (not a bug).
server_address.sin_port must be in the Host endian. You should not use htons() for port numbers in the RTCS Socket- API.
I know, it is confusing, especially if you have experience with other TCP/IP stacks.
Best regards,
Andrey Butok
Depends on your perspective - POSIX dictates .sin_port to be network byte order. Because MQX is supposed to be posix compliant it is a deviation from spec and consequently an implementation bug in RTCS on little-endian machines.
Ref: IEEE Std 1003.1 2004 <netinet/in.h>
Hi,
You are correct.
But the MQX is not fully POSIX compliant. So this is the feature :smileywink:
It is not easy to change it. This approach was used by RTCS from beginning. And changing it will require modification of all existing RTCS applications.
BTW: Some time ago, I was confused as you and wanted to change it. But it is unreal.
If you still believe that it must be changed, you may try to report it as the bug via a customer-service request.
Thanks,
Andrey Butok
sorry to hijack this thread - I had another issue related to htonl or htnos in pcb.h (MQX4)
See the definition here:
#define htonl(p,x) (((uint_8_ptr)(p))[0] = ((x) >> 24) & 0xFF, \
((uint_8_ptr)(p))[1] = ((x) >> 16) & 0xFF, \
((uint_8_ptr)(p))[2] = ((x) >> 8) & 0xFF, \
((uint_8_ptr)(p))[3] = (x) & 0xFF, \
(x))
The problem is the MACRO definition - this is not compliant to other system where on Linux for example below(man htonl) and htnol(&x, x) just did not work - I have to use another variable to save x - {int y = x; htnol(&x, y); }
This looks to me just wrong.
NAME
htonl, htons, ntohl, ntohs - convert values between host and network byte order
SYNOPSIS
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
You are right, htonl(p,x) is not compliant with common API.
I do not know why it was done this way (and probably it should be fixed).
But you can use ntohl(x) that has only one input parameter. I know, it has different purpose but in fact it does the same thing.
right - then htonl(p, x) should refine as
#define htonl(p) ntohl(p)
how simple is that!
htons means to convert from host to network short. Network is always big endian so if you're on a little endian machine (pretty much everybody these days) it needs to do a conversion. You only need to do conversion of data you're stuffing into TCP/UDP packets (which is really just limited to headers and specific protocols - nothing says your own protocol has to be big endian) so there is no reason to be using htons on the address port assignment since that is being used by the TCP/IP stack which will convert whatever it needs to.
(Edit: Apparently not all TCP/IP stacks do the conversion of address and port numbers for you - it appears the MQX implementation in this regard may be non-standard so if you're working with ported application code you might have to pay close attention to it)
Hi John,
Something to look at is that ColdFire is big endian and Kinetis is little endian architecture.
I looked at the MQX source and Kinetis htons calls a macro that does byte swapping. Maybe it shouldn't????
From pcb.h:
#define
htons(p, x) { *(uint_16*)(p) = HOST_TO_BE_SHORT(x); }
From mqx.h:
#if (PSP_ENDIAN == MQX_BIG_ENDIAN)
#define HOST_TO_BE_SHORT(n) (n) <--- ColdFire
.
.
.
#else // (PSP_ENDIAN == MQX_BIG_ENDIAN)
#define HOST_TO_BE_SHORT(n) _PSP_SWAP2BYTE(n) <--- Kinetis
Regards,
David
Hi,
Same problem here.
I'll do further investigation but if somoene has a fix, he/she is welcome.
Best regards,
edit: Sorry, it was a stupid user error in my case...
--
Emilien