iBeacon: Add API to register iBeacon scan filter. 32/90932/10
authorh.sandeep <h.sandeep@samsung.com>
Wed, 5 Oct 2016 04:43:24 +0000 (10:13 +0530)
committerh.sandeep <h.sandeep@samsung.com>
Wed, 16 Nov 2016 05:50:18 +0000 (11:20 +0530)
1. Adds the API to register for ibeacon scan reports
2. Handles the iBeacon scan report events

Change-Id: I68f73bad3dec532ffdde8fa563fa771b0b62b32c
Signed-off-by: h.sandeep <h.sandeep@samsung.com>
include/bluetooth_private.h
include/mobile/bluetooth_internal.h
include/mobile/bluetooth_type.h
include/tv/bluetooth_internal.h
include/tv/bluetooth_type.h
include/wearable/bluetooth_internal.h
include/wearable/bluetooth_type.h
src/bluetooth-adapter.c
src/bluetooth-common.c
test/bt_unit_test.c
test/bt_unit_test.h

index f2c61f080a9ee1c769c3c88d81a69e8952c9d6e1..5c51fa49cca4cb87c68ee351f6dccb390711571b 100644 (file)
@@ -44,6 +44,8 @@ extern "C" {
 
 #define OPP_UUID "00001105-0000-1000-8000-00805f9b34fb"
 
+/* Manufacture ID for Apple iBeacons */
+#define COMPANY_ID_APPLE 0x004C
 
 /**
  * @internal
index 528264e7bc9172810801da2c115261b17f5202f9..66b7069cbb39426c413f5e47a37091a6bbc58af8 100644 (file)
@@ -3188,6 +3188,27 @@ int bt_proximity_get_property(const char *remote_address, bt_proximity_property_
  * @brief Lists the Proximity Profile property/service supported.
  */
 int bt_proximity_get_supported_services(const char *remote_address, int *supported_services);
+
+/**
+ * @internal
+ * @brief API to set scan filter for iBeacons reports
+ */
+int bt_adapter_le_set_ibeacon_scan_filter(bt_scan_filter_h scan_filter,
+                       const char *data, unsigned int data_len);
+
+/**
+ * @internal
+ * @brief API to read iBeacon report from LE scan result information
+ */
+int bt_adapter_le_get_scan_result_ibeacon_report(const bt_adapter_le_device_scan_result_info_s *info,
+                       bt_adapter_le_packet_type_e pkt_type, bt_adapter_ibeacon_scan_result_info_s **ibeacon_info);
+
+/**
+ * @internal
+ * @brief API to clear the iBeacon report
+ */
+int bt_adapter_le_free_ibeacon_report(bt_adapter_ibeacon_scan_result_info_s *ibeacon_info);
+
 /**
  * @}
  */
index 0bd2741be9a74c842eed13fe58389c703e96c4e4..c49bc704c026a7bee1bfdff9fca900393e91076e 100644 (file)
@@ -878,6 +878,22 @@ typedef struct {
        char *scan_data;        /**< scan response data */
 } bt_adapter_le_device_scan_result_info_s;
 
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE
+ * @brief Structure of le iBeacon scan result information.
+ * @since_tizen 3.0
+ *
+ * @see bt_adapter_le_start_scan()
+ */
+typedef struct {
+       int company_id;         /**< company ID */
+       int ibeacon_type;       /**< Ibeacon type */
+       char *uuid;                     /**< UUID */
+       int major_id;           /**< Major ID */
+       int minor_id;           /**< Minor ID */
+       int measured_power;     /**< measured Power */
+} bt_adapter_ibeacon_scan_result_info_s;
+
 /**
  * @deprecated Deprecated since 2.3.1
  * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE
index 528264e7bc9172810801da2c115261b17f5202f9..66b7069cbb39426c413f5e47a37091a6bbc58af8 100644 (file)
@@ -3188,6 +3188,27 @@ int bt_proximity_get_property(const char *remote_address, bt_proximity_property_
  * @brief Lists the Proximity Profile property/service supported.
  */
 int bt_proximity_get_supported_services(const char *remote_address, int *supported_services);
+
+/**
+ * @internal
+ * @brief API to set scan filter for iBeacons reports
+ */
+int bt_adapter_le_set_ibeacon_scan_filter(bt_scan_filter_h scan_filter,
+                       const char *data, unsigned int data_len);
+
+/**
+ * @internal
+ * @brief API to read iBeacon report from LE scan result information
+ */
+int bt_adapter_le_get_scan_result_ibeacon_report(const bt_adapter_le_device_scan_result_info_s *info,
+                       bt_adapter_le_packet_type_e pkt_type, bt_adapter_ibeacon_scan_result_info_s **ibeacon_info);
+
+/**
+ * @internal
+ * @brief API to clear the iBeacon report
+ */
+int bt_adapter_le_free_ibeacon_report(bt_adapter_ibeacon_scan_result_info_s *ibeacon_info);
+
 /**
  * @}
  */
index f0b495a011e79f9bd030be197dadeab0e1ea2c30..d4af7a916573a0ff484f1411c310939af6770ff4 100644 (file)
@@ -878,6 +878,22 @@ typedef struct {
        char *scan_data;        /**< scan response data */
 } bt_adapter_le_device_scan_result_info_s;
 
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE
+ * @brief Structure of le iBeacon scan result information.
+ * @since_tizen 3.0
+ *
+ * @see bt_adapter_le_start_scan()
+ */
+typedef struct {
+       int company_id;         /**< company ID */
+       int ibeacon_type;       /**< Ibeacon type */
+       char *uuid;                     /**< UUID */
+       int major_id;           /**< Major ID */
+       int minor_id;           /**< Minor ID */
+       int measured_power;     /**< measured Power */
+} bt_adapter_ibeacon_scan_result_info_s;
+
 /**
  * @deprecated Deprecated since 2.3.1
  * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE
index 0d7f046f6e427b0dc3f7f5bd6128019f994e6670..6a99d860f8447fdc875fe890c483406f8394374c 100644 (file)
@@ -3336,6 +3336,27 @@ int bt_proximity_get_property(const char *remote_address, bt_proximity_property_
  * @brief Lists the Proximity Profile property/service supported.
  */
 int bt_proximity_get_supported_services(const char *remote_address, int *supported_services);
+
+/**
+ * @internal
+ * @brief API to set scan filter for iBeacons reports
+ */
+int bt_adapter_le_set_ibeacon_scan_filter(bt_scan_filter_h scan_filter,
+                       const char *data, unsigned int data_len);
+
+/**
+ * @internal
+ * @brief API to read iBeacon report from LE scan result information
+ */
+int bt_adapter_le_get_scan_result_ibeacon_report(const bt_adapter_le_device_scan_result_info_s *info,
+                       bt_adapter_le_packet_type_e pkt_type, bt_adapter_ibeacon_scan_result_info_s **ibeacon_info);
+
+/**
+ * @internal
+ * @brief API to clear the iBeacon report
+ */
+int bt_adapter_le_free_ibeacon_report(bt_adapter_ibeacon_scan_result_info_s *ibeacon_info);
+
 /**
  * @}
  */
index 2bb78599260e94d5c3b7caac0a4237c6ed8b2410..aa675e7e2d04d102470c33ccc7f87f01c004c6b7 100644 (file)
@@ -905,6 +905,22 @@ typedef struct {
        char *scan_data;        /**< scan response data */
 } bt_adapter_le_device_scan_result_info_s;
 
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE
+ * @brief Structure of le iBeacon scan result information.
+ * @since_tizen 3.0
+ *
+ * @see bt_adapter_le_start_scan()
+ */
+typedef struct {
+       int company_id;         /**< company ID */
+       int ibeacon_type;       /**< Ibeacon type */
+       char *uuid;                     /**< UUID */
+       int major_id;           /**< Major ID */
+       int minor_id;           /**< Minor ID */
+       int measured_power;     /**< measured Power */
+} bt_adapter_ibeacon_scan_result_info_s;
+
 /**
  * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE
  * @brief LE service data structure.
index f46e1d2f7ced83342401699a18188eb3cee8a907..72f515ed083cd46d8a78169202d4e39f3f933c6f 100644 (file)
@@ -3303,6 +3303,74 @@ int bt_adapter_le_get_scan_result_manufacturer_data(const bt_adapter_le_device_s
        return BT_ERROR_NO_DATA; /* LCOV_EXCL_STOP */
 }
 
