android 4.0 藍芽分析之二

慢慢的燃燒發表於2017-03-24
原址

packages/apps/Settings/src/com/Android/settings/bluetooth/BluetoothSettings.Java

onCreateOptionsMenu(Menu menu, MenuInflater inflater)

建立選單,裡面有MENU_ID_SCANMENU_ID_RENAME_DEVICEMENU_ID_VISIBILITY_TIMEOUTMENU_ID_SHOW_RECEIVED

 

onOptionsItemSelected(MenuItem item)

選單對應的執行操作

1Bluetoothd daemon

external/bluetooth/bluez/src/main.c

main

       |——init_defaults   填充main_opts

       |——g_option_context_new  下面四步是引數解析相關

       |——g_option_context_add_main_entries

       |——g_option_context_parse

       |——g_option_context_free

       |——daemon(0, 0) 引數為0,則將輸出都定向到/dev/null

       |——__btd_log_init       列印一些log

       |——agent_init

              |——connection = dbus_bus_get (DBUS_BUS_SYSTEM, NULL)

       |——connect_dbus()

              |——g_dbus_setup_bus  註冊dbus連線,並重新命名為"org.bluez"

              |——manager_init(conn, "/")  設定base_path

                     |——g_dbus_register_interface 註冊interface,包括medhod,signal

              |——set_dbus_connection(conn)  設定connectionconn

       |——start_sdp_server 初始化sdp協議

              |——init_server

                     |——建立l2cap_sock套接字

                     |——bind  l2cap_sock

                     |——listen  l2cap_sock

                     |——listen  unix_sock

              |——io = g_io_channel_unix_new(l2cap_sock)

              |——g_io_add_watch(io,, io_accept_event, &l2cap_sock) 等待對方connect

                     |——accept  l2cap_sock/unix_sock操作

       |——plugin_init

              |——執行plugin init

       |——g_main_loop_new

       |——adapter_ops_setup

              |——ops->setup()

       |——rfkill_init       電源操作

       |——g_main_loop_run

/**********************     main結束  ************************/

 

hciops_init

       |——btd_register_adapter_ops(&hci_ops, FALSE);

              |——g_slist設定,ops儲存

 

hciops_setup

       |——socket(,SOCK_RAW, BTPROTO_HCI)

              |——hci_filter_set_ptype  HCI_EVENT_PKT/EVT_STACK_INTERNAL設定過濾

              |——setsockopt(,,HCI_FILTER, &flt,)

              |——bind

              |——g_io_add_watch(,,io_stack_event,)

              |——g_idle_add(init_known_adapters,)

init_known_adapters

       |——ioctl  HCIGETDEVLIST

       |——init_device

              |——hci_open_dev

              |——start_hci_dev

                     |——setsockopt  HCI_FILTER設定event事件過濾

                     |——g_io_add_watch_full  io_security_event  檢測event事件

              |——ioctl  HCISETLINKMODE

              |——ioctl  HCIDEVUP

       |——device_event  HCI_DEV_UP

 

device_devup_setup

       |——hci_send_cmd(,,READ_STORED_LINK_KEY_CP_SIZE,)

              |——init_adapter(index)

                     |——btd_manager_register_adapter

                            |——adapter_create

                                   |——g_dbus_register_interface 註冊interface

                            |——adapter_init 讀取bdaddr,name,features

                            |——g_dbus_emit_signal “AdapterAdded”  to "org.bluez.Manager"

                            |——manager_update_adapters

                                   |—— sned signal "PropertyChanged" value "Adapters"

                            |——manager_set_default_adapter

                                   |——send signal “DefaultAdapterChanged

                     |——start_adapter

                            |——set_event_mask

                            |——set DEFAULT_LINK_POLICY

                     |——btd_adapter_start

                            |——send signal "PropertyChanged" value "Powered"

 

 

(2)藍芽服務啟動

SystemServer

       |―― bluetooth.initAfterA2dpRegistration();

              |―― mEventLoop.getProfileProxy();

                     |―― mAdapter.getProfileProxy(, ,BluetoothProfile.A2DP);

                            |―― a2dp = new BluetoothA2dp(context, listener);

                                   |―― mServiceListener.onServiceConnected(BluetoothProfile.A2DP,);

                                          |―― mService = (BluetoothA2dp) proxy;

                     |―― mAdapter.getProfileProxy(, ,BluetoothProfile. INPUT_DEVICE);

                            |―― iDev = new BluetoothInputDevice(context, listener);

 

(3)enable過程

LocalBluetoothAdapter.enable()

       |―― mAdapter.enable();

              |―― mService.enable();

                     |―― mBluetoothState.sendMessage(USER_TURN_ON, saveSetting);

                            |―― broadcastState(BluetoothAdapter.STATE_TURNING_ON);

                            |―― prepareBluetooth();

                                   |―― mBluetoothService.enableNative();

                                          |―― bt_enable();

 

4scan過程

BluetoothSettings

|―― onPreferenceTreeClick              KEY_BT_SCAN  點選scan

       |―― mLocalAdapter.startScanning(true);

                     |―― a2dp.isA2dpPlaying() – return; 如果A2DP正在播放,則退出

                     |―― mAdapter.startDiscovery()

                            |―― mService.startDiscovery()

                                   |―― startDiscoveryNative()

                                          |―― dbus介面 -- StartDiscovery

                                                 |―― adapter_start_discovery    bluez中接收到

                                                        |―― start_discovery(adapter);

                                                               |―― hciops_start_discovery

                                                                      |­―― hciops_start_inquiry

                                                                             |―― hci_send_cmd(,OCF_INQUIRY, ,);

 

