当前位置:首页>优优资讯 > 软件教程 > 电脑软件教程 > Bluedroid的结构和代码分布解析

Bluedroid的结构和代码分布解析

作者:本站整理 时间:2015-08-06

 
Bluedroid的结构和代码分布解析
 
  android development对于4.3蓝牙的介绍:
 
  android提供BlueDroid作为默认的协议栈,BlueDroid分为两个部分:
 
  1、Bluetooth Embedded System(BTE),它实现了BT的核心功能。
  2、Bluetooth Application Layer (BTA),用于和android framework层交互。
 
  BT 系统服务通过JNI与BT stack交互,并且通过Binder IPC通信与应用交互。这个系统服务同时也提供给RD获取不同的BT profiles;下面的图标展示BT stack的一个大体的结构:
 
  一、application Framework
 
  这个层的代码主要是利用android.bluetooth APIS 和 bluetooth hardware进行交互。 也就是通过Binder IPC机制调用bluetooth 进程;
 
  代码位于framework/base/core/java/android.bluetooth/下。
 
  比如A2DP的连接:framework/base/core/java/android.bluetooth/BluetoothA2dp.java中的connect(Bluetoothevice)方法。
 
  public boolean connect(BluetoothDevice device) {
  if (DBG) log("connect(" + device + ")");
  if (mService != null && isEnabled() &&
  isValidDevice(device)) {
  try {
  return mService.connect(device);
  } catch (RemoteException e) {
  Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
  return false;
  }
  }
  if (mService == null) Log.w(TAG, "Proxy not attached to service");
  return false;
  }
 
  通过Binder IPC 通信机制,调用到packages/apps/Bluetooth/src/com.android.bluetooth.a2dp/A2dpService.java下一个内部私有类
 
  A2dpService是一个继承于ProfileService,而ProfileService是继承于Service的。
 
  private static class BluetoothA2dpBinder extends IBluetoothA2dp.Stub{}的connect(BluetoothDevice)方法。
 
  public boolean connect(BluetoothDevice device) {
  A2dpService service = getService();
  if (service == null) return false;
  return service.connect(device);
  }
 
  然后调用到A2dpService的connect(BluetoothDevice)方法。
 
  public boolean connect(BluetoothDevice device) {
  enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
  "Need BLUETOOTH ADMIN permission");
  if (getPriority(device) == BluetoothProfile.PRIORITY_OFF) {
  return false;
  }
  int connectionState = mStateMachine.getConnectionState(device);
  if (connectionState == BluetoothProfile.STATE_CONNECTED ||
  connectionState == BluetoothProfile.STATE_CONNECTING) {
  return false;
  }
  mStateMachine.sendMessage(A2dpStateMachine.CONNECT, device);
  return true;
  }
 
  这个过程就是Bluetooth Application Framework与Bluetooth Process的调用过程。
 
  二、Bluetooth System service
 
  Bluetooth System service位于packages/apps/Bluetooth下,它打包成一个android app包,并且在android framework 层实现BT service
  和各种profile。BT app会通过JNI调用到HAL层。
 
  A2dpService的connect方法会发送一个StateMachine.sendMessage(A2dpStateMachine.CONNECT, device)的message,这个message会被A2dpStateMachine对象的processMessage(Message)方法接收到:
 
  case CONNECT:
  BluetoothDevice device = (BluetoothDevice) message.obj;
  broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING,
  BluetoothProfile.STATE_DISCONNECTED);
  if (!connectA2dpNative(getByteAddress(device)) ) {
  broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
  BluetoothProfile.STATE_CONNECTING);
  break;
  }
  synchronized (A2dpStateMachine.this) {
  mTargetDevice = device;
  transitionTo(mPending);
  }
  // TODO(BT) remove CONNECT_TIMEOUT when the stack
  //          sends back events consistently
  sendMessageDelayed(CONNECT_TIMEOUT, 30000);
  break;
 
  最重要的一句:connectA2dpNative(getByteAddress(device);
 
  即会通过JNI调用到Native;
 
  private native boolean connectA2dpNative(byte[] address);
 
  三、JNI
 
  与android.bluetooth有关的JNI代码位于packages/apps/bluetooth/jni下,JNI 的代码会调用到HAL层,并且在确信一些BT操作被触发时,会从HAL获取一些回调。比如当BT设备被发现时。
 
  再回到A2dp连接的例子中来,BT System Service通过JNI会调用到com_android_bluetooth_a2dp.cpp中:
 
  static jboolean connectA2dpNative(JNIEnv *env, jobject object, jbyteArray address) {
  jbyte *addr;
  bt_bdaddr_t * btAddr;
  bt_status_t status;
  ALOGI("%s: sBluetoothA2dpInterface: %p", __FUNCTION__, sBluetoothA2dpInterface);
  if (!sBluetoothA2dpInterface) return JNI_FALSE;
  addr = env->GetByteArrayElements(address, NULL);
  btAddr = (bt_bdaddr_t *) addr;
  if (!addr) {
  jniThrowIOException(env, EINVAL);
  return JNI_FALSE;
  }
  if ((status = sBluetoothA2dpInterface->connect((bt_bdaddr_t *)addr)) != BT_STATUS_SUCCESS) {
  ALOGE("Failed HF connection, status: %d", status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
  }
 
  重点代码是:status = sBluetoothA2dpInterface->connect((bt_bdaddr_t *)addr);
 
  这个sBluetoothA2dpInterface结构体对象是在initNative(JNIEnv *env, jobject object)方法时得到的。
 
  if ( (sBluetoothA2dpInterface = (btav_interface_t *)
  btInf->get_profile_interface(BT_PROFILE_ADVANCED_AUDIO_ID)) == NULL) {
  ALOGE("Failed to get Bluetooth A2DP Interface");
  return;
  }
 
  四、HAL
 
  硬件抽象层定义android.bluetooth APIs和BT process调用的标准接口,并且你必须实现这些接口来让你的BT hardware功能运行正常。BT HAL的的头文件位于hardware/libhardware/include/hardware/bluetooth.h和hardware/libhardware/include/hardware/bt_*.h 文件中。
  JNI中sBluetoothA2dpInterface是一个btav_interface_t结构体,位于hardware/libhardware/include/hardware/bt_av.h中,定义为:
 
  typedef struct {
  size_t          size;
  bt_status_t (*init)( btav_callbacks_t* callbacks );
  bt_status_t (*connect)( bt_bdaddr_t *bd_addr );
  bt_status_t (*disconnect)( bt_bdaddr_t *bd_addr );
  void  (*cleanup)( void );
  } btav_interface_t;
 
  五、BT stack
 
  作为默认的BT stack,(4.2之前是bluez作为协议栈的)
 
  代码位于external/bluetooth/bluedroid下,这个stack实现了通用的BT HAL并且也可以通过扩展和改变配置来自定义。
 
  A2dp的连接会调用到external/bluetooth/bluedroid/btif/src/btif_av.c的connect方法。
 
  static bt_status_t connect(bt_bdaddr_t *bd_addr)
  {
  BTIF_TRACE_EVENT1("%s", __FUNCTION__);
  CHECK_BTAV_INIT();
  return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int);
  }
 
  六、Vendor extension
 
  为了追踪添加自定义拓展和一个HCI层,你可以创建一个libbt-vendor模块并且指定这些组件。
 

相关文章

相关推荐

最新攻略

用户评论

(已有0条评论)
表情
注:您的评论需要经过审核才能显示哦,请文明发言!
还没有评论,快来抢沙发吧!