# beacon **Repository Path**: leconiot/beacon ## Basic Information - **Project Name**: beacon - **Description**: CC2640R2F 连接beacon 实现。可以通过连接配置beacon广播内容,支持大数据读写。 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2018-04-06 - **Last Updated**: 2022-01-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Beacon 嵌入式端设计说明 ## 使用说明 * 下载[simplelink_cc2640r2_sdk_1_40_00_45.exe](http://www.ti.com/tool/ble-stack) sdk,默认安装。 > **提示**:初始环境搭建可以参考[CC2640R2 BLE5.0 开发环境搭建](http://docs.leconiot.com/doku.php?id=cc2640r2f:get_started:development_environment_set_up:development_environment_set_up)。 * Clone 工程默认,解压SDK 安装根目录的同级目录。 ## Beacon 数据 对于Beacon的广播数据分布放在广播数据[AdvData](#AdvData)和扫描回复的[ScanRspData](#ScanRspData)。关于广播和扫描可以详细阅读[GAP](http://docs.leconiot.com/doku.php?id=cc2640r2f:ble_stack_app:stack:gap:gap) ,对于Beacon的数据结构设计参考阅读[Bluetooth® low energy Beacons](http://www.ti.com/lit/an/swra475a/swra475a.pdf) ### AdvData ```c // Advertisement data (max size = 31 bytes, though this is // best kept short to conserve power while advertising) static uint8_t advertData[] = { // Flags: this field sets the device to use general discoverable // mode (advertises indefinitely) instead of general // discoverable mode (advertise for 30 seconds at a time) 0x02, // length of this data GAP_ADTYPE_FLAGS, DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED, //!< Tx power level (BEACON_POWER_SIZE+1), // length of this data GAP_ADTYPE_POWER_LEVEL, 0, // 0dBm //!< 128bit-UUID (BEACON_UUID_SIZE+1), GAP_ADTYPE_SERVICE_DATA_128BIT, 0x00, // UUID - Variable based on different use cases/applications 0x00, // UUID 0x00, // UUID 0x00, // UUID 0x00, // UUID 0x00, // UUID 0x00, // UUID 0x00, // UUID 0x00, // UUID 0x00, // UUID 0x00, // UUID 0x00, // UUID 0x00, // UUID 0x00, // UUID 0x00, // UUID 0x00, // UUID //!< Major and Minor (BEACON_MAJOR_SIZE+BEACON_MINOR_SIZE+1), GAP_ADTYPE_MANUFACTURER_SPECIFIC, 0x00, // Major 0x01, // Major 0x00, // Minor 0x01, // Minor }; ``` ### ScanRspData ```c // Scan response data (max size = 31 bytes) static uint8_t scanRspData[BEACON_NAME_SIZE+BEACON_PASSWORD_SIZE+4] = { // complete name (BEACON_NAME_SIZE+1), // length of this data GAP_ADTYPE_LOCAL_NAME_COMPLETE, 'L', 'e', 'c', 'o', 'n', 'i', 'o', 't', '-', 'B', 'a', 'c', 'o', 'n', '0', //!< 最后三位数做随机数 '0', '1', '\0', '\0', '\0', //!< 这里做一个伪密码 (BEACON_PASSWORD_SIZE+1), GAP_ADTYPE_SIMPLE_PAIRING_HASHC_256, '0', '1', '2', '3', '4', '5', }; ``` ## 特征值 一共设计9个特诊值用以分别用以beacon信息和数据存储。详细实现参考`beacon_gatt_profile.c/h ` | 特诊值 | UID | 长度 | 说明 | 属性 | | -------------------------- | ------ | ---- | ------------------- | -------- | | BEACON_PROFILE_NAME | 0xFFF1 | 20 | 广播名字 | 读、写 | | BEACON_PROFILE_MAJOR | 0xFFF2 | 2 | Major | 读、写 | | BEACON_PROFILE_MINOR | 0xFFF3 | 2 | Minor | 读、写 | | BEACON_PROFILE_INTERVAL | 0xFFF4 | 4 | 广播间隔 | 读、写 | | BEACON_PROFILE_POWER_LEVEL | 0xFFF5 | 1 | 输出功率 | 读、写 | | BEACON_PROFILE_LONG_UUID | 0xFFF6 | 16 | UUID | 读、写 | | BEACON_PROFILE_PASSWORD | 0xFFF7 | 6 | 6位数密码 | 读、写 | | BEACON_PROFILE_DATA_TX | 0xFFF8 | 20 | 数据传输(相对App) | 读、写 | | BEACON_PROFILE_DATA_RX | 0xFFF9 | 20 | 数据接收(相对App) | 读、通知 | ## 数据存储 这里使用的Flash作为[NVS](file:///C:/ti/simplelink_cc2640r2_sdk_1_40_00_45/docs/tidrivers/doxygen/html/_n_v_s_8h.html#aae7abe0cb889a6d0cc1858bfc69ab7e0)存储,受Flash物理特性影响,不建议反复擦出和写入数据。这里设计到最大**2000**字节的数据读写,而最大特诊值长度限制在`ATT_MTU`为**20**字节,所以需要数据拆包和组包发送接收。 以下数据Android App 对数据读写UML序列图。 ![数据交互](images/uml_image.png) 对于数据读写,这里采用两个20字节长度的特诊值操作,其中`BEACON_PROFILE_DATA_TX`用以Android App到 Beacon Device 的数据发送,`BEACON_PROFILE_DATA_RX`用以 Android App 接收。 > **提示**:TX和RX 方向都是相对于Android App。 因为涉及拆包和组包,所以对于20字节的特诊值这里需要组装,因为定长协议,所以这里直接采用`TLV`格式。对于`Type`,如下枚举变量。 ```c typedef enum { TYPE_READ=0, //!< 读取数据 TYPE_READ_CNT, //!< 读取数据长度 TYPE_READ_ERROR, //!< 读取数据错误 TYPE_WRITE, //!< 写入数据 TYPE_WRITE_CNT, //!< 写入数据长度 TYPE_WRITE_ERROR, //!< 写入数据错误 TYPE_WRITE_REPEAT, //!< 重复写入数据 TYPE_CLEAR, //!< 清除保存的数据 TYPE_ACK, //!< 应答数据 } BeaconDataType_t; ``` `Length` 为有效数据长度,不包括`Type`,和`Length`,最大长度为18字节。 而对于`TYPE_READ`和`TYPE_WRITE` 类型 `Value`第一字节表示数据长度相对17字节的索引。 > **提示**: 这里的17字节为出去`Type`、`Length`、`Index`后数据长度。所以如果`TYPE_READ`和`TYPE_WRITE` 单词最大操作17字节,例如发送50字节,需要分3次发送,所以`Index`分别为0、1、2。 ## API * 修改Beacon数据只需要直接修改广播数据[AdvData](#AdvData)和扫描回复的[ScanRspData](#ScanRspData) 数据变量; * 读特诊值 ```c // beacon_gatt_profile.c Line.622 /********************************************************************* * @fn BeaconProfile_GetParameter * * @brief Get a Simple Profile parameter. * * @param param - Profile parameter ID * @param value - pointer to data to put. This is dependent on * the parameter ID and WILL be cast to the appropriate * data type (example: data type of uint16 will be cast to * uint16 pointer). * * @return bStatus_t */ bStatus_t BeaconProfile_GetParameter( uint8 param, void *value ) ``` * 写特征值 ```c // beacon_gatt_profile.c Line.520 /********************************************************************* * @fn BeaconProfile_SetParameter * * @brief Set a Simple Profile parameter. * * @param param - Profile parameter ID * @param len - length of data to write * @param value - pointer to data to write. This is dependent on * the parameter ID and WILL be cast to the appropriate * data type (example: data type of uint16 will be cast to * uint16 pointer). * * @return bStatus_t */ bStatus_t BeaconProfile_SetParameter( uint8 param, uint8 len, void *value ) ‘ ``` * 特征值改变通知 ```c //beacon_peripheral.c Line.1333 /********************************************************************* * @fn BeaconPeripheral_processCharValueChangeEvt * * @brief Process a pending Simple Profile characteristic value change * event. * * @param paramID - parameter ID of the value that was changed. * * @return None. */ static void BeaconPeripheral_processCharValueChangeEvt(uint8_t paramID); ``` * [NVS](file:///C:/ti/simplelink_cc2640r2_sdk_1_40_00_45/docs/tidrivers/doxygen/html/_n_v_s_8h.html#aae7abe0cb889a6d0cc1858bfc69ab7e0)操作数据 详细参考TI [NVS](file:///C:/ti/simplelink_cc2640r2_sdk_1_40_00_45/docs/tidrivers/doxygen/html/_n_v_s_8h.html#aae7abe0cb889a6d0cc1858bfc69ab7e0)驱动。