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