Skip to content

Commit

Permalink
lightdb: rework golioth_lightdb_set() on top of coap_req
Browse files Browse the repository at this point in the history
This commit is phasing out direct CoAP dependency and low-level CoAP
handling requirement when using golioth_lightdb_set() API.

Add new golioth_lightdb_set_cb() callback based API, which is really just a
thin wrapper around golioth_coap_req_cb() API, but leaves user flexibility
of calling it from other golioth callback (which are all executed from
system_client thread) as well as from time-sensitive threads like system
workqueue.

Update samples/lightdb/set to new API. Provide examples for both
synchronous golioth_lightdb_set() and asynchronous (callback based)
golioth_lightdb_set_cb() API. Add LOG_DBG() statements before and after
lightdb API calls, so that it makes it clear that main thread blocks on the
synchronous API, while continuing execution with the callback-based API.

Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
  • Loading branch information
mniestroj committed Oct 7, 2022
1 parent 5796567 commit 10dc6f1
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 56 deletions.
40 changes: 32 additions & 8 deletions include/net/golioth/lightdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,22 +64,46 @@ int golioth_lightdb_get(struct golioth_client *client, const uint8_t *path,
uint8_t *data, size_t *len);

/**
* @brief Set value to Golioth's LightDB
* @brief Set value to Golioth's LightDB (callback based)
*
* Set new value to LightDB.
* Asynchronously request to store new value to LightDB and let @p cb be invoked when such value is
* actually stored or some error condition happens.
*
* @param client Client instance
* @param path LightDB resource path
* @param format Format of payload
* @param data Payload data
* @param data_len Payload length
* @warning Experimental API
*
* @param[in] client Client instance
* @param[in] path LightDB resource path
* @param[in] format Requested format of payload
* @param[in] data Pointer to data to be set
* @param[in] data_len Length of data to be set
* @param[in] cb Callback executed on response received, timeout or error
* @param[in] user_data User data passed to @p cb
*
* @retval 0 On success
* @retval <0 On failure
*/
int golioth_lightdb_set_cb(struct golioth_client *client, const uint8_t *path,
enum golioth_content_format format,
const uint8_t *data, size_t data_len,
golioth_req_cb_t cb, void *user_data);

/**
* @brief Set value to Golioth's LightDB (synchronously)
*
* Synchronously set new value to LightDB.
*
* @param[in] client Client instance
* @param[in] path LightDB resource path
* @param[in] format Format of payload
* @param[in] data Payload data
* @param[in] data_len Payload length
*
* @retval 0 On success
* @retval <0 On failure
*/
int golioth_lightdb_set(struct golioth_client *client, const uint8_t *path,
enum golioth_content_format format,
uint8_t *data, uint16_t data_len);
const uint8_t *data, size_t data_len);

