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*******************************************************************************/
71BOOLEAN 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*******************************************************************************/
101BOOLEAN 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*******************************************************************************/
133BOOLEAN 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*******************************************************************************/
177BOOLEAN 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*******************************************************************************/
218void 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*******************************************************************************/
244void 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*******************************************************************************/
271BOOLEAN 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*******************************************************************************/
321void 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*******************************************************************************/
366void 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*******************************************************************************/
418void 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*******************************************************************************/
447void 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