Adapt the scan filter register functionality into BT-HAL framework 34/215934/4
authorhimanshu <h.himanshu@samsung.com>
Thu, 17 Oct 2019 12:53:51 +0000 (18:23 +0530)
committerhimanshu <h.himanshu@samsung.com>
Thu, 24 Oct 2019 13:34:45 +0000 (19:04 +0530)
This API registers a scan filter to use for scanning.

Change-Id: Icfa4bf8a87fde8668cc8e5c26689a2c3c29cbce7
Signed-off-by: himanshu <h.himanshu@samsung.com>
bt-oal/bluez_hal/src/bt-hal-gatt-client.c
bt-oal/hardware/bluetooth.h
bt-oal/include/oal-gatt.h
bt-oal/oal-gatt.c
bt-service-adaptation/services/adapter/bt-service-core-adapter-le.c
bt-service-adaptation/services/bt-request-handler.c
bt-service-adaptation/services/include/bt-service-core-adapter-le.h

index 632d221..544e4c8 100644 (file)
@@ -2721,8 +2721,43 @@ bt_status_t scan_filter_param_setup(int client_if, int action, int filt_index, i
                int rssi_low_thres, int dely_mode, int found_timeout,
                int lost_timeout, int found_timeout_cnt)
 {
+       GDBusProxy *proxy;
+       GError *error = NULL;
+       GVariant *ret, *param;
        CHECK_BTGATT_INIT();
-       return BT_STATUS_UNSUPPORTED;
+
+       proxy = _bt_hal_get_adapter_proxy();
+
+       if (proxy == NULL)
+               return BT_STATUS_FAIL;
+
+       param = g_variant_new("(iiiiiiiiiiii)",
+                               client_if,
+                               action,
+                               filt_index,
+                               feat_seln,
+                               list_logic_type,
+                               filt_logic_type,
+                               rssi_high_thres,
+                               rssi_low_thres,
+                               dely_mode,
+                               found_timeout,
+                               lost_timeout,
+                               found_timeout_cnt);
+       ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
+                       param, G_DBUS_CALL_FLAGS_NONE,
+                       -1, NULL, &error);
+
+       if (error) {
+               ERR("scan_filter_param_setup Fail: %s", error->message);
+               g_clear_error(&error);
+               return BT_STATUS_FAIL;
+       }
+
+       if (ret)
+               g_variant_unref(ret);
+
+       return BT_STATUS_SUCCESS;
 }
 
 /** Configure a scan filter condition */
