• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (c) 2014 The Android Open Source Project
4  *  Copyright (C) 2003-2012 Broadcom Corporation
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at:
9  *
10  *  http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  *
18  ******************************************************************************/
19 
20 /******************************************************************************
21  *
22  *  This file contains action functions for the handsfree client.
23  *
24  ******************************************************************************/
25 
26 #include "bta_api.h"
27 #include "bd.h"
28 #include "bta_hf_client_api.h"
29 #include "bta_hf_client_int.h"
30 #include "bta_dm_int.h"
31 #include "l2c_api.h"
32 #include "port_api.h"
33 #include "bta_sys.h"
34 #include "utl.h"
35 #include "bt_utils.h"
36 #include <string.h>
37 
38 /*****************************************************************************
39 **  Constants
40 *****************************************************************************/
41 
42 /* maximum length of data to read from RFCOMM */
43 #define BTA_HF_CLIENT_RFC_READ_MAX     512
44 
45 /*******************************************************************************
46 **
47 ** Function         bta_hf_client_register
48 **
49 ** Description      This function initializes values of the scb and sets up
50 **                  the SDP record for the services.
51 **
52 **
53 ** Returns          void
54 **
55 *******************************************************************************/
bta_hf_client_register(tBTA_HF_CLIENT_DATA * p_data)56 void bta_hf_client_register(tBTA_HF_CLIENT_DATA *p_data)
57 {
58     tBTA_HF_CLIENT evt;
59     tBTA_UTL_COD   cod;
60 
61     memset(&evt, 0, sizeof(evt));
62 
63     /* initialize control block */
64     bta_hf_client_scb_init();
65 
66     bta_hf_client_cb.scb.serv_sec_mask = p_data->api_register.sec_mask;
67     bta_hf_client_cb.scb.features = p_data->api_register.features;
68 
69     /* initialize AT control block */
70     bta_hf_client_at_init();
71 
72     /* create SDP records */
73     bta_hf_client_create_record(p_data);
74 
75     /* Set the Audio service class bit */
76     cod.service = BTM_COD_SERVICE_AUDIO;
77     utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
78 
79     /* start RFCOMM server */
80     bta_hf_client_start_server();
81 
82     /* call app callback with register event */
83     evt.reg.status = BTA_HF_CLIENT_SUCCESS;
84     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_REGISTER_EVT, &evt);
85 }
86 
87 /*******************************************************************************
88 **
89 ** Function         bta_hf_client_deregister
90 **
91 ** Description      This function removes the sdp records, closes the RFCOMM
92 **                  servers, and deallocates the service control block.
93 **
94 **
95 ** Returns          void
96 **
97 *******************************************************************************/
bta_hf_client_deregister(tBTA_HF_CLIENT_DATA * p_data)98 void bta_hf_client_deregister(tBTA_HF_CLIENT_DATA *p_data)
99 {
100     bta_hf_client_cb.scb.deregister = TRUE;
101 
102     /* remove sdp record */
103     bta_hf_client_del_record(p_data);
104 
105     /* remove rfcomm server */
106     bta_hf_client_close_server();
107 
108     /* disable */
109     bta_hf_client_scb_disable();
110 }
111 
112 /*******************************************************************************
113 **
114 ** Function         bta_hf_client_start_dereg
115 **
116 ** Description      Start a deregister event.
117 **
118 **
119 ** Returns          void
120 **
121 *******************************************************************************/
bta_hf_client_start_dereg(tBTA_HF_CLIENT_DATA * p_data)122 void bta_hf_client_start_dereg(tBTA_HF_CLIENT_DATA *p_data)
123 {
124     bta_hf_client_cb.scb.deregister = TRUE;
125 
126     /* remove sdp record */
127     bta_hf_client_del_record(p_data);
128 }
129 
130 /*******************************************************************************
131 **
132 ** Function         bta_hf_client_start_close
133 **
134 ** Description      Start the process of closing SCO and RFCOMM connection.
135 **
136 **
137 ** Returns          void
138 **
139 *******************************************************************************/
bta_hf_client_start_close(tBTA_HF_CLIENT_DATA * p_data)140 void bta_hf_client_start_close(tBTA_HF_CLIENT_DATA *p_data)
141 {
142     /* Take the link out of sniff and set L2C idle time to 0 */
143     bta_dm_pm_active(bta_hf_client_cb.scb.peer_addr);
144     L2CA_SetIdleTimeoutByBdAddr(bta_hf_client_cb.scb.peer_addr, 0);
145 
146     /* if SCO is open close SCO and wait on RFCOMM close */
147     if (bta_hf_client_cb.scb.sco_state == BTA_HF_CLIENT_SCO_OPEN_ST)
148     {
149         bta_hf_client_cb.scb.sco_close_rfc = TRUE;
150     }
151     else
152     {
153         bta_hf_client_rfc_do_close(p_data);
154     }
155 
156     /* always do SCO shutdown to handle all SCO corner cases */
157     bta_hf_client_sco_shutdown(NULL);
158 }
159 
160 /*******************************************************************************
161 **
162 ** Function         bta_hf_client_start_open
163 **
164 ** Description      This starts an HF Client open.
165 **
166 **
167 ** Returns          void
168 **
169 *******************************************************************************/
bta_hf_client_start_open(tBTA_HF_CLIENT_DATA * p_data)170 void bta_hf_client_start_open(tBTA_HF_CLIENT_DATA *p_data)
171 {
172     BD_ADDR pending_bd_addr;
173 
174     /* store parameters */
175     if (p_data)
176     {
177         bdcpy(bta_hf_client_cb.scb.peer_addr, p_data->api_open.bd_addr);
178         bta_hf_client_cb.scb.cli_sec_mask = p_data->api_open.sec_mask;
179     }
180 
181     /* Check if RFCOMM has any incoming connection to avoid collision. */
182     if (PORT_IsOpening (pending_bd_addr))
183     {
184         /* Let the incoming connection goes through.                        */
185         /* Issue collision for now.                                         */
186         /* We will decide what to do when we find incoming connection later.*/
187         bta_hf_client_collision_cback (0, BTA_ID_HS, 0, bta_hf_client_cb.scb.peer_addr);
188         return;
189     }
190 
191     /* close server */
192     bta_hf_client_close_server();
193 
194     /* set role */
195     bta_hf_client_cb.scb.role = BTA_HF_CLIENT_INT;
196 
197     /* do service search */
198     bta_hf_client_do_disc();
199 }
200 
201 /*******************************************************************************
202 **
203 ** Function         bta_hf_client_cback_open
204 **
205 ** Description      Send open callback event to application.
206 **
207 **
208 ** Returns          void
209 **
210 *******************************************************************************/
bta_hf_client_cback_open(tBTA_HF_CLIENT_DATA * p_data,tBTA_HF_CLIENT_STATUS status)211 static void bta_hf_client_cback_open(tBTA_HF_CLIENT_DATA *p_data, tBTA_HF_CLIENT_STATUS status)
212 {
213     tBTA_HF_CLIENT evt;
214 
215     memset(&evt, 0, sizeof(evt));
216 
217     /* call app callback with open event */
218     evt.open.status = status;
219     if(p_data)
220     {
221         /* if p_data is provided then we need to pick the bd address from the open api structure */
222         bdcpy(evt.open.bd_addr, p_data->api_open.bd_addr);
223     }
224     else
225     {
226         bdcpy(evt.open.bd_addr, bta_hf_client_cb.scb.peer_addr);
227     }
228 
229     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_OPEN_EVT, &evt);
230 }
231 
232 /*******************************************************************************
233 **
234 ** Function         bta_hf_client_rfc_open
235 **
236 ** Description      Handle RFCOMM channel open.
237 **
238 **
239 ** Returns          void
240 **
241 *******************************************************************************/
bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA * p_data)242 void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA *p_data)
243 {
244     UNUSED(p_data);
245 
246     bta_sys_conn_open(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
247 
248     bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_SUCCESS);
249 
250     /* start SLC procedure */
251     bta_hf_client_slc_seq(FALSE);
252 }
253 
254 /*******************************************************************************
255 **
256 ** Function         bta_hf_client_rfc_acp_open
257 **
258 ** Description      Handle RFCOMM channel open when accepting connection.
259 **
260 **
261 ** Returns          void
262 **
263 *******************************************************************************/
bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA * p_data)264 void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA *p_data)
265 {
266     UINT16          lcid;
267     int             i;
268     BD_ADDR         dev_addr;
269     int             status;
270 
271     /* set role */
272     bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
273 
274     APPL_TRACE_DEBUG ("bta_hf_client_rfc_acp_open: serv_handle = %d rfc.port_handle = %d",
275             bta_hf_client_cb.scb.serv_handle, p_data->rfc.port_handle);
276 
277     /* get bd addr of peer */
278     if (PORT_SUCCESS != (status=PORT_CheckConnection(p_data->rfc.port_handle, dev_addr, &lcid)))
279     {
280         APPL_TRACE_DEBUG ("bta_hf_client_rfc_acp_open error PORT_CheckConnection returned status %d", status);
281     }
282 
283     /* Collision Handling */
284     if (bta_hf_client_cb.scb.colli_tmr_on)
285     {
286         /* stop collision timer */
287         bta_hf_client_cb.scb.colli_tmr_on = FALSE;
288         bta_sys_stop_timer (&bta_hf_client_cb.scb.colli_timer);
289 
290         if (bdcmp (dev_addr, bta_hf_client_cb.scb.peer_addr) == 0)
291         {
292             /* If incoming and outgoing device are same, nothing more to do.            */
293             /* Outgoing conn will be aborted because we have successful incoming conn.  */
294         }
295         else
296         {
297             /* Resume outgoing connection. */
298             bta_hf_client_resume_open ();
299         }
300     }
301 
302     bdcpy (bta_hf_client_cb.scb.peer_addr, dev_addr);
303     bta_hf_client_cb.scb.conn_handle = p_data->rfc.port_handle;
304 
305     /* do service discovery to get features */
306     bta_hf_client_do_disc();
307 
308     /* continue with open processing */
309     bta_hf_client_rfc_open(p_data);
310 }
311 
312 /*******************************************************************************
313 **
314 ** Function         bta_hf_client_rfc_fail
315 **
316 ** Description      RFCOMM connection failed.
317 **
318 **
319 ** Returns          void
320 **
321 *******************************************************************************/
bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA * p_data)322 void bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA *p_data)
323 {
324     UNUSED(p_data);
325 
326     /* reinitialize stuff */
327     bta_hf_client_cb.scb.conn_handle = 0;
328     bta_hf_client_cb.scb.peer_features = 0;
329     bta_hf_client_cb.scb.chld_features = 0;
330     bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
331     bta_hf_client_cb.scb.svc_conn = FALSE;
332     bta_hf_client_cb.scb.send_at_reply = FALSE;
333     bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
334 
335     bta_hf_client_at_reset();
336 
337     /* reopen server */
338     bta_hf_client_start_server();
339 
340     /* call open cback w. failure */
341     bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_FAIL_RFCOMM);
342 }
343 
344 /*******************************************************************************
345 **
346 ** Function         bta_hf_client_disc_fail
347 **
348 ** Description      This function handles a discovery failure.
349 **
350 **
351 ** Returns          void
352 **
353 *******************************************************************************/
bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA * p_data)354 void bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA *p_data)
355 {
356     UNUSED(p_data);
357 
358     /* reopen server */
359     bta_hf_client_start_server();
360 
361     /* reinitialize stuff */
362 
363     /* call open cback w. failure */
364     bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_FAIL_SDP);
365 }
366 
367 /*******************************************************************************
368 **
369 ** Function         bta_hf_client_open_fail
370 **
371 ** Description      open connection failed.
372 **
373 **
374 ** Returns          void
375 **
376 *******************************************************************************/
bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA * p_data)377 void bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA *p_data)
378 {
379     /* call open cback w. failure */
380     bta_hf_client_cback_open(p_data, BTA_HF_CLIENT_FAIL_RESOURCES);
381 }
382 
383 /*******************************************************************************
384 **
385 ** Function         bta_hf_client_rfc_close
386 **
387 ** Description      RFCOMM connection closed.
388 **
389 **
390 ** Returns          void
391 **
392 *******************************************************************************/
bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA * p_data)393 void bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA *p_data)
394 {
395     int i, num_active_conn = 0;
396     UNUSED(p_data);
397 
398     /* reinitialize stuff */
399     bta_hf_client_cb.scb.peer_features = 0;
400     bta_hf_client_cb.scb.chld_features = 0;
401     bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
402     bta_hf_client_cb.scb.svc_conn = FALSE;
403     bta_hf_client_cb.scb.send_at_reply = FALSE;
404     bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
405 
406     bta_hf_client_at_reset();
407 
408     bta_sys_conn_close(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
409 
410     /* call close cback */
411     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLOSE_EVT, NULL);
412 
413     /* if not deregistering reopen server */
414     if (bta_hf_client_cb.scb.deregister == FALSE)
415     {
416         /* Clear peer bd_addr so instance can be reused */
417         bdcpy(bta_hf_client_cb.scb.peer_addr, bd_addr_null);
418 
419         /* start server as it might got closed on open*/
420         bta_hf_client_start_server();
421 
422         bta_hf_client_cb.scb.conn_handle = 0;
423 
424         /* Make sure SCO is shutdown */
425         bta_hf_client_sco_shutdown(NULL);
426 
427         bta_sys_sco_unuse(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
428     }
429     /* else close port and deallocate scb */
430     else
431     {
432         bta_hf_client_close_server();
433         bta_hf_client_scb_disable();
434     }
435 }
436 
437 /*******************************************************************************
438 **
439 ** Function         bta_hf_client_disc_int_res
440 **
441 ** Description      This function handles a discovery result when initiator.
442 **
443 **
444 ** Returns          void
445 **
446 *******************************************************************************/
bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA * p_data)447 void bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA *p_data)
448 {
449     UINT16 event = BTA_HF_CLIENT_DISC_FAIL_EVT;
450 
451     APPL_TRACE_DEBUG ("bta_hf_client_disc_int_res: Status: %d", p_data->disc_result.status);
452 
453     /* if found service */
454     if (p_data->disc_result.status == SDP_SUCCESS ||
455         p_data->disc_result.status == SDP_DB_FULL)
456     {
457         /* get attributes */
458         if (bta_hf_client_sdp_find_attr())
459         {
460             event = BTA_HF_CLIENT_DISC_OK_EVT;
461         }
462     }
463 
464     /* free discovery db */
465     bta_hf_client_free_db(p_data);
466 
467     /* send ourselves sdp ok/fail event */
468     bta_hf_client_sm_execute(event, p_data);
469 }
470 
471 /*******************************************************************************
472 **
473 ** Function         bta_hf_client_disc_acp_res
474 **
475 ** Description      This function handles a discovery result when acceptor.
476 **
477 **
478 ** Returns          void
479 **
480 *******************************************************************************/
bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA * p_data)481 void bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA *p_data)
482 {
483     /* if found service */
484     if (p_data->disc_result.status == SDP_SUCCESS ||
485         p_data->disc_result.status == SDP_DB_FULL)
486     {
487         /* get attributes */
488         bta_hf_client_sdp_find_attr();
489     }
490 
491     /* free discovery db */
492     bta_hf_client_free_db(p_data);
493 }
494 
495 /*******************************************************************************
496 **
497 ** Function         bta_hf_client_rfc_data
498 **
499 ** Description      Read and process data from RFCOMM.
500 **
501 **
502 ** Returns          void
503 **
504 *******************************************************************************/
bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA * p_data)505 void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA *p_data)
506 {
507     UINT16  len;
508     char    buf[BTA_HF_CLIENT_RFC_READ_MAX];
509     UNUSED(p_data);
510 
511     memset(buf, 0, sizeof(buf));
512 
513     /* read data from rfcomm; if bad status, we're done */
514     while (PORT_ReadData(bta_hf_client_cb.scb.conn_handle, buf, BTA_HF_CLIENT_RFC_READ_MAX, &len) == PORT_SUCCESS)
515     {
516         /* if no data, we're done */
517         if (len == 0)
518         {
519             break;
520         }
521 
522         bta_hf_client_at_parse(buf, len);
523 
524         /* no more data to read, we're done */
525         if (len < BTA_HF_CLIENT_RFC_READ_MAX)
526         {
527             break;
528         }
529     }
530 }
531 
532 /*******************************************************************************
533 **
534 ** Function         bta_hf_client_svc_conn_open
535 **
536 ** Description      Service level connection opened
537 **
538 **
539 ** Returns          void
540 **
541 *******************************************************************************/
bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA * p_data)542 void bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA *p_data)
543 {
544     tBTA_HF_CLIENT evt;
545     UNUSED(p_data);
546 
547     memset(&evt, 0, sizeof(evt));
548 
549     if (!bta_hf_client_cb.scb.svc_conn)
550     {
551         /* set state variable */
552         bta_hf_client_cb.scb.svc_conn = TRUE;
553 
554         /* call callback */
555         evt.conn.peer_feat = bta_hf_client_cb.scb.peer_features;
556         evt.conn.chld_feat = bta_hf_client_cb.scb.chld_features;
557 
558         (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CONN_EVT, &evt);
559     }
560 }
561 
562 /*******************************************************************************
563 **
564 ** Function         bta_hf_client_cback_ind
565 **
566 ** Description      Send indicator callback event to application.
567 **
568 ** Returns          void
569 **
570 *******************************************************************************/
bta_hf_client_ind(tBTA_HF_CLIENT_IND_TYPE type,UINT16 value)571 void bta_hf_client_ind(tBTA_HF_CLIENT_IND_TYPE type, UINT16 value)
572 {
573     tBTA_HF_CLIENT evt;
574 
575     memset(&evt, 0, sizeof(evt));
576 
577     evt.ind.type = type;
578     evt.ind.value = value;
579 
580     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_IND_EVT, &evt);
581 }
582 
583 /*******************************************************************************
584 **
585 ** Function         bta_hf_client_evt_val
586 **
587 ** Description      Send event to application.
588 **                  This is a generic helper for events with common data.
589 **
590 **
591 ** Returns          void
592 **
593 *******************************************************************************/
bta_hf_client_evt_val(tBTA_HF_CLIENT_EVT type,UINT16 value)594 void bta_hf_client_evt_val(tBTA_HF_CLIENT_EVT type, UINT16 value)
595 {
596     tBTA_HF_CLIENT evt;
597 
598     memset(&evt, 0, sizeof(evt));
599 
600     evt.val.value = value;
601 
602     (*bta_hf_client_cb.p_cback)(type, &evt);
603 }
604 
605 /*******************************************************************************
606 **
607 ** Function         bta_hf_client_operator_name
608 **
609 ** Description      Send operator name event to application.
610 **
611 **
612 ** Returns          void
613 **
614 *******************************************************************************/
bta_hf_client_operator_name(char * name)615 void bta_hf_client_operator_name(char *name)
616 {
617     tBTA_HF_CLIENT evt;
618 
619     memset(&evt, 0, sizeof(evt));
620 
621     strlcpy(evt.operator.name, name, BTA_HF_CLIENT_OPERATOR_NAME_LEN + 1);
622     evt.operator.name[BTA_HF_CLIENT_OPERATOR_NAME_LEN] = '\0';
623 
624     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_OPERATOR_NAME_EVT, &evt);
625 }
626 
627 
628 /*******************************************************************************
629 **
630 ** Function         bta_hf_client_clip
631 **
632 ** Description      Send CLIP event to application.
633 **
634 **
635 ** Returns          void
636 **
637 *******************************************************************************/
bta_hf_client_clip(char * number)638 void bta_hf_client_clip(char *number)
639 {
640     tBTA_HF_CLIENT evt;
641 
642     memset(&evt, 0, sizeof(evt));
643 
644     strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
645     evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
646 
647     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLIP_EVT, &evt);
648 }
649 
650 /*******************************************************************************
651 **
652 ** Function         bta_hf_client_ccwa
653 **
654 ** Description      Send CLIP event to application.
655 **
656 **
657 ** Returns          void
658 **
659 *******************************************************************************/
bta_hf_client_ccwa(char * number)660 void bta_hf_client_ccwa(char *number)
661 {
662     tBTA_HF_CLIENT evt;
663 
664     memset(&evt, 0, sizeof(evt));
665 
666     strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
667     evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
668 
669     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CCWA_EVT, &evt);
670 }
671 
672 /*******************************************************************************
673 **
674 ** Function         bta_hf_client_at_result
675 **
676 ** Description      Send AT result event to application.
677 **
678 **
679 ** Returns          void
680 **
681 *******************************************************************************/
bta_hf_client_at_result(tBTA_HF_CLIENT_AT_RESULT_TYPE type,UINT16 cme)682 void bta_hf_client_at_result(tBTA_HF_CLIENT_AT_RESULT_TYPE type, UINT16 cme)
683 {
684     tBTA_HF_CLIENT evt;
685 
686     memset(&evt, 0, sizeof(evt));
687 
688     evt.result.type = type;
689     evt.result.cme = cme;
690 
691     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_AT_RESULT_EVT, &evt);
692 }
693 
694 /*******************************************************************************
695 **
696 ** Function         bta_hf_client_clcc
697 **
698 ** Description      Send clcc event to application.
699 **
700 **
701 ** Returns          void
702 **
703 *******************************************************************************/
bta_hf_client_clcc(UINT32 idx,BOOLEAN incoming,UINT8 status,BOOLEAN mpty,char * number)704 void bta_hf_client_clcc(UINT32 idx, BOOLEAN incoming, UINT8 status, BOOLEAN mpty, char *number)
705 {
706     tBTA_HF_CLIENT evt;
707 
708     memset(&evt, 0, sizeof(evt));
709 
710     evt.clcc.idx = idx;
711     evt.clcc.inc = incoming;
712     evt.clcc.status = status;
713     evt.clcc.mpty = mpty;
714 
715     if (number)
716     {
717         evt.clcc.number_present = TRUE;
718         strlcpy(evt.clcc.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
719         evt.clcc.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
720     }
721 
722     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLCC_EVT, &evt);
723 }
724 
725 /*******************************************************************************
726 **
727 ** Function         bta_hf_client_cnum
728 **
729 ** Description      Send cnum event to application.
730 **
731 **
732 ** Returns          void
733 **
734 *******************************************************************************/
bta_hf_client_cnum(char * number,UINT16 service)735 void bta_hf_client_cnum(char *number, UINT16 service)
736 {
737     tBTA_HF_CLIENT evt;
738 
739     memset(&evt, 0, sizeof(evt));
740 
741     evt.cnum.service = service;
742     strlcpy(evt.cnum.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
743     evt.cnum.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
744 
745     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CNUM_EVT, &evt);
746 }
747 
748 /*******************************************************************************
749 **
750 ** Function         bta_hf_client_binp
751 **
752 ** Description      Send BINP event to application.
753 **
754 **
755 ** Returns          void
756 **
757 *******************************************************************************/
bta_hf_client_binp(char * number)758 void bta_hf_client_binp(char *number)
759 {
760     tBTA_HF_CLIENT evt;
761 
762     memset(&evt, 0, sizeof(evt));
763 
764     strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
765     evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
766 
767     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_BINP_EVT, &evt);
768 }
769