在蓝牙通信中,通常情况下,设备之间的交互往往需要通过建立连接来实现,例如ACL连接。然而,“无连接请求的服务(SERVICES WITHOUT CONNECTION REQUEST )” 提供了一种不同的交互方式,它允许设备在不建立完整的、传统意义上的连接的情况下,获取特定的信息或执行某些功能。
远程名称请求服务用于在不需要建立ACL(Asynchronous Connection-Less,异步连接)连接的情况下,查找远程设备的名称。
这种服务模式的优势在于:
主机发送一个 “主机控制器接口设置事件掩码”(HCI_Set_Event_Mask)命令,将 “远程主机支持特性通知事件”(Remote Host Supported Features Notification event)对应的位(第 60 位)置位,同时发送一个 “主机控制器接口远程名称请求”(HCI_Remote_Name_Request)命令,期望其本地设备会自动尝试连接到远程设备。【0x0001】HCI_Set_Event_Mask详解-CSDN博客

在这个步骤中,主机通过配置事件掩码(HCI_Set_Event_Mask)来告诉蓝牙控制器它感兴趣的事件类型,这里特别关注的是远程主机支持的功能通知事件(通常是为了确保蓝牙控制器能够报告关于远程设备能力的信息)。接着,主机发送远程名称请求命令(HCI_Remote_Name_Request),这个命令的目的是获取远程设备的名称,而且这个过程不需要先建立ACL连接。因为蓝牙规范允许在没有完整连接建立的情况下,通过一种称为“page扫描”的机制来查询远程设备的名称。【0x0019】HCI_Remote_Name_Request详解-CSDN博客
需要注意的是,虽然这个服务允许在不建立完整ACL连接的情况下获取远程设备名称,但在实际应用中,如果远程设备设置了隐私模式或者其他安全措施,可能会导致无法成功获取名称。此外,即使成功获取了名称,也不意味着可以立即与远程设备进行数据交换,因为还需要建立ACL连接来进行数据传输。
当设备A与设备B之间不存在ACL连接时,设备A通过寻呼等过程获取设备B的名称;而当ACL连接已经存在时,设备A则直接利用该连接来获取设备B的名称。
如果设备A与设备B之间不存在ACL连接,设备A会对设备B进行寻呼(Paging)。在完成基带寻呼程序后,本地设备(设备A)会尝试获取远程设备(设备B)的扩展功能,发送一个HCI_Remote_Host_Supported_Features_Notification事件,获取远程设备的名称,然后断开连接,并将远程设备的名称返回给主机。

在这个步骤中,详细过程如下:
需要注意的是,这个过程可能受到多种因素的影响,包括远程设备的隐私设置、蓝牙版本和特性支持等。因此,在实际应用中,可能需要考虑这些因素来确保过程的顺利进行。
如果在发出请求时已经存在ACL连接,那么远程名称请求过程将作为一个可选服务来执行。此时,不会进行寻呼操作,也不会断开ACL连接。

在这个步骤中,详细过程如下:
需要注意的是,虽然在这种情况下不需要进行寻呼和断开ACL连接,但仍然需要确保远程设备支持并愿意提供其名称信息。此外,如果远程设备设置了隐私模式或其他安全措施,可能会限制名称的获取。因此,在实际应用中,可能需要考虑这些因素来确保过程的顺利进行。
远程名称请求流程的实现细节涉及到与蓝牙硬件的交互,通常需要使用特定的蓝牙协议栈(如BlueZ、BLuedroid等)或硬件供应商提供的SDK。此外,蓝牙通信的许多方面(如事件处理、回调机制等)通常通过异步方式处理。
下面给一个简化的概念性示例,帮助理解流程。请注意,这个示例不会直接编译或运行,因为它省略了实际的蓝牙协议栈调用和错误处理,而且假设已经有了处理蓝牙事件的机制。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
// 假设这些函数是由蓝牙协议栈提供的,用于处理事件和发送命令
extern void register_event_callback(void (*callback)(uint16_t event, void *data));
extern int send_hci_command(uint16_t opcode, void *data, int len);
extern int get_remote_name(bdaddr_t *bdaddr, char *name, int len);
// 事件回调函数
void handle_event(uint16_t event, void *data) {
// 根据事件类型处理事件
// ...
// 例如,处理远程主机支持特性通知事件
if (event == EVT_REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION) {
// 解析数据并处理
// ...
}
// 或者处理其他事件
// ...
}
// 远程名称请求函数
int remote_name_request(bdaddr_t *bdaddr) {
char name[249]; // 蓝牙名称的最大长度是248个字符加上一个空终止符
// 检查是否存在ACL连接(在实际应用中,这可能需要查询蓝牙协议栈的状态)
// 这里我们假设不存在ACL连接,因此执行步骤2a
int acl_connected = 0; // 0表示未连接,1表示已连接
if (!acl_connected) {
// 执行寻呼、获取扩展功能、获取名称、断开连接等步骤
// 这些步骤在实际中通常是通过异步事件和回调来处理的
// 这里我们简化为一个假设的函数调用
printf("Paging remote device...\n");
// 寻呼过程(在实际中,这是由蓝牙协议栈处理的)
// ...
// 假设我们已经成功获取了名称(在实际中,通常是通过事件回调来完成的)
// 这里我们直接调用一个假设的函数来获取名称
int result = get_remote_name(bdaddr, name, sizeof(name));
if (result == 0) {
printf("Remote device name: %s\n", name);
return 0; // 成功
} else {
printf("Failed to get remote device name\n");
return -1; // 失败
}
} else {
// 如果ACL连接已存在,则直接获取名称
printf("ACL connection exists, getting remote device name...\n");
int result = get_remote_name(bdaddr, name, sizeof(name));
if (result == 0) {
printf("Remote device name: %s\n", name);
return 0; // 成功
} else {
printf("Failed to get remote device name\n");
return -1; // 失败
}
}
}
int main() {
bdaddr_t bdaddr;
str2ba("XX:XX:XX:XX:XX:XX", &bdaddr); // 将蓝牙地址替换为实际的远程设备地址
// 注册事件回调函数
register_event_callback(handle_event);
// 发送远程名称请求
int result = remote_name_request(&bdaddr);
if (result == 0) {
printf("Remote name request succeeded\n");
} else {
printf("Remote name request failed\n");
}
return 0;
}重要说明:
register_event_callback、send_hci_command 和 get_remote_name 函数是假设存在的,需要使用实际使用的蓝牙协议栈或SDK提供的实际函数来替换。为了编写一个完整的、可运行的程序,需要查阅所使用的蓝牙协议栈或SDK的文档,并了解如何正确地与蓝牙硬件进行交互。
获取远程蓝牙设备的名称这一特性在多个应用场景中发挥着重要作用。以下是一些具体的应用场景。
场景描述:在蓝牙设备的初始扫描阶段,如智能手机蓝牙设置中搜索附近设备时,用户希望快速查看并识别周围有哪些蓝牙设备可用。通过远程名称请求服务,手机可以快速获取并展示附近蓝牙设备的名称,如耳机、智能手环、蓝牙音箱等,方便用户选择想要连接的设备。
优势:
场景描述:在企业或机构的物联网环境中,存在大量蓝牙传感器设备,如温度传感器、湿度传感器、人员定位标签等。系统管理员需要定期检查这些设备的工作状态和身份信息。通过远程名称请求服务,可以在不建立数据传输连接的情况下,快速获取设备名称,进行设备清单核对和状态监控。
优势:
场景描述:在对安全要求较高的蓝牙应用场景中,如金融机构的蓝牙支付终端或企业的安全门禁系统,系统需要在允许设备进行深入连接之前进行身份验证。通过远程名称请求服务,系统可以获取设备名称,并与预先授权的设备名单进行比对,只有名称匹配的设备才会被允许进行后续的连接和操作。
优势:
场景描述:在蓝牙广播应用场景中,如商场的室内定位系统或基于蓝牙的广告推送系统,广播设备需要获取周围接收设备的名称,以便根据设备类型或用户自定义名称进行有针对性的信息推送。
优势:
场景描述:在社交或互动应用中,用户希望查找并连接附近的蓝牙设备以进行数据传输、游戏互动或共享资源。通过远程名称请求服务,用户可以快速识别并连接目标设备,提高应用的互动性和便捷性。
优势:
场景描述:在智能家居或物联网环境中,设备之间需要相互识别以进行协同工作。通过远程名称请求服务,设备可以快速获取其他设备的名称,建立正确的通信关系和协作机制。
优势:
场景描述:在蓝牙设备的调试和测试过程中,工程师需要频繁地查找和识别设备名称。通过远程名称请求服务,工程师可以简化这一过程,提高调试和测试的效率。
优势:
远程名称请求服务在蓝牙技术的多个应用领域中都发挥着重要作用,随着蓝牙技术的不断发展和普及,其应用场景还将不断拓展和深化。
一次性查询(One-time Inquiry)是用于检测和收集附近蓝牙设备的一种机制。在蓝牙通信中,当一个设备(通常称为主机或查询设备)想要发现其通信范围内的其他蓝牙设备时,它会执行一次性查询操作。这个过程不涉及建立完整的连接,而是简单地扫描并收集附近设备的地址和名称等信息。
在这一步中,主机(即执行查询的设备)通过其蓝牙控制器接口(HCI)发送一个 HCI_Inquiry 命令。这个命令包含了查询的一些参数,如查询的持续时间、需要返回的响应数量(即最大设备数)、以及是否请求远程设备的名称等。

