Issue with sending XDR serialized data fron C to Python - c

I am trying to serialize a structure in C using XDR and send the serialized data to python over a tcp socket.
I tried using xdrmem_create() to create an XDR stream , call appropriate pack functions and pass the character array to a socket, to achieve this but I get an EOF error on the python side when I try to deserialize the stream .
I was able to achieve this operation successfully between
C server and C client, also between
python server and python client.
I get an error only when I use it with C and Python.
C snippet
#include<rpc/rpc.h>
....
xdrmem_create(&xdrs, arr, MAXLENGTH, XDR_ENCODE);
if(!xdr_person(&xdrs,&pkt)){
printf("ERROR");
};
.....
send(new_fd, arr, MAXLENGTH, 0)
Python snippet
import xdrlib
.....
data = s.recv(4)
unpacker = xdrlib.Unpacker(data)
message_size = unpacker.unpack_uint()
data = s.recv(message_size)
unpacker.reset(data)
person={}
person["name"] = unpacker.unpack_string().decode()
person["age"] = unpacker.unpack_int()
person["flag"] = unpacker.unpack_bool()
person["errEnum"] = unpacker.unpack_enum()
I wonder if there is a mismatch between the way data is serialized in C and Python.

Related

How do I read OpenVINO IR models from memory with the OpenVINO C API

I am having trouble reading OpenVINO IR networks (XML and bin) from memory using ie_core_read_network_from_memory() in the OpenVINO 2021.4 C API ie_c_api.h.
I suspect that I am creating the network weight blob wrong, but I cannot find any information on how to create weight blobs correctly for networks.
I have read the OpenVINO C API docs but cannot deduce from docs what I am doing wrong. The OpenVINO code repo contains some C code samples, but none of the samples seem to use ie_core_read_network_from_memory().
Below is a cut out of the code I am having trouble with.
// void* dmem->data - network memory buffer (float32)
// size_t dmem->size - size of network memory buffer (bytes)
ie_core_t* ov_core = NULL;
IEStatusCode status = ie_core_create("", &ov_core);
if (status != OK)
{
// error handling
}
const dimensions_t weights_tensor_dims =
{ 4, { 1, 1, 1, dmem->size/sizeof(float) } };
tensor_desc_t weights_tensor_desc = { OIHW, weights_tensor_dims, FP32 };
ie_blob_t* ov_model_weight_blob = NULL;
status = ie_blob_make_memory_from_preallocated(
&weights_tensor_desc, dmem->data, dmem->size, &ov_model_weight_blob);
if (status != OK)
{
// error handling
}
// char* model_xml_desc - the model's XML string
uint8_t* ov_model_xml_content = (uint8_t*)model_xml_desc;
ie_network_t* ov_network = NULL;
size_t xml_sz = strlen(ov_model_xml_content);
status = ie_core_read_network_from_memory(
ov_core, ov_model_xml_content, xml_sz, ov_model_weight_blob, &ov_network);
if (status != OK)
{
// Always get "GENERAL_ERROR (-1)"
}
The code works fine down to the ie_core_read_network_from_memory() call which results in "GENERAL_ERROR".
I have tried two models that were converted from Tensorflow. One is a simple [X] -> [Y] regression model (single input value, single output value). The other is also a regression model [X_1, X_2, ..., X_9] -> [Y] (nine input values, single output value). They work fine when reading them from file with ie_core_read_network(), but for my use case I must provide the network as a binary memory buffer and XML string.
I would appreciate any help, either by pointing out what I am getting wrong or directing me to some code samples that use ie_core_read_network_from_memory().
System information:
Windows 10
OpenVINO v2021.4.689
Microsoft Visual Studio 2019
UPDATE: An Intel employee reached out to me in another forum and pointed out that there is a unit test for ie_core_read_network_from_memory(). The unit test successfully reads a network from memory and made clear that I was in fact using a faulty tensor description to produce the weight blob, just as I suspected. Apparently the weight blob descriptor should be one dimensional, have memory layout ANY and datatype U8 even though the model weights are fp32.
From the unit test:
std::string bin_std = TestDataHelpers::generate_model_path("test_model", "test_model_fp32.bin");
const char* bin = bin_std.c_str();
//...
std::vector<uint8_t> weights_content(content_from_file(bin, true));
tensor_desc_t weights_desc { ANY, { 1, { weights_content.size() } }, U8 };
However, simply changing the tensor descriptor was not enough to get my code to work so it remains for me to properly translate the C++ code from the unit test to my C environment before the issue to can be considered solved.
Thanks
Refer to tensor_desc struct and standard layout format.
Apart from that, it is recommended to use the Benchmark_app tool to test the inference performance.

NodeRed modbus data to float

I am a beginner with Node-Red and I would like to read the data of a meter via modbus and then display it in float format
With Modbus-Read node I'm getting this data:
How can I to convert in a float number like 407.555
thanks in advance for the help
Update 06/11/2021: I'tryng to convert the array recived from modbus but the result is wrong.
I try tu use a function like this:
let pay = msg.payload;
const buf = Buffer.allocUnsafe(4);
buf.writeInt16BE(pay[0],2);
buf.writeInt16BE(pay[1],0);
msg.payload = buf.readFloatBE(0);
return msg;
In NodeRed if I add a debug I can read
0x1f85
0xb40
so is the same reading using a different modbus reader but the conversion in nodered with the function is 3.700156759202689e-32 and the value right is 2.18

Parsing XML text on a MSP430F5529LP + CC3100Boost platform

I am working on a IOT project using MSP430F5529LP and CC3100Boost. The hardware is successfully connecting to the cloud and exchanging data. The response to the IOT devices is XML based. I am trying to parse the data. The following printf("\n%.*s\n", pch2-pch1-8, pch1 +8); extracts the data and prints to the console. Now in need to save this data to a variable. Here is my code snippet. The answer might be obvious, unfortunately I am failing to see it.
_i8 * databuffer;
char * pch0;
char * pch1;
char * pch2;
char data[7];
pch0 = strstr((char *)dataBuffer,"textResponse");
pch1 = strstr(pch0,"<text_1>");
pch2 = strstr(pch1,"</text_1>");
printf("\n%.*s\n", pch2-pch1-8, pch1 +8);
References:
Extract data between two delimiters
parsing the value in between two XML tags
MSP430G2121: looking for a xml library to parse xml text
Ensure that the data received is valid and of a length that will fit.
Print it to a string using sprintf() or equivalent function.
Print this string to the console with puts(the_string).

I2C output error when sending an array

I have recently started using Node-RED in a Raspberry Pi and my quest is to connect to a couple of I2C devices with the use of the node-red-contrib-i2c package.
One action which I am trying to do is to send an array of integers to the I2C device with the I2C output node but I always get the error
TypeError: String.isString is not a function
I have tried a couple of different syntax but without success. I have included an export of the flow below.
[{"id":"d2a2b073.e222c","type":"function","z":"e442e95f.6c2b98","name":"","func":"msg.address = 96;\nmsg.command = 48;\nmsg.payload = [85,85];\nreturn msg;","outputs":1,"noerr":0,"x":316,"y":243,"wires":[["7061e7e7.ac6f98","65101109.cf323"]]},{"id":"ce6f4bff.3bf998","type":"inject","z":"e442e95f.6c2b98","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":126,"y":244,"wires":[["d2a2b073.e222c"]]},{"id":"7061e7e7.ac6f98","type":"debug","z":"e442e95f.6c2b98","name":"","active":true,"console":"false","complete":"true","x":539,"y":263,"wires":[]},{"id":"65101109.cf323","type":"i2c out","z":"e442e95f.6c2b98","name":"","i2cdevice":"3d751c57.1120f4","address":"96","command":"","payload":"","count":"2","x":567,"y":223,"wires":[]},{"id":"3d751c57.1120f4","type":"i2c-device","z":"","device":"/dev/i2c-1","address":"100"}]
An example of the msg.payload sent:
msg.address = 96;
msg.command = 48;
msg.payload = [85,85];
return msg;

Parse JSON message manually in C

I need to parse manually, without external libraries, a JSON message coming from a server, in C language.
The message coming from server would be like:
{[CR+LF]
"Tmg": "R",[CR+LF]
"STP": 72[CR+LF]
}[CR+LF]
or
{[CR+LF]
"Tmg": "R",[CR+LF]
"STP": 150[CR+LF]
}[CR+LF]
I need the number after STP:. The number is different in each message structure, so I need to get that number from the JSON structure. I can't use external libraries because this code is in an embedded system and exernal code is not allowed.
I tried this following:
int main (){
const char response_message[35] = "{\r\n\"Tmg\":\"R\",\r\n\"STP\":72,\r\n}";
const char needle[8] = "P\":";
char *ret;
ret = strstr(response_message, needle);
printf("The number is: %s\n", ret);
return 0;
}
But obviously, I am getting this result:
The number is: P":72,
}
So I need to only get the number, how can I get this?
Thanks
You can use a hacked solution. Use strstr () to find "STP": then find the following , or } and extract the digits in between.
And that's a hack. Not guaranteed to work. For something that's guaranteed to work, you use a JSON parser.

Resources