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