发送 HCI_Inquiry 是整个设备发现过程的起始动作,类似于我们在一个房间里大声询问 “有谁在呀”,周边能听到这个询问并且愿意回应的设备(在蓝牙语境下就是那些设置为可被发现的蓝牙设备)就会接收到这个命令,并根据自身的配置和状态决定是否以及如何做出回应。
蓝牙控制器会根据指定的查询访问码(Inquiry Access Code, IAC)和查询时长(Inquiry Length)来启动基带查询(Baseband Inquiry)过程。这个过程是蓝牙协议栈中基带层(Baseband Layer)的一部分,负责实际扫描和发现附近的蓝牙设备。
当控制器启动基带查询过程后,会开始监听来自附近蓝牙设备的查询响应。这些响应包含了设备的地址、类别以及其他可能的信息(如设备名称的哈希值,如果设备支持的话)。

蓝牙控制器根据指定的查询访问码和查询长度来启动基带查询过程,并监听来自附近设备的查询响应。一旦接收到响应,控制器就会提取出所需的信息,并通过HCI_Inquiry_Result事件将这些信息返回给主机进行处理。
在某些情况下,主机可能希望提前终止查询过程,这时可以使用HCI_Inquiry_Cancel命令。该命令会立即停止蓝牙控制器的查询程序,避免不必要的资源占用和后续操作的干扰。另一方面,当查询过程因为获取到的设备信息数量满足要求或查询时长到期而完成时,蓝牙系统会返回一个HCI_Inquiry_Complete事件给主机。主机接收到这个事件后,就知道查询操作已经结束,并可以根据此事件来决定后续的操作,如筛选设备信息、发起配对连接等。这些机制确保了蓝牙查询过程的高效性和灵活性。
HCI_Inquiry_Cancel在某些情况下,主机可能由于各种原因(比如已经找到了想要连接的设备、不再需要继续搜索其他设备、系统资源紧张等)希望提前终止这个查询过程,可以使用 HCI_Inquiry_Cancel 命令。

当主机向蓝牙控制器发送这个命令后,蓝牙控制器会接收到指令并立即停止正在进行的查询程序,停止向周围发送查询请求以及处理查询响应等相关操作,使得整个查询过程能够快速、干净地结束,避免不必要的资源占用和对后续操作可能产生的干扰。并可能通过HCI层返回一个命令完成事件,以确认查询已被取消。【0x0002】HCI_Inquiry_Cancel命令详解-CSDN博客
HCI_Inquiry_Complete事件当查询过程因为以下两个原因之一而完成时:
当满足上述两种结束条件中的任意一种时,蓝牙系统会返回一个 “HCI_Inquiry_Complete” 事件给主机。【0x01】HCI_Inquiry_Complete事件详解-CSDN博客

