Skip to content

Commit

Permalink
cloud: dump storage on server endpoint selection change
Browse files Browse the repository at this point in the history
  • Loading branch information
Danielius1922 committed Feb 21, 2024
1 parent cdfa775 commit d4555c1
Show file tree
Hide file tree
Showing 15 changed files with 354 additions and 107 deletions.
11 changes: 7 additions & 4 deletions api/cloud/oc_cloud.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,9 @@ cloud_set_cloudconf(oc_cloud_context_t *ctx, const oc_cloud_conf_update_t *data)
oc_cloud_endpoints_deinit(&ctx->store.ci_servers);
// oc_cloud_endpoints_init only allocates, so the oc_string_view_t is valid
oc_string_view_t cis = oc_string_view2(data->ci_server);
if (!oc_cloud_endpoints_init(&ctx->store.ci_servers, cis, data->sid)) {
if (!oc_cloud_endpoints_init(
&ctx->store.ci_servers, ctx->store.ci_servers.on_selected_change,
ctx->store.ci_servers.on_selected_change_data, cis, data->sid)) {
OC_WRN("Failed to reinitialize cloud server endpoints");
}
}
Expand Down Expand Up @@ -218,9 +220,10 @@ oc_cloud_provision_conf_resource(oc_cloud_context_t *ctx, const char *server,
return -1;
}
size_t server_id_len = oc_strnlen(server_id, OC_UUID_LEN);
oc_uuid_t sid = { 0 };
if (server_id_len != (OC_UUID_LEN - 1) ||
oc_str_to_uuid_v1(server_id, server_id_len, &sid) < 0) {
oc_uuid_t sid = OCF_COAPCLOUDCONF_DEFAULT_SID;
if (server_id_len > 0 &&
oc_str_to_uuid_v1(server_id, server_id_len, &sid) != OC_UUID_ID_SIZE) {
OC_ERR("invalid sid(%s)", server_id);
return -1;
}
size_t auth_provider_len = oc_strnlen_s(auth_provider, OC_MAX_STRING_LENGTH);
Expand Down
8 changes: 1 addition & 7 deletions api/cloud/oc_cloud_apis.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,18 +333,12 @@ int
oc_cloud_discover_resources(const oc_cloud_context_t *ctx,
oc_discovery_all_handler_t handler, void *user_data)
{
if (!ctx) {
if (ctx == NULL || (ctx->store.status & OC_CLOUD_LOGGED_IN) == 0) {
return -1;
}

if (!(ctx->store.status & OC_CLOUD_LOGGED_IN)) {
return -1;
}

if (oc_do_ip_discovery_all_at_endpoint(handler, ctx->cloud_ep, user_data)) {
return 0;
}

return -1;
}

Expand Down
1 change: 0 additions & 1 deletion api/cloud/oc_cloud_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,6 @@ oc_cloud_select_server(oc_cloud_context_t *ctx,
return false;
}
ctx->store.ci_servers.selected = server;
// TODO: dump to storage on selection change
return true;
}

Expand Down
42 changes: 32 additions & 10 deletions api/cloud/oc_cloud_endpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,19 @@ cloud_endpoint_uri_is_valid(oc_string_view_t uri)
return uri.length > 0 && uri.length < OC_ENDPOINT_MAX_ENDPOINT_URI_LENGTH;
}

static void
cloud_endpoints_set_selected(oc_cloud_endpoints_t *ce,
const oc_cloud_endpoint_t *selected)
{
if (ce->selected == selected) {
return;
}
ce->selected = selected;
if (ce->on_selected_change != NULL) {
ce->on_selected_change(ce->on_selected_change_data);
}
}

