自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(336)
  • 收藏
  • 关注

原创 Android

如今的社会已经从IT时代过渡到了DT时代,数据的重要性不言而喻。将数据安全快速的传输给对方是一件非常重要的事情,如今诞生了很多不同的传输技术,每一种传输技术都是为了和对方进行数据交互。BLE技术也是这样,它的最终目的就是为了在两个设备间进行数据交互。我们从BLE的本质出发,搞清楚它是如何实现数据交互的,也就真正搞清楚了BLE的工作原理。下面从3个方面,逐步讲解BLE的数据收发过程。本文结合nordic的代码和蓝牙核心规范5.2来进行介绍。

2024-03-20 08:34:41 379

原创 Android

Host(纯软件的概念) (跟医院的功能简单类比)GAP: Generic Access Profile, 通用访问规范 (大堂: 按指定流程确定科室、挂号 发现设备、连接设备)GATT: Generic Attribute Profile, 通用属性规范 (医务室: 为病人提供服务 也是提供服务, 有哪些服务, 服务由哪些属性组成)

2024-02-25 19:09:15 820

原创 Android

在来电时,穿戴设备蓝牙从手机获取联系人信息,然后将其上报给UI进行显示。使用PBAP协议获取Android手机的联系人信息,需要从应用层主动下发拉取联系人的请求;使用ANCS获取IOS手机联系人信息,无需主动下发请求,当IOS手机收到来电时会主动将来电通知推送给手表蓝牙。

2024-02-25 19:08:45 934

原创 Android 蓝牙 整体架构、GAP详解

Core 5.0主要讲的是Bluetooth Architecture 架构部分,161页到264页,最重要的是vol 1 的 part A 部分Architecture 共有7个章节,1,2,3,4,5比较重要最核心需要理清的是2,3章节,第2章节从架构讲了Architecture的一些模块功能角度,第3章节从数据流的角度讲解了数据的传输路线等。蓝牙系统结构的最底层。每个通道由以下几方面组成,一是伪随机序列频率,二是特定的传输时隙,三是访问代码(accesscode)和编码包头。例如手机之间的配对。

2024-02-25 19:08:14 784

原创 Android

PBAP:Phone Book Access Profile的简称,电话本访问协议,是一种基于OBEX的上层协议,该协议可以同步手机这些具有电话本功能的设备上的通讯录和通话记录等信息。角色定义:PSE:Phone Book Server Equipment,拥有电话本源数据的设备,作为服务端,比如手机。PCE:Phone Book Client Equipment,向PSE端请求电话本信息的设备,作为客户端。如手机在与手表/手环连接进行蓝牙通话时,此时手表/手环是PCE ,手机作为PSE。

2024-02-25 19:07:44 891

原创 Android

1、ANCS(Apple Notification Center Service)是IOS系统中的一个通知服务,使用该服务的方式为,设备连接手机后,设备上的GATT客户端发现IOS手机端上的ANCS服务,并且使能其通知源Characteristics的notifys功能,之后IOS系统就会通过ble推送消息给设备。

2024-02-25 19:07:11 905

原创 Android

AMS 全称 Apple Media Service(苹果媒体服务),是提供给 BLE 设备的一种简单控制媒体应用程序的方式,并且用于获取已连接的 IOS 设备的媒体状态信息。类似于Android 的AVRCP协议。AMS 字节序和字节码除非另有规定,否则通过 AMS 传输的所有数值都应是小端格式。除非另有规定,否则通过 AMS 传输的所有字符串值都应是 UTF-8 编码的 unicode 字符所组成的。依赖性除了标准的通用属性配置文件(GATT)子程序集外,AMS 没有任何依赖性。

2024-02-25 19:06:40 987

原创 Android

l2c_link_send_to_lower 把数据交给了 L2C_LINK_SEND_ACL_DATA,L2C_LINK_SEND_ACL_DATA 其实是 bte_main_hci_send 函数,bte_main_hci_send 函数通过调用 hci 的接口 transmit_buf 来转送数据包。下面我们会继续分析这两个函数。注意,如果是 L2CEVT_SEC_COMP 事件(跟安全相关),会把 p_ccb->chnl_state 置为 CST_W4_L2CAP_CONNECT_RSP。

