1/******************************************************************************
2 *
3 *  Copyright (C) 2014 The Android Open Source Project
4 *  Copyright (C) 2003-2012 Broadcom Corporation
5 *
6 *  Licensed under the Apache License, Version 2.0 (the "License");
7 *  you may not use this file except in compliance with the License.
8 *  You may obtain a copy of the License at:
9 *
10 *  http://www.apache.org/licenses/LICENSE-2.0
11 *
12 *  Unless required by applicable law or agreed to in writing, software
13 *  distributed under the License is distributed on an "AS IS" BASIS,
14 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 *  See the License for the specific language governing permissions and
16 *  limitations under the License.
17 *
18 ******************************************************************************/
19
20/******************************************************************************
21 *
22 *  This file contains action functions for MCE.
23 *
24 ******************************************************************************/
25
26#include <hardware/bluetooth.h>
27#include <arpa/inet.h>
28
29#include "bt_types.h"
30#include "bt_common.h"
31#include "utl.h"
32#include "bta_sys.h"
33#include "bta_api.h"
34#include "bta_mce_api.h"
35#include "bta_mce_int.h"
36#include "btm_api.h"
37#include "btm_int.h"
38#include "sdp_api.h"
39#include <string.h>
40
41/*****************************************************************************
42**  Constants
43*****************************************************************************/
44
45static const tBT_UUID bta_mce_mas_uuid = {
46    .len = 2,
47    .uu.uuid16 = UUID_SERVCLASS_MESSAGE_ACCESS
48};
49
50/*******************************************************************************
51**
52** Function     bta_mce_search_cback
53**
54** Description  Callback from btm after search is completed
55**
56** Returns      void
57**
58*******************************************************************************/
59
60static void bta_mce_search_cback(UINT16 result, void * user_data)
61{
62    tSDP_DISC_REC *p_rec = NULL;
63    tBTA_MCE_MAS_DISCOVERY_COMP evt_data;
64    int found = 0;
65
66    APPL_TRACE_DEBUG("bta_mce_start_discovery_cback res: 0x%x", result);
67
68    bta_mce_cb.sdp_active = BTA_MCE_SDP_ACT_NONE;
69
70    if (bta_mce_cb.p_dm_cback == NULL) return;
71
72    evt_data.status = BTA_MCE_FAILURE;
73    bdcpy(evt_data.remote_addr, bta_mce_cb.remote_addr);
74    evt_data.num_mas = 0;
75
76    if (result == SDP_SUCCESS || result == SDP_DB_FULL)
77    {
78        do
79        {
80            tSDP_DISC_ATTR *p_attr;
81            tSDP_PROTOCOL_ELEM pe;
82
83            p_rec = SDP_FindServiceUUIDInDb(p_bta_mce_cfg->p_sdp_db, (tBT_UUID*) &bta_mce_mas_uuid, p_rec);
84
85            APPL_TRACE_DEBUG("p_rec:%p", p_rec);
86
87            if (p_rec == NULL)
88                break;
89
90            if (!SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe))
91                continue;
92
93            evt_data.mas[found].scn = pe.params[0];
94
95            if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) == NULL)
96                continue;
97
98            evt_data.mas[found].p_srv_name = (char *) p_attr->attr_value.v.array;
99            evt_data.mas[found].srv_name_len= SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
100
101            if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAS_INSTANCE_ID)) == NULL)
102                break;
103
104                 evt_data.mas[found].instance_id = p_attr->attr_value.v.u8;
105
106            if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_MSG_TYPE)) == NULL)
107                break;
108
109            evt_data.mas[found].msg_type = p_attr->attr_value.v.u8;
110
111            found++;
112        } while (p_rec != NULL && found < BTA_MCE_MAX_MAS_INSTANCES);
113
114        evt_data.num_mas = found;
115        evt_data.status = BTA_MCE_SUCCESS;
116    }
117
118    bta_mce_cb.p_dm_cback(BTA_MCE_MAS_DISCOVERY_COMP_EVT, (tBTA_MCE*) &evt_data, user_data);
119}
120
121/*******************************************************************************
122**
123** Function     bta_mce_enable
124**
125** Description  Initializes the MCE I/F
126**
127** Returns      void
128**
129*******************************************************************************/
130void bta_mce_enable(tBTA_MCE_MSG *p_data)
131{
132    tBTA_MCE_STATUS status = BTA_MCE_SUCCESS;
133    bta_mce_cb.p_dm_cback = p_data->enable.p_cback;
134    bta_mce_cb.p_dm_cback(BTA_MCE_ENABLE_EVT, (tBTA_MCE *)&status, NULL);
135}
136
137/*******************************************************************************
138**
139** Function     bta_mce_get_remote_mas_instances
140**
141** Description  Discovers MAS instances on remote device
142**
143** Returns      void
144**
145*******************************************************************************/
146void bta_mce_get_remote_mas_instances(tBTA_MCE_MSG *p_data)
147{
148    if(p_data == NULL)
149    {
150    APPL_TRACE_DEBUG("MCE control block handle is null");
151    return;
152    }
153    tBTA_MCE_STATUS status = BTA_MCE_FAILURE;
154
155    APPL_TRACE_DEBUG("%s in, sdp_active:%d", __FUNCTION__, bta_mce_cb.sdp_active);
156
157    if (bta_mce_cb.sdp_active != BTA_MCE_SDP_ACT_NONE)
158    {
159        /* SDP is still in progress */
160        status = BTA_MCE_BUSY;
161        if(bta_mce_cb.p_dm_cback)
162            bta_mce_cb.p_dm_cback(BTA_MCE_MAS_DISCOVERY_COMP_EVT, (tBTA_MCE *)&status, NULL);
163
164        return;
165    }
166
167    bta_mce_cb.sdp_active = BTA_MCE_SDP_ACT_YES;
168    bdcpy(bta_mce_cb.remote_addr, p_data->get_rmt_mas.bd_addr);
169
170    SDP_InitDiscoveryDb (p_bta_mce_cfg->p_sdp_db, p_bta_mce_cfg->sdp_db_size, 1,
171                                (tBT_UUID*) &bta_mce_mas_uuid, 0, NULL);
172
173    if (!SDP_ServiceSearchAttributeRequest2(p_data->get_rmt_mas.bd_addr, p_bta_mce_cfg->p_sdp_db,
174                                                bta_mce_search_cback, NULL))
175    {
176        bta_mce_cb.sdp_active = BTA_MCE_SDP_ACT_NONE;
177
178        /* failed to start SDP. report the failure right away */
179        if (bta_mce_cb.p_dm_cback)
180            bta_mce_cb.p_dm_cback(BTA_MCE_MAS_DISCOVERY_COMP_EVT, (tBTA_MCE *)&status, NULL);
181    }
182    /*
183    else report the result when the cback is called
184    */
185}
186