static oc_cloud_endpoint_t *
cloud_endpoint_item_allocate_and_add(oc_cloud_endpoints_t *ce,
oc_string_view_t uri, oc_uuid_t id)
Expand All @@ -55,7 +68,7 @@ cloud_endpoint_item_allocate_and_add(oc_cloud_endpoints_t *ce,
// automatically select the first endpoint added
if (ce->selected == NULL) {
assert(oc_list_length(ce->endpoints) == 0);
ce->selected = cei;
cloud_endpoints_set_selected(ce, cei);
}

oc_list_add(ce->endpoints, cei);
Expand Down Expand Up @@ -88,8 +101,10 @@ oc_cloud_endpoint_id(const oc_cloud_endpoint_t *ce)
}

bool
oc_cloud_endpoints_init(oc_cloud_endpoints_t *ce, oc_string_view_t default_uri,
oc_uuid_t default_id)
oc_cloud_endpoints_init(oc_cloud_endpoints_t *ce,
on_selected_change_fn_t on_selected_change,
void *on_selected_change_data,
oc_string_view_t default_uri, oc_uuid_t default_id)
{
memset(ce, 0, sizeof(oc_cloud_endpoints_t));
OC_LIST_STRUCT_INIT(ce, endpoints);
Expand All @@ -101,6 +116,9 @@ oc_cloud_endpoints_init(oc_cloud_endpoints_t *ce, oc_string_view_t default_uri,
return false;
}
}

ce->on_selected_change = on_selected_change;
ce->on_selected_change_data = on_selected_change_data;
return true;
}

Expand All @@ -122,7 +140,9 @@ oc_cloud_endpoints_reinit(oc_cloud_endpoints_t *ce,
oc_string_view_t default_uri, oc_uuid_t default_id)
{
oc_cloud_endpoints_deinit(ce);
return oc_cloud_endpoints_init(ce, default_uri, default_id);
return oc_cloud_endpoints_init(ce, ce->on_selected_change,
ce->on_selected_change_data, default_uri,
default_id);
}

size_t
Expand Down Expand Up @@ -162,7 +182,7 @@ oc_cloud_endpoints_clear(oc_cloud_endpoints_t *ce)
cloud_endpoint_item_free(cei);
cei = oc_list_pop(ce->endpoints);
}
ce->selected = NULL;
cloud_endpoints_set_selected(ce, NULL);
}

typedef struct
Expand Down Expand Up @@ -250,7 +270,8 @@ oc_cloud_endpoint_remove(oc_cloud_endpoints_t *ce,
return false;
}
if (ce->selected == ep) {
ce->selected = cloud_endpoint_item_next(ce, ce->selected, ep_next);
cloud_endpoints_set_selected(
ce, cloud_endpoint_item_next(ce, ce->selected, ep_next));
}
cloud_endpoint_item_free(found);
return true;
Expand All @@ -273,7 +294,7 @@ oc_cloud_endpoint_select_by_uri(oc_cloud_endpoints_t *ce, oc_string_view_t uri)
if (found == NULL) {
return false;
}
ce->selected = found;
cloud_endpoints_set_selected(ce, found);
return true;
}

Expand Down Expand Up @@ -321,10 +342,11 @@ cloud_encode_server(oc_cloud_endpoint_t *endpoint, void *data)
encoder->ci_servers, &endpoint_map, CborIndefiniteLength);
oc_rep_object_set_text_string(&endpoint_map, "uri", OC_CHAR_ARRAY_LEN("uri"),
uri.data, uri.length);
char sid_str[OC_UUID_LEN];
oc_uuid_to_str(&endpoint->id, sid_str, OC_UUID_LEN);
char sid_str[OC_UUID_LEN] = { 0 };
int sid_str_len = oc_uuid_to_str_v1(&endpoint->id, sid_str, OC_UUID_LEN);
assert(sid_str_len > 0);
oc_rep_object_set_text_string(&endpoint_map, "id", OC_CHAR_ARRAY_LEN("id"),
sid_str, strlen(sid_str));
sid_str, (size_t)sid_str_len);

encoder->error |=
oc_rep_encoder_close_container(encoder->ci_servers, &endpoint_map);
Expand Down
16 changes: 13 additions & 3 deletions api/cloud/oc_cloud_endpoint_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,32 +45,42 @@ struct oc_cloud_endpoint_t
oc_uuid_t id; ///< identity of the cloud server
};