2024-02-25 19:06:10 844

原创 Android 、

配置路径:xref: /packages/apps/Bluetooth/res/values/config.xml。协议配置文件有2个,一个是谷歌源生的,一个是高通自己添加的。优先级:高通 > 谷歌。对于同一种协议会进行覆盖。其中,ture 代表支持,false代表不支持。其中ldac为5001,优先级最高。

2024-02-25 19:05:16 396

原创 Android

SCO逻辑传输,是在主机和特定从机之间的一个对称的点对点传输。SCO逻辑传输保留插槽,因此可以被视为主机和从机之间的电路交换连接。主服务器最多可以支持三个到同一从服务器或不同从服务器的SCO链接。从属服务器最多可以支持来自同一主服务器的三个SCO链接,如果链接来自不同的主服务器,则支持两个SCO链接。SCO数据包永远不会被重新传输eSCO逻辑传输,是主机和特定从机之间的点对点逻辑传输。eSCO逻辑传输可以是对称的或不对称的。

2024-02-25 19:04:45 372

原创 Android

android/frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java:代表本地蓝牙适配器,是所有蓝牙交互的入口。/android/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothEnabler.java:蓝牙功能的开启/关闭功能处理。切换状态到mTurningOnState,并且调用其非状态的enter()方法,向上层汇报蓝牙此时状态。

2024-02-25 19:04:14 373

原创 Android 蓝牙手机侧连接HFP总是失败解析

因此在 bta_hf_client_mgmt_cback() 回调函数中因为连接数已达最大值而导致HFP连接失败,首先会 RFCOMM_RemoveServer() 清除掉此次连接所使用的服务端口,但是没有启动创建新服务端口等待其他连接请求。在bta_hf_client_mgmt_cback()回调中不管连接成功还是失败都重新创建新的服务端口,保证后续AG侧的HFP连接请求都能正常回复。2、bta_hf_client_mgmt_cback()前一个AG侧发起的连接成功后。:Android-9(P版本)

2024-02-25 19:03:43 344

原创 Android

目录一.概述二.Data Format三.数据元2.数据元尺寸描述符 四.Continuation StateThe service discovery protocol (SDP) provides a means for applications to discover which services are available andto determine the characteristics of those available services.基于C/S结构,service通过属性记

2024-02-25 19:03:04 752

原创 Android

目录一、HID Reports : Bluetooth HID devices支持三种Report:Input, Output, Feature。二、HID channel 三、HID Report Modes五、BLE HID 服务 : 手册 HIDS-V1.0.0-(HID-Service).pdf 1、Protocol Mode Characteristic :​编辑2、Report Characteristic : 3、Report Map Characteristic4、Boot Keyboar

2024-02-25 19:02:33 847 1

原创 Android

首先第一个括号中的是一个函数指针名,顾名思义,应该指向一个函数,通过查找,bta_sys_cb是一个结构体变量,访问到里面的成员reg数组,但是reg又是个结构体指针数组,也就是说evt_hdlr 就是bta_dm_search_sm_execute()函数,并且将参数p_msg传了进来。事件是怎么发送的呢?此时调用到了蓝牙协议栈中btif层了,这个函数的作用是 设备管理相关的函数;() 指向了这个回调函数:那么这个结构体中所有的回调函数在哪里赋值的呢?通过线程,会调用到bta_sys_event函数。

2024-02-25 19:01:50 951

原创 Android

HID写数据给Input子节点流程:键盘手柄->按键发送Keycode(HCI)->协议栈(bta_hh_cback()函数)->HID驱动()->Input子节点(getEvnet)

2024-02-25 19:01:11 986

原创 Android

HOGP写数据给Input子节点流程:键盘手柄->按键发送Keycode(HCI)->协议栈(bta_hh_le_input_rpt_notify()函数)->HID驱动()->Input子节点(getEvnet)

2024-02-24 18:05:48 371

原创 Android

