A2dp sink的初始化流程和A2dp 的初始化流程,基本一样,这里做简单分析.这里分析的android的版本是Android O.

我们先从service的启动说起吧.

下面 是启动的时候的log:

  1. D/BluetoothAdapterService( ): setProfileServiceState() - Starting service com.android.bluetooth.a2dpsink.A2dpSinkService
  1. - ::22.042 D/A2dpSinkService( ): Received start request. Starting profile...
  2. - ::22.045 D/A2dpSinkService( ): start()
  3. - ::22.054 I/BluetoothA2dpSinkServiceJni( ): classInitNative: succeeds

我们看看 A2dpSinkService.java的start函数的实现:

  1. protected boolean start() {
  2. if (DBG) {
  3. Log.d(TAG, "start()");
  4. }
  5. // Start the media browser service.
  6. Intent startIntent = new Intent(this, A2dpMediaBrowserService.class);
  7. startService(startIntent);//启动service
  8. mStateMachine = A2dpSinkStateMachine.make(this, this);//启动状态机
  9. setA2dpSinkService(this);//设置sA2dpSinkService = this
  10. return true;
  11. }

这里比较重要的地方就是 sink 状态机的启动,我们进一步看看:

  1. static A2dpSinkStateMachine make(A2dpSinkService svc, Context context) {
  2. Log.d("A2dpSinkStateMachine", "make");
  3. A2dpSinkStateMachine a2dpSm = new A2dpSinkStateMachine(svc, context);//新建状态机
  4. a2dpSm.start();
  5. return a2dpSm;
  6. }

我们看看这个类的构造函数实现:

  1. static {
  2. classInitNative();
  3. }
  1. private A2dpSinkStateMachine(A2dpSinkService svc, Context context) {
  2. super("A2dpSinkStateMachine");
  3. mService = svc;
  4. mContext = context;
  5. mAdapter = BluetoothAdapter.getDefaultAdapter();
  6.  
  7. initNative();//初始化
  8.  
  9. mDisconnected = new Disconnected();
  10. mPending = new Pending();
  11. mConnected = new Connected();
  12.  
  13. addState(mDisconnected);
  14. addState(mPending);
  15. addState(mConnected);
  16.  
  17. setInitialState(mDisconnected);
  18.  
  19. PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
  20.  
  21. mIntentBroadcastHandler = new IntentBroadcastHandler();
  22. }

上面  主要做了初始化,然后 新建三个状态,然后设置初始状态.这里主要分析一下初始化相关的流程: classInitNative()和initNative()

我们先看前者:

  1. private native static void classInitNative();

这是本地实现的函数,在com_android_bluetooth_a2dp_sink.cpp中:

  1. static void classInitNative(JNIEnv* env, jclass clazz) {
  2. method_onConnectionStateChanged =
  3. env->GetMethodID(clazz, "onConnectionStateChanged", "(I[B)V");
  4.  
  5. method_onAudioStateChanged =
  6. env->GetMethodID(clazz, "onAudioStateChanged", "(I[B)V");
  7.  
  8. method_onAudioConfigChanged =
  9. env->GetMethodID(clazz, "onAudioConfigChanged", "([BII)V");
  10.  
  11. ALOGI("%s: succeeds", __func__);
  12. }

主要就是 从上层 索取了一些函数调用的"句柄",我们继续看initNative:

  1. static void initNative(JNIEnv* env, jobject object) {
  2. const bt_interface_t* btInf = getBluetoothInterface();
  3. if (btInf == NULL) {
  4. ALOGE("Bluetooth module is not loaded");
  5. return;
  6. }
  7.  
  8. if (sBluetoothA2dpInterface != NULL) {
  9. ALOGW("Cleaning up A2DP Interface before initializing...");
  10. sBluetoothA2dpInterface->cleanup();
  11. sBluetoothA2dpInterface = NULL;
  12. }
  13.  
  14. if (mCallbacksObj != NULL) {
  15. ALOGW("Cleaning up A2DP callback object");
  16. env->DeleteGlobalRef(mCallbacksObj);
  17. mCallbacksObj = NULL;
  18. }
  19.  
  20. sBluetoothA2dpInterface =
  21. (btav_sink_interface_t*)btInf->get_profile_interface(
  22. BT_PROFILE_ADVANCED_AUDIO_SINK_ID);
  23. if (sBluetoothA2dpInterface == NULL) {
  24. ALOGE("Failed to get Bluetooth A2DP Sink Interface");
  25. return;
  26. }
  27.  
  28. bt_status_t status = sBluetoothA2dpInterface->init(&sBluetoothA2dpCallbacks);
  29. if (status != BT_STATUS_SUCCESS) {
  30. ALOGE("Failed to initialize Bluetooth A2DP Sink, status: %d", status);
  31. sBluetoothA2dpInterface = NULL;
  32. return;
  33. }
  34.  
  35. mCallbacksObj = env->NewGlobalRef(object);
  36. }

上面的逻辑 就是先获取蓝牙的接口,再获取sink 的接口,然后对sink 接口进行初始化.我们主要看初始化的过程:

实现是在btif_av.cc中:

  1. static const btav_sink_interface_t bt_av_sink_interface = {
  2. sizeof(btav_sink_interface_t),
  3. init_sink,
  4. sink_connect_src,
  5. disconnect,
  6. cleanup_sink,
  7. update_audio_focus_state,
  8. update_audio_track_gain,
  9. }

这里的init 对应的接口就是init_sink,我们继续看:

  1. /*******************************************************************************
  2. *
  3. * Function init_sink
  4. *
  5. * Description Initializes the AV interface for sink mode
  6. *
  7. * Returns bt_status_t
  8. *
  9. ******************************************************************************/
  10.  
  11. static bt_status_t init_sink(btav_sink_callbacks_t* callbacks) {
  12. BTIF_TRACE_EVENT("%s()", __func__);
  13.  
  14. bt_status_t status = btif_av_init(BTA_A2DP_SINK_SERVICE_ID);
  15. if (status == BT_STATUS_SUCCESS) bt_av_sink_callbacks = callbacks;
  16.  
  17. return status;
  18. }

