iotivity: support for android..."/compass1", resource_type, interface, entityhandler,...
TRANSCRIPT
1
IoTivity: Support for Android
Tim KourtLinux Foundation Collaboration Summit
February 20, 2015
2
Introduction to the IoTivity
Building blocks
Dive into the code
Android API Overview
Demo
3
What is the IoTivity Project?
IoTivity is an open source software framework providing connectivity for the Internet of
Things (IoT)
IoTivity is a reference implementation of the Open Interconnect Consortium (OIC)
specification
IoT technologies here will span multiple industries including:
• smart home
• automotive
• industrial automation
• healthcare
4
IoTivity Example
Smart Light BulbSmart Light Switch
Multicast request: Get light bulbs
Unicast response: I’m a light bulb
What is your status?
Set Status: On
Status (Off, Dim :75, …)
OK, Done
RESOURCE
LightStatus: On/Off
Dimming: 0 - 100
Hue: RGB
Color Temp: KLocal Network
Client Server
5
Building Blocks for Android SupportBuilding on top of an existing C++ SDK
• The IoTivity project has a well established C++ SDK for the unconstrained environments
• The Java language binding for the IoTivity is build on top of the C++ SDK and mimics its
APIs. The key reasons:
• Reuse of an existing code
• Maintainability
• Early detection of the programming errors
IoTivity Base (C++ SDK)
Application (C++)
IoTivity Base (C++ SDK)
JAVA
IoTivity Base (C SDK) IoTivity Base (C SDK)
6
Binding the IoTivity C++ APIs to Java
C++ API:
typedef std::function<void(std::shared_ptr<OCResource>)> FindCallback;
OCStackResult findResource(const std::string& host,
const std::string& resourceURI,
FindCallback resourceHandler);
public interface OnResourceFoundListener {
public void onResourceFound(OcResource resource);
}
public static native void findResource(
String host,
String resourceUri,
OnResourceFoundListener onResourceFoundListener) throws OcException;
Java API:
7
The Mechanics of Binding• Java Native Interface(JNI) is a programming framework that enables Java code running
in a Java Virtual Machine to interact with native libraries
• JNI glue layer (wrapper written in C++ ) maintains Java and native objects and
interoperability between them
• One-to-one relationship between the native and Java objects
Java library JNI glue layer Native library
OcJavaObject OcJniObject OCNativeObject
JNI
• Uses Java reflection to manipulate
OcJavaObjects
• Keeps a copy or refference to
OCNativeObjects
• Maintains refs for the listener objects
in JVM
• Keeps ref. to OcJniObjects
as a long
8
Memory ManagementThe differences between the C++ and Java programming languages
• Java has garbage collection mechanism
• C++ uses explicit memory management
• Java class’s finalize methods are used to delete C++ objects
public class OcResource {
. . .
@Override
protected void finalize() throws Throwable {
super.finalize();
dispose();
}
private native void dispose();
private long mNativeHandle;
}
Java:
JNIEXPORT void JNICALL
Java_org_iotivity_base_OcResource_dispose
(JNIEnv *env, jobject thiz)
{
JniOcResource *resource =
JniOcResource::getJniOcResourcePtr(env, thiz);
if (resource)
{
delete resource;
. . .
JNI:
9
Managing Listener Objects
OcPlatform.OnResourceFoundListener resourceFoundListener =
new OcPlatform.OnResourceFoundListener() {
@Override
public void onResourceFound(OcResource resource) {
//Do something
}
};
OcPlatform.findResource("",
RESOURCE_URI_1,
resourceFoundListener);
OcPlatform.findResource("",
RESOURCE_URI_2,
resourceFoundListener);
OcPlatform.findResource("",
RESOURCE_URI_3,
new OcPlatform.OnResourceFoundListener() {
@Override
public void onResourceFound(OcResource resource) {
//Do something
Java API use case:
public interface OnResourceFoundListener {
public void onResourceFound(OcResource resource);
Event handlers
10
JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_findResource
(JNIEnv *env, jclass clazz, jstring jHost, jstring jResourceUri, jobject jListener)
{
. . .
JniOnResourceFoundListener *onResFoundListener = AddOnResourceFoundListener(env, jListener);
FindCallback findCallback = [onResFoundListener](std::shared_ptr<OCResource> resource)
{
onResFoundListener->foundResourceCallback(resource);
};
OCStackResult result = OCPlatform::findResource(host, resourceUri, findCallback);
. . .
Managing Listener ObjectsEvent handlers
AddOnResourceFoundListener(env, jListener)
• Checks if jListener has been seen before:
• No: creates a global ref. in JVM, creates new wrapper JniOnResourceFoundListener and returns it
• Yes: increments reference counter for an existing JniOnResourceFoundListener and returns it
RemoveOnResourceFoundListener(env, jListener)
• Reverses the logic above
11
Exceptions
OCStackResult result = OCPlatform::findResource(host, resourceUri, findCallback);
if (OC_STACK_OK != result)
{
ThrowOcException(result, "Find resource has failed"); //Java exception gets thrown
...
Bindings throw and handle Java exceptions
env->CallVoidMethod(jListener, midL, jResource);
if (env->ExceptionCheck())
{
env->ExceptionClear();
LOGE("Exception is thrown in Java onResourceFound handler");
...
JNI
12
IoTivity Android Stack
Android Java Application (.apk)
IoTovity Base Java API library(.aar)
IoTivity Base C++ libraries (.so)
IoTovity JNI C++ glue layer (.so)
NativeJNI
JAVA
13
FunctionalityThe current Android API for IoTivity includes functionality for
• Resource registration
• Resource discovery
• Device discovery
• Resource management (get, set, observe)
• Resource tree (resources with sub-resources)
• Presence notification service defined as a virtual resource
14
Registering a ResourceRegistering a resource requires two basic items
• A handler to process requests from the stack
• A URI path to register the resource
OcPlatform.EntityHandler entityHandler = new OcPlatform.EntityHandler() {
@Override
public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) {
// handle request
return EntityHandlerResult.OK;
}
};
OcResourceHandle resourceHandle = OcPlatform.registerResource(
"/compass1",
RESOURCE_TYPE,
INTERFACE,
entityHandler,
EnumSet.of(ResourceProperty.DISCOVERABLE));
Server
15
Finding a Resource
This operation returns all resources of given type on the network service.
OcPlatform.OnResourceFoundListener resourceFoundListener =
new OcPlatform.OnResourceFoundListener() {
@Override
public void onResourceFound(OcResource resource) {
//do something
}
};
OcPlatform.findResource(
"",
"coap://224.0.1.187/oc/core?rt=" + RESOURCE_TYPE,
resourceFoundListener);
Client
16
Device Discovery
OcDeviceInfo devInfo = new OcDeviceInfo();
devInfo.setDeviceUuid("38454000-8cf0-11bd-b23e-10b96e4ef00d ");
devInfo.setFirmwareVersion(“2.3.4");
OcPlatform.registerDeviceInfo(devInfo);
Server
OcPlatform.OnDeviceFoundListener deviceFoundListener =
new OcPlatform.OnDeviceFoundListener() {
@Override
public void onDeviceFound(OcRepresentation ocRepresentation) {
Log.i(TAG, "Device Name: " + ocRepresentation.getValueString("dn"));
}
};
OcPlatform.getDeviceInfo("", "coap://224.0.1.187/oc/core/d", deviceFoundListener);
Client
17
Resource Management (get, set, observe)
@Override
public void onGetCompleted(List<OcHeaderOption> headerOptionList,
OcRepresentation ocRepresentation) {
}
@Override
public void onPutCompleted(List<OcHeaderOption> headerOptionList,
OcRepresentation ocRepresentation) {
}
@Override
public void onObserveCompleted(List<OcHeaderOption> headerOptionList,
OcRepresentation ocRepresentation,
int sequenceNumber) {
}
resource.get(queryParamsMap, this);
resource.put(queryParamsMap, this);
resource.observe(queryParamsMap, this);
Client
18
Resource Management (get, set, observe)
@Override
public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) {
...
if (handlerFlagSet.contains(RequestHandlerFlag.INIT)) {
...
}
if (handlerFlagSet.contains(RequestHandlerFlag.REQUEST)) {
switch (requestType) {
case GET:
break;
case PUT:
break;
}
OcPlatform.sendResponse(ocResourceResponse);
}
if (handlerFlagSet.contains(RequestHandlerFlag.OBSERVER)) {
...
}
return EntityHandlerResult.OK;
}
Server
19
Resource Tree
OcResourceHandle doorOpener = OcPlatform.registerResource(
"/doorOpener",
...
OcResourceHandle light1 = OcPlatform.registerResource(
"/Light1",
...
OcResourceHandle light2 = OcPlatform.registerResource(
"/Light2",
...
OcResourceHandle motor = OcPlatform.registerResource(
"/motor",
...
OcPlatform.bindResource(doorOpener, light1);
OcPlatform.bindResource(doorOpener, light2);
OcPlatform.bindResource(doorOpener, motor);
Server
20
Presence Notification
OcPlatform.startPresence(1);
//after some time
OcPlatform.stopPresence();
Server
public void onPresence(OcPresenceStatus ocPresenceStatus, int nonce, String hostAddress) {
//do something
}
OcPlatform.subscribePresence("coap://224.0.1.187“, this);
Client
Demo
Q & A