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