Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Running ohNet on a PowerPC machine
14-01-2013, 05:34 PM
Post: #1
Running ohNet on a PowerPC machine
I've tried cross-compiling ohNet for Linux PowerPC. The compile appeared to be sucessful, and the resulting binaries allow MinimServer to create a device with no errors. Unfortunately, this device isn't visible in DeviceSpy, so it seems that something is wrong with the code that responds to M-SEARCH requests.

Is there any part of the ohNet code that might be sensitive to PowerPC/ARM/x86/x64 differences? I'm somewhat in the dark at the moment because I don't have any PowerPC hardware that I can use to debug this myself. The target machine is a Synology DS213+ NAS.
Find all posts by this user
14-01-2013, 05:51 PM
Post: #2
RE: Running ohNet on a PowerPC machine
The most interesting difference between PowerPC and the other architectures ohNet has run on is that PPC is big endian. We've run ohNet successfully on a PPC Linn DS so I don't think endianess is a big issue for core code. We haven't tried running on Linux PPC or running Java code on a big-endian host however...

Like you, I don't have a suitable test device. A good first step would be to narrow down the problem. Could you try a couple of tests please?
  1. Build/install the native ohNet test TestDvTestBasic and see whether that shows up in Device Spy. This will tell us whether ohNet is behaving sensibly.
  2. Run a pure Java test and see whether that shows up on the network. I don't know whether it'd be less painful to write a simple MSEARCH responder that reports the presence of a dummy device or write a trivial tcp server and also a client app. This will confirm whether the JVM is behaving correctly.

If either test fails, we'll have an area to look into in more detail. If both tests pass, ohNet's Java bindings might be worth a closer look.
Find all posts by this user
14-01-2013, 06:50 PM
Post: #3
RE: Running ohNet on a PowerPC machine
(14-01-2013 05:51 PM)simonc Wrote:  The most interesting difference between PowerPC and the other architectures ohNet has run on is that PPC is big endian. We've run ohNet successfully on a PPC Linn DS so I don't think endianess is a big issue for core code. We haven't tried running on Linux PPC or running Java code on a big-endian host however...

Like you, I don't have a suitable test device. A good first step would be to narrow down the problem. Could you try a couple of tests please?
  1. Build/install the native ohNet test TestDvTestBasic and see whether that shows up in Device Spy. This will tell us whether ohNet is behaving sensibly.
  2. Run a pure Java test and see whether that shows up on the network. I don't know whether it'd be less painful to write a simple MSEARCH responder that reports the presence of a dummy device or write a trivial tcp server and also a client app. This will confirm whether the JVM is behaving correctly.

If either test fails, we'll have an area to look into in more detail. If both tests pass, ohNet's Java bindings might be worth a closer look.

Thanks for the quick reply.

The first of these seems worth doing, as it would be a good test for the possibility of a problem with the Java bindings. This seems quite a likely candidate for the problem area. I could also look through the Java bindings to see if I can spot any endianness issues.

I'm not so convinced about the second. This PowerPC JVM is from Oracle, and I'm sure Oracle wouldn't have released it without having first made sure it passes thousands (literally) of Java compliance tests.
Find all posts by this user
15-01-2013, 06:23 AM
Post: #4
RE: Running ohNet on a PowerPC machine
The problem seems to be in line 193 of Makefile:

endian = LITTLE

I'll adjust this and see what happens. Thanks for the pointer.
Find all posts by this user
15-01-2013, 11:27 PM
Post: #5
RE: Running ohNet on a PowerPC machine
(15-01-2013 06:23 AM)simoncn Wrote:  The problem seems to be in line 193 of Makefile:

endian = LITTLE

I'll adjust this and see what happens. Thanks for the pointer.

Unfortunately, this didn't solve the problem.

I'm wondering whether the problem could be related to the ordering of the bytes in TIpAddress (returned by the OhNetNetworkAdapterAddress and OhNetNetworkAdapterSubnet API calls). On ARM and x86, the most significant byte of TIpAddress corresponds to the least significant byte of the IP4 address, and the Java bindings are assuming this. Will this be the same on PowerPC, or the opposite?
Find all posts by this user
16-01-2013, 05:08 PM
Post: #6
RE: Running ohNet on a PowerPC machine
(15-01-2013 11:27 PM)simoncn Wrote:  Unfortunately, this didn't solve the problem.

I'm wondering whether the problem could be related to the ordering of the bytes in TIpAddress (returned by the OhNetNetworkAdapterAddress and OhNetNetworkAdapterSubnet API calls). On ARM and x86, the most significant byte of TIpAddress corresponds to the least significant byte of the IP4 address, and the Java bindings are assuming this. Will this be the same on PowerPC, or the opposite?

TIpAddress is defined as

/**
* IpV4 address as network order uint32
*/
typedef uint32_t TIpAddress;

so byte order should be big endian in all builds.

Can you expand on "didn't solve the problem" please? Does nothing show up in Device Spy yet? Or is the UPnP device discoverable but not working as a media server now?

If nothing is working yet, I'd fall back to my earlier suggestion of trying to build/run TestDvTestBasic and see whether it appears in Device Spy.

