Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,84 @@

A MessagePack RPC library for Arduino allows to create a client/server architecture using MessagePack as the serialization format. It follows the [MessagePack-RPC protocol specification](https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md). It is designed to be lightweight and easy to use, making it suitable for embedded systems and IoT applications.


## Server

```cpp
#include <Arduino_RPClite.h>

RPCServer server(Serial1);

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

String loopback(String message){
return message;
}

void setup() {
Serial1.begin(115200);
while(!Serial1);

Serial.begin(9600);
while(!Serial);

server.bind("add", add);
server.bind("loopback", loopback);

}

void loop() {
server.run();
}

```


## Client

```cpp
#include <Arduino_RPClite.h>

RPCClient client(Serial1);

void setup() {
Serial1.begin(115200);
while(!Serial1);

pinMode(LED_BUILTIN, OUTPUT);

Serial.begin(9600);
while(!Serial);
}

void loop() {

bool ok;

String response;
ok = client.call("loopback", response, "Sending a greeting");
if (ok) Serial.println(str_res);

int sum_result;
ok = client.call("add", sum_result, 2. 3);
if (ok) Serial.println(sum_result); // must print 5

// ERROR handling
float result;
bool ok = client.call("unbound_method", result, 10.0);
if (!ok) {
Serial.print("Testing Server-side exception OK. ERR code: ");
Serial.print(client.lastError.code);
Serial.print(" ERR trace: ");
Serial.println(client.lastError.traceback);
}

}

```

### Credits

This library is based on the MsgPack library by @hideakitai.
7 changes: 4 additions & 3 deletions examples/rpc_lite_client/rpc_lite_client.ino
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#include <Arduino_RPClite.h>

SerialTransport transport(&Serial1);
RPCClient client(transport);
RPCClient client(Serial1);

void setup() {
Serial1.begin(115200);
transport.begin();
while(!Serial1);

pinMode(LED_BUILTIN, OUTPUT);

Serial.begin(9600);
while(!Serial);
}
Expand Down
14 changes: 8 additions & 6 deletions examples/rpc_lite_server/rpc_lite_server.ino
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
#include <Arduino_RPClite.h>

SerialTransport transport(&Serial1);
RPCServer server(transport);
RPCServer server(Serial1);

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

MsgPack::str_t greet(){
return MsgPack::str_t ("Hello Friend");
String greet(){
return String("Hello Friend");
}

MsgPack::str_t loopback(MsgPack::str_t message){
String loopback(String message){
return message;
}

Expand All @@ -27,13 +26,16 @@ public:

void setup() {
Serial1.begin(115200);
transport.begin();
while(!Serial1);

pinMode(LED_BUILTIN, OUTPUT);

Serial.begin(9600);
while(!Serial);

server.bind("add", add);
server.bind("greet", greet);
server.bind("loopback", loopback);
server.bind("another_greeting", [] {return MsgPack::str_t ("This is a lambda greeting");});
server.bind("object_multi", &multiplier::mult);

Expand Down
2 changes: 2 additions & 0 deletions src/SerialTransport.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class SerialTransport: public ITransport {

SerialTransport(Stream* stream): _stream(stream){}

SerialTransport(Stream& stream): _stream(&stream){}

void begin(){}

bool available() override {
Expand Down
20 changes: 13 additions & 7 deletions src/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,39 @@
#define RPCLITE_CLIENT_H
#include "error.h"
#include "decoder_manager.h"
#include "SerialTransport.h"


class RPCClient {
ITransport& transport;
RpcDecoder<>& decoder;
RpcDecoder<>* decoder = nullptr;

public:
RpcError lastError;

RPCClient(ITransport& t) : transport(t), decoder(RpcDecoderManager<>::getDecoder(t)) {}
RPCClient(ITransport& t) : decoder(&RpcDecoderManager<>::getDecoder(t)) {}

RPCClient(Stream& stream) {
ITransport* transport = (ITransport*) new SerialTransport(stream);
decoder = &RpcDecoderManager<>::getDecoder(*transport);
}

template<typename... Args>
void notify(const MsgPack::str_t method, Args&&... args) {
int _id;
decoder.send_call(NOTIFY_MSG, method, _id, std::forward<Args>(args)...);
decoder->send_call(NOTIFY_MSG, method, _id, std::forward<Args>(args)...);
}

template<typename RType, typename... Args>
bool call(const MsgPack::str_t method, RType& result, Args&&... args) {

int msg_id;
if (!decoder.send_call(CALL_MSG, method, msg_id, std::forward<Args>(args)...)){
if (!decoder->send_call(CALL_MSG, method, msg_id, std::forward<Args>(args)...)){
}

RpcError error;
// blocking call
while (!decoder.get_response(msg_id, result, error)){
decoder.process();
while (!decoder->get_response(msg_id, result, error)){
decoder->process();
delay(1);
}

Expand Down
15 changes: 10 additions & 5 deletions src/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,30 @@
#include "dispatcher.h"
#include "decoder.h"
#include "decoder_manager.h"
#include "SerialTransport.h"

#define MAX_CALLBACKS 100

class RPCServer {
ITransport& transport;
RpcDecoder<>& decoder;
RpcDecoder<>* decoder = nullptr;
RpcFunctionDispatcher<MAX_CALLBACKS> dispatcher;

public:
RPCServer(ITransport& t) : transport(t), decoder(RpcDecoderManager<>::getDecoder(t)) {}
RPCServer(ITransport& t) : decoder(&RpcDecoderManager<>::getDecoder(t)) {}

RPCServer(Stream& stream) {
ITransport* transport = (ITransport*) new SerialTransport(stream);
decoder = &RpcDecoderManager<>::getDecoder(*transport);
}

template<typename F>
bool bind(const MsgPack::str_t& name, F&& func){
return dispatcher.bind(name, func);
}

void run() {
decoder.process();
decoder.process_requests(dispatcher);
decoder->process();
decoder->process_requests(dispatcher);
delay(1);
}

Expand Down