iBeacon: Add support to filter the iBeacon reports 39/90939/4
authorh.sandeep <h.sandeep@samsung.com>
Wed, 5 Oct 2016 05:07:35 +0000 (10:37 +0530)
committerPyun DoHyun <dh79.pyun@samsung.com>
Wed, 2 Nov 2016 02:29:56 +0000 (19:29 -0700)
Change-Id: I94c1911418783be65995995abcc4899c16dee0dc
Signed-off-by: h.sandeep <h.sandeep@samsung.com>
src/adapter.c
src/adapter.h
src/device.c
src/device.h

index 2f9598a..619df2a 100644 (file)
 #include "eir.h"
 
 #ifdef __TIZEN_PATCH__
-#define TIZEN_FEATURE_PLATFROM_SCAN_FILTER
-#endif
-
-#ifdef __TIZEN_PATCH__
 #include "adapter_le_vsc_features.h"
 #endif
 
 
 #define LE_BEARER_POSTFIX      " LE"
 #define LE_BEARER_POSTFIX_LEN  3
-
-/* Slot value shall be changed when required */
-#define SCAN_FILTER_SLOTS_MAX 20
 #endif /* __TIZEN_PATCH__ */
 
 
@@ -2906,10 +2899,14 @@ int adapter_le_manufacturer_data_cmp(gconstpointer a, gconstpointer b)
        const adapter_le_manf_data_params_t *params = a;
        const struct eir_msd *msd = b;
 
-       if (msd->company == params->company_id)
+       if (msd->company == params->company_id) {
+               /* if the advertisiement packet is an iBeacon */
+               if (msd->company == COMPANY_ID_APPLE)
+                       return 0;
                return strncasecmp((const char *)params->man_data, msd->data, params->man_data_len);
-       else
+       } else {
                return -1;
+       }
 }
 
 int adapter_le_local_name_cmp(gconstpointer a, gconstpointer b)
@@ -2977,7 +2974,7 @@ int adapter_le_scan_params_filter_index_cmp(gconstpointer a, gconstpointer b)
        return params->index - filter_inex;
 }
 
-static gboolean adapter_le_clear_platform_scan_filter_data (
+static gboolean adapter_le_clear_platform_scan_filter_data(
                        struct btd_adapter *adapter, int filter_index)
 {
        DBG("");
@@ -3043,7 +3040,7 @@ static gboolean adapter_le_clear_platform_scan_filter_data (
        return TRUE;
 }
 
-static gboolean adapter_le_enable_platform_scan_filtering (
+static gboolean adapter_le_enable_platform_scan_filtering(
                        struct btd_adapter *adapter, gboolean enable)
 {
        if (!adapter)
@@ -3478,32 +3475,33 @@ static gboolean adapter_le_service_clear_scan_filter_params(struct btd_adapter *
 int adapter_byte_arr_cmp_with_mask(const char *data1, const char *data2,
         const char *mask, int data_len)
 {
-        int i;
-        char a, b;
+       int i;
+       char a, b;
        if (data1 == NULL || data2 == NULL || mask == NULL)
                return -1;
-        for (i = 0; i < data_len; i++) {
-                a = data1[i] & mask[i];
-                b = data2[i] & mask[i];
-                if (a != b)
-                        return (int)(a - b);
-                }
-        return 0;
+       for (i = 0; i < data_len; i++) {
+               a = data1[i] & mask[i];
+               b = data2[i] & mask[i];
+               if (a != b)
+                       return (int)(a - b);
+       }
+       return 0;
 }
 
-static gboolean validate_for_filter_policy(struct btd_adapter *adapter, const struct eir_data *eir, gchar *addr)
+static uint8_t validate_for_filter_policy(struct btd_adapter *adapter,
+                                                               const struct eir_data *eir, gchar *addr)
 {
-       gboolean is_allowed = FALSE;
+       uint8_t allow_report = NONE_REPORT;
        DBG("");
 
        if (adapter->scan_filter_support == FALSE)
-               is_allowed = TRUE;
+               allow_report = SCAN_REPORT;
        else {
                if (adapter_le_service_find_addr_scan_filter_data(adapter, addr))
-                       is_allowed = TRUE;
+                       allow_report = SCAN_REPORT;
                if (eir->name) {
                        if(adapter_le_service_find_local_name_scan_filter_data(adapter, eir->name))
-                               is_allowed = TRUE;
+                               allow_report = SCAN_REPORT;
                        }
                if (eir->sd_list) {
                        GSList *list = NULL;
@@ -3523,7 +3521,7 @@ static gboolean validate_for_filter_policy(struct btd_adapter *adapter, const st
                                                                                service_data->filter_index);
                                                        if (scan_param_data && scan_param_data->rssi_high_threshold > eir->tx_power &&
                                                                scan_param_data->rssi_low_threshold < eir->tx_power)
-                                                               is_allowed = TRUE;
+                                                               allow_report = SCAN_REPORT;
                                                }
                                        }
                                        if (uuid_data != NULL) {
@@ -3534,10 +3532,10 @@ static gboolean validate_for_filter_policy(struct btd_adapter *adapter, const st
                                                                                                uuid_data->filter_index);
                                                        if (scan_param_data && scan_param_data->rssi_high_threshold > eir->tx_power &&
                                                                scan_param_data->rssi_low_threshold < eir->tx_power)
-                                                               is_allowed = TRUE;
+                                                               allow_report = SCAN_REPORT;
                                                }
                                        }
-                                       if (is_allowed)
+                                       if (allow_report)
                                                break;
                                }
                        }
@@ -3555,18 +3553,20 @@ static gboolean validate_for_filter_policy(struct btd_adapter *adapter, const st
                                                if (!adapter_byte_arr_cmp_with_mask((const char *)msd->data,
                                                        (const char *)manuf_data->man_data, (const char *)manuf_data->man_data_mask,
                                                        manuf_data->man_data_len)) {
-                                                               scan_param_data = adapter_le_service_find_scan_filter_params(adapter,
-                                                                                                       manuf_data->filter_index);
-                                                               if (scan_param_data && scan_param_data->rssi_high_threshold > eir->tx_power &&
-                                                                       scan_param_data->rssi_low_threshold < eir->tx_power)
-                                                                       is_allowed = TRUE;
-                                                       }
+                                                       scan_param_data = adapter_le_service_find_scan_filter_params(adapter,
+                                                                                               manuf_data->filter_index);
+                                                       if (scan_param_data && scan_param_data->rssi_high_threshold > eir->tx_power &&
+                                                               scan_param_data->rssi_low_threshold < eir->tx_power)
+                                                               allow_report = SCAN_REPORT;
+                                               }
+                                               if (msd->company == COMPANY_ID_APPLE)
+                                                       allow_report = IBEACON_REPORT;
                                        }
                                }
                        }
                }
        }