这里的核心是btif_av_init,这里和之前src的初始化很相似,由于Android版本的演化,这里的btif_av_init 接口已经有了参数,:

  1. /*******************************************************************************
  2. *
  3. * Function btif_av_init
  4. *
  5. * Description Initializes btif AV if not already done
  6. *
  7. * Returns bt_status_t
  8. *
  9. ******************************************************************************/
  10.  
  11. bt_status_t btif_av_init(int service_id) {
  12. if (btif_av_cb.sm_handle == NULL) {
  13. alarm_free(av_open_on_rc_timer);
  14. av_open_on_rc_timer = alarm_new("btif_av.av_open_on_rc_timer");
  15.  
  16. switch (service_id) {
  17. case BTA_A2DP_SOURCE_SERVICE_ID:
  18. if (!btif_a2dp_source_startup())
  19. return BT_STATUS_FAIL; // Already running
  20. break;
  21. case BTA_A2DP_SINK_SERVICE_ID:
  22. if (!btif_a2dp_sink_startup())
  23. return BT_STATUS_FAIL; // Already running
  24. break;
  25. }
  26.  
  27. /* Also initialize the AV state machine */
  28. btif_av_cb.sm_handle = btif_sm_init(
  29. (const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE);//初始化 av 状态机
  30.  
  31. btif_enable_service(service_id);//enable 某个service
  32.  
  33. }
  34.  
  35. return BT_STATUS_SUCCESS;
  36. }

从上面的代码结构可以看出,此接口是sink 和src 共享的.

上面的代码的执行任务分为3个部分:

  1. btif—a2dp-sink的线程启动btif_sm_init
  2. btif_sm_init
  3. btif_enable_service(sink)

我们发现根据传入的参数不同,如果是src,那么执行btif_a2dp_source_startup,如果是sink 执行:btif_a2dp_sink_startup,看了下两者的实现也是大致相同,都是先设置相应的状态,然后新建线程,然后绑定线程队列,然后调用thread_post 去执行 剩下的流程:

  1. bool btif_a2dp_sink_startup(void) {
  2. if (btif_a2dp_sink_state != BTIF_A2DP_SINK_STATE_OFF) {
  3. APPL_TRACE_ERROR("%s: A2DP Sink media task already running", __func__);//先判断状态机的状态
  4. return false;
  5. }
  6.  
  7. memset(&btif_a2dp_sink_cb, , sizeof(btif_a2dp_sink_cb));
  8. btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_STARTING_UP;//设置状态机
  9.  
  10. APPL_TRACE_EVENT("## A2DP SINK START MEDIA THREAD ##");
  11.  
  12. /* Start A2DP Sink media task */
  13. btif_a2dp_sink_cb.worker_thread = thread_new("btif_a2dp_sink_worker_thread");
  14. ...
  15.  
  16. btif_a2dp_sink_cb.rx_focus_state = BTIF_A2DP_SINK_FOCUS_NOT_GRANTED;
  17. btif_a2dp_sink_cb.audio_track = NULL;
  18. btif_a2dp_sink_cb.rx_audio_queue = fixed_queue_new(SIZE_MAX);//新建audio 队列
  19.  
  20. btif_a2dp_sink_cb.cmd_msg_queue = fixed_queue_new(SIZE_MAX);//新建cmd msg队列
  21. fixed_queue_register_dequeue(
  22. btif_a2dp_sink_cb.cmd_msg_queue,
  23. thread_get_reactor(btif_a2dp_sink_cb.worker_thread),
  24. btif_a2dp_sink_command_ready, NULL);绑定命令队列以及命令处理函数
  25.  
  26. APPL_TRACE_EVENT("## A2DP SINK MEDIA THREAD STARTED ##");
  27.  
  28. /* Schedule the rest of the startup operations */
  29. thread_post(btif_a2dp_sink_cb.worker_thread, btif_a2dp_sink_startup_delayed,
  30. NULL);//接下来的流程放置到btif_a2dp_sink_worker_thread的work_queue里面去
  31.  
  32. return true;
  33. }

我们看看 btif_a2dp_sink_startup_delayed  的实现:

  1. static void btif_a2dp_sink_startup_delayed(UNUSED_ATTR void* context) {
  2. raise_priority_a2dp(TASK_HIGH_MEDIA);
  3. btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_RUNNING;//更新sink的状态
  4. }

下面我们看看btif_sm_init的实现:

这里是新建了一个状态机,为后续的状态转换作准备:该函数将会传入以下的参数,我们发现是一个个的处理handler

  1. static const btif_sm_handler_t btif_av_state_handlers[] = {
  2. btif_av_state_idle_handler, btif_av_state_opening_handler,
  3. btif_av_state_opened_handler, btif_av_state_started_handler,
  4. btif_av_state_closing_handler};
  1. /*****************************************************************************
  2. *
  3. * Function btif_sm_init
  4. *
  5. * Description Initializes the state machine with the state handlers
  6. * The caller should ensure that the table and the corresponding
  7. * states match. The location that 'p_handlers' points to shall
  8. * be available until the btif_sm_shutdown API is invoked.
  9. *
  10. * Returns Returns a pointer to the initialized state machine handle.
  11. *
  12. *****************************************************************************/
  13.  
  14. btif_sm_handle_t btif_sm_init(const btif_sm_handler_t* p_handlers,
  15. btif_sm_state_t initial_state) {
  16.  
  17. btif_sm_cb_t* p_cb = (btif_sm_cb_t*)osi_malloc(sizeof(btif_sm_cb_t));
  18. p_cb->state = initial_state;//设置初始状态
  19. p_cb->p_handlers = (btif_sm_handler_t*)p_handlers;//将这个handler赋值到pcb里面
  20.  
  21. /* Send BTIF_SM_ENTER_EVT to the initial state */
  22. p_cb->p_handlers[initial_state](BTIF_SM_ENTER_EVT, NULL);
  23.  
  24. return (btif_sm_handle_t)p_cb;
  25. }

最后会执行 进如idle 的状态机的流程:这里不作具体分析了

  1. static bool btif_av_state_idle_handler(btif_sm_event_t event, void* p_data) {
  2. BTIF_TRACE_DEBUG("%s event:%s flags %x", __func__,
  3. dump_av_sm_event_name((btif_av_sm_event_t)event),
  4. btif_av_cb.flags);
  5.  
  6. switch (event) {
  7. case BTIF_SM_ENTER_EVT:
  8. /* clear the peer_bda */
  9. memset(&btif_av_cb.peer_bda, , sizeof(bt_bdaddr_t));
  10. btif_av_cb.flags = ;
  11. btif_av_cb.edr = ;
  12. bta_av_co_init(btif_av_cb.codec_priorities);
  13. btif_a2dp_on_idle();
  14. break;

下面我们在看看btif_enable_service 的流程:

  1. /*******************************************************************************
  2. *
  3. * Function btif_enable_service
  4. *
  5. * Description Enables the service 'service_ID' to the service_mask.
  6. * Upon BT enable, BTIF core shall invoke the BTA APIs to
  7. * enable the profiles
  8. *
  9. * Returns bt_status_t
  10. *
  11. ******************************************************************************/
  12. bt_status_t btif_enable_service(tBTA_SERVICE_ID service_id) {
  13. tBTA_SERVICE_ID* p_id = &service_id;
  14.  
  15. /* If BT is enabled, we need to switch to BTIF context and trigger the
  16. * enable for that profile
  17. *
  18. * Otherwise, we just set the flag. On BT_Enable, the DM will trigger
  19. * enable for the profiles that have been enabled */
  20.  
  21. btif_enabled_services |= ( << service_id);//设置标志位
  22.  
  23. BTIF_TRACE_DEBUG("%s: current services:0x%x", __func__,
  24. btif_enabled_services);
  25.  
  26. if (btif_is_enabled()) {
  27. btif_transfer_context(btif_dm_execute_service_request,
  28. BTIF_DM_ENABLE_SERVICE, (char*)p_id,
  29. sizeof(tBTA_SERVICE_ID), NULL);//开启该profile
  30. }
  31.  
  32. return BT_STATUS_SUCCESS;
  33. }

我们需要开始的profile 隐藏在p_id 参数中,那我们也可以看出,这里其他的profile 也应该是走的这个流程.

  1. void btif_dm_execute_service_request(uint16_t event, char* p_param) {
  2. bool b_enable = false;
  3. bt_status_t status;
  4. if (event == BTIF_DM_ENABLE_SERVICE) {
  5. b_enable = true;
  6. }
  7. status =
  8. btif_in_execute_service_request(*((tBTA_SERVICE_ID*)p_param), b_enable);
  9. if (status == BT_STATUS_SUCCESS) {
  10. bt_property_t property;
  11. bt_uuid_t local_uuids[BT_MAX_NUM_UUIDS];//新建内存存放uuid
  12.  
  13. /* Now send the UUID_PROPERTY_CHANGED event to the upper layer */
  14. BTIF_STORAGE_FILL_PROPERTY(&property, BT_PROPERTY_UUIDS,
  15. sizeof(local_uuids), local_uuids);//
  16. btif_storage_get_adapter_property(&property);//fill property value
  17. HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, BT_STATUS_SUCCESS, ,
  18. &property);//上报相关的property
  19. }
  20. return;
  21. }

我们知道当 profile启动完成之后,那么 将通过HAL_CBACK 将已经启动的property 上报到JNI 以及以上.

那么我们现在看看btif_in_execute_service_request的实现:

  1. bt_status_t btif_in_execute_service_request(tBTA_SERVICE_ID service_id,
  2. bool b_enable) {
  3. BTIF_TRACE_DEBUG("%s service_id: %d", __func__, service_id);
  4. /* Check the service_ID and invoke the profile's BT state changed API */
  5. switch (service_id) {
  6. case BTA_HFP_SERVICE_ID:
  7. case BTA_HSP_SERVICE_ID: {
  8. btif_hf_execute_service(b_enable);
  9. } break;
  10. case BTA_A2DP_SOURCE_SERVICE_ID: {
  11. btif_av_execute_service(b_enable);
  12. } break;
  13. case BTA_A2DP_SINK_SERVICE_ID: {
  14. btif_av_sink_execute_service(b_enable);
  15. } break;
  16. ...
  1. /*******************************************************************************
  2. *
  3. * Function btif_av_sink_execute_service
  4. *
  5. * Description Initializes/Shuts down the service
  6. *
  7. * Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
  8. *
  9. ******************************************************************************/
  10. bt_status_t btif_av_sink_execute_service(bool b_enable) {
  11. if (b_enable) {
  12. /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
  13. * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
  14. * be initiated by the app/audioflinger layers */
  15. BTA_AvEnable(BTA_SEC_AUTHENTICATE,
  16. BTA_AV_FEAT_NO_SCO_SSPD | BTA_AV_FEAT_RCCT |
  17. BTA_AV_FEAT_METADATA | BTA_AV_FEAT_VENDOR |
  18. BTA_AV_FEAT_ADV_CTRL | BTA_AV_FEAT_RCTG |
  19. BTA_AV_FEAT_BROWSE,
  20. bte_av_callback);
  21. BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AVK_SERVICE_NAME, ,
  22. bte_av_sink_media_callback, UUID_SERVCLASS_AUDIO_SINK);
  23. } else {
  24. BTA_AvDeregister(btif_av_cb.bta_handle);
  25. BTA_AvDisable();
  26. }
  27. return BT_STATUS_SUCCESS;
  28. }

这里和src的初始化的流程非常的相似,也是分为两个步骤:

  1. BTA_AvEnable(BTA_SEC_AUTHENTICATE,BTA_AV_FEAT_NO_SCO_SSPD | BTA_AV_FEAT_RCCT |BTA_AV_FEAT_METADATA | BTA_AV_FEAT_VENDOR |BTA_AV_FEAT_ADV_CTRL | BTA_AV_FEAT_RCTG |
    BTA_AV_FEAT_BROWSE,bte_av_callback);

  2. BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AVK_SERVICE_NAME, 0,bte_av_sink_media_callback, UUID_SERVCLASS_AUDIO_SINK);

我们先看BTA_AvEnable :

  1. #define BTA_SEC_AUTHENTICATE (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_OUT_AUTHENTICATE) /* Authentication required. */0x12
  1. #define BTM_SEC_IN_AUTHENTICATE 0x0002
  2. #define BTM_SEC_OUT_AUTHENTICATE 0x0010
  1. BTA_AV_FEAT_NO_SCO_SSPD | BTA_AV_FEAT_RCCT | BTA_AV_FEAT_METADATA | BTA_AV_FEAT_VENDOR | BTA_AV_FEAT_ADV_CTRL | BTA_AV_FEAT_RCTG | BTA_AV_FEAT_BROWSE,//0x825B

看看其回调函数:

  1. static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV* p_data) {
  2. btif_transfer_context(btif_av_handle_event, event, (char*)p_data,
  3. sizeof(tBTA_AV), btif_av_event_deep_copy);//基本上是把event 传给状态机
  4. }

现在看看BTA_AvEnable的实现

  1. /*******************************************************************************
  2. *
  3. * Function BTA_AvEnable
  4. *
  5. * Description Enable the advanced audio/video service. When the enable
  6. * operation is complete the callback function will be
  7. * called with a BTA_AV_ENABLE_EVT. This function must
  8. * be called before other function in the AV API are
  9. * called.
  10. *
  11. * Returns void
  12. *
  13. ******************************************************************************/
  14. void BTA_AvEnable(tBTA_SEC sec_mask, tBTA_AV_FEAT features,
  15. tBTA_AV_CBACK* p_cback) {
  16. tBTA_AV_API_ENABLE* p_buf =
  17. (tBTA_AV_API_ENABLE*)osi_malloc(sizeof(tBTA_AV_API_ENABLE));
  18.  
  19. /* register with BTA system manager */
  20. bta_sys_register(BTA_ID_AV, &bta_av_reg);
  21.  
  22. p_buf->hdr.event = BTA_AV_API_ENABLE_EVT;
  23. p_buf->p_cback = p_cback;//bte_av_callback
  24. p_buf->features = features;//0x825B
  25. p_buf->sec_mask = sec_mask;//0x0012
  26.  
  27. bta_sys_sendmsg(p_buf);
  28. }

发送了BTA_AV_API_ENABLE_EVT  这个事件;

  1. #define BTA_ID_AV 18 /* Advanced audio/video */

这个 event的 主ID 还是BTA_ID_AV,而并不是BTA_ID_AVK

  1. /* register with BTA system manager */
  2. bta_sys_register(BTA_ID_AV, &bta_av_reg);

我们看看

  1. static const tBTA_SYS_REG bta_av_reg = {bta_av_hdl_event, BTA_AvDisable};

也就是0x18开头的event 都是由bta_av_hdl_event  来统一处理:

  1. /*******************************************************************************
  2. *
  3. * Function bta_av_hdl_event
  4. *
  5. * Description Advanced audio/video main event handling function.
  6. *
  7. *
  8. * Returns bool
  9. *
  10. ******************************************************************************/
  11. bool bta_av_hdl_event(BT_HDR* p_msg) {
  12. if (p_msg->event > BTA_AV_LAST_EVT) {
  13. return true; /* to free p_msg */
  14. }
  15. if (p_msg->event >= BTA_AV_FIRST_NSM_EVT) {
  16. APPL_TRACE_VERBOSE("%s: AV nsm event=0x%x(%s)", __func__, p_msg->event,
  17. bta_av_evt_code(p_msg->event));
  18. /* non state machine events */
  19. (*bta_av_nsm_act[p_msg->event - BTA_AV_FIRST_NSM_EVT])(
  20. (tBTA_AV_DATA*)p_msg);
  21. } else if (p_msg->event >= BTA_AV_FIRST_SM_EVT &&
  22. p_msg->event <= BTA_AV_LAST_SM_EVT) {
  23. APPL_TRACE_VERBOSE("%s: AV sm event=0x%x(%s)", __func__, p_msg->event,
  24. bta_av_evt_code(p_msg->event));
  25. /* state machine events */
  26. bta_av_sm_execute(&bta_av_cb, p_msg->event, (tBTA_AV_DATA*)p_msg);
  27. } else {
  28. APPL_TRACE_VERBOSE("handle=0x%x", p_msg->layer_specific);
  29. /* stream state machine events */
  30. bta_av_ssm_execute(bta_av_hndl_to_scb(p_msg->layer_specific), p_msg->event,
  31. (tBTA_AV_DATA*)p_msg);
  32. }
  33. return true;
  34. }

从上面的代码实现,我们发现 其讲event 分为了3类,一类是不在状态机中处理的,一类是在状态机中处理,还有一类是在stream 的状态机中处理的,现在我们将这些event 分类一下:

一以下是所有的event:

  1. enum {
  2. /* these events are handled by the AV main state machine */
  3. BTA_AV_API_DISABLE_EVT = BTA_SYS_EVT_START(BTA_ID_AV),
  4. BTA_AV_API_REMOTE_CMD_EVT,
  5. BTA_AV_API_VENDOR_CMD_EVT,
  6. BTA_AV_API_VENDOR_RSP_EVT,
  7. BTA_AV_API_META_RSP_EVT,
  8. BTA_AV_API_RC_CLOSE_EVT,
  9. BTA_AV_AVRC_OPEN_EVT,
  10. BTA_AV_AVRC_MSG_EVT,
  11. BTA_AV_AVRC_NONE_EVT,
  12.  
  13. /* these events are handled by the AV stream state machine */
  14. BTA_AV_API_OPEN_EVT,
  15. BTA_AV_API_CLOSE_EVT,
  16. BTA_AV_AP_START_EVT, /* the following 2 events must be in the same order as
  17. the *API_*EVT */
  18. BTA_AV_AP_STOP_EVT,
  19. BTA_AV_API_RECONFIG_EVT,
  20. BTA_AV_API_PROTECT_REQ_EVT,
  21. BTA_AV_API_PROTECT_RSP_EVT,
  22. BTA_AV_API_RC_OPEN_EVT,
  23. BTA_AV_SRC_DATA_READY_EVT,
  24. BTA_AV_CI_SETCONFIG_OK_EVT,
  25. BTA_AV_CI_SETCONFIG_FAIL_EVT,
  26. BTA_AV_SDP_DISC_OK_EVT,
  27. BTA_AV_SDP_DISC_FAIL_EVT,
  28. BTA_AV_STR_DISC_OK_EVT,
  29. BTA_AV_STR_DISC_FAIL_EVT,
  30. BTA_AV_STR_GETCAP_OK_EVT,
  31. BTA_AV_STR_GETCAP_FAIL_EVT,
  32. BTA_AV_STR_OPEN_OK_EVT,
  33. BTA_AV_STR_OPEN_FAIL_EVT,
  34. BTA_AV_STR_START_OK_EVT,
  35. BTA_AV_STR_START_FAIL_EVT,
  36. BTA_AV_STR_CLOSE_EVT,
  37. BTA_AV_STR_CONFIG_IND_EVT,
  38. BTA_AV_STR_SECURITY_IND_EVT,
  39. BTA_AV_STR_SECURITY_CFM_EVT,
  40. BTA_AV_STR_WRITE_CFM_EVT,
  41. BTA_AV_STR_SUSPEND_CFM_EVT,
  42. BTA_AV_STR_RECONFIG_CFM_EVT,
  43. BTA_AV_AVRC_TIMER_EVT,
  44. BTA_AV_AVDT_CONNECT_EVT,
  45. BTA_AV_AVDT_DISCONNECT_EVT,
  46. BTA_AV_ROLE_CHANGE_EVT,
  47. BTA_AV_AVDT_DELAY_RPT_EVT,
  48. BTA_AV_ACP_CONNECT_EVT,
  49. BTA_AV_API_OFFLOAD_START_EVT,
  50. BTA_AV_API_OFFLOAD_START_RSP_EVT,
  51.  
  52. /* these events are handled outside of the state machine */
  53. BTA_AV_API_ENABLE_EVT,
  54. BTA_AV_API_REGISTER_EVT,
  55. BTA_AV_API_DEREGISTER_EVT,
  56. BTA_AV_API_DISCONNECT_EVT,
  57. BTA_AV_CI_SRC_DATA_READY_EVT,
  58. BTA_AV_SIG_CHG_EVT,
  59. BTA_AV_SIGNALLING_TIMER_EVT,
  60. BTA_AV_SDP_AVRC_DISC_EVT,
  61. BTA_AV_AVRC_CLOSE_EVT,
  62. BTA_AV_AVRC_BROWSE_OPEN_EVT,
  63. BTA_AV_AVRC_BROWSE_CLOSE_EVT,
  64. BTA_AV_CONN_CHG_EVT,
  65. BTA_AV_DEREG_COMP_EVT,
  66. #if (AVDT_REPORTING == TRUE)
  67. BTA_AV_AVDT_RPT_CONN_EVT,
  68. #endif
  69. BTA_AV_API_START_EVT, /* the following 2 events must be in the same order as
  70. the *AP_*EVT */
  71. BTA_AV_API_STOP_EVT
  72. }

我们发现,不在状态机中处理的event是:

  1. /* these events are handled outside of the state machine */
  2. BTA_AV_API_ENABLE_EVT,
  3. BTA_AV_API_REGISTER_EVT,
  4. BTA_AV_API_DEREGISTER_EVT,
  5. BTA_AV_API_DISCONNECT_EVT,
  6. BTA_AV_CI_SRC_DATA_READY_EVT,
  7. BTA_AV_SIG_CHG_EVT,
  8. BTA_AV_SIGNALLING_TIMER_EVT,
  9. BTA_AV_SDP_AVRC_DISC_EVT,
  10. BTA_AV_AVRC_CLOSE_EVT,
  11. BTA_AV_AVRC_BROWSE_OPEN_EVT,
  12. BTA_AV_AVRC_BROWSE_CLOSE_EVT,
  13. BTA_AV_CONN_CHG_EVT,
  14. BTA_AV_DEREG_COMP_EVT,
  15. #if (AVDT_REPORTING == TRUE)
  16. BTA_AV_AVDT_RPT_CONN_EVT,
  17. #endif
  18. BTA_AV_API_START_EVT, /* the following 2 events must be in the same order as
  19. the *AP_*EVT */
  20. BTA_AV_API_STOP_EVT

处理他的函数是:bta_av_nsm_act:

  1. /* action functions */
  2. const tBTA_AV_NSM_ACT bta_av_nsm_act[] = {
  3. bta_av_api_enable, /* BTA_AV_API_ENABLE_EVT */
  4. bta_av_api_register, /* BTA_AV_API_REGISTER_EVT */
  5. bta_av_api_deregister, /* BTA_AV_API_DEREGISTER_EVT */
  6. bta_av_api_disconnect, /* BTA_AV_API_DISCONNECT_EVT */
  7. bta_av_ci_data, /* BTA_AV_CI_SRC_DATA_READY_EVT */
  8. bta_av_sig_chg, /* BTA_AV_SIG_CHG_EVT */
  9. bta_av_signalling_timer, /* BTA_AV_SIGNALLING_TIMER_EVT */
  10. bta_av_rc_disc_done, /* BTA_AV_SDP_AVRC_DISC_EVT */
  11. bta_av_rc_closed, /* BTA_AV_AVRC_CLOSE_EVT */
  12. bta_av_rc_browse_opened, /* BTA_AV_AVRC_BROWSE_OPEN_EVT */
  13. bta_av_rc_browse_closed, /* BTA_AV_AVRC_BROWSE_CLOSE_EVT */
  14. bta_av_conn_chg, /* BTA_AV_CONN_CHG_EVT */
  15. bta_av_dereg_comp, /* BTA_AV_DEREG_COMP_EVT */
  16. #if (AVDT_REPORTING == TRUE)
  17. bta_av_rpc_conn, /* BTA_AV_AVDT_RPT_CONN_EVT */
  18. #endif
  19. bta_av_api_to_ssm, /* BTA_AV_API_START_EVT */
  20. bta_av_api_to_ssm, /* BTA_AV_API_STOP_EVT */
  21. }

还有一类事件 是在AV的main 的状态机中处理的:

  1. /* these events are handled by the AV main state machine */
  2. BTA_AV_API_DISABLE_EVT = BTA_SYS_EVT_START(BTA_ID_AV),
  3. BTA_AV_API_REMOTE_CMD_EVT,
  4. BTA_AV_API_VENDOR_CMD_EVT,
  5. BTA_AV_API_VENDOR_RSP_EVT,
  6. BTA_AV_API_META_RSP_EVT,
  7. BTA_AV_API_RC_CLOSE_EVT,
  8. BTA_AV_AVRC_OPEN_EVT,
  9. BTA_AV_AVRC_MSG_EVT,
  10. BTA_AV_AVRC_NONE_EVT,

处理的函数组是:bta_av_sm_execute --->bta_av_action:

  1. /* action functions */
  2. const tBTA_AV_ACTION bta_av_action[] = {
  3. bta_av_disable,
  4. bta_av_rc_opened,
  5. bta_av_rc_remote_cmd,
  6. bta_av_rc_vendor_cmd,
  7. bta_av_rc_vendor_rsp,
  8. bta_av_rc_free_rsp,
  9. bta_av_rc_free_browse_msg,
  10. bta_av_rc_meta_rsp,
  11. bta_av_rc_msg,
  12. bta_av_rc_close,
  13. };

最后一类是  建立 stream之后的event:

  1. /* these events are handled by the AV stream state machine */
  2. BTA_AV_API_OPEN_EVT,
  3. BTA_AV_API_CLOSE_EVT,
  4. BTA_AV_AP_START_EVT, /* the following 2 events must be in the same order as
  5. the *API_*EVT */
  6. BTA_AV_AP_STOP_EVT,
  7. BTA_AV_API_RECONFIG_EVT,
  8. BTA_AV_API_PROTECT_REQ_EVT,
  9. BTA_AV_API_PROTECT_RSP_EVT,
  10. BTA_AV_API_RC_OPEN_EVT,
  11. BTA_AV_SRC_DATA_READY_EVT,
  12. BTA_AV_CI_SETCONFIG_OK_EVT,
  13. BTA_AV_CI_SETCONFIG_FAIL_EVT,
  14. BTA_AV_SDP_DISC_OK_EVT,
  15. BTA_AV_SDP_DISC_FAIL_EVT,
  16. BTA_AV_STR_DISC_OK_EVT,
  17. BTA_AV_STR_DISC_FAIL_EVT,
  18. BTA_AV_STR_GETCAP_OK_EVT,
  19. BTA_AV_STR_GETCAP_FAIL_EVT,
  20. BTA_AV_STR_OPEN_OK_EVT,
  21. BTA_AV_STR_OPEN_FAIL_EVT,
  22. BTA_AV_STR_START_OK_EVT,
  23. BTA_AV_STR_START_FAIL_EVT,
  24. BTA_AV_STR_CLOSE_EVT,
  25. BTA_AV_STR_CONFIG_IND_EVT,
  26. BTA_AV_STR_SECURITY_IND_EVT,
  27. BTA_AV_STR_SECURITY_CFM_EVT,
  28. BTA_AV_STR_WRITE_CFM_EVT,
  29. BTA_AV_STR_SUSPEND_CFM_EVT,
  30. BTA_AV_STR_RECONFIG_CFM_EVT,
  31. BTA_AV_AVRC_TIMER_EVT,
  32. BTA_AV_AVDT_CONNECT_EVT,
  33. BTA_AV_AVDT_DISCONNECT_EVT,
  34. BTA_AV_ROLE_CHANGE_EVT,
  35. BTA_AV_AVDT_DELAY_RPT_EVT,
  36. BTA_AV_ACP_CONNECT_EVT,
  37. BTA_AV_API_OFFLOAD_START_EVT,
  38. BTA_AV_API_OFFLOAD_START_RSP_EVT,

处理的函数是bta_av_ssm_execute ,处理的action 是p_scb->p_act_tbl

我们继续看BTA_AV_API_ENABLE_EVT 的处理,根据上面的分类,处理的函数是bta_av_api_enable:

  1. /*******************************************************************************
  2. *
  3. * Function bta_av_api_enable
  4. *
  5. * Description Handle an API enable event.
  6. *
  7. *
  8. * Returns void
  9. *
  10. ******************************************************************************/
  11. static void bta_av_api_enable(tBTA_AV_DATA* p_data) {
  12. /* initialize control block */
  13. memset(&bta_av_cb, , sizeof(tBTA_AV_CB));
  14.  
  15. for (int i = ; i < BTA_AV_NUM_RCB; i++)
  16. bta_av_cb.rcb[i].handle = BTA_AV_RC_HANDLE_NONE;
  17.  
  18. bta_av_cb.rc_acp_handle = BTA_AV_RC_HANDLE_NONE;
  19.  
  20. /*
  21. * TODO: The "disable" event handling is missing - there we need
  22. * to alarm_free() the alarms below.
  23. */
  24. bta_av_cb.link_signalling_timer = alarm_new("bta_av.link_signalling_timer");//这里只是新建了一个timer ,还没有启动
  25. bta_av_cb.accept_signalling_timer =
  26. alarm_new("bta_av.accept_signalling_timer");
  27.  
  28. /* store parameters */
  29. bta_av_cb.p_cback = p_data->api_enable.p_cback;//bte_av_callback
  30. bta_av_cb.features = p_data->api_enable.features;//0x825B
  31. bta_av_cb.sec_mask = p_data->api_enable.sec_mask;//0x0012
  32.  
  33. tBTA_AV_ENABLE enable;
  34. enable.features = bta_av_cb.features;//0x825B
  35.  
  36. /* Register for SCO change event */
  37. if (!(bta_av_cb.features & BTA_AV_FEAT_NO_SCO_SSPD)) {
  38. bta_sys_sco_register(bta_av_sco_chg_cback);
  39. }
  40.  
  41. /* call callback with enable event */
  42. (*bta_av_cb.p_cback)(BTA_AV_ENABLE_EVT, (tBTA_AV*)&enable);//callback:bte_av_callback
  43. }

这里需要注意的是 上面只是新建了定时器,还么有 启动定时器,我们看看回调函数的实现:

  1. static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV* p_data) {
  2. btif_transfer_context(btif_av_handle_event, event, (char*)p_data,
  3. sizeof(tBTA_AV), btif_av_event_deep_copy);
  4. }
  1. static void btif_av_handle_event(uint16_t event, char* p_param) {
  2. BTIF_TRACE_EVENT("%s event:%s", __func__,
  3. dump_av_sm_event_name((btif_av_sm_event_t)event));
  4. switch (event) {
  5. case BTIF_AV_CLEANUP_REQ_EVT:
  6. btif_a2dp_source_shutdown();
  7. btif_a2dp_sink_shutdown();
  8. break;
  9.  
  10. case BTA_AV_REGISTER_EVT:
  11. if (btif_av_cb.sm_handle == NULL) {
  12. btif_av_cb.bta_handle = ((tBTA_AV*)p_param)->registr.hndl;
  13. BTIF_TRACE_DEBUG("%s: BTA AV Handle updated", __func__);
  14. }
  15. /* FALLTHROUGH */
  16. default:
  17. btif_sm_dispatch(btif_av_cb.sm_handle, event, (void*)p_param);
  18. btif_av_event_free_data(event, p_param);
  19. }
  20. }

