# MTK / Bluetooth ## GitHub [GitHub/MBP-bluetooth patch](https://github.com/leifliddy/macbook12-bluetooth-driver) [GitHub/MBP-sound driver](https://github.com/davidjo/snd_hda_macbookpro) [GitHub/bluez](https://github.com/bluez/bluez) [GitHub/bluez-alsa](https://github.com/Arkq/bluez-alsa) [GitHub/Bluez-GATT-HID-Keyboard-Emulator-Example](https://github.com/HeadHodge/Bluez-GATT-HID-Keyboard-Emulator-Example) [Google Git/Fluoride](https://android.googlesource.com/platform/system/bt/) [GitHub/coveragepy](https://github.com/nedbat/coveragepy) [GitHub/python-adb](https://github.com/google/python-adb) ## Domain Knowledge ### BT classic 1 by 1 * HFP * HID ... HF ![](https://i.imgur.com/1cL5Xl1.png) AG ![](https://i.imgur.com/0serlIl.png) ### BLE * GAP * GATT * HID Over Gatt Profile (HOGP) ... --- ### BAP #### CIG/CIS ![LE_Spec_Diagram_Update-1](https://hackmd.io/_uploads/r1gJSNUlex.png) ![image](https://hackmd.io/_uploads/BkHhD3dJll.png) Source ASE: ![image](https://hackmd.io/_uploads/SJkx_eIgee.png) Sink ASE: ![image](https://hackmd.io/_uploads/Sk6awe8lex.png) CIG: ![image](https://hackmd.io/_uploads/rJDVOxUegl.png) ### AOSP 準則對應模擬 log(連線 → 出聲 → 暫停 → 回復) ``` === GAP: Inquiry & Device Discovery === 05-05 14:00:00.100 I bt_gap: Start LE Inquiry (Active Scanning) 05-05 14:00:00.310 I bt_gap: Advertisement received: Name=LE_Headset, Addr=12:34:56:78:9A:BC, AdvData=[UUIDs=184E,1843,1844,1846] 05-05 14:00:00.315 I bt_gap: Classify remote device: TMAP_ROLE=Media Render, Call Render === GATT: Connection Establishment === 05-05 14:00:00.400 I bt_gatt: Connecting to 12:34:56:78:9A:BC 05-05 14:00:00.600 I bt_gatt: Connected. Starting Service Discovery... 05-05 14:00:00.650 I bt_gatt: Found service: PACS (0x184E) 05-05 14:00:00.651 I bt_gatt: Found service: ASCS (0x1843) 05-05 14:00:00.652 I bt_gatt: Found service: VCS (0x1844) 05-05 14:00:00.653 I bt_gatt: Found service: TMAS (0x1846) === PACS: Capability Discovery === 05-05 14:00:00.700 I bt_pacs: Sink PAC: Codec=LC3, Sampling=48000Hz, FrameDur=10ms 05-05 14:00:00.701 I bt_pacs: Sink Supported Contexts=MEDIA|CONVERSATIONAL 05-05 14:00:00.702 I bt_pacs: Sink Audio Locations=Front|Left|Right === ASCS + BAP: ASE Setup (with UNSPECIFIED context) === 05-05 14:00:00.750 I bt_bap: Allocating ASE[1] for Sink 05-05 14:00:00.755 I bt_bap: Configuring ASE[1]: Codec=LC3, FrameDur=10ms, Location=Front 05-05 14:00:00.756 I bt_bap: Initial context = UNSPECIFIED (0x0000) 05-05 14:00:00.760 I bt_bap: ASE[1] state changed: IDLE → CONFIGURED === ASCS: QoS Configuration === 05-05 14:00:00.800 I bt_bap: QoS Setup: Interval=10ms, PHY=2M, Framing=Framed 05-05 14:00:00.805 I bt_bap: ASE[1] state changed: CONFIGURED → QOS_CONFIGURED === ISO Channel Setup (CIS) === 05-05 14:00:00.850 I bt_iso: Creating CIG#1 with 1 CIS 05-05 14:00:00.860 I bt_iso: CIS[1] created, ISO_Handle=0x0101, Latency=20ms 05-05 14:00:00.880 I bt_iso: ISO Channel Established with 12:34:56:78:9A:BC === [Runtime Update] Audio Context Update === 05-05 14:00:00.900 I bt_bap: Updating Audio Context for ASE[1]: MEDIA (0x0001) 05-05 14:00:00.901 I bt_bap: Context Type updated: UNSPECIFIED → MEDIA === ASCS: Enable & Stream Start === 05-05 14:00:00.910 I bt_bap: Enabling ASE[1] 05-05 14:00:00.912 I bt_bap: ASE[1] state changed: QOS_CONFIGURED → ENABLING 05-05 14:00:00.915 I bt_bap: ASE[1] state changed: ENABLING → STREAMING === Audio Framework === 05-05 14:00:00.920 I audio_policy: Routing playback to LE Headset (device=LE_AUDIO) 05-05 14:00:00.923 I audio_track: Starting music stream session=0x4000 05-05 14:00:00.930 I audio_hw_bluetooth: Opened LE Audio stream: Codec=LC3, SampleRate=48000, FrameDur=10ms 05-05 14:00:00.940 I bt_iso: LC3 frame transmission begins on ISO_Handle=0x0101 05-05 14:00:00.950 I bt_iso: LC3 frame seq=0 sent 05-05 14:00:00.960 I bt_iso: LC3 frame seq=1 sent 05-05 14:00:00.970 I bt_iso: LC3 frame seq=2 sent 05-05 14:00:00.975 I bt_bap: ASE[1] streaming active, packets flowing === [User Action] Pause Media Playback === 05-05 14:02:10.500 I audio_track: Pause music stream session=0x4000 05-05 14:02:10.510 I audio_policy: Stopping routing to LE Audio (device=LE_AUDIO) 05-05 14:02:10.520 I bt_bap: Sending Disable ASE[1] to sink device 05-05 14:02:10.525 I bt_bap: Remote ASE[1] state changed: STREAMING → QOS_CONFIGURED 05-05 14:02:10.530 I bt_iso: LC3 frame transmission halted (ISO_Handle=0x0101) === [User Action] Resume Media Playback === 05-05 14:02:15.200 I audio_policy: Routing music stream to LE Audio (device=LE_AUDIO) 05-05 14:02:15.210 I audio_track: Resume music stream session=0x4000 05-05 14:02:15.220 I bt_bap: Sending Enable ASE[1] to sink device 05-05 14:02:15.221 I bt_bap: Remote ASE[1] state changed: QOS_CONFIGURED → ENABLING 05-05 14:02:15.225 I bt_bap: Remote ASE[1] state changed: ENABLING → STREAMING 05-05 14:02:15.230 I bt_iso: LC3 frame transmission restarted on ISO_Handle=0x0101 05-05 14:02:15.240 I bt_iso: LC3 frame seq=0 sent 05-05 14:02:15.250 I bt_iso: LC3 frame seq=1 sent ``` ``` coding round 模擬題目 1. 實作 multi-thread command queue 發送機制 2. 實作 BAP ASE state machine 切換機制 3. 1. 延伸實作 event 接收 callback function using PackReadCallback class ``` CR: BAP/ADSP: 耳機端雜音/無聲 -> Host端首先排查 sample freq, frame duration 等參數設定是否正常,VCP volume 相關 log 設置,確認問題時間點附近對應 sink ASE 為 streaming 接著確認 main log/hci log 無聲時間點附近 CIG/CIS/iso data path 是否存在 由於 off-load 接著檢查audio hal打印出的log確認下給 ADSP 端參數是否正確 最後是檢查 ADSP 端的 log 確認封包是否有在指定時間完成加密送出 單耳回連雜音/無聲 context轉換雜音/無聲 seldom出現的掉包問題,是由於ADSP上架構調整從單核擴展為多核時並未仔細考慮 IRQ handler 導致的 root cause: 1. 由於 ADSP 硬體架構上兩顆核心與 BT MCU 間共享一根 phy link, 2. 由於歷史遺留問題同一組封包 BT MCU 可能會發送多次中斷,會導致傳送空包造成耳機端解碼出氣泡音,因此在 IRQ handler 裡 mask 掉了 BT MCU 的中斷訊號 ``` void irq_handler() { clr_cr(); queue_work(encode); set_cr(); } ``` solution: 架構上修改為 ADSP core0 負責收發 BT MCU 的中斷訊號並根據任務內容發派至指定核心進行 --- HCI/HAL/Driver: HCI層較常出現的問題則是壓力測試時出現過 start_up_timer_expired 導致大量 NE 的問題 最初設想的改動是通過修改 BT Stack 中的 timer_expired 的行為,改為主動重啟但不觸發 NE 但由於 BT Stack 中存在多個 timer 且由於 mainline 的推動所以改動擱置 此外有出現過的問題是由於 HCI layer cmd/evt 的對應檢查機制與 sniff subrating event 上報衝突導致出現 NE 具體來說是由於 HCI layer 會檢查所有通過的 HCI cmd/evt 確保其一一對應 若有 HCI event 卻無對應的 HCI cmd 下發就會 trigger NE 因此該問題最後是透過修改 event 為 vendor specific event 並新增 sniff event 至 pdl 中 vendor specific event 欄位下解決 --- HAL層最常發生的問題則是 binder transction fail 這通常也是 system resource 不足所導致的 issue 能透過 ftrace double check 系統資源是被哪支 process 占用 測試時會使用三種load分別是 user/user-debug/engineer load 其中使用 engineer load 時對 CPU 使用量的限制最小,因此可能導致類似的問題 此外也可能是硬體版本與 init script 不符導致晶片初始化失敗的問題 由於MTK是將BT MCU init流程編譯成對應的shard lib並通過HAL層下發進行硬體初始化命令 整體流程 HAL 呼叫 BT Driver 進行 FW download (patch dl) MCU init,將 MCU 帶到 idle loop 接著 HAL 層開啟 shard lib 根據 property 設定針對Consys硬體下發 MCU 初始參數設定 最後通過 HAL 回應 Stack BT HAL ready --- AIDL開發 關於新版 HAL 的部分則是沿用 AOSP BT AIDL interface 介面並新增相關 debug 機制 主要目的是由於部分已MP的產品無法取得詳細的mainlog/hcilog/kernellog分析問題 我希望能通過 bugreport 主動調用 HAL 中的 dump methods 由於 MTK HAL 有相關的 debug 機制,我們能通過調用 dump 打印最後幾包 BT 的 TRX 來還原現場 開發中涉及修改對應 bt stack sepolicy,確保 BT stack 能正確調用到 AIDL 服務 與由於 VendorFreeze 修改 Makefile 僅讓新版 Android 調用 AIDL HAL SLT開發 開發該 SLT 目的是測試 BT Radio HW 開發流程是由 FW 提供 pattern 並由我這邊實現相關的 code 透過 BT Driver 從 golden board 經 RF cable 發送至 DUT 端 使用方法是會有兩塊 EVB 並各一塊golden radio/DUT radio 以Driver端來問題表象主要是由於RX timeout導致Stack藍牙重啟 root cause: cpu 被其他 kernel module 占用,導致的系統性問題 藍牙 kernel module 發生 deadlock -> 使用 syzkaller 打出,設計不良導致multi-user 場景下BT_open的過程中鎖的沒有適當釋放產生的 KE void BT_open() { int state = down_trylock(lock1); if (state == NOT_ACQUIRE) { return; } /*do some Control Reg setting*/ state = down_trylock(lock2); if (state == NOT_ACQUIRE) { // we didn't free lock1 return; } } ## Implementation ```bash dbus-send --system --print-reply --dest=org.ofono /hfp/org/bluez/hci0/dev_05_BA_8D_DF_B7_9C org.ofono.VoiceCallManager.Dial string:"1234567890" string:"default" ``` ### Issue [GitHub/pybluez#161](https://github.com/pybluez/pybluez/issues/161) [GitHub/pybluez#307](https://github.com/pybluez/pybluez/issues/307) ### Environment Macbook pro 14,1 / Ubuntu 20.04 LTS / Linux kernel 5.8.0-59-generic with kernel patch for Macbook Bluetooth [above](#GitHub) ### Architecture ## Experiment ## Reference [HCI command](https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host-controller-interface/host-controller-interface-functional-specification.html) [AOSP BT Stack](https://cs.android.com/android/platform/superproject/main/+/main:packages/modules/Bluetooth/system/gd/?hl=zh-tw) [HFP spec](https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=292287) [HID spec](https://www.bluetooth.org/docman/handlers/DownloadDoc.ashx?doc_id=246761) [Style Guide](https://google.github.io/styleguide/pyguide.html) [Socket](http://zake7749.github.io/2015/03/17/SocketProgramming/) [Socket Reconnect](https://blog.csdn.net/xpj8888/article/details/88592670) [Bluetooth shortcut](https://ithelp.ithome.com.tw/articles/10252873) [Bluez DBus usage](https://blog.csdn.net/Archer1991/article/details/62233164?locationNum=16&fps=1) [Bluez Gatt App](https://punchthrough.com/creating-a-ble-peripheral-with-bluez/) [Dbus spec](https://dbus.freedesktop.org/doc/dbus-specification.html) [dbus note](https://foreachsam.github.io/book-util-dbus/book/content/command/dbus-send/) [dbus-send](https://segmentfault.com/a/1190000023501116) [Bluez Overall](https://download.tizen.org/misc/media/conference2012/wednesday/bayview/2012-05-09-0900-0940-bluez-_plugging_the_unpluggable.pdf) [Code Coverage](https://zh.wikipedia.org/wiki/%E4%BB%A3%E7%A2%BC%E8%A6%86%E8%93%8B%E7%8E%87) [JaCoCo for android](https://www.tpisoftware.com/tpu/articleDetails/2374) [JaCoCo](https://jeremykao.gitbooks.io/learning-jacoco/content/) [AOSP compile](https://c55jeremy-tech.blogspot.com/2019/04/aosppixel-2-romrom.html) [Unit Test vs. Integration Test](https://ngeor.com/2018/08/11/code-coverage-on-integration-tests.html)