-       return is_allowed;
+       return allow_report;
 }
 
 gboolean adapter_le_set_platform_scan_filter_params(struct btd_adapter *adapter,
@@ -9751,7 +9751,7 @@ static void update_found_devices(struct btd_adapter *adapter,
        struct eir_data eir_data;
        bool name_known, discoverable;
 #ifdef TIZEN_FEATURE_PLATFROM_SCAN_FILTER
-       bool is_allowed;
+       uint8_t allow_report;
 #endif
        char addr[18];
 
@@ -9767,9 +9767,10 @@ static void update_found_devices(struct btd_adapter *adapter,
 
 #ifdef TIZEN_FEATURE_PLATFROM_SCAN_FILTER
        /* Check if the any filter policy */
-       is_allowed = validate_for_filter_policy(adapter, &eir_data, addr);
-       if (!is_allowed && ((adapter->scan_type == 1 && adv_type == 04) ||
-                       adapter->scan_type == 0)) {
+       allow_report = validate_for_filter_policy(adapter, &eir_data, addr);
+       if (allow_report == NONE_REPORT &&
+               ((adapter->scan_type == LE_ACTIVE_SCAN && adv_type == ADV_TYPE_SCAN_RESPONSE) ||
+               adapter->scan_type == LE_PASSIVE_SCAN)) {
                eir_data_free(&eir_data);
                return;
        }
@@ -9905,8 +9906,13 @@ static void update_found_devices(struct btd_adapter *adapter,
 
        if (bdaddr_type == BDADDR_BREDR)
                device_set_manufacturer_info(dev, &eir_data);
-       else
+       else {
+               /* if the application has registered for iBeacon report,
+                * then send ibeacon report along with advertisement report */
+               if (allow_report == IBEACON_REPORT)
+                       device_set_ibeacon_report_info(dev, (void*)data, data_len, adv_type, rssi);
                device_set_adv_report_info(dev, (void*)data, data_len, adv_type, rssi);
+       }
 #endif
 
        if (eir_data.msd_list) {
index 71c7665..6efead7 100644 (file)
 #define BT_DISC_TYPE_BREDR_ONLY 1
 #define BT_DISC_TYPE_LE_ONLY    2
 #define BT_DISC_TYPE_LE_BREDR   3
+
+#define TIZEN_FEATURE_PLATFROM_SCAN_FILTER
+#ifdef TIZEN_FEATURE_PLATFROM_SCAN_FILTER
+
+#define COMPANY_ID_APPLE 0x004C
+/* Deafult value set to 16(same as vendor specific value)
+ * and value shall be changed when required */
+#define SCAN_FILTER_SLOTS_MAX 16
+#define ADV_TYPE_SCAN_RESPONSE 04
+
+typedef enum {
+       NONE_REPORT,
+       SCAN_REPORT,
+       IBEACON_REPORT,
+} adapter_le_scan_report_type;
+
+typedef enum {
+       LE_PASSIVE_SCAN,
+       LE_ACTIVE_SCAN,
+} adapter_le_scan_type;
+#endif /* TIZEN_FEATURE_PLATFROM_SCAN_FILTER */
+
 #endif
 
 struct btd_adapter;
index a878790..bffe36a 100644 (file)
@@ -3916,6 +3916,17 @@ static const GDBusSignalTable device_signals[] = {
                                { "max_rx_time", "q"})) },
        { GDBUS_SIGNAL("IpspStateChanged",
                        GDBUS_ARGS({"connected","b"},{"if_name","s"}))},
+#ifdef TIZEN_FEATURE_PLATFROM_SCAN_FILTER
+       { GDBUS_SIGNAL("iBeaconReport",
+                       GDBUS_ARGS({"Address","s"},
+                               { "Address Type", "y" },
+                               { "company id", "u"},
+                               { "beacon type", "u"},
+                               { "UUID", "s"},
+                               { "major id", "u"},
+                               { "minor id", "u"},
+                               { "measured power", "y"})) },
+#endif
 };
 #endif
 
@@ -8225,6 +8236,61 @@ void btd_device_disconnect(struct btd_device *device)
 
        return;
 }
+
+#ifdef TIZEN_FEATURE_PLATFROM_SCAN_FILTER
+void device_set_ibeacon_report_info(struct btd_device *device, void *data, uint8_t data_len,
+                               uint8_t adv_type, int8_t rssi)
+{
+       char peer_addr[18];
+       const char *paddr = peer_addr;
+       const uint8_t *uuid_ptr = data+6;
+       uuid_t service;
+       const char *uuid_str = NULL;
+       dbus_int32_t rssi_val = rssi;
+       dbus_uint32_t company_id = 0;
+       dbus_uint32_t beacon_type = 0;
+       dbus_uint32_t major_id = 0;
+       dbus_uint32_t minor_id = 0;
+       uint8_t measured_power = 0;
+       uint8_t addr_type;
+       int k;
+       if (!device)
+               return;
+
+       ba2str(&device->bdaddr, peer_addr);
+       /* Replace address type for paired RPA device since IDA passed from controller */
+       if(device_get_rpa_exist(device) == true)
+               addr_type = BDADDR_LE_RANDOM;
+       else
+               addr_type = device->bdaddr_type;
+
+       company_id = get_le16(data+2);
+       beacon_type = get_le16(data+4);
+       major_id = get_le16(data+22);
+       minor_id = get_le16(data+24);
+       measured_power = get_u8(data+26);
+       service.type = SDP_UUID128;
+       for (k = 0; k < 16; k++)
+               service.value.uuid128.data[k] = uuid_ptr[16 - k - 1];
+       uuid_str = bt_uuid2string(&service);
+
+       DBG("Company_id: 0x%04x, beacon_type: 0x%04x, UUID: %s",
+                               company_id, beacon_type, uuid_str);
+       DBG(" major_id : 0x%04x, Minor_id: 0x%04x, measured_power: %d",
+                               major_id, minor_id, measured_power);
+       g_dbus_emit_signal(dbus_conn, device->path,
+               DEVICE_INTERFACE, "iBeaconReport",
+               DBUS_TYPE_STRING, &paddr,
+               DBUS_TYPE_BYTE, &addr_type,
+               DBUS_TYPE_UINT32, &company_id,
+               DBUS_TYPE_UINT32, &beacon_type,
+               DBUS_TYPE_STRING, &uuid_str,
+               DBUS_TYPE_UINT32, &major_id,
+               DBUS_TYPE_UINT32, &minor_id,
+               DBUS_TYPE_BYTE, &measured_power,
+               DBUS_TYPE_INVALID);
+}
+#endif /* TIZEN_FEATURE_PLATFROM_SCAN_FILTER */
 #endif
 
 static gboolean notify_attios(gpointer user_data)
index c0cfe2e..22583d9 100644 (file)
@@ -186,6 +186,10 @@ void device_le_data_length_changed(struct btd_device *device, uint16_t max_tx_oc
                        uint16_t max_rx_time);
 void device_get_tizen_addr(struct btd_device *device,
                                        struct device_addr_type *addr);
+#ifdef TIZEN_FEATURE_PLATFROM_SCAN_FILTER
+void device_set_ibeacon_report_info(struct btd_device *device, void *data, uint8_t data_len,
+                               uint8_t adv_type, int8_t rssi);
+#endif /* TIZEN_FEATURE_PLATFROM_SCAN_FILTER */
 #endif
 
 struct btd_device *btd_device_ref(struct btd_device *device);