+int bt_adapter_le_free_ibeacon_report(bt_adapter_ibeacon_scan_result_info_s *ibeacon_info)
+{
+
+       BT_CHECK_LE_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(ibeacon_info); /* LCOV_EXCL_START */
+
+       if (ibeacon_info->uuid)
+               g_free(ibeacon_info->uuid);
+
+       g_free(ibeacon_info);
+
+       return BT_ERROR_NONE; /* LCOV_EXCL_STOP */
+}
+
+int bt_adapter_le_get_scan_result_ibeacon_report(const bt_adapter_le_device_scan_result_info_s *info,
+                       bt_adapter_le_packet_type_e pkt_type, bt_adapter_ibeacon_scan_result_info_s **ibeacon_info)
+{
+       int manufacturer_id;
+       char *manufacturer_data;
+       int manufacturer_data_len;
+
+       BT_CHECK_LE_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(info);
+
+       if (bt_adapter_le_get_scan_result_manufacturer_data(
+                       info, pkt_type, &manufacturer_id, &manufacturer_data,
+                       &manufacturer_data_len) != BT_ERROR_NONE)
+                       return BT_ERROR_NO_DATA;
+
+       if (manufacturer_data == NULL || manufacturer_data_len < 23)
+               return BT_ERROR_NO_DATA;
+
+       if (manufacturer_id != COMPANY_ID_APPLE)
+               return BT_ERROR_NO_DATA;
+
+       *ibeacon_info = g_malloc0(sizeof(bt_adapter_ibeacon_scan_result_info_s));
+       if (*ibeacon_info == NULL)
+               return BT_ERROR_OUT_OF_MEMORY;
+
+       (*ibeacon_info)->company_id = manufacturer_id;
+       (*ibeacon_info)->ibeacon_type = manufacturer_data[1] << 8;
+       (*ibeacon_info)->ibeacon_type += manufacturer_data[0];
+
+       (*ibeacon_info)->uuid = g_malloc0(sizeof(char) *36 + 1);
+       if ((*ibeacon_info)->uuid == NULL) {
+               g_free(*ibeacon_info);
+               return BT_ERROR_OUT_OF_MEMORY;
+       }
+
+       snprintf((*ibeacon_info)->uuid, 37, "%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X",
+               manufacturer_data[17], manufacturer_data[16], manufacturer_data[15], manufacturer_data[14],
+               manufacturer_data[13], manufacturer_data[12], manufacturer_data[11], manufacturer_data[10], manufacturer_data[9], manufacturer_data[8],
+               manufacturer_data[7], manufacturer_data[6], manufacturer_data[5], manufacturer_data[4], manufacturer_data[3], manufacturer_data[2]);
+
+       (*ibeacon_info)->major_id = manufacturer_data[19] << 8;
+       (*ibeacon_info)->major_id += manufacturer_data[18];
+
+       (*ibeacon_info)->minor_id = manufacturer_data[21] << 8;
+       (*ibeacon_info)->minor_id += manufacturer_data[20];
+
+       (*ibeacon_info)->measured_power = manufacturer_data[22];
+
+       return BT_ERROR_NONE; /* LCOV_EXCL_STOP */
+}
+
+
 /* LCOV_EXCL_START */
 int bt_adapter_le_create_scan_filter(bt_scan_filter_h *scan_filter)
 {
@@ -3807,6 +3875,42 @@ int bt_adapter_unset_authentication_req_cb(void)
        _bt_unset_cb(BT_EVENT_AUTHENTICATION_REQUEST);
        return BT_ERROR_NONE;
 }