@@ -2733,7 +2768,311 @@ bt_status_t scan_filter_add_remove(int client_if, int action, int filt_type,
                char addr_type, int data_len, char* p_data, int mask_len,
                char* p_mask)
 {
+       GDBusProxy *proxy;
+       GError *error = NULL;
+       GVariant *ret, *param;
+       GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
+       GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
+       GArray *arr_uuid = NULL;
+       GArray *arr_uuid_mask = NULL;
+       GArray *arr_data = NULL;
+       GArray *arr_data_mask = NULL;
        CHECK_BTGATT_INIT();
+
+       proxy = _bt_hal_get_adapter_proxy();
+
+       if (proxy == NULL)
+               return BT_STATUS_FAIL;
+
+       if (filt_type == BT_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
+
+               char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
+
+               _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
+
+               INFO("BT_SCAN_FILTER_FEATURE_DEVICE_ADDRESS being added\nRemote Device Address is [%s]", address);
+
+               arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               NULL, 0, TRUE, NULL, NULL);
+               arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               NULL, 0, TRUE, NULL, NULL);
+               arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               NULL, 0, TRUE, NULL, NULL);
+               arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               NULL, 0, TRUE, NULL, NULL);
+
+               param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
+                                       client_if,      // client_if
+                                       action,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
+                                       BT_SCAN_FILTER_FEATURE_DEVICE_ADDRESS,        // filter_type
+                                       filt_index,       // filter_index
+                                       company_id,      // company_id
+                                       company_id_mask,      // company_id_mask
+                                       arr_uuid_param, // p_uuid
+                                       arr_uuid_mask_param,    // p_uuid_mask
+                                       address,        // string
+                                       addr_type,      // address_type
+                                       arr_data_param, // p_data
+                                       arr_data_mask_param);   // p_mask
+
+               ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
+                               param, G_DBUS_CALL_FLAGS_NONE,
+                               -1, NULL, &error);
+
+               if (error) {
+                       ERR("scan_filter_add_remove Fail: %s", error->message);
+                       g_clear_error(&error);
+                       return BT_STATUS_FAIL;
+               }
+
+               if (ret)
+                       g_variant_unref(ret);
+
+               return BT_STATUS_SUCCESS;
+       }
+
+       if (filt_type == BT_SCAN_FILTER_FEATURE_DEVICE_NAME) {
+
+               INFO("BT_SCAN_FILTER_FEATURE_DEVICE_NAME being added\nRemote Device Name is %s", p_data);
+               arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               NULL, 0, TRUE, NULL, NULL);
+               arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               NULL, 0, TRUE, NULL, NULL);
+               arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               NULL, 0, TRUE, NULL, NULL);
+               arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               NULL, 0, TRUE, NULL, NULL);
+
+               param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
+                                       client_if,      // client_if
+                                       action,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
+                                       BT_SCAN_FILTER_FEATURE_DEVICE_NAME,   // filter_type
+                                       filt_index,       // filter_index
+                                       company_id,      // company_id
+                                       company_id_mask,      // company_id_mask
+                                       arr_uuid_param, // p_uuid
+                                       arr_uuid_mask_param,    // p_uuid_mask
+                                       p_data,    // string
+                                       addr_type,      // address_type
+                                       arr_data_param, // p_data
+                                       arr_data_mask_param);
+
+               ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
+                               param, G_DBUS_CALL_FLAGS_NONE,
+                               -1, NULL, &error);
+
+               if (error) {
+                       ERR("scan_filter_add_remove Fail: %s", error->message);
+                       g_clear_error(&error);
+                       return BT_STATUS_FAIL;
+               }
+
+               if (ret)
+                       g_variant_unref(ret);
+
+               return BT_STATUS_SUCCESS;
+       }
+
+       if (filt_type == BT_SCAN_FILTER_FEATURE_SERVICE_UUID) {
+
+               arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
+               arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
+
+               g_array_append_vals(arr_uuid, p_uuid->uu, data_len * sizeof(guint8));
+               g_array_append_vals(arr_uuid_mask, p_uuid_mask->uu, mask_len * sizeof(guint8));
+
+               arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
+               arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
+               arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               NULL, 0, TRUE, NULL, NULL);
+               arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               NULL, 0, TRUE, NULL, NULL);
+
+               param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
+                                       client_if,      // client_if
+                                       action,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
+                                       BT_SCAN_FILTER_FEATURE_SERVICE_UUID,  // filter_type
+                                       filt_index,       // filter_index
+                                       company_id,      // company_id
+                                       company_id_mask,      // company_id_mask
+                                       arr_uuid_param, // p_uuid
+                                       arr_uuid_mask_param,    // p_uuid_mask
+                                       "",   // string
+                                       addr_type,      // address_type
+                                       arr_data_param, // p_data
+                                       arr_data_mask_param);
+
+               ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
+                               param, G_DBUS_CALL_FLAGS_NONE,
+                               -1, NULL, &error);
+
+               if (error) {
+                       ERR("scan_filter_add_remove Fail: %s", error->message);
+                       g_clear_error(&error);
+                       return BT_STATUS_FAIL;
+               }
+
+               if (ret)
+                       g_variant_unref(ret);
+
+               g_array_free(arr_uuid, TRUE);
+               g_array_free(arr_uuid_mask, TRUE);
+
+               return BT_STATUS_SUCCESS;
+       }
+
+       if (filt_type == BT_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
+
+               arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
+               arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
+
+               g_array_append_vals(arr_uuid, p_uuid->uu, data_len * sizeof(guint8));
+               g_array_append_vals(arr_uuid_mask, p_uuid_mask->uu, mask_len * sizeof(guint8));
+
+               arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
+               arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
+               arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               NULL, 0, TRUE, NULL, NULL);
+               arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               NULL, 0, TRUE, NULL, NULL);
+
+               param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
+                                       client_if,      // client_if
+                                       action,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
+                                       BT_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID,     // filter_type
+                                       filt_index,       // filter_index
+                                       company_id,      // company_id
+                                       company_id_mask,      // company_id_mask
+                                       arr_uuid_param, // p_uuid
+                                       arr_uuid_mask_param,    // p_uuid_mask
+                                       "",   // string
+                                       addr_type,      // address_type
+                                       arr_data_param, // p_data
+                                       arr_data_mask_param);
+
+               ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1, NULL, &error);
+
+               if (error) {
+                       ERR("scan_filter_add_remove Fail: %s", error->message);
+                       g_clear_error(&error);
+                       return BT_STATUS_FAIL;
+               }
+
+               if (ret)
+                       g_variant_unref(ret);
+
+               g_array_free(arr_uuid, TRUE);
+               g_array_free(arr_uuid_mask, TRUE);
+
+               return BT_STATUS_SUCCESS;
+       }
+
+       if (filt_type == BT_SCAN_FILTER_FEATURE_SERVICE_DATA) {
+
+               arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
+               arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
+
+               g_array_append_vals(arr_data, p_data, data_len * sizeof(guint8));
+               g_array_append_vals(arr_data_mask, p_mask, mask_len * sizeof(guint8));
+
+               arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               NULL, 0, TRUE, NULL, NULL);
+               arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               NULL, 0, TRUE, NULL, NULL);
+               arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               arr_data->data, arr_data->len, TRUE, NULL, NULL);
+                               arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
+
+               param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
+                                       client_if,      // client_if
+                                       action,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
+                                       BT_SCAN_FILTER_FEATURE_SERVICE_DATA,  // filter_type
+                                       filt_index,       // filter_index
+                                       company_id,      // company_id
+                                       company_id_mask,      // company_id_mask
+                                       arr_uuid_param, // p_uuid
+                                       arr_uuid_mask_param,    // p_uuid_mask
+                                       "",   // string
+                                       addr_type,      // address_type
+                                       arr_data_param, // p_data
+                                       arr_data_mask_param);
+
+               ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1, NULL, &error);
+
+               if (error) {
+                       ERR("scan_filter_add_remove Fail: %s", error->message);
+                       g_clear_error(&error);
+                       return BT_STATUS_FAIL;
+               }
+
+               if (ret)
+                       g_variant_unref(ret);
+
+               g_array_free(arr_data, TRUE);
+               g_array_free(arr_data_mask, TRUE);
+
+               return BT_STATUS_SUCCESS;
+       }
+
+       if (filt_type == BT_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
+
+               arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
+               arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
+
+               g_array_append_vals(arr_data, p_data, data_len * sizeof(guint8));
+               g_array_append_vals(arr_data_mask, p_mask, mask_len * sizeof(guint8));
+
+               arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               NULL, 0, TRUE, NULL, NULL);
+               arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               NULL, 0, TRUE, NULL, NULL);
+               arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               arr_data->data, arr_data->len, TRUE, NULL, NULL);
+               arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
+                               arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
+
+               param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
+                                       client_if,      // client_if
+                                       action,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
+                                       BT_SCAN_FILTER_FEATURE_MANUFACTURER_DATA,     // filter_type
+                                       filt_index,       // filter_index
+                                       company_id,        // company_id
+                                       company_id_mask, // company_id_mask
+                                       arr_uuid_param, // p_uuid
+                                       arr_uuid_mask_param,    // p_uuid_mask
+                                       "",   // string
+                                       addr_type,      // address_type
+                                       arr_data_param, // p_data
+                                       arr_data_mask_param);
+
+               ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1, NULL, &error);
+
+               if (error) {
+                       ERR("scan_filter_add_remove Fail: %s", error->message);
+                       g_clear_error(&error);
+                       return BT_STATUS_FAIL;
+               }
+
+               if (ret)
+                       g_variant_unref(ret);
+
+               g_array_free(arr_data, TRUE);
+               g_array_free(arr_data_mask, TRUE);
+
+               return BT_STATUS_SUCCESS;
+       }
+
        return BT_STATUS_UNSUPPORTED;
 }
 
