LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How to efficiently read network data into struct and correct endianess

Solved!
Go to solution

I have a device that transmits the following data over TCP

struct SomeData
{
  uint32_t counter;
  uint32_t status;
  double values[20];
} __attribute__((packed));

I can successfully read and make use of this data from a LabVIEW client, but the process is cumbersome.  Currently, I am manually selecting sub-arrays of bytes, reversing them to correct the endianess, type casting them to the correct type, and then bundling them into a struct.  Is there a more efficient way to do this?  I have explored using flatten/unflatten from string but I end up with Error 116.  Basically, what I want is something like the following C code.

SomeData some_data;
recv(sock_fd, &some_data, sizeof(some_data), MSG_WAITALL);
some_data.counter = be32toh(some_data.counter);
...

 

0 Kudos
Message 1 of 16
(3,306 Views)

what does the TCP string look like when LabVIEW receives it? Do you get the whole message in one packet or are there multiple reads involved?

0 Kudos
Message 2 of 16
(3,305 Views)

I get the whole message.  An example is 

[15, 0, 0, 0, 1, 0, 0, 0, 61, 10, 215, 163, 112, 157, 64, 64, ... ]

which should correspond to 

counter = 15

status = 1

values = [33.23, ...]

 

0 Kudos
Message 3 of 16
(3,295 Views)

To make our lives easier, can you attach a simple VI that contains a typical received string as diagram constant?

0 Kudos
Message 4 of 16
(3,293 Views)

Unflatten from String should do what you want. You need a LabVIEW cluster that matches the struct. The array element of the struct should be a 20-element cluster in LabVIEW (create an empty array of the appropriate data type, wire it to "Array to Cluster," set cluster size to 20, create a control, put it into your overall cluster).

 

Use that new cluster as the type input to Unflatten from String. Wire the string from TCP Read into Unflatten from String. Set the endianness input, if necessary. In some cases you can use Type Cast instead of Unflatten from String, but then you don't get to pick endianness.

0 Kudos
Message 5 of 16
(3,268 Views)

That array will mess things up a little.  But things are arranged in such a way that we can easily get around it.  I would use three Unflatten From Strings.  We can abuse the "Remaining String" output of the Unflatten From String and wire it up to the next.  This will allow us to get parts at a time.  The first gets the U32 counter.  The second the U32 status.  For the last one, you use an array of doubles as the data type and be sure to wire a FALSE to the "data includes array or string size".  You can then bundle the three data points together into your cluster.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 6 of 16
(3,254 Views)
Solution
Accepted by topic author tysonl

Or, much simpler, make the array into a cluster as I suggested:

unflatten struct.png

0 Kudos
Message 7 of 16
(3,243 Views)

@nathand wrote:

Or, much simpler, make the array into a cluster as I suggested:

unflatten struct.png


That is right but the data is obviously in Little Endian format from the example data he posted!

 

Little Endian = Little End first = LSB first

Rolf Kalbermatter
My Blog
Message 8 of 16
(3,225 Views)

@rolfk wrote:

That is right but the data is obviously in Little Endian format from the example data he posted!


Good point! I was focused on the array/cluster issue and didn't actually look at the data, I put the constant there to show that the input for endianness exists.

0 Kudos
Message 9 of 16
(3,220 Views)

I have tried using Unflatten From String, but I constantly get error 116 (Unflatten or byte stream read operation failed due to corrupt, unexpected, or truncated data).  If I clear the errors after the Unflatten From String, then the counter and status come out correct, but values is empty.  The simple code I am using is the following. Note, I have modified my device and my code to have values of length 3, not 20, in order to make it simpler to see all the data.tcp_client_some_data.png

 

 

 

 

0 Kudos
Message 10 of 16
(3,178 Views)