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