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 of the API for the HeaLth device profile (HL)
22 *  subsystem of BTA, Broadcom Corp's Bluetooth application layer for mobile
23 *  phones.
24 *
25 ******************************************************************************/
26
27#include <string.h>
28
29#include "bt_target.h"
30#if defined(HL_INCLUDED) && (HL_INCLUDED == TRUE)
31
32#include "gki.h"
33#include "bd.h"
34#include "bta_hl_api.h"
35#include "bta_hl_int.h"
36
37/*****************************************************************************
38**  Constants
39*****************************************************************************/
40
41static const tBTA_SYS_REG bta_hl_reg =
42{
43    bta_hl_hdl_event,
44    BTA_HlDisable
45};
46
47/*******************************************************************************
48**
49** Function         BTA_HlEnable
50**
51** Description      Enable the HL subsystems.  This function must be
52**                  called before any other functions in the HL API are called.
53**                  When the enable operation is completed the callback function
54**                  will be called with an BTA_HL_CTRL_ENABLE_CFM_EVT event.
55**
56** Parameters       p_cback - HL event call back function
57**
58** Returns          void
59**
60*******************************************************************************/
61void BTA_HlEnable(tBTA_HL_CTRL_CBACK *p_ctrl_cback)
62{
63    tBTA_HL_API_ENABLE *p_buf;
64
65    /* register with BTA system manager */
66    GKI_sched_lock();
67    bta_sys_register(BTA_ID_HL, &bta_hl_reg);
68    GKI_sched_unlock();
69
70    if ((p_buf = (tBTA_HL_API_ENABLE *)GKI_getbuf(sizeof(tBTA_HL_API_ENABLE))) != NULL)
71    {
72        p_buf->hdr.event    = BTA_HL_API_ENABLE_EVT;
73        p_buf->p_cback      = p_ctrl_cback;
74        bta_sys_sendmsg(p_buf);
75    }
76}
77
78/*******************************************************************************
79**
80** Function         BTA_HlDisable
81**
82** Description     Disable the HL subsystem.
83**
84** Returns          void
85**
86*******************************************************************************/
87void BTA_HlDisable(void)
88{
89    BT_HDR  *p_buf;
90
91    bta_sys_deregister(BTA_ID_HL);
92    if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR))) != NULL)
93    {
94        p_buf->event = BTA_HL_API_DISABLE_EVT;
95        bta_sys_sendmsg(p_buf);
96    }
97}
98
99/*******************************************************************************
100**
101** Function         BTA_HlUpdate
102**
103** Description      Register an HDP application
104**
105** Parameters       app_id        - Application ID
106**                  p_reg_param   - non-platform related parameters for the
107**                                  HDP application
108**                  p_cback       - HL event callback fucntion
109**
110** Returns          void
111**
112*******************************************************************************/
113void BTA_HlUpdate(UINT8  app_id,
114                    tBTA_HL_REG_PARAM *p_reg_param, BOOLEAN is_register,
115                    tBTA_HL_CBACK *p_cback)
116{
117    tBTA_HL_API_UPDATE *p_buf;
118
119    APPL_TRACE_DEBUG0("BTA_HlUpdate");
120    if (is_register)
121    {
122
123        if ((p_buf = (tBTA_HL_API_UPDATE *)GKI_getbuf((UINT16)sizeof(tBTA_HL_API_UPDATE))) != NULL)
124        {
125            p_buf->hdr.event    = BTA_HL_API_UPDATE_EVT;
126            p_buf->app_id       = app_id;
127            p_buf->sec_mask     = (p_reg_param->sec_mask | BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
128            p_buf->p_cback = p_cback;
129            p_buf->is_register = is_register;
130            if (p_reg_param->p_srv_name)
131            {
132                BCM_STRNCPY_S(p_buf->srv_name, sizeof(p_buf->srv_name),
133                              p_reg_param->p_srv_name, BTA_SERVICE_NAME_LEN);
134                p_buf->srv_name[BTA_SERVICE_NAME_LEN] = '\0';
135            }
136            else
137                p_buf->srv_name[0]= '\0';
138
139            if (p_reg_param->p_srv_desp)
140            {
141                BCM_STRNCPY_S(p_buf->srv_desp, sizeof(p_buf->srv_desp),
142                              p_reg_param->p_srv_desp, BTA_SERVICE_DESP_LEN);
143                p_buf->srv_desp[BTA_SERVICE_DESP_LEN]= '\0';
144            }
145            else
146                p_buf->srv_desp[0]= '\0';
147
148            if (p_reg_param->p_provider_name)
149            {
150                BCM_STRNCPY_S(p_buf->provider_name, sizeof(p_buf->provider_name),
151                              p_reg_param->p_provider_name, BTA_PROVIDER_NAME_LEN);
152                p_buf->provider_name[BTA_PROVIDER_NAME_LEN]= '\0';
153            }
154            else
155                p_buf->provider_name[0]= '\0';
156
157            bta_sys_sendmsg(p_buf);
158        }
159    }
160    else
161    {
162        if ((p_buf = (tBTA_HL_API_UPDATE *)GKI_getbuf((UINT16)sizeof(tBTA_HL_API_UPDATE))) != NULL)
163        {
164            p_buf->hdr.event    = BTA_HL_API_UPDATE_EVT;
165            p_buf->app_id       = app_id;
166            p_buf->is_register = is_register;
167            bta_sys_sendmsg(p_buf);
168        }
169
170    }
171}
172
173/*******************************************************************************
174**
175** Function         BTA_HlRegister
176**
177** Description      Register an HDP application
178**
179** Parameters       app_id        - Application ID
180**                  p_reg_param   - non-platform related parameters for the
181**                                  HDP application
182**                  p_cback       - HL event callback fucntion
183**
184** Returns          void
185**
186*******************************************************************************/
187void BTA_HlRegister(UINT8  app_id,
188                    tBTA_HL_REG_PARAM *p_reg_param,
189                    tBTA_HL_CBACK *p_cback)
190{
191    tBTA_HL_API_REGISTER *p_buf;
192
193    if ((p_buf = (tBTA_HL_API_REGISTER *)GKI_getbuf((UINT16)sizeof(tBTA_HL_API_REGISTER))) != NULL)
194    {
195        p_buf->hdr.event    = BTA_HL_API_REGISTER_EVT;
196        p_buf->app_id       = app_id;
197        p_buf->sec_mask     = (p_reg_param->sec_mask | BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
198        p_buf->p_cback = p_cback;
199        if (p_reg_param->p_srv_name)
200        {
201            BCM_STRNCPY_S(p_buf->srv_name, sizeof(p_buf->srv_name),
202                          p_reg_param->p_srv_name, BTA_SERVICE_NAME_LEN);
203            p_buf->srv_name[BTA_SERVICE_NAME_LEN] = '\0';
204        }
205        else
206            p_buf->srv_name[0]= '\0';
207
208        if (p_reg_param->p_srv_desp)
209        {
210            BCM_STRNCPY_S(p_buf->srv_desp, sizeof(p_buf->srv_desp),
211                          p_reg_param->p_srv_desp, BTA_SERVICE_DESP_LEN);
212            p_buf->srv_desp[BTA_SERVICE_DESP_LEN]= '\0';
213        }
214        else
215            p_buf->srv_desp[0]= '\0';
216
217        if (p_reg_param->p_provider_name)
218        {
219            BCM_STRNCPY_S(p_buf->provider_name, sizeof(p_buf->provider_name),
220                          p_reg_param->p_provider_name, BTA_PROVIDER_NAME_LEN);
221            p_buf->provider_name[BTA_PROVIDER_NAME_LEN]= '\0';
222        }
223        else
224            p_buf->provider_name[0]= '\0';
225
226        bta_sys_sendmsg(p_buf);
227    }
228}
229
230/*******************************************************************************
231**
232** Function         BTA_HlDeregister
233**
234** Description      Deregister an HDP application
235**
236** Parameters       app_handle - Application handle
237**
238** Returns           void
239**
240*******************************************************************************/
241void BTA_HlDeregister(UINT8 app_id,tBTA_HL_APP_HANDLE app_handle)
242{
243    tBTA_HL_API_DEREGISTER  *p_buf;
244
245    if ((p_buf = (tBTA_HL_API_DEREGISTER *)GKI_getbuf((UINT16)(sizeof(tBTA_HL_API_DEREGISTER)))) != NULL)
246    {
247        p_buf->hdr.event   = BTA_HL_API_DEREGISTER_EVT;
248        p_buf->app_id      = app_id;
249        p_buf->app_handle  = app_handle;
250        bta_sys_sendmsg(p_buf);
251    }
252}
253/*******************************************************************************
254**
255** Function         BTA_HlCchOpen
256**
257** Description      Open a Control channel connection with the specified BD address
258**
259** Parameters       app_handle - Application Handle
260**                  p_open_param - parameters for opening a control channel
261**
262** Returns          void
263**
264**                  Note: The control PSM value is used to select which
265**                  HDP insatnce should be used in case the peer device support
266**                  multiple HDP instances. Also, if the control PSM value is zero
267**                  then the first HDP instance is used for the control channel setup
268*******************************************************************************/
269void BTA_HlCchOpen(UINT8 app_id, tBTA_HL_APP_HANDLE app_handle,
270                   tBTA_HL_CCH_OPEN_PARAM *p_open_param)
271{
272    tBTA_HL_API_CCH_OPEN *p_buf;
273
274    if ((p_buf = (tBTA_HL_API_CCH_OPEN *)GKI_getbuf((UINT16)(sizeof(tBTA_HL_API_CCH_OPEN)))) != NULL)
275    {
276        p_buf->hdr.event        = BTA_HL_API_CCH_OPEN_EVT;
277        p_buf->app_id           = app_id;
278        p_buf->app_handle       = app_handle;
279        p_buf->sec_mask = (p_open_param->sec_mask | BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
280        bdcpy(p_buf->bd_addr, p_open_param->bd_addr);
281        p_buf->ctrl_psm       = p_open_param->ctrl_psm;
282        bta_sys_sendmsg(p_buf);
283    }
284}
285
286/*******************************************************************************
287**
288** Function         BTA_HlCchClose
289**
290** Description      Close a Control channel connection with the specified MCL
291**                  handle
292**
293** Parameters       mcl_handle - MCL handle
294**
295** Returns          void
296**
297*******************************************************************************/
298void BTA_HlCchClose(tBTA_HL_MCL_HANDLE mcl_handle)
299{
300    tBTA_HL_API_CCH_CLOSE *p_buf;
301
302    if ((p_buf = (tBTA_HL_API_CCH_CLOSE *)GKI_getbuf((UINT16)(sizeof(tBTA_HL_API_CCH_CLOSE)))) != NULL)
303    {
304        p_buf->hdr.event        = BTA_HL_API_CCH_CLOSE_EVT;
305        p_buf->mcl_handle       = mcl_handle;
306        bta_sys_sendmsg(p_buf);
307    }
308}
309
310/*******************************************************************************
311**
312** Function         BTA_HlDchOpen
313**
314** Description      Open a data channel connection with the specified DCH parameters
315**
316** Parameters       mcl_handle - MCL handle
317**                  p_open_param - parameters for opening a data channel
318**
319** Returns          void
320**
321*******************************************************************************/
322void BTA_HlDchOpen(tBTA_HL_MCL_HANDLE mcl_handle,
323                   tBTA_HL_DCH_OPEN_PARAM *p_open_param)
324{
325    tBTA_HL_API_DCH_OPEN *p_buf;
326
327    if ((p_buf = (tBTA_HL_API_DCH_OPEN *)GKI_getbuf((UINT16)(sizeof(tBTA_HL_API_DCH_OPEN)))) != NULL)
328    {
329        p_buf->hdr.event            = BTA_HL_API_DCH_OPEN_EVT;
330        p_buf->mcl_handle           = mcl_handle;
331        p_buf->ctrl_psm             = p_open_param->ctrl_psm;
332        p_buf->local_mdep_id        = p_open_param->local_mdep_id;
333        p_buf->peer_mdep_id         = p_open_param->peer_mdep_id;
334        p_buf->local_cfg            = p_open_param->local_cfg;
335        p_buf->sec_mask             = (p_open_param->sec_mask | BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
336        bta_sys_sendmsg(p_buf);
337    }
338}
339
340/*******************************************************************************
341**
342** Function         BTA_HlDchReconnect
343**
344** Description      Reconnect a data channel with the specified MDL_ID
345**
346** Parameters       mcl_handle      - MCL handle
347*8                  p_recon_param   - parameters for reconnecting a data channel
348**
349** Returns          void
350**
351*******************************************************************************/
352void BTA_HlDchReconnect(tBTA_HL_MCL_HANDLE mcl_handle,
353                        tBTA_HL_DCH_RECONNECT_PARAM *p_recon_param)
354{
355    tBTA_HL_API_DCH_RECONNECT *p_buf;
356
357    if ((p_buf = (tBTA_HL_API_DCH_RECONNECT *)GKI_getbuf((UINT16)(sizeof(tBTA_HL_API_DCH_RECONNECT)))) != NULL)
358    {
359        p_buf->hdr.event        = BTA_HL_API_DCH_RECONNECT_EVT;
360        p_buf->mcl_handle       = mcl_handle;
361        p_buf->ctrl_psm         = p_recon_param->ctrl_psm;
362        p_buf->mdl_id           = p_recon_param->mdl_id;
363        bta_sys_sendmsg(p_buf);
364    }
365}
366
367/*******************************************************************************
368**
369** Function         BTA_HlDchClose
370**
371** Description      Close a data channel with the specified MDL handle
372**
373** Parameters       mdl_handle  - MDL handle
374**
375** Returns          void
376**
377*******************************************************************************/
378void BTA_HlDchClose(tBTA_HL_MDL_HANDLE mdl_handle)
379{
380    tBTA_HL_API_DCH_CLOSE *p_buf;
381
382    if ((p_buf = (tBTA_HL_API_DCH_CLOSE *)GKI_getbuf((UINT16)(sizeof(tBTA_HL_API_DCH_CLOSE)))) != NULL)
383    {
384        p_buf->hdr.event    = BTA_HL_API_DCH_CLOSE_EVT;
385        p_buf->mdl_handle   = mdl_handle;
386        bta_sys_sendmsg(p_buf);
387    }
388}
389
390/*******************************************************************************
391**
392** Function         BTA_HlDchAbort
393**
394** Description      Abort the current data channel setup with the specified MCL
395**                  handle
396**
397** Parameters       mcl_handle  - MCL handle
398**
399**
400** Returns          void
401**
402*******************************************************************************/
403void BTA_HlDchAbort(tBTA_HL_MCL_HANDLE mcl_handle)
404{
405    tBTA_HL_API_DCH_ABORT *p_buf;
406
407    if ((p_buf = (tBTA_HL_API_DCH_ABORT *)GKI_getbuf((UINT16)(sizeof(tBTA_HL_API_DCH_ABORT)))) != NULL)
408    {
409        p_buf->hdr.event        = BTA_HL_API_DCH_ABORT_EVT;
410        p_buf->mcl_handle       = mcl_handle;
411        bta_sys_sendmsg(p_buf);
412    }
413}
414
415/*******************************************************************************
416**
417** Function         BTA_HlSendData
418**
419** Description      Send an APDU to the peer device
420**
421** Parameters       mdl_handle  - MDL handle
422**                  pkt_size    - size of the data packet to be sent
423**
424** Returns          void
425**
426*******************************************************************************/
427void BTA_HlSendData(tBTA_HL_MDL_HANDLE mdl_handle,
428                    UINT16           pkt_size)
429{
430    tBTA_HL_API_SEND_DATA *p_buf = NULL;
431
432    if ((p_buf = (tBTA_HL_API_SEND_DATA *)GKI_getbuf((UINT16)(sizeof(tBTA_HL_API_SEND_DATA)))) != NULL)
433    {
434        p_buf->hdr.event        = BTA_HL_API_SEND_DATA_EVT;
435        p_buf->mdl_handle       = mdl_handle;
436        p_buf->pkt_size         = pkt_size;
437        bta_sys_sendmsg(p_buf);
438    }
439
440}
441
442/*******************************************************************************
443**
444** Function         BTA_HlDeleteMdl
445**
446** Description      Delete the specified MDL_ID within the specified MCL handle
447**
448** Parameters       mcl_handle  - MCL handle
449**                  mdl_id      - MDL ID
450**
451** Returns          void
452**
453**                  note: If mdl_id = 0xFFFF then this means to delete all MDLs
454**                        and this value can only be used with DeleteMdl request only
455**                        not other requests
456**
457*******************************************************************************/
458void BTA_HlDeleteMdl(tBTA_HL_MCL_HANDLE mcl_handle,
459                     tBTA_HL_MDL_ID mdl_id )
460{
461    tBTA_HL_API_DELETE_MDL *p_buf;
462
463    if ((p_buf = (tBTA_HL_API_DELETE_MDL *)GKI_getbuf((UINT16)(sizeof(tBTA_HL_API_DELETE_MDL)))) != NULL)
464    {
465        p_buf->hdr.event        = BTA_HL_API_DELETE_MDL_EVT;
466        p_buf->mcl_handle       = mcl_handle;
467        p_buf->mdl_id           = mdl_id;
468        bta_sys_sendmsg(p_buf);
469    }
470}
471
472/*******************************************************************************
473**
474** Function         BTA_HlDchEchoTest
475**
476** Description      Initiate an echo test with the specified MCL handle
477**
478** Parameters       mcl_handle           - MCL handle
479*8                  p_echo_test_param   -  parameters for echo testing
480**
481** Returns          void
482**
483*******************************************************************************/
484void BTA_HlDchEchoTest( tBTA_HL_MCL_HANDLE  mcl_handle,
485                        tBTA_HL_DCH_ECHO_TEST_PARAM *p_echo_test_param)
486{
487    tBTA_HL_API_DCH_ECHO_TEST   *p_buf;
488
489    if ((p_buf = (tBTA_HL_API_DCH_ECHO_TEST *)GKI_getbuf((UINT16)(sizeof(tBTA_HL_API_DCH_ECHO_TEST)))) != NULL)
490    {
491        p_buf->hdr.event     = BTA_HL_API_DCH_ECHO_TEST_EVT;
492        p_buf->mcl_handle    = mcl_handle;
493        p_buf->ctrl_psm      = p_echo_test_param->ctrl_psm;
494        p_buf->local_cfg     = p_echo_test_param->local_cfg;
495        p_buf->pkt_size      = p_echo_test_param->pkt_size;
496        bta_sys_sendmsg(p_buf);
497    }
498}
499
500
501/*******************************************************************************
502**
503** Function         BTA_HlSdpQuery
504**
505** Description      SDP query request for the specified BD address
506**
507** Parameters       app_handle      - application handle
508**                  bd_addr         - BD address
509**
510** Returns          void
511**
512*******************************************************************************/
513void BTA_HlSdpQuery(UINT8  app_id,tBTA_HL_APP_HANDLE app_handle,
514                    BD_ADDR bd_addr)
515{
516    tBTA_HL_API_SDP_QUERY *p_buf;
517
518    if ((p_buf = (tBTA_HL_API_SDP_QUERY *)GKI_getbuf((UINT16)(sizeof(tBTA_HL_API_SDP_QUERY)))) != NULL)
519    {
520        p_buf->hdr.event        = BTA_HL_API_SDP_QUERY_EVT;
521        p_buf->app_id           = app_id;
522        p_buf->app_handle       = app_handle;
523        bdcpy(p_buf->bd_addr, bd_addr);
524        bta_sys_sendmsg(p_buf);
525    }
526}
527
528
529/*******************************************************************************
530**
531** Function         BTA_HlDchCreateMdlRsp
532**
533** Description      Set the Response and configuration values for the Create MDL
534**                  request
535**
536** Parameters       mcl_handle  - MCL handle
537**                  p_rsp_param - parameters specified whether the request should
538**                                be accepted or not and if it should be accepted
539**                                then it also specified the configuration response
540**                                value
541**
542** Returns          void
543**
544*******************************************************************************/
545void BTA_HlDchCreateRsp(tBTA_HL_MCL_HANDLE mcl_handle,
546                        tBTA_HL_DCH_CREATE_RSP_PARAM *p_rsp_param)
547{
548    tBTA_HL_API_DCH_CREATE_RSP *p_buf;
549
550    if ((p_buf = (tBTA_HL_API_DCH_CREATE_RSP *)GKI_getbuf((UINT16)(sizeof(tBTA_HL_API_DCH_CREATE_RSP)))) != NULL)
551    {
552        p_buf->hdr.event        = BTA_HL_API_DCH_CREATE_RSP_EVT;
553        p_buf->mcl_handle       = mcl_handle;
554        p_buf->mdl_id           = p_rsp_param->mdl_id;
555        p_buf->local_mdep_id    = p_rsp_param->local_mdep_id;
556        p_buf->rsp_code         = p_rsp_param->rsp_code;
557        p_buf->cfg_rsp          = p_rsp_param->cfg_rsp;
558        bta_sys_sendmsg(p_buf);
559    }
560}
561
562#endif /* HL_INCLUDED */
563