#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__ */
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)
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("");
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)
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;
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) {
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;
}
}
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,
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];
#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;
}
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) {
{ "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
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)