【android bluetooth 案例分析 03】【PTS 測試 】【PBAP/PCE/SSM/BV-10-C】

1. PBAP/PCE/SSM/BV-10-C

[PCE Does not share PbapSupportedFeatures bits]

這個 PTS 測試用例 PBAP/PCE/SSM/BV-10-C 的核心目的是驗證 PBAP 客戶端(PCE)在與舊版服務器通信時不會發送 PbapSupportedFeatures 特性位,以確保兼容性和標準符合性。

1. 測試目標

Verify that the PCE does not share its PbapSupportedFeatures bits with a legacy server.

目的:驗證 PCE(Phonebook Client Equipment)在與一個不支持 PbapSupportedFeatures SDP 屬性的 legacy(傳統)PBAP Server 建立連接時,不應在 OBEX CONNECT 請求中包含 PbapSupportedFeatures Header

這是為了保證新版本設備與老版本設備之間的向后兼容性。

2. 參考

[PBAP 1.2] 6.3節: 明確指出當 Server 的 SDP 中沒有 PbapSupportedFeatures 屬性時,Client 不應在 OBEX CONNECT 請求中發送該 Header 字段。

3. 測試條件

  • The IUT and the Lower Tester have been paired.

  • Lower Tester: The Lower Tester is in discoverable and connectable mode. The Lower Tester
    does not have a PbapSupportedFeatures attribute in its SDP record.

  • IUT(被測設備)和 Lower Tester 已配對。

  • Lower Tester 是 PBAP Server,并處于:

    • Discoverable + Connectable 狀態
    • 其 SDP 記錄中不含 PbapSupportedFeatures 屬性

4. 測試流程

  • Lower Tester 啟動并廣播自己的 SDP 信息(無 PbapSupportedFeatures 屬性)。
  • IUT(PCE) 嘗試發起 PBAP 連接。
  • 觀察 IUT 的 OBEX CONNECT 請求內容

5.預期流程

OBEX CONNECT 請求中

  • 不得包含 PbapSupportedFeatures Header(0xFB)
  • 若包含此字段,則視為 FAIL

6.如何判斷測試是否通過

抓包(如使用 Wireshark + Bluetooth HCI log)時,查看:

  • OBEX CONNECT 請求幀中是否包含 header ID 為 0xFB
  • 如果沒有,則測試通過

2. 真實測試案例

Test case : PBAP/PCE/SSM/BV-10-C started
- version=0x0102  rfcommPsm=0x02  l2capPsm=0x1005  supportRepositories=0x0f  supportedFeatures=0x00000000 
- Final supported Feature 0
- OBEX Connect request contains SupportedFeatures ApplicationParameter
- Received HCI disconnection event. Handle = 0x0063-Final Verdict: FAIL
PBAP/PCE/SSM/BV-10-C finished

1. pts 側

在這里插入圖片描述

  1. 車機向 PTS 發起了 SDP
  2. 但是 PTS SDP中回復了兩個 AttributeList

第一個 Attribute List如下
在這里插入圖片描述

  • 支持協議 V1.2
  • 可以通過 l2cap psm: 0x1005 對應十進制:4101
  • 支持 supported features.
  • 可以通過 RFCOMM 通道 2 連接

第二個 Attribute List 如下
在這里插入圖片描述

  • 支持協議 v.1.0
  • 可以通過 RFCOMM 通道 2 連接

這個 PTS 測試用例 PBAP/PCE/SSM/BV-10-C 的核心目的是驗證 PBAP 客戶端(PCE)在與舊版服務器通信時不會發送 PbapSupportedFeatures 特性位,以確保兼容性和標準符合性。

  • 也就是說 車機應該去連接 V1.0 這個。

2. 車機側

在這里插入圖片描述

# 車機收到第一個 UUID  也就是 v1.2
04-25 12:04:14.238917  6075  6075 I PbapClientStateMachine: Received UUID: 0000112f-0000-1000-8000-00805f9b34fb
04-25 12:04:14.239812  6075  6498 I PbapClientConnHandler: Handling Message = 1
# 使用 l2cap psm 0x1005 已經去連接了
04-25 12:04:14.239949  6075  6498 V PbapClientConnHandler: connectSocket: PSM: 410104-25 12:04:14.321776  6075  6498 D PbapClientConnHandler: Socket connected
04-25 12:04:14.321849  6075  6498 V PbapClientConnHandler: Start Obex Client Session
04-25 12:04:14.327761  6075  6498 D PbapClientConnHandler: Remote PbapSupportedFeatures 0
04-25 12:04:14.373370  6075  6498 D PbapClientConnHandler: Success = true# 車機收到 第二個 UUID  v1.0
04-25 12:04:14.239991  6075  6075 I PbapClientStateMachine: Received UUID: 0000112f-0000-1000-8000-00805f9b34fb04-25 12:04:14.373594  6075  6498 I PbapClientConnHandler: Handling Message = 1# 使用 rfcomm channle 2 去連, 連失敗了。
04-25 12:04:14.373891  6075  6498 V PbapClientConnHandler: connectSocket: channel: 2
04-25 12:04:14.471800  6075  6498 E PbapClientConnHandler: Error while connecting socket
04-25 12:04:14.471800  6075  6498 E PbapClientConnHandler: java.io.IOException: read failed, socket might closed or timeout, read ret: -1
  • 其實第一次 使用 v1.2 去連的時候,已經下發了 PbapSupportedFeatures , 所以 測試失敗了。

