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 "bta_hf_client_api.h"
28 #include "bta_hf_client_int.h"
29 #include "bta_dm_int.h"
30 #include "l2c_api.h"
31 #include "port_api.h"
32 #include "bta_sys.h"
33 #include "utl.h"
34 #include "bt_utils.h"
35 #include "osi/include/compat.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, BT_TRANSPORT_BR_EDR);
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 BD_ADDR dev_addr;
268 int status;
269
270 /* set role */
271 bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
272
273 APPL_TRACE_DEBUG ("bta_hf_client_rfc_acp_open: serv_handle = %d rfc.port_handle = %d",
274 bta_hf_client_cb.scb.serv_handle, p_data->rfc.port_handle);
275
276 /* get bd addr of peer */
277 if (PORT_SUCCESS != (status=PORT_CheckConnection(p_data->rfc.port_handle, dev_addr, &lcid)))
278 {
279 APPL_TRACE_DEBUG ("bta_hf_client_rfc_acp_open error PORT_CheckConnection returned status %d", status);
280 }
281
282 /* Collision Handling */
283 if (bta_hf_client_cb.scb.colli_tmr_on)
284 {
285 /* stop collision timer */
286 bta_hf_client_cb.scb.colli_tmr_on = FALSE;
287 bta_sys_stop_timer (&bta_hf_client_cb.scb.colli_timer);
288
289 if (bdcmp (dev_addr, bta_hf_client_cb.scb.peer_addr) == 0)
290 {
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 }
294 else
295 {
296 /* Resume outgoing connection. */
297 bta_hf_client_resume_open ();
298 }
299 }
300
301 bdcpy (bta_hf_client_cb.scb.peer_addr, dev_addr);
302 bta_hf_client_cb.scb.conn_handle = p_data->rfc.port_handle;
303
304 /* do service discovery to get features */
305 bta_hf_client_do_disc();
306
307 /* continue with open processing */
308 bta_hf_client_rfc_open(p_data);
309 }
310
311 /*******************************************************************************
312 **
313 ** Function bta_hf_client_rfc_fail
314 **
315 ** Description RFCOMM connection failed.
316 **
317 **
318 ** Returns void
319 **
320 *******************************************************************************/
bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA * p_data)321 void bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA *p_data)
322 {
323 UNUSED(p_data);
324
325 /* reinitialize stuff */
326 bta_hf_client_cb.scb.conn_handle = 0;
327 bta_hf_client_cb.scb.peer_features = 0;
328 bta_hf_client_cb.scb.chld_features = 0;
329 bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
330 bta_hf_client_cb.scb.svc_conn = FALSE;
331 bta_hf_client_cb.scb.send_at_reply = FALSE;
332 bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
333
334 bta_hf_client_at_reset();
335
336 /* reopen server */
337 bta_hf_client_start_server();
338
339 /* call open cback w. failure */
340 bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_FAIL_RFCOMM);
341 }
342
343 /*******************************************************************************
344 **
345 ** Function bta_hf_client_disc_fail
346 **
347 ** Description This function handles a discovery failure.
348 **
349 **
350 ** Returns void
351 **
352 *******************************************************************************/
bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA * p_data)353 void bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA *p_data)
354 {
355 UNUSED(p_data);
356
357 /* reopen server */
358 bta_hf_client_start_server();
359
360 /* reinitialize stuff */
361
362 /* call open cback w. failure */
363 bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_FAIL_SDP);
364 }
365
366 /*******************************************************************************
367 **
368 ** Function bta_hf_client_open_fail
369 **
370 ** Description open connection failed.
371 **
372 **
373 ** Returns void
374 **
375 *******************************************************************************/
bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA * p_data)376 void bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA *p_data)
377 {
378 /* call open cback w. failure */
379 bta_hf_client_cback_open(p_data, BTA_HF_CLIENT_FAIL_RESOURCES);
380 }
381
382 /*******************************************************************************
383 **
384 ** Function bta_hf_client_rfc_close
385 **
386 ** Description RFCOMM connection closed.
387 **
388 **
389 ** Returns void
390 **
391 *******************************************************************************/
bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA * p_data)392 void bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA *p_data)
393 {
394 UNUSED(p_data);
395
396 /* reinitialize stuff */
397 bta_hf_client_cb.scb.peer_features = 0;
398 bta_hf_client_cb.scb.chld_features = 0;
399 bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
400 bta_hf_client_cb.scb.svc_conn = FALSE;
401 bta_hf_client_cb.scb.send_at_reply = FALSE;
402 bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
403
404 bta_hf_client_at_reset();
405
406 bta_sys_conn_close(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
407
408 /* call close cback */
409 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLOSE_EVT, NULL);
410
411 /* if not deregistering reopen server */
412 if (bta_hf_client_cb.scb.deregister == FALSE)
413 {
414 /* Clear peer bd_addr so instance can be reused */
415 bdcpy(bta_hf_client_cb.scb.peer_addr, bd_addr_null);
416
417 /* start server as it might got closed on open*/
418 bta_hf_client_start_server();
419
420 bta_hf_client_cb.scb.conn_handle = 0;
421
422 /* Make sure SCO is shutdown */
423 bta_hf_client_sco_shutdown(NULL);
424
425 bta_sys_sco_unuse(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
426 }
427 /* else close port and deallocate scb */
428 else
429 {
430 bta_hf_client_close_server();
431 bta_hf_client_scb_disable();
432 }
433 }
434
435 /*******************************************************************************
436 **
437 ** Function bta_hf_client_disc_int_res
438 **
439 ** Description This function handles a discovery result when initiator.
440 **
441 **
442 ** Returns void
443 **
444 *******************************************************************************/
bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA * p_data)445 void bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA *p_data)
446 {
447 UINT16 event = BTA_HF_CLIENT_DISC_FAIL_EVT;
448
449 APPL_TRACE_DEBUG ("bta_hf_client_disc_int_res: Status: %d", p_data->disc_result.status);
450
451 /* if found service */
452 if (p_data->disc_result.status == SDP_SUCCESS ||
453 p_data->disc_result.status == SDP_DB_FULL)
454 {
455 /* get attributes */
456 if (bta_hf_client_sdp_find_attr())
457 {
458 event = BTA_HF_CLIENT_DISC_OK_EVT;
459 }
460 }
461
462 /* free discovery db */
463 bta_hf_client_free_db(p_data);
464
465 /* send ourselves sdp ok/fail event */
466 bta_hf_client_sm_execute(event, p_data);
467 }
468
469 /*******************************************************************************
470 **
471 ** Function bta_hf_client_disc_acp_res
472 **
473 ** Description This function handles a discovery result when acceptor.
474 **
475 **
476 ** Returns void
477 **
478 *******************************************************************************/
bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA * p_data)479 void bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA *p_data)
480 {
481 /* if found service */
482 if (p_data->disc_result.status == SDP_SUCCESS ||
483 p_data->disc_result.status == SDP_DB_FULL)
484 {
485 /* get attributes */
486 bta_hf_client_sdp_find_attr();
487 }
488
489 /* free discovery db */
490 bta_hf_client_free_db(p_data);
491 }
492
493 /*******************************************************************************
494 **
495 ** Function bta_hf_client_rfc_data
496 **
497 ** Description Read and process data from RFCOMM.
498 **
499 **
500 ** Returns void
501 **
502 *******************************************************************************/
bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA * p_data)503 void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA *p_data)
504 {
505 UINT16 len;
506 char buf[BTA_HF_CLIENT_RFC_READ_MAX];
507 UNUSED(p_data);
508
509 memset(buf, 0, sizeof(buf));
510
511 /* read data from rfcomm; if bad status, we're done */
512 while (PORT_ReadData(bta_hf_client_cb.scb.conn_handle, buf, BTA_HF_CLIENT_RFC_READ_MAX, &len) == PORT_SUCCESS)
513 {
514 /* if no data, we're done */
515 if (len == 0)
516 {
517 break;
518 }
519
520 bta_hf_client_at_parse(buf, len);
521
522 /* no more data to read, we're done */
523 if (len < BTA_HF_CLIENT_RFC_READ_MAX)
524 {
525 break;
526 }
527 }
528 }
529
530 /*******************************************************************************
531 **
532 ** Function bta_hf_client_svc_conn_open
533 **
534 ** Description Service level connection opened
535 **
536 **
537 ** Returns void
538 **
539 *******************************************************************************/
bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA * p_data)540 void bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA *p_data)
541 {
542 tBTA_HF_CLIENT evt;
543 UNUSED(p_data);
544
545 memset(&evt, 0, sizeof(evt));
546
547 if (!bta_hf_client_cb.scb.svc_conn)
548 {
549 /* set state variable */
550 bta_hf_client_cb.scb.svc_conn = TRUE;
551
552 /* call callback */
553 evt.conn.peer_feat = bta_hf_client_cb.scb.peer_features;
554 evt.conn.chld_feat = bta_hf_client_cb.scb.chld_features;
555
556 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CONN_EVT, &evt);
557 }
558 }
559
560 /*******************************************************************************
561 **
562 ** Function bta_hf_client_cback_ind
563 **
564 ** Description Send indicator callback event to application.
565 **
566 ** Returns void
567 **
568 *******************************************************************************/
bta_hf_client_ind(tBTA_HF_CLIENT_IND_TYPE type,UINT16 value)569 void bta_hf_client_ind(tBTA_HF_CLIENT_IND_TYPE type, UINT16 value)
570 {
571 tBTA_HF_CLIENT evt;
572
573 memset(&evt, 0, sizeof(evt));
574
575 evt.ind.type = type;
576 evt.ind.value = value;
577
578 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_IND_EVT, &evt);
579 }
580
581 /*******************************************************************************
582 **
583 ** Function bta_hf_client_evt_val
584 **
585 ** Description Send event to application.
586 ** This is a generic helper for events with common data.
587 **
588 **
589 ** Returns void
590 **
591 *******************************************************************************/
bta_hf_client_evt_val(tBTA_HF_CLIENT_EVT type,UINT16 value)592 void bta_hf_client_evt_val(tBTA_HF_CLIENT_EVT type, UINT16 value)
593 {
594 tBTA_HF_CLIENT evt;
595
596 memset(&evt, 0, sizeof(evt));
597
598 evt.val.value = value;
599
600 (*bta_hf_client_cb.p_cback)(type, &evt);
601 }
602
603 /*******************************************************************************
604 **
605 ** Function bta_hf_client_operator_name
606 **
607 ** Description Send operator name event to application.
608 **
609 **
610 ** Returns void
611 **
612 *******************************************************************************/
bta_hf_client_operator_name(char * name)613 void bta_hf_client_operator_name(char *name)
614 {
615 tBTA_HF_CLIENT evt;
616
617 memset(&evt, 0, sizeof(evt));
618
619 strlcpy(evt.operator.name, name, BTA_HF_CLIENT_OPERATOR_NAME_LEN + 1);
620 evt.operator.name[BTA_HF_CLIENT_OPERATOR_NAME_LEN] = '\0';
621
622 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_OPERATOR_NAME_EVT, &evt);
623 }
624
625
626 /*******************************************************************************
627 **
628 ** Function bta_hf_client_clip
629 **
630 ** Description Send CLIP event to application.
631 **
632 **
633 ** Returns void
634 **
635 *******************************************************************************/
bta_hf_client_clip(char * number)636 void bta_hf_client_clip(char *number)
637 {
638 tBTA_HF_CLIENT evt;
639
640 memset(&evt, 0, sizeof(evt));
641
642 strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
643 evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
644
645 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLIP_EVT, &evt);
646 }
647
648 /*******************************************************************************
649 **
650 ** Function bta_hf_client_ccwa
651 **
652 ** Description Send CLIP event to application.
653 **
654 **
655 ** Returns void
656 **
657 *******************************************************************************/
bta_hf_client_ccwa(char * number)658 void bta_hf_client_ccwa(char *number)
659 {
660 tBTA_HF_CLIENT evt;
661
662 memset(&evt, 0, sizeof(evt));
663
664 strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
665 evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
666
667 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CCWA_EVT, &evt);
668 }
669
670 /*******************************************************************************
671 **
672 ** Function bta_hf_client_at_result
673 **
674 ** Description Send AT result event to application.
675 **
676 **
677 ** Returns void
678 **
679 *******************************************************************************/
bta_hf_client_at_result(tBTA_HF_CLIENT_AT_RESULT_TYPE type,UINT16 cme)680 void bta_hf_client_at_result(tBTA_HF_CLIENT_AT_RESULT_TYPE type, UINT16 cme)
681 {
682 tBTA_HF_CLIENT evt;
683
684 memset(&evt, 0, sizeof(evt));
685
686 evt.result.type = type;
687 evt.result.cme = cme;
688
689 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_AT_RESULT_EVT, &evt);
690 }
691
692 /*******************************************************************************
693 **
694 ** Function bta_hf_client_clcc
695 **
696 ** Description Send clcc event to application.
697 **
698 **
699 ** Returns void
700 **
701 *******************************************************************************/
bta_hf_client_clcc(UINT32 idx,BOOLEAN incoming,UINT8 status,BOOLEAN mpty,char * number)702 void bta_hf_client_clcc(UINT32 idx, BOOLEAN incoming, UINT8 status, BOOLEAN mpty, char *number)
703 {
704 tBTA_HF_CLIENT evt;
705
706 memset(&evt, 0, sizeof(evt));
707
708 evt.clcc.idx = idx;
709 evt.clcc.inc = incoming;
710 evt.clcc.status = status;
711 evt.clcc.mpty = mpty;
712
713 if (number)
714 {
715 evt.clcc.number_present = TRUE;
716 strlcpy(evt.clcc.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
717 evt.clcc.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
718 }
719
720 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLCC_EVT, &evt);
721 }
722
723 /*******************************************************************************
724 **
725 ** Function bta_hf_client_cnum
726 **
727 ** Description Send cnum event to application.
728 **
729 **
730 ** Returns void
731 **
732 *******************************************************************************/
bta_hf_client_cnum(char * number,UINT16 service)733 void bta_hf_client_cnum(char *number, UINT16 service)
734 {
735 tBTA_HF_CLIENT evt;
736
737 memset(&evt, 0, sizeof(evt));
738
739 evt.cnum.service = service;
740 strlcpy(evt.cnum.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
741 evt.cnum.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
742
743 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CNUM_EVT, &evt);
744 }
745
746 /*******************************************************************************
747 **
748 ** Function bta_hf_client_binp
749 **
750 ** Description Send BINP event to application.
751 **
752 **
753 ** Returns void
754 **
755 *******************************************************************************/
bta_hf_client_binp(char * number)756 void bta_hf_client_binp(char *number)
757 {
758 tBTA_HF_CLIENT evt;
759
760 memset(&evt, 0, sizeof(evt));
761
762 strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
763 evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
764
765 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_BINP_EVT, &evt);
766 }
767