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