2 * Copyright (C) 2014 Intel Corporation
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 #include <cutils/properties.h>
28 #include "ipc-common.h"
30 #include "hal-utils.h"
32 static const bthf_callbacks_t *cbs = NULL;
34 static bool interface_ready(void)
39 static void handle_conn_state(void *buf, uint16_t len, int fd)
41 struct hal_ev_handsfree_conn_state *ev = buf;
43 if (cbs->connection_state_cb)
44 cbs->connection_state_cb(ev->state,
45 (bt_bdaddr_t *) (ev->bdaddr));
48 static void handle_audio_state(void *buf, uint16_t len, int fd)
50 struct hal_ev_handsfree_audio_state *ev = buf;
52 if (cbs->audio_state_cb)
53 cbs->audio_state_cb(ev->state, (bt_bdaddr_t *) (ev->bdaddr));
56 static void handle_vr_state(void *buf, uint16_t len, int fd)
58 struct hal_ev_handsfree_vr_state *ev = buf;
61 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
62 cbs->vr_cmd_cb(ev->state, (bt_bdaddr_t *) (ev->bdaddr));
64 cbs->vr_cmd_cb(ev->state);
68 static void handle_answer(void *buf, uint16_t len, int fd)
70 if (cbs->answer_call_cmd_cb) {
71 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
72 struct hal_ev_handsfree_answer *ev = buf;
74 cbs->answer_call_cmd_cb((bt_bdaddr_t *) (ev->bdaddr));
76 cbs->answer_call_cmd_cb();
81 static void handle_hangup(void *buf, uint16_t len, int fd)
83 if (cbs->hangup_call_cmd_cb) {
84 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
85 struct hal_ev_handsfree_hangup *ev = buf;
87 cbs->hangup_call_cmd_cb((bt_bdaddr_t *) (ev->bdaddr));
89 cbs->hangup_call_cmd_cb();
94 static void handle_volume(void *buf, uint16_t len, int fd)
96 struct hal_ev_handsfree_volume *ev = buf;
98 if (cbs->volume_cmd_cb)
99 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
100 cbs->volume_cmd_cb(ev->type, ev->volume,
101 (bt_bdaddr_t *) (ev->bdaddr));
103 cbs->volume_cmd_cb(ev->type, ev->volume);
107 static void handle_dial(void *buf, uint16_t len, int fd)
109 struct hal_ev_handsfree_dial *ev = buf;
110 uint16_t num_len = ev->number_len;
113 if (len != sizeof(*ev) + num_len ||
114 (num_len != 0 && ev->number[num_len - 1] != '\0')) {
115 error("invalid dial event, aborting");
119 if (!cbs->dial_call_cmd_cb)
123 number = (char *) ev->number;
125 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
126 cbs->dial_call_cmd_cb(number, (bt_bdaddr_t *) (ev->bdaddr));
128 cbs->dial_call_cmd_cb(number);
132 static void handle_dtmf(void *buf, uint16_t len, int fd)
134 struct hal_ev_handsfree_dtmf *ev = buf;
136 if (cbs->dtmf_cmd_cb)
137 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
138 cbs->dtmf_cmd_cb(ev->tone, (bt_bdaddr_t *) (ev->bdaddr));
140 cbs->dtmf_cmd_cb(ev->tone);
144 static void handle_nrec(void *buf, uint16_t len, int fd)
146 struct hal_ev_handsfree_nrec *ev = buf;
148 if (cbs->nrec_cmd_cb)
149 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
150 cbs->nrec_cmd_cb(ev->nrec, (bt_bdaddr_t *) (ev->bdaddr));
152 cbs->nrec_cmd_cb(ev->nrec);
156 static void handle_wbs(void *buf, uint16_t len, int fd)
158 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
159 struct hal_ev_handsfree_wbs *ev = buf;
162 cbs->wbs_cb(ev->wbs, (bt_bdaddr_t *) (ev->bdaddr));
166 static void handle_chld(void *buf, uint16_t len, int fd)
168 struct hal_ev_handsfree_chld *ev = buf;
170 if (cbs->chld_cmd_cb)
171 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
172 cbs->chld_cmd_cb(ev->chld, (bt_bdaddr_t *) (ev->bdaddr));
174 cbs->chld_cmd_cb(ev->chld);
178 static void handle_cnum(void *buf, uint16_t len, int fd)
180 if (cbs->cnum_cmd_cb) {
181 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
182 struct hal_ev_handsfree_cnum *ev = buf;
184 cbs->cnum_cmd_cb((bt_bdaddr_t *) (ev->bdaddr));
186 cbs->cnum_cmd_cb(NULL);
191 static void handle_cind(void *buf, uint16_t len, int fd)
193 if (cbs->cind_cmd_cb) {
194 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
195 struct hal_ev_handsfree_cind *ev = buf;
197 cbs->cind_cmd_cb((bt_bdaddr_t *) (ev->bdaddr));
204 static void handle_cops(void *buf, uint16_t len, int fd)
206 if (cbs->cops_cmd_cb) {
207 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
208 struct hal_ev_handsfree_cops *ev = buf;
210 cbs->cops_cmd_cb((bt_bdaddr_t *) (ev->bdaddr));
217 static void handle_clcc(void *buf, uint16_t len, int fd)
219 if (cbs->clcc_cmd_cb) {
220 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
221 struct hal_ev_handsfree_clcc *ev = buf;
223 cbs->clcc_cmd_cb((bt_bdaddr_t *) (ev->bdaddr));
230 static void handle_unknown_at(void *buf, uint16_t len, int fd)
232 struct hal_ev_handsfree_unknown_at *ev = buf;
234 if (len != sizeof(*ev) + ev->len ||
235 (ev->len != 0 && ev->buf[ev->len - 1] != '\0')) {
236 error("invalid unknown command event, aborting");
240 if (cbs->unknown_at_cmd_cb)
241 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
242 cbs->unknown_at_cmd_cb((char *) ev->buf,
243 (bt_bdaddr_t *) (ev->bdaddr));
245 cbs->unknown_at_cmd_cb((char *) ev->buf);
249 static void handle_hsp_key_press(void *buf, uint16_t len, int fd)
251 if (cbs->key_pressed_cmd_cb) {
252 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
253 struct hal_ev_handsfree_hsp_key_press *ev = buf;
255 cbs->key_pressed_cmd_cb((bt_bdaddr_t *) (ev->bdaddr));
257 cbs->key_pressed_cmd_cb();
263 * handlers will be called from notification thread context,
264 * index in table equals to 'opcode - HAL_MINIMUM_EVENT'
266 static const struct hal_ipc_handler ev_handlers[] = {
267 /* HAL_EV_HANDSFREE_CONN_STATE */
268 { handle_conn_state, false,
269 sizeof(struct hal_ev_handsfree_conn_state) },
270 /* HAL_EV_HANDSFREE_AUDIO_STATE */
271 { handle_audio_state, false,
272 sizeof(struct hal_ev_handsfree_audio_state) },
273 /* HAL_EV_HANDSFREE_VR */
274 { handle_vr_state, false, sizeof(struct hal_ev_handsfree_vr_state) },
275 /* HAL_EV_HANDSFREE_ANSWER */
276 { handle_answer, false, sizeof(struct hal_ev_handsfree_answer) },
277 /* HAL_EV_HANDSFREE_HANGUP */
278 { handle_hangup, false, sizeof(struct hal_ev_handsfree_hangup) },
279 /* HAL_EV_HANDSFREE_VOLUME */
280 { handle_volume, false, sizeof(struct hal_ev_handsfree_volume) },
281 /* HAL_EV_HANDSFREE_DIAL */
282 { handle_dial, true, sizeof(struct hal_ev_handsfree_dial) },
283 /* HAL_EV_HANDSFREE_DTMF */
284 { handle_dtmf, false, sizeof(struct hal_ev_handsfree_dtmf) },
285 /* HAL_EV_HANDSFREE_NREC */
286 { handle_nrec, false, sizeof(struct hal_ev_handsfree_nrec) },
287 /* HAL_EV_HANDSFREE_CHLD */
288 { handle_chld, false, sizeof(struct hal_ev_handsfree_chld) },
289 /* HAL_EV_HANDSFREE_CNUM */
290 { handle_cnum, false, sizeof(struct hal_ev_handsfree_cnum) },
291 /* HAL_EV_HANDSFREE_CIND */
292 { handle_cind, false, sizeof(struct hal_ev_handsfree_cind) },
293 /* HAL_EV_HANDSFREE_COPS */
294 { handle_cops, false, sizeof(struct hal_ev_handsfree_cops) },
295 /* HAL_EV_HANDSFREE_CLCC */
296 { handle_clcc, false, sizeof(struct hal_ev_handsfree_clcc) },
297 /* HAL_EV_HANDSFREE_UNKNOWN_AT */
298 { handle_unknown_at, true, sizeof(struct hal_ev_handsfree_unknown_at) },
299 /* HAL_EV_HANDSFREE_HSP_KEY_PRESS */
300 { handle_hsp_key_press, false,
301 sizeof(struct hal_ev_handsfree_hsp_key_press) },
302 /* HAL_EV_HANDSFREE_WBS */
303 { handle_wbs, false, sizeof(struct hal_ev_handsfree_wbs) },
306 static uint8_t get_mode(void)
308 char value[PROPERTY_VALUE_MAX];
310 if (get_config("handsfree", value, NULL) > 0) {
311 if (!strcasecmp(value, "hfp"))
312 return HAL_MODE_HANDSFREE_HFP;
314 if (!strcasecmp(value, "hfp_wbs"))
315 return HAL_MODE_HANDSFREE_HFP_WBS;
318 return HAL_MODE_HANDSFREE_HSP_ONLY;
321 static bt_status_t init_real(bthf_callbacks_t *callbacks, int max_hf_clients)
323 struct hal_cmd_register_module cmd;
328 if (interface_ready())
329 return BT_STATUS_DONE;
333 hal_ipc_register(HAL_SERVICE_ID_HANDSFREE, ev_handlers,
334 sizeof(ev_handlers)/sizeof(ev_handlers[0]));
336 cmd.service_id = HAL_SERVICE_ID_HANDSFREE;
337 cmd.mode = get_mode();
338 cmd.max_clients = max_hf_clients;
340 ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
341 sizeof(cmd), &cmd, NULL, NULL, NULL);
343 if (ret != BT_STATUS_SUCCESS) {
345 hal_ipc_unregister(HAL_SERVICE_ID_HANDSFREE);
351 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
352 static bt_status_t init(bthf_callbacks_t *callbacks, int max_hf_clients)
354 return init_real(callbacks, max_hf_clients);
357 static bt_status_t init(bthf_callbacks_t *callbacks)
359 return init_real(callbacks, 1);
363 static bt_status_t handsfree_connect(bt_bdaddr_t *bd_addr)
365 struct hal_cmd_handsfree_connect cmd;
369 if (!interface_ready())
370 return BT_STATUS_NOT_READY;
373 return BT_STATUS_PARM_INVALID;
375 memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
377 return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_CONNECT,
378 sizeof(cmd), &cmd, NULL, NULL, NULL);
381 static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
383 struct hal_cmd_handsfree_disconnect cmd;
387 if (!interface_ready())
388 return BT_STATUS_NOT_READY;
391 return BT_STATUS_PARM_INVALID;
393 memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
395 return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
396 HAL_OP_HANDSFREE_DISCONNECT, sizeof(cmd), &cmd,
400 static bt_status_t connect_audio(bt_bdaddr_t *bd_addr)
402 struct hal_cmd_handsfree_connect_audio cmd;
406 if (!interface_ready())
407 return BT_STATUS_NOT_READY;
410 return BT_STATUS_PARM_INVALID;
412 memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
414 return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
415 HAL_OP_HANDSFREE_CONNECT_AUDIO, sizeof(cmd),
416 &cmd, NULL, NULL, NULL);
419 static bt_status_t disconnect_audio(bt_bdaddr_t *bd_addr)
421 struct hal_cmd_handsfree_disconnect_audio cmd;
425 if (!interface_ready())
426 return BT_STATUS_NOT_READY;
429 return BT_STATUS_PARM_INVALID;
431 memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
433 return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
434 HAL_OP_HANDSFREE_DISCONNECT_AUDIO, sizeof(cmd),
435 &cmd, NULL, NULL, NULL);
438 static bt_status_t start_voice_recognition_real(bt_bdaddr_t *bd_addr)
440 struct hal_cmd_handsfree_start_vr cmd;
444 if (!interface_ready())
445 return BT_STATUS_NOT_READY;
447 memset(&cmd, 0, sizeof(cmd));
450 memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
452 return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_START_VR,
453 sizeof(cmd), &cmd, NULL, NULL, NULL);
456 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
457 static bt_status_t start_voice_recognition(bt_bdaddr_t *bd_addr)
459 return start_voice_recognition_real(bd_addr);
462 static bt_status_t start_voice_recognition(void)
464 return start_voice_recognition_real(NULL);
468 static bt_status_t stop_voice_recognition_real(bt_bdaddr_t *bd_addr)
470 struct hal_cmd_handsfree_stop_vr cmd;
474 if (!interface_ready())
475 return BT_STATUS_NOT_READY;
477 memset(&cmd, 0, sizeof(cmd));
480 memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
482 return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_STOP_VR,
483 sizeof(cmd), &cmd, NULL, NULL, NULL);
486 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
487 static bt_status_t stop_voice_recognition(bt_bdaddr_t *bd_addr)
489 return stop_voice_recognition_real(bd_addr);
492 static bt_status_t stop_voice_recognition(void)
494 return stop_voice_recognition_real(NULL);
498 static bt_status_t volume_control_real(bthf_volume_type_t type, int volume,
499 bt_bdaddr_t *bd_addr)
501 struct hal_cmd_handsfree_volume_control cmd;
505 if (!interface_ready())
506 return BT_STATUS_NOT_READY;
508 memset(&cmd, 0, sizeof(cmd));
514 memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
516 return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
517 HAL_OP_HANDSFREE_VOLUME_CONTROL, sizeof(cmd),
518 &cmd, NULL, NULL, NULL);
521 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
522 static bt_status_t volume_control(bthf_volume_type_t type, int volume,
523 bt_bdaddr_t *bd_addr)
525 return volume_control_real(type, volume, bd_addr);
528 static bt_status_t volume_control(bthf_volume_type_t type, int volume)
530 return volume_control_real(type, volume, NULL);
534 static bt_status_t device_status_notification(bthf_network_state_t state,
535 bthf_service_type_t type,
536 int signal, int battery)
538 struct hal_cmd_handsfree_device_status_notif cmd;
542 if (!interface_ready())
543 return BT_STATUS_NOT_READY;
548 cmd.battery = battery;
550 return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
551 HAL_OP_HANDSFREE_DEVICE_STATUS_NOTIF,
552 sizeof(cmd), &cmd, NULL, NULL, NULL);
555 static bt_status_t cops_response_real(const char *cops, bt_bdaddr_t *bd_addr)
558 struct hal_cmd_handsfree_cops_response *cmd = (void *) buf;
563 if (!interface_ready())
564 return BT_STATUS_NOT_READY;
567 return BT_STATUS_PARM_INVALID;
569 memset(cmd, 0, sizeof(*cmd));
572 memcpy(cmd->bdaddr, bd_addr, sizeof(cmd->bdaddr));
574 /* Size of cmd.buf */
575 cmd->len = strlen(cops) + 1;
576 memcpy(cmd->buf, cops, cmd->len);
578 len = sizeof(*cmd) + cmd->len;
580 return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
581 HAL_OP_HANDSFREE_COPS_RESPONSE,
582 len, cmd, NULL, NULL, NULL);
585 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
586 static bt_status_t cops_response(const char *cops, bt_bdaddr_t *bd_addr)
588 return cops_response_real(cops, bd_addr);
591 static bt_status_t cops_response(const char *cops)
593 return cops_response_real(cops, NULL);
597 static bt_status_t cind_response_real(int svc, int num_active, int num_held,
598 bthf_call_state_t state, int signal,
599 int roam, int batt_chg,
600 bt_bdaddr_t *bd_addr)
602 struct hal_cmd_handsfree_cind_response cmd;
606 if (!interface_ready())
607 return BT_STATUS_NOT_READY;
609 memset(&cmd, 0, sizeof(cmd));
612 memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
615 cmd.num_active = num_active;
616 cmd.num_held = num_held;
620 cmd.batt_chg = batt_chg;
622 return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
623 HAL_OP_HANDSFREE_CIND_RESPONSE,
624 sizeof(cmd), &cmd, NULL, NULL, NULL);
627 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
628 static bt_status_t cind_response(int svc, int num_active, int num_held,
629 bthf_call_state_t state, int signal,
630 int roam, int batt_chg,
631 bt_bdaddr_t *bd_addr)
633 return cind_response_real(svc, num_active, num_held, state, signal,
634 roam, batt_chg, bd_addr);
637 static bt_status_t cind_response(int svc, int num_active, int num_held,
638 bthf_call_state_t state, int signal,
639 int roam, int batt_chg)
641 return cind_response_real(svc, num_active, num_held, state, signal,
642 roam, batt_chg, NULL);
646 static bt_status_t formatted_at_response_real(const char *rsp,
647 bt_bdaddr_t *bd_addr)
650 struct hal_cmd_handsfree_formatted_at_response *cmd = (void *) buf;
655 if (!interface_ready())
656 return BT_STATUS_NOT_READY;
659 return BT_STATUS_PARM_INVALID;
661 memset(cmd, 0, sizeof(*cmd));
664 memcpy(cmd->bdaddr, bd_addr, sizeof(cmd->bdaddr));
666 cmd->len = strlen(rsp) + 1;
667 memcpy(cmd->buf, rsp, cmd->len);
669 len = sizeof(*cmd) + cmd->len;
671 return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
672 HAL_OP_HANDSFREE_FORMATTED_AT_RESPONSE,
673 len, cmd, NULL, NULL, NULL);
676 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
677 static bt_status_t formatted_at_response(const char *rsp, bt_bdaddr_t *bd_addr)
679 return formatted_at_response_real(rsp, bd_addr);
682 static bt_status_t formatted_at_response(const char *rsp)
684 return formatted_at_response_real(rsp, NULL);
688 static bt_status_t at_response_real(bthf_at_response_t response, int error,
689 bt_bdaddr_t *bd_addr)
691 struct hal_cmd_handsfree_at_response cmd;
695 if (!interface_ready())
696 return BT_STATUS_NOT_READY;
699 memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
701 memset(&cmd, 0, sizeof(cmd));
703 cmd.response = response;
706 return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
707 HAL_OP_HANDSFREE_AT_RESPONSE,
708 sizeof(cmd), &cmd, NULL, NULL, NULL);
711 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
712 static bt_status_t at_response(bthf_at_response_t response, int error,
713 bt_bdaddr_t *bd_addr)
715 return at_response_real(response, error, bd_addr);
718 static bt_status_t at_response(bthf_at_response_t response, int error)
720 return at_response_real(response, error, NULL);
724 static bt_status_t clcc_response_real(int index, bthf_call_direction_t dir,
725 bthf_call_state_t state,
726 bthf_call_mode_t mode,
727 bthf_call_mpty_type_t mpty,
729 bthf_call_addrtype_t type,
730 bt_bdaddr_t *bd_addr)
733 struct hal_cmd_handsfree_clcc_response *cmd = (void *) buf;
738 if (!interface_ready())
739 return BT_STATUS_NOT_READY;
741 memset(cmd, 0, sizeof(*cmd));
744 memcpy(cmd->bdaddr, bd_addr, sizeof(cmd->bdaddr));
754 cmd->number_len = strlen(number) + 1;
755 memcpy(cmd->number, number, cmd->number_len);
760 len = sizeof(*cmd) + cmd->number_len;
762 return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
763 HAL_OP_HANDSFREE_CLCC_RESPONSE,
764 len, cmd, NULL, NULL, NULL);
767 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
768 static bt_status_t clcc_response(int index, bthf_call_direction_t dir,
769 bthf_call_state_t state,
770 bthf_call_mode_t mode,
771 bthf_call_mpty_type_t mpty,
773 bthf_call_addrtype_t type,
774 bt_bdaddr_t *bd_addr)
776 return clcc_response_real(index, dir, state, mode, mpty, number, type,
780 static bt_status_t clcc_response(int index, bthf_call_direction_t dir,
781 bthf_call_state_t state,
782 bthf_call_mode_t mode,
783 bthf_call_mpty_type_t mpty,
785 bthf_call_addrtype_t type)
787 return clcc_response_real(index, dir, state, mode, mpty, number, type,
792 static bt_status_t phone_state_change(int num_active, int num_held,
793 bthf_call_state_t state,
795 bthf_call_addrtype_t type)
798 struct hal_cmd_handsfree_phone_state_change *cmd = (void *) buf;
803 if (!interface_ready())
804 return BT_STATUS_NOT_READY;
806 cmd->num_active = num_active;
807 cmd->num_held = num_held;
812 cmd->number_len = strlen(number) + 1;
813 memcpy(cmd->number, number, cmd->number_len);
818 len = sizeof(*cmd) + cmd->number_len;
820 return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
821 HAL_OP_HANDSFREE_PHONE_STATE_CHANGE,
822 len, cmd, NULL, NULL, NULL);
825 static void cleanup(void)
827 struct hal_cmd_unregister_module cmd;
831 if (!interface_ready())
834 cmd.service_id = HAL_SERVICE_ID_HANDSFREE;
836 hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
837 sizeof(cmd), &cmd, NULL, NULL, NULL);
839 hal_ipc_unregister(HAL_SERVICE_ID_HANDSFREE);
844 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
845 static bt_status_t configure_wbs(bt_bdaddr_t *bd_addr, bthf_wbs_config_t config)
847 struct hal_cmd_handsfree_configure_wbs cmd;
851 if (!interface_ready())
852 return BT_STATUS_NOT_READY;
855 return BT_STATUS_PARM_INVALID;
857 memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
860 return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE,
861 HAL_OP_HANDSFREE_CONFIGURE_WBS,
862 sizeof(cmd), &cmd, NULL, NULL, NULL);
866 static bthf_interface_t iface = {
867 .size = sizeof(iface),
869 .connect = handsfree_connect,
870 .disconnect = disconnect,
871 .connect_audio = connect_audio,
872 .disconnect_audio = disconnect_audio,
873 .start_voice_recognition = start_voice_recognition,
874 .stop_voice_recognition = stop_voice_recognition,
875 .volume_control = volume_control,
876 .device_status_notification = device_status_notification,
877 .cops_response = cops_response,
878 .cind_response = cind_response,
879 .formatted_at_response = formatted_at_response,
880 .at_response = at_response,
881 .clcc_response = clcc_response,
882 .phone_state_change = phone_state_change,
884 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
885 .configure_wbs = configure_wbs,
889 bthf_interface_t *bt_get_handsfree_interface(void)