/******************************************************************************* ** ** Function bta_hf_client_register ** ** Description This function initializes values of the scb and sets up ** the SDP record for the services. ** ** ** Returns void ** *******************************************************************************/ void bta_hf_client_register(tBTA_HF_CLIENT_DATA *p_data) { tBTA_HF_CLIENT evt; tBTA_UTL_COD cod; memset(&evt, 0, sizeof(evt)); /* initialize control block */ bta_hf_client_scb_init(); bta_hf_client_cb.scb.serv_sec_mask = p_data->api_register.sec_mask; bta_hf_client_cb.scb.features = p_data->api_register.features; /* initialize AT control block */ bta_hf_client_at_init(); /* create SDP records */ bta_hf_client_create_record(p_data); /* Set the Audio service class bit */ cod.service = BTM_COD_SERVICE_AUDIO; utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS); /* start RFCOMM server */ bta_hf_client_start_server(); /* call app callback with register event */ evt.reg.status = BTA_HF_CLIENT_SUCCESS; (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_REGISTER_EVT, &evt); }
/******************************************************************************* ** ** Function bta_av_api_register ** ** Description allocate stream control block, ** register the service to stack ** create SDP record ** ** Returns void ** *******************************************************************************/ static void bta_av_api_register(tBTA_AV_DATA *p_data) { tBTA_AV_REGISTER registr; tBTA_AV_SCB *p_scb; /* stream control block */ tAVDT_REG reg; tAVDT_CS cs; char *p_service_name; tBTA_AV_CODEC codec_type; tBTA_UTL_COD cod; UINT8 index = 0; memset(&cs,0,sizeof(tAVDT_CS)); registr.status = BTA_AV_FAIL_RESOURCES; registr.app_id = p_data->api_reg.app_id; registr.chnl = (tBTA_AV_CHNL)p_data->hdr.layer_specific; do { p_scb = bta_av_alloc_scb(registr.chnl); if(p_scb == NULL) { APPL_TRACE_ERROR0("failed to alloc SCB"); break; } registr.hndl = p_scb->hndl; p_scb->app_id = registr.app_id; /* initialize the stream control block */ p_scb->timer.p_cback = (TIMER_CBACK*)&bta_av_timer_cback; registr.status = BTA_AV_SUCCESS; if((bta_av_cb.reg_audio + bta_av_cb.reg_video) == 0) { /* the first channel registered. register to AVDTP */ reg.ctrl_mtu = p_bta_av_cfg->sig_mtu; reg.ret_tout = BTA_AV_RET_TOUT; reg.sig_tout = BTA_AV_SIG_TOUT; reg.idle_tout = BTA_AV_IDLE_TOUT; reg.sec_mask = bta_av_cb.sec_mask; #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE) bta_ar_reg_avdt(®, bta_av_conn_cback, BTA_ID_AV); #endif bta_sys_role_chg_register(&bta_av_sys_rs_cback); /* create remote control TG service if required */ if (bta_av_cb.features & (BTA_AV_FEAT_RCTG)) { /* register with no authorization; let AVDTP use authorization instead */ #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE) #if (BTA_AV_WITH_AVCTP_AUTHORIZATION == TRUE) bta_ar_reg_avct(p_bta_av_cfg->avrc_mtu, p_bta_av_cfg->avrc_br_mtu, bta_av_cb.sec_mask, BTA_ID_AV); #else bta_ar_reg_avct(p_bta_av_cfg->avrc_mtu, p_bta_av_cfg->avrc_br_mtu, (UINT8)(bta_av_cb.sec_mask & (~BTA_SEC_AUTHORIZE)), BTA_ID_AV); #endif bta_ar_reg_avrc(UUID_SERVCLASS_AV_REM_CTRL_TARGET, "AV Remote Control Target", NULL, p_bta_av_cfg->avrc_tg_cat, BTA_ID_AV); #endif } /* Set the Capturing service class bit */ cod.service = BTM_COD_SERVICE_CAPTURING; utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS); } /* if 1st channel */ /* get stream configuration and create stream */ /* memset(&cs.cfg,0,sizeof(tAVDT_CFG)); */ cs.cfg.num_codec = 1; #ifdef A2DP_SINK cs.tsep = AVDT_TSEP_SNK; #else cs.tsep = AVDT_TSEP_SRC; #endif /* * memset of cs takes care setting call back pointers to null. cs.p_data_cback = NULL; cs.p_report_cback = NULL; */ #ifdef A2DP_SINK cs.p_data_cback = bta_av_a2dp_data_cback; #endif cs.nsc_mask = AVDT_NSC_RECONFIG | ((bta_av_cb.features & BTA_AV_FEAT_PROTECT) ? 0 : AVDT_NSC_SECURITY); APPL_TRACE_DEBUG1("nsc_mask: 0x%x", cs.nsc_mask); if (p_data->api_reg.p_service_name[0] == 0) { p_service_name = NULL; } else { p_service_name = p_data->api_reg.p_service_name; } p_scb->suspend_sup = TRUE; p_scb->recfg_sup = TRUE; cs.p_ctrl_cback = bta_av_dt_cback[p_scb->hdi]; if(registr.chnl == BTA_AV_CHNL_AUDIO) { /* set up the audio stream control block */ p_scb->p_act_tbl = (const tBTA_AV_ACT *)bta_av_a2d_action; p_scb->p_cos = &bta_av_a2d_cos; p_scb->media_type= AVDT_MEDIA_AUDIO; cs.cfg.psc_mask = AVDT_PSC_TRANS; cs.media_type = AVDT_MEDIA_AUDIO; cs.mtu = p_bta_av_cfg->audio_mtu; cs.flush_to = L2CAP_DEFAULT_FLUSH_TO; #if AVDT_REPORTING == TRUE if(bta_av_cb.features & BTA_AV_FEAT_REPORT) { cs.cfg.psc_mask |= AVDT_PSC_REPORT; cs.p_report_cback = bta_av_a2dp_report_cback; #if AVDT_MULTIPLEXING == TRUE cs.cfg.mux_tsid_report = 2; #endif } #endif if(bta_av_cb.features & BTA_AV_FEAT_DELAY_RPT) cs.cfg.psc_mask |= AVDT_PSC_DELAY_RPT; /* keep the configuration in the stream control block */ memcpy(&p_scb->cfg, &cs.cfg, sizeof(tAVDT_CFG)); while(index < BTA_AV_MAX_SEPS && (*bta_av_a2d_cos.init)(&codec_type, cs.cfg.codec_info, &cs.cfg.num_protect, cs.cfg.protect_info, index) == TRUE) { if(AVDT_CreateStream(&p_scb->seps[index].av_handle, &cs) == AVDT_SUCCESS) { p_scb->seps[index].codec_type = codec_type; APPL_TRACE_DEBUG3("audio[%d] av_handle: %d codec_type: %d", index, p_scb->seps[index].av_handle, p_scb->seps[index].codec_type); index++; } else break; } if(!bta_av_cb.reg_audio) { /* create the SDP records on the 1st audio channel */ bta_av_cb.sdp_a2d_handle = SDP_CreateRecord(); #ifdef A2DP_SINK A2D_AddRecord(UUID_SERVCLASS_AUDIO_SINK, p_service_name, NULL, A2D_SUPF_SPEAKER, bta_av_cb.sdp_a2d_handle); bta_sys_add_uuid(UUID_SERVCLASS_AUDIO_SINK); #else A2D_AddRecord(UUID_SERVCLASS_AUDIO_SOURCE, p_service_name, NULL, A2D_SUPF_PLAYER, bta_av_cb.sdp_a2d_handle); bta_sys_add_uuid(UUID_SERVCLASS_AUDIO_SOURCE); #endif /* start listening when A2DP is registered */ if (bta_av_cb.features & BTA_AV_FEAT_RCTG) bta_av_rc_create(&bta_av_cb, AVCT_ACP, 0, BTA_AV_NUM_LINKS + 1); /* if the AV and AVK are both supported, it cannot support the CT role */ if (bta_av_cb.features & (BTA_AV_FEAT_RCCT)) { /* if TG is not supported, we need to register to AVCT now */ if ((bta_av_cb.features & (BTA_AV_FEAT_RCTG)) == 0) { #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE) #if (BTA_AV_WITH_AVCTP_AUTHORIZATION == TRUE) bta_ar_reg_avct(p_bta_av_cfg->avrc_mtu, p_bta_av_cfg->avrc_br_mtu, bta_av_cb.sec_mask, BTA_ID_AV); #else bta_ar_reg_avct(p_bta_av_cfg->avrc_mtu, p_bta_av_cfg->avrc_br_mtu, (UINT8)(bta_av_cb.sec_mask & (~BTA_SEC_AUTHORIZE)), BTA_ID_AV); #endif #endif } #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE) /* create an SDP record as AVRC CT. */ bta_ar_reg_avrc(UUID_SERVCLASS_AV_REMOTE_CONTROL, NULL, NULL, p_bta_av_cfg->avrc_ct_cat, BTA_ID_AV); #endif } } bta_av_cb.reg_audio |= BTA_AV_HNDL_TO_MSK(p_scb->hdi); APPL_TRACE_DEBUG1("reg_audio: 0x%x",bta_av_cb.reg_audio); } else { bta_av_cb.reg_video = BTA_AV_HNDL_TO_MSK(p_scb->hdi); bta_av_cb.sdp_vdp_handle = SDP_CreateRecord(); /* register the video channel */ /* no need to verify the function pointer here. it's verified prior */ (*p_bta_av_cfg->p_reg)(&cs, p_service_name, p_scb); } } while (0); /* call callback with register event */ (*bta_av_cb.p_cback)(BTA_AV_REGISTER_EVT, (tBTA_AV *)®istr); }