Home | History | Annotate | Download | only in ar
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 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 #include "bta_ar_api.h"
     27 #include "bta_ar_int.h"
     28 
     29 
     30 /* AV control block */
     31 #if BTA_DYNAMIC_MEMORY == FALSE
     32 tBTA_AR_CB  bta_ar_cb;
     33 #endif
     34 
     35 /*******************************************************************************
     36 **
     37 ** Function         bta_ar_id
     38 **
     39 ** Description      This function maps sys_id to ar id mask.
     40 **
     41 ** Returns          void
     42 **
     43 *******************************************************************************/
     44 static UINT8 bta_ar_id(tBTA_SYS_ID sys_id)
     45 {
     46     UINT8   mask = 0;
     47     if (sys_id == BTA_ID_AV)
     48     {
     49         mask = BTA_AR_AV_MASK;
     50     }
     51     else if (sys_id == BTA_ID_AVK)
     52     {
     53         mask = BTA_AR_AVK_MASK;
     54     }
     55 
     56     return mask;
     57 }
     58 
     59 /*******************************************************************************
     60 **
     61 ** Function         bta_ar_init
     62 **
     63 ** Description      This function is called to register to AVDTP.
     64 **
     65 ** Returns          void
     66 **
     67 *******************************************************************************/
     68 void bta_ar_init(void)
     69 {
     70     /* initialize control block */
     71     memset(&bta_ar_cb, 0, sizeof(tBTA_AR_CB));
     72 }
     73 
     74 /*******************************************************************************
     75 **
     76 ** Function         bta_ar_reg_avdt
     77 **
     78 ** Description      This function is called to register to AVDTP.
     79 **
     80 ** Returns          void
     81 **
     82 *******************************************************************************/
     83 static void bta_ar_avdt_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data)
     84 {
     85     /* route the AVDT registration callback to av or avk */
     86     if (bta_ar_cb.p_av_conn_cback)
     87         (*bta_ar_cb.p_av_conn_cback)(handle, bd_addr, event, p_data);
     88     if (bta_ar_cb.p_avk_conn_cback)
     89         (*bta_ar_cb.p_avk_conn_cback)(handle, bd_addr, event, p_data);
     90 }
     91 
     92 /*******************************************************************************
     93 **
     94 ** Function         bta_ar_reg_avdt
     95 **
     96 ** Description      AR module registration to AVDT.
     97 **
     98 ** Returns          void
     99 **
    100 *******************************************************************************/
    101 void bta_ar_reg_avdt(tAVDT_REG *p_reg, tAVDT_CTRL_CBACK *p_cback, tBTA_SYS_ID sys_id)
    102 {
    103     UINT8   mask = 0;
    104 
    105     if (sys_id == BTA_ID_AV)
    106     {
    107         bta_ar_cb.p_av_conn_cback = p_cback;
    108         mask = BTA_AR_AV_MASK;
    109     }
    110     else if (sys_id == BTA_ID_AVK)
    111     {
    112         bta_ar_cb.p_avk_conn_cback = p_cback;
    113         mask = BTA_AR_AVK_MASK;
    114     }
    115 #if (BTA_AR_DEBUG == TRUE)
    116     else
    117     {
    118         APPL_TRACE_ERROR("bta_ar_reg_avdt: the registration is from wrong sys_id:%d", sys_id);
    119     }
    120 #endif
    121 
    122     if (mask)
    123     {
    124         if (bta_ar_cb.avdt_registered == 0)
    125         {
    126             AVDT_Register(p_reg, bta_ar_avdt_cback);
    127         }
    128         bta_ar_cb.avdt_registered |= mask;
    129     }
    130 }
    131 
    132 /*******************************************************************************
    133 **
    134 ** Function         bta_ar_dereg_avdt
    135 **
    136 ** Description      This function is called to de-register from AVDTP.
    137 **
    138 ** Returns          void
    139 **
    140 *******************************************************************************/
    141 void bta_ar_dereg_avdt(tBTA_SYS_ID sys_id)
    142 {
    143     UINT8   mask = 0;
    144 
    145     if (sys_id == BTA_ID_AV)
    146     {
    147         bta_ar_cb.p_av_conn_cback = NULL;
    148         mask = BTA_AR_AV_MASK;
    149     }
    150     else if (sys_id == BTA_ID_AVK)
    151     {
    152         bta_ar_cb.p_avk_conn_cback = NULL;
    153         mask = BTA_AR_AVK_MASK;
    154     }
    155     bta_ar_cb.avdt_registered &= ~mask;
    156 
    157     if (bta_ar_cb.avdt_registered == 0)
    158         AVDT_Deregister();
    159 }
    160 
    161 /*******************************************************************************
    162 **
    163 ** Function         bta_ar_avdt_conn
    164 **
    165 ** Description      This function is called to let ar know that some AVDTP profile
    166 **                  is connected for this sys_id.
    167 **                  If the other sys modules started a timer for PENDING_EVT,
    168 **                  the timer can be stopped now.
    169 **
    170 ** Returns          void
    171 **
    172 *******************************************************************************/
    173 void bta_ar_avdt_conn(tBTA_SYS_ID sys_id, BD_ADDR bd_addr)
    174 {
    175     UINT8       event = BTA_AR_AVDT_CONN_EVT;
    176     tAVDT_CTRL  data;
    177 
    178     if (sys_id == BTA_ID_AV)
    179     {
    180         if (bta_ar_cb.p_avk_conn_cback)
    181         {
    182             (*bta_ar_cb.p_avk_conn_cback)(0, bd_addr, event, &data);
    183         }
    184     }
    185     else if (sys_id == BTA_ID_AVK)
    186     {
    187         if (bta_ar_cb.p_av_conn_cback)
    188         {
    189             (*bta_ar_cb.p_av_conn_cback)(0, bd_addr, event, &data);
    190         }
    191     }
    192 }
    193 
    194 /*******************************************************************************
    195 **
    196 ** Function         bta_ar_reg_avct
    197 **
    198 ** Description      This function is called to register to AVCTP.
    199 **
    200 ** Returns          void
    201 **
    202 *******************************************************************************/
    203 void bta_ar_reg_avct(UINT16 mtu, UINT16 mtu_br, UINT8 sec_mask, tBTA_SYS_ID sys_id)
    204 {
    205     UINT8   mask = bta_ar_id (sys_id);
    206 
    207     if (mask)
    208     {
    209         if (bta_ar_cb.avct_registered == 0)
    210         {
    211             AVCT_Register(mtu, mtu_br, sec_mask);
    212         }
    213         bta_ar_cb.avct_registered |= mask;
    214     }
    215 }
    216 
    217 /*******************************************************************************
    218 **
    219 ** Function         bta_ar_dereg_avct
    220 **
    221 ** Description      This function is called to deregister from AVCTP.
    222 **
    223 ** Returns          void
    224 **
    225 *******************************************************************************/
    226 void bta_ar_dereg_avct(tBTA_SYS_ID sys_id)
    227 {
    228     UINT8   mask = bta_ar_id (sys_id);
    229 
    230     bta_ar_cb.avct_registered &= ~mask;
    231 
    232     if (bta_ar_cb.avct_registered == 0)
    233         AVCT_Deregister();
    234 }
    235 
    236 /******************************************************************************
    237 **
    238 ** Function         bta_ar_reg_avrc
    239 **
    240 ** Description      This function is called to register an SDP record for AVRCP.
    241 **
    242 ** Returns          void
    243 **
    244 ******************************************************************************/
    245 void bta_ar_reg_avrc(UINT16 service_uuid, char *service_name, char *provider_name,
    246 					 UINT16 categories, tBTA_SYS_ID sys_id)
    247 {
    248     UINT8   mask = bta_ar_id (sys_id);
    249     UINT8   temp[8], *p;
    250 
    251     if (!mask || !categories)
    252         return;
    253 
    254     if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET)
    255     {
    256         if (bta_ar_cb.sdp_tg_handle == 0)
    257         {
    258             bta_ar_cb.tg_registered = mask;
    259             bta_ar_cb.sdp_tg_handle = SDP_CreateRecord();
    260             AVRC_AddRecord(service_uuid, service_name, provider_name, categories, bta_ar_cb.sdp_tg_handle);
    261             bta_sys_add_uuid(service_uuid);
    262         }
    263         /* only one TG is allowed (first-come, first-served).
    264          * If sdp_tg_handle is non-0, ignore this request */
    265     }
    266     else if ((service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) || (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_CONTROL))
    267     {
    268         bta_ar_cb.ct_categories [mask - 1] = categories;
    269         categories = bta_ar_cb.ct_categories[0]|bta_ar_cb.ct_categories[1];
    270         if (bta_ar_cb.sdp_ct_handle == 0)
    271         {
    272             bta_ar_cb.sdp_ct_handle = SDP_CreateRecord();
    273             AVRC_AddRecord(service_uuid, service_name, provider_name, categories, bta_ar_cb.sdp_ct_handle);
    274             bta_sys_add_uuid(service_uuid);
    275         }
    276         else
    277         {
    278             /* multiple CTs are allowed.
    279              * Change supported categories on the second one */
    280             p = temp;
    281             UINT16_TO_BE_STREAM(p, categories);
    282             SDP_AddAttribute(bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE,
    283                       (UINT32)2, (UINT8*)temp);
    284         }
    285     }
    286 }
    287 
    288 /******************************************************************************
    289 **
    290 ** Function         bta_ar_dereg_avrc
    291 **
    292 ** Description      This function is called to de-register/delete an SDP record for AVRCP.
    293 **
    294 ** Returns          void
    295 **
    296 ******************************************************************************/
    297 void bta_ar_dereg_avrc(UINT16 service_uuid, tBTA_SYS_ID sys_id)
    298 {
    299     UINT8   mask = bta_ar_id (sys_id);
    300     UINT16  categories = 0;
    301     UINT8   temp[8], *p;
    302 
    303     if (!mask)
    304         return;
    305 
    306     if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET)
    307     {
    308         if (bta_ar_cb.sdp_tg_handle && mask == bta_ar_cb.tg_registered)
    309         {
    310             bta_ar_cb.tg_registered = 0;
    311             SDP_DeleteRecord(bta_ar_cb.sdp_tg_handle);
    312             bta_ar_cb.sdp_tg_handle = 0;
    313             bta_sys_remove_uuid(service_uuid);
    314         }
    315     }
    316     else if (service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL)
    317     {
    318         if (bta_ar_cb.sdp_ct_handle)
    319         {
    320             bta_ar_cb.ct_categories [mask - 1] = 0;
    321             categories = bta_ar_cb.ct_categories[0]|bta_ar_cb.ct_categories[1];
    322             if (!categories)
    323             {
    324                 /* no CT is still registered - cleaup */
    325                 SDP_DeleteRecord(bta_ar_cb.sdp_ct_handle);
    326                 bta_ar_cb.sdp_ct_handle = 0;
    327                 bta_sys_remove_uuid(service_uuid);
    328             }
    329             else
    330             {
    331                 /* change supported categories to the remaning one */
    332                 p = temp;
    333                 UINT16_TO_BE_STREAM(p, categories);
    334                 SDP_AddAttribute(bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE,
    335                           (UINT32)2, (UINT8*)temp);
    336             }
    337         }
    338     }
    339 
    340 }
    341