replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / android / android_api / base / src / main / java / org / iotivity / ca / CaLeClientInterface.java
index 42165f2..fc1db0d 100644 (file)
@@ -38,66 +38,117 @@ 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 = "713d0000-503e-4c75-ba94-3148f18d941e";
+    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;
 
-    private CaLeClientInterface(Context context) {
+    //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;
 
-        caLeRegisterLeScanCallback(mLeScanCallback);
+    private CaLeClientInterface(Context context) {
+        getLeScanCallback();
         caLeRegisterGattCallback(mGattCallback);
-
-        registerIntentFilter(context);
+        synchronized(CaLeClientInterface.class) {
+            mContext = context;
+        }
+        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() {
         caLeRegisterGattCallback(mGattCallback);
     }
 
-    private static IntentFilter registerIntentFilter(Context context) {
+    private static IntentFilter registerIntentFilter() {
         IntentFilter filter = new IntentFilter();
         filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
         filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
-        context.registerReceiver(mReceiver, filter);
+        mContext.registerReceiver(mReceiver, filter);
         return filter;
     }
 
+    public static void destroyLeInterface() {
+        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,
-                                                int rssi, byte[] scanRecord);
+    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);
 
+    // BluetoothGattCallback for Connection Manager
+    private native static void caManagerLeGattConnectionStateChangeCB(
+            BluetoothGatt gatt, int status, int newState);
+
+    private native static void caLeGattNWConnectionStateChangeCallback(
+            BluetoothGatt gatt, int status, int newState);
+
     private native static void caLeGattServicesDiscoveredCallback(BluetoothGatt gatt, int status);
 
-    private native static void caLeGattCharacteristicReadCallback(
-            BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
-            byte[] data, int status);
+    private native static void caLeGattNWServicesDiscoveredCallback(BluetoothGatt gatt,
+                                                                    int status);
+
+    private native static void caLeGattNWDescriptorWriteCallback(BluetoothGatt gatt, int status);
 
     private native static void caLeGattCharacteristicWriteCallback(
-            BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
-            byte[] data, int status);
+            BluetoothGatt gatt, byte[] data, int status);
 
     private native static void caLeGattCharacteristicChangedCallback(
-            BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] data);
+            BluetoothGatt gatt, byte[] data);
 
-    private native static void caLeGattDescriptorReadCallback(BluetoothGatt gatt,
-                                                             BluetoothGattDescriptor descriptor,
-                                                             int status);
-
-    private native static void caLeGattDescriptorWriteCallback(BluetoothGatt gatt,
-                                                              BluetoothGattDescriptor descriptor,
-                                                              int status);
+    private native static void caLeGattDescriptorWriteCallback(BluetoothGatt gatt, int status);
 
     private native static void caLeGattReliableWriteCompletedCallback(BluetoothGatt gatt,
                                                                      int status);
@@ -111,35 +162,82 @@ public class CaLeClientInterface {
     // bond state
     private native static void caLeBondStateChangedCallback(String address);
 
-    // Callback
+    // adapter state
+    private native static void caManagerAdapterStateChangedCallback(int state);
+
+    // bond state
+    private native static void caManagerBondStateChangedCallback(BluetoothDevice address);
+
+    private native static void caManagerLeServicesDiscoveredCallback(BluetoothGatt gatt,
+                                                                     int status);
+
+    private native static void caManagerLeRemoteRssiCallback(BluetoothGatt gatt, int rssi,
+                                                             int status);
+
+    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("CA", "UUID : " + uuid.toString());
-                    if(uuid.toString().contains(SERVICE_UUID)) {
-                        Log.d("CA", "we found that has the Device");
-                        caLeScanCallback(device, rssi, scanRecord);
-                    }
-                }
-            } 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++];
@@ -165,7 +263,7 @@ public class CaLeClientInterface {
                         long leastSigBits = buffer.getLong();
                         uuids.add(new UUID(leastSigBits, mostSigBits));
                     } catch (IndexOutOfBoundsException e) {
-                        Log.e("CA", e.toString());
+                        Log.e(TAG, e.toString());
                         continue;
                     } finally {
                         offset += 15;
@@ -174,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;
             }
         }
