android bluetooth stack-enable
开机时在systemserver.java中startOtherServices里开启蓝牙服务,如开机中如果是模拟器是没有蓝牙启动的,
// Skip Bluetooth if we have an emulator kernel // TODO: Use a more reliable check to see if this product should // support Bluetooth - see bug 988521 if (isEmulator) { Slog.i(TAG, "No Bluetooth Service (emulator)"); } else if (mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL) { Slog.i(TAG, "No Bluetooth Service (factory test)"); } else if (!context.getPackageManager().hasSystemFeature (PackageManager.FEATURE_BLUETOOTH)) { Slog.i(TAG, "No Bluetooth Service (Bluetooth Hardware Not Present)"); } else if (disableBluetooth) { Slog.i(TAG, "Bluetooth Service disabled by config"); } else { traceBeginAndSlog("StartBluetoothService"); mSystemServiceManager.startService(BluetoothService.class); traceEnd(); }
frameworks/base/services/core/java/com/android/server/BluetoothService.java
public BluetoothService(Context context) { super(context); mBluetoothManagerService = new BluetoothManagerService(context); }
从而启动BluetoothManagerService,此BluetoothManagerService与BluetoothManager进行binder通讯
Android 蓝牙默认开关打开与关闭判断的地方
frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.javaloadBooleanSetting(stmt,Settings.Global.BLUETOOTH_ON,R.bool.def_bluetooth_on);
BluetoothManagerService判断上面的属性状态决定是否开蓝牙,
下面是默认打开蓝牙开机时BluetoothManagerService的打印
01-01 08:00:33.915 514 514 D BluetoothManagerService: Loading stored name and address01-01 08:00:33.917 514 514 D BluetoothManagerService: Stored bluetooth Name=Android Bluedroid,Address=DA:81:46:00:00:B701-01 08:00:33.918 514 514 D BluetoothManagerService: Bluetooth persisted state: 101-01 08:00:33.918 514 514 D BluetoothManagerService: Startup: Bluetooth persisted state is ON.01-01 08:00:36.278 514 610 D BluetoothManagerService: Trying to bind to profile: 1, while Bluetooth was disabled01-01 08:00:38.235 514 514 D BluetoothManagerService: Trying to bind to profile: 1, while Bluetooth was disabled01-01 08:00:38.569 514 514 D BluetoothManagerService: Trying to bind to profile: 1, while Bluetooth was disabled01-01 08:00:40.567 514 539 D BluetoothManagerService: Bluetooth boot completed01-01 08:00:40.568 514 539 D BluetoothManagerService: Auto-enabling Bluetooth.01-01 08:00:40.569 514 538 D BluetoothManagerService: MESSAGE_ENABLE(0): mBluetooth = null01-01 08:00:41.910 514 530 D BluetoothManagerService: User 0 unlocked01-01 08:00:41.928 514 538 D BluetoothManagerService: MESSAGE_USER_UNLOCKED01-01 08:00:43.571 514 538 E BluetoothManagerService: MESSAGE_TIMEOUT_BIND01-01 08:00:46.214 514 514 D BluetoothManagerService: BluetoothServiceConnection: com.android.bluetooth.btservice.AdapterService01-01 08:00:46.215 514 538 D BluetoothManagerService: MESSAGE_BLUETOOTH_SERVICE_CONNECTED: 101-01 08:00:46.228 514 538 D BluetoothManagerService: Broadcasting onBluetoothServiceUp() to 3 receivers.01-01 08:00:46.253 514 538 D BluetoothManagerService: MESSAGE_BLUETOOTH_STATE_CHANGE: OFF > BLE_TURNING_ON01-01 08:00:46.254 514 538 D BluetoothManagerService: Sending BLE State Change: OFF > BLE_TURNING_ON01-01 08:00:48.786 514 514 D BluetoothManagerService: Bluetooth Adapter address changed to DA:81:46:00:00:B701-01 08:00:48.795 514 514 D BluetoothManagerService: Stored Bluetoothaddress: DA:81:46:00:00:B701-01 08:00:48.816 514 514 D BluetoothManagerService: Bluetooth Adapter name changed to Android Bluedroid01-01 08:00:48.816 514 514 D BluetoothManagerService: Stored Bluetooth name: Android Bluedroid01-01 08:00:49.063 514 538 D BluetoothManagerService: MESSAGE_BLUETOOTH_STATE_CHANGE: BLE_TURNING_ON > BLE_ON01-01 08:00:49.063 514 538 D BluetoothManagerService: Bluetooth is in LE only mode01-01 08:00:49.063 514 538 D BluetoothManagerService: Binding Bluetooth GATT service01-01 08:00:49.069 514 514 D BluetoothManagerService: BluetoothServiceConnection: com.android.bluetooth.gatt.GattService01-01 08:00:49.073 514 538 D BluetoothManagerService: Sending BLE State Change: BLE_TURNING_ON > BLE_ON01-01 08:00:49.080 514 538 D BluetoothManagerService: MESSAGE_BLUETOOTH_SERVICE_CONNECTED: 201-01 08:00:49.082 514 538 D BluetoothManagerService: BluetoothGatt Service is Up01-01 08:00:49.122 514 538 D BluetoothManagerService: Persisting Bluetooth Setting: 101-01 08:00:49.122 514 538 D BluetoothManagerService: MESSAGE_BLUETOOTH_STATE_CHANGE: BLE_ON > TURNING_ON01-01 08:00:49.123 514 538 D BluetoothManagerService: Sending BLE State Change: BLE_ON > TURNING_ON01-01 08:00:49.181 514 525 D BluetoothManagerService: Creating new ProfileServiceConnections object for profile: 101-01 08:00:49.182 514 525 E BluetoothManagerService: Fail to bind to: Intent { act=android.bluetooth.IBluetoothHeadset }01-01 08:00:49.195 514 525 W BluetoothManagerService: Unable to bind with intent: Intent { act=android.bluetooth.IBluetoothHeadset }01-01 08:00:52.150 514 538 D BluetoothManagerService: MESSAGE_BLUETOOTH_STATE_CHANGE: TURNING_ON > ON01-01 08:00:52.150 514 538 D BluetoothManagerService: Broadcasting onBluetoothStateChange(true) to 10 receivers.01-01 08:00:52.151 514 538 D BluetoothManagerService: Creating new ProfileServiceConnections object for profile: 101-01 08:00:52.152 514 538 E BluetoothManagerService: Fail to bind to: Intent { act=android.bluetooth.IBluetoothHeadset }01-01 08:00:52.152 514 538 W BluetoothManagerService: Unable to bind with intent: Intent { act=android.bluetooth.IBluetoothHeadset }01-01 08:00:52.154 514 538 D BluetoothManagerService: Creating new ProfileServiceConnections object for profile: 101-01 08:00:52.154 514 538 E BluetoothManagerService: Fail to bind to: Intent { act=android.bluetooth.IBluetoothHeadset }01-01 08:00:52.154 514 538 W BluetoothManagerService: Unable to bind with intent: Intent { act=android.bluetooth.IBluetoothHeadset }01-01 08:00:52.159 514 538 D BluetoothManagerService: Creating new ProfileServiceConnections object for profile: 101-01 08:00:52.160 514 538 E BluetoothManagerService: Fail to bind to: Intent { act=android.bluetooth.IBluetoothHeadset }01-01 08:00:52.160 514 538 W BluetoothManagerService: Unable to bind with intent: Intent { act=android.bluetooth.IBluetoothHeadset }01-01 08:00:52.161 514 538 D BluetoothManagerService: Sending BLE State Change: TURNING_ON > ON01-01 08:00:52.168 514 1244 D BluetoothManagerService: Creating new ProfileServiceConnections object for profile: 101-01 08:00:52.183 514 1244 E BluetoothManagerService: Fail to bind to: Intent { act=android.bluetooth.IBluetoothHeadset }01-01 08:00:52.184 514 1244 W BluetoothManagerService: Unable to bind with intent: Intent { act=android.bluetooth.IBluetoothHeadset }
默认关闭蓝牙开机的打印
01-01 08:16:55.529 517 517 D BluetoothManagerService: Loading stored name and address01-01 08:16:55.534 517 517 D BluetoothManagerService: Stored bluetooth Name=Android Bluedroid,Address=DA:81:46:00:00:B701-01 08:16:55.535 517 517 D BluetoothManagerService: Bluetooth persisted state: 001-01 08:16:57.898 517 610 D BluetoothManagerService: Trying to bind to profile: 1, while Bluetooth was disabled01-01 08:16:59.870 517 517 D BluetoothManagerService: Trying to bind to profile: 1, while Bluetooth was disabled01-01 08:17:00.375 517 517 D BluetoothManagerService: Trying to bind to profile: 1, while Bluetooth was disabled01-01 08:17:02.036 517 539 D BluetoothManagerService: Bluetooth boot completed01-01 08:17:03.321 517 532 D BluetoothManagerService: User 0 unlocked01-01 08:17:03.325 517 538 D BluetoothManagerService: MESSAGE_USER_UNLOCKED01-01 08:17:10.155 517 980 D BluetoothManagerService: Trying to bind to profile: 1, while Bluetooth was disabled
从打印对比看,真正启动的地方判断之处为:handleOnBootPhase
代码流程为:
SystemServiceManager.startService(BluetoothService.class)->
BluetoothService:onBootPhase->BluetoothManagerService.handleOnBootPhase()->
MESSAGE_ENABLE-> handleEnable(0);->mBluetooth.enable())
/** * Send enable message and set adapter name and address. Called when the boot phase becomes * PHASE_SYSTEM_SERVICES_READY. */ public void handleOnBootPhase() { if (DBG) Slog.d(TAG, "Bluetooth boot completed"); UserManagerInternal userManagerInternal = LocalServices.getService(UserManagerInternal.class); userManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener); final boolean isBluetoothDisallowed = isBluetoothDisallowed(); if (isBluetoothDisallowed) { return; } if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) { if (DBG) Slog.d(TAG, "Auto-enabling Bluetooth."); sendEnableMsg(mQuietEnableExternal, REASON_SYSTEM_BOOT); } else if (!isNameAndAddressSet()) { if (DBG) Slog.d(TAG, "Getting adapter name and address"); Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS); mHandler.sendMessage(getMsg); } }
settings中触发打开的地方
https://blog.csdn.net/pashanhu6402/article/details/80672868
https://blog.csdn.net/w6980112/article/details/45500661
https://blog.csdn.net/liu362732346/article/details/81776675
BluetoothSettings.java->onActivityCreated
蓝牙配置和连接管理界面,就是咱们常见的蓝牙界面。它管理着蓝牙界面的加载,蓝牙搜索,蓝牙连接,蓝牙重命名等管理功能若已打开蓝牙的情况下,进入BluetoothSettings
会将蓝牙模式修改为可见可连接,这里分析的平台为mt6580
刚打开蓝牙时也是updateContent->BluetoothAdapter.STATE_ON
退出BluetoothSettings界面时会去掉这个可见,只有可连接模式
mAlwaysDiscoverable的方法如下,调用了setScanMode,参数分别为SCAN_MODE_CONNECTABLE_DISCOVERABLE,SCAN_MODE_CONNECTABLE
蓝牙开启流程
BluetoothEnabler.java—>onSwitchToggled()
开启和关闭蓝牙的switchbar的监听状态存在与BluetoothEnable类中,当点击switchbar时,由于BluetoothEnabler implements SwitchWidgetController.OnSwitchChangeListener ,所以会调用onSwitchToggled
LocalBluetoothAdapter.java—>setBluetoothEnabled()
public boolean setBluetoothEnabled(boolean enabled) { //调用到BluetoothAdapter.java-->enable() boolean success = enabled ? mAdapter.enable() : mAdapter.disable(); if (success) { setBluetoothStateInt(enabled ? BluetoothAdapter.STATE_TURNING_ON : BluetoothAdapter.STATE_TURNING_OFF); } else { if (Utils.V) { Log.v(TAG, "setBluetoothEnabled call, manager didn't return " + "success for enabled: " + enabled); } syncBluetoothState(); } return success; }
BluetoothAdapter.java–>enable()
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) public boolean enable() { if (isEnabled()) { if (DBG) Log.d(TAG, "enable(): BT already enabled!"); return true; } try { //走到service return mManagerService.enable(ActivityThread.currentPackageName()); } catch (RemoteException e) {Log.e(TAG, "", e);} return false; }
应用层或系统层调用BluetoothManager的enable接口时会call到BluetoothManagerService的enable进而进行如下调用流程
anroid framework开始默认打开时适配器,调用com_android_bluetooth_btservice_AdapterService
的enableNative
从而call到蓝牙协议栈的enable接口
BluetoothManagerService构造函数中有许多关于蓝牙适配器的初始化,如mac地址,名字的修改,广播接收者,是否打开,是否是飞行模式等标记,这些状态都是存储在类似于Settings.Global.BLUETOOTH_ON的键值对中的数据库中
static int enable(bool start_restricted) { LOG_INFO(LOG_TAG, "%s: start restricted = %d", __func__, start_restricted); restricted_mode = start_restricted; if (!interface_ready())/*已经初始化,则走下去*/ return BT_STATUS_NOT_READY; stack_manager_get_interface()->start_up_stack_async();/*到这执行函数start_up_stack_async*/ return BT_STATUS_SUCCESS;}
-----------------------------------// Synchronous function to start up the stackstatic void event_start_up_stack(UNUSED_ATTR void *context) { if (stack_is_running) {/*第一次进入这个函数,跳过去执行下面的process*/ LOG_DEBUG("%s stack already brought up.", __func__); return; } ensure_stack_is_initialized();/*这个stack_is_initialized已经初始化过了*/ LOG_DEBUG("%s is bringing up the stack.", __func__); hack_future = future_new(); // Include this for now to put btif config into a shutdown-able state module_start_up(get_module(BTIF_CONFIG_MODULE));/*加载并解析配置文件/data/misc/bluedroid/bt_config.xml*/ bte_main_enable();/*打开bte的 enable*/ if (future_await(hack_future) != FUTURE_SUCCESS) { stack_is_running = true; // So stack shutdown actually happens event_shut_down_stack(NULL); return; } stack_is_running = true; LOG_DEBUG("%s finished", __func__); btif_thread_post(event_signal_stack_up, NULL);/*适配器已打开*/}
-----------------------------------------------------------void bte_main_enable(){ APPL_TRACE_DEBUG("%s", __FUNCTION__); module_start_up(get_module(BTSNOOP_MODULE));/*打开并启动btsnoop_module模块 打开snoop日志 static future_t *start_up(void) { module_started = true; update_logging(); return NULL; }*/ module_start_up(get_module(HCI_MODULE));/*打开并启动hci_module模块*/ BTU_StartUp();/*BTU启动*/}
----------------------------------------------------static future_t *start_up(void) { LOG_INFO("%s", __func__); // The host is only allowed to send at most one command initially, // as per the Bluetooth spec, Volume 2, Part E, 4.4 (Command Flow Control) // This value can change when you get a command complete or command status event. command_credits = 1; firmware_is_configured = false; pthread_mutex_init(&commands_pending_response_lock, NULL); // Grab the override startup timeout ms, if present. period_ms_t startup_timeout_ms; char timeout_prop[PROPERTY_VALUE_MAX]; if (!property_get("bluetooth.enable_timeout_ms", timeout_prop, STRING_VALUE_OF(DEFAULT_STARTUP_TIMEOUT_MS)) || (startup_timeout_ms = atoi(timeout_prop)) < 100) startup_timeout_ms = DEFAULT_STARTUP_TIMEOUT_MS;/*如无特别定义,打开适配器的时间限度为8s*/ startup_timer = non_repeating_timer_new(startup_timeout_ms, startup_timer_expired, NULL);/*startup_timer启动时间*/ if (!startup_timer) { LOG_ERROR("%s unable to create startup timer.", __func__); goto error; } // Make sure we run in a bounded amount of time non_repeating_timer_restart(startup_timer); epilog_timer = non_repeating_timer_new(EPILOG_TIMEOUT_MS, epilog_timer_expired, NULL); if (!epilog_timer) { LOG_ERROR("%s unable to create epilog timer.", __func__); goto error; } command_response_timer = non_repeating_timer_new(COMMAND_PENDING_TIMEOUT, command_timed_out, NULL);/*命令发出去8s没发成功就command超时了*/ if (!command_response_timer) { LOG_ERROR("%s unable to create command response timer.", __func__); goto error; } command_queue = fixed_queue_new(SIZE_MAX); if (!command_queue) { LOG_ERROR("%s unable to create pending command queue.", __func__); goto error; } packet_queue = fixed_queue_new(SIZE_MAX); if (!packet_queue) { LOG_ERROR("%s unable to create pending packet queue.", __func__); goto error; } thread = thread_new("hci_thread"); if (!thread) { LOG_ERROR("%s unable to create thread.", __func__); goto error; } commands_pending_response = list_new(NULL); if (!commands_pending_response) { LOG_ERROR("%s unable to create list for commands pending response.", __func__); goto error; } memset(incoming_packets, 0, sizeof(incoming_packets)); packet_fragmenter->init(&packet_fragmenter_callbacks); fixed_queue_register_dequeue(command_queue, thread_get_reactor(thread), event_command_ready, NULL); fixed_queue_register_dequeue(packet_queue, thread_get_reactor(thread), event_packet_ready, NULL); vendor->open(btif_local_bd_addr.address, &interface); hal->init(&hal_callbacks, thread); /*当有事件来时调用些接口函数 static const hci_hal_callbacks_t hal_callbacks = { hal_says_data_ready };*/ low_power_manager->init(thread); vendor->set_callback(VENDOR_CONFIGURE_FIRMWARE, firmware_config_callback); vendor->set_callback(VENDOR_CONFIGURE_SCO, sco_config_callback); vendor->set_callback(VENDOR_DO_EPILOG, epilog_finished_callback); if (!hci_inject->open(&interface)) { // TODO(sharvil): gracefully propagate failures from this layer. } int power_state = BT_VND_PWR_OFF;#if (defined (BT_CLEAN_TURN_ON_DISABLED) && BT_CLEAN_TURN_ON_DISABLED == TRUE) LOG_WARN("%s not turning off the chip before turning on.", __func__); // So apparently this hack was needed in the past because a Wingray kernel driver // didn't handle power off commands in a powered off state correctly. // The comment in the old code said the workaround should be removed when the // problem was fixed. Sadly, I have no idea if said bug was fixed or if said // kernel is still in use, so we must leave this here for posterity. #sadpanda#else // cycle power on the chip to ensure it has been reset vendor->send_command(VENDOR_CHIP_POWER_CONTROL, &power_state);#endif power_state = BT_VND_PWR_ON; vendor->send_command(VENDOR_CHIP_POWER_CONTROL, &power_state); startup_future = future_new(); LOG_DEBUG("%s starting async portion", __func__); thread_post(thread, event_finish_startup, NULL); return startup_future;error:; shut_down(); // returns NULL so no need to wait for it return future_new_immediate(FUTURE_FAIL);}
---------------------------------------------------------------------------------------/********************************************************************************* Function BTU_StartUp**** Description Initializes the BTU control block.**** NOTE: Must be called before creating any tasks** (RPC, BTU, HCIT, APPL, etc.)**** Returns void********************************************************************************/void BTU_StartUp(void){ /*初始化一大堆hashmap&queue*/ // Continue startup on bt workqueue thread. thread_post(bt_workqueue_thread, btu_task_start_up, NULL); return; error_exit:; LOG_ERROR("%s Unable to allocate resources for bt_workqueue", __func__); BTU_ShutDown();}
各种重要的东西都将在这里执行btu_task_start_up
-------------------------------------------------------------------------------------------------void btu_task_start_up(UNUSED_ATTR void *context) { BT_TRACE(TRACE_LAYER_BTU, TRACE_TYPE_API, "btu_task pending for preload complete event"); LOG_INFO("Bluetooth chip preload is complete"); BT_TRACE(TRACE_LAYER_BTU, TRACE_TYPE_API, "btu_task received preload complete event"); /* Initialize the mandatory core stack control blocks (BTU, BTM, L2CAP, and SDP) */ btu_init_core(); /* Initialize any optional stack components */ BTE_InitStack(); bta_sys_init(); /* Initialise platform trace levels at this point as BTE_InitStack() and bta_sys_init() * reset the control blocks and preset the trace level with XXX_INITIAL_TRACE_LEVEL */#if ( BT_USE_TRACES==TRUE ) module_init(get_module(BTE_LOGMSG_MODULE));#endif // Inform the bt jni thread initialization is ok.通知从control来的Security Callback Events 事件,如acl建立等 /* Security Callback Events */#define BTA_DM_ENABLE_EVT 0 /* Enable Event */#define BTA_DM_DISABLE_EVT 1 /* Disable Event */#define BTA_DM_PIN_REQ_EVT 2 /* PIN request. */#define BTA_DM_AUTH_CMPL_EVT 3 /* Authentication complete indication. */#define BTA_DM_AUTHORIZE_EVT 4 /* Authorization request. */#define BTA_DM_LINK_UP_EVT 5 /* Connection UP event */#define BTA_DM_LINK_DOWN_EVT 6 /* Connection DOWN event */#define BTA_DM_SIG_STRENGTH_EVT 7 /* Signal strength for bluetooth connection */#define BTA_DM_BUSY_LEVEL_EVT 8 /* System busy level */#define BTA_DM_BOND_CANCEL_CMPL_EVT 9 /* Bond cancel complete indication */#define BTA_DM_SP_CFM_REQ_EVT 10 /* Simple Pairing User Confirmation request. */#define BTA_DM_SP_KEY_NOTIF_EVT 11 /* Simple Pairing Passkey Notification */#define BTA_DM_SP_RMT_OOB_EVT 12 /* Simple Pairing Remote OOB Data request. */#define BTA_DM_SP_KEYPRESS_EVT 13 /* Key press notification event. */#define BTA_DM_ROLE_CHG_EVT 14 /* Role Change event. */#define BTA_DM_BLE_KEY_EVT 15 /* BLE SMP key event for peer device keys */#define BTA_DM_BLE_SEC_REQ_EVT 16 /* BLE SMP security request */#define BTA_DM_BLE_PASSKEY_NOTIF_EVT 17 /* SMP passkey notification event */#define BTA_DM_BLE_PASSKEY_REQ_EVT 18 /* SMP passkey request event */#define BTA_DM_BLE_OOB_REQ_EVT 19 /* SMP OOB request event */#define BTA_DM_BLE_LOCAL_IR_EVT 20 /* BLE local IR event */#define BTA_DM_BLE_LOCAL_ER_EVT 21 /* BLE local ER event */#define BTA_DM_BLE_NC_REQ_EVT 22 /* SMP Numeric Comparison request event */// btla-specific ++#define BTA_DM_SP_RMT_OOB_EXT_EVT 23 /* Simple Pairing Remote OOB Extended Data request. */#define BTA_DM_BLE_AUTH_CMPL_EVT 24 /* BLE Auth complete */// btla-specific --#define BTA_DM_DEV_UNPAIRED_EVT 25#define BTA_DM_HW_ERROR_EVT 26 /* BT Chip H/W error */#define BTA_DM_LE_FEATURES_READ 27 /* Cotroller specific LE features are read */#define BTA_DM_ENER_INFO_READ 28 /* Energy info read */typedef UINT8 tBTA_DM_SEC_EVT; btif_transfer_context(btif_init_ok, 0, NULL, 0, NULL);---〉**btif_dm_upstreams_evt** fixed_queue_register_dequeue(btu_bta_msg_queue, thread_get_reactor(bt_workqueue_thread), btu_bta_msg_ready, NULL); fixed_queue_register_dequeue(btu_hci_msg_queue, thread_get_reactor(bt_workqueue_thread), btu_hci_msg_ready, NULL); fixed_queue_register_dequeue(btu_general_alarm_queue, thread_get_reactor(bt_workqueue_thread), btu_general_alarm_ready, NULL); fixed_queue_register_dequeue(btu_oneshot_alarm_queue, thread_get_reactor(bt_workqueue_thread), btu_oneshot_alarm_ready, NULL); fixed_queue_register_dequeue(btu_l2cap_alarm_queue, thread_get_reactor(bt_workqueue_thread), btu_l2cap_alarm_ready, NULL);}
fixed_queue_register_dequeue(btu_bta_msg_queue, thread_get_reactor(bt_workqueue_thread), btu_bta_msg_ready, NULL); btu_bta_msg_ready bta_sys_event bta_sys_event reg[id]根据void bta_sys_register(UINT8 id, const tBTA_SYS_REG *p_reg)的id号来取callback fixed_queue_register_dequeue(btu_hci_msg_queue, thread_get_reactor(bt_workqueue_thread), btu_hci_msg_ready, NULL); btu_hci_msg_ready btu_hci_msg_process
btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); ---》transmit_command ----》packet_fragmenter->fragment_and_dispatch(wait_entry->command) ---》transmit_fragment -》transmit_data -》write(uart_fd, data + transmitted_length, length); ---uart_fd是打开的串口描述符 bta_sys_sendmsg-->btu_bta_msg_ready -->bta_sys_event-->reg[id]根据void bta_sys_register(UINT8 id, const tBTA_SYS_REG *p_reg)的id号来取callback
更多相关文章
- 关于android 调用系统图片浏览器并返回图片路径问题
- Android保存图片到本地
- 【Android自学笔记】Android获取手机和存储卡上的图片
- Android 蓝牙设备的查找与连接
- android中如何显示图片的一部分
- android > layout > background 背景图片重复
- 如何在EditText中设置固定图片——Android移动开发
- Android 蓝牙浅析