|
@@ -7,8 +7,10 @@ import android.app.Notification;
|
|
import android.app.NotificationChannel;
|
|
import android.app.NotificationChannel;
|
|
import android.app.NotificationManager;
|
|
import android.app.NotificationManager;
|
|
import android.app.PendingIntent;
|
|
import android.app.PendingIntent;
|
|
|
|
+import android.content.ComponentName;
|
|
import android.content.Context;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.Intent;
|
|
|
|
+import android.content.ServiceConnection;
|
|
import android.os.Binder;
|
|
import android.os.Binder;
|
|
import android.os.Build;
|
|
import android.os.Build;
|
|
import android.os.Handler;
|
|
import android.os.Handler;
|
|
@@ -20,8 +22,12 @@ import android.os.RemoteException;
|
|
import android.support.annotation.Nullable;
|
|
import android.support.annotation.Nullable;
|
|
import android.support.v4.app.NotificationCompat;
|
|
import android.support.v4.app.NotificationCompat;
|
|
import android.util.Log;
|
|
import android.util.Log;
|
|
|
|
+import android.widget.Toast;
|
|
|
|
|
|
|
|
|
|
|
|
+import com.icontrols.service.control.ILightControlService;
|
|
|
|
+import com.icontrols.service.control.ILightControlServiceCallback;
|
|
|
|
+
|
|
import org.iotivity.OCCoreRes;
|
|
import org.iotivity.OCCoreRes;
|
|
import org.iotivity.OCQos;
|
|
import org.iotivity.OCQos;
|
|
import org.iotivity.OCUuid;
|
|
import org.iotivity.OCUuid;
|
|
@@ -40,6 +46,7 @@ import org.iotivity.oc.OcUtils;
|
|
import org.json.JSONArray;
|
|
import org.json.JSONArray;
|
|
import org.json.JSONException;
|
|
import org.json.JSONException;
|
|
import org.json.JSONObject;
|
|
import org.json.JSONObject;
|
|
|
|
+import org.json.JSONTokener;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Arrays;
|
|
@@ -64,6 +71,7 @@ public class BridgeService extends IntentService {
|
|
public static final int MSG_STRING = 2;
|
|
public static final int MSG_STRING = 2;
|
|
public static final int MSG_LINE = 3;
|
|
public static final int MSG_LINE = 3;
|
|
public static final int MSG_DEVICE_DISCOVERED = 4 ;
|
|
public static final int MSG_DEVICE_DISCOVERED = 4 ;
|
|
|
|
+ public static final int MSG_LIGHT_RESULT = 5 ;
|
|
|
|
|
|
// IBridgeService RESULT TYPEs
|
|
// IBridgeService RESULT TYPEs
|
|
public enum ResultType {
|
|
public enum ResultType {
|
|
@@ -101,6 +109,8 @@ public class BridgeService extends IntentService {
|
|
bridgeServer = new BridgeServer(this);
|
|
bridgeServer = new BridgeServer(this);
|
|
|
|
|
|
scheduledTaskInit();
|
|
scheduledTaskInit();
|
|
|
|
+
|
|
|
|
+ bindLightServiceForTest();
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -113,6 +123,8 @@ public class BridgeService extends IntentService {
|
|
Log.d(TAG, "onBind() action = " + intent.getAction());
|
|
Log.d(TAG, "onBind() action = " + intent.getAction());
|
|
if (IBridgeService.class.getName().equals(intent.getAction())) {
|
|
if (IBridgeService.class.getName().equals(intent.getAction())) {
|
|
return rBinder; // return Remote Binder
|
|
return rBinder; // return Remote Binder
|
|
|
|
+ } else if (ILightControlService.class.getName().equals(intent.getAction())) {
|
|
|
|
+ return lightBinder; // return Remote Binder
|
|
}
|
|
}
|
|
return lBinder; // return Local Binder
|
|
return lBinder; // return Local Binder
|
|
}
|
|
}
|
|
@@ -281,6 +293,243 @@ public class BridgeService extends IntentService {
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ private ILightControlService lightControlBinder = null ; // Light Control Service Binder for test
|
|
|
|
+ private void bindLightServiceForTest() {
|
|
|
|
+
|
|
|
|
+ // Light Control Service Remote Bind
|
|
|
|
+ LightControlServiceConnection lightConn = new LightControlServiceConnection();
|
|
|
|
+ Intent lIntent = new Intent();
|
|
|
|
+ lIntent.setClassName("org.iotivity.bridge.homeserver", "org.iotivity.bridge.homeserver.BridgeService");
|
|
|
|
+ lIntent.setAction(ILightControlService.class.getName());
|
|
|
|
+ bindService(lIntent, lightConn, Context.BIND_AUTO_CREATE);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ class LightControlServiceConnection implements ServiceConnection {
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void onServiceConnected(ComponentName name, IBinder service) {
|
|
|
|
+
|
|
|
|
+ Log.d(TAG, "onServiceConnected ComponentName=" + name + ", IBinder=" + service.toString());
|
|
|
|
+ if (service instanceof ILightControlService.Stub) {
|
|
|
|
+
|
|
|
|
+ lightControlBinder = ILightControlService.Stub.asInterface(service);
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ lightControlBinder.registerLightControlServiceCallback(lightCallback);
|
|
|
|
+
|
|
|
|
+ String devices = lightControlBinder.retrieveAllDevices();
|
|
|
|
+ Log.d(TAG, "Light Control retrieveAllDevices() : "+ devices);
|
|
|
|
+ if(devices != null) {
|
|
|
|
+ JSONArray array = new JSONArray(devices);
|
|
|
|
+
|
|
|
|
+ for (int index = 0 ; index < array.length(); index++) {
|
|
|
|
+ JSONObject obj = array.getJSONObject(index);
|
|
|
|
+ Iterator<String> it = obj.keys();
|
|
|
|
+ String n = null, sn = null, rt = null, state = null ;
|
|
|
|
+
|
|
|
|
+ while (it.hasNext()) {
|
|
|
|
+ String key = it.next();
|
|
|
|
+ Object value = obj.get(key);
|
|
|
|
+ if (key.equals("n") && value instanceof String) {
|
|
|
|
+ n = (String)value;
|
|
|
|
+ Log.d(TAG, "Light Control : n = " + n);
|
|
|
|
+ } else if (key.equals("sn") && value instanceof String) {
|
|
|
|
+ sn = (String)value;
|
|
|
|
+ Log.d(TAG, "Light Control : sn = " + sn);
|
|
|
|
+ } else if (key.equals("rt") && value instanceof JSONArray) {
|
|
|
|
+ rt = ((JSONArray)value).toString();
|
|
|
|
+ Log.d(TAG, "Light Control : rt = " + rt);
|
|
|
|
+ } else if (key.equals("state") && value instanceof String) {
|
|
|
|
+ state = (String)value;
|
|
|
|
+ Log.d(TAG, "Light Control : state = " + state);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String resources = lightControlBinder.retrieveAllResources(sn);
|
|
|
|
+ Log.d(TAG, "Light Control retrieveAllResources() : " + resources);
|
|
|
|
+ if(resources!=null) {
|
|
|
|
+ JSONArray aArr = new JSONArray(resources);
|
|
|
|
+ for (int loop = 0 ; loop < aArr.length(); loop++) {
|
|
|
|
+ JSONObject ob = aArr.getJSONObject(loop);
|
|
|
|
+ Iterator<String> keys = ob.keys();
|
|
|
|
+ String rName = null, rUri = null, rRT = null, rIF = null ;
|
|
|
|
+
|
|
|
|
+ while (keys.hasNext()) {
|
|
|
|
+ String rKey = keys.next();
|
|
|
|
+ Object rValue = ob.get(rKey);
|
|
|
|
+ if (rKey.equals("n") && rValue instanceof String) {
|
|
|
|
+ rName = (String)rValue;
|
|
|
|
+ Log.d(TAG, "Light Resource : n = " + rName);
|
|
|
|
+ } else if (rKey.equals("uri") && rValue instanceof String) {
|
|
|
|
+ rUri = (String)rValue;
|
|
|
|
+ Log.d(TAG, "Light Resource : uri = " + rUri);
|
|
|
|
+ } else if (rKey.equals("rt") && rValue instanceof JSONArray) {
|
|
|
|
+ rRT = ((JSONArray)rValue).toString();
|
|
|
|
+ Log.d(TAG, "Light Resource : rt = " + rRT);
|
|
|
|
+ } else if (rKey.equals("if") && rValue instanceof String) {
|
|
|
|
+ rIF = (String)rValue;
|
|
|
|
+ Log.d(TAG, "Light Resource : if = " + rIF);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ //Log.d(TAG, "Light Control doGetResourceProperties() : "+lightControlBinder.doGetResourceProperties("2b32e152-3756-4fb6-b3f2-d8db7aafe39f", "/light"));
|
|
|
|
+ //Log.d(TAG, "Light Control doGetResourceProperties() : "+lightControlBinder.doGetResourceProperties("2b32e152-3756-4fb6-b3f2-d8db7aafe39f", "/dimming"));
|
|
|
|
+ //Log.d(TAG, "Light Control doPostResourceProperties() : "+lightControlBinder.doPostResourceProperties("2b32e152-3756-4fb6-b3f2-d8db7aafe39f", "/light", null));
|
|
|
|
+ //Log.d(TAG, "Light Control doPostResourceProperties() : "+lightControlBinder.doPostResourceProperties("2b32e152-3756-4fb6-b3f2-d8db7aafe39f", "/dimming", null));
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ } catch (RemoteException | JSONException ex) {
|
|
|
|
+ Log.e(TAG, "Register Callback", ex);
|
|
|
|
+ // In this case the service has crashed before we could even
|
|
|
|
+ // do anything with it; we can count on soon being
|
|
|
|
+ // disconnected (and then reconnected if it can be restarted)
|
|
|
|
+ // so there is no need to do anything here.
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ msg( "Light Control Remote Service Connected");
|
|
|
|
+ printLine();
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void onServiceDisconnected(ComponentName name) {
|
|
|
|
+
|
|
|
|
+ //lightControlBinder.unregisterLightControlServiceCallback(lightCallback);
|
|
|
|
+ lightControlBinder = null;
|
|
|
|
+ msg("Light Control Remote Service Disconnected");
|
|
|
|
+ printLine();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private ILightControlServiceCallback lightCallback = new ILightControlServiceCallback.Stub() {
|
|
|
|
+ /**
|
|
|
|
+ * This is called by the light control remote service regularly to tell us about
|
|
|
|
+ * new values. Note that IPC calls are dispatched through a thread
|
|
|
|
+ * pool running in each process, so the code executing here will
|
|
|
|
+ * NOT be running in our main thread like most other things -- so,
|
|
|
|
+ * to update the UI, we need to use a Handler to hop over there.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void onResultReceived(int result_code, String result_data) throws RemoteException {
|
|
|
|
+ msg("result_code="+result_code + ", result_data="+result_data );
|
|
|
|
+ printLine();
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * The IBridgeService is defined through IDL
|
|
|
|
+ */
|
|
|
|
+ private final ILightControlServiceImpl lightBinder = new ILightControlServiceImpl() ;
|
|
|
|
+ class ILightControlServiceImpl extends ILightControlService.Stub {
|
|
|
|
+
|
|
|
|
+ final RemoteCallbackList<ILightControlServiceCallback> callbacks
|
|
|
|
+ = new RemoteCallbackList<ILightControlServiceCallback>();
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void registerLightControlServiceCallback(ILightControlServiceCallback cb) throws RemoteException {
|
|
|
|
+ if (cb != null) callbacks.register(cb);
|
|
|
|
+
|
|
|
|
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_STRING, "Light Control Client Callback was registered."));
|
|
|
|
+ mHandler.sendEmptyMessage(MSG_LINE);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void unregisterLightControlServiceCallback(ILightControlServiceCallback cb) throws RemoteException {
|
|
|
|
+ if (cb != null) callbacks.unregister(cb);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public String retrieveAllDevices() throws RemoteException {
|
|
|
|
+ return "[{\"n\":\"Light Switch\", \"rt\":[\"oic.d.light\"], \"sn\":\"2b32e152-3756-4fb6-b3f2-d8db7aafe39f\", \"state\":\"on-line\"}]";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public String retrieveAllResources(String device_uuid) throws RemoteException {
|
|
|
|
+ if("2b32e152-3756-4fb6-b3f2-d8db7aafe39f".equalsIgnoreCase(device_uuid)) {
|
|
|
|
+ return "[{\"n\":\"Light Switch\", \"uri\":\"/light\", \"rt\":[\"oic.r.switch.binary\"], \"if\":\"RW\"},\n" +
|
|
|
|
+ "{\"n\":\"Dimming Control\",\"uri\":\"/dimming\",\"rt\":[\"oic.r.light.dimming\"], \"if\":\"RW\"},\n" +
|
|
|
|
+ "{\"n\":\"Energy Consumption\", \"uri\":\"/EnergyConsumptionResURI\", \"rt\": [\"oic.r.energy.consumption\"], \"if\":\"S\"},\n" +
|
|
|
|
+ "{\"n\":\"Color Temperature\", \"uri\":\"/ColourTemperatureResURI\", \"rt\": [\"oic.r.colour.colourtemperature\"], \"if\":\"A\"}]";
|
|
|
|
+ }
|
|
|
|
+ return null ;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public String doGetResourceProperties(String device_uuid, String resource_uri) throws RemoteException {
|
|
|
|
+ if("2b32e152-3756-4fb6-b3f2-d8db7aafe39f".equalsIgnoreCase(device_uuid)) {
|
|
|
|
+ if("/light".equalsIgnoreCase(resource_uri)) {
|
|
|
|
+ return "{\"n\":\"Light Switch\", \"value\":true}" ;
|
|
|
|
+ } else if("/dimming".equalsIgnoreCase(resource_uri)) {
|
|
|
|
+ return "{\"n\":\"Dimming Control\",\"dimmingSetting\":100,\"range\":100,\"step\":10}";
|
|
|
|
+ } else if("/EnergyConsumptionResURI".equalsIgnoreCase(resource_uri)) {
|
|
|
|
+ return "{\"n\":\"Energy Consumption\",\"power\":200.1,\"energy\":3500.4}" ;
|
|
|
|
+ } else if("/ColourTemperatureResURI".equalsIgnoreCase(resource_uri)) {
|
|
|
|
+ return "{\"n\":\"Color Temperature\", \"ct\":457, \"range\":1000, \"step\":1}" ;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public boolean doPostResourceProperties(String device_uuid, String resource_uri, String prop_data) throws RemoteException {
|
|
|
|
+ if("2b32e152-3756-4fb6-b3f2-d8db7aafe39f".equalsIgnoreCase(device_uuid)) {
|
|
|
|
+ if("/light".equalsIgnoreCase(resource_uri)) {
|
|
|
|
+ String res_data = makeResultData(device_uuid, resource_uri, "{\"n\":\"Light Switch\", \"value\":true}");
|
|
|
|
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_LIGHT_RESULT, ResultType.OK.ordinal(), 0, res_data));
|
|
|
|
+ return true ;
|
|
|
|
+ } else if("/dimming".equalsIgnoreCase(resource_uri)) {
|
|
|
|
+ String res_data = makeResultData(device_uuid, resource_uri, "{\"n\":\"Dimming Control\",\"dimmingSetting\":100,\"range\":100,\"step\":10}");
|
|
|
|
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_LIGHT_RESULT, ResultType.OK.ordinal(), 0, res_data));
|
|
|
|
+ return true ;
|
|
|
|
+ } else if("/EnergyConsumptionResURI".equalsIgnoreCase(resource_uri)) {
|
|
|
|
+ String res_data = makeResultData(device_uuid, resource_uri, "{\"n\":\"Energy Consumption\",\"power\":200.1,\"energy\":3500.4}") ;
|
|
|
|
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_LIGHT_RESULT, ResultType.OK.ordinal(), 0, res_data));
|
|
|
|
+ return true ;
|
|
|
|
+ } else if("/ColourTemperatureResURI".equalsIgnoreCase(resource_uri)) {
|
|
|
|
+ String res_data = makeResultData(device_uuid, resource_uri, "{\"n\":\"Color Temperature\", \"ct\":457, \"range\":1000, \"step\":1}") ;
|
|
|
|
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_LIGHT_RESULT, ResultType.OK.ordinal(), 0, res_data));
|
|
|
|
+ return true ;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private String makeResultData(String device_uuid, String uri, String data) {
|
|
|
|
+ String res = "{\"tid\":\""+Utils.generateRandomID()+"\", " +
|
|
|
|
+ "\"sn\":\""+device_uuid+"\", " +
|
|
|
|
+ "\"uri\":\""+uri+"\", " +
|
|
|
|
+ "\"res_type\":\"POST\", " +
|
|
|
|
+ "\"res_data\":"+data+"}";
|
|
|
|
+ return res ;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void killCallbacks() {
|
|
|
|
+ callbacks.kill();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void broadcastResultToClients(int result_code, String result_data) {
|
|
|
|
+ // Broadcast to all clients the new value.
|
|
|
|
+ final int count = callbacks.beginBroadcast();
|
|
|
|
+ Log.i(TAG, "LigthControlServiceClientCallback count=" + count);
|
|
|
|
+ for (int index=0; index<count; index++) {
|
|
|
|
+ try {
|
|
|
|
+ callbacks.getBroadcastItem(index).onResultReceived(result_code, result_data);
|
|
|
|
+ } catch (RemoteException e) {
|
|
|
|
+ // The RemoteCallbackList will take care of removing
|
|
|
|
+ // the dead object for us.
|
|
|
|
+ Log.e(TAG, "onReceiveResult() RemoteException :", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ callbacks.finishBroadcast();
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+
|
|
public void msg(String msg) {
|
|
public void msg(String msg) {
|
|
mHandler.sendMessage(mHandler.obtainMessage(MSG_STRING, msg));
|
|
mHandler.sendMessage(mHandler.obtainMessage(MSG_STRING, msg));
|
|
}
|
|
}
|
|
@@ -309,6 +558,9 @@ public class BridgeService extends IntentService {
|
|
case MSG_RESULT: {
|
|
case MSG_RESULT: {
|
|
rBinder.broadcastResultToClients(msg.arg1, (String)msg.obj);
|
|
rBinder.broadcastResultToClients(msg.arg1, (String)msg.obj);
|
|
} break ;
|
|
} break ;
|
|
|
|
+ case MSG_LIGHT_RESULT: {
|
|
|
|
+ lightBinder.broadcastResultToClients(msg.arg1, (String)msg.obj);
|
|
|
|
+ } break ;
|
|
default:
|
|
default:
|
|
super.handleMessage(msg);
|
|
super.handleMessage(msg);
|
|
}
|
|
}
|
|
@@ -483,6 +735,7 @@ public class BridgeService extends IntentService {
|
|
}
|
|
}
|
|
|
|
|
|
public String getAllDiscoveredDevices() {
|
|
public String getAllDiscoveredDevices() {
|
|
|
|
+
|
|
if(bridgeServer!=null) {
|
|
if(bridgeServer!=null) {
|
|
ArrayList<OcRemoteDevice> devices = bridgeServer.getPairwisedDevices();
|
|
ArrayList<OcRemoteDevice> devices = bridgeServer.getPairwisedDevices();
|
|
try {
|
|
try {
|