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 {
2224K_SEM_DEFINE (time_sem , 0 , 1 );
2325
2426static attr_write_callback_t attribute_cb ;
27+ static rpc_callback_t rpc_cb ;
2528
2629static void client_request_time (struct k_work * work );
2730K_WORK_DELAYABLE_DEFINE (work_time , client_request_time );
@@ -189,6 +192,69 @@ 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+ // TODO: check length of params
247+ snprintf (payload , sizeof (payload ), "{\"method\":\"%s\", \"params\": %s}" , method , params );
248+ const uint8_t * uri [] = {"api" , "v1" , access_token , "rpc" , NULL };
249+
250+ err = coap_client_make_request (uri , payload , strlen (payload ), COAP_TYPE_CON ,
251+ COAP_METHOD_POST , client_handle_rpc_response );
252+ if (err ) {
253+ LOG_ERR ("Failed to perform RPC" );
254+ }
255+ rpc_cb = cb ;
256+ }
257+
192258int thingsboard_send_telemetry (const void * payload , size_t sz )
193259{
194260 int err ;
0 commit comments