+
+int bt_adapter_le_set_ibeacon_scan_filter(bt_scan_filter_h scan_filter,
+                       const char *data,
+                       unsigned int data_len)
+{
+       bt_le_scan_filter_s *__filter = (bt_le_scan_filter_s *)scan_filter;
+       int ibeacon_manufacturer_id = COMPANY_ID_APPLE;
+
+       BT_CHECK_LE_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(scan_filter);
+
+       BT_INFO("");
+
+       if (data_len > 27) {
+               BT_ERR("INVALID_PARAMETER(0x%08x)",
+                       BT_ERROR_INVALID_PARAMETER); /* LCOV_EXCL_LINE */
+               bt_adapter_le_destroy_scan_filter(scan_filter);
+               return BT_ERROR_INVALID_PARAMETER;
+       }
+       g_free(__filter->manufacturer_data);
+       g_free(__filter->manufacturer_data_mask);
+
+       __filter->manufacturer_id = ibeacon_manufacturer_id;
+       if (data != NULL) {
+               __filter->manufacturer_data = g_memdup(data, data_len);
+               __filter->manufacturer_data_len = data_len;
+       } else {
+               __filter->manufacturer_data = NULL;
+               __filter->manufacturer_data_len = 0;
+       }
+       __filter->manufacturer_data_mask = NULL;
+
+       return BT_ERROR_NONE;
+}
+
 /* LCOV_EXCL_STOP */
 
 int bt_adapter_passkey_reply(char *passkey, bool authentication_reply)