typedef void (*on_selected_change_fn_t)(void *data);

typedef struct
{
const oc_cloud_endpoint_t *selected; ///< currently selected server endpoint
OC_LIST_STRUCT(endpoints); ///< list of server endpoints
on_selected_change_fn_t
on_selected_change; ///< callback invoked when the selected endpoint changes
void *
on_selected_change_data; ///< data passed to the on_selected_change callback
OC_LIST_STRUCT(endpoints); ///< list of server endpoints
} oc_cloud_endpoints_t;

/** Initialize cloud server endpoints
*
* @param ce cloud endpoints (cannot be NULL)
* @param on_selected_change callback invoked when the selected endpoint changes
* @param on_selected_change_data data passed to the on_selected_change callback
* @param default_uri URI of the default endpoint to add (if the URI is empty
* the list will remain empty)
* @param default_id identity of the default endpoint to add
* @return true on success
* @return false on failure
*/
bool oc_cloud_endpoints_init(oc_cloud_endpoints_t *ce,
on_selected_change_fn_t on_selected_change,
void *on_selected_change_data,
oc_string_view_t default_uri, oc_uuid_t default_id)
OC_NONNULL();
OC_NONNULL(1);

/** Deinitialize cloud server endpoints */
void oc_cloud_endpoints_deinit(oc_cloud_endpoints_t *ce) OC_NONNULL();

/** Deinitialize and reinitialize cloud server endpoints */
bool oc_cloud_endpoints_reinit(oc_cloud_endpoints_t *ce,
oc_string_view_t default_uri,
oc_uuid_t default_id) OC_NONNULL();
oc_uuid_t default_id) OC_NONNULL(1);

/** Get the number of cloud server endpoints */
size_t oc_cloud_endpoints_size(const oc_cloud_endpoints_t *ce) OC_NONNULL();
Expand Down
79 changes: 40 additions & 39 deletions api/cloud/oc_cloud_resource.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ oc_cloud_encode(const oc_cloud_context_t *ctx)
oc_string_view_t cis =
oc_string_view2(oc_cloud_endpoint_selected_address(&ctx->store.ci_servers));
oc_rep_set_text_string_v1(root, cis, cis.data, cis.length);
g_err |= oc_cloud_endpoints_encode(
oc_rep_object(root), &ctx->store.ci_servers,
OC_STRING_VIEW(OCF_COAPCLOUDCONF_PROP_CISERVERS), true);

const oc_uuid_t *sid = oc_cloud_endpoint_selected_id(&ctx->store.ci_servers);
char sid_str[OC_UUID_LEN] = { 0 };
Expand All @@ -82,6 +79,10 @@ oc_cloud_encode(const oc_cloud_context_t *ctx)
}
oc_rep_set_text_string_v1(root, sid, sid_str, sid_str_len);

g_err |= oc_cloud_endpoints_encode(
oc_rep_object(root), &ctx->store.ci_servers,
OC_STRING_VIEW(OCF_COAPCLOUDCONF_PROP_CISERVERS), true);

oc_rep_set_int(root, clec, (int)ctx->last_error);