If a device is discoverable I'd try logging the IP addresses Minim tries to output to check that octets aren't getting reversed.
Find all posts by this user
16-01-2013, 06:36 PM
Post: #7
RE: Running ohNet on a PowerPC machine
(16-01-2013 05:08 PM)simonc Wrote:  TIpAddress is defined as

/**
* IpV4 address as network order uint32
*/
typedef uint32_t TIpAddress;

so byte order should be big endian in all builds.

It doesn't look that way to me. For example, the DvInvocation.c file in the Java bindings calls the C API function:

DvInvocationGetAdapter(invocation, &adapter);

If I add the following printf call after this:

printf("DvInvocation: adapter=0x%08x %d\n", adapter, adapter);

I get this output when runnng on an x86 machine:

DvInvocation: adapter=0x0e00a8c0 234924224

for the IP address 192.168.0.14. This doesn't seem to be in network byte order, unless I'm completely misunderstanding what this means.
Find all posts by this user
16-01-2013, 10:00 PM
Post: #8
RE: Running ohNet on a PowerPC machine
I think I've got this straight in my mind now. On a little-endian machine, the first octet in an IP address is the least-significant byte of TIpAddress, and on a big-endian machine it's the most-significant byte. The following code from Network.cpp confirms this.

Code:
void Endpoint::GetAddressOctets(TByte (&aOctets)[4]) const
{
#ifdef DEFINE_LITTLE_ENDIAN
    aOctets[0] = iAddress&0xff;
    aOctets[1] = (iAddress>>8)&0xff;
    aOctets[2] = (iAddress>>16)&0xff;
    aOctets[3] = (iAddress>>24)&0xff;
#elif defined DEFINE_BIG_ENDIAN
    aOctets[0] = (iAddress>>24)&0xff;
    aOctets[1] = (iAddress>>16)&0xff;
    aOctets[2] = (iAddress>>8)&0xff;
    aOctets[3] = iAddress&0xff;
#else
# error No endianess defined
#endif
}

The JNI interface between native code and Java code automatically converts integer values between native code "host order" and Java's big-endian representation. On a little-endian machine, a "host order" TIpAddress of 0x0e00a8c0 (192.168.0.14) is converted to 0x0e00a8c0 in Java. On a big-endian machine, a "host order" TIpAddress of 0xc0a8000e (192.168.0.14) is converted to 0xc0a8000e in Java.

Java programmers can't and shouldn't know anything about the endianness of the target platform. Integers should always be in Java's native big-endian form. This means that the conversion of IP addresses needs to reverse the byte order on a little-endian platform, so that the IP address 192.168.0.14 becomes 0xc0a8000e in Java on both big-endian and little-endian platforms.

Correcting the byte order requires adding some endian-sensitive code to the Java bindings (similar to the code shown above). Unfortunately, it also means that any Java application code that depends on the current incorrect byte-reversed integer representation of IP addresses on little-endian platforms will need to be changed.

I'm willing to produce a patch for all the necessary changes in the Java bindings, as well as a description of how Java application code will be affected by this change.
Find all posts by this user
17-01-2013, 11:47 AM (This post was last modified: 17-01-2013 01:35 PM by simonc.)
Post: #9
RE: Running ohNet on a PowerPC machine
(16-01-2013 06:36 PM)simoncn Wrote:  
(16-01-2013 05:08 PM)simonc Wrote:  TIpAddress ... byte order should be big endian in all builds.

It doesn't look that way to me. For example, the DvInvocation.c file in the Java bindings calls the C API function:

DvInvocationGetAdapter(invocation, &adapter);

If I add the following printf call after this:

printf("DvInvocation: adapter=0x%08x %d\n", adapter, adapter);

I get this output when runnng on an x86 machine:

DvInvocation: adapter=0x0e00a8c0 234924224

for the IP address 192.168.0.14. This doesn't seem to be in network byte order, unless I'm completely misunderstanding what this means.

This caught me out initially too. If you ran your test on a little endian host, it'll reorder the bytes of the TIpAddress to format them as hex (presenting the first byte as least significant etc.). If you change your printf to

uint8_t octets[4];
memcpy(octets, &adapter, sizeof(octets));
printf("DvInvocation: adapter=%d.%d.%d.%d\n", octets[0], octets[1], octets[2], octets[3]);

You'll avoid any byte reordering and get output that suggests TIpAddress is indeed using network byte order.
Find all posts by this user
17-01-2013, 12:03 PM
Post: #10
RE: Running ohNet on a PowerPC machine
(16-01-2013 10:00 PM)simoncn Wrote:  Correcting the byte order requires adding some endian-sensitive code to the Java bindings (similar to the code shown above). Unfortunately, it also means that any Java application code that depends on the current incorrect byte-reversed integer representation of IP addresses on little-endian platforms will need to be changed.

I'm willing to produce a patch for all the necessary changes in the Java bindings, as well as a description of how Java application code will be affected by this change.

Thanks, that'd be great. In case you haven't spotted it, Os.h contains a macro SwapEndian32() which might be useful here (if you continue to treat TIpAddress as an int; alternatives like converting it to a byte array may be preferable).
Find all posts by this user


Forum Jump: