1

I'm trying to send a parcel through a socket to an android application. The client is in libbinder(c++) and the server is an android application that will have to rebuild the parcel. I have been looking for a solution for some time but I don't know how to serialize the parcel and then re-build it on the server side. Any ideas on how this can be done?

Thanks

The part of code where I handle the data

Client

Parcel parc = Parcel();
double three = 5.5;
parc.writeDouble(three);

unsigned char b[sizeof(parc)];
std::memcpy(b, &parc, sizeof(parc));

Then I send like this

send(client, b, sizeof(b), 0);

Server

private int count
private InputStream in = null;
try {
    in = socket.getInputStream();
} catch (IOException e) {
    e.printStackTrace();
}
try {
    count = in.read(bytes);
}catch (IOException e) {
    e.printStackTrace();
}

Parcel parcel = Parcel.obtain();
parcel.unmarshall(bytes, 0, bytes.length);
parcel.setDataPosition(0);

double d = parcel.readDouble();

Log.v("----double---", "double" + d);
Pedro Maltez
  • 87
  • 1
  • 11

1 Answers1

0

A good example can be found here.

In general, you will need to make sure that you have the classes available to reconstruct (create from parcel) the objects.

Community
  • 1
  • 1
David Wasser
  • 93,459
  • 16
  • 209
  • 274
  • So... From what I realized from that example I can re-build a parcel from a byte array with the unmarshall function. Any idea on how to serialize the parcel on the client side, libbinder(c++)? – Pedro Maltez Dec 12 '16 at 13:47
  • Easiest way is to look at the [source code of the `Parcel` class](http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/os/Parcel.java#Parcel.writeByte%28byte%29). Basically, it is just a serialized byte stream. Look a the method `writeValue()`. You can see that for each item, it writes code indicating what the item is, followed by the serialized byes of the item. Create a simple program that parcels a bunch of different known types and then dumps the byte stream. You should be able to figure it out. – David Wasser Dec 12 '16 at 14:39
  • Source code for `Parcel.cpp` can be found here: https://android.googlesource.com/platform/frameworks/native/+/jb-mr1-release/libs/binder/Parcel.cpp If you are using libbinder, you should be able to use the `Parcel` class directly. – David Wasser Dec 12 '16 at 14:43
  • I created a program that parcels items and then sends the parcel through the socket. I used to put it on a byte array using memcpy (I think the problem might be here) and then send the byte array but the result is the same. On the server side I receive from the socket through an inputstream and read to a byte array. Then I use the unmarshal function to create a parcel. When I read the items the values are not correct. Does this mean that I can't pass the parcel over the socket or will it be due to compatibility problems between c++/java? Sorry for bothering you but I'm really stuck – Pedro Maltez Dec 12 '16 at 22:24
  • You should be able to do this. Can you inspect the byte stream that you get and see what it looks like? You are probably just off by a few bytes or maybe the byte ordering (LSB/MSB) is different. Post the code you use to send and receive. – David Wasser Dec 14 '16 at 10:47
  • I've edited my post with the part of the code where I handle the data that will be sent/received. SInce I didn't know if you receive a notification I've commented. I'm not sendig in a while loop because I can't introduce a loop in libbinder. It's just ignored – Pedro Maltez Dec 15 '16 at 15:33
  • You are sending the entire `Parcel` object. That's not going to work. You need to just send the data. Instead of using `memcpy()` to get the data, you should call `Parcel::ipcData()` to get the data and `Parcel::ipcDataSize()` to get the size of the data. Look at the source code for `Parcel` here: https://android.googlesource.com/platform/frameworks/native/+/jb-dev/libs/binder/Parcel.cpp The Java part of your code looks correct. – David Wasser Dec 15 '16 at 17:54