当前位置: 首页 > news >正文

【android bluetooth 案例分析 03】【PTS 测试 】【PBAP/PCE/SGSIT/SERR/BV-01-C】

1. PBAP/PCE/SGSIT/OFFS/BV-01-C

1. 测试项说明:

Please initiate a GATT connection over BR/EDR to the PTS.Description: Verify that the Implementation Under Test (IUT) can initiate GATT connect request over BR/EDR to PTS.

测试项名称
Please initiate a GATT connection over BR/EDR to the PTS.

测试项描述
验证被测设备(IUT)是否能够通过 BR/EDR(经典蓝牙)主动发起 GATT 连接请求到 PTS(Protocol Test System)

2. 基本概念

1. 什么是 GATT?

GATT(Generic Attribute Profile)是 BLE(低功耗蓝牙)中用于设备之间传输数据的通用协议,基于 ATT(Attribute Protocol)实现。

2. 什么是 BR/EDR?

BR/EDR 是“Basic Rate / Enhanced Data Rate”的缩写,也就是经典蓝牙。传统上,GATT 运行于 BLE(即 LE)上,但从 Bluetooth Core v4.1 起,GATT 也可以工作在 BR/EDR 上。

3. 为什么要测试 GATT over BR/EDR?

虽然 GATT 多用于 BLE,但有些场景或设备(比如某些老设备或兼容设备)需要在经典蓝牙上复用 GATT 协议。因此,Bluetooth SIG 定义了这个测试项来确保 IUT 能在 BR/EDR 上传输 GATT 协议。


3. 测试目的

验证被测设备(IUT)是否能够:

  1. 使用 BR/EDR(经典蓝牙)连接到 PTS
  2. 正确发起 GATT 连接请求(如发送 MTU 交换请求);
  3. 在 BR/EDR 信道上使用 ATT 协议通信
  4. 满足 GATT over BREDR 的规范要求

4. 测试流程简述