@@ -188,6 +307,8 @@ public class CaLeClientInterface {
             super.onConnectionStateChange(gatt, status, newState);
 
             caLeGattConnectionStateChangeCallback(gatt, status, newState);
+            caManagerLeGattConnectionStateChangeCB(gatt, status, newState);
+            caLeGattNWConnectionStateChangeCallback(gatt, status, newState);
         }
 
         @Override
@@ -195,15 +316,14 @@ public class CaLeClientInterface {
             super.onServicesDiscovered(gatt, status);
 
             caLeGattServicesDiscoveredCallback(gatt, status);
+            caManagerLeServicesDiscoveredCallback(gatt, status);
+            caLeGattNWServicesDiscoveredCallback(gatt, status);
         }
 
         @Override
         public void onCharacteristicRead(BluetoothGatt gatt,
                 BluetoothGattCharacteristic characteristic, int status) {
             super.onCharacteristicRead(gatt, characteristic, status);
-
-            caLeGattCharacteristicReadCallback(gatt, characteristic,
-                                               characteristic.getValue(), status);
         }
 
         @Override
@@ -211,8 +331,7 @@ public class CaLeClientInterface {
                 BluetoothGattCharacteristic characteristic, int status) {
             super.onCharacteristicWrite(gatt, characteristic, status);
 
-            caLeGattCharacteristicWriteCallback(gatt, characteristic,
-                                                characteristic.getValue(), status);
+            caLeGattCharacteristicWriteCallback(gatt, characteristic.getValue(), status);
         }
 
         @Override
@@ -220,16 +339,13 @@ public class CaLeClientInterface {
                 BluetoothGattCharacteristic characteristic) {
             super.onCharacteristicChanged(gatt, characteristic);
 
-            caLeGattCharacteristicChangedCallback(gatt, characteristic,
-                                                  characteristic.getValue());
+            caLeGattCharacteristicChangedCallback(gatt, characteristic.getValue());
         }
 
         @Override
         public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
                 int status) {
             super.onDescriptorRead(gatt, descriptor, status);
-
-            caLeGattDescriptorReadCallback(gatt, descriptor, status);
         }
 
         @Override
@@ -237,21 +353,25 @@ public class CaLeClientInterface {
                 int status) {
             super.onDescriptorWrite(gatt, descriptor, status);
 
-            caLeGattDescriptorWriteCallback(gatt, descriptor, status);
+            caLeGattDescriptorWriteCallback(gatt, status);
+            caLeGattNWDescriptorWriteCallback(gatt, status);
         }
 
         @Override
         public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
             super.onReliableWriteCompleted(gatt, status);
-
-            caLeGattReliableWriteCompletedCallback(gatt, status);
         }
 
         @Override
         public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
             super.onReadRemoteRssi(gatt, rssi, status);
+            caManagerLeRemoteRssiCallback(gatt, rssi, status);
+        }
 
-            caLeGattReadRemoteRssiCallback(gatt, rssi, status);
+        @Override
+        public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
+            super.onMtuChanged(gatt, mtu, status);
+            caLeGattMtuChangedCallback(gatt, mtu, status);
         }
     };
 
@@ -267,9 +387,11 @@ public class CaLeClientInterface {
                 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
                                                BluetoothAdapter.ERROR);
 
-                if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_OFF)
+                if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_OFF
+                        || state == BluetoothAdapter.STATE_TURNING_OFF)
                 {
                     caLeStateChangedCallback(state);
+                    caManagerAdapterStateChangedCallback(state);
                 }
             }
 
@@ -284,6 +406,7 @@ public class CaLeClientInterface {
                             BluetoothDevice device = intent
                                 .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
 
+                        caManagerBondStateChangedCallback(device);
                         caLeBondStateChangedCallback(device.getAddress());
                     }
                 }