Commit a0f1d9e1 authored by George Nash's avatar George Nash Committed by Kishen Maloor

Add callbacks for ownership status

Add a callback that is invoked when doxm "owned" value is
changed.

Add an API to query the current ownership status of a device.
Signed-off-by: George Nash's avatarGeorge Nash <george.nash@intel.com>
parent 492817f0
Pipeline #772 passed with stage
in 6 minutes and 53 seconds
......@@ -38,8 +38,7 @@
#include "port/oc_storage.h"
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
/**
......@@ -560,6 +559,64 @@ void oc_reset();
*/
void oc_reset_device(size_t device);
/**
* Callback invoked when the "owned" property of the doxm is changed
*
* @param device_uuid the UUID of the device that change ownership
* @param device_index of the logical device that changed ownership
* @param owned if true the device has been claimed by an onboarding tool
* @param user_data context pointer
*/
typedef void (*oc_ownership_status_cb_t)(const oc_uuid_t *device_uuid,
size_t device_index, bool owned,
void *user_data);
/**
* Add callback that is invoked when the doxm "owned" property is changed
*
* If oc_add_ownership_status_cb is called before oc_main_init or inside
* one of the , the oc_handler_t callback funtions the oc_ownership_status_cb_t
* will be invoked when the stack is initilized giving the startup ownership
* value. If oc_add_ownership_status_cb is called after oc_main_init the
* oc_add_ownership_status_cb will not be invoked for the startup ownership
* value.
*
* @note Use of this function requires building the stack with OC_SECURITY
* defined.
*
* @param cb callback function that will be invoked
* @param user_data context pointer passed to the oc_ownership_status_cb_t
* callback the pointer must remain valid till callback is removed.
*/
void oc_add_ownership_status_cb(oc_ownership_status_cb_t cb, void *user_data);
/**
* Remove the ownership changed callback
*
* @note Use of this function requires building the stack with OC_SECURITY
* defined.
*
* @param cb callback function to remove
* @param user_data the context pointer used when the callback was added
*/
void oc_remove_ownership_status_cb(oc_ownership_status_cb_t cb,
void *user_data);
/**
* Get the ownership status of the logical device this is the value of the
* doxm "owned" property
*
* If oc_is_owned_device is called before oc_main_init has completed it will
* always return false because stack security has not been intialized.
*
* @note Use of this function requires building the stack with OC_SECURITY
* defined.
*
* @param device_index the index of the logical device
*
* @return true if the device is owned by an onboarding tool
*/
bool oc_is_owned_device(size_t device_index);
/* Server side */
/**
@defgroup doc_module_tag_server_side Server side
......
......@@ -33,14 +33,30 @@
#include "port/oc_assert.h"
#include <stdlib.h>
static oc_sec_doxm_t *doxm;
#else /* OC_DYNAMIC_ALLOCATION */
#else /* OC_DYNAMIC_ALLOCATION */
static oc_sec_doxm_t doxm[OC_MAX_NUM_DEVICES];
#endif /* !OC_DYNAMIC_ALLOCATION */
typedef struct oc_doxm_owned_cb_s
{
struct oc_doxm_owned_cb_s *next;
oc_ownership_status_cb_t cb;
void *user_data;
} oc_doxm_owned_cb_t;
OC_LIST(oc_doxm_owned_cb_list_t);
OC_MEMB(oc_doxm_owned_cb_s, oc_doxm_owned_cb_t, OC_MAX_DOXM_OWNED_CBS);
void
oc_sec_doxm_free(void)
{
#ifdef OC_DYNAMIC_ALLOCATION
oc_doxm_owned_cb_t *doxm_cb_item =
(oc_doxm_owned_cb_t *)oc_list_pop(oc_doxm_owned_cb_list_t);
while (doxm_cb_item) {
free(doxm_cb_item);
doxm_cb_item = (oc_doxm_owned_cb_t *)oc_list_pop(oc_doxm_owned_cb_list_t);
}
if (doxm) {
free(doxm);
}
......@@ -79,6 +95,17 @@ evaluate_supported_oxms(size_t device)
void
oc_sec_doxm_default(size_t device)
{
// invoke the device owned changed cb before the deviceuuid is reset
if (doxm[device].owned) {
oc_doxm_owned_cb_t *doxm_cb_item =
(oc_doxm_owned_cb_t *)oc_list_head(oc_doxm_owned_cb_list_t);
while (doxm_cb_item) {
(doxm_cb_item->cb)(&doxm[device].deviceuuid, device, false,
doxm_cb_item->user_data);
doxm_cb_item = doxm_cb_item->next;
}
}
doxm[device].oxmsel = 0;
#ifdef OC_PKI
doxm[device].sct = 9;
......@@ -165,6 +192,7 @@ oc_sec_decode_doxm(oc_rep_t *rep, bool from_storage, size_t device)
oc_sec_pstat_t *ps = oc_sec_get_pstat(device);
oc_rep_t *t = rep;
size_t len = 0;
bool owned_changed = false;
while (t != NULL) {
len = oc_string_len(t->name);
......@@ -261,6 +289,7 @@ oc_sec_decode_doxm(oc_rep_t *rep, bool from_storage, size_t device)
case OC_REP_BOOL:
if (len == 5 && memcmp(oc_string(rep->name), "owned", 5) == 0) {
doxm[device].owned = rep->value.boolean;
owned_changed = true;
}
break;
/* oxmsel and sct */
......@@ -295,6 +324,17 @@ oc_sec_decode_doxm(oc_rep_t *rep, bool from_storage, size_t device)
}
rep = rep->next;
}
if (owned_changed == true) {
oc_doxm_owned_cb_t *doxm_cb_item =
(oc_doxm_owned_cb_t *)oc_list_head(oc_doxm_owned_cb_list_t);
while (doxm_cb_item) {
oc_doxm_owned_cb_t *invokee = doxm_cb_item;
doxm_cb_item = doxm_cb_item->next;
(invokee->cb)(&doxm[device].deviceuuid, device, doxm[device].owned,
invokee->user_data);
}
}
return true;
}
......@@ -312,4 +352,39 @@ post_doxm(oc_request_t *request, oc_interface_mask_t iface_mask, void *data)
}
}
void
oc_add_ownership_status_cb(oc_ownership_status_cb_t cb, void *user_data)
{
oc_doxm_owned_cb_t *new_doxm_cb = oc_memb_alloc(&oc_doxm_owned_cb_s);
if (!new_doxm_cb) {
oc_abort("Insufficient memory");
}
new_doxm_cb->cb = cb;
new_doxm_cb->user_data = user_data;
oc_list_add(oc_doxm_owned_cb_list_t, new_doxm_cb);
}
void
oc_remove_ownership_status_cb(oc_ownership_status_cb_t cb, void *user_data)
{
oc_doxm_owned_cb_t *doxm_cb_item =
(oc_doxm_owned_cb_t *)oc_list_head(oc_doxm_owned_cb_list_t);
while (doxm_cb_item) {
if (cb == doxm_cb_item->cb && user_data == doxm_cb_item->user_data) {
oc_list_remove(oc_doxm_owned_cb_list_t, doxm_cb_item);
free(doxm_cb_item);
break;
}
doxm_cb_item = doxm_cb_item->next;
}
}
bool
oc_is_owned_device(size_t device_index)
{
if (doxm) {
return doxm[device_index].owned;
}
return false;
}
#endif /* OC_SECURITY */
......@@ -26,8 +26,7 @@
#include <stdbool.h>
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
typedef enum oc_sec_doxmtype_t {
......
package java_lite_simple_server;
import org.iotivity.OCMain;
import org.iotivity.OCOwnershipStatusHandler;
import org.iotivity.OCUuid;
import org.iotivity.OCUuidUtil;
public class OwnershipStatusHandler implements OCOwnershipStatusHandler {
@Override
public void handler(OCUuid uuid, long device_index, boolean owned) {
System.out.print("Ownership Status: [" + device_index + "]" + OCUuidUtil.uuidToString(uuid));
if (owned) {
System.out.println(" owned.");
} else {
System.out.println(" un-owned.");
}
}
}
......@@ -33,6 +33,13 @@ public class Server {
System.exit(init_ret);
}
if (OCMain.isOwnedDevice(0)) {
System.out.println("Sever is already owned");
} else {
System.out.println("Sever is currently Un-owned");
}
OCMain.addOwnershipStatusHandler(new OwnershipStatusHandler());
try {
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
......
This diff is collapsed.
......@@ -28,7 +28,7 @@
#include "util/oc_list.h"
#include <jni.h>
#if defined (_WIN32)
#if defined(_WIN32)
HANDLE jni_poll_event_thread;
CRITICAL_SECTION jni_sync_lock;
CONDITION_VARIABLE jni_cv;
......@@ -63,7 +63,8 @@ typedef enum {
OC_CALLBACK_VALID_TILL_SET_CON_WRITE_CB,
OC_CALLBACK_VALID_TILL_DELETE_RESOURCE,
OC_CALLBACK_VALID_TILL_REMOVE_DELAYED_CALLBACK,
OC_CALLBACK_VALID_TILL_CLOUD_MANAGER_STOP
OC_CALLBACK_VALID_TILL_CLOUD_MANAGER_STOP,
OC_CALLBACK_VALID_TILL_REMOVE_OWNERSHIP_STATUS
} jni_callback_valid_t;
/*
......@@ -129,6 +130,7 @@ jclass cls_OCDiscoveryAllHandler;
jclass cls_OCFactoryPresetsHandler;
jclass cls_OCGetPropertiesHandler;
jclass cls_OCInitPlatformHandler;
jclass cls_OCOwnershipStatusHandler;
jclass cls_OCQueryValue;
jclass cls_OCRandomPinHandler;
jclass cls_OCRepresentation;
......@@ -169,14 +171,15 @@ jclass cls_OCSecurityAcl;
* passed back upto the java callback class. Serving the same
* function as the C void *user_data pointer.
*/
typedef struct jni_callback_data_s {
typedef struct jni_callback_data_s
{
struct jni_callback_data_s *next;
JNIEnv *jenv;
jobject jcb_obj;
jni_callback_valid_t cb_valid;
} jni_callback_data;
jni_callback_data * jni_list_get_head();
jni_callback_data *jni_list_get_head();
void jni_list_add(jni_callback_data *item);
void jni_list_remove(jni_callback_data *item);
void jni_list_clear();
......
package org.iotivity;
public interface OCOwnershipStatusHandler {
public void handler(OCUuid uuid, long device_index, boolean owned);
}
\ No newline at end of file
......@@ -525,6 +525,137 @@ void jni_reset_device(size_t device) {
}
%}
/* Code and typemaps for mapping the ocownership_status_cb to the OCOwnershipHandler */
%{
void jni_ownership_status_cb(const oc_uuid_t *device_uuid,
size_t device_index, bool owned,
void *user_data)
{
OC_DBG("JNI: %s\n", __func__);
jni_callback_data *data = (jni_callback_data *)user_data;
jint getEnvResult = 0;
data->jenv = get_jni_env(&getEnvResult);
assert(data->jenv);
assert(cls_OCOwnershipStatusHandler);
const jmethodID mid_handler = JCALL3(GetMethodID,
(data->jenv),
cls_OCOwnershipStatusHandler,
"handler",
"(Lorg/iotivity/OCUuid;JZ)V");
assert(mid_handler);
jobject jdevice_uuid = NULL;
if (device_uuid) {
assert(cls_OCUuid);
const jmethodID mid_OCUuid_init = JCALL3(GetMethodID, (data->jenv), cls_OCUuid, "<init>", "(JZ)V");
assert(mid_OCUuid_init);
/* make copy of uuid that will be owned by Java code */
oc_uuid_t *new_uuid = malloc(sizeof(oc_uuid_t));
memcpy(new_uuid->id, device_uuid->id, 16);
jdevice_uuid = JCALL4(NewObject, (data->jenv), cls_OCUuid, mid_OCUuid_init, (jlong)new_uuid, true);
}
JCALL5(CallVoidMethod,
(data->jenv),
data->jcb_obj,
mid_handler,
jdevice_uuid,
(jlong)device_index,
(jboolean)owned);
release_jni_env(getEnvResult);
}
%}
%typemap(jni) oc_ownership_status_cb_t cb "jobject";
%typemap(jtype) oc_ownership_status_cb_t cb "OCOwnershipStatusHandler";
%typemap(jstype) oc_ownership_status_cb_t cb "OCOwnershipStatusHandler";
%typemap(javain) oc_ownership_status_cb_t cb "$javainput";
%typemap(in,numinputs=1) (oc_ownership_status_cb_t cb, jni_callback_data *jcb)
{
jni_callback_data *user_data = (jni_callback_data *)malloc(sizeof *user_data);
user_data->jenv = jenv;
// see jni_remove_ownership_status_cb for the deletion of the GlobalRef in the jni_list_remove calls
user_data->jcb_obj = JCALL1(NewGlobalRef, jenv, $input);
user_data->cb_valid = OC_CALLBACK_VALID_TILL_REMOVE_OWNERSHIP_STATUS;
jni_list_add(user_data);
$1 = jni_ownership_status_cb;
$2 = user_data;
}
// DOCUMENTATION workaround
%javamethodmodifiers jni_add_ownership_status_cb "/**
* Add handler that is invoked when the doxm 'owned' property is changed
*
* If OCMain.addOwnershipStatusHandler is called before OCMain.init or inside
* one of the OCMainInitHandler callbacks, the OCOwnershipStatusHandler.handler
* will be invoked when the stack is initilized giving the startup ownership
* value. If called after OCMain.init the OCOwnershipStatusHandler.handler will
* not be invoked for the startup ownership value.
*
* Use of this method requires using the stack with security enabled.
*
* @param cb OCOwnershipStatusHandler class that will be invoked
*/
public";
%ignore oc_add_ownership_status_cb;
%rename (addOwnershipStatusHandler) jni_add_ownership_status_cb;
%inline %{
void jni_add_ownership_status_cb(oc_ownership_status_cb_t cb, jni_callback_data *jcb)
{
OC_DBG("JNI: %s\n", __func__);
#ifdef OC_SECURITY
oc_add_ownership_status_cb(cb, jcb);
#endif
}
%}
// DOCUMENTATION workaround
%javamethodmodifiers jni_remove_ownership_status_cb "/**
* Remove the ownership changed handler
*
* Use of this method requires using the stack with security enabled.
*
* @param cb OCOwnershipStatusHandler class to remove
*/
public";
%ignore oc_remove_ownership_status_cb;
%rename (removeOwnershipStatusHandler) jni_remove_ownership_status_cb;
%inline %{
void jni_remove_ownership_status_cb(jobject cb)
{
OC_DBG("JNI: %s\n", __func__);
#ifdef OC_SECURITY
jni_callback_data *item = jni_list_get_item_by_java_callback(cb);
if (item) {
assert(item->cb_valid == OC_CALLBACK_VALID_TILL_REMOVE_OWNERSHIP_STATUS);
oc_remove_ownership_status_cb(jni_ownership_status_cb, item);
}
jni_list_remove(item);
#endif
}
%}
// DOCUMENTATION workaround
%javamethodmodifiers oc_is_owned_device "/**
* Get the ownership status of the logical device, this is the value of the
* doxm 'owned' property
*
* If OCMain.isOwnedDevice is called before OCMain.init has it will
* always return false because stack security has not been intialized.
*
* Use of this method requires using the stack with security enabled.
*
* @param device_index the index of the logical device
*
* @return true if the device is owned by an onboarding tool
*/
public";
%rename (isOwnedDevice) oc_is_owned_device;
// server side
%rename(newResource) oc_new_resource;
%rename(resourceBindResourceInterface) oc_resource_bind_resource_interface;
......
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