主机接收到这个事件后,就知道查询操作已经结束。它可以根据这个事件来决定后续的操作,比如开始对获取到的设备信息进行筛选、发起配对连接等操作。
下面的代码示例是一个高度简化的版本,旨在展示基本流程而非实际可用的代码。请注意,下面的代码示例并非实际可运行的代码,而是用于说明如何组织这样的查询过程。实际实现将依赖于特定的蓝牙库和硬件平台。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
// 假设这是蓝牙库提供的函数原型(这些函数在实际中是不存在的,仅用于说明)
void hci_send_inquiry_command(uint8_t duration, uint8_t max_devices, bool request_names);
void hci_cancel_inquiry_command(void);
void hci_event_callback(void *callback_data, uint8_t event_code, uint8_t *event_data, uint16_t data_length);
// 假设的回调函数数据结构体
typedef struct {
bool inquiry_complete;
// 其他可能需要的数据
} CallbackData;
// 回调函数,用于处理来自HCI层的事件
void handle_hci_event(void *callback_data, uint8_t event_code, uint8_t *event_data, uint16_t data_length) {
CallbackData *cb_data = (CallbackData *)callback_data;
switch (event_code) {
case HCI_INQUIRY_RESULT_EVENT: // 假设这是HCI_Inquiry_Result事件的代码
// 处理查询结果事件,解析event_data
// ...
break;
case HCI_INQUIRY_COMPLETE_EVENT: // 假设这是HCI_Inquiry_Complete事件的代码
cb_data->inquiry_complete = true;
// 查询完成,可以在这里执行后续操作
printf("Inquiry complete.\n");
break;
// 其他事件处理...
default:
// 未知事件
break;
}
}
int main() {
CallbackData cb_data = {false};
// 注册回调函数(在实际实现中,通常是通过某种形式的注册机制完成的)
// hci_register_event_callback(handle_hci_event, &cb_data);
// 发送查询命令
hci_send_inquiry_command(8, 10, true); // 例如:查询持续时间为8 * 1.25秒,最大设备数为10,请求名称
// 在这里,通常会有一个循环来等待事件回调
// 由于这是一个简化的示例,我们将使用一个简单的忙等待循环
while (!cb_data.inquiry_complete) {
// 在实际实现中,这里应该有一个事件循环或者等待机制
// 例如:使用select()、poll()、epoll()等,或者库提供的事件等待函数
// 在这里什么也不做,只是模拟等待回调
}
// 查询完成后的后续操作
// ...
return 0;
}
// 假设的蓝牙库函数实现(在实际中,这些函数是由蓝牙协议栈或芯片制造商提供的)
// 这里只是占位符,不会实际执行任何操作
void hci_send_inquiry_command(uint8_t duration, uint8_t max_devices, bool request_names) {
// 发送HCI查询命令的实现
// ...
}
void hci_cancel_inquiry_command(void) {
// 取消HCI查询命令的实现
// ...
}
void hci_event_callback(void *callback_data, uint8_t event_code, uint8_t *event_data, uint16_t data_length) {
// 实际上,这个函数应该由蓝牙库调用,而不是在这里调用
// 它只是用来模拟回调机制
handle_hci_event(callback_data, event_code, event_data, data_length);
}hci_send_inquiry_command、hci_cancel_inquiry_command和hci_event_callback函数。此外,由于蓝牙协议栈的复杂性和不同平台之间的差异,实际代码可能会更加复杂,并且需要深入了解蓝牙规范和特定平台的API文档。
HCI_Inquiry是蓝牙技术中的一个重要环节,主要用于发现和搜集附近的蓝牙设备。以下是HCI_Inquiry的主要使用场景。
场景描述:当用户需要将新的蓝牙设备(如耳机、音箱等)与手机或其他蓝牙设备进行配对时,会启动蓝牙设备搜索过程。这一过程依赖于HCI_Inquiry命令,它允许设备主动发送查询请求,以发现和识别附近的蓝牙设备。
优势:
场景描述:在物联网环境中,如智能家居系统部署时,智能网关需要连接多个蓝牙传感器设备。通过发送HCI_Inquiry命令,智能网关可以快速找到并连接这些传感器设备,如温度传感器、门窗传感器等。
优势:
场景描述:在企业或机构中管理大量蓝牙设备时,需要定期检查设备的连接状态和可用性。通过发送HCI_Inquiry命令,管理员可以快速检查设备的存在性和基本状态,如蓝牙打印机、蓝牙扫描枪等。
优势:
场景描述:蓝牙设备软件开发人员在开发和测试过程中,需要频繁查找和连接不同的蓝牙设备来验证软件功能。通过发送HCI_Inquiry命令,开发人员可以快速找到并连接测试设备,如运动手环等。
优势:
场景描述:在某些情况下,HCI_Inquiry还可以用于设备认证过程,通过比较搜索到的设备信息与已知的、受信任的设备信息库中的条目,验证设备的身份和合法性。同时,用户也需要注意隐私保护问题,可以在不需要时关闭蓝牙设备的可发现性模式或限制搜索范围。
优势:
HCI_Inquiry在蓝牙技术中具有广泛的应用场景,涵盖了设备配对与连接、物联网设备部署与连接、蓝牙设备维护与管理、蓝牙设备应用开发与测试以及安全性与隐私保护等多个方面。通过合理使用HCI_Inquiry命令,用户可以更高效地管理蓝牙设备,提升使用体验。
“Periodic inquiry” 是在蓝牙通信场景中,当需要周期性地重复执行查询(inquiry)程序时所采用的一种机制。通过这种方式,主机能够按照一定的时间间隔不断地去搜索周围可连接的蓝牙设备,以获取最新的设备信息或者查找新出现的可连接设备等,适用于一些需要持续监控周边蓝牙设备状态变化的应用场景,比如在某些蓝牙设备管理系统、动态发现新设备的应用中会用到。
当主机希望蓝牙设备以周期性的方式执行查询操作时,它会向蓝牙控制器发送一个HCI_Periodic_Inquiry_Mode命令。这个命令的目的是告诉蓝牙控制器启动周期性查询模式,并按照预设的参数(如查询间隔、查询窗口大小、需要查找的设备类型等)来执行查询。

