diff --git a/README.md b/README.md index f6f2d3d..cd260b3 100644 --- a/README.md +++ b/README.md @@ -57,9 +57,9 @@ void loop() { if (!async_rpc.result(sum)) { Monitor.println("Error calling method: add"); Monitor.print("Error code: "); - Monitor.println(async_rpc.error.code); + Monitor.println(async_rpc.getErrorCode()); Monitor.print("Error message: "); - Monitor.println(async_rpc.error.traceback); + Monitor.println(async_rpc.getErrorMessage()); } // Implicit boolean cast. Use with caution as in this case the call is indeed diff --git a/examples/simple_bridge/simple_bridge.ino b/examples/simple_bridge/simple_bridge.ino index 508098f..22eaba3 100644 --- a/examples/simple_bridge/simple_bridge.ino +++ b/examples/simple_bridge/simple_bridge.ino @@ -59,8 +59,8 @@ void loop() { Serial.print("Result of the operation is: "); Serial.println(res); } else { - Serial.println(outcome.error.code); - Serial.println(outcome.error.traceback); + Serial.println(outcome.getErrorCode()); + Serial.println(outcome.getErrorMessage()); } Bridge.notify("signal", 200); diff --git a/examples/test/test.ino b/examples/test/test.ino index 619bfaa..e03d662 100644 --- a/examples/test/test.ino +++ b/examples/test/test.ino @@ -64,8 +64,8 @@ void loop() { if (async_res.result(pow)) { Monitor.println("Result of assignment and then result: "+String(pow)); // returns true, so the right result } else { - Monitor.println("Error code: "+String(async_res.error.code)); - Monitor.println("Error message: "+async_res.error.traceback); + Monitor.println("Error code: "+String(async_res.getErrorCode())); + Monitor.println("Error message: "+async_res.getErrorMessage()); } float div = 0; @@ -73,8 +73,8 @@ void loop() { if (async_res1.result(div)) { Monitor.println("Result of assignment and then result: "+String(div)); // returns true, so the right result } else { - Monitor.println("Error code: "+String(async_res1.error.code)); - Monitor.println("Error message: "+async_res1.error.traceback); + Monitor.println("Error code: "+String(async_res1.getErrorCode())); + Monitor.println("Error message: "+async_res1.getErrorMessage()); } div = 0; @@ -82,8 +82,8 @@ void loop() { if (async_res2.result(div)) { Monitor.println("Result of assignment and then result: "+String(div)); // returns true, so the right result } else { - Monitor.println("Error code: "+String(async_res2.error.code)); - Monitor.println("Error message: "+async_res2.error.traceback); + Monitor.println("Error code: "+String(async_res2.getErrorCode())); + Monitor.println("Error message: "+async_res2.getErrorMessage()); } x = false; @@ -91,7 +91,7 @@ void loop() { if (async_res3.result(x)) { Monitor.println("Result of assignment and then result: "+String(x)); // returns true, so the right result } else { - Monitor.println("Error expecting bool result: "+String(async_res3.error.code)); + Monitor.println("Error expecting bool result: "+String(async_res3.getErrorCode())); } // Avoid the following: diff --git a/src/bridge.h b/src/bridge.h index 8e684d0..e0f2069 100644 --- a/src/bridge.h +++ b/src/bridge.h @@ -27,22 +27,56 @@ #include #include +#include + void updateEntryPoint(void *, void *, void *); template class RpcCall { + + RpcError error; + + void setError(int code, MsgPack::str_t text) { + k_mutex_lock(&call_mutex, K_FOREVER); + error.code = code; + error.traceback = std::move(text); + k_mutex_unlock(&call_mutex); + } + public: - RpcError error{GENERIC_ERR, "This call is not executed yet"}; - RpcCall(const MsgPack::str_t& m, RPCClient* c, struct k_mutex* rm, struct k_mutex* wm, Args&&... args): method(m), client(c), read_mutex(rm), write_mutex(wm), callback_params(std::forward_as_tuple(std::forward(args)...)) {} + RpcCall(const MsgPack::str_t& m, RPCClient* c, struct k_mutex* rm, struct k_mutex* wm, Args&&... args): method(m), client(c), read_mutex(rm), write_mutex(wm), callback_params(std::forward_as_tuple(std::forward(args)...)) { + k_mutex_init(&call_mutex); + setError(GENERIC_ERR, "This call is not yet executed"); + } + + bool isError() { + k_mutex_lock(&call_mutex, K_FOREVER); + const bool out = error.code > NO_ERR; + k_mutex_unlock(&call_mutex); + return out; + } + + int getErrorCode() { + k_mutex_lock(&call_mutex, K_FOREVER); + const int out = error.code; + k_mutex_unlock(&call_mutex); + return out; + } + + MsgPack::str_t getErrorMessage() { + k_mutex_lock(&call_mutex, K_FOREVER); + MsgPack::str_t out = error.traceback; + k_mutex_unlock(&call_mutex); + return out; + } template bool result(RType& result) { if (!atomic_cas(&_executed, 0, 1)){ // this thread lost the race - error.code = GENERIC_ERR; - error.traceback = "This call result is no longer available"; + setError(GENERIC_ERR, "This call is no longer available"); return false; } @@ -60,13 +94,15 @@ class RpcCall { while(true) { if (k_mutex_lock(read_mutex, K_MSEC(10)) == 0 ) { - if (client->get_response(msg_id_wait, result, error)) { + RpcError temp_err; + if (client->get_response(msg_id_wait, result, temp_err)) { 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); // } + setError(temp_err.code, temp_err.traceback); break; } k_mutex_unlock(read_mutex); @@ -76,7 +112,7 @@ class RpcCall { } } - return error.code == NO_ERR; + return !isError(); } bool result() { @@ -100,6 +136,7 @@ class RpcCall { RPCClient* client; struct k_mutex* read_mutex; struct k_mutex* write_mutex; + struct k_mutex call_mutex{}; std::tuple callback_params; }; diff --git a/src/monitor.h b/src/monitor.h index 4c5f70f..d84d662 100644 --- a/src/monitor.h +++ b/src/monitor.h @@ -31,6 +31,7 @@ class BridgeMonitor: public Stream { RingBufferN temp_buffer; struct k_mutex monitor_mutex{}; bool _connected = false; + bool _debug_mode = false; public: explicit BridgeMonitor(BridgeClass& bridge): bridge(&bridge) {} @@ -56,6 +57,20 @@ class BridgeMonitor: public Stream { return out; } + void setDebugMode(bool debug_mode) { + k_mutex_lock(&monitor_mutex, K_FOREVER); + _debug_mode = debug_mode; + k_mutex_unlock(&monitor_mutex); + } + + bool debugMode() { + bool debug_mode; + k_mutex_lock(&monitor_mutex, K_FOREVER); + debug_mode = _debug_mode; + k_mutex_unlock(&monitor_mutex); + return debug_mode; + } + bool is_connected() { k_mutex_lock(&monitor_mutex, K_FOREVER); bool out = _connected; @@ -114,10 +129,14 @@ class BridgeMonitor: public Stream { send_buffer += static_cast(buffer[i]); } - size_t written; - const bool ret = bridge->call(MON_WRITE_METHOD, send_buffer).result(written); + size_t written = 0; + if (debugMode()) { + bridge->call(MON_WRITE_METHOD, send_buffer).result(written); + } else { + bridge->notify(MON_WRITE_METHOD, send_buffer); + } - return ret? written : 0; + return written; } bool reset() { @@ -151,7 +170,7 @@ class BridgeMonitor: public Stream { } } - // if (async_rpc.error.code > NO_ERR) { + // if (async_rpc.getErrorCode() > NO_ERR) { // _connected = false; // } diff --git a/src/tcp_client.h b/src/tcp_client.h index 8a26e30..39c851d 100644 --- a/src/tcp_client.h +++ b/src/tcp_client.h @@ -202,7 +202,7 @@ class BridgeTCPClient : public Client { } } - if (async_rpc.error.code > NO_ERR) { + if (async_rpc.getErrorCode() > NO_ERR) { _connected = false; }