以下内容基于android Q。手表通话分蓝牙通话、esim卡通话。esim卡通话和手机通话一样,通过modem和运营商基站通信。蓝牙通话则是把手机上的通话信息和状态同步到手表上,然后把手表上的操作返回到手机上进行实际处理。蓝牙通话其实就是在手表端的Telecom交互从Telephony变成了Bluetooth。

2024-02-24 18:04:49 321

原创 Android

例如:当一台手机连接两个蓝牙耳机A和B,目前通话正在使用A,用户在蓝牙设置界面选择切换成B。此时,蓝牙会先断开A的audio连接然后再建立B的audio连接。于是通话会先收到A的HFP_LOST然后再收到B的HFP_IS_ON,这里就会有一个time issue:当AudioConnectedState收到HFP_LOST时B的audio没有连接上,但进入到AudioOffState前B的audio连接上了,此时在AudioOffState的enter中会断开B的连接,导致声道切换成B失败,而从听筒出声。

2024-02-24 18:04:16 323

原创 Android

这个时候,打开蓝牙的操作已经来到了Bluetooth协议栈里面,具体的是AdapterService这个类里面。这个bt_interface_t是一个结构体,在android/hardware/libhardware/include/hardware/bluetooth.h中被定义,作为一个标准的蓝牙接口来给到硬件驱动,也就是蓝牙CHIP。注意,这里的确是先去打开蓝牙BLE的开关,而不是直接就去打开整个传统蓝牙的开关。至此,打开蓝牙的操作已经调入到了硬件驱动程序,等待硬件真正的打开。

2024-02-24 18:03:44 332

原创 Android

Bluetooth协议栈的AdapterService在接收到onLeServiceUp的调用之后,会给AdapterState状态机发一条AdapterState.USER_TURN_ON的消息,于是这次操作又交到了AdapterState状态机去处理了。至此,从应用调用打开蓝牙的方法,到收到蓝牙打开的广播,整个蓝牙打开的流程就已经分析完毕!每一个服务启动后,都会通知到AdapterService,当所有的协议服务都启动完毕之后,也就意味着蓝牙真正的打开了。蓝牙进程使用 JNI 与蓝牙。

2024-02-24 18:03:01 365

原创 Android

那接下来进入SettingsLib,接收扫描结果的是BluetoothEventManager这个类,其中定义了DeviceFoundHandler和ScanningStateChangedHandler这两个内部类,前一个是处理扫描到的设备,后一个是处理扫描状态的改变逻辑。started为false,那就意味着本次扫描结束了,如果用户没有操作停止,那么mIsScanningEnabled就会是true,那么就会发起新一轮的扫描操作,这样不停的扫描,才能发现搜索到更多更完整的蓝牙设备。

2024-02-24 18:02:30 333

原创 Android

场景:比如手机和车载连接,在车载端拨号,通过蓝牙将拨号指令传递给手机,手机再处理拨号行为。蓝牙的HFP协议定义了两个角色,一个是HF端,如蓝牙耳机、车机端等免提设备;一个是AG端,通常指的就是手机端。在Android系统里面,也有对应的两个Profile,HF端对应HeadsetClient Profile,而AG端对应Headset Profile。下面我们就通过拨号指令,梳理Headset端的处理过程。

2024-02-24 18:01:59 300

原创 数码管温湿度通讯协议 V0.3 2021.4设备采用RS485通讯接口,默认串口参数配置:9600 8 N 1。协议遵循标准Modbus_RTU通信协议,主要用到03

我们以HF端发起拨号请求为例,那么最开始回调的状态就是CALL_STATE_DIALING,callsetup的值为2。如果我们要实现一个蓝牙电话的功能,那么直接接收BluetoothHeadsetClient.ACTION_CALL_CHANGED这个广播就可以获取到通话的状态。可以看到,最后的通话状态是通过广播的形式传递出去的,BluetoothHeadsetClientCall继承自Parcelable接口,是可以实现序列化传递的。可以看出,它是连接HFP和Telecom的桥梁。

2024-02-24 18:01:29 336

