Commit 51ba75bd authored by Larry Sachs's avatar Larry Sachs Committed by Rick Bell

Additional work for Android Multi-Device Client

Moves the discovery logic previously in the client code
to the swig/oc_java/oc layer.  Added api for a single call
in OcUtils to discover all devices (and their resources).  Once the
resource discovery is complete the fully populated device
is handed to the client application's handler.

Change-Id: Ib71bc6d6f32a268fc143620346578f77819dcbc7
Signed-off-by: Larry Sachs's avatarLarry Sachs <larry.j.sachs@intel.com>
parent 4553e346
package org.iotivity.multideviceclient;
import android.util.Log;
import org.iotivity.OCUuidUtil;
import org.iotivity.oc.OcDeviceDiscoveryHandler;
import org.iotivity.oc.OcRemoteDevice;
public class DeviceDiscoveryHandler implements OcDeviceDiscoveryHandler {
private static final String TAG = DeviceDiscoveryHandler.class.getSimpleName();
private MultiDeviceClientActivity activity;
public DeviceDiscoveryHandler(MultiDeviceClientActivity activity) {
this.activity = activity;
}
@Override
public void discoveredDevice(OcRemoteDevice remoteDevice) {
Log.d(TAG, "Remote Device Discovery Handler: " + OCUuidUtil.uuidToString(remoteDevice.getDeviceId()) + ", " + remoteDevice.getName());
activity.addDevice(remoteDevice);
}
}
package org.iotivity.multideviceclient;
import android.util.Log;
import android.widget.Toast;
import org.iotivity.OCClientResponse;
import org.iotivity.OCEndpoint;
import org.iotivity.OCResponseHandler;
import org.iotivity.OCUuidUtil;
import org.iotivity.oc.OcCborException;
import org.iotivity.oc.OcRepresentation;
import org.iotivity.oc.OcUtils;
public class GetDeviceHandler implements OCResponseHandler {
private static final String TAG = GetDeviceHandler.class.getSimpleName();
private static final String N_KEY = "n";
private static final String DI_KEY = "di";
private MultiDeviceClientActivity activity;
public GetDeviceHandler(MultiDeviceClientActivity activity) {
this.activity = activity;
}
@Override
public void handler(OCClientResponse response) {
Log.d(TAG, "Get Device Name Handler:");
OcRepresentation rep = new OcRepresentation(response.getPayload());
String n = null;
String di = null;
while (rep != null) {
try {
if (N_KEY.equals(rep.getKey())) {
n = rep.getString(N_KEY);
}
if (DI_KEY.equals(rep.getKey())) {
di = rep.getString(DI_KEY);
}
} catch (OcCborException e) {
Log.e(TAG, e.getMessage());
}
rep = rep.getNext();
}
if ((di != null) && (n != null)) {
Log.d(TAG, "\tdi: " + di);
Log.d(TAG, "\tn: " + n);
OcfDeviceInfo deviceInfo = new OcfDeviceInfo(OCUuidUtil.stringToUuid(di), n);
OCEndpoint ep = response.getEndpoint();
while (ep != null) {
String endpointStr = OcUtils.endpointToString(ep);
Log.d(TAG, "\tendpoint: " + endpointStr);
deviceInfo.addEndpoint(endpointStr);
ep = ep.getNext();
}
Log.d(TAG, "discover resources at endpoint " + deviceInfo.getEndpoints()[0]);
if (!OcUtils.doIPDiscoveryAllAtEndpoint(new ResourceDiscoveryAllHandler(deviceInfo), response.getEndpoint())) {
final String msg = "Error issuing resource discovery all request for uuid " + di;
Log.d(TAG, msg);
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
}
});
}
activity.addDevice(deviceInfo);
}
}
}
......@@ -17,6 +17,8 @@ import android.widget.Toast;
import org.iotivity.OCUuidUtil;
import org.iotivity.oc.OcPlatform;
import org.iotivity.oc.OcRemoteDevice;
import org.iotivity.oc.OcRemoteResource;
import org.iotivity.oc.OcUtils;
import java.util.ArrayList;
......@@ -30,12 +32,12 @@ public class MultiDeviceClientActivity extends AppCompatActivity {
private ListView listView;
private AdapterView.OnItemClickListener resourceItemClickListener;
private ArrayAdapter<OcfResourceInfo> resourceArrayAdapter;
private ArrayAdapter<OcRemoteResource> resourceArrayAdapter;
private AdapterView.OnItemClickListener deviceItemClickListener;
private ArrayAdapter<OcfDeviceInfo> deviceArrayAdapter;
private ArrayAdapter<OcRemoteDevice> deviceArrayAdapter;
ArrayList<OcfDeviceInfo> deviceList = new ArrayList<>();
ArrayList<OcRemoteDevice> deviceList = new ArrayList<>();
private final Object arrayAdapterSync = new Object();
private OcPlatform ocPlatform;
......@@ -48,10 +50,10 @@ public class MultiDeviceClientActivity extends AppCompatActivity {
resourceItemClickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
OcfResourceInfo resourceInfo = resourceArrayAdapter.getItem((int) id);
if (resourceInfo != null) {
OcRemoteResource resource = resourceArrayAdapter.getItem((int) id);
if (resource != null) {
AlertDialog.Builder resourceDialogBuilder = new AlertDialog.Builder(MultiDeviceClientActivity.this);
resourceDialogBuilder.setTitle(resourceInfo.getAnchor() + resourceInfo.getUri());
resourceDialogBuilder.setTitle(resource.getAnchor() + resource.getUri());
ListView resourceDetailsListView = new ListView(MultiDeviceClientActivity.this);
final ArrayList<HashMap<String, String>> resourceDetailsList = new ArrayList<>();
......@@ -62,7 +64,7 @@ public class MultiDeviceClientActivity extends AppCompatActivity {
resourceDetailsListView.setAdapter(resourceDetailsAdapter);
resourceDialogBuilder.setView(resourceDetailsListView);
ResourceDetailsHelper.buildResourceDetails(resourceInfo, resourceDetailsList);
ResourceDetailsHelper.buildResourceDetails(resource, resourceDetailsList);
Dialog resourceDialog = resourceDialogBuilder.create();
resourceDialog.show();
......@@ -76,22 +78,22 @@ public class MultiDeviceClientActivity extends AppCompatActivity {
deviceItemClickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
OcfDeviceInfo deviceInfo = deviceArrayAdapter.getItem((int) id);
if (deviceInfo != null) {
OcRemoteDevice device = deviceArrayAdapter.getItem((int) id);
if (device != null) {
AlertDialog.Builder discoverResourcesDialogBuilder = new AlertDialog.Builder(MultiDeviceClientActivity.this);
discoverResourcesDialogBuilder.setTitle(R.string.discoveredResources);
ListView resourceListView = new ListView(MultiDeviceClientActivity.this);
final ArrayList<OcfResourceInfo> resourceArrayList = new ArrayList<>();
final ArrayList<OcRemoteResource> resourceArrayList = new ArrayList<>();
resourceArrayAdapter = new ArrayAdapter(MultiDeviceClientActivity.this, android.R.layout.simple_list_item_1, android.R.id.text1, resourceArrayList) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView text1 = (TextView) view.findViewById(android.R.id.text1);
OcfResourceInfo resourceInfo = resourceArrayAdapter.getItem(position);
if (resourceInfo != null) {
text1.setText(resourceInfo.getAnchor() + resourceInfo.getUri());
OcRemoteResource resource = resourceArrayAdapter.getItem(position);
if (resource != null) {
text1.setText(resource.getAnchor() + resource.getUri());
}
return view;
}
......@@ -101,8 +103,8 @@ public class MultiDeviceClientActivity extends AppCompatActivity {
discoverResourcesDialogBuilder.setView(resourceListView);
resourceArrayAdapter.setNotifyOnChange(false);
for (OcfResourceInfo resourceInfo : deviceInfo.getResourceInfos()) {
resourceArrayAdapter.add(resourceInfo);
for (OcRemoteResource resource : device.getResources()) {
resourceArrayAdapter.add(resource);
}
resourceArrayAdapter.setNotifyOnChange(true);
......@@ -127,7 +129,7 @@ public class MultiDeviceClientActivity extends AppCompatActivity {
new Thread(new Runnable() {
public void run() {
if (!OcUtils.doIPMulticast("/oic/d", null, new GetDeviceHandler(MultiDeviceClientActivity.this))) {
if (!OcUtils.discoverAllDevices(new DeviceDiscoveryHandler(MultiDeviceClientActivity.this))) {
final String msg = "Failed to discover devices";
Log.d(TAG, msg);
runOnUiThread(new Runnable() {
......@@ -148,10 +150,10 @@ public class MultiDeviceClientActivity extends AppCompatActivity {
TextView text1 = (TextView) view.findViewById(android.R.id.text1);
TextView text2 = (TextView) view.findViewById(android.R.id.text2);
OcfDeviceInfo deviceInfo = deviceArrayAdapter.getItem(position);
if (deviceInfo != null) {
text1.setText(OCUuidUtil.uuidToString(deviceInfo.getUuid()));
text2.setText("\t" + deviceInfo.getName());
OcRemoteDevice device = deviceArrayAdapter.getItem(position);
if (device != null) {
text1.setText(OCUuidUtil.uuidToString(device.getDeviceId()));
text2.setText("\t" + device.getName());
}
return view;
}
......@@ -176,10 +178,10 @@ public class MultiDeviceClientActivity extends AppCompatActivity {
super.onDestroy();
}
public void addDevice(OcfDeviceInfo deviceInfo) {
public void addDevice(OcRemoteDevice device) {
synchronized (arrayAdapterSync) {
deviceArrayAdapter.setNotifyOnChange(false);
deviceArrayAdapter.add(deviceInfo);
deviceArrayAdapter.add(device);
deviceArrayAdapter.setNotifyOnChange(true);
}
......
package org.iotivity.multideviceclient;
import java.util.ArrayList;
import java.util.List;
import org.iotivity.OCUuid;
public class OcfDeviceInfo {
private OCUuid uuid;
private String name;
private List<String> endpoints = new ArrayList<>();
private List<OcfResourceInfo> resourceInfos = new ArrayList<>();
OcfDeviceInfo(OCUuid uuid, String name) {
this.uuid = uuid;
this.name = name;
}
public OCUuid getUuid() {
return uuid;
}
public String getName() {
return name;
}
public String[] getEndpoints() {
return endpoints.toArray(new String[0]);
}
public void addEndpoint(String endpoint) {
if (endpoint != null) {
endpoints.add(endpoint);
}
}
public OcfResourceInfo[] getResourceInfos() {
return resourceInfos.toArray(new OcfResourceInfo[0]);
}
public void addResourceInfo(OcfResourceInfo resourceInfo) {
if (resourceInfo != null) {
resourceInfos.add(resourceInfo);
}
}
public int hashCode() {
int result = 17;
result = 37 * result + uuid.hashCode();
result = 37 * result + name.hashCode();
return result;
}
public boolean equals(Object obj) {
OcfDeviceInfo other = (OcfDeviceInfo) obj;
return (uuid.equals(other.uuid) && name.equals(other.name));
}
}
......@@ -2,8 +2,11 @@ package org.iotivity.multideviceclient;
import android.util.Log;
import org.iotivity.OCEndpoint;
import org.iotivity.OCInterfaceMask;
import org.iotivity.OCResourcePropertiesMask;
import org.iotivity.oc.OcRemoteResource;
import org.iotivity.oc.OcUtils;
import java.util.ArrayList;
import java.util.Arrays;
......@@ -13,55 +16,55 @@ public class ResourceDetailsHelper {
private static final String TAG = ResourceDetailsHelper.class.getSimpleName();
static public void buildResourceDetails(OcfResourceInfo resourceInfo, ArrayList<HashMap<String, String>> resourceDetailsList) {
if (resourceInfo != null) {
static public void buildResourceDetails(OcRemoteResource resource, ArrayList<HashMap<String, String>> resourceDetailsList) {
if (resource != null) {
HashMap<String, String> item = new HashMap<>();
String line = "Types: " + Arrays.toString(resourceInfo.getTypes());
String line = "Types: " + Arrays.toString(resource.getTypes());
item.put("line1", line);
Log.d(TAG, line);
StringBuilder interfaces = new StringBuilder();
if ((resourceInfo.getInterfaceMask() & OCInterfaceMask.BASELINE) > 0) {
if ((resource.getInterfaceMask() & OCInterfaceMask.BASELINE) > 0) {
interfaces.append("BASELINE");
}
if ((resourceInfo.getInterfaceMask() & OCInterfaceMask.LL) > 0) {
if ((resource.getInterfaceMask() & OCInterfaceMask.LL) > 0) {
if (interfaces.length() > 0) {
interfaces.append(" | ");
}
interfaces.append("LL");
}
if ((resourceInfo.getInterfaceMask() & OCInterfaceMask.B) > 0) {
if ((resource.getInterfaceMask() & OCInterfaceMask.B) > 0) {
if (interfaces.length() > 0) {
interfaces.append(" | ");
}
interfaces.append("B");
}
if ((resourceInfo.getInterfaceMask() & OCInterfaceMask.R) > 0) {
if ((resource.getInterfaceMask() & OCInterfaceMask.R) > 0) {
if (interfaces.length() > 0) {
interfaces.append(" | ");
}
interfaces.append("R");
}
if ((resourceInfo.getInterfaceMask() & OCInterfaceMask.RW) > 0) {
if ((resource.getInterfaceMask() & OCInterfaceMask.RW) > 0) {
if (interfaces.length() > 0) {
interfaces.append(" | ");
}
interfaces.append("RW");
}
if ((resourceInfo.getInterfaceMask() & OCInterfaceMask.A) > 0) {
if ((resource.getInterfaceMask() & OCInterfaceMask.A) > 0) {
if (interfaces.length() > 0) {
interfaces.append(" | ");
}
interfaces.append("A");
}
if ((resourceInfo.getInterfaceMask() & OCInterfaceMask.S) > 0) {
if ((resource.getInterfaceMask() & OCInterfaceMask.S) > 0) {
if (interfaces.length() > 0) {
interfaces.append(" | ");
}
interfaces.append("S");
}
if ((resourceInfo.getInterfaceMask() & OCInterfaceMask.CREATE) > 0) {
if ((resource.getInterfaceMask() & OCInterfaceMask.CREATE) > 0) {
if (interfaces.length() > 0) {
interfaces.append(" | ");
}
......@@ -72,22 +75,22 @@ public class ResourceDetailsHelper {
Log.d(TAG, line);
StringBuilder resourceProperties = new StringBuilder();
if ((resourceInfo.getResourcePropertiesMask() & OCResourcePropertiesMask.OC_DISCOVERABLE) > 0) {
if ((resource.getResourcePropertiesMask() & OCResourcePropertiesMask.OC_DISCOVERABLE) > 0) {
resourceProperties.append("DISCOVERABLE");
}
if ((resourceInfo.getResourcePropertiesMask() & OCResourcePropertiesMask.OC_OBSERVABLE) > 0) {
if ((resource.getResourcePropertiesMask() & OCResourcePropertiesMask.OC_OBSERVABLE) > 0) {
if (resourceProperties.length() > 0) {
resourceProperties.append(" | ");
}
resourceProperties.append("OBSERVABLE");
}
if ((resourceInfo.getResourcePropertiesMask() & OCResourcePropertiesMask.OC_SECURE) > 0) {
if ((resource.getResourcePropertiesMask() & OCResourcePropertiesMask.OC_SECURE) > 0) {
if (resourceProperties.length() > 0) {
resourceProperties.append(" | ");
}
resourceProperties.append("SECURE");
}
if ((resourceInfo.getResourcePropertiesMask() & OCResourcePropertiesMask.OC_PERIODIC) > 0) {
if ((resource.getResourcePropertiesMask() & OCResourcePropertiesMask.OC_PERIODIC) > 0) {
if (resourceProperties.length() > 0) {
resourceProperties.append(" | ");
}
......@@ -98,11 +101,11 @@ public class ResourceDetailsHelper {
Log.d(TAG, line);
StringBuilder endPoints = new StringBuilder();
for (String endpoint : resourceInfo.getEndpoints()) {
for (OCEndpoint endpoint : resource.getEndpoints()) {
if (endPoints.length() > 0) {
endPoints.append("\n");
}
endPoints.append("\t" + endpoint);
endPoints.append("\t" + OcUtils.endpointToString(endpoint));
}
line = "Endpoints:\n" + endPoints.toString();
item.put("line4", line);
......
package org.iotivity.multideviceclient;
import android.util.Log;
import org.iotivity.OCDiscoveryAllHandler;
import org.iotivity.OCDiscoveryFlags;
import org.iotivity.OCEndpoint;
import org.iotivity.oc.OcUtils;
public class ResourceDiscoveryAllHandler implements OCDiscoveryAllHandler {
private static final String TAG = ResourceDiscoveryAllHandler.class.getSimpleName();
private OcfDeviceInfo deviceInfo;
public ResourceDiscoveryAllHandler(OcfDeviceInfo deviceInfo) {
this.deviceInfo = deviceInfo;
}
@Override
public OCDiscoveryFlags handler(String anchor, String uri, String[] types, int interfaceMask, OCEndpoint endpoints, int resourcePropertiesMask, boolean more) {
Log.d(TAG, "anchor: " + anchor + ", uri: " + uri);
OcfResourceInfo resourceInfo = new OcfResourceInfo(anchor, uri, types, interfaceMask, resourcePropertiesMask);
OCEndpoint ep = endpoints;
while (ep != null) {
String endpointStr = OcUtils.endpointToString(ep);
Log.d(TAG, "\tendpoint: " + endpointStr);
resourceInfo.addEndpoint(endpointStr);
ep = ep.getNext();
}
deviceInfo.addResourceInfo(resourceInfo);
if (!more) {
Log.d(TAG, "----End of discovery response---");
return OCDiscoveryFlags.OC_STOP_DISCOVERY;
}
return OCDiscoveryFlags.OC_CONTINUE_DISCOVERY;
}
}
package org.iotivity.multideviceclient;
import android.util.Log;
import org.iotivity.OCDiscoveryFlags;
import org.iotivity.OCDiscoveryHandler;
import org.iotivity.OCEndpoint;
import org.iotivity.oc.OcUtils;
public class ResourceDiscoveryHandler implements OCDiscoveryHandler {
private static final String TAG = ResourceDiscoveryHandler.class.getSimpleName();
private OcfDeviceInfo deviceInfo;
public ResourceDiscoveryHandler(OcfDeviceInfo deviceInfo) {
this.deviceInfo = deviceInfo;
}
@Override
public OCDiscoveryFlags handler(String anchor, String uri, String[] types, int interfaceMask, OCEndpoint endpoints, int resourcePropertiesMask) {
Log.d(TAG, "anchor: " + anchor + ", uri: " + uri);
OcfResourceInfo resourceInfo = new OcfResourceInfo(anchor, uri, types, interfaceMask, resourcePropertiesMask);
OCEndpoint ep = endpoints;
while (ep != null) {
String endpointStr = OcUtils.endpointToString(ep);
Log.d(TAG, "\tendpoint: " + endpointStr);
resourceInfo.addEndpoint(endpointStr);
ep = ep.getNext();
}
deviceInfo.addResourceInfo(resourceInfo);
return OCDiscoveryFlags.OC_CONTINUE_DISCOVERY;
}
}
package org.iotivity.oc;
public interface OcDeviceDiscoveryHandler {
public void discoveredDevice(OcRemoteDevice remoteDevice);
}
package org.iotivity.oc;
import org.iotivity.*;
public class OcGetRemoteDeviceHandler implements OCResponseHandler {
private static final String N_KEY = "n";
private static final String DI_KEY = "di";
private static final String PIID_KEY = "piid";
private static final String ICV_KEY = "icv";
private static final String DMV_KEY = "dmv";
private OcDeviceDiscoveryHandler deviceDiscoveryHandler;
public OcGetRemoteDeviceHandler(OcDeviceDiscoveryHandler deviceDiscoveryHandler) {
this.deviceDiscoveryHandler = deviceDiscoveryHandler;
}
@Override
public void handler(OCClientResponse response) {
OcRepresentation rep = null;
try {
rep = new OcRepresentation(response.getPayload());
} catch (Exception e) {
System.err.println("Failed to get representation from client response, " + e.getMessage());
return;
}
String n = null;
String di = null;
String piid = null;
String icv = null;
String dmv = null;
while (rep != null) {
try {
if (N_KEY.equals(rep.getKey())) {
n = rep.getString(N_KEY);
}
if (DI_KEY.equals(rep.getKey())) {
di = rep.getString(DI_KEY);
}
if (PIID_KEY.equals(rep.getKey())) {
piid = rep.getString(PIID_KEY);
}
if (ICV_KEY.equals(rep.getKey())) {
icv = rep.getString(ICV_KEY);
}
if (DMV_KEY.equals(rep.getKey())) {
dmv = rep.getString(DMV_KEY);
}
} catch (OcCborException e) {
System.err.println(e.getMessage());
}
rep = rep.getNext();
}
if ((di != null) && (n != null)) {
OcRemoteDevice device = new OcRemoteDevice(OCUuidUtil.stringToUuid(di), n, piid, icv, dmv);
OCEndpoint endpoint = response.getEndpoint();
while (endpoint != null) {
if (OcUtils.endpointToString(endpoint).startsWith("coap://")) {