完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
平台
RK3288 + Android 7.1 概述 本文用于跟踪android获取蓝牙MAC接口实现的代码流程。 《 》 《 y=“0” rx=“3” ry=“3” 》 《 y=“32.5” 》 APP 《 》 《 y=“0” rx=“3” ry=“3” 》 《 y=“ 32.5” 》 框架 《 》 《 y=“0” rx=“3” ry=“3” 》 《 y=“32.5” 》 蓝牙 《 》 《 y=“0” rx=“3” ry=“3” 》 《 y=“32.5” 》 JNI 《 》 《 y=“ 《 y=”128“ 》 bindService 《 》 《 y=”163“ 》 getAddress() 《 》 《 y=”198“ 》 initNative 《 》 《 y=”233“ 》 adapter_properties_callback 《 》 《 y=”260“ rx= ”3“ ry=”3“ 》 《 y=”292.5“ 》 应用 程序 《 y=”260“ rx=”3“ ry=”3“ 》 《 y=”292.5“ 》 框架 《 y=”260“ rx= ”3“ ry=”3“ 》 《 y=”292.5“ 》 蓝牙 《 y=”260“ rx=”3“ ry=”3“ 》 《 y=”292.5“ 》 JNI 《 y=”260“ rx=”3“ ry=”3“ 》 《 y=”292.5“ 》 HAL 实现与参考代码 Android 提供了标准的信息接口用于访问蓝牙的MAC地址BlueothAdapter bt BluetoothAdapter.getDefaultAdapter(); 字符串地址 = bt.getAddress(); String name = bt.getName();//00:11:22:33:44:55 注意权限的申请如下 FRAMEWORK层 SDK接口的BluetoothAdapter源码: |-- frameworks/base/core/java/android/bluetooth/ BluetoothAdapter.java 公共静态同步 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, ”蓝牙绑定器为空“); } } 返回适配器; } BluetoothAdapter(IBluetoothManager managerService) { if (managerService == null) { throw new IllegalArgumentException(”bluetooth manager service is null“); } 尝试 { mServiceLock.writeLock().lock(); mService = managerService.registerAdapter(mManagerCallback); } catch (RemoteException e) { Log.e(TAG, ”“, e); } 最后 { mServiceLock.writeLock().unlock(); } mManagerService = managerService; mLeScanClients = new HashMap《LeScanCallback, ScanCallback》(); mToken = new Binder(); } 公共字符串 getAddress() { 尝试 { 返回 mManagerService.getAddress(); } catch (RemoteException e) {Log.e(TAG, ”“, e);} return null; } mManagerService服务接口, 由BluetoothService注册到系统服务中 |-- frameworks/base/services/core/java/com/android/server/BluetoothService.java @Override public void onBootPhase(int phase) { if (phase == SystemService .PHASE_SYSTEM_SERVICES_READY) { publishBinderService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, mBluetoothManagerService); } else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) { mBluetoothManagerService.handleOnBootPhase(); } } |-- frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java public String getAddress() { mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, ”需要 BLUETOOTH 权限“); if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) { Slog.w(TAG,”getAddress(): not allowed for non-active and non system user“); 返回空值; } if (mContext.checkCallingOrSelfPermission(Manifest.permission.LOCAL_MAC_ADDRESS) != PackageManager.PERMISSION_GRANTED) { return BluetoothAdapter.DEFAULT_MAC_ADDRESS; } 尝试 { mBluetoothLock.readLock().lock(); if (mBluetooth != null) return mBluetooth.getAddress(); } catch (RemoteException e) { Slog.e(TAG, ”getAddress(): 无法远程检索地址。返回缓存地址“, e); } 最后 { mBluetoothLock.readLock().unlock(); } // mAddress 从外部访问。 // 没有锁也没关系。此处,蓝牙已关闭,没有其他线程在 // 更改 mAddress return mAddress; } 私有类 BluetoothServiceConnection 实现 ServiceConnection { public void onServiceConnected(ComponentName componentName, IBinder service) { String name = componentName.getClassName(); if (DBG) Slog.d(TAG, ”BluetoothServiceConnection: “ + name); 消息消息 = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED); if (name.equals(”com.android.bluetooth.btservice.AdapterService“)) { msg.arg1 = SERVICE_IBLUETOOTH; } else if (name.equals(”com.android.bluetooth.gatt.GattService“)) { msg.arg1 = SERVICE_IBLUETOOTHGATT; } else { Slog.e(TAG, ”未知服务已连接:“ + name); 返回; } msg.obj = 服务; mHandler.sendMessage(msg); } public void onServiceDisconnected(ComponentName componentName) { // 如果我们意外断开连接,则调用。 字符串名称 = componentName.getClassName(); if (DBG) Slog.d(TAG, ”BluetoothServiceConnection, disconnected: “ + name); 消息消息 = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED); if (name.equals(”com.android.bluetooth.btservice.AdapterService“)) { msg.arg1 = SERVICE_IBLUETOOTH; } else if (name.equals(”com.android.bluetooth.gatt.GattService“)) { msg.arg1 = SERVICE_IBLUETOOTHGATT; } else { Slog.e(TAG, ”未知服务已断开:“ + name); 返回; } mHandler.sendMessage(msg); } } 私有类 BluetoothHandler 扩展处理程序 { boolean mGetNameAddressOnly = false; 超级(弯针); } @Override public void handleMessage(Message msg) { switch (msg.what) { case MESSAGE_GET_NAME_AND_ADDRESS: if (DBG) Slog.d(TAG, ”MESSAGE_GET_NAME_AND_ADDRESS“); 尝试 { mBluetoothLock.writeLock().lock(); if ((mBluetooth == null) && (!mBinding)) { if (DBG) Slog.d(TAG, ”绑定到服务以获取名称和地址“); mGetNameAddressOnly = 真; 消息 timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND); mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS); 意图 i = new Intent(IBluetooth.class.getName()); if (!doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.CURRENT)) { mHandler.removeMessages(MESSAGE_TIMEOUT_BIND); } 其他 { mBinding = true; } } else if (mBluetooth != null) { 试试 { storeNameAndAddress(mBluetooth.getName(), mBluetooth.getAddress()); } catch (RemoteException re) { Slog.e(TAG, ”Unable to grab names“, re); } if (mGetNameAddressOnly && !mEnable) { unbindAndFinish(); } mGetNameAddressOnly = 假; } } 最后 { mBluetoothLock.writeLock().unlock(); } 打破; //。.. case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: { if (DBG) Slog.d(TAG,”MESSAGE_BLUETOOTH_SERVICE_CONNECTED: “ + msg.arg1); IBinder 服务 = (IBinder) msg.obj; 尝试 { mBluetoothLock.writeLock().lock(); if (msg.arg1 == SERVICE_IBLUETOOTHGATT) { mBluetoothGatt = IBluetoothGatt.Stub.asInterface(service); onBluetoothGattServiceUp(); 休息; } // else 必须是 SERVICE_IBLUETOOTH //移除超时 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND); mBinding = 假; mBluetoothBinder = 服务; mBluetooth = IBluetooth.Stub.asInterface(service); if (!isNameAndAddressSet()) { Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS); mHandler.sendMessage(getMsg); 如果(mGetNameAddressOnly)返回; } 尝试 { boolean enableHciSnoopLog = (Settings.Secure.getInt(mContentResolver, Settings.Secure.BLUETOOTH_HCI_LOG, 0) == 1); if (!mBluetooth.configHciSnoopLog(enableHciSnoopLog)) { Slog.e(TAG,”IBluetooth.configHciSnoopLog return false“); } } catch (RemoteException e) { Slog.e(TAG,”无法调用 configHciSnoopLog“, e); } //注册回调对象 try { mBluetooth.registerCallback(mBluetoothCallback); } 捕捉(远程异常重新){ Slog.e(TAG, ”无法注册蓝牙回调“,re); } //通知蓝牙适配器实例服务已启动 sendBluetoothServiceUpCallback(); //启用请求 try { if (mQuietEnable == false) { if (!mBluetooth.enable()) { Slog.e(TAG,”IBluetooth.enable() returned false“); } } else { if (!mBluetooth.enableNoAutoConnect()) { Slog.e(TAG,”IBluetooth.enableNoAutoConnect() 返回 false“); } } } catch (RemoteException e) { Slog.e(TAG,”无法调用 enable()“,e); } } 最后 { mBluetoothLock.writeLock().unlock(); } if (!mEnable) { waitForOnOff(true, false); 处理禁用(); waitForOnOff(假,假); } 打破; } PACKAGES 与 HAL 层的通讯实现发现蓝牙的 APP 中,由蓝牙 APPBIND 服务: |--packages/apps/Bluetooth/AndroidManifest.xml 《service android: android:name = ”.btservice.AdapterService“》 《 intent-filter》 《action android:name=”android.bluetooth.IBluetooth“ /》 《/intent-filter》 《/service》 |--packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService. java private static class AdapterServiceBinder extends IBluetooth.Stub { //。.. public String getAddress() { if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!Utils.checkCallerAllowManagedProfiles(mService))) { Log.w(TAG, ”getAddress() - 非活动用户和非系统用户不允许“); 返回空值; } AdapterService 服务 = getService(); 如果(服务 == null)返回 null; 返回服务.getAddress(); } //。.. } String getAddress() { enforceCallingOrSelfPermission(BLUETOOTH_PERM, ”需要 BLUETOOTH 权限“); 字符串 addrString = null; 字节[] 地址 = mAdapterProperties.getAddress(); return Utils.getAddressStringFromByte(address); } |-- packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterProperties.java /** * @return mAddress */ byte[] getAddress() { return mAddress; } void adapterPropertyChangedCallback(int[] types, byte[][] values) { Intent intent; 整数类型; 字节[] 值; for (int i = 0; i 《 types.length; i++) { val = values ; 类型 = 类型; infoLog(”adapterPropertyChangedCallback with type:“ + type + ” len:“ + val.length); 同步(mObject){ 开关(类型){ case AbstractionLayer.BT_PROPERTY_BDNAME: mName = new String(val); intent = new Intent(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED); intent.putExtra(BluetoothAdapter.EXTRA_LOCAL_NAME, mName); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); mService.sendBroadcastAsUser(intent, UserHandle.ALL, mService.BLUETOOTH_PERM); debugLog(”Name is: “ + mName); break; case AbstractionLayer.BT_PROPERTY_BDADDR: mAddress = val; debugLog(”Address is:“ + Utils.getAddressStringFromByte(mAddress)); break; } JNI |-- packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp static bt_callbacks_t sBluetoothCallbacks = { sizeof(sBluetoothCallbacks), adapter_state_change_callback, adapter_properties_callback, remote_device_properties_callback, device_found_callback, discovery_state_changed_callback, pin_request_callback, ssp_request_callback, bond_state_changed_callback, acl_state_changed_callback, callback_thread_event, dut_mode_recv_callback, le_test_mode_recv_callback, energy_info_recv_callback }; static bool initNative(JNIEnv* env, jobject obj) { ALOGV(”%s:“,__FUNCTION__); android_bluetooth_UidTraffic.clazz = (jclass) env-》NewGlobalRef( env-》FindClass(”android/bluetooth/UidTraffic“)); sJniAdapterServiceObj = env-》NewGlobalRef(obj); sJniCallbacksObj = env-》NewGlobalRef(env-》GetObjectField(obj, sJniCallbacksField)); if (sBluetoothInterface) { int ret = sBluetoothInterface-》init(&sBluetoothCallbacks); if (ret != BT_STATUS_SUCCESS) { ALOGE(”Error while setting the callbacks: %dn“, ret); sBluetoothInterface = NULL; return JNI_FALSE; } ret = sBluetoothInterface-》set_os_callouts(&sBluetoothOsCallouts); if (ret != BT_STATUS_SUCCESS) { ALOGE(”Error while setting Bluetooth callouts: %dn“, ret); sBluetoothInterface-》cleanup(); sBluetoothInterface = NULL; return JNI_FALSE; } if ( (sBluetoothSocketInterface = (btsock_interface_t *) sBluetoothInterface-》get_profile_interface(BT_PROFILE_SOCKETS_ID)) == NULL) { ALOGE(”Error getting socket interface“); } return JNI_TRUE; } return JNI_FALSE; } static void adapter_properties_callback(bt_status_t status, int num_properties, bt_property_t *properties) { jobjectArray props; jintArray types; ***yteArray val; jclass mclass; if (!checkCallbackThread()) { ALOGE(”Callback: ‘%s’ is not called on the correct thread“, __FUNCTION__); return; } ALOGV(”%s: Status is: %d, Properties: %d“, __FUNCTION__, status, num_properties); if (status != BT_STATUS_SUCCESS) { ALOGE(”%s: Status %d is incorrect“, __FUNCTION__, status); return; } val = (***yteArray) callbackEnv-》NewByteArray(num_properties); if (val == NULL) { ALOGE(”%s: Error allocating byteArray“, __FUNCTION__); return; } mclass = callbackEnv-》GetObjectClass(val); /* (BT) Initialize the jobjectArray and jintArray here itself and send the initialized array pointers alone to get_properties */ props = callbackEnv-》NewObjectArray(num_properties, mclass, NULL); if (props == NULL) { ALOGE(”%s: Error allocating object Array for properties“, __FUNCTION__); return; } types = (jintArray)callbackEnv-》NewIntArray(num_properties); if (types == NULL) { ALOGE(”%s: Error allocating int Array for values“, __FUNCTION__); return; } // Delete the reference to val and mclass callbackEnv-》DeleteLocalRef(mclass); callbackEnv-》DeleteLocalRef(val); if (get_properties(num_properties, properties, &types, &props) 《 0) { if (props) callbackEnv-》DeleteLocalRef(props); if (types) callbackEnv-》DeleteLocalRef(types); return; } callbackEnv-》CallVoidMethod(sJniCallbacksObj, method_adapterPropertyChangedCallback, types, props); checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__); callbackEnv-》DeleteLocalRef(props); callbackEnv-》DeleteLocalRef(types); return; } 在系统中存在两个hardware 的lib库: rk3288:/ # ll /system/lib/hw/bluetooth* -rw-r--r-- 1 root root 1272568 2019-11-25 15:47 /system/lib/hw/bluetooth.default.so -rw-r--r-- 1 root root 1334308 2020-05-07 15:45 /system/lib/hw/bluetooth_rtk.default.so 主板使用的是8723的模块, 所以对应使用的是:bluetooth_rtk.default.so HAL |-- hardware/realtek/rtkbt/code/bt/btif/src/bluetooth.c static int init(bt_callbacks_t *callbacks) { LOG_INFO(LOG_TAG, ”%s“, __func__); if (interface_ready()) return BT_STATUS_DONE; #ifdef BLUEDROID_DEBUG allocation_tracker_init(); #endif bt_hal_cbacks = callbacks; stack_manager_get_interface()-》init_stack(); btif_debug_init(); #ifdef BLUETOOTH_RTK_API uipc_inited = FALSE; #endif return BT_STATUS_SUCCESS; } |-- hardware/realtek/rtkbt/code/bt/btif/src/btif_core.c bt_status_t btif_init_bluetooth() { LOG_DEBUG(LOG_TAG, ”%s“, __func__); bte_main_boot_entry(); /* As part of the init, fetch the local BD ADDR */ memset(&btif_local_bd_addr, 0, sizeof(bt_bdaddr_t)); btif_fetch_local_bdaddr(&btif_local_bd_addr); bt_jni_workqueue_thread = thread_new(BT_JNI_WORKQUEUE_NAME); if (bt_jni_workqueue_thread == NULL) { LOG_ERROR(LOG_TAG, ”%s Unable to create thread %s“, __func__, BT_JNI_WORKQUEUE_NAME); goto error_exit; } // Associate this workqueue thread with jni. btif_transfer_context(btif_jni_associate, 0, NULL, 0, NULL); return BT_STATUS_SUCCESS; error_exit:; thread_free(bt_jni_workqueue_thread); bt_jni_workqueue_thread = NULL; return BT_STATUS_FAIL; } static void btif_fetch_local_bdaddr(bt_bdaddr_t *local_addr) { char val[PROPERTY_VALUE_MAX] = {0}; uint8_t valid_bda = FALSE; int val_size = 0; int vflash_fd; const uint8_t null_bdaddr[BD_ADDR_LEN] = {0,0,0,0,0,0}; if ((vflash_fd = open(”/dev/vflash“, O_RDONLY)) != -1) { char bd_addr[6] = {0}; BTIF_TRACE_ERROR(”Get local bdaddr from vflash“); #define VFLASH_READ_BDA 0x01 if(ioctl(vflash_fd, VFLASH_READ_BDA, (unsigned long)bd_addr) 》= 0 && memcmp(bd_addr, null_bdaddr, BD_ADDR_LEN) != 0) { local_addr-》address[0] = bd_addr[5]; local_addr-》address[1] = bd_addr[4]; local_addr-》address[2] = bd_addr[3]; local_addr-》address[3] = bd_addr[2]; local_addr-》address[4] = bd_addr[1]; local_addr-》address[5] = bd_addr[0]; //local_addr-》address[0] = local_addr-》address[0] 《《 1; valid_bda = TRUE; BTIF_TRACE_DEBUG(”Got Factory BDA %02X:%02X:%02X:%02X:%02X:%02X“, local_addr-》address[0], local_addr-》address[1], local_addr-》address[2], local_addr-》address[3], local_addr-》address[4], local_addr-》address[5]); } close(vflash_fd); } //。.. } 读取MAC的优先级如下: 读取/dev/vflash 读取/dev/vendor_storage 读取属性PROPERTY_BT_BDADDR_PATH(ro.bt.bdaddr_path)指向的文件, 手上的平台对应的是 /data/misc/bluetooth/bdaddr 读取属性PERSIST_BDADDR_PROPERTY和FACTORY_BT_ADDR_PROPERTY 定义见:hardware/realtek/rtkbt/code/bt/btif/include/btif_common.h |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
基于米尔瑞芯微RK3576核心板/开发板的人脸疲劳检测应用方案
1744 浏览 0 评论
1858 浏览 1 评论
1532 浏览 1 评论
2875 浏览 1 评论
3920 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-7 21:01 , Processed in 0.583146 second(s), Total 70, Slave 54 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (威廉希尔官方网站 图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号