原创 Android

实际上我们在之前分析过,在打开蓝牙的过程中,首先就是打开BLE,在Android系统中对应的就是GattService;再打开BLE之后,再去打开其他的Profile服务,所有Profile服务开启完毕之后,再通过广播形式通知蓝牙开关打开成功。最近有一个功能需要使用蓝牙BLE,如果在使用之前蓝牙是关闭的状态,需要先打开蓝牙,并且在使用完之后,需要把蓝牙关闭。于是决定本功能模块单独使用蓝牙BLE,而不去操作经典蓝牙,这样就不会影响到设置模块对蓝牙开关的操作逻辑了。

2024-02-24 18:00:59 198

原创 Android 蓝牙JNI层如何调用到navite层?---详解

其中packagename.classname是Java代码编译后的.class文件,而在生成的output.h文件里,声明了对应JNI函数,只要实现里面的函数即可。下面主要讲一下动态注册,动态注册比较方便jni的移植,而静态注册如果移植到其他的packet,需要修改所有的jni函数名.加载的效率上,动态注册也优于静态注册。Java支持函数重载,可以定义相同方法名,但是不同参数的方法,然后Java根据其不同的参数,找到其对应的实现的方法.在jni的文件中重载JNI_OnLoad函数。1、获取JNIEnv。

2024-02-24 18:00:24 356

原创 Android

RSSI的单位是dbm,在蓝牙中,我们可以直接理解为,收到蓝牙信号的强度,RSSI = 10*log P,P代表接收到的信号功率,蓝牙会发送广播,距离不同会影响接收到的信号功率,假设发射功率取最大值为1mw,那么RSSI的值为0,也就是说你的距离离蓝牙最近时在理想状态下所获取的RSSI的值为0,但在实际中基本不会存在这个理想状态,因此RSSI的值基本都为负数,而在蓝牙中,当距离很近时,所收到的RSSI的信号值大约在-50dbm。

2024-02-24 17:59:53 231

原创 Android

此时我们终于明白了蓝牙协议栈的消息发送机制,确实复杂,那么我们每次都得这样去查找吗?其实不用的,我们只需要直接去对应的文件中找对应的action就行,一般都是在/system/bt/bta/xxx协议/xxxx_main.cc函数中定义着。但是对于一个蓝牙开发者,背后的原理还是要懂得。

2024-02-24 17:59:23 349

原创 Android

以上这些方法都是底层回调数据到上层的方法,这下刚刚的疑惑就得到解决了,那么这个101状态值肯定是必须要走的,期间把event作为传入传递过去了,其中event就包含了state和type信息,记住此时的state为1,type为EVENT_TYPE_AUDIO_STATE_CHANGED,至此源头就找到了,接着回到AudioConnecting连接状态,看如下片段代码。以上就是蓝牙连接到蓝牙断开的七个连接状态,每个状态都继承了状态机,接下来看看每个连接状态的具体方法,具体实现稍后分析。

2024-02-24 17:58:50 349

原创 Android

HID写数据给Input子节点流程:键盘手柄->按键发送Keycode(HCI)->协议栈(bta_hh_cback()函数)->HID驱动()->Input子节点(getEvnet)

2024-02-24 17:58:03 412

原创 Android

本人做手机项目的时候,在ble蓝牙这块有时候很纠结,纠结什么呢?突然有一天功耗组同时告知我,蓝牙在关闭情况下,功耗较高,这我就很纳闷了?蓝牙本就关着,哪来的功耗?后来看HCI日志,发现并没有inquiry扫描,但是有ble扫描,这就很奇怪了,如果没有inquiry,证明在setting中蓝牙开关是关闭的啊,那这个ble扫描从哪里冒出来的呢?

2024-02-24 17:57:43 333

原创 Android

HOGP写数据给Input子节点流程:键盘手柄->按键发送Keycode(HCI)->协议栈(bta_hh_le_input_rpt_notify()函数)->HID驱动()->Input子节点(getEvnet)

2024-02-23 13:40:35 551

原创 Android