步骤动作
1IUT 与 PTS 建立配对(通过经典蓝牙)
2IUT 执行 SDP 查询,找到 PTS 提供的 GATT 服务(UUID: 0x1801
3IUT 通过 BR/EDR 打开 L2CAP 固定信道(通常为 0x0004)
4IUT 发送 ATT 请求(如 Exchange MTU Request)
5PTS 响应,连接建立成功
6记录测试结果(通过 / 失败)

5. 测试重点与注意事项

项目要点
✅ 连接方式必须是 BR/EDR(经典蓝牙),不能使用 BLE
✅ SDP 查询IUT 应能找到 GATT 服务的 SDP 记录(Generic Attribute Profile)
✅ L2CAP 信道使用固定信道 0x0004 建立 ATT 通道
✅ ATT 层IUT 应发送标准的 GATT 请求,如 MTU 交换、服务发现等
❌ 错误示范如果 IUT 走了 BLE 的 GATT 路径,则测试会被判为失败
⚠️ 蓝牙协议栈支持部分蓝牙协议栈(如 Android、BlueZ)默认不支持 GATT over BR/EDR,需要手动适配或扩展

6. 常见失败原因(SERR)

问题原因
GATT 请求未发出IUT 没有正确连接或协议栈不支持
使用了 LE 连接测试要求使用经典蓝牙,不能用 LE
SDP 查询失败未找到 GATT 服务 UUID
L2CAP 信道错误未使用 0x0004 或配置不当
没有发送 ATT 数据上层未触发 GATT 请求流程

7. 调试建议

  • 抓包工具:使用 Ellisys 或 Frontline 观察 HCI 层是否通过 BR/EDR 连接;

  • 确认 ACL 链路类型:应为 classic BR ACL 而非 LE;

  • 查看 SDP 记录:确认 PTS 是否发布了 GATT 服务 UUID;

  • 打印日志:开启协议栈日志,如 BlueZ 可查看 btmon,Android 可用 logcat


8. 总结

本测试项的关键是:

确保设备在 BR/EDR 上传输 GATT 协议,并能主动连接并通信。

由于很多现代蓝牙协议栈默认只支持 GATT over LE,若设备原生不支持,需要自行扩展协议栈才能通过此项测试。

2. 真实车机侧案例

我们 IUT 测试对象是车机。 android 的协议栈不支持,默认不支持 GATT over BR/EDR。 看到这里, 是不是有点担心。 如果要过这一项测试,是不是要 人为改代码, 来适配 GATT over BR/EDR。 我实际测试了一下。直接是可以通过的。

我这里 记录一下 车机侧的 btsnoop 日志。 看一下为何在协议栈不支持 GATT over BR/EDR 的情况下。还能测试通过。

在这里插入图片描述

  • 发现只有 sdp 的流程, 没有后续 连接 pbap 的流程。
  • 那我们重点看一下, 车机发起 sdp 后, pts. 回复的内容。
# 车机向 pts 查询 Phonebook Access Server 
975	2025-04-25 17:53:59.966042	22:22:96:de:b1:39 (leo 8295 chan)	Vencer_f4:b1:83 (PTS-PBAP-B183)	SDP	29	Sent Service Search Attribute Request : Phonebook Access Server: Attribute Range (0x0000 - 0xffff) # pts 回复如下:
980	2025-04-25 17:53:59.991359	Vencer_f4:b1:83 (PTS-PBAP-B183)	22:22:96:de:b1:39 (leo 8295 chan)	SDP	19	Rcvd Service Search Attribute Response Bluetooth SDP ProtocolPDU: Service Search Attribute Response (0x07)Transaction Id: 0x0000Parameter Length: 5Attribute List Byte Count: 2Attribute Lists [count =  0]Data Element: Sequence uint8 0 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 0Data Value: MISSING     # 这里看到 pts 返回的 数据内容是空的。Continuation State: no (00)

而我们 协议栈判断到, pts 的 返回的 sdp record 是空的后, 就没有继续发起 pbap 的连接。

04-25 17:53:59.140092  9393  9488 D PbapClientStateMachine: mCchPathUsed: false
04-25 17:53:59.140338  9393  9720 I PbapClientStateMachine: Enter Connecting: -2
04-25 17:53:59.140520  9393  9720 D PbapClientStateMachine: Connection state 00:1B:DC:F4:B1:83: 0->1
04-25 17:54:00.009577  9393  9393 I PbapClientStateMachine: onReceiveandroid.bluetooth.device.action.SDP_RECORD
04-25 17:54:00.009815  9393  9393 I PbapClientStateMachine: Received UUID: 0000112f-0000-1000-8000-00805f9b34fb
04-25 17:54:00.009968  9393  9393 I PbapClientStateMachine: expected UUID: 0000112f-0000-1000-8000-00805f9b34fb// 直接返回错误了
04-25 17:54:00.010025  9393  9393 E PbapClientStateMachine: SDP Record fetched status isn't ok - Ignore. status=1
// android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.javaprivate class SDPBroadcastReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (DBG) {Log.i(TAG, "onReceive" + action);}if (action.equals(BluetoothDevice.ACTION_SDP_RECORD)) {BluetoothDevice device =intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);BluetoothDevice sm_device = getDevice();if (sm_device !=null) {if (!device.equals(getDevice())) {Log.w(TAG, "SDP Record fetched for different device - Ignore");return;}} else {Log.d(TAG, "SDP Record get device is null - Ignore");return;}ParcelUuid uuid = intent.getParcelableExtra(BluetoothDevice.EXTRA_UUID);if (DBG) {Log.i(TAG, "Received UUID: " + uuid.toString());Log.i(TAG, "expected UUID: " + BluetoothUuid.PBAP_PSE.toString());}int search_status= intent.getIntExtra(BluetoothDevice.EXTRA_SDP_SEARCH_STATUS,-1);if (search_status != AbstractionLayer.BT_STATUS_SUCCESS) {// 直接在这里返回退出了。Log.e(TAG, "SDP Record fetched status isn't ok - Ignore. status="+search_status);return;}if (uuid.equals(BluetoothUuid.PBAP_PSE)) {// 正常的逻辑,应该走到这里, sdp 完成后,会继续触发 后续连接操作。sendMessage(MSG_SDP_COMPLETE,intent.getParcelableExtra(BluetoothDevice.EXTRA_SDP_RECORD));}}}}}

发现这一项, 由于 pts 返回的 sdp record 状态有问题。 后续车机干脆没有发起 pbap 的连接。 直接 pts软件 pass 了。


3. 正确的 sdp

这里对比分享一个 正常,可以建立 pbap 情况下的, sdp 的内容。

# 车机主动发起 sdp 请求
846	2025-04-25 14:08:32.468449	22:22:96:de:b1:39 (leo 8295 chan)	Vencer_f4:b1:83 (PTS-PBAP-B183)	SDP	29	Sent Service Search Attribute Request : Phonebook Access Server: Attribute Range (0x0000 - 0xffff) # pts 回复正确的 sdp record
849	2025-04-25 14:08:32.507350	Vencer_f4:b1:83 (PTS-PBAP-B183)	22:22:96:de:b1:39 (leo 8295 chan)	SDP	255	Rcvd Service Search Attribute Response Bluetooth SDP ProtocolPDU: Service Search Attribute Response (0x07)Transaction Id: 0x0000Parameter Length: 241Attribute List Byte Count: 238Attribute Lists [count =  2]Data Element: Sequence uint8 236 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 236Data ValueAttribute List [count = 10] (Phonebook Access Server)Data Element: Sequence uint8 119 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 119Data ValueService Attribute: Service Record Handle (0x0), value = 0x00090021 (589857)Attribute ID: Service Record HandleData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute ID: Service Record Handle (0x0000)ValueData Element: Unsigned Integer 4 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .010 = Data Element Size: 4 bytes (2)Data ValueService Record Handle: 0x00090021Service Attribute: Service Class ID List (0x1), value = Phonebook Access ServerAttribute ID: Service Class ID ListData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute ID: Service Class ID List (0x0001)ValueData Element: Sequence uint8 3 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 3Data ValueData Element: UUID 2 bytes0001 1... = Data Element Type: UUID (3).... .001 = Data Element Size: 2 bytes (1)Data ValueValue: UUID: Phonebook Access Server (0x112f)Service Attribute: Protocol Descriptor List (0x4), value = L2CAP -> RFCOMM:2 -> OBEXAttribute ID: Protocol Descriptor ListData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute ID: Protocol Descriptor List (0x0004)ValueData Element: Sequence uint8 17 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 17Data ValueProtocol #1: L2CAPData Element: Sequence uint8 3 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 3Data ValueProtocol Entry: L2CAPData Element: UUID 2 bytes0001 1... = Data Element Type: UUID (3).... .001 = Data Element Size: 2 bytes (1)Data ValueValue: UUID: L2CAP (0x0100)Protocol #2: RFCOMM, RFCOMM Channel: 2Data Element: Sequence uint8 5 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 5Data ValueProtocol Entry: RFCOMM, RFCOMM Channel: 2Data Element: UUID 2 bytes0001 1... = Data Element Type: UUID (3).... .001 = Data Element Size: 2 bytes (1)Data ValueValue: UUID: RFCOMM (0x0003)Data Element: Unsigned Integer 1 byte (0 bytes if Nil)0000 1... = Data Element Type: Unsigned Integer (1).... .000 = Data Element Size: 1 byte (0 bytes if Nil) (0)Data ValueRFCOMM Channel: 2 (0x02)Protocol #3: OBEXData Element: Sequence uint8 3 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 3Data ValueProtocol Entry: OBEXData Element: UUID 2 bytes0001 1... = Data Element Type: UUID (3).... .001 = Data Element Size: 2 bytes (1)Data ValueValue: UUID: OBEX (0x0008)Service Attribute: Browse Group List (0x5), value = Public Browse GroupAttribute ID: Browse Group ListData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute ID: Browse Group List (0x0005)ValueData Element: Sequence uint8 3 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 3Data ValueData Element: UUID 2 bytes0001 1... = Data Element Type: UUID (3).... .001 = Data Element Size: 2 bytes (1)Data ValueValue: UUID: Public Browse Group (0x1002)Service Attribute: Language Base Attribute ID List (0x6), value = (Lang: en, Encoding: UTF-8, Attribute Base: 0x0100)Attribute ID: Language Base Attribute ID ListData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute ID: Language Base Attribute ID List (0x0006)ValueData Element: Sequence uint8 9 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 9Data ValueLanguage #1: Lang: en, Encoding: UTF-8, Attribute Base: 0x0100Data Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueLanguage Code: enData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueLanguage Encoding: UTF-8 (106)Data Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute Base: 0x0100Service Attribute: Bluetooth Profile Descriptor List (0x9), value = Phonebook Access Profile 1.2Attribute ID: Bluetooth Profile Descriptor ListData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute ID: Bluetooth Profile Descriptor List (0x0009)ValueData Element: Sequence uint8 8 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 8Data ValueData Element: Sequence uint8 6 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 6Data ValueProfile Descriptor List #1: Phonebook Access Profile, Version 1.2Data Element: UUID 2 bytes0001 1... = Data Element Type: UUID (3).... .001 = Data Element Size: 2 bytes (1)Data ValueValue: UUID: Phonebook Access Profile (0x1130)Data Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueProtocol Version: 0x0102Service Attribute: Service Name (0x100), value = Phonebook Acccess PSEAttribute ID: Service NameData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute ID: Service Name (0x0100)ValueData Element: Text string uint8 22 bytes0010 0... = Data Element Type: Text string (4).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 22Data ValueService Name: Phonebook Acccess PSEService Attribute: (PBAP) GOEP L2CAP PSM (0x200), value = 4101 (0x1005)Attribute ID: GOEP L2CAP PSMData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute ID: GOEP L2CAP PSM (0x0200)ValueData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueGOEP L2CAP PSM: 4101 (0x1005)Service Attribute: (PBAP) Supported Repositories (0x314), value = LocalPhonebook SIM SpeedDial Favourites Attribute ID: Supported RepositoriesData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute ID: Supported Repositories (0x0314)ValueData Element: Unsigned Integer 1 byte (0 bytes if Nil)0000 1... = Data Element Type: Unsigned Integer (1).... .000 = Data Element Size: 1 byte (0 bytes if Nil) (0)Data ValueSupported Repositories: 0x0f0000 .... = Reserved: 0x0.... 1... = Favourites: True.... .1.. = Speed Dial: True.... ..1. = SIM Card: True.... ...1 = Local Phonebook: TrueService Attribute: (PBAP) Supported Features (0x317), value = Attribute ID: Supported FeaturesData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute ID: Supported Features (0x0317)ValueData Element: Unsigned Integer 4 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .010 = Data Element Size: 4 bytes (2)Data ValueSupported Features: 0x000000000000 0000 0000 0000 0000 00.. .... .... = Reserved: 0x000000.... .... .... .... .... ..0. .... .... = Default Contact Image Format: False.... .... .... .... .... ...0 .... .... = Contact Referencing: False.... .... .... .... .... .... 0... .... = X-BT-UID vCard Property: False.... .... .... .... .... .... .0.. .... = X-BT-UCI vCard Property: False.... .... .... .... .... .... ..0. .... = Enhanced Missed Calls: False.... .... .... .... .... .... ...0 .... = vCard Selecting: False.... .... .... .... .... .... .... 0... = Folder Version Counters: False.... .... .... .... .... .... .... .0.. = Database Identifier: False.... .... .... .... .... .... .... ..0. = Browsing: False.... .... .... .... .... .... .... ...0 = Download: FalseAttribute List [count =  9] (Phonebook Access Server)Data Element: Sequence uint8 113 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 113Data ValueService Attribute: Service Record Handle (0x0), value = 0x00090063 (589923)Attribute ID: Service Record HandleData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute ID: Service Record Handle (0x0000)ValueData Element: Unsigned Integer 4 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .010 = Data Element Size: 4 bytes (2)Data ValueService Record Handle: 0x00090063Service Attribute: Service Class ID List (0x1), value = Phonebook Access ServerAttribute ID: Service Class ID ListData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute ID: Service Class ID List (0x0001)ValueData Element: Sequence uint8 3 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 3Data ValueData Element: UUID 2 bytes0001 1... = Data Element Type: UUID (3).... .001 = Data Element Size: 2 bytes (1)Data ValueValue: UUID: Phonebook Access Server (0x112f)Service Attribute: Protocol Descriptor List (0x4), value = L2CAP -> RFCOMM:2 -> OBEXAttribute ID: Protocol Descriptor ListData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute ID: Protocol Descriptor List (0x0004)ValueData Element: Sequence uint8 17 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 17Data ValueProtocol #1: L2CAPData Element: Sequence uint8 3 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 3Data ValueProtocol Entry: L2CAPData Element: UUID 2 bytes0001 1... = Data Element Type: UUID (3).... .001 = Data Element Size: 2 bytes (1)Data ValueValue: UUID: L2CAP (0x0100)Protocol #2: RFCOMM, RFCOMM Channel: 2Data Element: Sequence uint8 5 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 5Data ValueProtocol Entry: RFCOMM, RFCOMM Channel: 2Data Element: UUID 2 bytes0001 1... = Data Element Type: UUID (3).... .001 = Data Element Size: 2 bytes (1)Data ValueValue: UUID: RFCOMM (0x0003)Data Element: Unsigned Integer 1 byte (0 bytes if Nil)0000 1... = Data Element Type: Unsigned Integer (1).... .000 = Data Element Size: 1 byte (0 bytes if Nil) (0)Data ValueRFCOMM Channel: 2 (0x02)Protocol #3: OBEXData Element: Sequence uint8 3 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 3Data ValueProtocol Entry: OBEXData Element: UUID 2 bytes0001 1... = Data Element Type: UUID (3).... .001 = Data Element Size: 2 bytes (1)Data ValueValue: UUID: OBEX (0x0008)Service Attribute: Browse Group List (0x5), value = Public Browse GroupAttribute ID: Browse Group ListData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute ID: Browse Group List (0x0005)ValueData Element: Sequence uint8 3 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 3Data ValueData Element: UUID 2 bytes0001 1... = Data Element Type: UUID (3).... .001 = Data Element Size: 2 bytes (1)Data ValueValue: UUID: Public Browse Group (0x1002)Service Attribute: Language Base Attribute ID List (0x6), value = (Lang: en, Encoding: UTF-8, Attribute Base: 0x0100)Attribute ID: Language Base Attribute ID ListData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute ID: Language Base Attribute ID List (0x0006)ValueData Element: Sequence uint8 9 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 9Data ValueLanguage #1: Lang: en, Encoding: UTF-8, Attribute Base: 0x0100Data Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueLanguage Code: enData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueLanguage Encoding: UTF-8 (106)Data Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute Base: 0x0100Service Attribute: Bluetooth Profile Descriptor List (0x9), value = Phonebook Access Profile 1.0Attribute ID: Bluetooth Profile Descriptor ListData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute ID: Bluetooth Profile Descriptor List (0x0009)ValueData Element: Sequence uint8 8 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 8Data ValueData Element: Sequence uint8 6 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 6Data ValueProfile Descriptor List #1: Phonebook Access Profile, Version 1.0Data Element: UUID 2 bytes0001 1... = Data Element Type: UUID (3).... .001 = Data Element Size: 2 bytes (1)Data ValueValue: UUID: Phonebook Access Profile (0x1130)Data Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueProtocol Version: 0x0100Service Attribute: Service Name (0x100), value = Phonebook Acccess PSEAttribute ID: Service NameData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute ID: Service Name (0x0100)ValueData Element: Text string uint8 22 bytes0010 0... = Data Element Type: Text string (4).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 22Data ValueService Name: Phonebook Acccess PSEService Attribute: (PBAP) Supported Repositories (0x314), value = LocalPhonebook SIM SpeedDial Favourites Attribute ID: Supported RepositoriesData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute ID: Supported Repositories (0x0314)ValueData Element: Unsigned Integer 1 byte (0 bytes if Nil)0000 1... = Data Element Type: Unsigned Integer (1).... .000 = Data Element Size: 1 byte (0 bytes if Nil) (0)Data ValueSupported Repositories: 0x0f0000 .... = Reserved: 0x0.... 1... = Favourites: True.... .1.. = Speed Dial: True.... ..1. = SIM Card: True.... ...1 = Local Phonebook: TrueService Attribute: (PBAP) Supported Features (0x317), value = Attribute ID: Supported FeaturesData Element: Unsigned Integer 2 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .001 = Data Element Size: 2 bytes (1)Data ValueAttribute ID: Supported Features (0x0317)ValueData Element: Unsigned Integer 4 bytes0000 1... = Data Element Type: Unsigned Integer (1).... .010 = Data Element Size: 4 bytes (2)Data ValueSupported Features: 0x000000000000 0000 0000 0000 0000 00.. .... .... = Reserved: 0x000000.... .... .... .... .... ..0. .... .... = Default Contact Image Format: False.... .... .... .... .... ...0 .... .... = Contact Referencing: False.... .... .... .... .... .... 0... .... = X-BT-UID vCard Property: False.... .... .... .... .... .... .0.. .... = X-BT-UCI vCard Property: False.... .... .... .... .... .... ..0. .... = Enhanced Missed Calls: False.... .... .... .... .... .... ...0 .... = vCard Selecting: False.... .... .... .... .... .... .... 0... = Folder Version Counters: False.... .... .... .... .... .... .... .0.. = Database Identifier: False.... .... .... .... .... .... .... ..0. = Browsing: False.... .... .... .... .... .... .... ...0 = Download: FalseContinuation State: no (00)

相关文章:

【android bluetooth 案例分析 03】【PTS 测试 】【PBAP/PCE/SGSIT/SERR/BV-01-C】

1. PBAP/PCE/SGSIT/OFFS/BV-01-C 1. 测试项说明: Please initiate a GATT connection over BR/EDR to the PTS.Description: Verify that the Implementation Under Test (IUT) can initiate GATT connect request over BR/EDR to PTS.测试项名称: Ple…...

VIC-2D 7.0 为平面样件机械试验提供全视野位移及应变数据软件

The VIC-2D系统是一个完全集成的解决方案,它基于优化的相关算法为平面试样的力学测试提供非接触、全场的二维位移和应变数据,可测量关注区域内的每个像素子集的面内位移,并通过多种张量选项计算全场应变。The VIC-2D 系统可测量超过 2000%变形…...

深入理解Embedding Models(嵌入模型):从原理到实战(下)

🐇明明跟你说过:个人主页 🏅个人专栏:《深度探秘:AI界的007》 🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、什么是 Embedding 2、什么是嵌入模型 二、构建嵌入…...

labview硬件采集

(1)硬件的描述 (2)实验步骤1: (3)实验步骤2 库名/路径的选择要使用32位的开发资料 (4)实验步骤3 (5)实验步骤4 找到DoSetV12() 设置返回类型 设置chan 设置state labv…...

自动驾驶技术栈——DoIP通信协议

一、DoIP协议简介 DoIP,英文全称是Diagnostic communication over Internet Protocol,是一种基于因特网的诊断通信协议。 DoIP协议基于TCP/IP等网络协议实现了车辆电子控制单元(ECU)与诊断应用程序之间的通信,常用于汽车行业的远程诊断、远…...

uniapp引入七鱼客服微信小程序SDK

小程序引入七鱼sdk 1.微信公众平台引入2.代码引入3.在pagesQiyu.vue初始化企业appKey4.跳转打开七鱼客服 1.微信公众平台引入 账号设置->第三方设置->添加插件->搜索 QIYUSDK ->添加 2.代码引入 在分包中引入插件 "subPackages": [{"root":…...

【SSM-SpringMVC(二)】Spring接入Web环境!本篇开始研究SpringMVC的使用!SpringMVC数据响应和获取请求数据

SpringMVC的数据响应方式 页面跳转 直接返回字符串通过ModelAndView对象返回 回写数据 直接返回字符串返回对象或集合 页面跳转: 返回字符串方式 直接返回字符串:此种方式会将返回的字符串与视图解析器的前后缀拼接后跳转 RequestMapping("/con&…...

【AXI总线专题】AXI-FULL-Master

【AXI总线专题】AXI-FULL-Master 1.axi-full概述2.信号定义3.测试4.仿真波形5.附录clogb2函数axi4中的一些参数解释wishbone总线 6.工程文件 概述 参考文档: 《3-2-03米联客2022版AXI4总线专题-20211123.pdf》 《IHI0022E_amba_axi_and_ace_protocol_spec.pdf》 1.a…...

风车OVF镜像:解放AI开发限制的Ubuntu精简系统

风车OVF镜像:解放AI开发限制的Ubuntu精简系统 AI白嫖续杯一站式-风车ovf AI白嫖续杯一站式解决-风车ovf 前言 作为一名AI开发者,我经常在Windows和Linux环境之间切换开发。然而,Windows平台上的各种免费版限制逐渐成为我工作效率的瓶颈。在寻…...

降低60.6%碰撞率!复旦大学地平线CorDriver:首次引入「走廊」增强端到端自动驾驶安全性

导读 复旦大学&地平线新作-CorDriver: 首次通过引入"走廊"作为中间表征,揭开一个新的范式。预测的走廊作为约束条件整合到轨迹优化过程中。通过扩展优化的可微分性,使优化后的轨迹能无缝地在端到端学习框架中训练,从而提高安全…...

查看购物车

一.查看购物车 查看购物车使用get请求。我们要查看当前用户的购物车,就要获取当前用户的userId字段进行条件查询。因为在用户登录时就已经将userId封装在token中了,因此我们只需要解析token获取userId即可,不需要前端再传入参数了。 Control…...

11 配置Hadoop集群-免密登录

一、复习导入 前面的课程中我们在虚拟机上安装并测试使用了hadoop的示例程序wordcount,并且在准备好了集群的同步工具,那接下来,我们就可去配置hadoop集群了。 二、授新 (一)认识ssh命令 SSH(Secure Shell…...

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】金融风控分析案例-10.1 风险数据清洗与特征工程

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 PostgreSQL金融风控分析案例:风险数据清洗与特征工程实战一、案例背景:金融风控数据处理需求二、风险数据清洗实战(一)缺失值…...

《AI大模型应知应会100篇》第60篇:Pinecone 与 Milvus,向量数据库在大模型应用中的作用

第60篇:Pinecone与Milvus,向量数据库在大模型应用中的作用 摘要 本文将系统比较Pinecone与Milvus两大主流向量数据库的技术特点、性能表现和应用场景,提供详细的接入代码和最佳实践,帮助开发者为大模型应用选择并优化向量存储解…...

如何在通义灵码里使用 MCP 能力?

通义灵码编程智能体支持 MCP 工具使用,根据用户需求描述,通过模型自主规划,实现 MCP 工具调用,并深度集成国内最大的 MCP 中文社区——魔搭 MCP 广场,涵盖开发者工具、文件系统、搜索、地图等十大热门领域 2400 MCP 服…...

关于mac配置hdc(鸿蒙)

关于mac配置hdc(鸿蒙) 在最开始配置的hdc -v时候老是出现格式不匹配 于是乎在网上找官网也不行,最后在csdn上找到了这篇文章Mac配置hdc才有的头绪 环境变量的问题 自己做一个简单的总结 首先在访达里面打开ide 打开之后输入下面的命令,一步一步的找…...

几何_平面方程表示_点+向量形式

三维平面方程可以写成: π : n ⊤ X d 0 \boxed{\pi: \mathbf{n}^\top \mathbf{X} d 0} π:n⊤Xd0​ 📐 一、几何直观解释 ✅ 平面是“法向量 平面上一点”定义的集合 一个平面可以由: 一个单位法向量 n ∈ R 3 \mathbf{n} \in \mat…...

iOS safari和android chrome开启网页调试与检查器的方法

手机开启远程调试教程(适用于 Chrome / Safari) 前端移动端调试指南|适用 iPhone 和 Android|WebDebugX 出品 本教程将详细介绍如何在 iPhone 和 Android 手机上开启网页检查器,配合 WebDebugX 实现远程调试。教程包含…...

Matlab 模糊pid控制的永磁同步电机PMSM

1、内容简介 Matlab 226-模糊pid控制的永磁同步电机PMSM 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略基于模糊控制的高精度伺服速度控制器的设计与实现_刘京航...

ActiveMQ 高级特性:延迟消息与优先级队列实战(二)

三、优先级队列实战 3.1 优先级队列概念与应用场景 优先级队列是一种特殊的队列,与普通队列按照先进先出(FIFO)的规则不同,优先级队列中的元素按照其优先级进行排序,在消费消息时,高优先级的消息会优先被…...

ActiveMQ 高级特性:延迟消息与优先级队列实战(一)

引言 在当今的分布式系统开发中,消息中间件扮演着至关重要的角色,而 ActiveMQ 作为一款广泛使用的开源消息中间件,凭借其丰富的特性和良好的性能,深受开发者的青睐。它支持多种消息模型,如点对点和发布 / 订阅&#x…...

动手学深度学习12.4.硬件-笔记练习(PyTorch)

以下内容为结合李沐老师的课程和教材补充的学习笔记,以及对课后练习的一些思考,自留回顾,也供同学之人交流参考。 本节课程地址:31 深度学习硬件:CPU 和 GPU【动手学深度学习v2】_哔哩哔哩_bilibili 本节教材地址&am…...

LAN-402 全国产信号采集处理模块K7-325T(4通道采集)

UD LAN-402全国产化信号处理模块最多支持2通道16bit125Msps的短波采集(或2通道14bit250Msps超短波采集)、2通道16bit310Msps超短波采集,可选配XC7K325T、XC7K410T、JFM7K325T、JFM7K410T FPGA芯片,对外支持PCIe2.0x8接口、千兆网、…...

关于大语言模型的困惑度(PPL)指标优势与劣势

1. 指标本身的局限性 与人类感知脱节: PPL衡量的是模型对词序列的预测概率(基于交叉熵损失),但低困惑度未必对应高质量的生成结果。例如: 模型可能生成语法正确但内容空洞的文本(PPL低但质量差)…...

[Spring AOP 8] Spring AOP 源码全流程总结

Spring AOP总结 更美观清晰的版本在:Github 前面的章节: [Spring AOP 1] 从零开始的JDK动态代理 [Spring AOP 2] 从零开始的CGLIB动态代理 [Spring AOP 3] Spring选择代理 [Spring AOP 4] Spring AOP 切点匹配 [Spring AOP 5] 高级切面与低级切面&#…...

通信网络编程——JAVA

1.计算机网络 IP 定义与作用 :IP 地址是在网络中用于标识设备的数字标签,它允许网络中的设备之间相互定位和通信。每一个设备在特定网络环境下都有一个唯一的 IP 地址,以此来确定其在网络中的位置。 分类 :常见的 IP 地址分为 I…...

支持向量机算法

支持向量机(Support Vector Machine,SVM)作为机器学习领域中一颗耀眼的明星,凭借其卓越的分类与回归能力,在众多算法中独树一帜。它宛如一位精准的边界守护者,通过巧妙地构建超平面,将不同类别的…...

Redis集群模式、持久化、过期策略、淘汰策略、缓存穿透雪崩击穿问题

Redis四种模式 单节点模式 架构​​:单个Redis实例运行在单台服务器。 ​​优点​​: ​​简单​​:部署和配置容易,适合开发和测试。 ​​低延迟​​:无网络通信开销。 ​​缺点​​: ​​单点故障​​&…...

【WPF】Opacity 属性的使用

在WPF(Windows Presentation Foundation)中,Opacity 属性是定义一个元素透明度的属性,其值范围是从 0.0(完全透明)到 1.0(完全不透明)。由于 Opacity 是在 UIElement 类中定义的&…...

编程题 02-线性结构3 Reversing Linked List【PAT】

文章目录 题目输入格式输出格式输入样例输出样例 题解解题思路完整代码 编程练习题目集目录 题目 Given a constant K K K and a singly linked list L L L, you are supposed to reverse the links of every K K K elements on L L L. For example, given L being 1 → …...

集成指南:如何采用融云 Flutter IMKit 实现双端丝滑社交体验

在移动应用开发领域,跨平台框架的广泛应用已成为一种趋势。 融云跨平台方案持续升级,近期正式上线 Flutter IMKit,uni-app IMKit 也将紧随其后向广大开发者开放。覆盖两大跨平台核心框架,一套代码即可支持 Android、iOS 双端丝滑…...

使用vite重构vue-cli的vue3项目

一、修改依赖 首先修改 package.json,修改启动方式与相应依赖 移除vue-cli并下载vite相关依赖,注意一些peerDependency如fast-glob需要手动下载 # 移除 vue-cli 相关依赖 npm remove vue/cli-plugin-babel vue/cli-plugin-eslint vue/cli-plugin-rout…...

LeetCode 2094.找出 3 位偶数:遍历3位偶数

【LetMeFly】2094.找出 3 位偶数:遍历3位偶数 力扣题目链接:https://leetcode.cn/problems/finding-3-digit-even-numbers/ 给你一个整数数组 digits ,其中每个元素是一个数字(0 - 9)。数组中可能存在重复元素。 你…...

FLASH闪存(擦除、编译)

FLASH闪存 文章目录 FLASH闪存1.存储器映像位置2.FLASH简介3.闪存模块组织3.2闪存的共性: 4.FLASH基本结构4.1FLASH解锁4.2使用指针访问寄存器 5.选项字节5.1选项字节编程5.2选项字节擦除 6.相关函数介绍7.读取内部FLASH(实操)7.1接线图7.2工…...

企业即时通讯软件,私有化安全防泄密

在数字化转型与信创战略双重驱动下,企业对即时通讯工具的需求已从基础沟通转向安全可控、高效协同的综合能力。BeeWorks作为一款专为政企设计的私有化即时通讯与协同办公平台,凭借其全链路安全架构、深度国产化适配及灵活的业务集成能力,成为…...

直方图特征结合 ** 支持向量机图片分类

一、核心技术框架 1. 直方图特征原理 颜色直方图:统计图像中每个颜色区间(如 RGB 通道)的像素数量,反映颜色分布。HOG 直方图(方向梯度直方图):统计图像局部区域的梯度方向分布,捕…...

【prometheus+Grafana篇】基于Prometheus+Grafana实现windows操作系统的监控与可视化

💫《博主主页》: 🔎 CSDN主页 🔎 IF Club社区主页 🔥《擅长领域》:擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控;并对SQLserver、NoSQL(MongoDB)有了…...

PyTorch实战(4)——卷积神经网络(Convolutional Neural Network, CNN)详解

PyTorch实战(4)——卷积神经网络详解 0. 前言1. 全连接网络的缺陷2. 卷积神经网络基本组件2.1 卷积2.2 步幅和填充2.3 池化2.3 卷积神经网络完整流程 3. 卷积和池化相比全连接网络的优势4. 使用 PyTorch 构建卷积神经网络4.1 使用 PyTorch 构建 CNN 架构…...

【Python】Python常用控制结构详解:条件判断、遍历与循环控制

Python提供了多种控制结构来处理逻辑判断和循环操作,包括if-else条件分支、switch替代方案、遍历方法以及循环控制语句break和continue。以下是对这些功能的详细说明及示例: 一、条件判断:if-else与多分支结构 单分支结构 • 语法&#xff1…...

在Linux中安装JDK并且搭建Java环境

1.首先准备好JDK的Linux的安装包 2.打开Linux,进入root的文件夹,直接拖入即可 3.输入解压命令,后面指定的是位置(注意不要填写错误,就填写这个) 4.之后进入我们安装的jdk的文件 利用pwd命令,展示我们安装的目录,之后…...

理解多智能体深度确定性策略梯度MADDPG算法:基于python从零实现

引言:多智能体强化学习(MARL) 多智能体强化学习(MARL)将强化学习拓展到多个智能体在共享环境中相互交互的场景。这些智能体可能相互合作、竞争,或者目标混杂。MARL 引入了单智能体设置中不存在的独特挑战。…...

【AI大语言模型本质分析框架】

AI大语言模型本质分析框架 ——从教育危机到智能本质的七层递进式解构 第一层:现象观察——阴(显性危机)与阳(隐性变革)的共存 观点1(阴):AI作弊泛滥,传统教育体系崩溃…...

算法模型部署后_python脚本API测试指南-记录3

API 测试指南 服务运行后&#xff0c;可以通过以下方式测试&#xff1a; Curl: curl -X POST -F "file./test_dataset/surface/surface57.png" http://<服务器IP>:9000/api/v1/predictPython 脚本: (参考 svm_request测试.py) import requestsurl http://…...

鸿蒙(HarmonyOS)应用开发入门教程

目录 第一章:鸿蒙系统简介 1.1 什么是鸿蒙系统? 1.2 鸿蒙系统架构 第二章:开发环境搭建 2.1 安装DevEco Studio 步骤1:下载与安装 步骤2:首次配置 步骤3:设备准备 2.2 创建第一个项目 第三章:鸿蒙应用开发基础 3.1 核心概念:Ability与AbilitySlice 示例代码…...

MIT XV6 - 1.6 Lab: Xv6 and Unix utilities -uptime

接上文 MIT XV6 - 1.5 Lab: Xv6 and Unix utilities - xargs 第一章持续有点久了&#xff0c;虽然肯定有些特点和细节还没注意到&#xff0c;但这次的主要目的是学习内核部分&#xff0c;决定水一篇然后进入第二章节 uptime 第一章的最后一个实验&#xff0c;选做性质&#xf…...

Python语言在地球科学交叉领域中的应用——从数据可视化到常见数据分析方法的使用【实例操作】

前言&#xff1a; Python是功能强大、免费、开源&#xff0c;实现面向对象的编程语言&#xff0c;Python能够运行在Linux、Windows、Macintosh、AIX操作系统上及不同平台&#xff08;x86和arm&#xff09;&#xff0c;Python简洁的语法和对动态输入的支持&#xff0c;再加上解释…...

flutter 的 json序列化和反序列化

一、json转实体 Instantly parse JSON in any language | quicktype 二、实体中的toJson和fromJson 实现 官方推荐的 两个插件(个人觉得一个实体会多一个.g.dart 文件太多了&#xff0c;不喜欢) json_annotation json_serializable 三、使用 dart_json_mapper 实现上面的功…...

什么是数据集市(Data Mart)?

数据集市&#xff08;Data Mart&#xff09;是数据仓库&#xff08;Data Warehouse&#xff09;的一个子集&#xff0c;专门针对某个特定业务部门、业务线或主题领域&#xff0c;存储和管理该部门或领域所需的特定数据。它通常包含从企业范围的数据仓库中抽取、筛选和汇总的部分…...

从攻击者角度来看Go1.24的路径遍历攻击防御

目录 一、具体攻击示例 程序 攻击步骤&#xff1a; 二、为什么攻击者能成功&#xff1f; 分析 类比理解 总结 三、TOCTOU 竞态条件漏洞 1、背景&#xff1a;符号链接遍历攻击 2. TOCTOU 竞态条件漏洞 3. 另一种变体&#xff1a;目录移动攻击 4. 问题的核心 四、防…...

[ARM][汇编] 01.基础概念

目录 1.全局标号 1.1.使用方法 1.1.1.声明全局标号 1.1.2.定义全局标号 1.1.3.引用全局标号 1.2.全局标号与局部标号的区别 1.3.注意事项 2.局部标号 2.1.使用方法 2.1.1.定义局部标号 2.1.2.跳转引用 2.2.局部标号与全局标号的对比 2.3.注意事项 3.符号定义伪指…...