Implementation of Filtered Scan for BLE android client
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / android / caleclient.c
index 9977465..83ed0ae 100644 (file)
 #define GATT_WRITE_NOT_PERMITTED            3
 
 // samsung
-#define BLE_SCAN_API_LEVEL (100) //(21)
+#define BLE_SCAN_API_LEVEL (21) //(21)
 #define BLE_MIN_API_LEVEL  (18)
 #define HIDDEN_API
+#define MANUFACTURE_ID 117
 
 static ca_thread_pool_t g_threadPoolHandle = NULL;
 
@@ -118,7 +119,7 @@ static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
 static int32_t g_jniIntSdk = -1;
 
 static bool g_setHighQoS = true;
-static bool g_setFullScanFlag = true;
+static bool g_setFullScanFlag = false;
 jclass g_LEInterface = NULL;
 /**
  * check if retry logic for connection routine has to be stopped or not.
@@ -1431,6 +1432,10 @@ CAResult_t CALEClientStartScan()
         return CA_STATUS_FAILED;
     }
 
+    if(g_jniIntSdk < BLE_SCAN_API_LEVEL)
+    {
+        g_setFullScanFlag = true;
+    }
     bool isAttached = false;
     JNIEnv* env = NULL;
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
@@ -1456,11 +1461,13 @@ CAResult_t CALEClientStartScan()
             if (!g_setFullScanFlag)
             {
                 //new uuid scan with callback
+                OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImplForV21 will be called");
                 ret = CALEClientStartScanWithUUIDImplForV21(env, g_uuidList, g_leScanCallback);
             }
             else
             {
                 //new full scan with callback
+                OIC_LOG(DEBUG, TAG, "CALEClientStartScanImplForV21 will be called");
                 ret = CALEClientStartScanImplForV21(env, g_leScanCallback);
             }
         }
@@ -1468,10 +1475,12 @@ CAResult_t CALEClientStartScan()
         {
             if (!g_setFullScanFlag)
             {
+                OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImpl will be called");
                 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
             }
             else
             {
+                OIC_LOG(DEBUG, TAG, "CALEClientStartScanImpl will be called");
                 ret = CALEClientStartScanImpl(env, g_leScanCallback);
             }
         }
@@ -1822,6 +1831,45 @@ CAResult_t CALEClientStartScanWithUUIDImplForV21(JNIEnv *env, jobjectArray uuids
         return CA_STATUS_FAILED;
     }
 
+    // call scanfilter.Builder()
+    jobject jni_obj_scanfilterBuilder2 = (*env)->NewObject(env, jni_cid_scanfilterBuilder,
+                                                          jni_mid_scanfilterBuilderCtor);
+    if (!jni_obj_scanfilterBuilder2)
+    {
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilterBuilder2 is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+        return CA_STATUS_FAILED;
+    }
+
+    // call scanfilter.Builder()
+    jobject jni_obj_scanfilterBuilder3 = (*env)->NewObject(env, jni_cid_scanfilterBuilder,
+                                                          jni_mid_scanfilterBuilderCtor);
+    if (!jni_obj_scanfilterBuilder3)
+    {
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilterBuilder3 is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
+        return CA_STATUS_FAILED;
+    }
+
+    // call scanfilter.Builder()
+    jobject jni_obj_scanfilterBuilder4 = (*env)->NewObject(env, jni_cid_scanfilterBuilder,
+                                                          jni_mid_scanfilterBuilderCtor);
+    if (!jni_obj_scanfilterBuilder4)
+    {
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilterBuilder4 is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
+        return CA_STATUS_FAILED;
+    }
+
     // get scanfilter.Builder.setServiceUuid method id
     jmethodID jni_mid_setServiceUuid = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
                                                            "setServiceUuid",
@@ -1833,9 +1881,28 @@ CAResult_t CALEClientStartScanWithUUIDImplForV21(JNIEnv *env, jobjectArray uuids
         CACheckJNIException(env);
         (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
         (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
         return CA_STATUS_FAILED;
     }
 
+    // get scanfilter.Builder.setManufacturerData method id
+    jmethodID jni_mid_setManufacturerData = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
+                                                           "setManufacturerData",
+                                                           "(I[B)Landroid/"
+                                                           "bluetooth/le/ScanFilter$Builder;");
+    if (!jni_mid_setManufacturerData)
+    {
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_setManufacturerData is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
+        return CA_STATUS_FAILED;
+    }
     // get scanfilter.Builder.build method id
     jmethodID jni_mid_build_scanfilterBuilder = (*env)->GetMethodID(env,
                                                                     jni_cid_scanfilterBuilder,
@@ -1848,6 +1915,9 @@ CAResult_t CALEClientStartScanWithUUIDImplForV21(JNIEnv *env, jobjectArray uuids
         CACheckJNIException(env);
         (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
         (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
         return CA_STATUS_FAILED;
     }
     (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
@@ -1859,6 +1929,9 @@ CAResult_t CALEClientStartScanWithUUIDImplForV21(JNIEnv *env, jobjectArray uuids
         OIC_LOG(ERROR, TAG, "scanSettings: jni_obj_parcelUuid is null");
         CACheckJNIException(env);
         (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
         return CA_STATUS_FAILED;
     }
 
@@ -1872,6 +1945,9 @@ CAResult_t CALEClientStartScanWithUUIDImplForV21(JNIEnv *env, jobjectArray uuids
         OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setServiceUuid is null");
         CACheckJNIException(env);
         (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
         (*env)->DeleteLocalRef(env, jni_obj_parcelUuid);
         return CA_STATUS_FAILED;
     }
@@ -1887,10 +1963,152 @@ CAResult_t CALEClientStartScanWithUUIDImplForV21(JNIEnv *env, jobjectArray uuids
         OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilter is null");
         CACheckJNIException(env);
         (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
         return CA_STATUS_FAILED;
     }
     (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
 
+    OIC_LOG(DEBUG, TAG, "Service UUID scanfilter set");
+
+    jint jni_int_manId;
+    jbyteArray jni_byte_manData;
+    // set manufactererId
+    jni_int_manId = MANUFACTURE_ID;
+
+    // call utility function to set manufacturerData
+    jni_byte_manData = CALEGetManufacturerData(env, OIC_GATT_CUSTOM_UUID);
+    if(!jni_byte_manData)
+    {
+        OIC_LOG(ERROR, TAG, "scanSettings: jni_byte_manData is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
+        return CA_STATUS_FAILED;
+    }
+
+    // call set(uuid)
+    jobject jni_obj_setManufacturerData = (*env)->CallObjectMethod(env,
+                                                              jni_obj_scanfilterBuilder2,
+                                                              jni_mid_setManufacturerData,
+                                                              jni_int_manId,
+                                                              jni_byte_manData);
+    if (!jni_obj_setManufacturerData)
+    {
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setManufacturerData is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
+        return CA_STATUS_FAILED;
+    }
+    (*env)->DeleteLocalRef(env, jni_byte_manData);
+    (*env)->DeleteLocalRef(env, jni_obj_setManufacturerData);
+
+    // call build()
+    jobject jni_obj_scanfilter2 = (*env)->CallObjectMethod(env,
+                                                          jni_obj_scanfilterBuilder2,
+                                                          jni_mid_build_scanfilterBuilder);
+    if (!jni_obj_scanfilter2)
+    {
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilter2 is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
+        return CA_STATUS_FAILED;
+    }
+    (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder2);
+
+    OIC_LOG(DEBUG, TAG, "First custom UUID scanfilter set");
+
+    // call utility function to set manufacturerData
+    jni_byte_manData = CALEGetManufacturerData(env, OIC_GATT_CUSTOM_UUID2);
+    if(!jni_byte_manData)
+    {
+        OIC_LOG(ERROR, TAG, "scanSettings: jni_byte_manData is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
+        return CA_STATUS_FAILED;
+    }
+
+    // call set(uuid)
+    jni_obj_setManufacturerData = (*env)->CallObjectMethod(env,
+                                                              jni_obj_scanfilterBuilder3,
+                                                              jni_mid_setManufacturerData,
+                                                              jni_int_manId,
+                                                              jni_byte_manData);
+
+    if (!jni_obj_setManufacturerData)
+    {
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setManufacturerData is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
+        return CA_STATUS_FAILED;
+    }
+    (*env)->DeleteLocalRef(env, jni_byte_manData);
+    (*env)->DeleteLocalRef(env, jni_obj_setManufacturerData);
+
+    // call build()
+    jobject jni_obj_scanfilter3 = (*env)->CallObjectMethod(env,
+                                                          jni_obj_scanfilterBuilder3,
+                                                          jni_mid_build_scanfilterBuilder);
+    if (!jni_obj_scanfilter3)
+    {
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilter3 is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
+        return CA_STATUS_FAILED;
+    }
+    (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder3);
+    OIC_LOG(DEBUG, TAG, "Second custom UUID scanfilter set");
+
+    // call utility function to set manufacturerData
+    jni_byte_manData = CALEGetManufacturerData(env, OIC_GATT_CUSTOM_UUID3);
+    if(!jni_byte_manData)
+    {
+        OIC_LOG(ERROR, TAG, "scanSettings: jni_byte_manData is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
+        return CA_STATUS_FAILED;
+    }
+
+    // call set(uuid)
+    jni_obj_setManufacturerData = (*env)->CallObjectMethod(env,
+                                                               jni_obj_scanfilterBuilder4,
+                                                               jni_mid_setManufacturerData,
+                                                               jni_int_manId,
+                                                               jni_byte_manData);
+
+    if (!jni_obj_setManufacturerData)
+    {
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setManufacturerData is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
+        return CA_STATUS_FAILED;
+    }
+    (*env)->DeleteLocalRef(env, jni_byte_manData);
+    (*env)->DeleteLocalRef(env, jni_obj_setManufacturerData);
+
+    // call build()
+    jobject jni_obj_scanfilter4 = (*env)->CallObjectMethod(env,
+                                                           jni_obj_scanfilterBuilder4,
+                                                           jni_mid_build_scanfilterBuilder);
+    if (!jni_obj_scanfilter4)
+    {
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilter4 is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
+        return CA_STATUS_FAILED;
+    }
+    (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder4);
+    OIC_LOG(DEBUG, TAG, "Third custom UUID scanfilter set");
+
     // get scanSettings.Builder class id
     jclass jni_cid_scanSettingsBuilder = (*env)->FindClass(env,
                                                           "android/bluetooth/le/"
@@ -2014,6 +2232,46 @@ CAResult_t CALEClientStartScanWithUUIDImplForV21(JNIEnv *env, jobjectArray uuids
     }
     (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
 
+    jni_bool_arrayListIsAdded = (*env)->CallBooleanMethod(env, jni_obj_filterList,
+                                                                   jni_mid_arrayListAdd,
+                                                                   jni_obj_scanfilter2);
+    if (!jni_bool_arrayListIsAdded)
+    {
+        OIC_LOG(ERROR, TAG, "ArrayList: jni_bool_arrayListIsAdded is null");
+        (*env)->DeleteLocalRef(env, jni_obj_filterList);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilter2);
+        (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
+        return CA_STATUS_FAILED;
+    }
+    (*env)->DeleteLocalRef(env, jni_obj_scanfilter2);
+
+    jni_bool_arrayListIsAdded = (*env)->CallBooleanMethod(env, jni_obj_filterList,
+                                                                   jni_mid_arrayListAdd,
+                                                                   jni_obj_scanfilter3);
+    if (!jni_bool_arrayListIsAdded)
+    {
+        OIC_LOG(ERROR, TAG, "ArrayList: jni_bool_arrayListIsAdded is null");
+        (*env)->DeleteLocalRef(env, jni_obj_filterList);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilter3);
+        (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
+        return CA_STATUS_FAILED;
+    }
+    (*env)->DeleteLocalRef(env, jni_obj_scanfilter3);
+
+    jni_bool_arrayListIsAdded = (*env)->CallBooleanMethod(env, jni_obj_filterList,
+                                                                   jni_mid_arrayListAdd,
+                                                                   jni_obj_scanfilter4);
+    if (!jni_bool_arrayListIsAdded)
+    {
+        OIC_LOG(ERROR, TAG, "ArrayList: jni_bool_arrayListIsAdded is null");
+        (*env)->DeleteLocalRef(env, jni_obj_filterList);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilter4);
+        (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
+        return CA_STATUS_FAILED;
+    }
+    (*env)->DeleteLocalRef(env, jni_obj_scanfilter4);
+
+    OIC_LOG(INFO, TAG, "ScanFilters Added");
     // get ScanSettings.SCAN_MODE_BALANCED jint value
     jint jni_int_scanBalancedMode = CALEGetConstantsValue(env, CLASSPATH_LE_SCANSETTINGS,
                                                           "SCAN_MODE_BALANCED");
@@ -2045,6 +2303,7 @@ CAResult_t CALEClientStartScanWithUUIDImplForV21(JNIEnv *env, jobjectArray uuids
     (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
 
     CAResult_t res = CA_STATUS_FAILED;
+
     // get default bt adapter class
     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
     if (!jni_cid_BTAdapter)