From: h.sandeep Date: Wed, 5 Oct 2016 04:43:24 +0000 (+0530) Subject: iBeacon: Add API to register iBeacon scan filter. X-Git-Tag: submit/tizen/20161117.015745~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a2ad0e596dcdff27a185084ab484f7d4b3fc620f;p=platform%2Fcore%2Fapi%2Fbluetooth.git iBeacon: Add API to register iBeacon scan filter. 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 --- diff --git a/include/bluetooth_private.h b/include/bluetooth_private.h index f2c61f0..5c51fa4 100644 --- a/include/bluetooth_private.h +++ b/include/bluetooth_private.h @@ -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 diff --git a/include/mobile/bluetooth_internal.h b/include/mobile/bluetooth_internal.h index 528264e..66b7069 100644 --- a/include/mobile/bluetooth_internal.h +++ b/include/mobile/bluetooth_internal.h @@ -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); + /** * @} */ diff --git a/include/mobile/bluetooth_type.h b/include/mobile/bluetooth_type.h index 0bd2741..c49bc70 100644 --- a/include/mobile/bluetooth_type.h +++ b/include/mobile/bluetooth_type.h @@ -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 diff --git a/include/tv/bluetooth_internal.h b/include/tv/bluetooth_internal.h index 528264e..66b7069 100644 --- a/include/tv/bluetooth_internal.h +++ b/include/tv/bluetooth_internal.h @@ -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); + /** * @} */ diff --git a/include/tv/bluetooth_type.h b/include/tv/bluetooth_type.h index f0b495a..d4af7a9 100644 --- a/include/tv/bluetooth_type.h +++ b/include/tv/bluetooth_type.h @@ -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 diff --git a/include/wearable/bluetooth_internal.h b/include/wearable/bluetooth_internal.h index 0d7f046..6a99d86 100644 --- a/include/wearable/bluetooth_internal.h +++ b/include/wearable/bluetooth_internal.h @@ -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); + /** * @} */ diff --git a/include/wearable/bluetooth_type.h b/include/wearable/bluetooth_type.h index 2bb7859..aa675e7 100644 --- a/include/wearable/bluetooth_type.h +++ b/include/wearable/bluetooth_type.h @@ -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. diff --git a/src/bluetooth-adapter.c b/src/bluetooth-adapter.c index f46e1d2..72f515e 100644 --- a/src/bluetooth-adapter.c +++ b/src/bluetooth-adapter.c @@ -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) diff --git a/src/bluetooth-common.c b/src/bluetooth-common.c index 2a47176..e26223d 100755 --- a/src/bluetooth-common.c +++ b/src/bluetooth-common.c @@ -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( diff --git a/test/bt_unit_test.c b/test/bt_unit_test.c index 5c4644e..b61fd16 100644 --- a/test/bt_unit_test.c +++ b/test/bt_unit_test.c @@ -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) diff --git a/test/bt_unit_test.h b/test/bt_unit_test.h index 87c08c9..6e83527 100644 --- a/test/bt_unit_test.h +++ b/test/bt_unit_test.h @@ -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,