OC_CLOUD_DBG(
Expand Down Expand Up @@ -118,49 +119,49 @@ cloud_resource_get(oc_request_t *request, oc_interface_mask_t interface,
oc_send_response_with_callback(request, OC_STATUS_OK, true);
}

static const oc_string_t *
resource_payload_get_string_property(const oc_rep_t *payload,
oc_string_view_t key, bool cannotBeEmpty)
{
const oc_rep_t *rep =
oc_rep_get(payload, OC_REP_STRING, key.data, key.length);
if (rep == NULL ||
(cannotBeEmpty && oc_string_is_empty(&rep->value.string))) {
return NULL;
}
return &rep->value.string;
}

static bool
cloud_update_from_request(oc_cloud_context_t *ctx, const oc_request_t *request)
{
oc_cloud_conf_update_t data;
memset(&data, 0, sizeof(data));

const oc_rep_t *rep = oc_rep_get(
request->request_payload, OC_REP_STRING, OCF_COAPCLOUDCONF_PROP_ACCESSTOKEN,
OC_CHAR_ARRAY_LEN(OCF_COAPCLOUDCONF_PROP_ACCESSTOKEN));
if (rep != NULL && !oc_string_is_empty(&rep->value.string)) {
data.access_token = &rep->value.string;
}

rep = oc_rep_get(request->request_payload, OC_REP_STRING,
OCF_COAPCLOUDCONF_PROP_AUTHPROVIDER,
OC_CHAR_ARRAY_LEN(OCF_COAPCLOUDCONF_PROP_AUTHPROVIDER));
if (rep != NULL && !oc_string_is_empty(&rep->value.string)) {
data.auth_provider = &rep->value.string;
}

rep = oc_rep_get(request->request_payload, OC_REP_STRING,
OCF_COAPCLOUDCONF_PROP_CISERVER,
OC_CHAR_ARRAY_LEN(OCF_COAPCLOUDCONF_PROP_CISERVER));
if (rep != NULL) {
data.ci_server = &rep->value.string;
}
data.access_token = resource_payload_get_string_property(
request->request_payload,
OC_STRING_VIEW(OCF_COAPCLOUDCONF_PROP_ACCESSTOKEN), true);
data.auth_provider = resource_payload_get_string_property(
request->request_payload,
OC_STRING_VIEW(OCF_COAPCLOUDCONF_PROP_AUTHPROVIDER), true);
data.ci_server = resource_payload_get_string_property(
request->request_payload, OC_STRING_VIEW(OCF_COAPCLOUDCONF_PROP_CISERVER),
false);

// OCF 2.0 spec version added sid property.
bool has_sid = false;
rep = oc_rep_get(request->request_payload, OC_REP_STRING,
OCF_COAPCLOUDCONF_PROP_SERVERID,
OC_CHAR_ARRAY_LEN(OCF_COAPCLOUDCONF_PROP_SERVERID));
if (rep != NULL && !oc_string_is_empty(&rep->value.string)) {
has_sid = true;
if (oc_str_to_uuid_v1(oc_string(rep->value.string),
oc_string_len(rep->value.string), &data.sid) < 0) {
OC_ERR("Error parsing sid(%s)", oc_string(rep->value.string));
const oc_string_t *sid = resource_payload_get_string_property(
request->request_payload, OC_STRING_VIEW(OCF_COAPCLOUDCONF_PROP_SERVERID),
true);
if (sid != NULL) {
oc_string_view_t sidv = oc_string_view2(sid);
if (oc_str_to_uuid_v1(sidv.data, sidv.length, &data.sid) < 0) {
OC_ERR("failed parsing sid(%s)", sidv.data);
return false;
}
}

if (data.ci_server != NULL && (oc_string_is_empty(data.ci_server) ||
(data.access_token != NULL && has_sid))) {
(data.access_token != NULL && sid != NULL))) {
oc_cloud_update_by_resource(ctx, &data);
return true;
}
Expand Down Expand Up @@ -217,13 +218,13 @@ cloud_resource_post(oc_request_t *request, oc_interface_mask_t interface,
return;
}

bool changed = cloud_update_from_request(ctx, request);
oc_cloud_encode(ctx);
oc_send_response_with_callback(
request, changed ? OC_STATUS_CHANGED : OC_STATUS_BAD_REQUEST, true);
if (changed) {
oc_cloud_store_dump_async(&ctx->store);
if (!cloud_update_from_request(ctx, request) || !oc_cloud_encode(ctx)) {
oc_send_response_with_callback(request, OC_STATUS_BAD_REQUEST, true);
return;
}

oc_send_response_with_callback(request, OC_STATUS_CHANGED, true);
oc_cloud_store_dump_async(&ctx->store);
}

void
Expand Down
Loading

0 comments on commit d4555c1

Please sign in to comment.