上面走到到了 btif_sm_dispatch 里面了:

  1. /*****************************************************************************
  2. *
  3. * Function btif_sm_dispatch
  4. *
  5. * Description Dispatches the 'event' along with 'data' to the current state
  6. * handler
  7. *
  8. * Returns BT_STATUS_SUCCESS on success
  9. * BT_STATUS_UNHANDLED if event was not processed
  10. * BT_STATUS_FAIL otherwise
  11. *
  12. *****************************************************************************/
  13. bt_status_t btif_sm_dispatch(btif_sm_handle_t handle, btif_sm_event_t event,
  14. void* data) {
  15. bt_status_t status = BT_STATUS_SUCCESS;
  16.  
  17. btif_sm_cb_t* p_cb = (btif_sm_cb_t*)handle;
  18.  
  19. if (p_cb == NULL) {
  20. BTIF_TRACE_ERROR("%s : Invalid handle", __func__);
  21. return BT_STATUS_FAIL;
  22. }
  23.  
  24. if (p_cb->p_handlers[p_cb->state](event, data) == false)
  25. return BT_STATUS_UNHANDLED;
  26.  
  27. return status;
  28. }

这里的state  还是idle 状态, 这里发现 对于这个BTA_AV_ENABLE_EVT 并么有处理,这里就不分析。(和src的分析的流程基本一致)