index 2a4717637654f4720778e75e624281c0aaf718b5..e26223d93bcd3cb76b6ae86ec7d1b145fab0ccac 100755 (executable)
@@ -50,6 +50,7 @@ static int __bt_get_bt_adapter_device_discovery_info_s(bt_adapter_device_discove
 static void __bt_free_bt_adapter_device_discovery_info_s(bt_adapter_device_discovery_info_s *discovery_info);
 static int __bt_get_bt_adapter_le_device_scan_info_s(bt_adapter_le_device_scan_result_info_s **scan_info, bluetooth_le_device_info_t *source_info);
 static void __bt_free_bt_adapter_le_device_scan_info_s(bt_adapter_le_device_scan_result_info_s *scan_info);
+
 #if !defined(TIZEN_PROFILE_WEARABLE) && !defined(TIZEN_PROFILE_IVI)
 static int __bt_get_bt_adapter_le_device_discovery_info_s(bt_adapter_le_device_discovery_info_s **le_discovery_info, bluetooth_le_device_info_t *source_info);
 static void __bt_free_bt_adapter_le_device_discovery_info_s(bt_adapter_le_device_discovery_info_s *discovery_info);
@@ -2808,6 +2809,7 @@ static int __bt_get_bt_adapter_le_device_scan_info_s(
        return BT_ERROR_NONE;
 }
 
+
 static void __bt_free_bt_adapter_le_device_scan_info_s(bt_adapter_le_device_scan_result_info_s *scan_info)
 {
        if (scan_info == NULL)
@@ -2824,6 +2826,7 @@ static void __bt_free_bt_adapter_le_device_scan_info_s(bt_adapter_le_device_scan
        free(scan_info);
        scan_info = NULL;
 }
+
 /* LCOV_EXCL_START */
 #if !defined(TIZEN_PROFILE_WEARABLE) && !defined(TIZEN_PROFILE_IVI)
 static int __bt_get_bt_adapter_le_device_discovery_info_s(
index 5c4644e519ac243ff46b649990c06842ea99f198..b61fd162f79712e83e22e4622378a05756fe4d60 100644 (file)
@@ -325,6 +325,8 @@ tc_table_t tc_adapter_le[] = {
                , BT_UNIT_TEST_FUNCTION_ADAPTER_LE_REGISTER_SCAN_FILTER_SERVICE_UUID},
        {"Register scan filter (Service Solicitation UUID)"
                , BT_UNIT_TEST_FUNCTION_ADAPTER_LE_REGISTER_SCAN_FILTER_SERVICE_SOLICITATION_UUID},
+       {"Register iBeaconscan filter (Manufacturer DATA)"
+               , BT_UNIT_TEST_FUNCTION_ADAPTER_LE_REGISTER_SCAN_FILTER_IBEACON_DATA},
        {"Unregister all scan filters"
                , BT_UNIT_TEST_FUNCTION_ADAPTER_LE_UNREGISTER_ALL_SCAN_FILTERS},
 #if !defined(TIZEN_PROFILE_WEARABLE) && !defined(TIZEN_PROFILE_IVI)
@@ -1509,6 +1511,7 @@ static void __bt_adapter_le_scan_result_cb(
                char *manufacturer_data;
                int manufacturer_data_len;
                int count;
+               bt_adapter_ibeacon_scan_result_info_s *ibeacon_info = NULL;
 
                pkt_type += i;
                if (pkt_type == BT_ADAPTER_LE_PACKET_ADVERTISING
@@ -1566,6 +1569,17 @@ static void __bt_adapter_le_scan_result_cb(
                                manufacturer_data[1], manufacturer_data_len);
                        g_free(manufacturer_data);
                }
+               if (bt_adapter_le_get_scan_result_ibeacon_report(info, pkt_type,
+                                                               &ibeacon_info) == BT_ERROR_NONE) {
+                               TC_PRT("APPLE IBEACON");
+                               TC_PRT("Company_id: %d", ibeacon_info->company_id);
+                               TC_PRT("ibeacon_type: %d", ibeacon_info->ibeacon_type);
+                               TC_PRT("uuid: %s", ibeacon_info->uuid);
+                               TC_PRT("major_id: %d", ibeacon_info->major_id);
+                               TC_PRT("minor_id: %d", ibeacon_info->minor_id);
+                               TC_PRT("measured_power: %d", ibeacon_info->measured_power);
+                               bt_adapter_le_free_ibeacon_report(ibeacon_info);
+               }
        }
 }
 
@@ -5445,6 +5459,25 @@ int test_input_callback(void *data)
                        break;
                }
 
+               case BT_UNIT_TEST_FUNCTION_ADAPTER_LE_REGISTER_SCAN_FILTER_IBEACON_DATA: {
+                       bt_scan_filter_h scan_filter;
+                       char manufacture_1[] = {0x02, 0x15, 0xD9, 0xB9, 0xEC, 0x1F, 0x39, 0x25, 0x43, 0xD0, 0x80, 0xA9, 0x1E, 0x39, 0xD4, 0xCE, 0xA9, 0x5C, 0x01, 0x00, 0x0A, 0x00, 0x10};
+
+                       ret = bt_adapter_le_create_scan_filter(&scan_filter);
+                       if (ret != BT_ERROR_NONE)
+                          TC_PRT("failed with [0x%04x]", ret);
+
+                       ret = bt_adapter_le_set_ibeacon_scan_filter(scan_filter, manufacture_1, sizeof(manufacture_1));
+                       if (ret != BT_ERROR_NONE)
+                               TC_PRT("failed with [0x%04x]", ret);
+
+                       ret = bt_adapter_le_register_scan_filter(scan_filter);
+                       if (ret != BT_ERROR_NONE)
+                               TC_PRT("failed with [0x%04x]", ret);
+
+                       break;
+               }
+
                case BT_UNIT_TEST_FUNCTION_ADAPTER_LE_UNREGISTER_ALL_SCAN_FILTERS: {
                        ret = bt_adapter_le_unregister_all_scan_filters();
                        if (ret != BT_ERROR_NONE)
index 87c08c9b84ea70086c0338bae803457a6db6a2be..6e83527f963b91cc7bcf51af5bcfa5b7e746523e 100644 (file)
@@ -126,6 +126,7 @@ typedef enum {
        BT_UNIT_TEST_FUNCTION_ADAPTER_LE_REGISTER_SCAN_FILTER_DEVICE_ADDRESS,
        BT_UNIT_TEST_FUNCTION_ADAPTER_LE_REGISTER_SCAN_FILTER_SERVICE_UUID,
        BT_UNIT_TEST_FUNCTION_ADAPTER_LE_REGISTER_SCAN_FILTER_SERVICE_SOLICITATION_UUID,
+       BT_UNIT_TEST_FUNCTION_ADAPTER_LE_REGISTER_SCAN_FILTER_IBEACON_DATA,
        BT_UNIT_TEST_FUNCTION_ADAPTER_LE_UNREGISTER_ALL_SCAN_FILTERS,
 #ifndef TIZEN_PROFILE_WEARABLE
        BT_UNIT_TEST_FUNCTION_ADAPTER_LE_SET_DEVICE_DISCOVERY_STATE_CHANGED_CB,