周期性查询模式在需要持续监控蓝牙设备环境的应用场景中非常有用,比如蓝牙音箱、蓝牙耳机等需要随时准备与其他蓝牙设备建立连接的设备。通过周期性查询,这些设备可以及时发现并响应其他设备的连接请求,从而提供更好的用户体验。
需要注意的是,周期性查询会消耗一定的系统资源,因此在实际应用中需要根据具体需求来合理设置查询参数,以平衡资源消耗和查询效率之间的关系。
一旦蓝牙控制器接收到HCI_Periodic_Inquiry_Mode命令并确认无误,就会开始按照指定的参数执行周期性查询。在查询周期内,控制器会不断向周围发送查询请求,并处理接收到的查询响应。每当发现新的蓝牙设备或更新现有设备的信息时,控制器都会向主机返回一个或多个HCI_Inquiry_Result事件。这些事件包含了发现设备的详细信息,如设备地址、设备名称、设备类型等。

当当前周期性查询周期结束时,无论是否发现了新的设备,蓝牙控制器都会向主机返回一个HCI_Inquiry_Complete事件。这个事件标志着当前查询周期的结束,并允许主机根据查询结果进行后续操作,如选择设备进行连接等。

如果主机希望停止周期性查询,可以发送HCI_Exit_Periodic_Inquiry_Mode命令给蓝牙控制器。一旦接收到此命令,控制器将停止当前的周期性查询模式,并准备接收其他命令。

