日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

android6.0 Bluetooth蓝牙源码流程笔记

發布時間:2023/12/20 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android6.0 Bluetooth蓝牙源码流程笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

注:基于mtk平臺的android6.0,由于我個人水平有限,代碼細節不能詳細說明,抱歉

參考文章:

http://blog.csdn.net/shichaog/article/details/52728684

http://blog.csdn.net/baimy1985/article/details/8922508
http://blog.csdn.net/yanli0084/article/details/51821064
謝謝以上大佬

首先從BluetoothAdapter.enable開始

frameworks/base/core/java/android/bluetooth.BluetoothAdapter.java public boolean enable() {int state = STATE_OFF;if (isEnabled() == true){if (DBG) Log.d(TAG, "enable(): BT is already enabled..!");return true;}//Use service interface to get the exact stateif (mService != null) {try {state = mService.getState();} catch (RemoteException e) {Log.e(TAG, "", e);}}if (state == BluetoothAdapter.STATE_BLE_ON) {Log.e(TAG, "BT is in BLE_ON State");notifyUserAction(true);return true;}try {if (DBG) Log.d(TAG, "enable");return mManagerService.enable();} catch (RemoteException e) {Log.e(TAG, "", e);}return false;} 這個mManagerService是構造函數傳來的,再看看單例的getDefaultAdapter

public static synchronized BluetoothAdapter getDefaultAdapter() {if (sAdapter == null) {IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);if (b != null) {IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b);sAdapter = new BluetoothAdapter(managerService);} else {Log.e(TAG, "Bluetooth binder is null");}}return sAdapter;}
看來有個地方把binder注冊成了BLUETOOTH_MANAGER_SERVICE,搜索發現在BluetoothService中


@Overridepublic void onStart() {Log.d(TAG, "onStart: publishing BluetoothManagerService");publishBinderService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, mBluetoothManagerService);} 這個mBluetoothManagerService是BluetoothManagerService.java的實例。

public boolean enable() {if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&(!checkIfCallerIsForegroundUser())) {Log.w(TAG,"enable(): not allowed for non-active and non system user");return false;}mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,"Need BLUETOOTH ADMIN permission");if (DBG) {Log.d(TAG,"enable(): mBluetooth =" + mBluetooth +" mBinding = " + mBinding);}/// M: MoMS permission check @{if (MobileManagerUtils.isSupported()) {checkEnablePermission();return true;}/// @}synchronized(mReceiver) {mQuietEnableExternal = false;mEnableExternal = true;// waive WRITE_SECURE_SETTINGS permission checksendEnableMsg(false);}if (DBG) Log.d(TAG, "enable returning");return true;} ? ? private void sendEnableMsg(boolean quietMode) {mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE,quietMode ? 1 : 0, 0));} ? ? ? ? ? ? ? case MESSAGE_ENABLE:if (DBG) {Log.d(TAG, "MESSAGE_ENABLE: mBluetooth = " + mBluetooth);}mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);mEnable = true;handleEnable(msg.arg1 == 1);break; private void handleEnable(boolean quietMode) {mQuietEnable = quietMode;synchronized(mConnection) {if (DBG) Log.d(TAG, "handleEnable: mBluetooth = " + mBluetooth +", mBinding = " + mBinding + "quietMode = " + quietMode);if ((mBluetooth == null) && (!mBinding)) {if (DBG) Log.d(TAG, "Bind AdapterService");//Start bind timeout and bindMessage timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);mConnection.setGetNameAddressOnly(false);Intent i = new Intent(IBluetooth.class.getName());if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,UserHandle.CURRENT)) {mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);Log.e(TAG, "Fail to bind to: " + IBluetooth.class.getName());} else {mBinding = true;}} else if (mBluetooth != null) {if (mConnection.isGetNameAddressOnly()) {// if GetNameAddressOnly is set, we can clear this flag,// so the service won't be unbind// after name and address are savedmConnection.setGetNameAddressOnly(false);//Register callback objecttry {mBluetooth.registerCallback(mBluetoothCallback);} catch (RemoteException re) {Log.e(TAG, "Unable to register BluetoothCallback",re);}//Inform BluetoothAdapter instances that service is upsendBluetoothServiceUpCallback();}//Enable bluetoothtry {if (!mQuietEnable) {if(!mBluetooth.enable()) {Log.e(TAG,"IBluetooth.enable() returned false");}}else {if(!mBluetooth.enableNoAutoConnect()) {Log.e(TAG,"IBluetooth.enableNoAutoConnect() returned false");}}} catch (RemoteException e) {Log.e(TAG,"Unable to call enable()",e);}}}} boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);intent.setComponent(comp);if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) {Log.e(TAG, "Fail to bind to: " + intent);return false;}return true;} 這個intent指向packages/apps/Bluetooth的AdapterService

Manifest.xml<serviceandroid:process="@string/process"android:name = ".btservice.AdapterService"><intent-filter><action android:name="android.bluetooth.IBluetooth" /></intent-filter></service> bindService的時候注意看這個mConnection,它是BluetoothServiceConnection的實例,在onServiceConnected里

public void onServiceConnected(ComponentName className, IBinder service) {if (DBG) Log.d(TAG, "BluetoothServiceConnection: " + className.getClassName());Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);// TBD if (className.getClassName().equals(IBluetooth.class.getName())) {if (className.getClassName().equals("com.android.bluetooth.btservice.AdapterService")) {msg.arg1 = SERVICE_IBLUETOOTH;// } else if (className.getClassName().equals(IBluetoothGatt.class.getName())) {} else if (className.getClassName().equals("com.android.bluetooth.gatt.GattService")) {msg.arg1 = SERVICE_IBLUETOOTHGATT;} else {Log.e(TAG, "Unknown service connected: " + className.getClassName());return;}msg.obj = service;mHandler.sendMessage(msg);} case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:{if (DBG) Log.d(TAG,"MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);IBinder service = (IBinder) msg.obj;synchronized(mConnection) {if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {mBluetoothGatt = IBluetoothGatt.Stub.asInterface(service);onBluetoothGattServiceUp();break;} // else must be SERVICE_IBLUETOOTH//Remove timeoutmHandler.removeMessages(MESSAGE_TIMEOUT_BIND);mBinding = false;mBluetooth = IBluetooth.Stub.asInterface(service);try {boolean enableHciSnoopLog = (Settings.Secure.getInt(mContentResolver,Settings.Secure.BLUETOOTH_HCI_LOG, 0) == 1);if (!mBluetooth.configHciSnoopLog(enableHciSnoopLog)) {Log.e(TAG,"IBluetooth.configHciSnoopLog return false");}} catch (RemoteException e) {Log.e(TAG,"Unable to call configHciSnoopLog", e);}if (mConnection.isGetNameAddressOnly()) {//Request GET NAME AND ADDRESSMessage getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);mHandler.sendMessage(getMsg);if (!mEnable) return;}mConnection.setGetNameAddressOnly(false);//Register callback objecttry {mBluetooth.registerCallback(mBluetoothCallback);} catch (RemoteException re) {Log.e(TAG, "Unable to register BluetoothCallback",re);}//Inform BluetoothAdapter instances that service is upsendBluetoothServiceUpCallback();//Do enable requesttry {if (mQuietEnable == false) {if(!mBluetooth.enable()) {Log.e(TAG,"IBluetooth.enable() returned false");}}else{if(!mBluetooth.enableNoAutoConnect()) {Log.e(TAG,"IBluetooth.enableNoAutoConnect() returned false");}}} catch (RemoteException e) {Log.e(TAG,"Unable to call enable()",e);}}if (!mEnable) {waitForOnOff(true, false);handleDisable();waitForOnOff(false, false);}break;} 看到沒,剛才mBluetooth 為空才去bindService,這個bind完成也要調用mBluetooth.enable()

在AdapterService的onBind會返回AdapterServiceBinder,看下AdapterServiceBinder

public boolean enable() {if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&(!Utils.checkCaller())) {Log.w(TAG, "enable() - Not allowed for non-active user and non system user");return false;}AdapterService service = getService();if (service == null) return false;return service.enable();} 最終調用AdapterService的enable()

