diff --git a/README.md b/README.md index 8eed4d7..e877494 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ void setup() { void loop() { float res; - if (!Bridge.call("multiply", res, 1.0, 2.0)) { + if (!Bridge.call("multiply", 1.0, 2.0).result(res)) { Serial.println("Error calling method: multiply"); Serial.println(Bridge.get_error_code()); Serial.println(Bridge.get_error_message()); diff --git a/examples/simple_bridge/simple_bridge.ino b/examples/simple_bridge/simple_bridge.ino index 6a1eccb..face5cc 100644 --- a/examples/simple_bridge/simple_bridge.ino +++ b/examples/simple_bridge/simple_bridge.ino @@ -47,11 +47,23 @@ void setup() { void loop() { float res; - if (!Bridge.call("multiply", res, 1.0, 2.0)) { + if (!Bridge.call("multiply", 1.0, 2.0).result(res)) { Serial.println("Error calling method: multiply"); Serial.println(Bridge.get_error_code()); Serial.println(Bridge.get_error_message()); }; + // Call with deferred response check + RpcResult outcome = Bridge.call("multiply", 5.0, 7.0); + Serial.println("RPC called"); + delay(10); + if (outcome.result(res)) { + Serial.print("Result of the operation is: "); + Serial.println(res); + } else { + Serial.println(Bridge.get_error_code()); + Serial.println(Bridge.get_error_message()); + } + Bridge.notify("signal", 200); } diff --git a/src/bridge.h b/src/bridge.h index 95faaab..7a2858c 100644 --- a/src/bridge.h +++ b/src/bridge.h @@ -16,6 +16,7 @@ #define RESET_METHOD "$/reset" #define BIND_METHOD "$/register" +//#define BRIDGE_ERROR "$/bridgeLog" #define UPDATE_THREAD_STACK_SIZE 500 #define UPDATE_THREAD_PRIORITY 5 @@ -28,6 +29,58 @@ void updateEntryPoint(void *, void *, void *); +class RpcResult { + +public: + RpcError error; + + RpcResult(uint32_t id, RPCClient* c, struct k_mutex* rm, struct k_mutex* wm) : msg_id_wait(id), client(c), read_mutex(rm), write_mutex(wm) {} + + template bool result(RType& result) { + if (_executed) return error.code == NO_ERR; + + while(true) { + if (k_mutex_lock(read_mutex, K_MSEC(10)) == 0 ) { + if (client->get_response(msg_id_wait, result, error)) { + k_mutex_unlock(read_mutex); + // if (error.code == PARSING_ERR) { + // k_mutex_lock(write_mutex, K_FOREVER); + // client->notify(BRIDGE_ERROR, error.traceback); + // k_mutex_unlock(write_mutex); + // } + break; + } + k_mutex_unlock(read_mutex); + k_msleep(1); + } else { + k_yield(); + } + } + _executed = true; + return error.code == NO_ERR; + } + + bool result() { + MsgPack::object::nil_t nil; + return result(nil); + } + + ~RpcResult(){ + result(); + } + + operator bool() { + return result(); + } + +private: + uint32_t msg_id_wait; + RPCClient* client; + bool _executed = false; + struct k_mutex* read_mutex; + struct k_mutex* write_mutex; +}; + class BridgeClass { RPCClient* client = nullptr; @@ -73,7 +126,7 @@ class BridgeClass { UPDATE_THREAD_PRIORITY, 0, K_NO_WAIT); bool res; - call(RESET_METHOD, res); + call(RESET_METHOD).result(res); if (res) { started = true; } @@ -83,7 +136,7 @@ class BridgeClass { template bool provide(const MsgPack::str_t& name, F&& func) { bool res; - if (!call(BIND_METHOD, res, name)) { + if (!call(BIND_METHOD, name).result(res)) { return false; } return server->bind(name, func); @@ -92,7 +145,7 @@ class BridgeClass { template bool provide_safe(const MsgPack::str_t& name, F&& func) { bool res; - if (!call(BIND_METHOD, res, name)) { + if (!call(BIND_METHOD, name).result(res)) { return false; } @@ -131,8 +184,8 @@ class BridgeClass { } - template - bool call(const MsgPack::str_t& method, RType& result, Args&&... args) { + template + RpcResult call(const MsgPack::str_t& method, Args&&... args) { uint32_t msg_id_wait; @@ -145,26 +198,11 @@ class BridgeClass { } else { k_yield(); } - } - - // Lock read mutex - while(true) { - if (k_mutex_lock(&read_mutex, K_MSEC(10)) == 0 ) { - if (client->get_response(msg_id_wait, result)) { - k_mutex_unlock(&read_mutex); - break; - } - k_mutex_unlock(&read_mutex); - k_msleep(1); - } else { - k_yield(); - } - - } + } + return RpcResult{msg_id_wait, client, &read_mutex, &write_mutex}; + } - return (client->lastError.code == NO_ERR); - } template void notify(const MsgPack::str_t method, Args&&... args) { diff --git a/src/monitor.h b/src/monitor.h index 99154d0..bac7465 100644 --- a/src/monitor.h +++ b/src/monitor.h @@ -44,7 +44,7 @@ class BridgeMonitor: public Stream { if (!bridge_started) { bridge_started = bridge->begin(); } - return bridge_started && bridge->call(MON_CONNECTED_METHOD, is_connected); + return bridge_started && bridge->call(MON_CONNECTED_METHOD).result(is_connected); } explicit operator bool() const { @@ -99,7 +99,7 @@ class BridgeMonitor: public Stream { } size_t written; - const bool ret = bridge->call(MON_WRITE_METHOD, written, send_buffer); + const bool ret = bridge->call(MON_WRITE_METHOD, send_buffer).result(written); if (ret) { return written; } @@ -109,7 +109,7 @@ class BridgeMonitor: public Stream { bool reset() { bool res; - bool ok = bridge->call(MON_RESET_METHOD, res); + bool ok = bridge->call(MON_RESET_METHOD).result(res); if (ok && res) { is_connected = false; } @@ -121,25 +121,22 @@ class BridgeMonitor: public Stream { if (size == 0) return; - k_mutex_lock(&monitor_mutex, K_FOREVER); - MsgPack::arr_t message; - bool ret = bridge->call(MON_READ_METHOD, message, size); + bool ret = bridge->call(MON_READ_METHOD, size).result(message); if (ret) { + k_mutex_lock(&monitor_mutex, K_FOREVER); for (size_t i = 0; i < message.size(); ++i) { temp_buffer.store_char(static_cast(message[i])); } + k_mutex_unlock(&monitor_mutex); } // if (bridge.lastError.code > NO_ERR) { // is_connected = false; // } - - k_mutex_unlock(&monitor_mutex); } - }; extern BridgeClass Bridge; diff --git a/src/tcp_client.h b/src/tcp_client.h index 8874314..62da5e7 100644 --- a/src/tcp_client.h +++ b/src/tcp_client.h @@ -61,7 +61,7 @@ class BridgeTCPClient : public Client { k_mutex_lock(&client_mutex, K_FOREVER); - const bool resp = bridge->call(TCP_CONNECT_METHOD, connection_id, hostname, port); + const bool resp = bridge->call(TCP_CONNECT_METHOD, hostname, port).result(connection_id); if (!resp) { _connected = false; @@ -84,7 +84,7 @@ class BridgeTCPClient : public Client { k_mutex_lock(&client_mutex, K_FOREVER); - const bool resp = bridge->call(TCP_CONNECT_SSL_METHOD, connection_id, hostname, port, ca_cert_str); + const bool resp = bridge->call(TCP_CONNECT_SSL_METHOD, hostname, port, ca_cert_str).result(connection_id); if (!resp) { _connected = false; @@ -116,7 +116,7 @@ class BridgeTCPClient : public Client { } size_t written; - const bool ret = bridge->call(TCP_WRITE_METHOD, written, connection_id, payload); + const bool ret = bridge->call(TCP_WRITE_METHOD, connection_id, payload).result(written); if (ret) { return written; } @@ -170,7 +170,7 @@ class BridgeTCPClient : public Client { void stop() override { k_mutex_lock(&client_mutex, K_FOREVER); String msg; - const bool resp = bridge->call(TCP_CLOSE_METHOD, msg, connection_id); + const bool resp = bridge->call(TCP_CLOSE_METHOD, connection_id).result(msg); if (resp) { _connected = false; } @@ -198,7 +198,7 @@ class BridgeTCPClient : public Client { k_mutex_lock(&client_mutex, K_FOREVER); MsgPack::arr_t message; - const bool ret = bridge->call(TCP_READ_METHOD, message, connection_id, size); + const bool ret = bridge->call(TCP_READ_METHOD, connection_id, size).result(message); if (ret) { for (size_t i = 0; i < message.size(); ++i) { diff --git a/src/tcp_server.h b/src/tcp_server.h index ad4c0a5..f62e57d 100644 --- a/src/tcp_server.h +++ b/src/tcp_server.h @@ -52,7 +52,7 @@ class BridgeTCPServer final: public Server { k_mutex_lock(&server_mutex, K_FOREVER); String hostname = _addr.toString(); - _listening = bridge->call(TCP_LISTEN_METHOD, listener_id, hostname, _port); + _listening = bridge->call(TCP_LISTEN_METHOD, hostname, _port).result(listener_id); k_mutex_unlock(&server_mutex); @@ -70,7 +70,7 @@ class BridgeTCPServer final: public Server { k_mutex_lock(&server_mutex, K_FOREVER); - const bool ret = bridge->call(TCP_ACCEPT_METHOD, connection_id, listener_id); + const bool ret = bridge->call(TCP_ACCEPT_METHOD, listener_id).result(connection_id); k_mutex_unlock(&server_mutex); @@ -104,7 +104,7 @@ class BridgeTCPServer final: public Server { k_mutex_lock(&server_mutex, K_FOREVER); String msg; - const bool ret = bridge->call(TCP_CLOSE_LISTENER_METHOD, msg, listener_id); + const bool ret = bridge->call(TCP_CLOSE_LISTENER_METHOD, listener_id).result(msg); if (ret) { _listening = false;