以下是一个简化代码示例,用于展示如何实现蓝牙周期性查询。请注意,这只是一个示例,并非完整的蓝牙应用程序代码。在实际应用中,需要与蓝牙协议栈(如BlueZ、bluedroid等)进行交互,并且需要处理更多的错误检查和状态管理。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
// 假设这些是蓝牙HCI命令和事件的伪定义,实际使用时需要替换为实际的蓝牙栈API
#define HCI_PERIODIC_INQUIRY_MODE 0x0043
#define HCI_EXIT_PERIODIC_INQUIRY_MODE 0x0044
#define HCI_INQUIRY_RESULT 0x02
#define HCI_INQUIRY_COMPLETE 0x01
// 假设的蓝牙设备地址结构
typedef struct {
uint8_t bd_addr[6];
} bd_addr_t;
// 假设的HCI命令结构
typedef struct {
uint16_t opcode;
uint8_t param_len;
// 周期性查询参数(示例中未详细列出)
// ...
} hci_command_t;
// 假设的HCI事件结构
typedef struct {
uint8_t evt;
uint8_t plen;
// 事件数据(示例中未详细列出)
// ...
} hci_event_t;
// 发送HCI命令的伪函数(实际使用时需要替换为与蓝牙协议栈交互的函数)
void send_hci_command(const hci_command_t *command) {
// 发送HCI命令到蓝牙控制器(示例代码省略实现细节)
printf("Sending HCI command: opcode=0x%04X\n", command->opcode);
}
// 处理HCI事件的伪函数(实际使用时需要替换为处理蓝牙栈事件的函数)
void handle_hci_event(const hci_event_t *event) {
switch (event->evt) {
case HCI_INQUIRY_RESULT:
// 处理查询结果事件(示例代码省略实现细节)
printf("Received HCI Inquiry Result\n");
break;
case HCI_INQUIRY_COMPLETE:
// 处理查询完成事件(示例代码省略实现细节)
printf("Received HCI Inquiry Complete\n");
break;
// 处理其他事件...
default:
printf("Received unknown HCI event: evt=0x%02X\n", event->evt);
break;
}
}
// 周期性查询的主函数
void periodic_inquiry(uint16_t interval, uint16_t window, uint8_t length) {
// 构建HCI周期性查询模式命令
hci_command_t periodic_inquiry_command = {
.opcode = HCI_PERIODIC_INQUIRY_MODE,
.param_len = // 设置参数长度(根据实际需要填写)
// .param = // 设置查询参数(如interval, window, length等,示例中省略)
};
// 发送周期性查询模式命令
send_hci_command(&periodic_inquiry_command);
// 模拟周期性查询过程(实际使用时需要等待蓝牙控制器的响应)
while (1) {
// 在这里可以添加代码来处理其他任务或检查是否应该停止查询
// 假设接收到一个HCI事件(在实际应用中,这通常是通过回调函数或事件循环来实现的)
hci_event_t event;
// ...(从蓝牙控制器获取事件并填充到event结构中)
// 处理接收到的HCI事件
handle_hci_event(&event);
// 如果接收到查询完成事件且需要停止查询,则跳出循环
if (event.evt == HCI_INQUIRY_COMPLETE && /* 其他停止条件 */) {
break;
}
// 根据interval和window参数模拟等待时间(实际使用时应该使用定时器)
sleep(interval / 1000); // 注意:这里假设interval的单位是毫秒,实际使用时需要转换
}
// 构建并发送HCI退出周期性查询模式命令
hci_command_t exit_periodic_inquiry_command = {
.opcode = HCI_EXIT_PERIODIC_INQUIRY_MODE,
.param_len = 0 // 通常退出命令没有参数
};
// 发送退出周期性查询模式命令
send_hci_command(&exit_periodic_inquiry_command);
}
int main() {
// 设置周期性查询的参数(示例值)
uint16_t interval = 1280; // 查询间隔(单位:1.25ms)
uint16_t window = 11250; // 查询窗口大小(单位:1.25ms,通常设置为小于或等于interval的倍数)
uint8_t length = 8; // 查询响应的最大设备数
// 启动周期性查询
periodic_inquiry(interval, window, length);
return 0;
}注意:
send_hci_command和handle_hci_event函数是伪函数,需要替换为实际蓝牙协议栈交互的实际函数。
sleep函数用于模拟等待时间,但在实际应用中,应该使用定时器来更精确地控制查询间隔和窗口大小。
interval, window, length)是示例值,需要根据实际应用需求进行调整。
周期性查询(Periodic Inquiry)在多个领域和场景中都有广泛的应用,以下是一些典型的应用和场景。
周期性查询在多个领域和场景中都有广泛的应用和重要的价值。通过定期查询和分析数据,企业、科研机构和个人可以更好地了解市场动态、设备状态、业务趋势等关键信息,从而做出更加明智的决策和行动。
综上所述,“SERVICES WITHOUT CONNECTION REQUEST” 即无连接请求的服务在蓝牙通信中具有重要的作用和广泛的应用前景。通过这种服务模式,可以在不建立完整连接的情况下,实现设备之间的信息获取和交互,提高系统的效率、灵活性和安全性。随着技术的不断发展,无连接请求的服务将不断完善和创新,为蓝牙通信和物联网应用带来更多的价值。