/**
* @brief Delete value in Golioth's LightDB
Expand Down
43 changes: 16 additions & 27 deletions net/golioth/lightdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,36 +110,25 @@ int golioth_lightdb_get(struct golioth_client *client, const uint8_t *path,
return 0;
}

int golioth_lightdb_set_cb(struct golioth_client *client, const uint8_t *path,
enum golioth_content_format format,
const uint8_t *data, size_t data_len,
golioth_req_cb_t cb, void *user_data)
{
return golioth_coap_req_lightdb_cb(client, COAP_METHOD_POST, path, format,
data, data_len,
cb, user_data,
GOLIOTH_COAP_REQ_NO_RESP_BODY);
}

int golioth_lightdb_set(struct golioth_client *client, const uint8_t *path,
enum golioth_content_format format,
uint8_t *data, uint16_t data_len)
const uint8_t *data, size_t data_len)
{
struct coap_packet packet;
uint8_t buffer[GOLIOTH_COAP_MAX_NON_PAYLOAD_LEN];
int err;

err = coap_packet_init(&packet, buffer, sizeof(buffer),
COAP_VERSION_1, COAP_TYPE_CON,
COAP_TOKEN_MAX_LEN, coap_next_token(),
COAP_METHOD_POST, coap_next_id());
if (err) {
return err;
}

err = coap_packet_append_uri_path_from_stringz(&packet, path);
if (err) {
LOG_ERR("Unable add uri path to packet");
return err;
}

err = coap_append_option_int(&packet, COAP_OPTION_CONTENT_FORMAT,
format);
if (err) {
LOG_ERR("Unable add content format to packet");
return err;
}

return golioth_send_coap_payload(client, &packet, data, data_len);
return golioth_coap_req_lightdb_sync(client, COAP_METHOD_POST, path, format,
data, data_len,
NULL, NULL,
GOLIOTH_COAP_REQ_NO_RESP_BODY);
}

static int golioth_coap_observe_init(struct coap_packet *packet,
Expand Down
32 changes: 22 additions & 10 deletions samples/lightdb/set/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -145,16 +145,28 @@ This is the output from the serial console:

.. code-block:: console
[00:00:04.033,000] <inf> esp_event: WIFI_EVENT_STA_DISCONNECTED
[00:00:04.186,000] <inf> esp_event: WIFI_EVENT_STA_CONNECTED
[00:00:08.102,000] <inf> net_dhcpv4: Received: 192.168.0.180
[00:00:08.102,000] <inf> net_config: IPv4 address: 192.168.0.180
[00:00:08.102,000] <inf> net_config: Lease time: 7200 seconds
[00:00:08.102,000] <inf> net_config: Subnet: 255.255.255.0
[00:00:08.102,000] <inf> net_config: Router: 192.168.0.1
[00:00:08.102,000] <dbg> golioth_lightdb.main: Start LightDB set sample
[00:00:08.102,000] <inf> golioth_system: Starting connect
[00:00:08.103,000] <inf> golioth_system: Client connected!
[00:00:00.000,000] <inf> golioth_system: Initializing
[00:00:00.000,000] <inf> net_config: Initializing network
[00:00:00.000,000] <inf> net_config: IPv4 address: 192.0.2.1
[00:00:00.000,000] <dbg> golioth_lightdb: main: Start LightDB set sample
[00:00:00.010,000] <inf> golioth_system: Starting connect
[00:00:00.030,000] <dbg> golioth_lightdb: main: Setting counter to 0
[00:00:00.030,000] <dbg> golioth_lightdb: main: Before request (async)
[00:00:00.030,000] <dbg> golioth_lightdb: main: After request (async)
[00:00:00.030,000] <inf> golioth_system: Client connected!
[00:00:00.030,000] <dbg> golioth_lightdb: counter_set_handler: Counter successfully set
[00:00:05.040,000] <dbg> golioth_lightdb: main: Setting counter to 1
[00:00:05.040,000] <dbg> golioth_lightdb: main: Before request (sync)
[00:00:05.040,000] <dbg> golioth_lightdb: counter_set_sync: Counter successfully set
[00:00:05.040,000] <dbg> golioth_lightdb: main: After request (sync)
[00:00:10.050,000] <dbg> golioth_lightdb: main: Setting counter to 2
[00:00:10.050,000] <dbg> golioth_lightdb: main: Before request (async)
[00:00:10.050,000] <dbg> golioth_lightdb: main: After request (async)
[00:00:10.050,000] <dbg> golioth_lightdb: counter_set_handler: Counter successfully set
[00:00:15.060,000] <dbg> golioth_lightdb: main: Setting counter to 3
[00:00:15.060,000] <dbg> golioth_lightdb: main: Before request (sync)
[00:00:15.060,000] <dbg> golioth_lightdb: counter_set_sync: Counter successfully set
[00:00:15.060,000] <dbg> golioth_lightdb: main: After request (sync)
Monitor counter value
=====================
Expand Down
2 changes: 1 addition & 1 deletion samples/lightdb/set/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ CONFIG_MAIN_STACK_SIZE=4096
CONFIG_GOLIOTH=y
CONFIG_GOLIOTH_SYSTEM_CLIENT=y

CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE=256
CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE=2048
58 changes: 48 additions & 10 deletions samples/lightdb/set/src/main.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Golioth, Inc.
* Copyright (c) 2021-2022 Golioth, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -9,7 +9,6 @@ LOG_MODULE_REGISTER(golioth_lightdb, LOG_LEVEL_DBG);

#include <net/golioth/system_client.h>
#include <samples/common/net_connect.h>
#include <zephyr/net/coap.h>

#include <stdlib.h>

Expand All @@ -22,23 +21,51 @@ static void golioth_on_connect(struct golioth_client *client)
k_sem_give(&connected);
}

/*
* This function stores `counter` in lightdb at `/counter`.
*/
static void counter_set(int counter)
static int counter_set_handler(struct golioth_req_rsp *rsp)
{
if (rsp->err) {
LOG_WRN("Failed to set counter: %d", rsp->err);
return rsp->err;
}

LOG_DBG("Counter successfully set");

return 0;
}

static void counter_set_async(int counter)
{
char sbuf[sizeof("4294967295")];
int err;

snprintk(sbuf, sizeof(sbuf) - 1, "%d", counter);

err = golioth_lightdb_set(client,
GOLIOTH_LIGHTDB_PATH("counter"),
err = golioth_lightdb_set_cb(client, "counter",
GOLIOTH_CONTENT_FORMAT_APP_JSON,
sbuf, strlen(sbuf),
counter_set_handler, NULL);
if (err) {
LOG_WRN("Failed to set counter: %d", err);
return;
}
}

static void counter_set_sync(int counter)
{
char sbuf[sizeof("4294967295")];
int err;

snprintk(sbuf, sizeof(sbuf) - 1, "%d", counter);

err = golioth_lightdb_set(client, "counter",
GOLIOTH_CONTENT_FORMAT_APP_JSON,
sbuf, strlen(sbuf));
if (err) {
LOG_WRN("Failed to update counter: %d", err);
LOG_WRN("Failed to set counter: %d", err);
return;
}

LOG_DBG("Counter successfully set");
}

void main(void)
Expand All @@ -58,10 +85,21 @@ void main(void)

while (true) {
LOG_DBG("Setting counter to %d", counter);
counter_set(counter);

LOG_DBG("Before request (async)");
counter_set_async(counter);
LOG_DBG("After request (async)");

counter++;
k_sleep(K_SECONDS(5));

LOG_DBG("Setting counter to %d", counter);

LOG_DBG("Before request (sync)");
counter_set_sync(counter);
LOG_DBG("After request (sync)");

counter++;
k_sleep(K_SECONDS(5));
}
}

0 comments on commit 10dc6f1

Please sign in to comment.