下面继续看看BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AVK_SERVICE_NAME, 0,bte_av_sink_media_callback, UUID_SERVCLASS_AUDIO_SINK);的实现:

这里和之前的src的分析不同点在于(Android版本不同)这里的参数个数多了一个,这里会传入了一个参数,标志是src还是sink 进行的注册。

  1. /*******************************************************************************
  2. *
  3. * Function BTA_AvRegister
  4. *
  5. * Description Register the audio or video service to stack. When the
  6. * operation is complete the callback function will be
  7. * called with a BTA_AV_REGISTER_EVT. This function must
  8. * be called before AVDT stream is open.
  9. *
  10. *
  11. * Returns void
  12. *
  13. ******************************************************************************/
  14. void BTA_AvRegister(tBTA_AV_CHNL chnl, const char* p_service_name,
  15. uint8_t app_id, tBTA_AV_SINK_DATA_CBACK* p_sink_data_cback,
  16. uint16_t service_uuid) {
  17. tBTA_AV_API_REG* p_buf =
  18. (tBTA_AV_API_REG*)osi_malloc(sizeof(tBTA_AV_API_REG));
  19.  
  20. p_buf->hdr.layer_specific = chnl;//BTA_AV_CHNL_AUDIO = 0x40
  21. p_buf->hdr.event = BTA_AV_API_REGISTER_EVT;
  22. if (p_service_name)
  23. strlcpy(p_buf->p_service_name, p_service_name, BTA_SERVICE_NAME_LEN);
  24. else
  25. p_buf->p_service_name[] = ;
  26. p_buf->app_id = app_id;//
  27. p_buf->p_app_sink_data_cback = p_sink_data_cback;//bte_av_sink_media_callback
  28. p_buf->service_uuid = service_uuid;//UUID_SERVCLASS_AUDIO_SINK = 0x110B
  29.  
  30. bta_sys_sendmsg(p_buf);
  31. }

