aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Prestwood <james.prestwood@intel.com>2017-03-15 11:45:19 -0700
committerGeoff Gustafson <geoff@linux.intel.com>2017-03-15 11:45:19 -0700
commit556ac3404ded8217f890cc5e61aff5811b81a840 (patch)
tree69a6024ce52141723267fb840d774cf1943107e8
parent60455e99b3d937864ae2520f07754d632658439e (diff)
[ocf] register resource correctly (#800)
Signed-off-by: James Prestwood <james.prestwood@intel.com>
-rw-r--r--samples/OcfServer.js2
-rw-r--r--src/zjs_modules.c2
-rw-r--r--src/zjs_ocf_client.c35
-rw-r--r--src/zjs_ocf_client.h5
-rw-r--r--src/zjs_ocf_common.c20
-rw-r--r--src/zjs_ocf_common.h13
-rw-r--r--src/zjs_ocf_server.c229
-rw-r--r--src/zjs_ocf_server.h12
8 files changed, 254 insertions, 64 deletions
diff --git a/samples/OcfServer.js b/samples/OcfServer.js
index 33b4013..eb2d3ef 100644
--- a/samples/OcfServer.js
+++ b/samples/OcfServer.js
@@ -39,7 +39,7 @@ var resourceInit = {
var MyResource = null;
server.register(resourceInit).then(function(resource) {
- console.log("Registered resource");
+ console.log("Registered resource. UUID: " + ocf.device.uuid);
MyResource = resource;
server.on("retrieve", function(request, observe) {
MyProperties.state = (MyProperties.state) ? false : true;
diff --git a/src/zjs_modules.c b/src/zjs_modules.c
index 41b3262..c89b2cb 100644
--- a/src/zjs_modules.c
+++ b/src/zjs_modules.c
@@ -110,7 +110,7 @@ module_t zjs_modules_array[] = {
{ "performance", zjs_performance_init },
#endif
#ifdef BUILD_MODULE_OCF
- { "ocf", zjs_ocf_init },
+ { "ocf", zjs_ocf_init, zjs_ocf_cleanup },
#endif
#ifdef BUILD_MODULE_TEST_PROMISE
{ "test_promise", zjs_test_promise_init }
diff --git a/src/zjs_ocf_client.c b/src/zjs_ocf_client.c
index b6a822f..2add8c2 100644
--- a/src/zjs_ocf_client.c
+++ b/src/zjs_ocf_client.c
@@ -49,7 +49,7 @@ struct ocf_handler {
struct client_resource* res;
};
-struct client_resource* resources = NULL;
+static struct client_resource* resource_list = NULL;
#define MAX_URI_LENGTH (30)
@@ -216,7 +216,7 @@ static void print_props_data(oc_client_response_t *data)
static struct client_resource* find_resource_by_id(const char* device_id)
{
if (device_id) {
- struct client_resource* cur = resources;
+ struct client_resource* cur = resource_list;
while (cur) {
if (cur->state != RES_STATE_SEARCHING) {
if (strcmp(cur->device_id, device_id) == 0) {
@@ -236,7 +236,7 @@ static struct client_resource* find_resource_by_id(const char* device_id)
static struct client_resource* find_resource_by_path(const char* path)
{
if (path) {
- struct client_resource* cur = resources;
+ struct client_resource* cur = resource_list;
while (cur) {
if (cur->state != RES_STATE_SEARCHING) {
if (strcmp(cur->resource_path, path) == 0) {
@@ -273,7 +273,7 @@ static void free_client(const uintptr_t native_p)
{
struct client_resource* client = (struct client_resource*)native_p;
if (client) {
- struct client_resource* cur = resources;
+ struct client_resource* cur = resource_list;
while (cur->next) {
if (cur->next == client) {
cur->next = client->next;
@@ -295,7 +295,7 @@ static void free_client(const uintptr_t native_p)
}
/*
- * Add a discovered resource to the list of resources
+ * Add a discovered resource to the list of resource_list
*/
static void add_resource(char* id, char* type, char* path, jerry_value_t client, jerry_value_t listener)
{
@@ -328,8 +328,8 @@ static void add_resource(char* id, char* type, char* path, jerry_value_t client,
zjs_add_event_listener(new->client, "resourcefound", listener);
}
- new->next = resources;
- resources = new;
+ new->next = resource_list;
+ resource_list = new;
}
static void post_ocf_promise(void* handle)
@@ -377,7 +377,7 @@ static oc_discovery_flags_t discovery(const char *di,
for (i = 0; i < oc_string_array_get_allocated_size(types); i++) {
char *t = oc_string_array_get_item(types, i);
- struct client_resource* cur = resources;
+ struct client_resource* cur = resource_list;
while (cur) {
if (cur->state == RES_STATE_SEARCHING) {
// check if resource has any filter constraints
@@ -1080,4 +1080,23 @@ jerry_value_t zjs_ocf_client_init()
return ocf_client;
}
+void zjs_ocf_client_cleanup()
+{
+ if (resource_list) {
+ struct client_resource *cur = resource_list;
+ while (cur) {
+ if (cur->resource_type) {
+ zjs_free(cur->resource_type);
+ }
+ if (cur->resource_path) {
+ zjs_free(cur->resource_path);
+ }
+ jerry_release_value(cur->client);
+ resource_list = resource_list->next;
+ zjs_free(cur);
+ cur = resource_list;
+ }
+ }
+}
+
#endif // BUILD_MODULE_OCF
diff --git a/src/zjs_ocf_client.h b/src/zjs_ocf_client.h
index 6f78d1a..0ac1ac0 100644
--- a/src/zjs_ocf_client.h
+++ b/src/zjs_ocf_client.h
@@ -10,4 +10,9 @@
*/
jerry_value_t zjs_ocf_client_init();
+/*
+ * Cleanup OCF client
+ */
+void zjs_ocf_client_cleanup();
+
#endif // __zjs_ocf_client__
diff --git a/src/zjs_ocf_common.c b/src/zjs_ocf_common.c
index 86c1eb8..9e4f6b7 100644
--- a/src/zjs_ocf_common.c
+++ b/src/zjs_ocf_common.c
@@ -210,6 +210,15 @@ static void issue_requests(void)
#define CONFIG_DEVICE_NAME CONFIG_BLUETOOTH_DEVICE_NAME
#endif
+void zjs_set_uuid(char* uuid)
+{
+ jerry_value_t device = zjs_get_property(ocf_object, "device");
+ if (!jerry_value_is_undefined(device)) {
+ zjs_obj_add_string(device, uuid, "uuid");
+ }
+ jerry_release_value(device);
+}
+
static void platform_init(void *data)
{
uint32_t size;
@@ -470,4 +479,15 @@ jerry_value_t zjs_ocf_init()
return ocf_object;
}
+void zjs_ocf_cleanup()
+{
+#ifdef OC_SERVER
+ zjs_ocf_server_cleanup();
+#endif
+#ifdef OC_CLIENT
+ zjs_ocf_client_cleanup();
+#endif
+ jerry_release_value(ocf_object);
+}
+
#endif // BUILD_MODULE_OCF
diff --git a/src/zjs_ocf_common.h b/src/zjs_ocf_common.h
index 99e0c7f..e3847e8 100644
--- a/src/zjs_ocf_common.h
+++ b/src/zjs_ocf_common.h
@@ -79,6 +79,14 @@ void zjs_ocf_free_props(void* h);
*/
uint8_t main_poll_routine(void* handle);
+/**
+ * Set the 'uuid' property in the device object. This API is required because
+ * we dont get the UUID until after the device object is created/initialized.
+ *
+ * @param uuid UUID obtained from iotivity-constrained system
+ */
+void zjs_set_uuid(char* uuid);
+
/*
* Start Iotivity-constrained.
*/
@@ -88,3 +96,8 @@ int zjs_ocf_start();
* Object returned from require('ocf')
*/
jerry_value_t zjs_ocf_init();
+
+/*
+ * Cleanup for OCF object
+ */
+void zjs_ocf_cleanup();
diff --git a/src/zjs_ocf_server.c b/src/zjs_ocf_server.c
index 0a4f8ae..cc7c879 100644
--- a/src/zjs_ocf_server.c
+++ b/src/zjs_ocf_server.c
@@ -23,12 +23,22 @@ struct server_resource {
* 'this' pointer so we have to save it in C.
*/
jerry_value_t object;
- char* device_id;
- char* resource_path;
uint32_t error_code;
oc_resource_t *res;
+ char* device_id;
+ char* resource_path;
+ uint8_t num_types;
+ char** resource_types;
+ uint8_t num_ifaces;
+ char** resource_ifaces;
+ uint8_t flags;
};
+typedef struct resource_list {
+ struct server_resource* resource;
+ struct resource_list* next;
+} resource_list_t;
+
struct ocf_response {
oc_method_t method; // Current method being executed
oc_request_t* request;
@@ -41,6 +51,8 @@ struct ocf_handler {
struct server_resource* res;
};
+static resource_list_t* res_list = NULL;
+
#define FLAG_OBSERVE 1 << 0
#define FLAG_DISCOVERABLE 1 << 1
#define FLAG_SLOW 1 << 2
@@ -392,14 +404,15 @@ static jerry_value_t ocf_notify(const jerry_value_t function_val,
}
/*
-typedef struct resource_list {
- oc_resource_t *resource;
- struct resource_list* next;
-} resource_list_t;
-
-static resource_list_t *r_list = NULL;
-static bool has_registered = false;
-*/
+ * TODO: This is a workaround for getting the resource UUID. There is no API
+ * available to do this currently so we must get it with this external
+ * structure.
+ */
+extern struct
+{
+ oc_uuid_t uuid;
+ oc_string_t payload;
+} oc_device_info[OC_MAX_NUM_DEVICES];
static jerry_value_t ocf_register(const jerry_value_t function_val,
const jerry_value_t this,
@@ -412,11 +425,12 @@ static jerry_value_t ocf_register(const jerry_value_t function_val,
struct server_resource* resource;
int i;
jerry_value_t promise = jerry_create_object();
- struct ocf_handler* h;
+ struct ocf_handler* h = NULL;
// Required
jerry_value_t resource_path_val = zjs_get_property(argv[0], "resourcePath");
if (!jerry_value_is_string(resource_path_val)) {
+ jerry_release_value(resource_path_val);
ERR_PRINT("resourcePath not found\n");
REJECT(promise, "TypeMismatchError", "resourcePath not found", h);
return promise;
@@ -426,14 +440,14 @@ static jerry_value_t ocf_register(const jerry_value_t function_val,
jerry_value_t res_type_array = zjs_get_property(argv[0], "resourceTypes");
if (!jerry_value_is_array(res_type_array)) {
+ jerry_release_value(res_type_array);
ERR_PRINT("resourceTypes array not found\n");
REJECT(promise, "TypeMismatchError", "resourceTypes array not found", h);
return promise;
}
- uint32_t num_types = jerry_get_array_length(res_type_array);
// Optional
- uint32_t flags = 0;
+ uint8_t flags = 0;
jerry_value_t observable_val = zjs_get_property(argv[0], "observable");
if (jerry_value_is_boolean(observable_val)) {
if (jerry_get_boolean_value(observable_val)) {
@@ -466,47 +480,86 @@ static jerry_value_t ocf_register(const jerry_value_t function_val,
}
jerry_release_value(secure_val);
+ resource_list_t* new = zjs_malloc(sizeof(resource_list_t));
+ if (!new) {
+ jerry_release_value(res_type_array);
+ REJECT(promise, "InternalError", "Could not allocate resource list", h);
+ return promise;
+ }
resource = new_server_resource(resource_path);
-
- if (zjs_ocf_start() < 0) {
- REJECT(promise, "InternalError", "OCF failed to start", h);
+ if (!resource) {
+ jerry_release_value(res_type_array);
+ REJECT(promise, "InternalError", "Could not allocate resource", h);
return promise;
}
+ new->resource = resource;
+ new->next = res_list;
+ res_list = new;
- resource->res = oc_new_resource(resource_path, num_types, 0);
+ resource->flags = flags;
+
+ resource->num_types = jerry_get_array_length(res_type_array);
+ resource->resource_types = zjs_malloc(sizeof(char*) * resource->num_types);
+ if (!resource->resource_types) {
+ jerry_release_value(res_type_array);
+ REJECT(promise, "InternalError", "resourceType alloc failed", h);
+ return promise;
+ }
- for (i = 0; i < num_types; ++i) {
+ for (i = 0; i < resource->num_types; ++i) {
jerry_value_t type_val = jerry_get_property_by_index(res_type_array, i);
- ZJS_GET_STRING(type_val, type_name, OCF_MAX_RES_TYPE_LEN);
- oc_resource_bind_resource_type(resource->res, type_name);
+ uint32_t size = OCF_MAX_RES_TYPE_LEN;
+ resource->resource_types[i] = zjs_alloc_from_jstring(type_val, &size);
+ if (!resource->resource_types[i]) {
+ jerry_release_value(res_type_array);
+ jerry_release_value(type_val);
+ REJECT(promise, "InternalError", "resourceType alloc failed", h);
+ return promise;
+ }
jerry_release_value(type_val);
}
- oc_resource_bind_resource_interface(resource->res, OC_IF_RW);
- oc_resource_set_default_interface(resource->res, OC_IF_RW);
+ jerry_release_value(res_type_array);
-#ifdef OC_SECURITY
- oc_resource_make_secure(resource->res);
-#endif
+ jerry_value_t iface_array = zjs_get_property(argv[0], "interfaces");
+ if (!jerry_value_is_array(iface_array)) {
+ jerry_release_value(iface_array);
+ ERR_PRINT("interfaces array not found\n");
+ REJECT(promise, "TypeMismatchError", "resourceTypes array not found", h);
+ return promise;
+ }
- if (flags & FLAG_DISCOVERABLE) {
- oc_resource_set_discoverable(resource->res, 1);
+ resource->num_ifaces = jerry_get_array_length(iface_array);
+ resource->resource_ifaces = zjs_malloc(sizeof(char*) * resource->num_ifaces);
+ if (!resource->resource_ifaces) {
+ jerry_release_value(iface_array);
+ REJECT(promise, "InternalError", "interfaces alloc failed", h);
+ return promise;
}
- if (flags & FLAG_OBSERVE) {
- oc_resource_set_periodic_observable(resource->res, 1);
+
+ for (i = 0; i < resource->num_ifaces; ++i) {
+ jerry_value_t val = jerry_get_property_by_index(iface_array, i);
+ uint32_t size = OCF_MAX_RES_TYPE_LEN;
+ resource->resource_ifaces[i] = zjs_alloc_from_jstring(val, &size);
+ if (!resource->resource_ifaces[i]) {
+ jerry_release_value(iface_array);
+ jerry_release_value(val);
+ REJECT(promise, "InternalError", "resourceType alloc failed", h);
+ return promise;
+ }
+ jerry_release_value(val);
}
- /*
- * TODO: Since requests are handled in JS can POST/PUT use the same handler?
- */
- oc_resource_set_request_handler(resource->res, OC_GET, ocf_get_handler, resource);
- oc_resource_set_request_handler(resource->res, OC_PUT, ocf_put_handler, resource);
- oc_resource_set_request_handler(resource->res, OC_POST, ocf_put_handler, resource);
+ jerry_release_value(iface_array);
- oc_add_resource(resource->res);
+ // Start OCF. Device/platform/resource properties should all be set after
+ if (zjs_ocf_start() < 0) {
+ REJECT(promise, "InternalError", "OCF failed to start", h);
+ return promise;
+ }
- /*resource_list_t *new = zjs_malloc(sizeof(resource_list_t));
- new->resource = resource->res;
- new->next = r_list;
- r_list = new;*/
+ // Get UUID and set it in the ocf.device object
+ char uuid[37];
+ oc_uuid_to_str(&oc_device_info[resource->res->device].uuid, uuid, 37);
+ zjs_set_uuid(uuid);
h = new_ocf_handler(resource);
zjs_make_promise(promise, post_ocf_promise, h);
@@ -526,26 +579,56 @@ static jerry_value_t ocf_register(const jerry_value_t function_val,
DBG_PRINT("registered resource, path=%s\n", resource_path);
- jerry_release_value(res_type_array);
-
return promise;
}
-/*
- * TODO: iotivity-constrained requires that resources get registered in this
- * function, which gets called long before we know about any resources.
- * What we have "works" but its not how its supposed to be structured.
- */
void zjs_ocf_register_resources(void)
{
- // ZJS_PRINT("zjs_ocf_register_resources() callback\n");
- /*resource_list_t *cur = r_list;
+ resource_list_t* cur = res_list;
while (cur) {
- oc_add_resource(cur->resource);
- resource_list_t *next = cur->next;
- zjs_free(cur);
- cur = next;
- }*/
+ int i;
+ struct server_resource* resource = cur->resource;
+
+ resource->res = oc_new_resource(resource->resource_path, resource->num_types, 0);
+ for (i = 0; i < resource->num_types; ++i) {
+ oc_resource_bind_resource_type(resource->res, resource->resource_types[i]);
+ }
+ for (i = 0; i < resource->num_ifaces; ++i) {
+ if (strcmp(resource->resource_ifaces[i], "/oic/if/rw") == 0) {
+ oc_resource_bind_resource_interface(resource->res, OC_IF_RW);
+ oc_resource_set_default_interface(resource->res, OC_IF_RW);
+ } else if (strcmp(resource->resource_ifaces[0], "/oic/if/r") == 0) {
+ oc_resource_bind_resource_interface(resource->res, OC_IF_R);
+ oc_resource_set_default_interface(resource->res, OC_IF_R);
+ } else if (strcmp(resource->resource_ifaces[0], "/oic/if/a") == 0) {
+ oc_resource_bind_resource_interface(resource->res, OC_IF_A);
+ oc_resource_set_default_interface(resource->res, OC_IF_A);
+ } else if (strcmp(resource->resource_ifaces[0], "/oic/if/s") == 0) {
+ oc_resource_bind_resource_interface(resource->res, OC_IF_S);
+ oc_resource_set_default_interface(resource->res, OC_IF_S);
+ } else if (strcmp(resource->resource_ifaces[0], "/oic/if/b") == 0) {
+ oc_resource_bind_resource_interface(resource->res, OC_IF_B);
+ oc_resource_set_default_interface(resource->res, OC_IF_B);
+ } else if (strcmp(resource->resource_ifaces[0], "/oic/if/ll") == 0) {
+ oc_resource_bind_resource_interface(resource->res, OC_IF_LL);
+ oc_resource_set_default_interface(resource->res, OC_IF_LL);
+ }
+ }
+ if (resource->flags & FLAG_DISCOVERABLE) {
+ oc_resource_set_discoverable(resource->res, 1);
+ }
+ if (resource->flags & FLAG_OBSERVE) {
+ oc_resource_set_periodic_observable(resource->res, 1);
+ }
+
+ oc_resource_set_request_handler(resource->res, OC_GET, ocf_get_handler, resource);
+ oc_resource_set_request_handler(resource->res, OC_PUT, ocf_put_handler, resource);
+ oc_resource_set_request_handler(resource->res, OC_POST, ocf_put_handler, resource);
+
+ oc_add_resource(resource->res);
+
+ cur = cur->next;
+ }
}
jerry_value_t zjs_ocf_server_init()
@@ -560,4 +643,42 @@ jerry_value_t zjs_ocf_server_init()
return server;
}
+void zjs_ocf_server_cleanup()
+{
+ if (res_list) {
+ resource_list_t* cur = res_list;
+ while (cur) {
+ int i;
+ struct server_resource* resource = cur->resource;
+ if (resource->device_id) {
+ zjs_free(resource->device_id);
+ }
+ if (resource->resource_path) {
+ zjs_free(resource->resource_path);
+ }
+ if (resource->resource_types) {
+ for (i = 0; i < resource->num_types; ++i) {
+ if (resource->resource_types[i]) {
+ zjs_free(resource->resource_types[i]);
+ }
+ }
+ zjs_free(resource->resource_types);
+ }
+ if (resource->resource_ifaces) {
+ for (i = 0; i < resource->num_ifaces; ++i) {
+ if (resource->resource_ifaces[i]) {
+ zjs_free(resource->resource_ifaces[i]);
+ }
+ }
+ zjs_free(resource->resource_ifaces);
+ }
+ jerry_release_value(resource->object);
+ zjs_free(resource);
+ res_list = res_list->next;
+ zjs_free(cur);
+ cur = res_list;
+ }
+ }
+}
+
#endif // BUILD_MODULE_OCF
diff --git a/src/zjs_ocf_server.h b/src/zjs_ocf_server.h
index 291474e..465bab4 100644
--- a/src/zjs_ocf_server.h
+++ b/src/zjs_ocf_server.h
@@ -3,5 +3,17 @@
#include "zjs_util.h"
#include "zjs_common.h"
+/*
+ * Initialize and return OCF server object
+ */
jerry_value_t zjs_ocf_server_init();
+
+/*
+ * iotivity-constrained callback to register resources.
+ */
void zjs_ocf_register_resources(void);
+
+/*
+ * OCF server module cleanup
+ */
+void zjs_ocf_server_cleanup();