index a377912..4270e22 100644 (file)
@@ -100,6 +100,17 @@ typedef enum {
 #endif
 } bt_status_t;
 
+typedef enum {
+       BT_SCAN_FILTER_FEATURE_DEVICE_ADDRESS = 0x01,                 /**< device address */
+       BT_SCAN_FILTER_FEATURE_SERVICE_DATA_CHANGED = 0x02,           /**< service data changed */
+       BT_SCAN_FILTER_FEATURE_SERVICE_UUID = 0x04,                   /**< service uuid */
+       BT_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID = 0x08,      /**< service solicitation uuid */
+       BT_SCAN_FILTER_FEATURE_DEVICE_NAME = 0x10,                    /**< device name */
+       BT_SCAN_FILTER_FEATURE_MANUFACTURER_DATA = 0x20,              /**< manufacturer data */
+       BT_SCAN_FILTER_FEATURE_SERVICE_DATA = 0x40,                   /**< service data */
+} bt_scan_filter_feature_t;
+
+
 /** Bluetooth PinKey Code */
 typedef struct {
        uint8_t pin[16];
index 090c0c4..b18ec11 100644 (file)
@@ -39,6 +39,19 @@ typedef enum {
        OAL_GATT_AUTH_REQ_SIGNED_MITM,
 } oal_gatt_auth_req_t;
 
+/**
+* Scan filter entry
+*/
+typedef enum {
+        OAL_BLE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS = 0x01,                 /**< device address */
+       OAL_BLE_SCAN_FILTER_FEATURE_SERVICE_DATA_CHANGED = 0x02,           /**< service data changed */
+        OAL_BLE_SCAN_FILTER_FEATURE_SERVICE_UUID = 0x04,                   /**< service uuid */
+        OAL_BLE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID = 0x08,      /**< service solicitation uuid */
+        OAL_BLE_SCAN_FILTER_FEATURE_DEVICE_NAME = 0x10,                    /**< device name */
+        OAL_BLE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA = 0x20,              /**< manufacturer data */
+        OAL_BLE_SCAN_FILTER_FEATURE_SERVICE_DATA = 0x40,                   /**< service data */
+} oal_ble_scan_filter_feature_t;
+
 /** GATT value type used in response to remote read requests */
 typedef struct {
        uint8_t           value[OAL_GATT_MAX_ATTR_LEN];
@@ -76,6 +89,41 @@ typedef struct {
        uint8_t  timeout_s;
 } oal_ble_multi_adv_param_setup_t;
 
+typedef struct {
+       int slot_id;
+       int added_features;
+       bt_address_t* device_address;
+       char*  device_name;
+       oal_uuid_t* service_uuid;
+       int service_uuid_len;
+       oal_uuid_t* service_uuid_mask;
+       int service_uuid_mask_len;
+       oal_uuid_t* service_solicitation_uuid;
+       int  service_solicitation_uuid_len;
+       oal_uuid_t* service_solicitation_uuid_mask;
+       int service_solicitation_uuid_mask_len;
+       uint8_t* service_data;
+       int service_data_len;
+       uint8_t* service_data_mask;
+       int service_data_mask_len;
+       int manufacturer_id;
+       uint8_t* manufacturer_data;
+       int manufacturer_data_len;
+       uint8_t* manufacturer_data_mask;
+       int manufacturer_data_mask_len;
+} oal_ble_scan_filter_t;
+
+typedef struct {
+       int list_logic_type;   // list_logic_type (OR - 0x00, AND - 0x01)
+       int filt_logic_type;   // filt_logic_type (OR - 0x00, AND - 0x01)
+       int rssi_high_thres;
+       int rssi_low_thres;
+       int dely_mode;         // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
+       int found_timeout;
+       int lost_timeout;
+       int found_timeout_cnt;
+} oal_ble_scan_filter_param_setup_t;
+
 /**
  * @brief Enable Bluetooth Low Energy GATT Feature
  *
@@ -449,6 +497,8 @@ oal_status_t gattc_unregister_scan_filter(int slot_id);
 
 oal_status_t gattc_conn_param_update(bt_address_t * address, int min, int max, int latency, int timeout);
 
+oal_status_t gattc_register_scan_filter(oal_ble_scan_filter_t* filter_data);
+
 oal_status_t gattc_register_for_notification(int client_id, bt_address_t * address,
                                oal_gatt_srvc_id_t *srvc_id, oal_gatt_id_t *char_id);
 
index 000439e..ce183c2 100644 (file)
@@ -2170,3 +2170,210 @@ oal_status_t gattc_unregister_scan_filter(int slot_id)
        }
        return OAL_STATUS_SUCCESS;
 }
+
+oal_status_t gattc_register_scan_filter(oal_ble_scan_filter_t* filter_data)
+{
+       int ret;
+       int client_info = 0;
+       int action = 0;
+       int company_id = 0;
+       int company_id_mask = 0;
+       int address_type = 0;
+       int feature_selection = 0;
+
+       oal_ble_scan_filter_param_setup_t scan_filter_setup = {.list_logic_type = 0,
+                                                               .filt_logic_type = 1,
+                                                               .rssi_high_thres = -127,
+                                                               .rssi_low_thres = -127,
+                                                               .dely_mode = 0,
+                                                               .found_timeout = 0,
+                                                               .lost_timeout = 0,
+                                                               .found_timeout_cnt = 0
+                                                               };
+
+       OAL_CHECK_PARAMETER(filter_data, return);
+       API_TRACE();
+       CHECK_OAL_GATT_ENABLED();
+
+       if (filter_data->added_features & OAL_BLE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS){
+               bdstr_t bdstr;
+               BT_INFO("OAL_BLE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS is being added");
+               BT_INFO("BT remote Device address is %s", bdt_bd2str(filter_data->device_address, &bdstr));
+               ret = gatt_api->client->scan_filter_add_remove(client_info,
+                                                               action,
+                                                               OAL_BLE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS,
+                                                               filter_data->slot_id,
+                                                               company_id,
+                                                               company_id_mask,
+                                                               NULL,
+                                                               NULL,
+                                                               (bt_bdaddr_t*)filter_data->device_address,
+                                                               address_type,
+                                                               0,
+                                                               NULL,
+                                                               0,
+                                                               NULL
+                                                               );
+               if (ret != BT_STATUS_SUCCESS){
+                       BT_ERR("error: %s", status2string(ret));
+                       BT_INFO("unregistering already set filter features.");
+                       gatt_api->client->scan_filter_clear(client_info, filter_data->slot_id);
+                       return convert_to_oal_status(ret);
+               }
+
+               feature_selection |= OAL_BLE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
+       }
+       if (filter_data->added_features & OAL_BLE_SCAN_FILTER_FEATURE_DEVICE_NAME){
+               ret = gatt_api->client->scan_filter_add_remove(client_info,
+                                                               action,
+                                                               OAL_BLE_SCAN_FILTER_FEATURE_DEVICE_NAME,
+                                                               filter_data->slot_id,
+                                                               company_id,
+                                                               company_id_mask,
+                                                               NULL,
+                                                               NULL,
+                                                               NULL,
+                                                               address_type,
+                                                               0,
+                                                               filter_data->device_name,     // device_name as p_data in HAL
+                                                               0,
+                                                               NULL
+                                                               );
+               if (ret != BT_STATUS_SUCCESS){
+                       BT_ERR("error: %s", status2string(ret));
+                       BT_INFO("unregistering already set filter features.");
+                       gatt_api->client->scan_filter_clear(client_info, filter_data->slot_id);
+                       return convert_to_oal_status(ret);
+               }
+
+               feature_selection |= OAL_BLE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
+       }
+       if (filter_data->added_features & OAL_BLE_SCAN_FILTER_FEATURE_SERVICE_UUID){
+               BT_INFO("OAL_BLE_SCAN_FILTER_FEATURE_SERVICE_UUID is being added");
+               char uuid_str1[2*BT_UUID_STRING_MAX];
+               char uuid_str2[2*BT_UUID_STRING_MAX];
+
+               uuid_to_stringname((service_uuid_t*)filter_data->service_uuid, uuid_str1);
+               uuid_to_stringname((service_uuid_t*)filter_data->service_uuid_mask, uuid_str2);
+
+               BT_INFO("Service UUID  is [%s] and Service UUID mask is [%s]", uuid_str1, uuid_str2);
+               ret = gatt_api->client->scan_filter_add_remove(client_info,
+                                                               action,
+                                                               OAL_BLE_SCAN_FILTER_FEATURE_SERVICE_UUID,
+                                                               filter_data->slot_id,
+                                                               company_id,
+                                                               company_id_mask,
+                                                               (bt_uuid_t*)filter_data->service_uuid,
+                                                               (bt_uuid_t*)filter_data->service_uuid_mask,
+                                                               NULL,
+                                                               address_type,
+                                                               filter_data->service_uuid_len,   // service_uuid_len as data_len in HAL
+                                                               NULL,
+                                                               filter_data->service_uuid_mask_len,
+                                                               NULL
+                                                               );
+               if (ret != BT_STATUS_SUCCESS){
+                       BT_ERR("error: %s", status2string(ret));
+                       BT_INFO("unregistering already set filter features.");
+                       gatt_api->client->scan_filter_clear(client_info, filter_data->slot_id);
+                       return convert_to_oal_status(ret);
+               }
+
+               feature_selection |= OAL_BLE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
+       }
+       if (filter_data->added_features & OAL_BLE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID){
+               BT_INFO("OAL_BLE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID is being added");
+               char uuid_str1[2*BT_UUID_STRING_MAX];
+               char uuid_str2[2*BT_UUID_STRING_MAX];
+               uuid_to_stringname((service_uuid_t*)filter_data->service_solicitation_uuid, uuid_str1);
+               uuid_to_stringname((service_uuid_t*)filter_data->service_solicitation_uuid_mask, uuid_str2);
+               BT_INFO("Service Solicitation UUID  is [%s] and Service Solicitation UUID mask is [%s]", uuid_str1, uuid_str2);
+               ret = gatt_api->client->scan_filter_add_remove(client_info,
+                                                               action,
+                                                               OAL_BLE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID,
+                                                               filter_data->slot_id,
+                                                               company_id,
+                                                               company_id_mask,
+                                                               (bt_uuid_t*)filter_data->service_solicitation_uuid,
+                                                               (bt_uuid_t*)filter_data->service_solicitation_uuid_mask,
+                                                               NULL,
+                                                               address_type,
+                                                               filter_data->service_solicitation_uuid_len,   // service_solicitation_uuid_len as data_len in HAL
+                                                               NULL,
+                                                               filter_data->service_solicitation_uuid_mask_len,
+                                                               NULL
+                                                               );
+               if (ret != BT_STATUS_SUCCESS){
+                       BT_ERR("error: %s", status2string(ret));
+                       BT_INFO("unregistering already set filter features.");
+                       gatt_api->client->scan_filter_clear(client_info, filter_data->slot_id);
+                       return convert_to_oal_status(ret);
+               }
+
+               feature_selection |= OAL_BLE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
+       }
+       if (filter_data->added_features & OAL_BLE_SCAN_FILTER_FEATURE_SERVICE_DATA){
+               ret = gatt_api->client->scan_filter_add_remove(client_info,
+                                                               action,
+                                                               OAL_BLE_SCAN_FILTER_FEATURE_SERVICE_DATA,
+                                                               filter_data->slot_id,
+                                                               company_id,
+                                                               company_id_mask,
+                                                               NULL,
+                                                               NULL,
+                                                               NULL,
+                                                               address_type,
+                                                               filter_data->service_data_len,    //service_data_len as data_len in HAL
+                                                               (char*)filter_data->service_data,
+                                                               filter_data->service_data_mask_len,
+                                                               (char*)filter_data->service_data_mask
+                                                               );
+               if (ret != BT_STATUS_SUCCESS){
+                       BT_ERR("error: %s", status2string(ret));
+                       BT_INFO("unregistering already set filter features.");
+                       gatt_api->client->scan_filter_clear(client_info, filter_data->slot_id);
+                       return convert_to_oal_status(ret);
+               }
+
+               feature_selection |= OAL_BLE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
+       }
+       if (filter_data->added_features & OAL_BLE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA){
+               ret = gatt_api->client->scan_filter_add_remove(client_info,
+                                                               action,
+                                                               OAL_BLE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA,
+                                                               filter_data->slot_id,
+                                                               filter_data->manufacturer_id,
+                                                               company_id_mask,
+                                                               NULL,
+                                                               NULL,
+                                                               NULL,
+                                                               address_type,
+                                                               filter_data->manufacturer_data_len,    //manufacturer_data_len as data_len in HAL
+                                                               (char*)filter_data->manufacturer_data,
+                                                               filter_data->manufacturer_data_mask_len,
+                                                               (char*)filter_data->manufacturer_data_mask
+                                                               );
+               feature_selection |= OAL_BLE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
+               if (ret != BT_STATUS_SUCCESS){
+                       BT_ERR("error: %s", status2string(ret));
+                       BT_INFO("unregistering already set filter features.");
+                       gatt_api->client->scan_filter_clear(client_info, filter_data->slot_id);
+                       return convert_to_oal_status(ret);
+               }
+
+               feature_selection |= OAL_BLE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
+       }
+
+       BT_DBG("Filter selection 0x%.2x", feature_selection);
+
+       ret = gatt_api->client->scan_filter_param_setup(client_info, action, filter_data->slot_id, feature_selection,
+                                                       scan_filter_setup.list_logic_type, scan_filter_setup.filt_logic_type,
+                                                       scan_filter_setup.rssi_high_thres, scan_filter_setup.rssi_low_thres,
+                                                       scan_filter_setup.dely_mode, scan_filter_setup.found_timeout,
+                                                       scan_filter_setup.lost_timeout, scan_filter_setup.found_timeout_cnt);
+       if (ret != BT_STATUS_SUCCESS){
+               BT_ERR("error: %s", status2string(ret));
+               return convert_to_oal_status(ret);
+       }
+       return OAL_STATUS_SUCCESS;
+}
index 9774f17..aea178a 100644 (file)
@@ -720,6 +720,7 @@ static void __bt_le_event_handler(int event_type, gpointer event_data)
 
                le_feature_info.le_2m_phy = le_features->le_2m_phy_support;
                le_feature_info.le_coded_phy = le_features->le_coded_phy_support;
+               le_feature_info.max_filter = le_features->max_adv_filter;
 
                BT_INFO("Adapter LE 2M PHY Support [%s]", le_feature_info.le_2m_phy ? "TRUE" : "FALSE");
                BT_INFO("Adapter LE CODED PHY Support [%s]", le_feature_info.le_coded_phy ? "TRUE" : "FALSE");
@@ -1761,6 +1762,95 @@ void _bt_check_le_scanner_app_termination(const char *sender)
        g_free(scanner);
 }
 
+int __bt_get_available_scan_filter_slot_id(void)
+{
+       GSList *l;
+       bt_adapter_le_scanner_t *scanner;
+       GSList *fl;
+       bluetooth_le_scan_filter_t *filter_data;
+       gboolean *slot_check_list = NULL;
+       int i;
+
+       if (le_feature_info.max_filter == 0) {
+               BT_ERR("Scan filter is NOT Supported");
+               return -1;
+       }
+       slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
+
+       for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
+               scanner = l->data;
+               for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
+                       filter_data = fl->data;
+                       if (filter_data->slot_id < le_feature_info.max_filter)
+                               slot_check_list[filter_data->slot_id] = TRUE;
+               }
+       }
+
+       for (i = 0; i < le_feature_info.max_filter; i++) {
+               if (slot_check_list[i] == FALSE) {
+                       g_free(slot_check_list);
+                       return i;
+               }
+       }
+
+       BT_ERR("There is NO available slot for scan filter.");
+       g_free(slot_check_list);
+       return -1;
+}
+
+int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
+{
+       int ret = BLUETOOTH_ERROR_NONE;
+       bt_adapter_le_scanner_t *scanner = NULL;
+       bluetooth_le_scan_filter_t *scan_filter_data = NULL;
+
+       *slot_id = __bt_get_available_scan_filter_slot_id();
+
+       if (*slot_id == -1)
+               return BLUETOOTH_ERROR_NO_RESOURCES;
+
+       oal_ble_scan_filter_t filter_data = {.slot_id = *slot_id, .device_address = (bt_address_t*)&filter->device_address, .device_name = filter->device_name,
+                                               .service_uuid = (oal_uuid_t*)&filter->service_uuid.data, .service_uuid_len = filter->service_uuid.data_len,
+                                               .service_uuid_mask = (oal_uuid_t*)&filter->service_uuid_mask.data, .service_uuid_mask_len = filter->service_uuid_mask.data_len,
+                                               .service_solicitation_uuid = (oal_uuid_t*)&filter->service_solicitation_uuid.data,
+                                               .service_solicitation_uuid_len = filter->service_solicitation_uuid.data_len,
+                                               .service_solicitation_uuid_mask = (oal_uuid_t*)&filter->service_solicitation_uuid_mask.data,
+                                               .service_solicitation_uuid_mask_len = filter->service_solicitation_uuid_mask.data_len,
+                                               .service_data = filter->service_data.data.data, .service_data_len = filter->service_data.data_len,
+                                               .service_data_mask = filter->service_data_mask.data.data, .service_data_mask_len = filter->service_data_mask.data_len,
+                                               .manufacturer_id = filter->manufacturer_id, .manufacturer_data = filter->manufacturer_data.data.data,
+                                               .manufacturer_data_len = filter->manufacturer_data.data_len, .manufacturer_data_mask = filter->manufacturer_data_mask.data.data,
+                                               .manufacturer_data_mask_len = filter->manufacturer_data_mask.data_len , .added_features = filter->added_features
+                                       };
+       ret = gattc_register_scan_filter(&filter_data);
+
+       if (OAL_STATUS_SUCCESS != ret) {
+               BT_ERR("gattc_register_scan_filter failed");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       scanner = __bt_find_scanner_from_list(sender);
+
+       if (scanner == NULL) {
+               scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
+
+               if (scanner == NULL)
+                       return BLUETOOTH_ERROR_MEMORY_ALLOCATION;
+
+               scanner->sender = g_strdup(sender);
+               scanner_list = g_slist_append(scanner_list, scanner);
+       }
+
+       scan_filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
+
+       memcpy(scan_filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
+
+       scan_filter_data->slot_id = *slot_id;
+       scanner->filter_list = g_slist_append(scanner->filter_list, scan_filter_data);
+
+       return ret;
+}
+
 int _bt_service_le_init(void)
 {
        le_init();
index 58ac62e..9676206 100644 (file)
@@ -3168,6 +3168,22 @@ normal:
                result = _bt_disconnect_device(&address);
                break;
        }
+       case BT_REGISTER_SCAN_FILTER: {
+               bluetooth_le_scan_filter_t scan_filter;
+               int slot_id;
+
+               sender = (char*)g_dbus_method_invocation_get_sender(context);
+               __bt_service_get_parameters(in_param1, &scan_filter,
+                               sizeof(bluetooth_le_scan_filter_t));
+
+               BT_DBG("bluetooth_le_scan_filter_t [features : 0x%.2x]",
+                               scan_filter.added_features);
+
+               result = _bt_register_scan_filter(sender, &scan_filter, &slot_id);
+
+               g_array_append_vals(*out_param1, &slot_id, sizeof(int));
+               break;
+       }
        default:
                BT_INFO("UnSupported function [%d]", function_name);
                result = BLUETOOTH_ERROR_NOT_SUPPORT;
index 5107892..1353180 100644 (file)
@@ -104,6 +104,8 @@ int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data);
 int _bt_unregister_scan_filter(const char *sender, int slot_id);
 
 int _bt_unregister_all_scan_filters(const char *sender);
+
+int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id);
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */