Skip to content
This repository was archived by the owner on Oct 27, 2025. It is now read-only.

Commit 519954d

Browse files
committed
add function for RPC calls
1 parent db8f36e commit 519954d

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

include/thingsboard.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,20 @@ time_t thingsboard_time_msec(void);
4040
*/
4141
int thingsboard_send_telemetry(const void *payload, size_t sz);
4242

43+
/**
44+
* This callback will be called when the response for an RPC call
45+
* was received from the Thingsboard server.
46+
*/
47+
typedef void (*rpc_callback_t)(const uint8_t *data, size_t len);
48+
49+
/**
50+
* Send RPC call.
51+
* 'method' is required, a callback in case the call returns data, too.
52+
* Parameters are an optional string in JSON format as the variadic arguments
53+
* See https://thingsboard.io/docs/reference/coap-api/#client-side-rpc for details.
54+
*/
55+
void thingsboard_rpc(const char *method, rpc_callback_t cb, ...);
56+
4357
struct tb_fw_id {
4458
/** Title of your firmware, e.g. <project>-prod. This
4559
* must match to what you configure on your thingsboard

src/thingsboard.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#include "thingsboard.h"
22

33
#include <string.h>
4+
#include <stdio.h>
45

56
#include <zephyr/kernel.h>
67
#include <zephyr/net/coap.h>
8+
#include <zephyr/net/http/client.h>
79
#include <thingsboard_attr_parser.h>
810

911
#include "coap_client.h"
@@ -22,6 +24,7 @@ static struct {
2224
K_SEM_DEFINE(time_sem, 0, 1);
2325

2426
static attr_write_callback_t attribute_cb;
27+
static rpc_callback_t rpc_cb;
2528

2629
static void client_request_time(struct k_work *work);
2730
K_WORK_DELAYABLE_DEFINE(work_time, client_request_time);
@@ -189,6 +192,68 @@ static void client_request_time(struct k_work *work)
189192
k_work_reschedule(k_work_delayable_from_work(work), K_SECONDS(10));
190193
}
191194

195+
static int client_handle_rpc_response(struct coap_client_request *req, struct coap_packet *response)
196+
{
197+
const uint8_t *payload;
198+
uint16_t payload_len;
199+
uint8_t code;
200+
char code_str[5];
201+
char expected_code_str[5];
202+
203+
LOG_INF("%s", __func__);
204+
205+
code = coap_header_get_code(response);
206+
if (code != COAP_RESPONSE_CODE_CONTENT) {
207+
coap_response_code_to_str(code, code_str);
208+
coap_response_code_to_str(COAP_RESPONSE_CODE_CONTENT, expected_code_str);
209+
LOG_ERR("Unexpected response code for RPC request: got %s, expected %s", code_str,
210+
expected_code_str);
211+
return -1;
212+
}
213+
214+
payload = coap_packet_get_payload(response, &payload_len);
215+
if (!payload_len) {
216+
LOG_ERR("Received an empty RCP response");
217+
return payload_len;
218+
}
219+
220+
if (rpc_cb) {
221+
rpc_cb(payload, payload_len);
222+
}
223+
224+
return 0;
225+
}
226+
227+
void thingsboard_rpc(const char *method, rpc_callback_t cb, ...)
228+
{
229+
int err;
230+
va_list param;
231+
char params[64];
232+
char payload[128];
233+
234+
if (method == NULL) {
235+
LOG_ERR("method name must not be 'NULL'");
236+
return;
237+
}
238+
239+
va_start(param, cb);
240+
bool params_exist = vsnprintf(params, sizeof(params), "%s", param) > 0 ? true : false;
241+
if (!params_exist) {
242+
strcpy(params, "{}");
243+
}
244+
va_end(param);
245+
246+
snprintf(payload, sizeof(payload), "{\"method\":\"%s\", \"params\": %s}", method, params);
247+
const uint8_t *uri[] = {"api", "v1", access_token, "rpc", NULL};
248+
249+
err = coap_client_make_request(uri, payload, strlen(payload), COAP_TYPE_CON,
250+
COAP_METHOD_POST, client_handle_rpc_response);
251+
if (err) {
252+
LOG_ERR("Failed to perform RPC");
253+
}
254+
rpc_cb = cb;
255+
}
256+
192257
int thingsboard_send_telemetry(const void *payload, size_t sz)
193258
{
194259
int err;

0 commit comments

Comments
 (0)