3. 解決辦法

通過上面的分析,我們可以清晰的看到, 車機在這個測試中,不應該處理 v1.2 的連接。 應該去連接 v1.0

  • 那我們就按照這個思路來做調整。

3. 代碼分析

// android/app/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandler.java@Overridepublic void handleMessage(Message msg) {if (DBG) {Log.i(TAG, "Handling Message = " + msg.what);}switch (msg.what) {case MSG_CONNECT:mRetryTime = 0;case MSG_RECONNECT:mPseRec = (SdpPseRecord) msg.obj; // 將 SDP 賦值給 mPseRec/* To establish a connection, first open a socket and then create an OBEX session */if (connectSocket()) {} else {return;}if (connectObexSession()) {} else {}break;}return;}

整個 連接邏輯其實很簡單,當SDP 結束后,會觸發 PbapClientConnectionHandler 處理 MSG_CONNECT 消息。

  1. 調用 connectSocket()
  2. 如果第一步調用成功,調用 connectObexSession()
    synchronized boolean connectSocket() { try {/* Use BluetoothSocket to connect */if (mPseRec == null) {// BackWardCompatability: Fall back to create RFCOMM through UUID.if (VDBG) Log.v(TAG, "connectSocket: UUID: " + BluetoothUuid.PBAP_PSE.getUuid());mSocket =mDevice.createRfcommSocketToServiceRecord(BluetoothUuid.PBAP_PSE.getUuid());} else if (mPseRec.getL2capPsm() != L2CAP_INVALID_PSM) { // 由于 V1.2 中 L2cap 的 PCM 是  0x1005   對應十進制:4101  , 這里有限去連接  v1.2 if (SystemProperties.getBoolean("xxx.bluetooth.pts.pbap.pce.ssm.bv-10-c", false)) {Log.d(TAG, "pts test, pbap.pce.ssm.bv-10-c");} else {if (VDBG)Log.v(TAG, "connectSocket: PSM: " + mPseRec.getL2capPsm());mSocket = mDevice.createL2capSocket(mPseRec.getL2capPsm()); // 也就是 v1.2 是使用 l2cap 通道去 連接 obex 的。}} else {// 這里是 v1.0 的邏輯, 使用 rfcomm  channel:2 去連接 obexif (VDBG) Log.v(TAG, "connectSocket: channel: " + mPseRec.getRfcommChannelNumber());mSocket = mDevice.createRfcommSocket(mPseRec.getRfcommChannelNumber());}if (mSocket != null) {mSocket.connect();return true;} else {Log.w(TAG, "Could not create socket");}} catch (IOException e) {Log.e(TAG, "Error while connecting socket", e);}return false;}
  • 上面已經給出了處理辦法,就是在當前測試環境中,不去連 v1.2 協議。

  • 第一步,只是 決定了 當前 上層obex 走那種通道, 是直接走 l2cap, 還是 走 rfcomm->l2cap 方式

那還有一個疑問, 測試提到的 PbapSupportedFeatures 是在哪里設置的呢?

繼續看 第二步 connectObexSession

boolean connectObexSession() {boolean connectionSuccessful = false;try {if (VDBG) {Log.v(TAG, "Start Obex Client Session");}BluetoothObexTransport transport = new BluetoothObexTransport(mSocket);mObexSession = new ClientSession(transport);mObexSession.setAuthenticator(mAuth);HeaderSet connectionRequest = new HeaderSet();connectionRequest.setHeader(HeaderSet.TARGET, PBAP_TARGET);if (mPseRec != null) {if (DBG) {Log.d(TAG, "Remote PbapSupportedFeatures " + mPseRec.getSupportedFeatures());}ObexAppParameters oap = new ObexAppParameters();if (mPseRec.getProfileVersion() >= PBAP_V1_2) { // 如何是 v1.2 就會去添加 PbapSupportedFeatures, 如何是 1.0 跳過oap.add(BluetoothPbapRequest.OAP_TAGID_PBAP_SUPPORTED_FEATURES,PBAP_SUPPORTED_FEATURE);}oap.addToHeaderSet(connectionRequest);}HeaderSet connectionResponse = mObexSession.connect(connectionRequest); // 這里會去發起 obex 的連接請求connectionSuccessful =(connectionResponse.getResponseCode() == ResponseCodes.OBEX_HTTP_OK);if (DBG) {Log.d(TAG, "Success = " + Boolean.toString(connectionSuccessful));}} return connectionSuccessful;}

4.整改后的

在這里插入圖片描述

# 收到 sdp
04-25 13:22:04.301633  5766  5766 I PbapClientStateMachine: Received UUID: 0000112f-0000-1000-8000-00805f9b34fb
04-25 13:22:04.302432  5766  5766 I PbapClientStateMachine: Received UUID: 0000112f-0000-1000-8000-00805f9b34fb# v1.2 連接失敗
04-25 13:22:04.303335  5766  6197 I PbapClientConnHandler: Handling Message = 1
04-25 13:22:04.303911  5766  6197 D PbapClientConnHandler: pts test, pbap.pce.ssm.bv-10-c
04-25 13:22:04.304104  5766  6197 W PbapClientConnHandler: Could not create socket 
04-25 13:22:04.304145  5766  6197 W PbapClientConnHandler: Socket CONNECT Failure # v1.0 連接成功
04-25 13:22:04.304193  5766  6197 I PbapClientConnHandler: Handling Message = 1
04-25 13:22:04.304238  5766  6197 V PbapClientConnHandler: connectSocket: channel: 2
04-25 13:22:04.419481  5766  6197 D PbapClientConnHandler: Socket connected
04-25 13:22:04.419564  5766  6197 V PbapClientConnHandler: Start Obex Client Session
04-25 13:22:04.425265  5766  6197 D PbapClientConnHandler: Remote PbapSupportedFeatures 0
04-25 13:22:04.483244  5766  6197 D PbapClientConnHandler: Success = true
04-25 13:22:04.483363  5766  6197 I PbapClientConnHandler: Handling Message = 257
04-25 13:22:04.483404  5766  6197 D PbapClientConnHandler: pts test, pbap.pce.ssm.bv-10-c

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/903602.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/903602.shtml
英文地址,請注明出處:http://en.pswp.cn/news/903602.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

批量刪除OpenStack實例

在Linux終端實現批量刪除OpenStack實例,支持并發刪除、安全確認、重試機制、優先清理運行中實例 #!/bin/bash # # 增強版 OpenStack 刪除實例腳本 # 功能:支持并發刪除、安全確認、重試機制、優先清理運行中實例 # 更新:2025年4月30日 # ##…

# 基于 Python 和 jieba 的中文文本自動摘要工具

基于 Python 和 jieba 的中文文本自動摘要工具 在信息爆炸的時代,快速準確地提取文本核心內容變得至關重要。今天,我將介紹一個基于 Python 和 jieba 的中文文本自動摘要工具,幫助你高效地從長文本中提取關鍵信息。 一、背景與需求 在處理…

Seaborn數據可視化庫

一、Seaborn介紹:基于Matplotlib的Python數據可視化庫,專注繪制統計圖形,簡化可視化過程,提供高級接口和美觀默認主題。 二、安裝與導入 1.安裝:可使用pip install seaborn或conda install seaborn,也可使…

機器視覺2D碼垛和機器視覺3D碼垛的區別

機器視覺3D碼垛是一種結合3D視覺技術和工業機器人的自動化系統,主要用于在復雜環境中精準識別、定位并堆疊(碼垛)各種形狀、尺寸的物體。它通過3D傳感器(如激光雷達、結構光相機、雙目視覺等)獲取物體的三維空間信息,并結合算法規劃機器人的抓取路徑和碼放策略,實現高效…

Python魔法函數深度解析

一、魔法函數是什么? 魔法函數(Magic Methods)是Python中以雙下劃線(__xx__)包裹的特殊方法,它們為類提供了一種與Python內置語法深度集成的能力。這些方法由解釋器自動調用,無需顯式調用&…

C++負載均衡遠程調用學習之自定義內存池管理

目錄 1.內存管理_io_buf的結構分析 2.Lars_內存管理_io_buf內存塊的實現 3.buf總結 4.buf_pool連接池的單例模式設計和基本屬性 5.buf_pool的初始化構造內存池 6.buf_pool的申請內存和重置內存實現 7.課前回顧 1.內存管理_io_buf的結構分析 ## 3) Lars系統總體架構 ? …

流水線問題(算法設計)C++

目錄 一、需求分析 1.1 問題描述 1.2 數據需求 1.3 功能需求 1.4 開發環境 二、概要設計 2.1 抽象數據類型 ADT 的定義 2.2 系統的主要功能模塊 2.3 功能模塊聯系圖 三、詳細設計 3.1 數據結構設計 3.2 主要算法 四、系統運行及結果分析 1. 用戶界面 2. 程序運行…

從實列中學習linux shell4: shell 腳本中 $0 $1 $2 $3 >> 以及 awk 都是干啥的?

在 Linux Shell 腳本中,這些符號和工具的功能如下: 一、位置參數 $0 $1 $2 $3 符號功能說明示例$0腳本自身的文件名若執行 ./test.sh,則 $0 值為 ./test.sh$1第一個參數執行 ./test.sh apple 時,$1 值為 "apple"$2第二…

TM1668芯片學習心得三

一、鍵掃數據儲存地址如下所示,先發讀鍵命令后,開始讀取按鍵數據BYTE1-BYTE5字節,讀數據從低位開始輸出,其中B6和B7位為無效位,此時芯片輸出為0。芯片K和KS引腳對應的按鍵按下時,相對應的字節內的 BIT位為1…

MySQL 基本查詢(一)

文章目錄 Create(insert)指定列的單行插入和全列插入多行全列插入和指定列的多行插入如果主鍵存在,要插入替換存在的值replace 基本select全列查詢指定列查詢where子句where子句案例語文成績在 [80, 90] 分的同學及語文成績數學成績是 58 或者 59 或者 98 或者 99 分…

LeetCode路徑總和系列問題解析:I、II、III的解決方案與優化

文章目錄 引言一、路徑總和 I(LeetCode 112)問題描述方法思路Java代碼實現復雜度分析 二、路徑總和 II(LeetCode 113)問題描述方法思路Java代碼實現復雜度分析 三、路徑總和 III(LeetCode 437)問題描述方法…

NFC 碰一碰發視頻貼牌技術,音頻功能的開發實踐與技術解析

在數字化營銷與信息交互場景中,NFC 碰一碰技術憑借其便捷性和高效性,成為快速傳遞多媒體內容的新選擇。通過 NFC 實現視頻音頻的快速傳輸,不僅能提升用戶體驗,還能為各類場景帶來創新應用。本文將深入探討該功能開發過程中的關鍵技…

跨境電商生死劫:IP篩查三法則破解封號魔咒

一、血淚數據:90%封號案源于IP污染 跨境電商平臺風控系統持續升級,2023年亞馬遜全球封號案例中,67%涉及賬號關聯(Marketplace Pulse數據),其中IP問題占比高達91%。更觸目驚心的是: 新號存活率&…

MIPS架構詳解:定義、應用與其他架構對比

一、MIPS架構的定義 MIPS(Microprocessor without Interlocked Pipeline Stages) 是一種經典的精簡指令集(RISC)處理器架構,由斯坦福大學John Hennessy團隊于1981年提出,強調高效流水線設計和硬件簡化。 核…

第十六屆藍橋杯 2025 C/C++組 脈沖強度之和

目錄 題目: 題目描述: 題目鏈接: 思路: 思路詳解: 代碼: 代碼詳解: 題目: 題目描述: 題目鏈接: P12338 [藍橋杯 2025 省 B/Python B 第二場] 脈沖強度…

從Ping到iperf3:深度實戰無線網絡壓測與優化指南

以下是測試無線網絡穩定性的詳細步驟與工具指南,涵蓋信號質量、吞吐量、干擾排查等關鍵維度: 一、基礎信號質量測試 1. 信號強度與覆蓋測試 工具:手機APP(WiFi Analyzer、NetSpot)或筆記本(Acrylic WiFi&a…

MySQL 連接池 (Pool) 常用方法詳解

MySQL 連接池 (Pool) 常用方法詳解 1. 創建連接池 首先需要創建連接池實例: const mysql require(mysql2/promise); // 使用Promise版本const pool mysql.createPool({host: localhost,user: root,password: password,database: test,waitForConnections: true…

大型連鎖酒店集團數據湖應用示例

目錄 一、應用前面臨的嚴峻背景 二、數據湖的精細化構建過程 (一)全域數據整合規劃 (二)高效的數據攝取與存儲架構搭建 (三)完善的元數據管理體系建設 (四)強大的數據分析平臺…

GNU gettext 快速上手

文章目錄 1.簡介2.核心概念國際化 (i18n)本地化 (l10n)POT 文件PO 文件MO 文件文本域翻譯函數 3.主要組件4.使用示例參考文獻 1.簡介 GNU gettext 是一套用于軟件國際化(internationalization,i18n)和本地化(localization&#x…

分享:VTK版本的選擇 - WPF空域問題

在早期版本中,ActiViz 對 Windows Presentation Foundation (WPF) 框架的支持是通過 WindowsFormHost 組件實現的,這種方式依賴于 WindowsForm 和 WPF 的互操作性。然而,這種方法存在一個眾所周知的“空域問題”(airspace issue&a…