AdapterServicepublic synchronized boolean enable(boolean quietMode) {enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");debugLog("enable() - Enable called with quiet mode status = " + mQuietmode);mQuietmode = quietMode;Message m = mAdapterStateMachine.obtainMessage(AdapterState.BLE_TURN_ON);mAdapterStateMachine.sendMessage(m);return true;} 這里和android4.2的不太一樣,打開了ble?先不管這個??纯碅dapterState內部類OffState的處理

switch(msg.what) {case BLE_TURN_ON:notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_TURNING_ON);mPendingCommandState.setBleTurningOn(true);transitionTo(mPendingCommandState);sendMessageDelayed(BLE_START_TIMEOUT, BLE_START_TIMEOUT_DELAY);adapterService.BleOnProcessStart();break; AdapterService.javavoid BleOnProcessStart() {debugLog("BleOnProcessStart()");Class[] supportedProfileServices = Config.getSupportedProfiles();//Initialize data objectsdebugLog("supportedProfileServices.length = " + supportedProfileServices.length);for (int i=0; i < supportedProfileServices.length;i++) {debugLog("supportedProfileServices[" + i + "]: " + supportedProfileServices[i].getName());mProfileServicesState.put(supportedProfileServices[i].getName(),BluetoothAdapter.STATE_OFF);}mRemoteDevices = new RemoteDevices(this);mAdapterProperties.init(mRemoteDevices);debugLog("BleOnProcessStart() - Make Bond State Machine");mBondStateMachine = BondStateMachine.make(this, mAdapterProperties, mRemoteDevices);mJniCallbacks.init(mBondStateMachine,mRemoteDevices);//FIXME: Set static instance here???setAdapterService(this);//Start Gatt servicesetGattProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON);} 這個把聲明支持的profile加載進來,具體不分析了,只上xml配置

config.xml <resources><bool name="profile_supported_a2dp">true</bool><bool name="profile_supported_a2dp_sink">false</bool><bool name="profile_supported_hdp">true</bool><bool name="profile_supported_hs_hfp">true</bool><bool name="profile_supported_hfpclient">false</bool><bool name="profile_supported_hid">true</bool><bool name="profile_supported_opp">true</bool><bool name="profile_supported_pan">true</bool><bool name="profile_supported_pbap">true</bool><bool name="profile_supported_gatt">true</bool><bool name="pbap_include_photos_in_vcard">false</bool><bool name="pbap_use_profile_for_owner_vcard">true</bool><bool name="profile_supported_map">true</bool><bool name="profile_supported_avrcp_controller">false</bool><bool name="profile_supported_sap">false</bool> 再看看setGattProfileServiceState
AdapterService.javaprivate void setGattProfileServiceState(Class[] services, int state) {if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) {Log.w(TAG,"setGattProfileServiceState(): invalid state...Leaving...");return;}int expectedCurrentState= BluetoothAdapter.STATE_OFF;int pendingState = BluetoothAdapter.STATE_TURNING_ON;if (state == BluetoothAdapter.STATE_OFF) {expectedCurrentState= BluetoothAdapter.STATE_ON;pendingState = BluetoothAdapter.STATE_TURNING_OFF;}for (int i=0; i <services.length;i++) {String serviceName = services[i].getName();String simpleName = services[i].getSimpleName();if (simpleName.equals("GattService")) {Integer serviceState = mProfileServicesState.get(serviceName);if(serviceState != null && serviceState != expectedCurrentState) {debugLog("setProfileServiceState() - Unable to "+ (state == BluetoothAdapter.STATE_OFF ? "start" : "stop" )+ " service " + serviceName+ ". Invalid state: " + serviceState);continue;}debugLog("setProfileServiceState() - "+ (state == BluetoothAdapter.STATE_OFF ? "Stopping" : "Starting")+ " service " + serviceName);mProfileServicesState.put(serviceName,pendingState);Intent intent = new Intent(this,services[i]);intent.putExtra(EXTRA_ACTION,ACTION_SERVICE_STATE_CHANGED);intent.putExtra(BluetoothAdapter.EXTRA_STATE,state);startService(intent);return;}}} 打開了GattService.java,GattService繼承了ProfileService,在ProfileService的onStartCommand中

調用了notifyProfileServiceStateChanged(BluetoothAdapter.STATE_ON);

protected void notifyProfileServiceStateChanged(int state) {//Notify adapter serviceif (mAdapterService != null) {mAdapterService.onProfileServiceStateChanged(getClass().getName(), state);}}
AdapterService.javapublic void onProfileServiceStateChanged(String serviceName, int state) {Message m = mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);m.obj=serviceName;m.arg1 = state;mHandler.sendMessage(m);} switch (msg.what) {case MESSAGE_PROFILE_SERVICE_STATE_CHANGED: {debugLog("handleMessage() - MESSAGE_PROFILE_SERVICE_STATE_CHANGED");processProfileServiceStateChanged((String) msg.obj, msg.arg1);}break; private void processProfileServiceStateChanged(String serviceName, int state) { ...if (isBleTurningOn) {if (serviceName.equals("com.android.bluetooth.gatt.GattService")) {debugLog("GattService is started");mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BLE_STARTED));return;}} 還是在OffState中

case BLE_STARTED://Remove start timeoutremoveMessages(BLE_START_TIMEOUT);//Enableboolean isGuest = UserManager.get(mAdapterService).isGuestUser();if (!adapterService.enableNative(isGuest)) {errorLog("Error while turning Bluetooth on");notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);transitionTo(mOffState);} else {sendMessageDelayed(ENABLE_TIMEOUT, ENABLE_TIMEOUT_DELAY);}break; 調用了AdapterService的enableNative方法,這是個jni調用,在com_android_bluetooth_btservice_AdapterService.cpp中聲明了該方法

static jboolean enableNative(JNIEnv* env, jobject obj, jboolean isGuest) {ALOGV("%s:",__FUNCTION__);jboolean result = JNI_FALSE;if (!sBluetoothInterface) return result;int ret = sBluetoothInterface->enable(isGuest == JNI_TRUE ? 1 : 0);result = (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE : JNI_FALSE;return result; }
調用了sBluetoothInterface->enable,這個 sBluetoothInterface在classInitNative中初始化了

static void classInitNative(JNIEnv* env, jclass clazz) {int err;hw_module_t* module; ...char value[PROPERTY_VALUE_MAX];property_get("bluetooth.mock_stack", value, "");const char *id = (strcmp(value, "1")? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID);err = hw_get_module(id, (hw_module_t const**)&module);if (err == 0) {hw_device_t* abstraction;err = module->methods->open(module, id, &abstraction);if (err == 0) {bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction;sBluetoothInterface = btStack->get_bluetooth_interface();} else {ALOGE("Error while opening Bluetooth library");}} else {ALOGE("No Bluetooth Library found");} hw_get_module是定義在hardware/libhardware/Hardware.c中的方法,jni文件的.mk中聲明了LOCAL_SHARED_LIBRARIES+=libhardware,所以ok

int hw_get_module(const char *id, const struct hw_module_t **module) {return hw_get_module_by_class(id, NULL, module); } static int hw_module_exists(char *path, size_t path_len, const char *name,const char *subname) { ...return load(class_id, path, module); } static int load(const char *id,const char *path,const struct hw_module_t **pHmi) {int status = -EINVAL;void *handle = NULL;struct hw_module_t *hmi = NULL;/** load the symbols resolving undefined symbols before* dlopen returns. Since RTLD_GLOBAL is not or'd in with* RTLD_NOW the external symbols will not be global*/handle = dlopen(path, RTLD_NOW);if (handle == NULL) {char const *err_str = dlerror();ALOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");status = -EINVAL;goto done;}/* Get the address of the struct hal_module_info. */const char *sym = HAL_MODULE_INFO_SYM_AS_STR;hmi = (struct hw_module_t *)dlsym(handle, sym);if (hmi == NULL) {ALOGE("load: couldn't find symbol %s", sym);status = -EINVAL;goto done;}/* Check that the id matches */if (strcmp(id, hmi->id) != 0) {ALOGE("load: id=%s != hmi->id=%s", id, hmi->id);status = -EINVAL;goto done;}hmi->dso = handle;/* success */status = 0;done:if (status != 0) {hmi = NULL;if (handle != NULL) {dlclose(handle);handle = NULL;}} else {ALOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",id, path, *pHmi, handle);}*pHmi = hmi;return status; } 這段代碼不太懂,感覺就是打開一個c文件,傳入id是BT_STACK_MODULE_ID,因為const char *id = (strcmp(value, "1")? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID);后面那個明顯是test的啊

至于BT_STACK_MODULE_ID,在hardware/libhardware/include/hardware/Bluetooth.h中定義了

#define BT_STACK_MODULE_ID "bluetooth"

看下system/bt/btif/src/Bluetooth.c,果然找到相關方法

const bt_interface_t* bluetooth__get_bluetooth_interface () {/* fixme -- add property to disable bt interface ? */return &bluetoothInterface; } static const bt_interface_t bluetoothInterface = {sizeof(bluetoothInterface),init,enable,disable,cleanup,get_adapter_properties,get_adapter_property,set_adapter_property,get_remote_device_properties,get_remote_device_property,set_remote_device_property,get_remote_service_record,get_remote_services,start_discovery,cancel_discovery,create_bond,remove_bond,cancel_bond,get_connection_state,pin_reply,ssp_reply,get_profile_interface,dut_mode_configure,dut_mode_send, #if BLE_INCLUDED == TRUEle_test_mode, #elseNULL, #endifconfig_hci_snoop_log,set_os_callouts,read_energy_info,dump,config_clear }; 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();return BT_STATUS_SUCCESS; }

stack_manager_get_interface在stack_manager.c中

const stack_manager_t *stack_manager_get_interface() {ensure_manager_initialized();return &interface; } static const stack_manager_t interface = {init_stack,start_up_stack_async,shut_down_stack_async,clean_up_stack_async,get_stack_is_running }; static void start_up_stack_async(void) {thread_post(management_thread, event_start_up_stack, NULL); } static void event_start_up_stack(UNUSED_ATTR void *context) {if (stack_is_running) {LOG_DEBUG("%s stack already brought up.", __func__);return;}ensure_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 statemodule_start_up(get_module(BTIF_CONFIG_MODULE));bte_main_enable();if (future_await(hack_future) != FUTURE_SUCCESS) {stack_is_running = true; // So stack shutdown actually happensevent_shut_down_stack(NULL);return; } stack_is_running = true; LOG_DEBUG("%s finished", __func__); btif_thread_post(event_signal_stack_up, NULL);} Bte_main.c

void bte_main_enable() {APPL_TRACE_DEBUG("%s", __FUNCTION__);module_start_up(get_module(BTSNOOP_MODULE));module_start_up(get_module(HCI_MODULE));BTU_StartUp(); } Btu_init.c

void BTU_StartUp(void) {memset (&btu_cb, 0, sizeof (tBTU_CB));btu_cb.trace_level = HCI_INITIAL_TRACE_LEVEL;btu_bta_msg_queue = fixed_queue_new(SIZE_MAX);if (btu_bta_msg_queue == NULL)goto error_exit;btu_general_alarm_hash_map = hash_map_new(BTU_GENERAL_ALARM_HASH_MAP_SIZE,hash_function_pointer, NULL, (data_free_fn)alarm_free, NULL);if (btu_general_alarm_hash_map == NULL)goto error_exit;if (pthread_mutex_init(&btu_general_alarm_lock, NULL))goto error_exit;btu_general_alarm_queue = fixed_queue_new(SIZE_MAX);if (btu_general_alarm_queue == NULL)goto error_exit;btu_oneshot_alarm_hash_map = hash_map_new(BTU_ONESHOT_ALARM_HASH_MAP_SIZE,hash_function_pointer, NULL, (data_free_fn)alarm_free, NULL);if (btu_oneshot_alarm_hash_map == NULL)goto error_exit;if (pthread_mutex_init(&btu_oneshot_alarm_lock, NULL))goto error_exit;btu_oneshot_alarm_queue = fixed_queue_new(SIZE_MAX);if (btu_oneshot_alarm_queue == NULL)goto error_exit;btu_l2cap_alarm_hash_map = hash_map_new(BTU_L2CAP_ALARM_HASH_MAP_SIZE,hash_function_pointer, NULL, (data_free_fn)alarm_free, NULL);if (btu_l2cap_alarm_hash_map == NULL)goto error_exit;if (pthread_mutex_init(&btu_l2cap_alarm_lock, NULL))goto error_exit;btu_l2cap_alarm_queue = fixed_queue_new(SIZE_MAX);if (btu_l2cap_alarm_queue == NULL)goto error_exit;bt_workqueue_thread = thread_new(BT_WORKQUEUE_NAME);if (bt_workqueue_thread == NULL)goto error_exit;// 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(); } 前面的都是錯誤判斷,只看thread_post(bt_workqueue_thread, btu_task_start_up, NULL);就行了
Btu_task.c

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.btif_transfer_context(btif_init_ok, 0, NULL, 0, NULL);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); }

Btif_core.c

void btif_init_ok(UNUSED_ATTR uint16_t event, UNUSED_ATTR char *p_param) {BTIF_TRACE_DEBUG("btif_task: received trigger stack init event"); #if (BLE_INCLUDED == TRUE)btif_dm_load_ble_local_keys(); #endifBTA_EnableBluetooth(bte_dm_evt); } system/bt/bta/dm/Bta_dm_api.c tBTA_STATUS BTA_EnableBluetooth(tBTA_DM_SEC_CBACK *p_cback) {tBTA_DM_API_ENABLE *p_msg;/* Bluetooth disabling is in progress */if (bta_dm_cb.disabling)return BTA_FAILURE;memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));bta_sys_register (BTA_ID_DM, &bta_dm_reg );bta_sys_register (BTA_ID_DM_SEARCH, &bta_dm_search_reg );/* if UUID list is not provided as static data */bta_sys_eir_register(bta_dm_eir_update_uuid);if ((p_msg = (tBTA_DM_API_ENABLE *) GKI_getbuf(sizeof(tBTA_DM_API_ENABLE))) != NULL){p_msg->hdr.event = BTA_DM_API_ENABLE_EVT;p_msg->p_sec_cback = p_cback;bta_sys_sendmsg(p_msg);return BTA_SUCCESS;}return BTA_FAILURE;} 這里看看這個BTA_DM_API_ENABLE_EVT是什么,首先看看Bta_dm_int.h聲明了一組枚舉類型 enum {/* device manager local device API events */BTA_DM_API_ENABLE_EVT = BTA_SYS_EVT_START(BTA_ID_DM),BTA_DM_API_DISABLE_EVT, 這個BTA_SYS_EVT_START又是什么?通過搜索在Bta_sys.h中找到了這個宏,這里先標志一下 #define BTA_SYS_EVT_START(id) ? ? ? ((id) << 8) system/bt/gki/common/Gki_buffer.c void *GKI_getbuf (UINT16 size) {BUFFER_HDR_T *header = osi_malloc(size + BUFFER_HDR_SIZE);header->status = BUF_STATUS_UNLINKED;header->p_next = NULL;header->Type = 0;header->size = size;return header + 1; }
system/bt/bta/sys/Bta_sys_main.c void bta_sys_sendmsg(void *p_msg) {// There is a race condition that occurs if the stack is shut down while// there is a procedure in progress that can schedule a task via this// message queue. This causes |btu_bta_msg_queue| to get cleaned up before// it gets used here; hence we check for NULL before using it.if (btu_bta_msg_queue)fixed_queue_enqueue(btu_bta_msg_queue, p_msg); } 向消息隊列發送msg,這個 btu_bta_msg_queue 是在Btu_init.c里面創建的

system/bt/stack/btu/Btu_init.c void BTU_StartUp(void) {memset (&btu_cb, 0, sizeof (tBTU_CB));btu_cb.trace_level = HCI_INITIAL_TRACE_LEVEL;btu_bta_msg_queue = fixed_queue_new(SIZE_MAX);if (btu_bta_msg_queue == NULL)goto error_exit; ...... 相關處理函數在Btu_task.c里注冊
system/bt/stack/btu/Btu_task.c void btu_task_start_up(UNUSED_ATTR void *context) { ......fixed_queue_register_dequeue(btu_bta_msg_queue,thread_get_reactor(bt_workqueue_thread),btu_bta_msg_ready,NULL); void btu_bta_msg_ready(fixed_queue_t *queue, UNUSED_ATTR void *context) {BT_HDR *p_msg = (BT_HDR *)fixed_queue_dequeue(queue);bta_sys_event(p_msg); }

system/bt/bta/sys/Bta_sys_main.cvoid bta_sys_event(BT_HDR *p_msg) {UINT8 id;BOOLEAN freebuf = TRUE;APPL_TRACE_EVENT("BTA got event 0x%x", p_msg->event);/* get subsystem id from event */id = (UINT8) (p_msg->event >> 8);/* verify id and call subsystem event handler */if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL)){freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);}else{APPL_TRACE_WARNING("BTA got unregistered event id %d", id);}if (freebuf){GKI_freebuf(p_msg);}}

關鍵在于freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);這個reg的賦值在

void bta_sys_register(UINT8 id, const tBTA_SYS_REG *p_reg) {bta_sys_cb.reg[id] = (tBTA_SYS_REG *) p_reg;bta_sys_cb.is_reg[id] = TRUE; } 那么,這個id是什么呢,就是上面我們標志的BTA_ID_DM

搜索bta_sys_register (BTA_ID_DM發現是在Bta_dm_api.c有調用

tBTA_STATUS BTA_EnableBluetooth(tBTA_DM_SEC_CBACK *p_cback) {tBTA_DM_API_ENABLE *p_msg;/* Bluetooth disabling is in progress */if (bta_dm_cb.disabling)return BTA_FAILURE;memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));bta_sys_register (BTA_ID_DM, &bta_dm_reg );bta_sys_register (BTA_ID_DM_SEARCH, &bta_dm_search_reg );/* if UUID list is not provided as static data */bta_sys_eir_register(bta_dm_eir_update_uuid);if ((p_msg = (tBTA_DM_API_ENABLE *) GKI_getbuf(sizeof(tBTA_DM_API_ENABLE))) != NULL){p_msg->hdr.event = BTA_DM_API_ENABLE_EVT;p_msg->p_sec_cback = p_cback;bta_sys_sendmsg(p_msg);return BTA_SUCCESS;}return BTA_FAILURE; static const tBTA_SYS_REG bta_dm_reg = {bta_dm_sm_execute,bta_dm_sm_disable }; 然后在Bta_dm_main.c中

system/bt/bta/dm/Bta_dm_main.c BOOLEAN bta_dm_sm_execute(BT_HDR *p_msg) {UINT16 event = p_msg->event & 0x00ff;APPL_TRACE_EVENT("bta_dm_sm_execute event:0x%x", event);/* execute action functions */if(event < BTA_DM_NUM_ACTIONS){(*bta_dm_action[event])( (tBTA_DM_MSG*) p_msg);}return TRUE; }

還記得嗎,event=1<<8也就是256,化成二進制就是100000000(1和八個零),而0x00ff是011111111(0和八個一),兩個&運算等于0,bta_dm_action的定義也在這個文件中

/* action function list */ const tBTA_DM_ACTION bta_dm_action[] = {/* device manager local device API events */bta_dm_enable, /* 0 BTA_DM_API_ENABLE_EVT */bta_dm_disable, /* 1 BTA_DM_API_DISABLE_EVT */bta_dm_set_dev_name, /* 2 BTA_DM_API_SET_NAME_EVT */bta_dm_set_visibility, /* 3 BTA_DM_API_SET_VISIBILITY_EVT */bta_dm_acl_change, /* 8 BTA_DM_ACL_CHANGE_EVT */bta_dm_add_device, /* 9 BTA_DM_API_ADD_DEVICE_EVT */bta_dm_close_acl, /* 10 BTA_DM_API_ADD_DEVICE_EVT *//* security API events */bta_dm_bond, /* 11 BTA_DM_API_BOND_EVT */bta_dm_bond_cancel, /* 12 BTA_DM_API_BOND_CANCEL_EVT */bta_dm_pin_reply, /* 13 BTA_DM_API_PIN_REPLY_EVT */
bta_dm_enable的實現在Bta_dm_act中

void bta_dm_enable(tBTA_DM_MSG *p_data) {tBTA_SYS_HW_MSG *sys_enable_event;tBTA_DM_ENABLE enable_event;/* if already in use, return an error */if( bta_dm_cb.is_bta_dm_active == TRUE ){APPL_TRACE_WARNING("%s Device already started by another application", __func__);memset(&enable_event, 0, sizeof(tBTA_DM_ENABLE));enable_event.status = BTA_FAILURE;if (p_data->enable.p_sec_cback != NULL)p_data->enable.p_sec_cback(BTA_DM_ENABLE_EVT, (tBTA_DM_SEC *)&enable_event);return;}/* first, register our callback to SYS HW manager */bta_sys_hw_register( BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback );/* make sure security callback is saved - if no callback, do not erase the previous one,it could be an error recovery mechanism */if( p_data->enable.p_sec_cback != NULL )bta_dm_cb.p_sec_cback = p_data->enable.p_sec_cback;/* notify BTA DM is now active */bta_dm_cb.is_bta_dm_active = TRUE;/* send a message to BTA SYS */if ((sys_enable_event = (tBTA_SYS_HW_MSG *) GKI_getbuf(sizeof(tBTA_SYS_HW_MSG))) != NULL){sys_enable_event->hdr.event = BTA_SYS_API_ENABLE_EVT;sys_enable_event->hw_module = BTA_SYS_HW_BLUETOOTH;bta_sys_sendmsg(sys_enable_event);} } 看注釋應該沒錯了,前面通過?bta_dm_cb.is_bta_dm_active == TRUE判斷是不是正在使用,后面有個?bta_dm_cb.is_bta_dm_active == TRUE,那么中間就應該是打開操作咯,
/* first, register our callback to SYS HW manager */bta_sys_hw_register( BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback );/* make sure security callback is saved - if no callback, do not erase the previous one,it could be an error recovery mechanism */if( p_data->enable.p_sec_cback != NULL )bta_dm_cb.p_sec_cback = p_data->enable.p_sec_cback;

-_-!這不就兩個注冊回調函數嗎!?我們再回頭看看

看來? bta_sys_sendmsg(sys_enable_event)才是處理,這個和之前分析的一樣,我們只要找到BTA_SYS_API_ENABLE_EVT的值,再找到對應的注冊,就可以知道在哪處理的了

enum {/* device manager local device API events */BTA_SYS_API_ENABLE_EVT = BTA_SYS_EVT_START(BTA_ID_SYS),BTA_SYS_EVT_ENABLED_EVT,BTA_SYS_EVT_STACK_ENABLED_EVT,BTA_SYS_API_DISABLE_EVT,BTA_SYS_EVT_DISABLED_EVT,BTA_SYS_ERROR_EVT,BTA_SYS_MAX_EVT }; 現在可以搜索注冊bta_sys_register(BTA_ID_SYS 了,在Bta_sys_main中找到了

void bta_sys_init(void) {memset(&bta_sys_cb, 0, sizeof(tBTA_SYS_CB));pthread_mutex_init(&bta_alarm_lock, NULL);bta_alarm_hash_map = hash_map_new(BTA_ALARM_HASH_MAP_SIZE,hash_function_pointer, NULL, (data_free_fn)alarm_free, NULL);btu_bta_alarm_queue = fixed_queue_new(SIZE_MAX);fixed_queue_register_dequeue(btu_bta_alarm_queue,thread_get_reactor(bt_workqueue_thread),btu_bta_alarm_ready,NULL);appl_trace_level = APPL_INITIAL_TRACE_LEVEL;/* register BTA SYS message handler */bta_sys_register( BTA_ID_SYS, &bta_sys_hw_reg);/* register for BTM notifications */BTM_RegisterForDeviceStatusNotif ((tBTM_DEV_STATUS_CB*)&bta_sys_hw_btm_cback );#if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)bta_ar_init(); #endif}static const tBTA_SYS_REG bta_sys_hw_reg = {bta_sys_sm_execute,NULL };BOOLEAN bta_sys_sm_execute(BT_HDR *p_msg) {BOOLEAN freebuf = TRUE;tBTA_SYS_ST_TBL state_table;UINT8 action;int i;APPL_TRACE_EVENT("bta_sys_sm_execute state:%d, event:0x%x", bta_sys_cb.state, p_msg->event);/* look up the state table for the current state */state_table = bta_sys_st_tbl[bta_sys_cb.state];/* update state */bta_sys_cb.state = state_table[p_msg->event & 0x00ff][BTA_SYS_NEXT_STATE];/* execute action functions */for (i = 0; i < BTA_SYS_ACTIONS; i++){if ((action = state_table[p_msg->event & 0x00ff][i]) != BTA_SYS_IGNORE){(*bta_sys_action[action])( (tBTA_SYS_HW_MSG*) p_msg);}else{break;}}return freebuf;}

這里是狀態模式了,狀態模式的特點是不同狀態響應命令有不同操作。首先BTA_ID_SYS=0,所以BTA_SYS_API_ENABLE_EVT=0<<8=0;

bta_sys_cb.state=bta_sys_hw_off,所以state_table = bta_sys_st_tbl[bta_sys_cb.state]

--》state_table =?
const UINT8 bta_sys_hw_off[][BTA_SYS_NUM_COLS] =
{
/* Event ? ? ? ? ? ? ? ? ? ?Action 1 ? ? ? ? ? ? ? Action 2 ? ? ? ? ? ? Next State */
/* API_ENABLE ? ?*/ ?{BTA_SYS_HW_API_ENABLE, ? ?BTA_SYS_IGNORE, ? ? BTA_SYS_HW_STARTING},
/* EVT_ENABLED ? */ ?{BTA_SYS_IGNORE, ? ? ? ? ? BTA_SYS_IGNORE, ? ? BTA_SYS_HW_STARTING},
/* STACK_ENABLED */ ?{BTA_SYS_IGNORE, ? ? ? ? ? BTA_SYS_IGNORE, ? ? BTA_SYS_HW_ON},
/* API_DISABLE ? */ ?{BTA_SYS_HW_EVT_DISABLED, ?BTA_SYS_IGNORE, ? ? BTA_SYS_HW_OFF},
/* EVT_DISABLED ?*/ ?{BTA_SYS_IGNORE, ? ? ? ? ? BTA_SYS_IGNORE, ? ? BTA_SYS_HW_OFF},
/* EVT_ERROR ? ? */ ?{BTA_SYS_IGNORE, ? ? ? ? ? BTA_SYS_IGNORE, ? ? BTA_SYS_HW_OFF}
};

bta_sys_cb.state = state_table[p_msg->event & 0x00ff][BTA_SYS_NEXT_STATE]——》bta_sys_cb.state =BTA_SYS_HW_STARTING,下個狀態是starting,進入循環,state_table【0】【0】=BTA_SYS_HW_API_ENABLE(下一次循環就break了),所以執行bta_sys_hw_api_enable

附:

/* state table */ const tBTA_SYS_ST_TBL bta_sys_st_tbl[] = {bta_sys_hw_off,bta_sys_hw_starting,bta_sys_hw_on,bta_sys_hw_stopping }; /* state table for OFF state */ const UINT8 bta_sys_hw_off[][BTA_SYS_NUM_COLS] = { /* Event Action 1 Action 2 Next State */ /* API_ENABLE */ {BTA_SYS_HW_API_ENABLE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING}, /* EVT_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING}, /* STACK_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, /* API_DISABLE */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_IGNORE, BTA_SYS_HW_OFF}, /* EVT_DISABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_OFF}, /* EVT_ERROR */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_OFF} };const UINT8 bta_sys_hw_starting[][BTA_SYS_NUM_COLS] = { /* Event Action 1 Action 2 Next State */ /* API_ENABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING}, /* wait for completion event */ /* EVT_ENABLED */ {BTA_SYS_HW_EVT_ENABLED, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING}, /* STACK_ENABLED */ {BTA_SYS_HW_EVT_STACK_ENABLED, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, /* API_DISABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING}, /* successive disable/enable: change state wait for completion to disable */ /* EVT_DISABLED */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_HW_API_ENABLE, BTA_SYS_HW_STARTING}, /* successive enable/disable: notify, then restart HW */ /* EVT_ERROR */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON} };const UINT8 bta_sys_hw_on[][BTA_SYS_NUM_COLS] = { /* Event Action 1 Action 2 Next State */ /* API_ENABLE */ {BTA_SYS_HW_API_ENABLE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, /* EVT_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, /* STACK_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, /* API_DISABLE */ {BTA_SYS_HW_API_DISABLE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, /* don't change the state here, as some other modules might be active */ /* EVT_DISABLED */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, /* EVT_ERROR */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON} };const UINT8 bta_sys_hw_stopping[][BTA_SYS_NUM_COLS] = { /* Event Action 1 Action 2 Next State */ /* API_ENABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING}, /* change state, and wait for completion event to enable */ /* EVT_ENABLED */ {BTA_SYS_HW_EVT_ENABLED, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING}, /* successive enable/disable: finish the enable before disabling */ /* STACK_ENABLED */ {BTA_SYS_HW_EVT_STACK_ENABLED, BTA_SYS_HW_API_DISABLE, BTA_SYS_HW_STOPPING}, /* successive enable/disable: notify, then stop */ /* API_DISABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING}, /* wait for completion event */ /* EVT_DISABLED */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_IGNORE, BTA_SYS_HW_OFF}, /* EVT_ERROR */ {BTA_SYS_HW_API_DISABLE, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING} };
我們看下bta_sys_hw_api_enable方法


/******************************************************************************* ** ** Function bta_sys_hw_enable ** ** Description this function is called after API enable and HW has been turned on ** ** ** Returns success or failure ** *******************************************************************************/void bta_sys_hw_api_enable( tBTA_SYS_HW_MSG *p_sys_hw_msg ) {if ((!bta_sys_cb.sys_hw_module_active) && (bta_sys_cb.state != BTA_SYS_HW_ON)){/* register which HW module was turned on */bta_sys_cb.sys_hw_module_active |= ((UINT32)1 << p_sys_hw_msg->hw_module );tBTA_SYS_HW_MSG *p_msg;if ((p_msg = (tBTA_SYS_HW_MSG *) GKI_getbuf(sizeof(tBTA_SYS_HW_MSG))) != NULL){p_msg->hdr.event = BTA_SYS_EVT_ENABLED_EVT;p_msg->hw_module = p_sys_hw_msg->hw_module;bta_sys_sendmsg(p_msg);}}else{/* register which HW module was turned on */bta_sys_cb.sys_hw_module_active |= ((UINT32)1 << p_sys_hw_msg->hw_module );/* HW already in use, so directly notify the caller */if (bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ]!= NULL )bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ]( BTA_SYS_HW_ON_EVT );}APPL_TRACE_EVENT ("bta_sys_hw_api_enable for %d, active modules 0x%04X",p_sys_hw_msg->hw_module, bta_sys_cb.sys_hw_module_active);} -_-!這注釋不是說已經打開了嗎,莫非這狀態機是為了回調,之前已經打開了?

網上查了很多,發現漏了一個很重要的地方,在bte_main.c的bte_main_enable()方法中,有句module_start_up(get_module(HCI_MODULE)),這個HCI_MODULE就是hci_layer.c,再看看module_start_up()方法,

bool module_start_up(const module_t *module) {assert(metadata != NULL);assert(module != NULL);// TODO(zachoverflow): remove module->init check once automagic order/call is in place.// This hack is here so modules which don't require init don't have to have useless calls// as we're converting the startup sequence.assert(get_module_state(module) == MODULE_STATE_INITIALIZED || module->init == NULL);if (!call_lifecycle_function(module->start_up)) {LOG_ERROR("%s failed to start up \"%s\"", __func__, module->name);return false;}set_module_state(module, MODULE_STATE_STARTED);return true; } 會調用modle的start_up方法

static future_t *start_up(void) {......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);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 resetvendor->send_command(VENDOR_CHIP_POWER_CONTROL, &power_state); #endifpower_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 itreturn future_new_immediate(FUTURE_FAIL); } vendor->open調用vendor.c的vendor_open(),調用廠商的open接口,后面vendor->send_command應該是上電操作。

總結

以上是生活随笔為你收集整理的android6.0 Bluetooth蓝牙源码流程笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

天堂av一区二区 | 91香蕉视频 mp4 | 97在线视| 一区二区三区免费在线观看 | 亚洲精品视频网站在线观看 | 干天天| 亚洲天堂网在线视频观看 | 欧美一级免费在线 | 国产综合小视频 | 欧美先锋影音 | 国产精品成人一区二区三区 | 久久不射电影院 | 最新婷婷色 | 婷婷亚洲激情 | 国产精品美女久久久久久久久久久 | 在线小视频你懂得 | 亚洲视频2| 97国产在线视频 | 亚洲天堂网在线视频 | 国产在线精品播放 | 久久99久久久久 | 高清中文字幕 | 欧美国产精品一区二区 | 日韩精品一区二区三区不卡 | 天天干天天操天天做 | 久久综合欧美精品亚洲一区 | 成人毛片一区 | 91激情在线视频 | 亚洲精品国产麻豆 | 国产原创在线观看 | 日韩免费av片 | 国产精品久久久久久久久久久不卡 | 久久99偷拍视频 | 97av视频 | 99久久国产免费免费 | 久久久久美女 | 免费看色网站 | 国产99在线播放 | 日韩毛片在线播放 | 久久久久五月天 | 夜夜视频资源 | 手机色站 | 国产精品黄网站在线观看 | 亚洲我射av | 四虎亚洲精品 | 91.精品高清在线观看 | 色97在线| 欧美日韩二区三区 | 97在线免费观看 | 日本久久久久久 | 美女免费黄视频网站 | 国产一区二区久久久久 | 国产视频一区二区在线播放 | 中文理论片 | 欧美巨大荫蒂茸毛毛人妖 | 永久免费视频国产 | 亚洲天天摸日日摸天天欢 | 日日干干 | 狠狠干激情 | 国产精品mv | 91久久久国产精品 | 亚洲免费在线视频 | 国产在线播放观看 | 日本高清xxxx| 五月导航 | 国产视频一| 亚洲视频2| 人人澡人人爱 | 国产精品18久久久久vr手机版特色 | 深爱婷婷 | www免费在线观看 | 精品欧美乱码久久久久久 | 国产精品私人影院 | 99爱精品视频 | 免费视频91蜜桃 | 久久九九久久精品 | 一区二区三区精品在线视频 | 2019天天干夜夜操 | 亚洲蜜桃在线 | 久久成人午夜视频 | 婷婷网在线 | 99久久婷婷国产一区二区三区 | 国产91欧美 | 成人黄大片视频在线观看 | www.夜夜爽 | 精品一区二区av | 亚洲人在线视频 | 国产系列在线观看 | 99国产精品久久久久老师 | 国产一级二级在线播放 | 亚洲va男人天堂 | 人人爱人人射 | 日韩免费精品 | 国产精品18久久久久久久久久久久 | www.夜夜爽| 久久久www成人免费毛片 | 日韩欧美一区二区不卡 | www.夜夜干.com | 日本久久高清视频 | 91av在| 毛片网站在线观看 | 国产成人不卡 | 亚洲一区二区三区在线看 | 日韩av一区二区在线影视 | 亚洲乱码在线观看 | 婷婷激情在线观看 | 日韩在线不卡av | 天天操天天能 | 久久久久在线观看 | 综合天堂av久久久久久久 | 亚洲伦理电影在线 | 黄色免费观看网址 | 91看片在线播放 | 日本精品一 | 欧美色综合 | 国产精品久久久久久模特 | 天堂成人在线 | 超碰97在线资源站 | av动态图片 | 91女神的呻吟细腰翘臀美女 | 18国产精品福利片久久婷 | 亚洲a网| 最近久乱中文字幕 | www.黄色片.com| 五月开心六月伊人色婷婷 | 亚洲免费视频在线观看 | av夜夜操 | 久久高清 | 国产亚洲精品久久久网站好莱 | 亚洲伦理精品 | 在线看片91 | 日韩在线二区 | 中文免费 | 免费av影视| 欧美黄污视频 | 欧美色综合 | 九九99 | 欧美福利视频一区 | 国产免费叼嘿网站免费 | 色综合欧洲 | 精品免费| 五月婷婷网站 | 丁香久久婷婷 | 天堂av免费观看 | 最新在线你懂的 | 国产 欧美 在线 | 欧美激情综合五月色丁香 | 黄色看片 | 97精品免费视频 | 免费观看性生交大片3 | www.亚洲| 婷婷av电影 | 久久久免费精品国产一区二区 | 国产精品亚洲视频 | 国产小视频精品 | 国产小视频在线免费观看视频 | 国产精品久久网 | 国产精品99久久久久久武松影视 | 免费日韩在线 | 久久精品亚洲精品国产欧美 | 久艹视频在线观看 | 69亚洲乱| 果冻av在线 | 狠狠干夜夜 | 国产精品 日韩精品 | 天天插天天操天天干 | 欧美性做爰猛烈叫床潮 | 中文字幕网址 | 我爱av激情网 | 欧美成人按摩 | 国产一级大片在线观看 | 久久久精品二区 | av视屏在线播放 | 欧美黄色高清 | www.狠狠插.com | 四虎影视4hu4虎成人 | 久久人人爽人人爽人人片av免费 | 91香蕉视频720p| 久久国产网站 | 国产免费亚洲 | 看黄色91 | 日韩av影片在线观看 | 五月天激情视频在线观看 | 日韩欧美在线一区 | 激情婷婷亚洲 | 日韩av进入 | 免费在线观看污网站 | 精品理论片 | 四虎视频| 伊人精品影院 | 久久国产精品久久精品 | 缴情综合网五月天 | 天天干天天草天天爽 | 欧美午夜久久 | 精品国产一区二区三区在线 | 亚洲精品国产欧美在线观看 | 日韩精品黄 | 欧美福利片在线观看 | 性色xxxxhd| 国产二区视频在线观看 | 日日日操 | 日韩最新在线视频 | 97理论电影 | 久久久久久亚洲精品 | 三级动图 | ww亚洲ww亚在线观看 | 波多野结衣在线播放视频 | 国内视频在线观看 | 国产精品18毛片一区二区 | 伊人超碰在线 | 丰满少妇麻豆av | 亚洲国产剧情 | 国产在线综合视频 | 色在线免费 | 天天操夜夜干 | 丁香六月五月婷婷 | 婷婷午夜天 | 久久天天躁狠狠躁夜夜不卡公司 | 在线播放精品一区二区三区 | 成人在线播放免费观看 | 国产黑丝袜在线 | 99精品偷拍视频一区二区三区 | 99热精品国产 | 香蕉色综合 | 九九电影在线 | 欧美精品久久久久久久久久久 | 中文永久字幕 | 精品国产精品一区二区夜夜嗨 | www亚洲一区 | 亚洲少妇自拍 | 日韩动漫免费观看高清完整版在线观看 | av黄色在线观看 | 欧美少妇xxx | 手机色在线 | 精品96久久久久久中文字幕无 | 黄色在线看网站 | 在线视频你懂得 | 99精品国产在热久久下载 | 国产精品一区电影 | 九九亚洲精品 | 亚洲精品在线视频网站 | 五月婷婷开心中文字幕 | 久操97 | 一区二区三区四区在线免费观看 | 五月婷婷综合激情 | 精品国产一区二区在线 | 亚洲日本在线视频观看 | 欧美黄色免费 | 97在线精品| 国产免费影院 | 久久精视频 | 美国三级黄色大片 | 久久久久久久久久毛片 | 日韩免费不卡视频 | 国产黄色片免费 | 中文字幕亚洲精品在线观看 | 在线免费av网站 | 日韩a欧美| 国产视频黄 | 亚洲国产经典视频 | 中文字幕日本特黄aa毛片 | 久 久久影院 | 成人av电影免费在线播放 | 在线观看黄| 麻豆视频国产在线观看 | 91探花在线视频 | 91九色国产蝌蚪 | 亚洲经典视频 | av综合网址 | 国产亚洲精品久久久久秋 | 日日夜夜精品 | 亚洲成a人片77777kkkk1在线观看 | 久久国产精品久久国产精品 | 精品国内自产拍在线观看视频 | 日韩精品免费在线观看视频 | 夜添久久精品亚洲国产精品 | 国产亚洲日 | 成人网大片 | 成人av资源网站 | 91精品视频免费在线观看 | 人人爽人人乐 | 国产成人久久精品一区二区三区 | 88av视频| 午夜精品在线看 | 亚洲最大成人网4388xx | 精品久久久久久亚洲综合网站 | 午夜影院先 | 超碰免费成人 | 久操操| 在线观看免费av网站 | 欧美一区二区三区在线播放 | av三级在线看 | 在线免费中文字幕 | 亚洲精品久久久久www | 久久国产精品久久国产精品 | 国产白浆在线观看 | 精品999| 久草在线视频精品 | 国产高清福利在线 | 337p欧美| 波多野结衣精品在线 | 久久一区国产 | 丁香电影小说免费视频观看 | 中文字幕日本电影 | 国内视频1区 | 九九在线免费视频 | 免费视频黄 | 天堂va在线观看 | 久久毛片网 | 最新成人av | 91在线播放视频 | 国产亚洲精品久久久久久电影 | 一区二区三区www | 精品国产亚洲在线 | 日日爽天天爽 | 成人在线视频免费 | 国内少妇自拍视频一区 | 国产高清免费观看 | 中文免费在线观看 | 手机成人免费视频 | 免费看精品久久片 | 91精品国自产在线 | 亚洲精品国产欧美在线观看 | 最近中文字幕mv免费高清在线 | 婷婷综合久久 | 亚洲免费成人av电影 | 看黄色.com | 精品国产91亚洲一区二区三区www | 久久久久久久99精品免费观看 | 亚洲国产成人在线观看 | 国产99精品在线观看 | 国产一级免费av | 97在线免费视频 | 国产韩国精品一区二区三区 | 国产专区视频在线观看 | 91精品一区二区三区久久久久久 | 视频一区视频二区在线观看 | 欧美贵妇性狂欢 | 亚洲精品成人av在线 | 国产亚洲免费的视频看 | 三级黄色免费 | 国产精品一区二区免费看 | 91精品国自产拍天天拍 | 欧美性精品| 国产一区二区在线免费观看 | www.亚洲视频.com | 9热精品 | 丁香六月网 | 极品中文字幕 | 成人一级影视 | 激情久久伊人 | 亚洲欧美日韩精品久久奇米一区 | 婷婷在线综合 | 国产日产欧美在线观看 | 日韩二区三区在线观看 | 日韩影视大全 | 一区二区三高清 | 久久www免费人成看片高清 | 极品久久久 | 99热这里是精品 | 99热这里是精品 | 国产a级精品 | 91精品啪在线观看国产 | 国产一级片视频 | 欧美日韩3p | 精品一区电影国产 | 国产3p视频| 久久精品这里都是精品 | 在线 影视 一区 | 成人av亚洲| 在线视频福利 | 日韩在线无 | 四虎影视精品永久在线观看 | 在线国产激情视频 | 亚洲一区精品人人爽人人躁 | 国产精品久久久久久久免费观看 | 亚洲免费av在线播放 | 亚洲成人精品在线观看 | 日韩色av色资源 | 国产 字幕 制服 中文 在线 | 成人四虎影院 | 亚洲高清在线精品 | 激情丁香综合五月 | 中文一区在线观看 | 国产一二区精品 | 国产字幕在线观看 | 91精品国产入口 | 亚洲精品视频网站在线观看 | 成人免费av电影 | 久久激情电影 | 天天天天色综合 | 亚洲综合激情小说 | 国产麻豆剧传媒免费观看 | 亚洲少妇久久 | 在线观看中文字幕网站 | 久久不卡国产精品一区二区 | 私人av| 欧美久久电影 | 最近日本韩国中文字幕 | 精品中文字幕在线观看 | 玖玖爱国产在线 | www.国产高清 | 天天爽天天爽天天爽 | 国产99久久九九精品免费 | 中文字幕在线观看亚洲 | 在线观看视频色 | 成人久久久精品国产乱码一区二区 | 四虎www com| 午夜影视av | 免费视频二区 | 麻豆传媒视频观看 | 国语自产偷拍精品视频偷 | 久久视频网 | 欧美最新另类人妖 | 日日夜夜骑 | 深爱激情五月综合 | 亚洲精品在线视频网站 | 国产视频资源在线观看 | 一区二区三区高清 | 欧美日韩视频在线一区 | 国产一级片观看 | 黄色网址国产 | 日日夜夜天天久久 | 亚洲成av人片在线观看香蕉 | 丝袜美腿在线视频 | 黄色av电影在线 | 91试看 | 97免费公开视频 | 成人h电影 | 日日夜夜狠狠 | 一级黄网| 六月天色婷婷 | 久久视频这里有久久精品视频11 | 一本色道久久综合亚洲二区三区 | 日韩网站在线免费观看 | 一区二区视频在线播放 | 久久久国产高清 | 97久久精品午夜一区二区 | 国产午夜在线观看视频 | 最新国产福利 | 国产精品精品久久久久久 | 在线成人免费电影 | 超碰在线最新网址 | 91麻豆文化传媒在线观看 | 久久久久久久免费观看 | 国产精品自产拍在线观看 | 国产精品午夜久久 | 国模吧一区 | 日韩在线免费观看视频 | 亚洲精品乱码久久久久久 | 国产精品乱码久久 | av在线最新 | 亚洲成人黄| 亚洲精品在线网站 | 欧美日韩另类在线观看 | 婷婷丁香色 | 日韩在线视频网址 | 丰满少妇麻豆av | 亚洲精品小视频在线观看 | 国产v欧美 | 国产专区第一页 | 亚洲资源视频 | 久草在线高清视频 | 久久免费黄色 | 国产在线久久久 | 国内精品久久久久久久97牛牛 | 片黄色毛片黄色毛片 | 日韩欧美xxx | 视频一区视频二区在线观看 | 久草免费在线视频 | 毛片网站在线观看 | 久久久久国产一区二区 | 公与妇乱理三级xxx 在线观看视频在线观看 | 免费日韩在线 | 久久久久久久久久国产精品 | 国产精品久久电影网 | 亚洲精品一区二区三区在线观看 | 欧美黑人猛交 | 国产99中文字幕 | 天天爱天天操天天干 | 日韩精品在线一区 | 黄色资源网站 | 成人av高清在线 | 久久久久久久电影 | 91精品国产欧美一区二区成人 | 黄a网| 亚洲在线综合 | 午夜影院三级 | 在线观看中文 | 国产精品视频全国免费观看 | 国产免费一区二区三区最新6 | 国产午夜亚洲精品 | 日本一区二区三区视频在线播放 | 天天玩天天干天天操 | 国产精品成人免费精品自在线观看 | 成人av影视在线 | 狠狠狠综合 | 久久精品视频国产 | 日韩区在线观看 | 人人澡人人模 | 91麻豆国产 | 丁香五婷| 99热在线国产 | 这里有精品在线视频 | 去看片| 亚洲久草网 | 日韩成人精品 | 婷婷 综合 色 | 久久久在线视频 | 一级黄色毛片 | 在线中文字幕观看 | 日韩免费网址 | 亚洲日韩欧美视频 | 91久久精品日日躁夜夜躁国产 | 日韩精品久久久久久中文字幕8 | 欧美日韩大片在线观看 | 麻豆91视频 | 中文字幕有码在线 | 亚洲国产高清在线 | 天天爱天天操天天射 | 国产99在线| 最新亚洲视频 | 99免费在线播放99久久免费 | 97高清免费视频 | 欧美另类成人 | 人人爽人人爽人人爽学生一级 | 一区 二区电影免费在线观看 | 成人av手机在线 | 婷婷综合成人 | 综合激情网 | 欧美日韩国产欧美 | 国产成人精品一二三区 | 欧美不卡视频在线 | 久草在线免费新视频 | 国产资源在线视频 | 亚洲精品视频二区 | 日本爱爱片 | 九色在线 | 国产特级毛片 | a级免费观看 | 黄污视频网站 | 亚洲乱码精品 | 中文字幕在线视频精品 | 91视频在线免费 | 久久久久久久看片 | 免费av看片 | 日韩免费三级 | 伊人狠狠色 | 日韩av午夜在线观看 | 久久久久免费电影 | 免费在线播放视频 | 91成人网页版 | 麻豆91在线播放 | 日韩精品极品视频 | 久草在线视频网站 | 日本精品中文字幕在线观看 | 亚洲天堂自拍视频 | www.888.av| 日韩福利在线观看 | 色综合久久五月天 | 免费视频二区 | 久久精品国产免费观看 | 久久国产精品小视频 | 久久69精品久久久久久久电影好 | 成人精品视频 | 久久久免费精品国产一区二区 | 欧美成人xxxxx | 亚洲精品美女在线 | 国产免费观看久久 | 免费激情在线电影 | 久久久久久久久久久久国产精品 | 激情综合色图 | 国产理伦在线 | 草久在线观看视频 | а中文在线天堂 | 久久伊人爱| 国产精品免费视频网站 | 天天色天天射天天操 | 精品电影一区 | 色狠狠婷婷 | 在线观看91 | 亚洲天堂精品视频在线观看 | 99中文视频在线 | 国产在线观看黄 | 99在线热播 | 日韩av成人在线观看 | 丁香六月久久综合狠狠色 | 四虎国产精品免费观看视频优播 | 色婷婷色 | 亚洲欧洲精品一区 | 91人人网 | 免费观看日韩av | 69久久久久久久 | 91精品啪在线观看国产 | 久久午夜羞羞影院 | 国产黄色一级大片 | 国产精品久久久久久模特 | 日日爱网站| 色婷婷激情四射 | 99国产在线观看 | 日韩一二三区不卡 | 久久久久北条麻妃免费看 | 麻豆视频在线播放 | 国产一区在线不卡 | 精品福利网站 | 亚洲高清视频在线观看 | 日本动漫做毛片一区二区 | 久久精品麻豆 | www色片 | 亚洲黄色小说网 | 91大片网站 | 人人玩人人爽 | av播放在线 | 97电影手机 | 中文字幕韩在线第一页 | 国产黄色免费看 | 欧美日韩亚洲第一 | 成人一级免费电影 | 欧美大片第1页 | 久久久片 | 欧美日韩国产在线精品 | 99精品毛片| 欧美激情综合五月色丁香 | 一级黄毛片 | 综合伊人av | 日韩com | 狠狠干天天 | 久久久久久久久久久综合 | 亚洲成av人片在线观看 | 狠狠躁日日躁夜夜躁av | 色吊丝在线永久观看最新版本 | 色妞色视频一区二区三区四区 | 日韩欧美精选 | 日韩精品欧美专区 | 欧美日韩99 | 久久国产视频网站 | 日韩精品aaa| 久久精品91久久久久久再现 | 欧美日韩综合在线观看 | 2019久久精品| 黄色网址av| 00av视频 | 国产自产高清不卡 | 69精品久久久 | 二区在线播放 | 丰满少妇对白在线偷拍 | 亚洲黄色成人 | 九九色网| 超碰97在线资源 | 一区二区三区国产精品 | 欧美日韩高清一区二区 国产亚洲免费看 | 成人av高清在线观看 | 高清av中文字幕 | 99视频精品视频高清免费 | 色干综合 | 国产精品美女久久久久aⅴ 干干夜夜 | 国产日韩欧美精品在线观看 | 中文字幕在线字幕中文 | 999国内精品永久免费视频 | 成人久久国产 | 亚洲激情 在线 | 97超碰人人澡人人 | 免费又黄又爽视频 | 久久视频在线观看 | 日韩一区二区三区在线观看 | 97香蕉超级碰碰久久免费软件 | 国产又黄又硬又爽 | 人人澡人摸人人添学生av | 亚洲91精品在线观看 | 色噜噜在线观看视频 | 久久精品国产99国产 | 五月婷婷另类国产 | 久久久官网 | 91正在播放 | 91亚洲精品久久久蜜桃 | 国产中文字幕在线视频 | 亚洲国产三级在线观看 | 欧美一区二区三区激情视频 | 国产aaa毛片 | 免费视频你懂得 | 国产精品久久久久久超碰 | 91网站在线视频 | 91九色视频观看 | 国内丰满少妇猛烈精品播放 | 一区二区三区精品在线视频 | 国产香蕉久久精品综合网 | 久久久91精品国产一区二区精品 | 狠狠操操操| 美女黄色网在线播放 | 国产精品 日本 | 国产精品视频区 | 免费中文字幕在线观看 | 日日夜夜精品免费观看 | 狠狠的干狠狠的操 | 狠狠色丁香婷婷综合 | 国产女人18毛片水真多18精品 | 精品国产一区二区三区男人吃奶 | 麻豆视频国产精品 | 精品国产乱码久久 | 狠狠插狠狠干 | 欧美九九视频 | 最近中文字幕完整视频高清1 | 天天干干 | 亚洲精品乱码久久久久久蜜桃动漫 | 国产一卡二卡四卡国 | 六月婷婷久香在线视频 | 亚洲全部视频 | 91在线操| 人人看人人爱 | 国产高清成人 | 婷婷久月 | 欧美激情第28页 | 中文字幕国产精品一区二区 | 特级黄色电影 | 69视频永久免费观看 | 麻豆视频在线免费观看 | 欧美日韩在线观看视频 | 日韩黄色av网站 | 超碰免费观看 | 国产婷婷在线观看 | 欧洲av在线| 久久精品国产精品亚洲精品 | 成人影视免费看 | 97电影网手机版 | 欧美在线99| 国产一级电影 | 日本久久高清视频 | 日本夜夜草视频网站 | 中文字幕在线第一页 | www.久久色 | 亚洲精品中文在线 | www.久久久精品 | 精品美女在线观看 | 国产99久久久国产精品免费二区 | 综合网中文字幕 | 亚洲高清视频在线观看 | 国产又粗又猛又爽 | 久久亚洲欧美日韩精品专区 | 国产精品小视频网站 | 色免费在线 | 色网站免费在线观看 | 久久人人爽人人片 | 日本成址在线观看 | 91九色视频国产 | 99久久99精品 | 国产涩涩网站 | av电影在线播放 | 色综合婷婷久久 | 国产剧情一区在线 | 天天干天天搞天天射 | 超碰97公开 | 国产无套精品久久久久久 | 免费中文字幕视频 | 亚洲国产精品成人va在线观看 | 亚洲黄色一级电影 | 欧美精品久久人人躁人人爽 | 免费观看一区二区三区视频 | 91精品入口| 激情小说网站亚洲综合网 | 婷婷综合成人 | 国产999视频在线观看 | 在线影院中文字幕 | 国产黄色片网站 | 日韩中文字幕a | 久久经典国产视频 | 99色资源| 欧美少妇的秘密 | 日韩欧美一区二区三区免费观看 | 91在线视频免费观看 | 欧美精品一区在线发布 | 人人爽人人乐 | 国产视频丨精品|在线观看 国产精品久久久久久久久久久久午夜 | 成人免费ⅴa| 亚洲天堂在线观看完整版 | 99精品在线观看视频 | 一区二区三区在线影院 | 久草在线免费播放 | 欧美视频xxx | 午夜91在线 | 日韩av成人 | 国产999精品久久久影片官网 | 九九免费在线观看 | 日日碰狠狠添天天爽超碰97久久 | 啪啪午夜免费 | 日韩av中文在线 | 国产成人久 | 亚洲精品综合在线观看 | 久久国产免费视频 | 国产青青青| 91久草视频| 亚洲 综合 激情 | 免费又黄又爽的视频 | 亚洲精品美女久久17c | av中文字幕在线免费观看 | 伊人五月天av | 免费一级日韩欧美性大片 | 精品亚洲视频在线观看 | 91精品国自产在线观看 | 国产精品v欧美精品v日韩 | 日韩高清免费观看 | 91黄色在线看 | 日韩美女高潮 | 中文字幕日韩国产 | 午夜av免费观看 | 日韩在线免费视频 | 久久久久久久久网站 | 国产在线中文 | 亚洲高清视频在线 | 最近中文字幕第一页 | 久久久久久久久久久久久9999 | 国产亚州精品视频 | 亚洲精品2区 | 亚洲精品理论 | 毛片美女网站 | 99精品福利 | 国产免费又黄又爽 | 91av中文字幕 | 久久久国产精品成人免费 | 日韩精品一区在线播放 | 欧美污污网站 | 欧美精品久久久久久久 | 超碰在线官网 | 国产精品美女在线 | 最新真实国产在线视频 | 久久久久久久久毛片精品 | 正在播放国产一区二区 | 亚洲欧美精品在线 | 久久精品这里都是精品 | 国产视频一区二区在线观看 | 欧美va天堂在线电影 | 国产精品成人av电影 | 激情久久婷婷 | 成年一级片 | 奇米7777狠狠狠琪琪视频 | av导航福利 | 亚洲国产大片 | 五月激情综合婷婷 | 丁香综合av | 亚洲精品视频播放 | 日本不卡123区 | 欧美人zozo| 成人免费观看av | 中文字幕在线观看视频一区 | 中文字幕日韩有码 | 久久久久国产成人精品亚洲午夜 | 成人免费在线播放视频 | 91传媒在线 | 99re8这里有精品热视频免费 | 久久亚洲免费视频 | 最新极品jizzhd欧美 | 探花视频在线观看免费 | 国产一级片播放 | 中文字幕美女免费在线 | 国产福利专区 | 国产一区欧美日韩 | 精品中文字幕在线播放 | 日韩综合第一页 | 欧美 日韩 性 | 91亚洲欧美 | 国内精品久久久久久久影视麻豆 | 九九视频精品在线 | 日本久久中文字幕 | 国产成人一级电影 | 久久理论电影 | 在线视频你懂得 | 国产精品久久久久久久久久久久午夜 | 精品视频在线免费 | 久久99精品久久只有精品 | 久久久久久视频 | 蜜臀av网址 | 日本久久91 | 国产三级在线播放 | 国产成人福利在线 | 久久日韩精品 | 激情五月婷婷综合网 | 91精品少妇偷拍99 | 亚洲国产免费 | 日韩久久影院 | 亚洲精品日韩av | 亚洲视频免费在线观看 | 久草剧场| 久久久久久久久国产 | 超碰在线人人艹 | 久久1电影院 | 久久久久久免费 | 伊人电影在线观看 | av中文字幕免费在线观看 | 国产 日韩 欧美 自拍 | 极品嫩模被强到高潮呻吟91 | 亚洲精品中文字幕视频 | 久热免费在线 | 国产99自拍 | 91成人欧美 | 超碰97人人爱 | 国产精品网红直播 | 成人激情开心网 | 天天干天天操天天操 | 成年人国产视频 | 亚州国产精品久久久 | 久久久久久久久久久久电影 | 亚洲视频axxx | 99精品欧美一区二区三区黑人哦 | 午夜久久久久久久久 | 国产日韩精品一区二区三区 | 美女网站在线免费观看 | 久久歪歪| 日韩成人免费电影 | 亚洲人天堂 | 成人国产电影在线观看 | 日韩中文字幕免费在线观看 | 97免费视频在线 | 亚洲综合视频在线 | 亚洲成成品网站 | 久久超级碰视频 | 狠狠干天天色 | 国产午夜精品福利视频 | 日韩毛片久久久 | 美女免费网视频 | 天天视频色 | 国产一区二区三区 在线 | 婷婷午夜天| 一区二区三区在线免费观看视频 | 久久久午夜剧场 | 黄色av播放 | 国产高清一级 | 国产vs久久 | 成人免费视频观看 | 91在线蜜桃臀 | 97超碰网 | 国产精品一区二区三区久久久 | 99性视频 | 国产婷婷久久 | 在线观看免费黄视频 | 天天曰视频 | 在线播放视频一区 | 99久久er热在这里只有精品15 | 久久综合干 | 911久久香蕉国产线看观看 | 亚洲精品日韩在线观看 | 欧美一二区在线 | 国产精品欧美久久久久久 | 97视频入口免费观看 | www.五月婷婷.com | 国产色综合天天综合网 | 麻豆免费在线播放 | 免费福利在线播放 | 久久视频一区 | 亚洲综合在线五月 | 精品国产伦一区二区三区观看说明 | 亚洲在线a | 国产精品网站一区二区三区 | 玖草影院 | 中文字幕乱码电影 | 综合久久久| av电影免费在线 | 久在线观看视频 | 久久久久久久久久影视 | 成人在线视频免费观看 | 久久er99热精品一区二区 | 亚洲国产成人久久综合 | 国产视频在线观看一区二区 | 中文字幕在线视频一区二区三区 | 日韩精品最新在线观看 | 欧美色就是色 | 91.dizhi永久地址最新 | 亚洲国产精品第一区二区 | 成人手机在线视频 | 欧美日韩精品区 | 中文字幕999| 一级a毛片高清视频 | www.狠狠色 | 97久久精品午夜一区二区 | 久久久久久久久爱 | 久久99中文字幕 | 又黄又爽又无遮挡免费的网站 | 国产一区二区不卡在线 | 日韩精品在线免费播放 | 欧美激情第一区 | 中文字幕在线视频免费播放 | 亚洲精品在线电影 | 欧美性色黄 | www天天操 | 亚洲视频2| 五月婷综合| 亚洲精品久久久久久久不卡四虎 | 黄色视屏av | 国产精品久久久久久久av大片 | 国产字幕在线看 | 西西444www大胆高清视频 | 亚洲日本精品视频 | 久久欧美在线电影 | 久久免费视频网站 | 欧美日韩精品免费观看 | 97精品国产 | 日本精品中文字幕在线观看 | 91影视成人| 日日干天天 | 最新日韩中文字幕 |