我们继续看这个event 的处理,我们发现bta_av_api_register 这个函数也是 sink 和src 共用的,这也是和Android6.0的实现不同的地方。

其实可以仿照AndroidO的代码去修改AndroidM的代码,以此将sink 和src 分开。

  1. /*******************************************************************************
  2. *
  3. * Function bta_av_api_register
  4. *
  5. * Description allocate stream control block,
  6. * register the service to stack
  7. * create SDP record
  8. *
  9. * Returns void
  10. *
  11. ******************************************************************************/
  12. static void bta_av_api_register(tBTA_AV_DATA* p_data) {
  13. tBTA_AV_REGISTER registr;
  14. tBTA_AV_SCB* p_scb; /* stream control block */
  15. tAVDT_REG reg;
  16. tAVDT_CS cs;
  17. char* p_service_name;
  18. tBTA_UTL_COD cod;
  19.  
  20. memset(&cs, , sizeof(tAVDT_CS));//初始化cs,该项最终拷贝到p_scb->cfg,并且AVDT_CreateStream 会使用到
  21.  
  22. registr.status = BTA_AV_FAIL_RESOURCES;//register 记录注册的信息,回调的时候会上报
  23. registr.app_id = p_data->api_reg.app_id;//
  24. registr.chnl = (tBTA_AV_CHNL)p_data->hdr.layer_specific;//layer_specific = 0x40
  25.  
  26. uint16_t profile_initialized = p_data->api_reg.service_uuid;//sink
  27. if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK) {
  28. p_bta_av_cfg = (tBTA_AV_CFG*)&bta_avk_cfg;
  29. } else if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE) {
  30. p_bta_av_cfg = (tBTA_AV_CFG*)&bta_av_cfg;
  31. }
  32.  
  33. do {
  34. p_scb = bta_av_alloc_scb(registr.chnl);//分配了一个 stream control block :bta_av_cb.p_scb[xx] = p_scb
  35.  
  36. registr.hndl = p_scb->hndl;//0x41 or 0x42 --- hndl = (tBTA_AV_HNDL)((xx + 1) | chnl);
  37. p_scb->app_id = registr.app_id;
  38.  
  39. /* initialize the stream control block */
  40. registr.status = BTA_AV_SUCCESS;
  41.  
  42. if ((bta_av_cb.reg_audio + bta_av_cb.reg_video) == ) {
  43. /* the first channel registered. register to AVDTP */
  44. reg.ctrl_mtu = p_bta_av_cfg->sig_mtu;
  45. reg.ret_tout = BTA_AV_RET_TOUT;
  46. reg.sig_tout = BTA_AV_SIG_TOUT;
  47. reg.idle_tout = BTA_AV_IDLE_TOUT;
  48. reg.sec_mask = bta_av_cb.sec_mask;
  49.  
  50. bta_ar_reg_avdt(&reg, bta_av_conn_cback, BTA_ID_AV);//注册到AVDT
  51.  
  52. bta_sys_role_chg_register(&bta_av_sys_rs_cback);
  53.  
  54. /* create remote control TG service if required */
  55. if (bta_av_cb.features & (BTA_AV_FEAT_RCTG)) {
  56. /* register with no authorization; let AVDTP use authorization instead */
  57. bta_ar_reg_avct(p_bta_av_cfg->avrc_mtu, p_bta_av_cfg->avrc_br_mtu,
  58. (uint8_t)(bta_av_cb.sec_mask & (~BTA_SEC_AUTHORIZE)),
  59. BTA_ID_AV);
  60.  
  61. /* For the Audio Sink role we support additional TG 1.3 to support
  62. * absolute volume.
  63. */
  64. uint16_t profile_version = AVRC_REV_1_0;
  65.  
  66. if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE) {
  67. ...
  68. } else if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK) {
  69. // Initialize AVRCP1.4 to provide Absolute Volume control.
  70. profile_version = AVRC_REV_1_4;
  71. }
  72.  
  73. bta_ar_reg_avrc(
  74. UUID_SERVCLASS_AV_REM_CTRL_TARGET, "AV Remote Control Target", NULL,
  75. p_bta_av_cfg->avrc_tg_cat, BTA_ID_AV,
  76. (bta_av_cb.features & BTA_AV_FEAT_BROWSE), profile_version);
  77. #endif
  78. }
  79.  
  80. /* Set the Capturing service class bit */
  81. if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE)
  82. cod.service = BTM_COD_SERVICE_CAPTURING;
  83. else if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK)
  84. cod.service = BTM_COD_SERVICE_RENDERING;
  85. utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
  86. } /* if 1st channel */
  87.  
  88. /* get stream configuration and create stream */
  89. cs.cfg.num_codec = ;
  90. cs.nsc_mask =
  91. AVDT_NSC_RECONFIG |
  92. ((bta_av_cb.features & BTA_AV_FEAT_PROTECT) ? : AVDT_NSC_SECURITY);
  93. APPL_TRACE_DEBUG("nsc_mask: 0x%x", cs.nsc_mask);
  94.  
  95. if (p_data->api_reg.p_service_name[] == ) {
  96. p_service_name = NULL;
  97. } else {
  98. p_service_name = p_data->api_reg.p_service_name;//用于后面创建SDP record
  99. }
  100.  
  101. p_scb->suspend_sup = true;
  102. p_scb->recfg_sup = true;
  103. p_scb->skip_sdp = false;
  104.  
  105. cs.p_ctrl_cback = bta_av_dt_cback[p_scb->hdi];
  106. if (registr.chnl == BTA_AV_CHNL_AUDIO) {//填充p_scb
  107. /* set up the audio stream control block */
  108. p_scb->p_act_tbl = (const tBTA_AV_ACT*)bta_av_a2dp_action;
  109. p_scb->p_cos = &bta_av_a2dp_cos;
  110. p_scb->media_type = AVDT_MEDIA_TYPE_AUDIO;
  111. cs.cfg.psc_mask = AVDT_PSC_TRANS;
  112. cs.media_type = AVDT_MEDIA_TYPE_AUDIO;
  113. cs.mtu = p_bta_av_cfg->audio_mtu;
  114. cs.flush_to = L2CAP_DEFAULT_FLUSH_TO;
  115. btav_a2dp_codec_index_t codec_index_min =
  116. BTAV_A2DP_CODEC_INDEX_SOURCE_MIN;
  117. btav_a2dp_codec_index_t codec_index_max =
  118. BTAV_A2DP_CODEC_INDEX_SOURCE_MAX;
  119.  
  120. if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE) {
  121. ...
  122. } else if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK) {
  123. cs.tsep = AVDT_TSEP_SNK;
  124. cs.p_sink_data_cback = bta_av_sink_data_cback;
  125. codec_index_min = BTAV_A2DP_CODEC_INDEX_SINK_MIN;
  126. codec_index_max = BTAV_A2DP_CODEC_INDEX_SINK_MAX;
  127. }
  128.  
  129. /* Initialize handles to zero */
  130. for (int xx = ; xx < BTAV_A2DP_CODEC_INDEX_MAX; xx++) {
  131. p_scb->seps[xx].av_handle = ;
  132. }
  133.  
  134. /* keep the configuration in the stream control block */
  135. memcpy(&p_scb->cfg, &cs.cfg, sizeof(tAVDT_CFG));
  136. for (int i = codec_index_min; i < codec_index_max; i++) {
  137. btav_a2dp_codec_index_t codec_index =
  138. static_cast<btav_a2dp_codec_index_t>(i);
  139. if (!(*bta_av_a2dp_cos.init)(codec_index, &cs.cfg)) {
  140. continue;
  141. }
  142. if (AVDT_CreateStream(&p_scb->seps[codec_index].av_handle, &cs) !=
  143. AVDT_SUCCESS) {
  144. continue;
  145. }
  146. /* Save a copy of the codec */
  147. memcpy(p_scb->seps[codec_index].codec_info, cs.cfg.codec_info,
  148. AVDT_CODEC_SIZE);
  149. p_scb->seps[codec_index].tsep = cs.tsep;
  150. if (cs.tsep == AVDT_TSEP_SNK) {
  151. p_scb->seps[codec_index].p_app_sink_data_cback =
  152. p_data->api_reg.p_app_sink_data_cback;
  153. } else {
  154. /* In case of A2DP SOURCE we don't need a callback to
  155. * handle media packets.
  156. */
  157. p_scb->seps[codec_index].p_app_sink_data_cback = NULL;
  158. }
  159. }
  160.  
  161. if (!bta_av_cb.reg_audio) {
  162. bta_av_cb.sdp_a2dp_handle = ;
  163. bta_av_cb.sdp_a2dp_snk_handle = ;
  164. if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE) {
  165. ...
  166. } else if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK) {
  167. #if (BTA_AV_SINK_INCLUDED == TRUE)
  168. bta_av_cb.sdp_a2dp_snk_handle = SDP_CreateRecord();
  169. A2DP_AddRecord(UUID_SERVCLASS_AUDIO_SINK, p_service_name, NULL,
  170. A2DP_SUPF_PLAYER, bta_av_cb.sdp_a2dp_snk_handle);
  171. bta_sys_add_uuid(UUID_SERVCLASS_AUDIO_SINK);
  172. #endif
  173. }
  174. /* start listening when A2DP is registered */
  175. if (bta_av_cb.features & BTA_AV_FEAT_RCTG)
  176. bta_av_rc_create(&bta_av_cb, AVCT_ACP, , BTA_AV_NUM_LINKS + );
  177.  
  178. /* if the AV and AVK are both supported, it cannot support the CT role
  179. */
  180. if (bta_av_cb.features & (BTA_AV_FEAT_RCCT)) {
  181.  
  182. /* create an SDP record as AVRC CT. We create 1.3 for SOURCE
  183. * because we rely on feature bits being scanned by external
  184. * devices more than the profile version itself.
  185. *
  186. * We create 1.4 for SINK since we support browsing.
  187. */
  188. if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE) {
  189. ...
  190. } else if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK) {
  191. bta_ar_reg_avrc(UUID_SERVCLASS_AV_REMOTE_CONTROL, NULL, NULL,
  192. p_bta_av_cfg->avrc_ct_cat, BTA_ID_AV,
  193. (bta_av_cb.features & BTA_AV_FEAT_BROWSE),
  194. AVRC_REV_1_6);
  195. }
  196.  
  197. }
  198. }
  199. bta_av_cb.reg_audio |= BTA_AV_HNDL_TO_MSK(p_scb->hdi);
  200. APPL_TRACE_DEBUG("reg_audio: 0x%x", bta_av_cb.reg_audio);
  201. }
  202. } while ();
  203.  
  204. /* call callback with register event */
  205. (*bta_av_cb.p_cback)(BTA_AV_REGISTER_EVT, (tBTA_AV*)&registr);
  206. }

