SDK版本:nRF5_SDK_15.0.0app
芯片:nRF52832-QFAAide
iBeacon的核心就是廣播,不須要進行鏈接,經過在廣播包中插入信息而後廣播出去。ui
廣播數據包最多僅能夠包含31字節數據,因此設計者必須慎重選擇須要包含的數據。藍牙SIG組織在Core Specification Supplement (CSS)文件中將這31個字節數據分紅多個AD Type結構,每一個AD Type都有相同的結構,分別爲長度字節,類型字節以及數據域。
Beacon設備能夠在一個或多個標準廣播數據包中編碼數據,傳遞信息。可是編碼原理可能有所差別,即幀格式不一樣。目前主流的三種幀格式分別爲蘋果公司的iBeacon,Radius Networks公司的AltBeacon以及谷歌公司的Eddystone。
所以爲了與不一樣的beacon設備進行交互,應用開發者在開發beacon應用時須要瞭解對應設備的幀格式。this
AD Field Length 表示 advertisement data的長度,即廣播包有用信息的總長度;編碼
Type 廣播類型spa
Company ID 廠商數據字段的數據域前2字節爲公司識別碼。由藍牙SIG組織分配給各公司,指示後續數據的解碼方式。在上圖中,0x004C爲蘋果公司的ID。設計
0x02 指明該設備爲「proximity beacon」,該值在iBeacon設備中均爲0x02。code
UUID指明擁有該beacon設備的機構。orm
Major 和 Minor 主次字段用來編碼位置信息,一般主字段指明某個建築,而次字段指明在這棟建築中的特定位置。例如「倫敦中心商場,運動產品區」。blog
Tx Power 發送功率字段幫助應用進行距離估算。
有關iBeacon的詳細內容能夠參考Getting started with iBeacon
#if (GNT_IBEACON_EN) #define APP_BEACON_INFO_LENGTH 0x17 /**< Total length of information advertised by the Beacon. */ #define APP_ADV_DATA_LENGTH 0x15 /**< Length of manufacturer specific data in the advertisement. */ #define APP_DEVICE_TYPE 0x02 /**< 0x02 refers to Beacon. */ #define APP_MEASURED_RSSI 0xC3 /**< The Beacon's measured RSSI at 1 meter distance in dBm. */ #define APP_COMPANY_IDENTIFIER 0x0059 /**< Company identifier for Nordic Semiconductor ASA. as per www.bluetooth.org. */ #define APP_MAJOR_VALUE 0x01, 0x02 /**< Major value used to identify Beacons. */ #define APP_MINOR_VALUE 0x03, 0x04 /**< Minor value used to identify Beacons. */ #define APP_BEACON_UUID 0x01, 0x12, 0x23, 0x34, \ 0x45, 0x56, 0x67, 0x78, \ 0x89, 0x9a, 0xab, 0xbc, \ 0xcd, 0xde, 0xef, 0xf0 /**< Proprietary UUID for Beacon. */ #define MAJ_VAL_OFFSET_IN_BEACON_INFO 18 /**< Position of the MSB of the Major Value in m_beacon_info array. */ #define UICR_ADDRESS 0x10001080 /**< Address of the UICR register used by this example. The major and minor versions to be encoded into the advertising data will be picked up from this location. */ static uint8_t m_beacon_info[APP_BEACON_INFO_LENGTH] = /**< Information advertised by the Beacon. */ { APP_DEVICE_TYPE, // Manufacturer specific information. Specifies the device type in this // implementation. APP_ADV_DATA_LENGTH, // Manufacturer specific information. Specifies the length of the // manufacturer specific data in this implementation. APP_BEACON_UUID, // 128 bit UUID value. APP_MAJOR_VALUE, // Major arbitrary value that can be used to distinguish between Beacons. APP_MINOR_VALUE, // Minor arbitrary value that can be used to distinguish between Beacons. APP_MEASURED_RSSI // Manufacturer specific information. The Beacon's measured TX power in // this implementation. }; #endif /**@brief Function for initializing the Advertising functionality. */ static void advertising_init(void) { ret_code_t err_code; ble_advertising_init_t init; memset(&init, 0, sizeof(init)); // 使用iBeacon廣播,因爲廣播包長度須要控制好,部分信息可放置到廣播應答包中 #if (GNT_IBEACON_EN) ble_advdata_manuf_data_t manuf_specific_data; //廠商自定義信息 manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER; //廠商ID uint16_t major_value = (uint16_t)((UICR_ADDRESS & 0xFFFF0000) >> 16); uint16_t minor_value = (uint16_t)(UICR_ADDRESS & 0x0000FFFF); uint8_t index = MAJ_VAL_OFFSET_IN_BEACON_INFO; m_beacon_info[index++] = MSB_16(major_value); m_beacon_info[index++] = LSB_16(major_value); m_beacon_info[index++] = MSB_16(minor_value); m_beacon_info[index++] = LSB_16(minor_value); NRF_LOG_HEXDUMP_INFO(m_beacon_info, APP_BEACON_INFO_LENGTH); manuf_specific_data.data.p_data = (uint8_t *) m_beacon_info; manuf_specific_data.data.size = APP_BEACON_INFO_LENGTH; init.advdata.p_manuf_specific_data = &manuf_specific_data; #endif //注意advdata長度不能超過 BLE_GAP_ADV_SET_DATA_SIZE_MAX (31) init.advdata.name_type = BLE_ADVDATA_NO_NAME; //廣播iBeacon信息,長度有限 --廣播時的名稱顯示類型(全名)BLE_ADVDATA_FULL_NAME // init.advdata.include_appearance = true; //是否須要圖標 init.advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; //藍牙設備普通發現模式 BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE // init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]); //廣播UUID // init.advdata.uuids_complete.p_uuids = m_adv_uuids; // init.advdata.p_tx_power_level = &tx_power_level; //設置發射功率 init.srdata.name_type = BLE_ADVDATA_FULL_NAME; init.config.ble_adv_fast_enabled = true; //快速廣播使能 init.config.ble_adv_fast_interval = APP_FAST_ADV_INTERVAL; //快速廣播間隔 30ms init.config.ble_adv_fast_timeout = APP_FAST_ADV_DURATION; //默認快速廣播超時 20s init.config.ble_adv_slow_enabled = true; //慢速廣播使能 init.config.ble_adv_slow_interval = APP_SLOW_ADV_INTERVAL; //慢速廣播間隔 200ms // init.config.ble_adv_slow_timeout = APP_SLOW_ADV_DURATION; //默認慢速廣播超時 40s if(nrf_gpio_pin_read(USBVIN_CHECK) == 1) //USB插入 { gnt_led_indication_set(LED_USB_IN); g_gnt_info.gnt_usbvin_flag = 1; init.config.ble_adv_slow_timeout = 0; } else { gnt_led_indication_set(LED_USB_OUT); g_gnt_info.gnt_usbvin_flag = 0; init.config.ble_adv_slow_timeout = APP_SLOW_ADV_DURATION; //默認慢速廣播超時 40s } init.evt_handler = on_adv_evt; err_code = ble_advertising_init(&m_advertising, &init); APP_ERROR_CHECK(err_code); ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG); }