Upgrade bluez5_37 :Merge the code from private
[platform/upstream/bluez.git] / android / hal-handsfree-client.c
1 /*
2  * Copyright (C) 2014 Intel Corporation
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 #include <stdbool.h>
19 #include <stddef.h>
20 #include <string.h>
21 #include <stdlib.h>
22
23 #include <cutils/properties.h>
24
25 #include "hal-log.h"
26 #include "hal.h"
27 #include "hal-msg.h"
28 #include "ipc-common.h"
29 #include "hal-ipc.h"
30
31 static const bthf_client_callbacks_t *cbs = NULL;
32
33 static bool interface_ready(void)
34 {
35         return cbs != NULL;
36 }
37
38 static void handle_conn_state(void *buf, uint16_t len, int fd)
39 {
40         struct hal_ev_hf_client_conn_state *ev = buf;
41
42         if (cbs->connection_state_cb)
43                 cbs->connection_state_cb(ev->state, ev->peer_feat,
44                                                 ev->chld_feat,
45                                                 (bt_bdaddr_t *) ev->bdaddr);
46 }
47
48 static void handle_audio_state(void *buf, uint16_t len, int fd)
49 {
50         struct hal_ev_hf_client_audio_state *ev = buf;
51
52         if (cbs->audio_state_cb)
53                 cbs->audio_state_cb(ev->state, (bt_bdaddr_t *) (ev->bdaddr));
54 }
55
56 static void handle_vr_state(void *buf, uint16_t len, int fd)
57 {
58         struct hal_ev_hf_client_vr_state *ev = buf;
59
60         if (cbs->vr_cmd_cb)
61                 cbs->vr_cmd_cb(ev->state);
62 }
63
64 static void handle_network_state(void *buf, uint16_t len, int fd)
65 {
66         struct hal_ev_hf_client_net_state *ev = buf;
67
68         if (cbs->network_state_cb)
69                 cbs->network_state_cb(ev->state);
70 }
71
72 static void handle_network_roaming(void *buf, uint16_t len, int fd)
73 {
74         struct hal_ev_hf_client_net_roaming_type *ev = buf;
75
76         if (cbs->network_roaming_cb)
77                 cbs->network_roaming_cb(ev->state);
78 }
79
80 static void handle_network_signal(void *buf, uint16_t len, int fd)
81 {
82         struct hal_ev_hf_client_net_signal_strength *ev = buf;
83
84         if (cbs->network_signal_cb)
85                 cbs->network_signal_cb(ev->signal_strength);
86 }
87
88 static void handle_battery_level(void *buf, uint16_t len, int fd)
89 {
90         struct hal_ev_hf_client_battery_level *ev = buf;
91
92         if (cbs->battery_level_cb)
93                 cbs->battery_level_cb(ev->battery_level);
94 }
95
96 static void handle_operator_name(void *buf, uint16_t len, int fd)
97 {
98         struct hal_ev_hf_client_operator_name *ev = buf;
99         uint16_t name_len = ev->name_len;
100         char *name = NULL;
101
102         if (len != sizeof(*ev) + name_len ||
103                 (name_len != 0 && ev->name[name_len - 1] != '\0')) {
104                 error("invalid operator name, aborting");
105                 exit(EXIT_FAILURE);
106         }
107
108         if (name_len)
109                 name = (char *) ev->name;
110
111         if (cbs->current_operator_cb)
112                 cbs->current_operator_cb(name);
113 }
114
115 static void handle_call(void *buf, uint16_t len, int fd)
116 {
117         struct hal_ev_hf_client_call_indicator *ev = buf;
118
119         if (cbs->call_cb)
120                 cbs->call_cb(ev->call);
121 }
122
123 static void handle_call_setup(void *buf, uint16_t len, int fd)
124 {
125         struct hal_ev_hf_client_call_setup_indicator *ev = buf;
126
127         if (cbs->callsetup_cb)
128                 cbs->callsetup_cb(ev->call_setup);
129 }
130
131 static void handle_call_held(void *buf, uint16_t len, int fd)
132 {
133         struct hal_ev_hf_client_call_held_indicator *ev = buf;
134
135         if (cbs->callheld_cb)
136                 cbs->callheld_cb(ev->call_held);
137 }
138
139 static void handle_response_and_hold(void *buf, uint16_t len, int fd)
140 {
141         struct hal_ev_hf_client_response_and_hold_status *ev = buf;
142
143         if (cbs->resp_and_hold_cb)
144                 cbs->resp_and_hold_cb(ev->status);
145 }
146
147 static void handle_clip(void *buf, uint16_t len, int fd)
148 {
149         struct hal_ev_hf_client_calling_line_ident *ev = buf;
150         uint16_t num_len = ev->number_len;
151         char *number = NULL;
152
153         if (len != sizeof(*ev) + num_len ||
154                 (num_len != 0 && ev->number[num_len - 1] != '\0')) {
155                 error("invalid  clip, aborting");
156                 exit(EXIT_FAILURE);
157         }
158
159         if (num_len)
160                 number = (char *) ev->number;
161
162         if (cbs->clip_cb)
163                 cbs->clip_cb(number);
164 }
165
166 static void handle_call_waiting(void *buf, uint16_t len, int fd)
167 {
168         struct hal_ev_hf_client_call_waiting *ev = buf;
169         uint16_t num_len = ev->number_len;
170         char *number = NULL;
171
172         if (len != sizeof(*ev) + num_len ||
173                 (num_len != 0 && ev->number[num_len - 1] != '\0')) {
174                 error("invalid call waiting, aborting");
175                 exit(EXIT_FAILURE);
176         }
177
178         if (num_len)
179                 number = (char *) ev->number;
180
181         if (cbs->call_waiting_cb)
182                 cbs->call_waiting_cb(number);
183 }
184
185 static void handle_current_calls(void *buf, uint16_t len, int fd)
186 {
187         struct hal_ev_hf_client_current_call *ev = buf;
188         uint16_t num_len = ev->number_len;
189         char *number = NULL;
190
191         if (len != sizeof(*ev) + num_len ||
192                 (num_len != 0 && ev->number[num_len - 1] != '\0')) {
193                 error("invalid current calls, aborting");
194                 exit(EXIT_FAILURE);
195         }
196
197         if (num_len)
198                 number = (char *) ev->number;
199
200         if (cbs->current_calls_cb)
201                 cbs->current_calls_cb(ev->index, ev->direction, ev->call_state,
202                                                         ev->multiparty, number);
203 }
204
205 static void handle_volume_change(void *buf, uint16_t len, int fd)
206 {
207         struct hal_ev_hf_client_volume_changed *ev = buf;
208
209         if (cbs->volume_change_cb)
210                 cbs->volume_change_cb(ev->type, ev->volume);
211 }
212
213 static void handle_command_cmp(void *buf, uint16_t len, int fd)
214 {
215         struct hal_ev_hf_client_command_complete *ev = buf;
216
217         if (cbs->cmd_complete_cb)
218                 cbs->cmd_complete_cb(ev->type, ev->cme);
219 }
220
221 static void handle_subscriber_info(void *buf, uint16_t len, int fd)
222 {
223         const struct hal_ev_hf_client_subscriber_service_info *ev = buf;
224         uint16_t name_len = ev->name_len;
225         char *name = NULL;
226
227         if (len != sizeof(*ev) + name_len ||
228                 (name_len != 0 && ev->name[name_len - 1] != '\0')) {
229                 error("invalid sunscriber info, aborting");
230                 exit(EXIT_FAILURE);
231         }
232
233         if (name_len)
234                 name = (char *) ev->name;
235
236         if (cbs->subscriber_info_cb)
237                 cbs->subscriber_info_cb(name, ev->type);
238 }
239
240 static void handle_in_band_ringtone(void *buf, uint16_t len, int fd)
241 {
242         struct hal_ev_hf_client_inband_settings *ev = buf;
243
244         if (cbs->in_band_ring_tone_cb)
245                 cbs->in_band_ring_tone_cb(ev->state);
246 }
247
248 static void handle_last_voice_tag_number(void *buf, uint16_t len, int fd)
249 {
250         const struct hal_ev_hf_client_last_void_call_tag_num *ev = buf;
251         char *number = NULL;
252         uint16_t num_len = ev->number_len;
253
254         if (len != sizeof(*ev) + num_len ||
255                 (num_len != 0 && ev->number[num_len - 1] != '\0')) {
256                 error("invalid voice tag, aborting");
257                 exit(EXIT_FAILURE);
258         }
259
260         if (num_len)
261                 number = (char *) ev->number;
262
263         if (cbs->last_voice_tag_number_callback)
264                 cbs->last_voice_tag_number_callback(number);
265 }
266
267 static void handle_ring_indication(void *buf, uint16_t len, int fd)
268 {
269         if (cbs->ring_indication_cb)
270                 cbs->ring_indication_cb();
271 }
272
273 /*
274  * handlers will be called from notification thread context,
275  * index in table equals to 'opcode - HAL_MINIMUM_EVENT'
276  */
277 static const struct hal_ipc_handler ev_handlers[] = {
278         /* HAL_EV_HF_CLIENT_CONN_STATE */
279         { handle_conn_state, false,
280                                 sizeof(struct hal_ev_hf_client_conn_state) },
281         /* HAL_EV_HF_CLIENT_AUDIO_STATE */
282         { handle_audio_state, false,
283                                 sizeof(struct hal_ev_hf_client_audio_state) },
284         /* HAL_EV_HF_CLIENT_VR_STATE */
285         { handle_vr_state, false, sizeof(struct hal_ev_hf_client_vr_state) },
286         /*HAL_EV_HF_CLIENT_NET_STATE */
287         { handle_network_state, false,
288                                 sizeof(struct hal_ev_hf_client_net_state)},
289         /*HAL_EV_HF_CLIENT_NET_ROAMING_TYPE */
290         { handle_network_roaming, false,
291                         sizeof(struct hal_ev_hf_client_net_roaming_type) },
292         /* HAL_EV_HF_CLIENT_NET_SIGNAL_STRENGTH */
293         { handle_network_signal, false,
294                         sizeof(struct hal_ev_hf_client_net_signal_strength) },
295         /* HAL_EV_HF_CLIENT_BATTERY_LEVEL */
296         { handle_battery_level, false,
297                         sizeof(struct hal_ev_hf_client_battery_level) },
298         /* HAL_EV_HF_CLIENT_OPERATOR_NAME */
299         { handle_operator_name, true,
300                         sizeof(struct hal_ev_hf_client_operator_name) },
301         /* HAL_EV_HF_CLIENT_CALL_INDICATOR */
302         { handle_call, false,
303                         sizeof(struct hal_ev_hf_client_call_indicator) },
304         /* HAL_EV_HF_CLIENT_CALL_SETUP_INDICATOR */
305         { handle_call_setup, false,
306                 sizeof(struct hal_ev_hf_client_call_setup_indicator) },
307         /* HAL_EV_HF_CLIENT_CALL_HELD_INDICATOR */
308         { handle_call_held, false,
309                         sizeof(struct hal_ev_hf_client_call_held_indicator) },
310         /* HAL_EV_HF_CLIENT_RESPONSE_AND_HOLD_STATUS */
311         { handle_response_and_hold, false,
312                 sizeof(struct hal_ev_hf_client_response_and_hold_status) },
313         /* HAL_EV_HF_CLIENT_CALLING_LINE_IDENT */
314         { handle_clip, true,
315                         sizeof(struct hal_ev_hf_client_calling_line_ident) },
316         /* HAL_EV_HF_CLIENT_CALL_WAITING */
317         { handle_call_waiting, true,
318                         sizeof(struct hal_ev_hf_client_call_waiting) },
319         /* HAL_EV_HF_CLIENT_CURRENT_CALL */
320         { handle_current_calls, true,
321                         sizeof(struct hal_ev_hf_client_current_call) },
322         /* HAL_EV_CLIENT_VOLUME_CHANGED */
323         { handle_volume_change, false,
324                         sizeof(struct hal_ev_hf_client_volume_changed) },
325         /* HAL_EV_CLIENT_COMMAND_COMPLETE */
326         { handle_command_cmp, false,
327                         sizeof(struct hal_ev_hf_client_command_complete) },
328         /* HAL_EV_CLIENT_SUBSCRIBER_SERVICE_INFO */
329         { handle_subscriber_info, true,
330                 sizeof(struct hal_ev_hf_client_subscriber_service_info) },
331         /* HAL_EV_CLIENT_INBAND_SETTINGS */
332         { handle_in_band_ringtone, false,
333                 sizeof(struct hal_ev_hf_client_inband_settings) },
334         /* HAL_EV_CLIENT_LAST_VOICE_CALL_TAG_NUM */
335         { handle_last_voice_tag_number, true,
336                 sizeof(struct hal_ev_hf_client_last_void_call_tag_num) },
337         /* HAL_EV_CLIENT_RING_INDICATION */
338         { handle_ring_indication, false, 0 },
339 };
340
341 static bt_status_t init(bthf_client_callbacks_t *callbacks)
342 {
343         struct hal_cmd_register_module cmd;
344         int ret;
345
346         DBG("");
347
348         if (interface_ready())
349                 return BT_STATUS_DONE;
350
351         cbs = callbacks;
352
353         hal_ipc_register(HAL_SERVICE_ID_HANDSFREE_CLIENT, ev_handlers,
354                                 sizeof(ev_handlers)/sizeof(ev_handlers[0]));
355
356         cmd.service_id = HAL_SERVICE_ID_HANDSFREE_CLIENT;
357         cmd.mode = HAL_MODE_DEFAULT;
358         cmd.max_clients = 1;
359
360         ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
361                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
362         if (ret != BT_STATUS_SUCCESS) {
363                 cbs = NULL;
364                 hal_ipc_unregister(HAL_SERVICE_ID_HANDSFREE_CLIENT);
365         }
366
367         return ret;
368 }
369
370 static bt_status_t hf_client_connect(bt_bdaddr_t *bd_addr)
371 {
372         struct hal_cmd_hf_client_connect cmd;
373
374         DBG("");
375
376         if (!interface_ready())
377                 return BT_STATUS_NOT_READY;
378
379         if (!bd_addr)
380                 return BT_STATUS_PARM_INVALID;
381
382         memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
383
384         return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT,
385                                 HAL_OP_HF_CLIENT_CONNECT, sizeof(cmd), &cmd,
386                                 NULL, NULL, NULL);
387 }
388
389 static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
390 {
391         struct hal_cmd_hf_client_disconnect cmd;
392
393         DBG("");
394
395         if (!interface_ready())
396                 return BT_STATUS_NOT_READY;
397
398         if (!bd_addr)
399                 return BT_STATUS_PARM_INVALID;
400
401         memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
402
403         return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT,
404                                 HAL_OP_HF_CLIENT_DISCONNECT, sizeof(cmd), &cmd,
405                                 NULL, NULL, NULL);
406 }
407
408 static bt_status_t connect_audio(bt_bdaddr_t *bd_addr)
409 {
410         struct hal_cmd_hf_client_connect_audio cmd;
411
412         DBG("");
413
414         if (!interface_ready())
415                 return BT_STATUS_NOT_READY;
416
417         if (!bd_addr)
418                 return BT_STATUS_PARM_INVALID;
419
420         memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
421
422         return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT,
423                                 HAL_OP_HF_CLIENT_CONNECT_AUDIO, sizeof(cmd),
424                                 &cmd, NULL, NULL, NULL);
425 }
426
427 static bt_status_t disconnect_audio(bt_bdaddr_t *bd_addr)
428 {
429         struct hal_cmd_hf_client_disconnect_audio cmd;
430
431         DBG("");
432
433         if (!interface_ready())
434                 return BT_STATUS_NOT_READY;
435
436         if (!bd_addr)
437                 return BT_STATUS_PARM_INVALID;
438
439         memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
440
441         return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT,
442                                 HAL_OP_HF_CLIENT_DISCONNECT_AUDIO, sizeof(cmd),
443                                 &cmd, NULL, NULL, NULL);
444 }
445
446 static bt_status_t start_voice_recognition(void)
447 {
448         DBG("");
449
450         if (!interface_ready())
451                 return BT_STATUS_NOT_READY;
452
453         return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT,
454                                 HAL_OP_HF_CLIENT_START_VR, 0, NULL, NULL, NULL,
455                                 NULL);
456 }
457
458 static bt_status_t stop_voice_recognition(void)
459 {
460         DBG("");
461
462         if (!interface_ready())
463                 return BT_STATUS_NOT_READY;
464
465         return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT,
466                                 HAL_OP_HF_CLIENT_STOP_VR, 0, NULL, NULL, NULL,
467                                 NULL);
468 }
469
470 static bt_status_t volume_control(bthf_client_volume_type_t type,
471                                                                 int volume)
472 {
473         struct hal_cmd_hf_client_volume_control cmd;
474
475         DBG("");
476
477         if (!interface_ready())
478                 return BT_STATUS_NOT_READY;
479
480         cmd.type = type;
481         cmd.volume = volume;
482
483         return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT,
484                                 HAL_OP_HF_CLIENT_VOLUME_CONTROL, sizeof(cmd),
485                                 &cmd, NULL, NULL, NULL);
486 }
487
488 static bt_status_t dial(const char *number)
489 {
490         char buf[IPC_MTU];
491         struct hal_cmd_hf_client_dial *cmd = (void *) buf;
492         size_t len;
493
494         DBG("");
495
496         if (!interface_ready())
497                 return BT_STATUS_NOT_READY;
498
499         if (number) {
500                 cmd->number_len = strlen(number) + 1;
501                 memcpy(cmd->number, number, cmd->number_len);
502         } else {
503                 cmd->number_len = 0;
504         }
505
506         len = sizeof(*cmd) + cmd->number_len;
507
508         return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT,
509                                 HAL_OP_HF_CLIENT_DIAL, len, cmd, NULL, NULL,
510                                 NULL);
511 }
512
513 static bt_status_t dial_memory(int location)
514 {
515         struct hal_cmd_hf_client_dial_memory cmd;
516
517         DBG("");
518
519         if (!interface_ready())
520                 return BT_STATUS_NOT_READY;
521
522         cmd.location = location;
523
524         return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT,
525                                         HAL_OP_HF_CLIENT_DIAL_MEMORY,
526                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
527 }
528
529 static bt_status_t call_action(bthf_client_call_action_t action, int index)
530 {
531         struct hal_cmd_hf_client_call_action cmd;
532
533         DBG("");
534
535         if (!interface_ready())
536                 return BT_STATUS_NOT_READY;
537
538         cmd.action = action;
539         cmd.index = index;
540
541         return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT,
542                                 HAL_OP_HF_CLIENT_CALL_ACTION, sizeof(cmd), &cmd,
543                                 NULL, NULL, NULL);
544 }
545
546 static bt_status_t query_current_calls(void)
547 {
548         DBG("");
549
550         if (!interface_ready())
551                 return BT_STATUS_NOT_READY;
552
553         return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT,
554                                 HAL_OP_HF_CLIENT_QUERY_CURRENT_CALLS, 0, NULL,
555                                 NULL, NULL, NULL);
556 }
557
558 static bt_status_t query_operator_name(void)
559 {
560         DBG("");
561
562         if (!interface_ready())
563                 return BT_STATUS_NOT_READY;
564
565         return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT,
566                                 HAL_OP_HF_CLIENT_QUERY_OPERATOR_NAME, 0, NULL,
567                                 NULL, NULL, NULL);
568 }
569
570 static bt_status_t retrieve_subsr_info(void)
571 {
572         DBG("");
573
574         if (!interface_ready())
575                 return BT_STATUS_NOT_READY;
576
577         return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT,
578                                 HAL_OP_HF_CLIENT_RETRIEVE_SUBSCR_INFO, 0, NULL,
579                                 NULL, NULL, NULL);
580 }
581
582 static bt_status_t send_dtmf(char tone)
583 {
584         struct hal_cmd_hf_client_send_dtmf cmd;
585
586         DBG("");
587
588         if (!interface_ready())
589                 return BT_STATUS_NOT_READY;
590
591         cmd.tone = tone;
592
593         return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT,
594                                 HAL_OP_HF_CLIENT_SEND_DTMF, sizeof(cmd), &cmd,
595                                 NULL, NULL, NULL);
596 }
597
598 static bt_status_t request_last_voice_tag_number(void)
599 {
600         DBG("");
601
602         if (!interface_ready())
603                 return BT_STATUS_NOT_READY;
604
605         return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT,
606                                         HAL_OP_HF_CLIENT_GET_LAST_VOICE_TAG_NUM,
607                                         0, NULL, NULL, NULL, NULL);
608 }
609
610 static void cleanup(void)
611 {
612         struct hal_cmd_unregister_module cmd;
613
614         DBG("");
615
616         if (!interface_ready())
617                 return;
618
619         cmd.service_id = HAL_SERVICE_ID_HANDSFREE_CLIENT;
620
621         hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
622                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
623
624         hal_ipc_unregister(HAL_SERVICE_ID_HANDSFREE_CLIENT);
625
626         cbs = NULL;
627 }
628
629 static bthf_client_interface_t iface = {
630         .size = sizeof(iface),
631         .init = init,
632         .connect = hf_client_connect,
633         .disconnect = disconnect,
634         .connect_audio = connect_audio,
635         .disconnect_audio = disconnect_audio,
636         .start_voice_recognition = start_voice_recognition,
637         .stop_voice_recognition = stop_voice_recognition,
638         .volume_control = volume_control,
639         .dial = dial,
640         .dial_memory = dial_memory,
641         .handle_call_action = call_action,
642         .query_current_calls = query_current_calls,
643         .query_current_operator_name = query_operator_name,
644         .retrieve_subscriber_info = retrieve_subsr_info,
645         .send_dtmf = send_dtmf,
646         .request_last_voice_tag_number = request_last_voice_tag_number,
647         .cleanup = cleanup
648 };
649
650 bthf_client_interface_t *bt_get_hf_client_interface(void)
651 {
652         return &iface;
653 }