jfjlaros / simpleRPC

Simple RPC implementation for Arduino.
MIT License
50 stars 17 forks source link

Question: Sending a request to RCP server and reading response. #23

Closed slaff closed 3 years ago

slaff commented 3 years ago

We are evaluating the use of SimpleRPC in Sming and for export functions and writing the server part this library is really great for us.

My question is how to implement also the client side in C/C++ using this library? For example we would like to have a function like this one:

uint8_t digitalRead(uint16_t pin)
{
    // TODO: send the "digitalRead" command with one parameter the pin
       // hostedClient.send("digitalRead", pin);

        // TODO: wait for response....
        // uint8_t result = hostedClient.wait(sizeof(uint8_t));

        return result;
}

The hostedClient after a successful connection will get the list of available functions. After that the send command will use the provided name as first argument to find the id of the command. And use the rest of the arguments to pass them directly to a client RPC function. Finally the hostedClient.wait will wait until the desired number of bytes are sent back.

Can we use rcpCall or rpcWrite somehow for sending the request to the RPC server?

jfjlaros commented 3 years ago

Just for my understanding, are you more or less searching for a C/C++ implementation of this library?

slaff commented 3 years ago

searching for a C/C++ implementation of this library?

Yes, to a degree. I just need the serialization part. It would have been great if simpleRPC was having a C++ wrapper that

Something like

wrap = WRAP(stream, digitalPin);
wrap.send();
wrap.wait(); // called only when the RCP remote function is having a return value.
jfjlaros commented 3 years ago

Okay, and should this wrapper run on an embedded device or on a desktop machine?

slaff commented 3 years ago

Okay, and should this wrapper run on an embedded device or on a desktop machine?

Desktop machine. Let me try to explain what we try to achieve.

For example the Basic_Blink sample can be compiled also on the desktop, or Host as we call it. When that application is compiled on the Host there is just a text message saying digital pin X was set to have value Y.

But it would have been great instead of faking the digital operations to actually run them on an existing microcontroller. The Host application will use simpleRPC and make a remote call to an already preflashed application (The RPC server) on the microcontroller. The application on the microcontroller will expose the needed functions (digitalRead, digitalWrite, pinMode, etc). We have already working PoC for this.

The last missing piece is how to easy and elegantly in C++ do what the python client library is doing. And to avoid writing a lot of boilerplate code that can probably be written with C++ templates. And I was just wondering if you have tried/played/did the client part for C++ ?

jfjlaros commented 3 years ago

I have to think about this some more, but here are my first thoughts. At the moment I see two ways of implementing this:

  1. A dynamical solution.
  2. A compile time solution.

I do not think is is possible to make a type safe dynamical solution. So a general purpose command line tool for any client can not be type safe.

A type safe compile time solution should be possible. Either by using the client code itself, or by constructing the function signatures from the client response, which can then be used to generate the host code using templates.

So I guess the next question is how generic the solution should be?

slaff commented 3 years ago

I have to think about this some more ... A type safe compile time solution should be possible.

Thank you for your efforts. Take your time. type safe compile time sounds good to me.

So I guess the next question is how generic the solution should be?

Well, I guess as generic as possible. But even less generic should also be fine.

jfjlaros commented 3 years ago

What do you think about the following approach?

This approach should work more or less as follows.

On the device, we define a function, e.g.,

int add(int a, int b) { return a + b; }

On the host, we can call this function as follows:

int result = call(add, 10, 20);
slaff commented 3 years ago

What do you think about the following approach?

Sounds great to me!

jfjlaros commented 3 years ago

Okay, I will give it some more thought and come back to you.

Is there any urgency?

slaff commented 3 years ago

Is there any urgency?

No, take your time :)

jfjlaros commented 3 years ago

I made a proof of concept.

The structure is as follows:

jfjlaros commented 3 years ago

Moved discussion to the new repository.