1 /******************************************************************************
2 *
3 * Copyright (C) 2009-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 file for the HeaLth device profile (HL)
22 * subsystem call-out functions.
23 *
24 ******************************************************************************/
25
26 #include <ctype.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/socket.h>
33 #include <sys/types.h>
34 #include <sys/un.h>
35 #include <time.h>
36
37 #include "bta_api.h"
38 #include "bta_hl_api.h"
39 #include "bta_hl_ci.h"
40 #include "bta_hl_co.h"
41 #include "bta_sys.h"
42 #include "btif_hl.h"
43 #include "btif_util.h"
44 #include "btm_api.h"
45 #include "osi/include/osi.h"
46
47 /*****************************************************************************
48 * Constants and Data Types
49 ****************************************************************************/
50 /**************************
51 * Common Definitions
52 **************************/
53
54 /*******************************************************************************
55 *
56 * Function bta_hl_co_get_num_of_mdep
57 *
58 * Description This function is called to get the number of MDEPs for this
59 * application ID
60 *
61 * Parameters app_id - application ID
62 * p_num_of_mdep (output) - number of MDEP configurations
63 * supported by the application
64 *
65 * Returns true on success
66 *
67 ******************************************************************************/
bta_hl_co_get_num_of_mdep(uint8_t app_id,uint8_t * p_num_of_mdep)68 bool bta_hl_co_get_num_of_mdep(uint8_t app_id, uint8_t* p_num_of_mdep) {
69 uint8_t app_idx;
70 bool success = false;
71
72 if (btif_hl_find_app_idx(app_id, &app_idx)) {
73 *p_num_of_mdep = p_btif_hl_cb->acb[app_idx].sup_feature.num_of_mdeps;
74 success = true;
75 }
76
77 BTIF_TRACE_DEBUG("%s success=%d num_mdeps=%d", __func__, success,
78 *p_num_of_mdep);
79 return success;
80 }
81
82 /*******************************************************************************
83 *
84 * Function bta_hl_co_advrtise_source_sdp
85 *
86 * Description This function is called to find out whether the SOURCE MDEP
87 * configuration information should be advertise in the SDP or
88 * not.
89 *
90 * Parameters app_id - application ID
91 *
92 * Returns true when advertise the SOURCE MDEP configuration
93 * information
94 *
95 ******************************************************************************/
bta_hl_co_advrtise_source_sdp(uint8_t app_id)96 bool bta_hl_co_advrtise_source_sdp(uint8_t app_id) {
97 bool advertize_source_sdp = false;
98 uint8_t app_idx;
99
100 if (btif_hl_find_app_idx(app_id, &app_idx)) {
101 advertize_source_sdp =
102 p_btif_hl_cb->acb[app_idx].sup_feature.advertize_source_sdp;
103 }
104
105 BTIF_TRACE_DEBUG("%s advertize_flag=%d", __func__, advertize_source_sdp);
106
107 return advertize_source_sdp;
108 }
109 /*******************************************************************************
110 *
111 * Function bta_hl_co_get_mdep_config
112 *
113 * Description This function is called to get the supported feature
114 * configuration for the specified mdep index and it also
115 * assigns the MDEP ID for the specified mdep index
116 *
117 * Parameters app_id - HDP application ID
118 * mdep_idx - the mdep index
119 * mdep_counter - number of mdeps
120 * mdep_id - the assigned MDEP ID for the specified medp_idx
121 * p_mdl_cfg (output) - pointer to the MDEP configuration
122 *
123 *
124 * Returns Bloolean - true success
125 ******************************************************************************/
bta_hl_co_get_mdep_config(uint8_t app_id,uint8_t mdep_idx,uint8_t mdep_counter,tBTA_HL_MDEP_ID mdep_id,tBTA_HL_MDEP_CFG * p_mdep_cfg)126 bool bta_hl_co_get_mdep_config(uint8_t app_id, uint8_t mdep_idx,
127 uint8_t mdep_counter, tBTA_HL_MDEP_ID mdep_id,
128 tBTA_HL_MDEP_CFG* p_mdep_cfg) {
129 uint8_t idx;
130 uint8_t app_idx;
131 bool success = false;
132
133 BTIF_TRACE_DEBUG("%s app_id=%d mdep_idx=%d mdep_id=%d mdep_counter=%d",
134 __func__, app_id, mdep_idx, mdep_id, mdep_counter);
135
136 if (btif_hl_find_app_idx(app_id, &app_idx)) {
137 idx = mdep_idx - mdep_counter - 1;
138 p_btif_hl_cb->acb[app_idx].sup_feature.mdep[idx].mdep_id = mdep_id;
139 memcpy(p_mdep_cfg,
140 &p_btif_hl_cb->acb[app_idx].sup_feature.mdep[idx].mdep_cfg,
141 sizeof(tBTA_HL_MDEP_CFG));
142
143 success = true;
144 }
145
146 BTIF_TRACE_DEBUG("%s success=%d mdep_idx=%d mdep_id=%d", __func__, success,
147 mdep_idx, mdep_id);
148
149 return success;
150 }
151
152 /*******************************************************************************
153 *
154 * Function bta_hl_co_get_echo_config
155 *
156 * Description This function is called to get the echo test
157 * maximum APDU size configurations
158 *
159 * Parameters app_id - HDP application ID
160 * p_echo_cfg (output) - pointer to the Echo test maximum APDU
161 * size configuration
162 *
163 * Returns Bloolean - true success
164 ******************************************************************************/
bta_hl_co_get_echo_config(uint8_t app_id,tBTA_HL_ECHO_CFG * p_echo_cfg)165 bool bta_hl_co_get_echo_config(uint8_t app_id, tBTA_HL_ECHO_CFG* p_echo_cfg) {
166 uint8_t app_idx;
167 bool success = false;
168 btif_hl_app_cb_t* p_acb;
169 tBTA_HL_SUP_FEATURE* p_sup;
170
171 BTIF_TRACE_DEBUG("%s app_id=%d", __func__, app_id);
172
173 if (btif_hl_find_app_idx(app_id, &app_idx)) {
174 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
175 p_sup = &p_acb->sup_feature;
176 p_echo_cfg->max_rx_apdu_size = p_sup->echo_cfg.max_rx_apdu_size;
177 p_echo_cfg->max_tx_apdu_size = p_sup->echo_cfg.max_tx_apdu_size;
178 success = true;
179 }
180
181 BTIF_TRACE_DEBUG("%s success=%d max tx_size=%d rx_size=%d", __func__, success,
182 p_echo_cfg->max_tx_apdu_size, p_echo_cfg->max_rx_apdu_size);
183
184 return success;
185 }
186
187 /*******************************************************************************
188 *
189 * Function bta_hl_co_save_mdl
190 *
191 * Description This function is called to save a MDL configuration item in
192 * persistent storage
193 *
194 * Parameters app_id - HDP application ID
195 * item_idx - the MDL configuration storage index
196 * p_mdl_cfg - pointer to the MDL configuration data
197 *
198 * Returns void
199 *
200 ******************************************************************************/
bta_hl_co_save_mdl(uint8_t mdep_id,uint8_t item_idx,tBTA_HL_MDL_CFG * p_mdl_cfg)201 void bta_hl_co_save_mdl(uint8_t mdep_id, uint8_t item_idx,
202 tBTA_HL_MDL_CFG* p_mdl_cfg) {
203 BTIF_TRACE_DEBUG("%s mdep_id =%d, item_idx=%d active=%d mdl_id=%d time=%d",
204 __func__, mdep_id, item_idx, p_mdl_cfg->active,
205 p_mdl_cfg->mdl_id, p_mdl_cfg->time);
206
207 btif_hl_save_mdl_cfg(mdep_id, item_idx, p_mdl_cfg);
208 }
209
210 /*******************************************************************************
211 *
212 * Function bta_hl_co_delete_mdl
213 *
214 * Description This function is called to delete a MDL configuration item in
215 * persistent storage
216 *
217 * Parameters app_id - HDP application ID
218 * item_idx - the MDL configuration storage index
219 *
220 * Returns void
221 *
222 ******************************************************************************/
bta_hl_co_delete_mdl(uint8_t mdep_id,uint8_t item_idx)223 void bta_hl_co_delete_mdl(uint8_t mdep_id, uint8_t item_idx) {
224 BTIF_TRACE_DEBUG("%s mdep_id=%d, item_idx=%d", __func__, mdep_id, item_idx);
225
226 btif_hl_delete_mdl_cfg(mdep_id, item_idx);
227 }
228
229 /*******************************************************************************
230 *
231 * Function bta_hl_co_get_mdl_config
232 *
233 * Description This function is called to get the MDL configuration
234 * from the persistent memory. This function shall only be
235 * called once after the device is powered up
236 *
237 * Parameters app_id - HDP application ID
238 * buffer_size - the unit of the buffer size is
239 * sizeof(tBTA_HL_MDL_CFG)
240 * p_mdl_buf - Point to the starting location of the buffer
241 *
242 * Returns bool
243 *
244 *
245 ******************************************************************************/
bta_hl_co_load_mdl_config(uint8_t app_id,uint8_t buffer_size,tBTA_HL_MDL_CFG * p_mdl_buf)246 bool bta_hl_co_load_mdl_config(uint8_t app_id, uint8_t buffer_size,
247 tBTA_HL_MDL_CFG* p_mdl_buf) {
248 bool result = true;
249 uint8_t i;
250 tBTA_HL_MDL_CFG* p;
251
252 BTIF_TRACE_DEBUG("%s app_id=%d, num_items=%d", __func__, app_id, buffer_size);
253
254 if (buffer_size > BTA_HL_NUM_MDL_CFGS) {
255 result = false;
256 return result;
257 }
258 result = btif_hl_load_mdl_config(app_id, buffer_size, p_mdl_buf);
259
260 if (result) {
261 for (i = 0, p = p_mdl_buf; i < buffer_size; i++, p++) {
262 if (p->active) {
263 BTIF_TRACE_DEBUG(
264 "i=%d mdl_id=0x%x dch_mode=%d local mdep_role=%d mdep_id=%d mtu=%d",
265 i, p->mdl_id, p->dch_mode, p->local_mdep_role, p->local_mdep_role,
266 p->mtu);
267 }
268 }
269 }
270
271 BTIF_TRACE_DEBUG("%s success=%d num_items=%d", __func__, result, buffer_size);
272
273 return result;
274 }
275
276 /*******************************************************************************
277 *
278 * Function bta_hl_co_get_tx_data
279 *
280 * Description Get the data to be sent
281 *
282 * Parameters app_id - HDP application ID
283 * mdl_handle - MDL handle
284 * buf_size - the size of the buffer
285 * p_buf - the buffer pointer
286 * evt - the evt to be passed back to the HL in the
287 * bta_hl_ci_get_tx_data call-in function
288 *
289 * Returns Void
290 *
291 ******************************************************************************/
bta_hl_co_get_tx_data(uint8_t app_id,tBTA_HL_MDL_HANDLE mdl_handle,uint16_t buf_size,uint8_t * p_buf,uint16_t evt)292 void bta_hl_co_get_tx_data(uint8_t app_id, tBTA_HL_MDL_HANDLE mdl_handle,
293 uint16_t buf_size, uint8_t* p_buf, uint16_t evt) {
294 uint8_t app_idx, mcl_idx, mdl_idx;
295 btif_hl_mdl_cb_t* p_dcb;
296 tBTA_HL_STATUS status = BTA_HL_STATUS_FAIL;
297
298 BTIF_TRACE_DEBUG("%s app_id=%d mdl_handle=0x%x buf_size=%d", __func__, app_id,
299 mdl_handle, buf_size);
300
301 if (btif_hl_find_mdl_idx_using_handle(mdl_handle, &app_idx, &mcl_idx,
302 &mdl_idx)) {
303 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
304
305 if ((p_dcb->tx_size <= buf_size) && p_dcb->p_tx_pkt) {
306 memcpy(p_buf, p_dcb->p_tx_pkt, p_dcb->tx_size);
307 osi_free_and_reset((void**)&p_dcb->p_tx_pkt);
308 p_dcb->tx_size = 0;
309 status = BTA_HL_STATUS_OK;
310 }
311 }
312
313 bta_hl_ci_get_tx_data(mdl_handle, status, evt);
314 }
315
316 /*******************************************************************************
317 *
318 * Function bta_hl_co_put_rx_data
319 *
320 * Description Put the received data
321 *
322 * Parameters app_id - HDP application ID
323 * mdl_handle - MDL handle
324 * data_size - the size of the data
325 * p_data - the data pointer
326 * evt - the evt to be passed back to the HL in the
327 * bta_hl_ci_put_rx_data call-in function
328 *
329 * Returns Void
330 *
331 ******************************************************************************/
bta_hl_co_put_rx_data(uint8_t app_id,tBTA_HL_MDL_HANDLE mdl_handle,uint16_t data_size,uint8_t * p_data,uint16_t evt)332 void bta_hl_co_put_rx_data(uint8_t app_id, tBTA_HL_MDL_HANDLE mdl_handle,
333 uint16_t data_size, uint8_t* p_data, uint16_t evt) {
334 uint8_t app_idx, mcl_idx, mdl_idx;
335 btif_hl_mdl_cb_t* p_dcb;
336 tBTA_HL_STATUS status = BTA_HL_STATUS_FAIL;
337 BTIF_TRACE_DEBUG("%s app_id=%d mdl_handle=0x%x data_size=%d", __func__,
338 app_id, mdl_handle, data_size);
339
340 if (btif_hl_find_mdl_idx_using_handle(mdl_handle, &app_idx, &mcl_idx,
341 &mdl_idx)) {
342 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
343
344 p_dcb->p_rx_pkt = (uint8_t*)osi_malloc(data_size);
345 memcpy(p_dcb->p_rx_pkt, p_data, data_size);
346 if (p_dcb->p_scb) {
347 BTIF_TRACE_DEBUG("app_idx=%d mcl_idx=0x%x mdl_idx=0x%x data_size=%d",
348 app_idx, mcl_idx, mdl_idx, data_size);
349 ssize_t r;
350 OSI_NO_INTR(
351 r = send(p_dcb->p_scb->socket_id[1], p_dcb->p_rx_pkt, data_size, 0));
352 if (r == data_size) {
353 BTIF_TRACE_DEBUG("socket send success data_size=%d", data_size);
354 status = BTA_HL_STATUS_OK;
355 } else {
356 BTIF_TRACE_ERROR("socket send failed r=%d data_size=%d", r, data_size);
357 }
358 }
359 osi_free_and_reset((void**)&p_dcb->p_rx_pkt);
360 }
361
362 bta_hl_ci_put_rx_data(mdl_handle, status, evt);
363 }
364
365 /*******************************************************************************
366 *
367 * Function bta_hl_co_get_tx_data
368 *
369 * Description Get the Echo data to be sent
370 *
371 * Parameters app_id - HDP application ID
372 * mcl_handle - MCL handle
373 * buf_size - the size of the buffer
374 * p_buf - the buffer pointer
375 * evt - the evt to be passed back to the HL in the
376 * bta_hl_ci_get_tx_data call-in function
377 *
378 * Returns Void
379 *
380 ******************************************************************************/
bta_hl_co_get_echo_data(UNUSED_ATTR uint8_t app_id,tBTA_HL_MCL_HANDLE mcl_handle,UNUSED_ATTR uint16_t buf_size,UNUSED_ATTR uint8_t * p_buf,uint16_t evt)381 void bta_hl_co_get_echo_data(UNUSED_ATTR uint8_t app_id,
382 tBTA_HL_MCL_HANDLE mcl_handle,
383 UNUSED_ATTR uint16_t buf_size,
384 UNUSED_ATTR uint8_t* p_buf, uint16_t evt) {
385 tBTA_HL_STATUS status = BTA_HL_STATUS_FAIL;
386
387 BTIF_TRACE_ERROR("%s not supported", __func__);
388 bta_hl_ci_get_echo_data(mcl_handle, status, evt);
389 }
390
391 /*******************************************************************************
392 *
393 * Function bta_hl_co_put_echo_data
394 *
395 * Description Put the received loopback echo data
396 *
397 * Parameters app_id - HDP application ID
398 * mcl_handle - MCL handle
399 * data_size - the size of the data
400 * p_data - the data pointer
401 * evt - the evt to be passed back to the HL in the
402 * bta_hl_ci_put_echo_data call-in function
403 *
404 * Returns Void
405 *
406 ******************************************************************************/
bta_hl_co_put_echo_data(UNUSED_ATTR uint8_t app_id,tBTA_HL_MCL_HANDLE mcl_handle,UNUSED_ATTR uint16_t data_size,UNUSED_ATTR uint8_t * p_data,uint16_t evt)407 void bta_hl_co_put_echo_data(UNUSED_ATTR uint8_t app_id,
408 tBTA_HL_MCL_HANDLE mcl_handle,
409 UNUSED_ATTR uint16_t data_size,
410 UNUSED_ATTR uint8_t* p_data, uint16_t evt) {
411 tBTA_HL_STATUS status = BTA_HL_STATUS_FAIL;
412
413 BTIF_TRACE_ERROR("%s not supported", __func__);
414 bta_hl_ci_put_echo_data(mcl_handle, status, evt);
415 }
416