上面注册的内容和 a2dp 初始化的流程基本相同,不作具体分析。

关于a2dp sink的初始化的流程,就分析到这里了。

A2dp sink 初始化流程源码分析的更多相关文章

  1. A2dp初始化流程源码分析

    蓝牙启动的时候,会涉及到各个profile 的启动.这篇文章分析一下,蓝牙中a2dp profile的初始化流程. 我们从AdapterState.java中对于USER_TURN_ON 消息的处理说 ...

  2. [Android]从Launcher开始启动App流程源码分析

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5017056.html 从Launcher开始启动App流程源码 ...

  3. [Android]Android系统启动流程源码分析

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5013863.html Android系统启动流程源码分析 首先 ...

  4. Spring加载流程源码分析03【refresh】

      前面两篇文章分析了super(this)和setConfigLocations(configLocations)的源代码,本文来分析下refresh的源码, Spring加载流程源码分析01[su ...

  5. Android笔记--View绘制流程源码分析(二)

    Android笔记--View绘制流程源码分析二 通过上一篇View绘制流程源码分析一可以知晓整个绘制流程之前,在activity启动过程中: Window的建立(activit.attach生成), ...

  6. Android笔记--View绘制流程源码分析(一)

    Android笔记--View绘制流程源码分析 View绘制之前框架流程分析 View绘制的分析始终是离不开Activity及其内部的Window的.在Activity的源码启动流程中,一并包含 着A ...

  7. Spark(五十一):Spark On YARN(Yarn-Cluster模式)启动流程源码分析(二)

    上篇<Spark(四十九):Spark On YARN启动流程源码分析(一)>我们讲到启动SparkContext初始化,ApplicationMaster启动资源中,讲解的内容明显不完整 ...

  8. Spark(四十九):Spark On YARN启动流程源码分析(一)

    引导: 该篇章主要讲解执行spark-submit.sh提交到将任务提交给Yarn阶段代码分析. spark-submit的入口函数 一般提交一个spark作业的方式采用spark-submit来提交 ...

  9. spring boot 加载web容器tomcat流程源码分析

    spring boot 加载web容器tomcat流程源码分析 我本地的springboot版本是2.5.1,后面的分析都是基于这个版本 <parent> <groupId>o ...

随机推荐

  1. Wu反走样算法绘制圆(C++/MFC实现)

    Wu反走样圆 原理:参考Bresenham算法,在主位移过程中计算出离理想圆最近的两个点,赋予不同的亮度值,绘制像素点即可! MFC 中CXXXView类中添加函数: //Wu算法画反走样圆 void ...

  2. html之css选择器学习

    相关内容: 什么是css选择器 标签选择器 类选择器 id选择器 并集选择器(分组选择器) 交集选择器 后代选择器 子标签选择器 属性选择器 相邻兄弟选择器 伪类选择器 伪元素选择器(伪对象选择器) ...

  3. Apache httpd.conf配置文件主要内容解释

    1 ServerRoot 配置 ["ServerRoot" 主要用于指定Apache的安装路径,此选项参数值在安装Apache时系统会自动把Apache的路径写入.Windows安 ...

  4. [20190225]删除tab$记录的恢复5.txt

    [20190225]删除tab$记录的恢复5.txt --//昨天下午看了链接https://blog.csdn.net/Enmotech/article/details/87834503,大概知道对 ...

  5. Elasticsearch深入搜索之结构化搜索及JavaAPI的使用

    一.Es中创建索引 1.创建索引: 在之前的Es插件的安装和使用中说到创建索引自定义分词器和创建type,当时是分开写的,其实创建索引时也可以创建type,并指定分词器. PUT /my_index ...

  6. 如何让PHP程序自动执行(后台)

    如何让php程序自动执行,这个就需要用到一个函数了: int ignore_user_abort ( [bool setting] )  定义和用法 ignore_user_abort() 函数设置与 ...

  7. LeetCode算法题-Path Sum III(Java实现)

    这是悦乐书的第227次更新 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第94题(顺位题号是437).您将获得一个二叉树,其中每个节点都包含一个整数值.找到与给定值相加的路径数 ...

  8. CISCO 过载NAT配置(小型网络)

    一.实验涉及技术  vlan(虚拟局域网). svi(三层交换) .nat(网络地址转换).static router(静态路由) 三.实验目的: 通过配置过载NAT从而实现企业内网正常访问公网,PC ...

  9. Caused by: java.io.FileNotFoundException: velocity.log (No such file or directory)

    Caused by: org.apache.velocity.exception.VelocityException: Error initializing log: Failed to initia ...

  10. Java面试知识点之设计模式(一)

    前言:关于设计模式,在框架中用的比较多.在平常接触最为频繁的估计是单例模式了,因此笔者在此对设计模式相关知识点进行总结. 1.设计模式的种类 总体来说,设计模式分为3大类总共23种: 1)创建型模式, ...