以下内容基于android Q。手表通话分蓝牙通话、esim卡通话。esim卡通话和手机通话一样,通过modem和运营商基站通信。蓝牙通话则是把手机上的通话信息和状态同步到手表上,然后把手表上的操作返回到手机上进行实际处理。蓝牙通话其实就是在手表端的Telecom交互从Telephony变成了Bluetooth。

2024-02-23 13:39:44 551

原创 Android

例如:当一台手机连接两个蓝牙耳机A和B,目前通话正在使用A,用户在蓝牙设置界面选择切换成B。此时,蓝牙会先断开A的audio连接然后再建立B的audio连接。于是通话会先收到A的HFP_LOST然后再收到B的HFP_IS_ON,这里就会有一个time issue:当AudioConnectedState收到HFP_LOST时B的audio没有连接上,但进入到AudioOffState前B的audio连接上了,此时在AudioOffState的enter中会断开B的连接,导致声道切换成B失败,而从听筒出声。

2024-02-23 13:39:14 557

原创 Android

这个时候,打开蓝牙的操作已经来到了Bluetooth协议栈里面,具体的是AdapterService这个类里面。这个bt_interface_t是一个结构体,在android/hardware/libhardware/include/hardware/bluetooth.h中被定义,作为一个标准的蓝牙接口来给到硬件驱动,也就是蓝牙CHIP。注意,这里的确是先去打开蓝牙BLE的开关,而不是直接就去打开整个传统蓝牙的开关。至此,打开蓝牙的操作已经调入到了硬件驱动程序,等待硬件真正的打开。

2024-02-23 13:38:42 602

原创 Android

Bluetooth协议栈的AdapterService在接收到onLeServiceUp的调用之后,会给AdapterState状态机发一条AdapterState.USER_TURN_ON的消息,于是这次操作又交到了AdapterState状态机去处理了。至此,从应用调用打开蓝牙的方法,到收到蓝牙打开的广播,整个蓝牙打开的流程就已经分析完毕!每一个服务启动后,都会通知到AdapterService,当所有的协议服务都启动完毕之后,也就意味着蓝牙真正的打开了。蓝牙进程使用 JNI 与蓝牙。

2024-02-23 13:38:12 591

原创 Android

那接下来进入SettingsLib,接收扫描结果的是BluetoothEventManager这个类,其中定义了DeviceFoundHandler和ScanningStateChangedHandler这两个内部类,前一个是处理扫描到的设备,后一个是处理扫描状态的改变逻辑。started为false,那就意味着本次扫描结束了,如果用户没有操作停止,那么mIsScanningEnabled就会是true,那么就会发起新一轮的扫描操作,这样不停的扫描,才能发现搜索到更多更完整的蓝牙设备。

2024-02-23 13:37:29 633

原创 Android

场景:比如手机和车载连接,在车载端拨号,通过蓝牙将拨号指令传递给手机,手机再处理拨号行为。蓝牙的HFP协议定义了两个角色,一个是HF端,如蓝牙耳机、车机端等免提设备;一个是AG端,通常指的就是手机端。在Android系统里面,也有对应的两个Profile,HF端对应HeadsetClient Profile,而AG端对应Headset Profile。下面我们就通过拨号指令,梳理Headset端的处理过程。

2024-02-23 13:36:58 680

原创 Android

1、通话状态有改变,会通过NativeInterface这个类里面的onCallSetup方法。

2024-02-23 13:36:24 659

原创 Android

实际上我们在之前分析过,在打开蓝牙的过程中,首先就是打开BLE,在Android系统中对应的就是GattService;再打开BLE之后,再去打开其他的Profile服务,所有Profile服务开启完毕之后,再通过广播形式通知蓝牙开关打开成功。最近有一个功能需要使用蓝牙BLE,如果在使用之前蓝牙是关闭的状态,需要先打开蓝牙,并且在使用完之后,需要把蓝牙关闭。于是决定本功能模块单独使用蓝牙BLE,而不去操作经典蓝牙,这样就不会影响到设置模块对蓝牙开关的操作逻辑了。

2024-02-23 13:35:54 312

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除