事件返回處理

Inquiry指令發出後,host會收到三種event事件回覆

Command status EventInquiry result EventInquiry Complete event

 

io_security_event

       |―― read(fd, buf, sizeof(buf));

              |―― switch (eh->evt)事件型別查詢

                     |——cmd_status  case EVT_CMD_STATUS  Discovering

                     |―― inquiry_complete_evt -- case EVT_INQUIRY_COMPLETE

                            |―― set_state(index, DISCOV_HALTED);

                     |―― inquiry_result -- case EVT_INQUIRY_RESULT

                            |―― btd_event_device_found

                                   |―― adapter_update_found_devices

                                          |―― adapter_emit_device_found

                                                 |―― emit_device_found

                                                        |―― dbus_message_new_signal(, , "DeviceFound");

                                                               |―― g_dbus_send_message(connection, signal);

 

JNI處的dbus接收到” DeviceFound” singal後,回撥到JNI

BluetoothEventLoop. event_filter

       |―― dbus_message_is_signal(,"org.bluez.Adapter", "DeviceFound")??

              |―― parse_remote_device_properties(env, &iter)

              |―― env->CallVoidMethod(,method_onDeviceFound, ,);

                     |―― onDeviceFound

                            |―― addDevice(address, properties);

                                   |―― send intent BluetoothDevice.ACTION_FOUND

BluetoothEventManager.java 接收intent

DeviceFoundHandler

       |―― mDeviceManager.addDevice  -- cachedDevice

       |―― dispatchDeviceAdded(cachedDevice);

              回撥,在UI上顯示掃描到得裝置

 

5SDP流程

搜尋到某裝置後,確定該裝置所具有的profile

CachedBluetoothDevice

       |―― fillData()

              |―― fetchName();

              |―― fetchBtClass();

|―― updateProfiles();

                     |―― mProfileManager.updateProfiles

                            add  A2dpProfile  HeadsetProfile

                     |——dispatchAttributesChanged();

                            回撥,UI顯示

 

6pair過程

BluetoothSettings

       DeviceListPreferenceFragment

|―― onPreferenceTreeClick                點選除scan外的其它區域

|——onDevicePreferenceClick

|——BluetoothDevicePreference.onClicked()

|——pair()     配對

|——CachedBluetoothDevice. startPairing()

|——BluetoothDevice. createBond()

IBluetooth callback介面

|——BluetoothService. createBond

|——createPairedDeviceNative (address, 60000)  一分鐘

|——dbus_func_args_async(, , , ,"CreatePairedDevice",)

                            |——dbus介面 CreatePairedDevice

                                   |——create_paired_device            bluez中處理

                                          |——dbus_message_get_args 讀取需要匹配的device資訊

                                          |——create_device_internal

                                                 |——adapter_create_device

                                                        |——dbus signal “DeviceCreated

                                                        |——adapter_update_devices

                                                               |——dbus  “PropertyChanged” “Devices

                                          |——device_create_bonding

                                                 |——adapter_create_bonding

                                                        |——hciops_create_bonding(BT_IO_L2RAW, , ,)

                                                               |——l2cap_connect 建立L2CAP連線

                                                               |——connect_add

                                                 |——bonding_request_new

       |——mBondState.setBondState(,BOND_BONDING)  改變狀態為bonding

              |——new Intent  ACTION_BOND_STATE_CHANGED

BluetoothEventManager.java 接收intent

              |——BondStateChangedHandler

                     |——dispatchAttributesChanged();

UI上顯示

 

 

JNI收到 “DeviceCreated” signal

onDeviceCreated

       |——mBluetoothService.getRemoteDeviceProperties

       |——addDevice(address, properties)

              |——send intent “ACTION_FOUND”

JNI處的dbus接收到”RequestPairingConsent” singal後,回撥到JNI

env->CallVoidMethod(, method_onRequestPairingConsent,,)

BluetoothEventLoop.java

       |——onRequestPairingConsent

              |——send intent ACTION_PAIRING_REQUEST

 

 

 

(7)connect過程

BluetoothDevicePreference.onClicked()

       |——CachedBluetoothDevice. connect(true)

              |——connectWithoutResettingTimer(connectAllProfiles);  連線所有profile

                     |——for (LocalBluetoothProfile profile : mProfiles) 遍歷每個profile

|——connectInt (profile)

       |——profile.connect (mDevice)  A2DP  HSP connect

 

 

(8)A2DP profile

A2dpProfile. connect()

       |——BluetoothA2dp. connect()

              |——BluetoothA2dpService. connect()

                     |——BluetoothService. connectSink

                            msg.arg1 = BluetoothDeviceProfileState.CONNECT_A2DP_OUTGOING;

                            |——BluetoothProfileState. sendMsg(msg)

                                   |——BluetoothDeviceProfileState. sendMessage(cmd)

                                          |——BluetoothA2dpService. connectSinkInternal

                                                 |——handleSinkStateChange   STATE_CONNECTING

                                                        |——BluetoothService.sendConnectionStateChange

                                                               |——updateProfileConnectionState

                                                 |——connectSinkNative

                                                        |——dbus_func_args_async

("org.bluez.AudioSink", "Connect",)

Bluez  org.bluez.AudioSink 收到Connect訊號後

bluez/audio/device.c

dev_connect

       |——sink_setup_stream

              |——avdtp_discover

                     |——send_request(,,,AVDTP_DISCOVER,)

BluetoothA2dpService.cpp 收到dbus訊號

onConnectSinkResult

       回撥到 BluetoothA2dpService.java

       |——onConnectSinkResult

相關文章