Commit 4a4180cb authored by Daniel Adam's avatar Daniel Adam

apps: keep list of switches in ordered in cloud_server.c

We want the hrefs of collection elements to take the
form of {collection_href}/{item_index}. To keep track of
the next possible index value after insertion/deletions
it best to keep the list in order and at each insertion
look for the next free index value.
parent bab3a0d2
Pipeline #1302 passed with stage
in 3 minutes and 24 seconds
......@@ -328,10 +328,11 @@ typedef struct oc_switch_t
{
struct oc_switch_t *next;
oc_resource_t *resource;
uint16_t id;
bool state;
} oc_switch_t;
OC_MEMB(switch_s, oc_switch_t, 1);
OC_LIST(switches);
OC_LIST(switches); // list of switch instances ordered by id
static bool
set_switch_properties(oc_resource_t *resource, oc_rep_t *rep, void *data)
......@@ -423,6 +424,30 @@ get_cswitch(oc_request_t *request, oc_interface_mask_t iface_mask,
#ifdef OC_COLLECTIONS_IF_CREATE
/**
* Get pointer to the first element that either has no following element
* or the following element has an id with larger increment than 1
*
* Example: list of three elements with ids 1, 2 and 5, it will return
* the second element (id=2) because the next id in order should be 3.
* Since it is 5 and the list is ordered we know 3 is free to use.
*/
static oc_switch_t* get_next_free_position()
{
oc_switch_t* item = oc_list_head(switches);
if (!item || item->id != 1) {
return NULL;
}
for(uint16_t id = 1;
oc_list_item_next(item) != NULL && ((oc_switch_t*)oc_list_item_next(item))->id == ++id;
item = oc_list_item_next(item)) {
;
}
return item;
}
static oc_event_callback_retval_t
register_to_cloud(void* res)
{
......@@ -436,11 +461,22 @@ get_switch_instance(const char *href, oc_string_array_t *types,
oc_resource_properties_t bm, oc_interface_mask_t iface_mask,
size_t device)
{
(void)href;
oc_switch_t *cswitch = (oc_switch_t *)oc_memb_alloc(&switch_s);
if (cswitch) {
uint16_t cswitch_id = 1;
oc_switch_t *prev = get_next_free_position();
if (prev) {
cswitch_id = prev->id + 1;
}
const size_t href_size = sizeof("/platform/") + 5; // 5 = max number of digits in uint16_t value
char cswitch_href[href_size];
snprintf(cswitch_href, sizeof(cswitch_href), "/platform/%u", (unsigned)cswitch_id);
cswitch->resource = oc_new_resource(
NULL, href, oc_string_array_get_allocated_size(*types), device);
NULL, cswitch_href, oc_string_array_get_allocated_size(*types), device);
if (cswitch->resource) {
cswitch->id = cswitch_id;
size_t i;
for (i = 0; i < oc_string_array_get_allocated_size(*types); i++) {
const char *rt = oc_string_array_get_item(*types, i);
......@@ -458,7 +494,7 @@ get_switch_instance(const char *href, oc_string_array_t *types,
oc_add_resource(cswitch->resource);
oc_set_delayed_callback(cswitch->resource, register_to_cloud, 0);
oc_list_add(switches, cswitch);
oc_list_insert(switches, prev, cswitch);
return cswitch->resource;
} else {
oc_memb_free(&switch_s, cswitch);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment