Repository: org-arl/unet-contrib (language: python)

Issue:
UnetSocket C API receive fails due to outdated fjage C API
Testing on both Ubuntu 20.04 LTS and MacOS Ventura beta, the UnetSocket C API can successfully transmit data, but consistently received corrupted data. 

Instructions to reproduce:
- clone unet-contrib
- navigate to c gateway directory
- "make", "make rxdata", "make txdata"
- launch Unet 3.4.0 sample 2-node-network
- "samples/rxdata localhost 1101" and "samples/txdata localhost 232 1102"

If the issue is successfully reproduced, and output like this should be observed:
`Connecting to localhost:1101
Waiting for a Datagram
Received a org.arl.unet.DatagramNtf : [0,232,210,31,116,34,127,0,0,]
Reception Complete
`

Potential Solution:
- replace b49c7ac1b071ded3dbd2a58db39818da54a202ba with 229b37c063eec87870cf129dbf94f766a97d0cb0 in the Makefile (which corresponds to v1.9.1 of fjage)
- "make clean", "make", "make rxdata", "make txdata"
- launch Unet 3.4.0 sample 2-node-network
- "samples/rxdata localhost 1101" and "samples/txdata localhost 232 1102"

When I perform the above steps to update fjage, my output becomes:
`Connecting to localhost:1101
Waiting for a Datagram
Received a org.arl.unet.DatagramNtf : [1,2,3,4,5,6,7,8,9,]
Reception Complete`

Which is the correct representation of the data sent.

It is also worth noting that the test for data reception in test_unet.c only checks to make sure the class is equal to org.arl.unet.DatagramNtf, but takes no steps to ensure that the data transmitted is received correctly. This means that even though data transmitted was not being received correctly, the test was passing. This meant that the issue was impossible to spot via testing before shipping the update.



Discussion / hints:

Fix patch:
diff --git a/unetsocket/c/Makefile b/unetsocket/c/Makefile
index 3a899e6..c1d955b 100644
--- a/unetsocket/c/Makefile
+++ b/unetsocket/c/Makefile
@@ -1,6 +1,6 @@
 CC = gcc
 CFLAGS += -std=c99 -Wall -Wextra -Werror -Wfloat-equal -Wconversion -Wparentheses -pedantic -Wunused-parameter -Wunused-variable -Wreturn-type -Wno-unused-function -Wredundant-decls -Wreturn-type -Wunused-value -Wswitch-default -Wuninitialized -Winit-self -O2
-FJAGE_VER=b49c7ac1b071ded3dbd2a58db39818da54a202ba
+FJAGE_VER=229b37c063eec87870cf129dbf94f766a97d0cb0
 FJAGE_DIR=fjage-$(FJAGE_VER)
 BUILD = build
 BUILD_API = $(BUILD)/api


Test patch:
diff --git a/unetsocket/c/test/test_unet.c b/unetsocket/c/test/test_unet.c
index 49e2903..8fc4215 100644
--- a/unetsocket/c/test/test_unet.c
+++ b/unetsocket/c/test/test_unet.c
@@ -64,7 +64,8 @@ int main(int argc, char* argv[]) {
   int rv;
   int port_tx = 1100;
   int port_rx = 1100;
-  uint8_t data[7] = {1,2,3,4,5,6,7};
+  uint8_t data_tx[7] = {1,2,3,4,5,6,7};
+  uint8_t data_rx[7] = {0,0,0,0,0,0,0};
   float range = 0;
   int framelength = 0;
   float powerlevel = 0;
@@ -118,7 +119,7 @@ int main(int argc, char* argv[]) {
   if (rv == 0) printf("Range measured is : %f \n", range);
   test_assert("Ranging", rv == 0);
   // send data
-  rv = unetsocket_send(sock_tx, data, 7, rx_node_address, DATA);
+  rv = unetsocket_send(sock_tx, data_tx, 7, rx_node_address, DATA);
   test_assert("unetsocket_send", rv == 0);
   // bind to protocol
   if (unetsocket_bind(sock_rx, 0) == 0 && unetsocket_bind(sock_rx, USER+1) == 0 && unetsocket_bind(sock_rx, 10) == -1) {
@@ -159,10 +160,17 @@ int main(int argc, char* argv[]) {
   trv = unetsocket_get_timeout(sock_tx);
   test_assert("unetsocket_get_timeout", trv == -1);
   // receive
-  unetsocket_send(sock_tx, data, 7, rx_node_address, DATA);
+  unetsocket_send(sock_tx, data_tx, 7, rx_node_address, DATA);
   unetsocket_set_timeout(sock_rx, 10000);
   ntf = unetsocket_receive(sock_rx);
-  test_assert("unetsocket_receive", strcmp("org.arl.unet.DatagramNtf", fjage_msg_get_clazz(ntf))==0);
+  fjage_msg_get_byte_array(ntf, "data", data_rx, 7);
+  bool rx_test_data_match_flag = true;
+  for (int i = 0; i < 7; i++) {
+    if (data_tx[i] != data_rx[i]) {
+      rx_test_data_match_flag = false;
+    }
+  }
+  test_assert("unetsocket_receive", strcmp("org.arl.unet.DatagramNtf", fjage_msg_get_clazz(ntf))==0 && rx_test_data_match_flag);
   fjage_msg_destroy(ntf);
   // power level
   rv = unetsocket_ext_set_powerlevel(sock_tx, 1, -6);