replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / android / android_api / base / src / main / java / org / iotivity / ca / CaLeClientInterface.java
index 695359b..fc1db0d 100644 (file)
@@ -38,25 +38,47 @@ import android.content.Intent;
 import android.content.IntentFilter;
 import android.util.Log;
 
+// For using bluetooth.le APIs
+import android.bluetooth.le.BluetoothLeScanner;
+import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
+import android.os.ParcelUuid;
+import java.util.Iterator;
+import android.os.Build;
+
 public class CaLeClientInterface {
 
     private static String SERVICE_UUID = "ADE3D529-C784-4F63-A987-EB69F70EE816";
     private static String TAG          = "OIC_LE_CB_INTERFACE";
     private static Context mContext;
+    private static volatile boolean isLeClientInitialized = false;
+
+    //For custom uuid ble server
+    final static String CUSTOM_UUID   = "75004209-0000-0000-0000-000000000000";
+    final static String CUSTOM_UUID2  = "75004204-0000-0000-0000-000000000000";
+    final static int custom_uuid_len1 = 9;
+    final static int custom_uuid_strlen1 = 4;
 
     private CaLeClientInterface(Context context) {
-        caLeRegisterLeScanCallback(mLeScanCallback);
+        getLeScanCallback();
         caLeRegisterGattCallback(mGattCallback);
         synchronized(CaLeClientInterface.class) {
             mContext = context;
         }
-        registerIntentFilter();
+        if (!isLeClientInitialized) {
+            registerIntentFilter();
+            isLeClientInitialized = true;
+        }
     }
 
-
-
     public static void getLeScanCallback() {
-        caLeRegisterLeScanCallback(mLeScanCallback);
+//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+//            caLeRegisterLeScanCallbackForV21(mLeScanCallbackForV21);
+//        } else {
+            caLeRegisterLeScanCallback(mLeScanCallback);
+//        }
     }
 
     public static void getLeGattCallback() {
@@ -72,16 +94,36 @@ public class CaLeClientInterface {
     }
 
     public static void destroyLeInterface() {
-        mContext.unregisterReceiver(mReceiver);
+        if (isLeClientInitialized) {
+            mContext.unregisterReceiver(mReceiver);
+            isLeClientInitialized = false;
+        }
+    }
+
+    public static BluetoothGatt connectGattforHidden(BluetoothDevice device,
+            String address, boolean autoConnect) {
+        if (isLeClientInitialized) {
+            BluetoothAdapter mbluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+            BluetoothDevice mDevice = mbluetoothAdapter.getRemoteDevice(address);
+            Log.d(TAG, "connectGattforHidden method : getAddress : " + mDevice.getAddress() 
+                    + ", autoconnect : " + autoConnect);
+            return mDevice.connectGatt(mContext, autoConnect, mGattCallback);
+        }
+        return null;
     }
 
     private native static void caLeRegisterLeScanCallback(BluetoothAdapter.LeScanCallback callback);
 
+    private native static void caLeRegisterLeScanCallbackForV21(ScanCallback callback);
+
     private native static void caLeRegisterGattCallback(BluetoothGattCallback callback);
 
     // BluetoothAdapter.LeScanCallback
     private native static void caLeScanCallback(BluetoothDevice device);
 
+    // scan failed callback for ca layer
+    private native static void caLeScanFailedCallback(int errorCode);
+
     // BluetoothGattCallback
     private native static void caLeGattConnectionStateChangeCallback(
             BluetoothGatt gatt, int status, int newState);
@@ -132,36 +174,70 @@ public class CaLeClientInterface {
     private native static void caManagerLeRemoteRssiCallback(BluetoothGatt gatt, int rssi,
                                                              int status);
 
-    // Callback
+    private native static void caLeGattMtuChangedCallback(BluetoothGatt gatt, int mtu,
+                                                          int status);
+
+    // Le Scan Callback which lower than API 21
     private static BluetoothAdapter.LeScanCallback mLeScanCallback =
                    new BluetoothAdapter.LeScanCallback() {
 
         @Override
         public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
+            filteringScanResult(device, scanRecord);
+        }
+    };
 
-            try {
-                List<UUID> uuids = getUuids(scanRecord);
-                for (UUID uuid : uuids) {
-                    Log.d(TAG, "UUID : " + uuid.toString());
-                    if(uuid.toString().contains(SERVICE_UUID.toLowerCase())) {
-                        Log.d(TAG, "we found that has the Device");
-                        Log.d(TAG, "scanned device address : " + device.getAddress());
-                        caLeScanCallback(device);
-                    }
-                }
-            } catch(UnsatisfiedLinkError e) {
+    // Le Scan Callback which upper than API 21
+    private static ScanCallback mLeScanCallbackForV21 = new ScanCallback() {
+        @Override
+        public void onScanResult(int callbackType, ScanResult result) {
+            super.onScanResult(callbackType, result);
+            Log.d(TAG, "onScanResult from ScanCallback");
+            filteringScanResult(result.getDevice(), result.getScanRecord().getBytes());
+        }
 
+        @Override
+        public void onBatchScanResults(List<ScanResult> results) {
+            super.onBatchScanResults(results);
+            Iterator<ScanResult> itr = results.iterator();
+            while (itr.hasNext()) {
+                filteringScanResult(itr.next().getDevice(),
+                        itr.next().getScanRecord().getBytes());
             }
         }
+
+        @Override
+        public void onScanFailed(int errorCode) {
+            super.onScanFailed(errorCode);
+            caLeScanFailedCallback(errorCode);
+        }
     };
 
+    private static void filteringScanResult(BluetoothDevice device, byte[] scanRecord) {
+        try {
+            List<UUID> uuids = getUuids(scanRecord);
+            for (UUID uuid : uuids) {
+                if(uuid.toString().contains(SERVICE_UUID.toLowerCase())) {
+                    caLeScanCallback(device);
+                } else if(uuid.toString().contains(CUSTOM_UUID.toLowerCase()) ||
+                         uuid.toString().contains(CUSTOM_UUID2.toLowerCase())) {
+                    Log.d(TAG, "we found that has the Device [" + device.getAddress() +
+                               "] which has custom adv");
+                    caLeScanCallback(device);
+                }
+            }
+        } catch(UnsatisfiedLinkError e) {
+            e.printStackTrace();
+        }
+    }
+
     private static List<UUID> getUuids(final byte[] scanRecord) {
         List<UUID> uuids = new ArrayList<UUID>();
 
         int offset = 0;
         while (offset < (scanRecord.length - 2)) {
             int len = scanRecord[offset++];
-            if (len == 0)
+            if (len <= 0)
                 break;
 
             int type = scanRecord[offset++];
@@ -196,7 +272,28 @@ public class CaLeClientInterface {
                 }
                 break;
             default:
-                offset += (len - 1);
+                if (len >= custom_uuid_len1) {
+                    StringBuffer strbuf1 = new StringBuffer();
+                    int strcnt = 0;
+                    int backlen = len;
+                    while (backlen > 1) {
+                        String str = String.format("%02x", scanRecord[offset++]);
+                        backlen -= 1;
+                        if (strcnt < custom_uuid_strlen1) {
+                            strbuf1.append(str);
+                        }
+                        else {
+                            break;
+                        }
+                        strcnt++;
+                    }
+                    offset += (backlen - 1);
+                    uuids.add(UUID.fromString(String.format(
+                            "%4s-0000-0000-0000-000000000000",
+                            strbuf1.toString())));
+                } else {
+                    offset += (len - 1);
+                }
                 break;
             }
         }
@@ -270,6 +367,12 @@ public class CaLeClientInterface {
             super.onReadRemoteRssi(gatt, rssi, status);
             caManagerLeRemoteRssiCallback(gatt, rssi, status);
         }
+
+        @Override
+        public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
+            super.onMtuChanged(gatt, mtu, status);
+            caLeGattMtuChangedCallback(gatt, mtu, status);
+        }
     };
 
     private static final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -312,4 +415,3 @@ public class CaLeClientInterface {
     };
 }
 
-