1#ifndef Server_Side_RPC_h
2#define Server_Side_RPC_h
15#if !THINGSBOARD_ENABLE_DYNAMIC
18#if THINGSBOARD_ENABLE_DEBUG
19char constexpr SERVER_RPC_METHOD_NULL[] =
"Server-side RPC method name is NULL";
20char constexpr RPC_RESPONSE_NULL[] =
"Response JsonDocument is NULL, skipping sending";
21char constexpr NO_RPC_PARAMS_PASSED[] =
"No parameters passed with RPC, passing null JSON";
22char constexpr CALLING_RPC_CB[] =
"Calling subscribed callback for rpc with methodname (%s)";
29#if THINGSBOARD_ENABLE_DYNAMIC
30template <
typename Logger = DefaultLogger>
37template<
size_t MaxSubscriptions = DEFAULT_SUBSCRIPTION_AMOUNT,
size_t MaxRPC = DEFAULT_RPC_AMOUNT,
typename Logger = DefaultLogger>
59 template<
typename InputIterator>
60 bool RPC_Subscribe(InputIterator
const & first, InputIterator
const & last) {
61#if !THINGSBOARD_ENABLE_DYNAMIC
63 if (m_rpc_callbacks.
size() + size > m_rpc_callbacks.
capacity()) {
70 m_rpc_callbacks.
insert(m_rpc_callbacks.
end(), first, last);
84#if !THINGSBOARD_ENABLE_DYNAMIC
85 if (m_rpc_callbacks.
size() + 1 > m_rpc_callbacks.
capacity()) {
100 m_rpc_callbacks.
clear();
105 return API_Process_Type::JSON;
114#if THINGSBOARD_ENABLE_DEBUG
115 Logger::printfln(SERVER_RPC_METHOD_NULL);
121#if THINGSBOARD_ENABLE_STL
122 auto it = std::find_if(m_rpc_callbacks.
begin(), m_rpc_callbacks.
end(), [&method_name](
RPC_Callback const & rpc) {
123 char const * subscribedMethodName = rpc.Get_Name();
124 return (!Helper::String_IsNull_Or_Empty(subscribedMethodName) && strncmp(subscribedMethodName, method_name, strlen(subscribedMethodName)) == 0);
126 if (it != m_rpc_callbacks.
end()) {
129 for (
auto const & rpc : m_rpc_callbacks) {
130 char const * subscribedMethodName = rpc.
Get_Name();
135#if THINGSBOARD_ENABLE_DEBUG
137 Logger::printfln(NO_RPC_PARAMS_PASSED);
141#if THINGSBOARD_ENABLE_DEBUG
142 Logger::printfln(CALLING_RPC_CB, method_name);
146#if THINGSBOARD_ENABLE_DYNAMIC
147 auto const & rpc_response_size = rpc.Get_Response_Size();
148 TBJsonDocument json_buffer(rpc_response_size);
150 size_t constexpr rpc_response_size = MaxRPC;
151 StaticJsonDocument<JSON_OBJECT_SIZE(MaxRPC)> json_buffer;
155 if (json_buffer.isNull()) {
156#if THINGSBOARD_ENABLE_DEBUG
157 Logger::printfln(RPC_RESPONSE_NULL);
161 else if (json_buffer.overflowed()) {
169 (void)m_send_json_callback.
Call_Callback(responseTopic, json_buffer);
190#if !THINGSBOARD_USE_ESP_TIMER
200 void Set_Client_Callbacks(
Callback<void, IAPI_Implementation &>::function subscribe_api_callback,
Callback<bool, char const * const, JsonDocument const &>::function send_json_callback,
Callback<bool, char const * const, char const * const>::function send_json_string_callback,
Callback<bool, char const * const>::function subscribe_topic_callback,
Callback<bool, char const * const>::function unsubscribe_topic_callback,
Callback<uint16_t>::function get_receive_size_callback,
Callback<uint16_t>::function get_send_size_callback,
Callback<bool, uint16_t, uint16_t>::function set_buffer_size_callback,
Callback<size_t *>::function get_request_id_callback)
override {
202 m_subscribe_topic_callback.Set_Callback(subscribe_topic_callback);
203 m_unsubscribe_topic_callback.Set_Callback(unsubscribe_topic_callback);
207#if THINGSBOARD_ENABLE_DYNAMIC
216 Callback_Container m_rpc_callbacks = {};
API_Process_Type
Possible processing types an API Implementation uses to handle responses from the server.
Definition: API_Process_Type.h:19
char constexpr MAX_SUBSCRIPTIONS_TEMPLATE_NAME[]
Definition: IAPI_Implementation.h:22
char constexpr RPC_PARAMS_KEY[]
Definition: IAPI_Implementation.h:27
char constexpr SUBSCRIBE_TOPIC_FAILED[]
Definition: IAPI_Implementation.h:23
char constexpr MAX_SUBSCRIPTIONS_EXCEEDED[]
Definition: IAPI_Implementation.h:20
char constexpr RPC_METHOD_KEY[]
Definition: IAPI_Implementation.h:26
char constexpr RPC_RESPONSE_OVERFLOWED[]
Definition: Server_Side_RPC.h:14
char constexpr RPC_REQUEST_TOPIC[]
Definition: Server_Side_RPC.h:11
char constexpr SERVER_SIDE_RPC_SUBSCRIPTIONS[]
Definition: Server_Side_RPC.h:16
char constexpr RPC_SUBSCRIBE_TOPIC[]
Definition: Server_Side_RPC.h:10
char constexpr RPC_SEND_RESPONSE_TOPIC[]
Definition: Server_Side_RPC.h:12
General purpose safe callback wrapper. Expects either c-style or c++ style function pointer,...
Definition: Callback.h:30
std::function< return_type(argument_types... arguments)> function
Callback signature.
Definition: Callback.h:34
void Set_Callback(function callback)
Sets the callback method that will be called upon data arrival with the given data that was received....
Definition: Callback.h:72
return_type Call_Callback(argument_types const &... arguments) const
Calls the callback that was subscribed, when this class instance was initally created.
Definition: Callback.h:62
Custom std::array or std::vector implementation that contains a partial vector-like interface impleme...
Definition: Container.h:29
size_type size() const
Gets the current amount of elements in the underlying data container.
Definition: Container.h:147
iterator begin()
Returns an iterator to the first element of the underlying data container. If the array is empty,...
Definition: Container.h:165
void insert(iterator position, InputIterator const &first, InputIterator const &last)
Copies all elements from the given start to exclusively the given end iterator into the underlying da...
Definition: Container.h:257
size_type constexpr capacity() const
Gets the maximum amount of elements that can be stored in the underlying data container.
Definition: Container.h:157
void push_back(const_reference element)
Appends the given element at the end of the underlying data container.
Definition: Container.h:230
bool empty() const
Returns whether there are any elements in the underlying data container.
Definition: Container.h:141
void clear()
Erases all elements from the container. After this call, size() returns zero.
Definition: Container.h:330
iterator end()
Returns a iterator to one-past-the-last element of the underlying data container.
Definition: Container.h:209
static size_t Calculate_Print_Size(char const *format, Args const &... args)
Returns the total amount of bytes needed to store the formatted string with null termination,...
Definition: Helper.h:32
static size_t distance(InputIterator const &first, InputIterator const &last)
Calculates the distance between two iterators.
Definition: Helper.h:85
static bool String_IsNull_Or_Empty(char const *str)
Returns wheter the given string is either a nullptr or is an empty string, meaning it only contains a...
Definition: Helper.cpp:27
static size_t Split_Topic_Into_Request_ID(char const *received_topic, size_t const &end_position)
Splits the topic at the given position and extracts the request id parameter from the remaining strin...
Definition: Helper.cpp:31
Base functionality required by all API implementation.
Definition: IAPI_Implementation.h:37
Server-side RPC callback wrapper, contains the needed configuration settings to create the request th...
Definition: RPC_Callback.h:12
char const * Get_Name() const
Gets the name we expect to be sent with the server-side RPC request so that this method callback will...
Definition: RPC_Callback.h:45
Handles the internal implementation of the ThingsBoard server-side RPC API. See https://thingsboard....
Definition: Server_Side_RPC.h:39
void Process_Json_Response(char const *topic, JsonDocument const &data) override
Process callback that will be called upon response arrival.
Definition: Server_Side_RPC.h:112
bool Resubscribe_Permanent_Subscriptions() override
Forwards the call to let the API clear up any ongoing single-event subscriptions (Provision,...
Definition: Server_Side_RPC.h:182
Server_Side_RPC()=default
Constructor.
bool RPC_Subscribe(RPC_Callback const &callback)
Subscribe one server-side RPC callback, that will be called if a request from the server for the meth...
Definition: Server_Side_RPC.h:83
bool Is_Response_Topic_Matching(char const *topic) const override
Compares received response topic and the topic this api implementation handles responses on,...
Definition: Server_Side_RPC.h:174
API_Process_Type Get_Process_Type() const override
Returns the way the server response should be processed.
Definition: Server_Side_RPC.h:104
bool RPC_Subscribe(InputIterator const &first, InputIterator const &last)
Subscribes multiple server-side RPC callbacks, that will be called if a request from the server for t...
Definition: Server_Side_RPC.h:60
~Server_Side_RPC() override=default
void Set_Client_Callbacks(Callback< void, IAPI_Implementation & >::function subscribe_api_callback, Callback< bool, char const *const, JsonDocument const & >::function send_json_callback, Callback< bool, char const *const, char const *const >::function send_json_string_callback, Callback< bool, char const *const >::function subscribe_topic_callback, Callback< bool, char const *const >::function unsubscribe_topic_callback, Callback< uint16_t >::function get_receive_size_callback, Callback< uint16_t >::function get_send_size_callback, Callback< bool, uint16_t, uint16_t >::function set_buffer_size_callback, Callback< size_t * >::function get_request_id_callback) override
Sets the underlying callbacks that are required for the different API Implementation to communicate w...
Definition: Server_Side_RPC.h:200
void Process_Response(char const *topic, uint8_t *payload, uint32_t length) override
Process callback that will be called upon response arrival.
Definition: Server_Side_RPC.h:108
bool Unsubscribe() override
Unsubcribes all callbacks, to clear up any ongoing subscriptions and stop receiving information over ...
Definition: Server_Side_RPC.h:178
void loop() override
Internal loop method to update inernal timers for API calls that can timeout.
Definition: Server_Side_RPC.h:191
void Initialize() override
Method that allows to construct internal objects, after the required callback member methods have bee...
Definition: Server_Side_RPC.h:196
bool RPC_Unsubscribe()
Unsubcribes all server-side RPC callbacks. See https://thingsboard.io/docs/user-guide/rpc/#server-sid...
Definition: Server_Side_RPC.h:99