Home | History | Annotate | Download | only in ar
      1 /******************************************************************************
      2  *
      3  *  Copyright 2008-2012 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 /******************************************************************************
     20  *
     21  *  This is the implementation for the audio/video registration module.
     22  *
     23  ******************************************************************************/
     24 
     25 #include <string.h>
     26 
     27 #include "bta_ar_api.h"
     28 #include "bta_ar_int.h"
     29 
     30 /* AV control block */
     31 tBTA_AR_CB bta_ar_cb;
     32 
     33 /*******************************************************************************
     34  *
     35  * Function         bta_ar_id
     36  *
     37  * Description      This function maps sys_id to ar id mask.
     38  *
     39  * Returns          void
     40  *
     41  ******************************************************************************/
     42 static uint8_t bta_ar_id(tBTA_SYS_ID sys_id) {
     43   uint8_t mask = 0;
     44   if (sys_id == BTA_ID_AV) {
     45     mask = BTA_AR_AV_MASK;
     46   } else if (sys_id == BTA_ID_AVK) {
     47     mask = BTA_AR_AVK_MASK;
     48   }
     49 
     50   return mask;
     51 }
     52 
     53 /*******************************************************************************
     54  *
     55  * Function         bta_ar_init
     56  *
     57  * Description      This function is called to register to AVDTP.
     58  *
     59  * Returns          void
     60  *
     61  ******************************************************************************/
     62 void bta_ar_init(void) {
     63   /* initialize control block */
     64   memset(&bta_ar_cb, 0, sizeof(tBTA_AR_CB));
     65 }
     66 
     67 /*******************************************************************************
     68  *
     69  * Function         bta_ar_reg_avdt
     70  *
     71  * Description      This function is called to register to AVDTP.
     72  *
     73  * Returns          void
     74  *
     75  ******************************************************************************/
     76 static void bta_ar_avdt_cback(uint8_t handle, const RawAddress& bd_addr,
     77                               uint8_t event, tAVDT_CTRL* p_data,
     78                               uint8_t scb_index) {
     79   /* route the AVDT registration callback to av or avk */
     80   if (bta_ar_cb.p_av_conn_cback)
     81     (*bta_ar_cb.p_av_conn_cback)(handle, bd_addr, event, p_data, scb_index);
     82   if (bta_ar_cb.p_avk_conn_cback)
     83     (*bta_ar_cb.p_avk_conn_cback)(handle, bd_addr, event, p_data, scb_index);
     84 }
     85 
     86 /*******************************************************************************
     87  *
     88  * Function         bta_ar_reg_avdt
     89  *
     90  * Description      AR module registration to AVDT.
     91  *
     92  * Returns          void
     93  *
     94  ******************************************************************************/
     95 void bta_ar_reg_avdt(AvdtpRcb* p_reg, tAVDT_CTRL_CBACK* p_cback,
     96                      tBTA_SYS_ID sys_id) {
     97   uint8_t mask = 0;
     98 
     99   if (sys_id == BTA_ID_AV) {
    100     bta_ar_cb.p_av_conn_cback = p_cback;
    101     mask = BTA_AR_AV_MASK;
    102   } else if (sys_id == BTA_ID_AVK) {
    103     bta_ar_cb.p_avk_conn_cback = p_cback;
    104     mask = BTA_AR_AVK_MASK;
    105   }
    106 #if (BTA_AR_DEBUG == TRUE)
    107   else {
    108     APPL_TRACE_ERROR(
    109         "bta_ar_reg_avdt: the registration is from wrong sys_id:%d", sys_id);
    110   }
    111 #endif
    112 
    113   if (mask) {
    114     if (bta_ar_cb.avdt_registered == 0) {
    115       AVDT_Register(p_reg, bta_ar_avdt_cback);
    116     }
    117     bta_ar_cb.avdt_registered |= mask;
    118   }
    119 }
    120 
    121 /*******************************************************************************
    122  *
    123  * Function         bta_ar_dereg_avdt
    124  *
    125  * Description      This function is called to de-register from AVDTP.
    126  *
    127  * Returns          void
    128  *
    129  ******************************************************************************/
    130 void bta_ar_dereg_avdt(tBTA_SYS_ID sys_id) {
    131   uint8_t mask = 0;
    132 
    133   if (sys_id == BTA_ID_AV) {
    134     bta_ar_cb.p_av_conn_cback = NULL;
    135     mask = BTA_AR_AV_MASK;
    136   } else if (sys_id == BTA_ID_AVK) {
    137     bta_ar_cb.p_avk_conn_cback = NULL;
    138     mask = BTA_AR_AVK_MASK;
    139   }
    140   bta_ar_cb.avdt_registered &= ~mask;
    141 
    142   if (bta_ar_cb.avdt_registered == 0) AVDT_Deregister();
    143 }
    144 
    145 /*******************************************************************************
    146  *
    147  * Function         bta_ar_avdt_conn
    148  *
    149  * Description      This function is called to let ar know that some AVDTP
    150  *                  profile is connected for this sys_id.
    151  *                  If the other sys modules started a timer for PENDING_EVT,
    152  *                  the timer can be stopped now.
    153  *
    154  * Returns          void
    155  *
    156  ******************************************************************************/
    157 void bta_ar_avdt_conn(tBTA_SYS_ID sys_id, const RawAddress& bd_addr,
    158                       uint8_t scb_index) {
    159   uint8_t event = BTA_AR_AVDT_CONN_EVT;
    160   tAVDT_CTRL data;
    161 
    162   if (sys_id == BTA_ID_AV) {
    163     if (bta_ar_cb.p_avk_conn_cback) {
    164       (*bta_ar_cb.p_avk_conn_cback)(0, bd_addr, event, &data, scb_index);
    165     }
    166   } else if (sys_id == BTA_ID_AVK) {
    167     if (bta_ar_cb.p_av_conn_cback) {
    168       (*bta_ar_cb.p_av_conn_cback)(0, bd_addr, event, &data, scb_index);
    169     }
    170   }
    171 }
    172 
    173 /*******************************************************************************
    174  *
    175  * Function         bta_ar_reg_avct
    176  *
    177  * Description      This function is called to register to AVCTP.
    178  *
    179  * Returns          void
    180  *
    181  ******************************************************************************/
    182 void bta_ar_reg_avct(uint16_t mtu, uint16_t mtu_br, uint8_t sec_mask,
    183                      tBTA_SYS_ID sys_id) {
    184   uint8_t mask = bta_ar_id(sys_id);
    185 
    186   if (mask) {
    187     if (bta_ar_cb.avct_registered == 0) {
    188       AVCT_Register(mtu, mtu_br, sec_mask);
    189     }
    190     bta_ar_cb.avct_registered |= mask;
    191   }
    192 }
    193 
    194 /*******************************************************************************
    195  *
    196  * Function         bta_ar_dereg_avct
    197  *
    198  * Description      This function is called to deregister from AVCTP.
    199  *
    200  * Returns          void
    201  *
    202  ******************************************************************************/
    203 void bta_ar_dereg_avct(tBTA_SYS_ID sys_id) {
    204   uint8_t mask = bta_ar_id(sys_id);
    205 
    206   bta_ar_cb.avct_registered &= ~mask;
    207 
    208   if (bta_ar_cb.avct_registered == 0) AVCT_Deregister();
    209 }
    210 
    211 /******************************************************************************
    212  *
    213  * Function         bta_ar_reg_avrc
    214  *
    215  * Description      This function is called to register an SDP record for AVRCP.
    216  *
    217  * Returns          void
    218  *
    219  *****************************************************************************/
    220 void bta_ar_reg_avrc(uint16_t service_uuid, const char* service_name,
    221                      const char* provider_name, uint16_t categories,
    222                      tBTA_SYS_ID sys_id, bool browse_supported,
    223                      uint16_t profile_version) {
    224   uint8_t mask = bta_ar_id(sys_id);
    225   uint8_t temp[8], *p;
    226 
    227   if (!mask || !categories) return;
    228 
    229   if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) {
    230     if (bta_ar_cb.sdp_tg_handle == 0) {
    231       bta_ar_cb.tg_registered = mask;
    232       bta_ar_cb.sdp_tg_handle = SDP_CreateRecord();
    233       AVRC_AddRecord(service_uuid, service_name, provider_name, categories,
    234                      bta_ar_cb.sdp_tg_handle, browse_supported,
    235                      profile_version);
    236       bta_sys_add_uuid(service_uuid);
    237     }
    238     /* only one TG is allowed (first-come, first-served).
    239      * If sdp_tg_handle is non-0, ignore this request */
    240   } else if ((service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) ||
    241              (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_CONTROL)) {
    242     bta_ar_cb.ct_categories[mask - 1] = categories;
    243     categories = bta_ar_cb.ct_categories[0] | bta_ar_cb.ct_categories[1];
    244     if (bta_ar_cb.sdp_ct_handle == 0) {
    245       bta_ar_cb.sdp_ct_handle = SDP_CreateRecord();
    246       AVRC_AddRecord(service_uuid, service_name, provider_name, categories,
    247                      bta_ar_cb.sdp_ct_handle, browse_supported,
    248                      profile_version);
    249       bta_sys_add_uuid(service_uuid);
    250     } else {
    251       /* multiple CTs are allowed.
    252        * Change supported categories on the second one */
    253       p = temp;
    254       UINT16_TO_BE_STREAM(p, categories);
    255       SDP_AddAttribute(bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES,
    256                        UINT_DESC_TYPE, (uint32_t)2, (uint8_t*)temp);
    257     }
    258   }
    259 }
    260 
    261 /******************************************************************************
    262  *
    263  * Function         bta_ar_dereg_avrc
    264  *
    265  * Description      This function is called to de-register/delete an SDP record
    266  *                  for AVRCP.
    267  *
    268  * Returns          void
    269  *
    270  *****************************************************************************/
    271 void bta_ar_dereg_avrc(uint16_t service_uuid, tBTA_SYS_ID sys_id) {
    272   uint8_t mask = bta_ar_id(sys_id);
    273   uint16_t categories = 0;
    274   uint8_t temp[8], *p;
    275 
    276   if (!mask) return;
    277 
    278   if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) {
    279     if (bta_ar_cb.sdp_tg_handle && mask == bta_ar_cb.tg_registered) {
    280       bta_ar_cb.tg_registered = 0;
    281       SDP_DeleteRecord(bta_ar_cb.sdp_tg_handle);
    282       bta_ar_cb.sdp_tg_handle = 0;
    283       bta_sys_remove_uuid(service_uuid);
    284     }
    285   } else if (service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) {
    286     if (bta_ar_cb.sdp_ct_handle) {
    287       bta_ar_cb.ct_categories[mask - 1] = 0;
    288       categories = bta_ar_cb.ct_categories[0] | bta_ar_cb.ct_categories[1];
    289       if (!categories) {
    290         /* no CT is still registered - cleaup */
    291         SDP_DeleteRecord(bta_ar_cb.sdp_ct_handle);
    292         bta_ar_cb.sdp_ct_handle = 0;
    293         bta_sys_remove_uuid(service_uuid);
    294       } else {
    295         /* change supported categories to the remaning one */
    296         p = temp;
    297         UINT16_TO_BE_STREAM(p, categories);
    298         SDP_AddAttribute(bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES,
    299                          UINT_DESC_TYPE, (uint32_t)2, (uint8_t*)temp);
    300       }
    301     }
    302   }
    303 }
    304