tizen 2.3.1 release
[framework/connectivity/bluez.git] / android / hal-gatt.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 <string.h>
20 #include <stdlib.h>
21
22 #include "hal-log.h"
23 #include "hal.h"
24 #include "hal-msg.h"
25 #include "ipc-common.h"
26 #include "hal-ipc.h"
27 #include "hal-utils.h"
28
29 static const btgatt_callbacks_t *cbs = NULL;
30
31 static bool interface_ready(void)
32 {
33         return cbs != NULL;
34 }
35
36 static void gatt_id_from_hal(btgatt_gatt_id_t *to,
37                                                 struct hal_gatt_gatt_id *from)
38 {
39         memcpy(&to->uuid, from->uuid, sizeof(to->uuid));
40         to->inst_id = from->inst_id;
41 }
42
43 static void gatt_id_to_hal(struct hal_gatt_gatt_id *to, btgatt_gatt_id_t *from)
44 {
45         memcpy(to->uuid, &from->uuid, sizeof(from->uuid));
46         to->inst_id = from->inst_id;
47 }
48
49 static void srvc_id_from_hal(btgatt_srvc_id_t *to,
50                                                 struct hal_gatt_srvc_id *from)
51 {
52         memcpy(&to->id.uuid, from->uuid, sizeof(to->id.uuid));
53         to->id.inst_id = from->inst_id;
54         to->is_primary = from->is_primary;
55 }
56
57 static void srvc_id_to_hal(struct hal_gatt_srvc_id *to, btgatt_srvc_id_t *from)
58 {
59         memcpy(to->uuid, &from->id.uuid, sizeof(from->id.uuid));
60         to->inst_id = from->id.inst_id;
61         to->is_primary = from->is_primary;
62 }
63
64 /* Client Event Handlers */
65
66 static void handle_register_client(void *buf, uint16_t len, int fd)
67 {
68         struct hal_ev_gatt_client_register_client *ev = buf;
69
70         if (cbs->client->register_client_cb)
71                 cbs->client->register_client_cb(ev->status, ev->client_if,
72                                                 (bt_uuid_t *) ev->app_uuid);
73 }
74
75 static void handle_scan_result(void *buf, uint16_t len, int fd)
76 {
77         struct hal_ev_gatt_client_scan_result *ev = buf;
78         uint8_t ad[62];
79
80         if (len != sizeof(*ev) + ev->len) {
81                 error("gatt: invalid scan result event, aborting");
82                 exit(EXIT_FAILURE);
83         }
84
85         /* Java assumes that passed data has 62 bytes */
86         memset(ad, 0, sizeof(ad));
87         memcpy(ad, ev->adv_data, ev->len > sizeof(ad) ? sizeof(ad) : ev->len);
88
89         if (cbs->client->scan_result_cb)
90                 cbs->client->scan_result_cb((bt_bdaddr_t *) ev->bda, ev->rssi,
91                                                                         ad);
92 }
93
94 static void handle_connect(void *buf, uint16_t len, int fd)
95 {
96         struct hal_ev_gatt_client_connect *ev = buf;
97
98         if (cbs->client->open_cb)
99                 cbs->client->open_cb(ev->conn_id, ev->status, ev->client_if,
100                                                 (bt_bdaddr_t *) ev->bda);
101 }
102
103 static void handle_disconnect(void *buf, uint16_t len, int fd)
104 {
105         struct hal_ev_gatt_client_disconnect *ev = buf;
106
107         if (cbs->client->close_cb)
108                 cbs->client->close_cb(ev->conn_id, ev->status, ev->client_if,
109                                                 (bt_bdaddr_t *) ev->bda);
110 }
111
112 static void handle_search_complete(void *buf, uint16_t len, int fd)
113 {
114         struct hal_ev_gatt_client_search_complete *ev = buf;
115
116         if (cbs->client->search_complete_cb)
117                 cbs->client->search_complete_cb(ev->conn_id, ev->status);
118 }
119
120 static void handle_search_result(void *buf, uint16_t len, int fd)
121 {
122         struct hal_ev_gatt_client_search_result *ev = buf;
123         btgatt_srvc_id_t srvc_id;
124
125         srvc_id_from_hal(&srvc_id, &ev->srvc_id);
126
127         if (cbs->client->search_result_cb)
128                 cbs->client->search_result_cb(ev->conn_id, &srvc_id);
129 }
130
131 static void handle_get_characteristic(void *buf, uint16_t len, int fd)
132 {
133         struct hal_ev_gatt_client_get_characteristic *ev = buf;
134         btgatt_gatt_id_t char_id;
135         btgatt_srvc_id_t srvc_id;
136
137         srvc_id_from_hal(&srvc_id, &ev->srvc_id);
138         gatt_id_from_hal(&char_id, &ev->char_id);
139
140         if (cbs->client->get_characteristic_cb)
141                 cbs->client->get_characteristic_cb(ev->conn_id, ev->status,
142                                                         &srvc_id, &char_id,
143                                                         ev->char_prop);
144 }
145
146 static void handle_get_descriptor(void *buf, uint16_t len, int fd)
147 {
148         struct hal_ev_gatt_client_get_descriptor *ev = buf;
149         btgatt_gatt_id_t descr_id;
150         btgatt_gatt_id_t char_id;
151         btgatt_srvc_id_t srvc_id;
152
153         srvc_id_from_hal(&srvc_id, &ev->srvc_id);
154         gatt_id_from_hal(&char_id, &ev->char_id);
155         gatt_id_from_hal(&descr_id, &ev->descr_id);
156
157         if (cbs->client->get_descriptor_cb)
158                 cbs->client->get_descriptor_cb(ev->conn_id, ev->status,
159                                                 &srvc_id, &char_id, &descr_id);
160 }
161
162 static void handle_get_included_service(void *buf, uint16_t len, int fd)
163 {
164         struct hal_ev_gatt_client_get_inc_service *ev = buf;
165         btgatt_srvc_id_t srvc_id;
166         btgatt_srvc_id_t incl_srvc_id;
167
168         srvc_id_from_hal(&srvc_id, &ev->srvc_id);
169         srvc_id_from_hal(&incl_srvc_id, &ev->incl_srvc_id);
170
171         if (cbs->client->get_included_service_cb)
172                 cbs->client->get_included_service_cb(ev->conn_id, ev->status,
173                                                                 &srvc_id,
174                                                                 &incl_srvc_id);
175 }
176
177 static void handle_register_for_notification(void *buf, uint16_t len, int fd)
178 {
179         struct hal_ev_gatt_client_reg_for_notif *ev = buf;
180         btgatt_gatt_id_t char_id;
181         btgatt_srvc_id_t srvc_id;
182
183         srvc_id_from_hal(&srvc_id, &ev->srvc_id);
184         gatt_id_from_hal(&char_id, &ev->char_id);
185
186         if (cbs->client->register_for_notification_cb)
187                 cbs->client->register_for_notification_cb(ev->conn_id,
188                                                                 ev->registered,
189                                                                 ev->status,
190                                                                 &srvc_id,
191                                                                 &char_id);
192 }
193
194 static void handle_notify(void *buf, uint16_t len, int fd)
195 {
196         struct hal_ev_gatt_client_notify *ev = buf;
197         btgatt_notify_params_t params;
198
199         if (len != sizeof(*ev) + ev->len) {
200                 error("gatt: invalid notify event, aborting");
201                 exit(EXIT_FAILURE);
202         }
203
204         memset(&params, 0, sizeof(params));
205         memcpy(params.value, ev->value, ev->len);
206         memcpy(&params.bda, ev->bda, sizeof(params.bda));
207
208         srvc_id_from_hal(&params.srvc_id, &ev->srvc_id);
209         gatt_id_from_hal(&params.char_id, &ev->char_id);
210
211         params.len = ev->len;
212         params.is_notify = ev->is_notify;
213
214         if (cbs->client->notify_cb)
215                 cbs->client->notify_cb(ev->conn_id, &params);
216 }
217
218 static void handle_read_characteristic(void *buf, uint16_t len, int fd)
219 {
220         struct hal_ev_gatt_client_read_characteristic *ev = buf;
221         btgatt_read_params_t params;
222
223         if (len != sizeof(*ev) + ev->data.len) {
224                 error("gatt: invalid read characteristic event, aborting");
225                 exit(EXIT_FAILURE);
226         }
227
228         memset(&params, 0, sizeof(params));
229
230         srvc_id_from_hal(&params.srvc_id, &ev->data.srvc_id);
231         gatt_id_from_hal(&params.char_id, &ev->data.char_id);
232         gatt_id_from_hal(&params.descr_id, &ev->data.descr_id);
233
234         memcpy(&params.value.value, ev->data.value, ev->data.len);
235
236         params.value_type = ev->data.value_type;
237         params.value.len = ev->data.len;
238         params.status = ev->data.status;
239
240         if (cbs->client->read_characteristic_cb)
241                 cbs->client->read_characteristic_cb(ev->conn_id, ev->status,
242                                                                 &params);
243 }
244
245 static void handle_write_characteristic(void *buf, uint16_t len, int fd)
246 {
247         struct hal_ev_gatt_client_write_characteristic *ev = buf;
248         btgatt_write_params_t params;
249
250         memset(&params, 0, sizeof(params));
251
252         srvc_id_from_hal(&params.srvc_id, &ev->data.srvc_id);
253         gatt_id_from_hal(&params.char_id, &ev->data.char_id);
254         gatt_id_from_hal(&params.descr_id, &ev->data.descr_id);
255
256         params.status = ev->data.status;
257
258         if (cbs->client->write_characteristic_cb)
259                 cbs->client->write_characteristic_cb(ev->conn_id, ev->status,
260                                                                 &params);
261 }
262
263 static void handle_read_descriptor(void *buf, uint16_t len, int fd)
264 {
265         struct hal_ev_gatt_client_read_descriptor *ev = buf;
266         btgatt_read_params_t params;
267
268         if (len != sizeof(*ev) + ev->data.len) {
269                 error("gatt: invalid read descriptor event, aborting");
270                 exit(EXIT_FAILURE);
271         }
272
273         memset(&params, 0, sizeof(params));
274
275         srvc_id_from_hal(&params.srvc_id, &ev->data.srvc_id);
276         gatt_id_from_hal(&params.char_id, &ev->data.char_id);
277         gatt_id_from_hal(&params.descr_id, &ev->data.descr_id);
278
279         memcpy(&params.value.value, ev->data.value, ev->data.len);
280
281         params.value_type = ev->data.value_type;
282         params.value.len = ev->data.len;
283         params.status = ev->data.status;
284
285         if (cbs->client->read_descriptor_cb)
286                 cbs->client->read_descriptor_cb(ev->conn_id, ev->status,
287                                                                 &params);
288 }
289
290 static void handle_write_descriptor(void *buf, uint16_t len, int fd)
291 {
292         struct hal_ev_gatt_client_write_descriptor *ev = buf;
293         btgatt_write_params_t params;
294
295         memset(&params, 0, sizeof(params));
296
297         srvc_id_from_hal(&params.srvc_id, &ev->data.srvc_id);
298         gatt_id_from_hal(&params.char_id, &ev->data.char_id);
299         gatt_id_from_hal(&params.descr_id, &ev->data.descr_id);
300
301         params.status = ev->data.status;
302
303         if (cbs->client->write_descriptor_cb)
304                 cbs->client->write_descriptor_cb(ev->conn_id, ev->status,
305                                                                 &params);
306 }
307
308 static void handle_execute_write(void *buf, uint16_t len, int fd)
309 {
310         struct hal_ev_gatt_client_exec_write *ev = buf;
311
312         if (cbs->client->execute_write_cb)
313                 cbs->client->execute_write_cb(ev->conn_id, ev->status);
314 }
315
316 static void handle_read_remote_rssi(void *buf, uint16_t len, int fd)
317 {
318         struct hal_ev_gatt_client_read_remote_rssi *ev = buf;
319
320         if (cbs->client->read_remote_rssi_cb)
321                 cbs->client->read_remote_rssi_cb(ev->client_if,
322                                                 (bt_bdaddr_t *) ev->address,
323                                                 ev->rssi, ev->status);
324 }
325
326 static void handle_listen(void *buf, uint16_t len, int fd)
327 {
328         struct hal_ev_gatt_client_listen *ev = buf;
329
330         if (cbs->client->listen_cb)
331                 cbs->client->listen_cb(ev->status, ev->server_if);
332 }
333
334 /* Server Event Handlers */
335
336 static void handle_register_server(void *buf, uint16_t len, int fd)
337 {
338         struct hal_ev_gatt_server_register *ev = buf;
339
340         if (cbs->server->register_server_cb)
341                 cbs->server->register_server_cb(ev->status, ev->server_if,
342                                                 (bt_uuid_t *) &ev->uuid);
343 }
344
345 static void handle_connection(void *buf, uint16_t len, int fd)
346 {
347         struct hal_ev_gatt_server_connection *ev = buf;
348
349         if (cbs->server->connection_cb)
350                 cbs->server->connection_cb(ev->conn_id, ev->server_if,
351                                                 ev->connected,
352                                                 (bt_bdaddr_t *) &ev->bdaddr);
353 }
354
355 static void handle_service_added(void *buf, uint16_t len, int fd)
356 {
357         struct hal_ev_gatt_server_service_added *ev = buf;
358         btgatt_srvc_id_t srvc_id;
359
360         srvc_id_from_hal(&srvc_id, &ev->srvc_id);
361
362         if (cbs->server->service_added_cb)
363                 cbs->server->service_added_cb(ev->status, ev->server_if,
364                                                 &srvc_id, ev->srvc_handle);
365 }
366
367 static void handle_included_service_added(void *buf, uint16_t len, int fd)
368 {
369         struct hal_ev_gatt_server_inc_srvc_added *ev = buf;
370
371         if (cbs->server->included_service_added_cb)
372                 cbs->server->included_service_added_cb(ev->status,
373                                                         ev->server_if,
374                                                         ev->srvc_handle,
375                                                         ev->incl_srvc_handle);
376 }
377
378 static void handle_characteristic_added(void *buf, uint16_t len, int fd)
379 {
380         struct hal_ev_gatt_server_characteristic_added *ev = buf;
381
382         if (cbs->server->characteristic_added_cb)
383                 cbs->server->characteristic_added_cb(ev->status, ev->server_if,
384                                                         (bt_uuid_t *) &ev->uuid,
385                                                         ev->srvc_handle,
386                                                         ev->char_handle);
387 }
388
389 static void handle_descriptor_added(void *buf, uint16_t len, int fd)
390 {
391         struct hal_ev_gatt_server_descriptor_added *ev = buf;
392
393         if (cbs->server->descriptor_added_cb)
394                 cbs->server->descriptor_added_cb(ev->status, ev->server_if,
395                                                         (bt_uuid_t *) &ev->uuid,
396                                                         ev->srvc_handle,
397                                                         ev->descr_handle);
398 }
399
400 static void handle_service_started(void *buf, uint16_t len, int fd)
401 {
402         struct hal_ev_gatt_server_service_started *ev = buf;
403
404         if (cbs->server->service_started_cb)
405                 cbs->server->service_started_cb(ev->status, ev->server_if,
406                                                         ev->srvc_handle);
407 }
408
409 static void handle_service_stopped(void *buf, uint16_t len, int fd)
410 {
411         struct hal_ev_gatt_server_service_stopped *ev = buf;
412
413         if (cbs->server->service_stopped_cb)
414                 cbs->server->service_stopped_cb(ev->status, ev->server_if,
415                                                         ev->srvc_handle);
416 }
417
418 static void handle_service_deleted(void *buf, uint16_t len, int fd)
419 {
420         struct hal_ev_gatt_server_service_deleted *ev = buf;
421
422         if (cbs->server->service_deleted_cb)
423                 cbs->server->service_deleted_cb(ev->status, ev->server_if,
424                                                         ev->srvc_handle);
425 }
426
427 static void handle_request_read(void *buf, uint16_t len, int fd)
428 {
429         struct hal_ev_gatt_server_request_read *ev = buf;
430
431         if (cbs->server->request_read_cb)
432                 cbs->server->request_read_cb(ev->conn_id, ev->trans_id,
433                                                 (bt_bdaddr_t *) &ev->bdaddr,
434                                                 ev->attr_handle, ev->offset,
435                                                 ev->is_long);
436 }
437
438 static void handle_request_write(void *buf, uint16_t len, int fd)
439 {
440         struct hal_ev_gatt_server_request_write *ev = buf;
441
442         if (len != sizeof(*ev) + ev->length) {
443                 error("gatt: invalid request write event, aborting");
444                 exit(EXIT_FAILURE);
445         }
446
447         if (cbs->server->request_write_cb)
448                 cbs->server->request_write_cb(ev->conn_id, ev->trans_id,
449                                                 (bt_bdaddr_t *) ev->bdaddr,
450                                                 ev->attr_handle, ev->offset,
451                                                 ev->length, ev->need_rsp,
452                                                 ev->is_prep, ev->value);
453 }
454
455 static void handle_request_exec_write(void *buf, uint16_t len, int fd)
456 {
457         struct hal_ev_gatt_server_request_exec_write *ev = buf;
458
459         if (cbs->server->request_exec_write_cb)
460                 cbs->server->request_exec_write_cb(ev->conn_id, ev->trans_id,
461                                                 (bt_bdaddr_t *) ev->bdaddr,
462                                                 ev->exec_write);
463 }
464
465 static void handle_response_confirmation(void *buf, uint16_t len, int fd)
466 {
467         struct hal_ev_gatt_server_rsp_confirmation *ev = buf;
468
469         if (cbs->server->response_confirmation_cb)
470                 cbs->server->response_confirmation_cb(ev->status, ev->handle);
471 }
472
473 static void handle_configure_mtu(void *buf, uint16_t len, int fd)
474 {
475 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
476         struct hal_ev_gatt_client_configure_mtu *ev = buf;
477
478         if (cbs->client->configure_mtu_cb)
479                 cbs->client->configure_mtu_cb(ev->conn_id, ev->status, ev->mtu);
480 #endif
481 }
482
483 static void handle_filter_config(void *buf, uint16_t len, int fd)
484 {
485 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
486         struct hal_ev_gatt_client_filter_config *ev = buf;
487
488         if (cbs->client->scan_filter_cfg_cb)
489                 cbs->client->scan_filter_cfg_cb(ev->action, ev->client_if,
490                                                 ev->status, ev->type,
491                                                 ev->space);
492 #endif
493 }
494
495 static void handle_filter_params(void *buf, uint16_t len, int fd)
496 {
497 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
498         struct hal_ev_gatt_client_filter_params *ev = buf;
499
500         if (cbs->client->scan_filter_param_cb)
501                 cbs->client->scan_filter_param_cb(ev->action, ev->client_if,
502                                                         ev->status, ev->space);
503 #endif
504 }
505
506 static void handle_filter_status(void *buf, uint16_t len, int fd)
507 {
508 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
509         struct hal_ev_gatt_client_filter_status *ev = buf;
510
511         if (cbs->client->scan_filter_status_cb)
512                 cbs->client->scan_filter_status_cb(ev->enable, ev->client_if,
513                                                                 ev->status);
514 #endif
515 }
516
517 static void handle__multi_adv_enable(void *buf, uint16_t len, int fd)
518 {
519 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
520         struct hal_ev_gatt_client_multi_adv_enable *ev = buf;
521
522         if (cbs->client->multi_adv_enable_cb)
523                 cbs->client->multi_adv_enable_cb(ev->client_if, ev->status);
524 #endif
525 }
526
527 static void handle_multi_adv_update(void *buf, uint16_t len, int fd)
528 {
529 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
530         struct hal_ev_gatt_client_multi_adv_update *ev = buf;
531
532         if (cbs->client->multi_adv_update_cb)
533                 cbs->client->multi_adv_update_cb(ev->client_if, ev->status);
534 #endif
535 }
536
537 static void handle_multi_adv_data(void *buf, uint16_t len, int fd)
538 {
539 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
540         struct hal_ev_gatt_client_multi_adv_data *ev = buf;
541
542         if (cbs->client->multi_adv_data_cb)
543                 cbs->client->multi_adv_data_cb(ev->client_if, ev->status);
544 #endif
545 }
546
547 static void handle_multi_adv_disable(void *buf, uint16_t len, int fd)
548 {
549 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
550         struct hal_ev_gatt_client_multi_adv_disable *ev = buf;
551
552         if (cbs->client->multi_adv_disable_cb)
553                 cbs->client->multi_adv_disable_cb(ev->client_if, ev->status);
554 #endif
555 }
556
557 static void handle_client_congestion(void *buf, uint16_t len, int fd)
558 {
559 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
560         struct hal_ev_gatt_client_congestion *ev = buf;
561
562         if (cbs->client->congestion_cb)
563                 cbs->client->congestion_cb(ev->conn_id, ev->congested);
564 #endif
565 }
566
567 static void handle_config_batchscan(void *buf, uint16_t len, int fd)
568 {
569 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
570         struct hal_ev_gatt_client_config_batchscan *ev = buf;
571
572         if (cbs->client->batchscan_cfg_storage_cb)
573                 cbs->client->batchscan_cfg_storage_cb(ev->client_if,
574                                                                 ev->status);
575 #endif
576 }
577
578 static void handle_enable_batchscan(void *buf, uint16_t len, int fd)
579 {
580 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
581         struct hal_ev_gatt_client_enable_batchscan *ev = buf;
582
583         if (cbs->client->batchscan_enb_disable_cb)
584                 cbs->client->batchscan_enb_disable_cb(ev->action, ev->client_if,
585                                                                 ev->status);
586 #endif
587 }
588
589 static void handle_client_batchscan_reports(void *buf, uint16_t len, int fd)
590 {
591 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
592         struct hal_ev_gatt_client_batchscan_reports *ev = buf;
593
594         if (cbs->client->batchscan_reports_cb)
595                 cbs->client->batchscan_reports_cb(ev->client_if, ev->status,
596                                                         ev->format, ev->num,
597                                                         ev->data_len, ev->data);
598 #endif
599 }
600
601 static void handle_batchscan_threshold(void *buf, uint16_t len, int fd)
602 {
603 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
604         struct hal_ev_gatt_client_batchscan_threshold *ev = buf;
605
606         if (cbs->client->batchscan_threshold_cb)
607                 cbs->client->batchscan_threshold_cb(ev->client_if);
608 #endif
609 }
610
611 static void handle_track_adv(void *buf, uint16_t len, int fd)
612 {
613 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
614         struct hal_ev_gatt_client_track_adv *ev = buf;
615
616         if (cbs->client->track_adv_event_cb)
617                 cbs->client->track_adv_event_cb(ev->client_if, ev->filetr_index,
618                                                 ev->address_type,
619                                                 (bt_bdaddr_t *) ev->address,
620                                                 ev->state);
621 #endif
622 }
623
624 static void handle_indication_send(void *buf, uint16_t len, int fd)
625 {
626 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
627         struct hal_ev_gatt_server_indication_sent *ev = buf;
628
629         if (cbs->server->indication_sent_cb)
630                 cbs->server->indication_sent_cb(ev->conn_id, ev->status);
631 #endif
632 }
633
634 static void handle_server_congestion(void *buf, uint16_t len, int fd)
635 {
636 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
637         struct hal_ev_gatt_server_congestion *ev = buf;
638
639         if (cbs->server->congestion_cb)
640                 cbs->server->congestion_cb(ev->conn_id, ev->congested);
641 #endif
642 }
643
644 /*
645  * handlers will be called from notification thread context,
646  * index in table equals to 'opcode - HAL_MINIMUM_EVENT'
647  */
648 static const struct hal_ipc_handler ev_handlers[] = {
649         /* HAL_EV_GATT_CLIENT_REGISTER_CLIENT */
650         { handle_register_client, false,
651                 sizeof(struct hal_ev_gatt_client_register_client) },
652         /* HAL_EV_GATT_CLIENT_SCAN_RESULT */
653         { handle_scan_result, true,
654                 sizeof(struct hal_ev_gatt_client_scan_result) },
655         /* HAL_EV_GATT_CLIENT_CONNECT */
656         { handle_connect, false, sizeof(struct hal_ev_gatt_client_connect) },
657         /* HAL_EV_GATT_CLIENT_DISCONNECT */
658         { handle_disconnect, false,
659                 sizeof(struct hal_ev_gatt_client_disconnect) },
660         /* HAL_EV_GATT_CLIENT_SEARCH_COMPLETE */
661         { handle_search_complete, false,
662                 sizeof(struct hal_ev_gatt_client_search_complete) },
663         /* HAL_EV_GATT_CLIENT_SEARCH_RESULT */
664         { handle_search_result, false,
665                 sizeof(struct hal_ev_gatt_client_search_result) },
666         /* HAL_EV_GATT_CLIENT_GET_CHARACTERISTIC */
667         { handle_get_characteristic, false,
668                 sizeof(struct hal_ev_gatt_client_get_characteristic) },
669         /* HAL_EV_GATT_CLIENT_GET_DESCRIPTOR */
670         { handle_get_descriptor, false,
671                 sizeof(struct hal_ev_gatt_client_get_descriptor) },
672         /* HAL_EV_GATT_CLIENT_GET_INC_SERVICE */
673         { handle_get_included_service, false,
674                 sizeof(struct hal_ev_gatt_client_get_inc_service) },
675         /* HAL_EV_GATT_CLIENT_REGISTER_FOR_NOTIF */
676         { handle_register_for_notification, false,
677                 sizeof(struct hal_ev_gatt_client_reg_for_notif) },
678         /* HAL_EV_GATT_CLIENT_NOTIFY */
679         { handle_notify, true, sizeof(struct hal_ev_gatt_client_notify) },
680         /* HAL_EV_GATT_CLIENT_READ_CHARACTERISTIC */
681         { handle_read_characteristic, true,
682                 sizeof(struct hal_ev_gatt_client_read_characteristic) },
683         /* HAL_EV_GATT_CLIENT_WRITE_CHARACTERISTIC */
684         { handle_write_characteristic, false,
685                 sizeof(struct hal_ev_gatt_client_write_characteristic) },
686         /* HAL_EV_GATT_CLIENT_READ_DESCRIPTOR */
687         { handle_read_descriptor, true,
688                 sizeof(struct hal_ev_gatt_client_read_descriptor) },
689         /* HAL_EV_GATT_CLIENT_WRITE_DESCRIPTOR */
690         { handle_write_descriptor, false,
691                 sizeof(struct hal_ev_gatt_client_write_descriptor) },
692         /* HAL_EV_GATT_CLIENT_EXEC_WRITE */
693         { handle_execute_write, false,
694                 sizeof(struct hal_ev_gatt_client_exec_write) },
695         /* HAL_EV_GATT_CLIENT_READ_REMOTE_RSSI */
696         { handle_read_remote_rssi, false,
697                 sizeof(struct hal_ev_gatt_client_read_remote_rssi) },
698         /* HAL_EV_GATT_CLIENT_LISTEN */
699         { handle_listen, false, sizeof(struct hal_ev_gatt_client_listen) },
700         /* HAL_EV_GATT_SERVER_REGISTER */
701         { handle_register_server, false,
702                 sizeof(struct hal_ev_gatt_server_register) },
703         /* HAL_EV_GATT_SERVER_CONNECTION */
704         { handle_connection, false,
705                 sizeof(struct hal_ev_gatt_server_connection) },
706         /* HAL_EV_GATT_SERVER_SERVICE_ADDED */
707         { handle_service_added, false,
708                 sizeof(struct hal_ev_gatt_server_service_added) },
709         /* HAL_EV_GATT_SERVER_INC_SRVC_ADDED */
710         { handle_included_service_added, false,
711                 sizeof(struct hal_ev_gatt_server_inc_srvc_added) },
712         /* HAL_EV_GATT_SERVER_CHAR_ADDED */
713         { handle_characteristic_added, false,
714                 sizeof(struct hal_ev_gatt_server_characteristic_added) },
715         /* HAL_EV_GATT_SERVER_DESCRIPTOR_ADDED */
716         { handle_descriptor_added, false,
717                 sizeof(struct hal_ev_gatt_server_descriptor_added) },
718         /* HAL_EV_GATT_SERVER_SERVICE_STARTED */
719         { handle_service_started, false,
720                 sizeof(struct hal_ev_gatt_server_service_started) },
721         /* HAL_EV_GATT_SERVER_SERVICE_STOPPED */
722         { handle_service_stopped, false,
723                 sizeof(struct hal_ev_gatt_server_service_stopped) },
724         /* HAL_EV_GATT_SERVER_SERVICE_DELETED */
725         { handle_service_deleted, false,
726                 sizeof(struct hal_ev_gatt_server_service_deleted) },
727         /* HAL_EV_GATT_SERVER_REQUEST_READ */
728         { handle_request_read, false,
729                 sizeof(struct hal_ev_gatt_server_request_read) },
730         /* HAL_EV_GATT_SERVER_REQUEST_WRITE */
731         { handle_request_write, true,
732                 sizeof(struct hal_ev_gatt_server_request_write) },
733         /* HAL_EV_GATT_SERVER_REQUEST_EXEC_WRITE */
734         { handle_request_exec_write, false,
735                 sizeof(struct hal_ev_gatt_server_request_exec_write) },
736         /* HAL_EV_GATT_SERVER_RSP_CONFIRMATION */
737         { handle_response_confirmation, false,
738                 sizeof(struct hal_ev_gatt_server_rsp_confirmation) },
739         /* HAL_EV_GATT_CLIENT_CONFIGURE_MTU */
740         { handle_configure_mtu, false,
741                 sizeof(struct hal_ev_gatt_client_configure_mtu) },
742         /* HAL_EV_GATT_CLIENT_FILTER_CONFIG */
743         { handle_filter_config, false,
744                 sizeof(struct hal_ev_gatt_client_filter_config) },
745         /* HAL_EV_GATT_CLIENT_FILTER_PARAMS */
746         { handle_filter_params, false,
747                 sizeof(struct hal_ev_gatt_client_filter_params) },
748         /* HAL_EV_GATT_CLIENT_FILTER_STATUS */
749         { handle_filter_status, false,
750                 sizeof(struct hal_ev_gatt_client_filter_status) },
751         /* HAL_EV_GATT_CLIENT_MULTI_ADV_ENABLE */
752         { handle__multi_adv_enable, false,
753                 sizeof(struct hal_ev_gatt_client_multi_adv_enable) },
754         /* HAL_EV_GATT_CLIENT_MULTI_ADV_UPDATE */
755         { handle_multi_adv_update, false,
756                 sizeof(struct hal_ev_gatt_client_multi_adv_update) },
757         /* HAL_EV_GATT_CLIENT_MULTI_ADV_DATA */
758         { handle_multi_adv_data, false,
759                 sizeof(struct hal_ev_gatt_client_multi_adv_data) },
760         /* HAL_EV_GATT_CLIENT_MULTI_ADV_DISABLE */
761         { handle_multi_adv_disable, false,
762                 sizeof(struct hal_ev_gatt_client_multi_adv_disable) },
763         /* HAL_EV_GATT_CLIENT_CONGESTION */
764         { handle_client_congestion, false,
765                 sizeof(struct hal_ev_gatt_client_congestion) },
766         /* HAL_EV_GATT_CLIENT_CONFIG_BATCHSCAN */
767         { handle_config_batchscan, false,
768                 sizeof(struct hal_ev_gatt_client_config_batchscan) },
769         /* HAL_EV_GATT_CLIENT_ENABLE_BATCHSCAN */
770         { handle_enable_batchscan, false,
771                 sizeof(struct hal_ev_gatt_client_enable_batchscan) },
772         /* HAL_EV_GATT_CLIENT_BATCHSCAN_REPORTS */
773         { handle_client_batchscan_reports, true,
774                 sizeof(struct hal_ev_gatt_client_batchscan_reports) },
775         /* HAL_EV_GATT_CLIENT_BATCHSCAN_THRESHOLD */
776         { handle_batchscan_threshold, false,
777                 sizeof(struct hal_ev_gatt_client_batchscan_threshold) },
778         /* HAL_EV_GATT_CLIENT_TRACK_ADV */
779         { handle_track_adv, false,
780                 sizeof(struct hal_ev_gatt_client_track_adv) },
781         /* HAL_EV_GATT_SERVER_INDICATION_SENT */
782         { handle_indication_send, false,
783                 sizeof(struct hal_ev_gatt_server_indication_sent) },
784         /* HAL_EV_GATT_SERVER_CONGESTION */
785         { handle_server_congestion, false,
786                 sizeof(struct hal_ev_gatt_server_congestion) },
787         };
788
789 /* Client API */
790
791 static bt_status_t register_client(bt_uuid_t *uuid)
792 {
793         struct hal_cmd_gatt_client_register cmd;
794
795         if (!interface_ready())
796                 return BT_STATUS_NOT_READY;
797
798         memcpy(cmd.uuid, uuid, sizeof(*uuid));
799
800         return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_REGISTER,
801                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
802 }
803
804 static bt_status_t unregister_client(int client_if)
805 {
806         struct hal_cmd_gatt_client_unregister cmd;
807
808         if (!interface_ready())
809                 return BT_STATUS_NOT_READY;
810
811         cmd.client_if = client_if;
812
813         return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_UNREGISTER,
814                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
815 }
816
817 static bt_status_t scan_real(int client_if, bool start)
818 {
819         struct hal_cmd_gatt_client_scan cmd;
820
821         if (!interface_ready())
822                 return BT_STATUS_NOT_READY;
823
824         cmd.client_if = client_if;
825         cmd.start = start;
826
827         return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_SCAN,
828                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
829 }
830
831 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
832 static bt_status_t scan(bool start)
833 {
834         return scan_real(0, start);
835 }
836 #else
837 static bt_status_t scan(int client_if, bool start)
838 {
839         return scan_real(client_if, start);
840 }
841 #endif
842
843 static bt_status_t connect_real(int client_if, const bt_bdaddr_t *bd_addr,
844                                                 bool is_direct, int transport)
845 {
846         struct hal_cmd_gatt_client_connect cmd;
847
848         if (!interface_ready())
849                 return BT_STATUS_NOT_READY;
850
851         cmd.client_if = client_if;
852         cmd.is_direct = is_direct;
853         cmd.transport = transport;
854
855         memcpy(cmd.bdaddr, bd_addr, sizeof(*bd_addr));
856
857         return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_CONNECT,
858                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
859 }
860
861 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
862 static bt_status_t connect(int client_if, const bt_bdaddr_t *bd_addr,
863                                                 bool is_direct, int transport)
864 {
865         return connect_real(client_if, bd_addr, is_direct, transport);
866 }
867 #else
868 static bt_status_t connect(int client_if, const bt_bdaddr_t *bd_addr,
869                                                                 bool is_direct)
870 {
871         return connect_real(client_if, bd_addr, is_direct,
872                                                         BT_TRANSPORT_UNKNOWN);
873 }
874 #endif
875
876 static bt_status_t disconnect(int client_if, const bt_bdaddr_t *bd_addr,
877                                                                 int conn_id)
878 {
879         struct hal_cmd_gatt_client_disconnect cmd;
880
881         if (!interface_ready())
882                 return BT_STATUS_NOT_READY;
883
884         cmd.client_if = client_if;
885         cmd.conn_id = conn_id;
886
887         memcpy(cmd.bdaddr, bd_addr, sizeof(*bd_addr));
888
889         return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_DISCONNECT,
890                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
891 }
892
893 static bt_status_t listen(int client_if, bool start)
894 {
895         struct hal_cmd_gatt_client_listen cmd;
896
897         if (!interface_ready())
898                 return BT_STATUS_NOT_READY;
899
900         cmd.client_if = client_if;
901         cmd.start = start;
902
903         return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_LISTEN,
904                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
905 }
906
907 static bt_status_t refresh(int client_if, const bt_bdaddr_t *bd_addr)
908 {
909         struct hal_cmd_gatt_client_refresh cmd;
910
911         if (!interface_ready())
912                 return BT_STATUS_NOT_READY;
913
914         cmd.client_if = client_if;
915
916         memcpy(cmd.bdaddr, bd_addr, sizeof(*bd_addr));
917
918         return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_REFRESH,
919                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
920 }
921
922 static bt_status_t search_service(int conn_id, bt_uuid_t *filter_uuid)
923 {
924         char buf[IPC_MTU];
925         struct hal_cmd_gatt_client_search_service *cmd = (void *) buf;
926         size_t len = sizeof(*cmd);
927
928         if (!interface_ready())
929                 return BT_STATUS_NOT_READY;
930
931         memset(cmd, 0, sizeof(*cmd));
932
933         cmd->conn_id = conn_id;
934
935         if (filter_uuid) {
936                 memcpy(cmd->filter_uuid, filter_uuid, sizeof(*filter_uuid));
937                 len += sizeof(*filter_uuid);
938                 cmd->filtered = 1;
939         }
940
941         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
942                                         HAL_OP_GATT_CLIENT_SEARCH_SERVICE,
943                                         len, cmd, NULL, NULL, NULL);
944 }
945
946 static bt_status_t get_included_service(int conn_id, btgatt_srvc_id_t *srvc_id,
947                                         btgatt_srvc_id_t *start_incl_srvc_id)
948 {
949         char buf[IPC_MTU];
950         struct hal_cmd_gatt_client_get_included_service *cmd = (void *) buf;
951         size_t len = sizeof(*cmd);
952
953         if (!interface_ready())
954                 return BT_STATUS_NOT_READY;
955
956         cmd->conn_id = conn_id;
957
958         srvc_id_to_hal(&cmd->srvc_id, srvc_id);
959         cmd->continuation = 0;
960
961         if (start_incl_srvc_id) {
962                 srvc_id_to_hal(&cmd->incl_srvc_id[0], start_incl_srvc_id);
963                 len += sizeof(cmd->incl_srvc_id[0]);
964                 cmd->continuation = 1;
965         }
966
967         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
968                                         HAL_OP_GATT_CLIENT_GET_INCLUDED_SERVICE,
969                                         len, cmd, NULL, NULL, NULL);
970 }
971
972 static bt_status_t get_characteristic(int conn_id, btgatt_srvc_id_t *srvc_id,
973                                                 btgatt_gatt_id_t *start_char_id)
974 {
975         char buf[IPC_MTU];
976         struct hal_cmd_gatt_client_get_characteristic *cmd = (void *) buf;
977         size_t len = sizeof(*cmd);
978
979         if (!interface_ready())
980                 return BT_STATUS_NOT_READY;
981
982         cmd->conn_id = conn_id;
983
984         srvc_id_to_hal(&cmd->srvc_id, srvc_id);
985         cmd->continuation = 0;
986
987         if (start_char_id) {
988                 gatt_id_to_hal(&cmd->char_id[0], start_char_id);
989                 len += sizeof(cmd->char_id[0]);
990                 cmd->continuation = 1;
991         }
992
993         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
994                                         HAL_OP_GATT_CLIENT_GET_CHARACTERISTIC,
995                                         len, cmd, NULL, NULL, NULL);
996 }
997
998 static bt_status_t get_descriptor(int conn_id, btgatt_srvc_id_t *srvc_id,
999                                         btgatt_gatt_id_t *char_id,
1000                                         btgatt_gatt_id_t *start_descr_id)
1001 {
1002         char buf[IPC_MTU];
1003         struct hal_cmd_gatt_client_get_descriptor *cmd = (void *) buf;
1004         size_t len = sizeof(*cmd);
1005
1006         if (!interface_ready())
1007                 return BT_STATUS_NOT_READY;
1008
1009         cmd->conn_id = conn_id;
1010
1011         srvc_id_to_hal(&cmd->srvc_id, srvc_id);
1012         gatt_id_to_hal(&cmd->char_id, char_id);
1013         cmd->continuation = 0;
1014
1015         if (start_descr_id) {
1016                 gatt_id_to_hal(&cmd->descr_id[0], start_descr_id);
1017                 len += sizeof(cmd->descr_id[0]);
1018                 cmd->continuation = 1;
1019         }
1020
1021         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1022                                         HAL_OP_GATT_CLIENT_GET_DESCRIPTOR,
1023                                         len, cmd, NULL , NULL, NULL);
1024 }
1025
1026 static bt_status_t read_characteristic(int conn_id, btgatt_srvc_id_t *srvc_id,
1027                                         btgatt_gatt_id_t *char_id,
1028                                         int auth_req)
1029 {
1030         struct hal_cmd_gatt_client_read_characteristic cmd;
1031
1032         if (!interface_ready())
1033                 return BT_STATUS_NOT_READY;
1034
1035         cmd.conn_id = conn_id;
1036         cmd.auth_req = auth_req;
1037
1038         srvc_id_to_hal(&cmd.srvc_id, srvc_id);
1039         gatt_id_to_hal(&cmd.char_id, char_id);
1040
1041         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1042                                         HAL_OP_GATT_CLIENT_READ_CHARACTERISTIC,
1043                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1044 }
1045
1046 static bt_status_t write_characteristic(int conn_id, btgatt_srvc_id_t *srvc_id,
1047                                         btgatt_gatt_id_t *char_id,
1048                                         int write_type, int len, int auth_req,
1049                                         char *p_value)
1050 {
1051         char buf[IPC_MTU];
1052         struct hal_cmd_gatt_client_write_characteristic *cmd = (void *) buf;
1053         size_t cmd_len = sizeof(*cmd) + len;
1054
1055         if (!interface_ready())
1056                 return BT_STATUS_NOT_READY;
1057
1058         cmd->conn_id = conn_id;
1059         cmd->write_type = write_type;
1060         cmd->len = len;
1061         cmd->auth_req = auth_req;
1062
1063         srvc_id_to_hal(&cmd->srvc_id, srvc_id);
1064         gatt_id_to_hal(&cmd->char_id, char_id);
1065
1066         memcpy(cmd->value, p_value, len);
1067
1068         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1069                                         HAL_OP_GATT_CLIENT_WRITE_CHARACTERISTIC,
1070                                         cmd_len, cmd, NULL, NULL, NULL);
1071 }
1072
1073 static bt_status_t read_descriptor(int conn_id, btgatt_srvc_id_t *srvc_id,
1074                                                 btgatt_gatt_id_t *char_id,
1075                                                 btgatt_gatt_id_t *descr_id,
1076                                                 int auth_req)
1077 {
1078         struct hal_cmd_gatt_client_read_descriptor cmd;
1079
1080         if (!interface_ready())
1081                 return BT_STATUS_NOT_READY;
1082
1083         cmd.conn_id = conn_id;
1084         cmd.auth_req = auth_req;
1085
1086         srvc_id_to_hal(&cmd.srvc_id, srvc_id);
1087         gatt_id_to_hal(&cmd.char_id, char_id);
1088         gatt_id_to_hal(&cmd.descr_id, descr_id);
1089
1090         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1091                                         HAL_OP_GATT_CLIENT_READ_DESCRIPTOR,
1092                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1093 }
1094
1095 static bt_status_t write_descriptor(int conn_id, btgatt_srvc_id_t *srvc_id,
1096                                         btgatt_gatt_id_t *char_id,
1097                                         btgatt_gatt_id_t *descr_id,
1098                                         int write_type, int len, int auth_req,
1099                                         char *p_value)
1100 {
1101         char buf[IPC_MTU];
1102         struct hal_cmd_gatt_client_write_descriptor *cmd = (void *) buf;
1103         size_t cmd_len = sizeof(*cmd) + len;
1104
1105         if (!interface_ready())
1106                 return BT_STATUS_NOT_READY;
1107
1108         cmd->conn_id = conn_id;
1109         cmd->write_type = write_type;
1110         cmd->len = len;
1111         cmd->auth_req = auth_req;
1112
1113         srvc_id_to_hal(&cmd->srvc_id, srvc_id);
1114         gatt_id_to_hal(&cmd->char_id, char_id);
1115         gatt_id_to_hal(&cmd->descr_id, descr_id);
1116
1117         memcpy(cmd->value, p_value, len);
1118
1119         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1120                                         HAL_OP_GATT_CLIENT_WRITE_DESCRIPTOR,
1121                                         cmd_len, cmd, NULL, NULL, NULL);
1122 }
1123
1124 static bt_status_t execute_write(int conn_id, int execute)
1125 {
1126         struct hal_cmd_gatt_client_execute_write cmd;
1127
1128         if (!interface_ready())
1129                 return BT_STATUS_NOT_READY;
1130
1131         cmd.conn_id = conn_id;
1132         cmd.execute = execute;
1133
1134         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1135                                         HAL_OP_GATT_CLIENT_EXECUTE_WRITE,
1136                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1137 }
1138
1139 static bt_status_t register_for_notification(int client_if,
1140                                                 const bt_bdaddr_t *bd_addr,
1141                                                 btgatt_srvc_id_t *srvc_id,
1142                                                 btgatt_gatt_id_t *char_id)
1143 {
1144         struct hal_cmd_gatt_client_register_for_notification cmd;
1145
1146         if (!interface_ready())
1147                 return BT_STATUS_NOT_READY;
1148
1149         cmd.client_if = client_if;
1150
1151         memcpy(cmd.bdaddr, bd_addr, sizeof(*bd_addr));
1152
1153         srvc_id_to_hal(&cmd.srvc_id, srvc_id);
1154         gatt_id_to_hal(&cmd.char_id, char_id);
1155
1156         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1157                                 HAL_OP_GATT_CLIENT_REGISTER_FOR_NOTIFICATION,
1158                                 sizeof(cmd), &cmd, NULL, NULL, NULL);
1159 }
1160
1161 static bt_status_t deregister_for_notification(int client_if,
1162                                                 const bt_bdaddr_t *bd_addr,
1163                                                 btgatt_srvc_id_t *srvc_id,
1164                                                 btgatt_gatt_id_t *char_id)
1165 {
1166         struct hal_cmd_gatt_client_deregister_for_notification cmd;
1167
1168         if (!interface_ready())
1169                 return BT_STATUS_NOT_READY;
1170
1171         cmd.client_if = client_if;
1172
1173         memcpy(cmd.bdaddr, bd_addr, sizeof(*bd_addr));
1174
1175         srvc_id_to_hal(&cmd.srvc_id, srvc_id);
1176         gatt_id_to_hal(&cmd.char_id, char_id);
1177
1178         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1179                                 HAL_OP_GATT_CLIENT_DEREGISTER_FOR_NOTIFICATION,
1180                                 sizeof(cmd), &cmd, NULL, NULL, NULL);
1181 }
1182
1183 static bt_status_t read_remote_rssi(int client_if, const bt_bdaddr_t *bd_addr)
1184 {
1185         struct hal_cmd_gatt_client_read_remote_rssi cmd;
1186
1187         if (!interface_ready())
1188                 return BT_STATUS_NOT_READY;
1189
1190         cmd.client_if = client_if;
1191
1192         memcpy(cmd.bdaddr, bd_addr, sizeof(*bd_addr));
1193
1194         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1195                                         HAL_OP_GATT_CLIENT_READ_REMOTE_RSSI,
1196                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1197 }
1198
1199 static int get_device_type(const bt_bdaddr_t *bd_addr)
1200 {
1201         struct hal_cmd_gatt_client_get_device_type cmd;
1202         uint8_t dev_type;
1203         size_t resp_len = sizeof(dev_type);
1204         bt_status_t status;
1205
1206         if (!interface_ready())
1207                 return BT_STATUS_NOT_READY;
1208
1209         memcpy(cmd.bdaddr, bd_addr, sizeof(*bd_addr));
1210
1211         status = hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1212                                 HAL_OP_GATT_CLIENT_GET_DEVICE_TYPE,
1213                                 sizeof(cmd), &cmd, &resp_len, &dev_type, NULL);
1214
1215         if (status != BT_STATUS_SUCCESS || resp_len != sizeof(dev_type))
1216                 return 0;
1217
1218         return dev_type;
1219 }
1220
1221 static bt_status_t set_adv_data_real(int server_if, bool set_scan_rsp,
1222                                 bool include_name, bool include_txpower,
1223                                 int min_interval, int max_interval,
1224                                 int appearance, uint16_t manufacturer_len,
1225                                 char *manufacturer_data,
1226                                 uint16_t service_data_len, char *service_data,
1227                                 uint16_t service_uuid_len, char *service_uuid)
1228 {
1229         char buf[IPC_MTU];
1230         struct hal_cmd_gatt_client_set_adv_data *cmd = (void *) buf;
1231         size_t cmd_len;
1232         uint8_t *data;
1233
1234         if (!interface_ready())
1235                 return BT_STATUS_NOT_READY;
1236
1237         cmd_len = sizeof(*cmd) + manufacturer_len + service_data_len +
1238                                                         service_uuid_len;
1239
1240         if (cmd_len > IPC_MTU)
1241                 return BT_STATUS_FAIL;
1242
1243         cmd->server_if = server_if;
1244         cmd->set_scan_rsp = set_scan_rsp;
1245         cmd->include_name = include_name;
1246         cmd->include_txpower = include_txpower;
1247         cmd->min_interval = min_interval;
1248         cmd->max_interval = max_interval;
1249         cmd->appearance = appearance;
1250         cmd->manufacturer_len = manufacturer_len;
1251         cmd->service_data_len = service_data_len;
1252         cmd->service_uuid_len = service_uuid_len;
1253
1254         data = cmd->data;
1255
1256         if (manufacturer_data && manufacturer_len) {
1257                 memcpy(data, manufacturer_data, manufacturer_len);
1258                 data += manufacturer_len;
1259         }
1260
1261         if (service_data && service_data_len) {
1262                 memcpy(data, service_data, service_data_len);
1263                 data += service_data_len;
1264         }
1265
1266         if (service_uuid && service_uuid_len)
1267                 memcpy(data, service_uuid, service_uuid_len);
1268
1269         return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_SET_ADV_DATA,
1270                                                 cmd_len, cmd, NULL, NULL, NULL);
1271 }
1272
1273 /*
1274  * This is temporary solution and support for older Android versions might
1275  * be removed at any time.
1276  */
1277 #if ANDROID_VERSION < PLATFORM_VER(4, 4, 3)
1278 static bt_status_t set_adv_data(int server_if, bool set_scan_rsp,
1279                                 bool include_name, bool include_txpower,
1280                                 int min_interval, int max_interval,
1281                                 int appearance, uint16_t manufacturer_len,
1282                                 char *manufacturer_data)
1283 {
1284         return set_adv_data_real(server_if, set_scan_rsp, include_name,
1285                                         include_txpower, min_interval,
1286                                         max_interval, appearance,
1287                                         manufacturer_len, manufacturer_data,
1288                                         0, NULL, 0, NULL);
1289 }
1290 #else
1291 static bt_status_t set_adv_data(int server_if, bool set_scan_rsp,
1292                                 bool include_name, bool include_txpower,
1293                                 int min_interval, int max_interval,
1294                                 int appearance, uint16_t manufacturer_len,
1295                                 char *manufacturer_data,
1296                                 uint16_t service_data_len, char *service_data,
1297                                 uint16_t service_uuid_len, char *service_uuid)
1298 {
1299         return set_adv_data_real(server_if, set_scan_rsp, include_name,
1300                                         include_txpower, min_interval,
1301                                         max_interval, appearance,
1302                                         manufacturer_len, manufacturer_data,
1303                                         service_data_len, service_data,
1304                                         service_uuid_len, service_uuid);
1305 }
1306 #endif
1307
1308 static bt_status_t test_command(int command, btgatt_test_params_t *params)
1309 {
1310         struct hal_cmd_gatt_client_test_command cmd;
1311
1312         if (!interface_ready())
1313                 return BT_STATUS_NOT_READY;
1314
1315         cmd.command = command;
1316
1317         memcpy(cmd.bda1, params->bda1, sizeof(*params->bda1));
1318         memcpy(cmd.uuid1, params->uuid1, sizeof(*params->uuid1));
1319
1320         cmd.u1 = params->u1;
1321         cmd.u2 = params->u2;
1322         cmd.u3 = params->u3;
1323         cmd.u4 = params->u4;
1324         cmd.u5 = params->u5;
1325
1326         return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_TEST_COMMAND,
1327                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1328 }
1329
1330 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
1331 static bt_status_t scan_filter_param_setup(int client_if, int action,
1332                                                 int filt_index, int feat_seln,
1333                                                 int list_logic_type,
1334                                                 int filt_logic_type,
1335                                                 int rssi_high_thres,
1336                                                 int rssi_low_thres,
1337                                                 int dely_mode,
1338                                                 int found_timeout,
1339                                                 int lost_timeout,
1340                                                 int found_timeout_cnt)
1341 {
1342         struct hal_cmd_gatt_client_scan_filter_setup cmd;
1343
1344         if (!interface_ready())
1345                 return BT_STATUS_NOT_READY;
1346
1347         cmd.client_if = client_if;
1348         cmd.action = action;
1349         cmd.filter_index = filt_index;
1350         cmd.features = feat_seln;
1351         cmd.list_type = list_logic_type;
1352         cmd.filter_type = filt_logic_type;
1353         cmd.rssi_hi = rssi_high_thres;
1354         cmd.rssi_lo = rssi_low_thres;
1355         cmd.delivery_mode = dely_mode;
1356         cmd.found_timeout = found_timeout;
1357         cmd.lost_timeout = lost_timeout;
1358         cmd.found_timeout_cnt = found_timeout_cnt;
1359
1360         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1361                                         HAL_OP_GATT_CLIENT_SCAN_FILTER_SETUP,
1362                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1363 }
1364
1365 static bt_status_t scan_filter_add_remove(int client_if, int action,
1366                                                 int filt_type, int filt_index,
1367                                                 int company_id,
1368                                                 int company_id_mask,
1369                                                 const bt_uuid_t *p_uuid,
1370                                                 const bt_uuid_t *p_uuid_mask,
1371                                                 const bt_bdaddr_t *bd_addr,
1372                                                 char addr_type,
1373                                                 int data_len, char *p_data,
1374                                                 int mask_len, char *p_mask)
1375 {
1376         char buf[IPC_MTU];
1377         struct hal_cmd_gatt_client_scan_filter_add_remove *cmd = (void *) buf;
1378         size_t cmd_len;
1379
1380         if (!interface_ready())
1381                 return BT_STATUS_NOT_READY;
1382
1383         if (!p_uuid || !p_uuid_mask || !bd_addr)
1384                 return BT_STATUS_PARM_INVALID;
1385
1386         cmd_len = sizeof(*cmd) + data_len + mask_len;
1387         if (cmd_len > IPC_MTU)
1388                 return BT_STATUS_FAIL;
1389
1390         cmd->client_if = client_if;
1391         cmd->action = action;
1392         cmd->filter_type = filt_type;
1393         cmd->filter_index = filt_index;
1394         cmd->company_id = company_id;
1395         cmd->company_id_mask = company_id_mask;
1396         memcpy(cmd->uuid, p_uuid, sizeof(*p_uuid));
1397         memcpy(cmd->uuid_mask, p_uuid_mask, sizeof(*p_uuid_mask));
1398         memcpy(cmd->address, bd_addr, sizeof(*bd_addr));
1399         cmd->address_type = addr_type;
1400
1401         cmd->data_len = data_len;
1402         memcpy(cmd->data_mask, p_data, data_len);
1403
1404         cmd->mask_len = mask_len;
1405         memcpy(cmd->data_mask + data_len, p_mask, mask_len);
1406
1407         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1408                                 HAL_OP_GATT_CLIENT_SCAN_FILTER_ADD_REMOVE,
1409                                 cmd_len, cmd, NULL, NULL, NULL);
1410 }
1411
1412 static bt_status_t scan_filter_clear(int client_if, int filt_index)
1413 {
1414         struct hal_cmd_gatt_client_scan_filter_clear cmd;
1415
1416         if (!interface_ready())
1417                 return BT_STATUS_NOT_READY;
1418
1419         cmd.client_if = client_if;
1420         cmd.index = filt_index;
1421
1422         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1423                                         HAL_OP_GATT_CLIENT_SCAN_FILTER_CLEAR,
1424                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1425 }
1426
1427 static bt_status_t scan_filter_enable(int client_if, bool enable)
1428 {
1429         struct hal_cmd_gatt_client_scan_filter_enable cmd;
1430
1431         if (!interface_ready())
1432                 return BT_STATUS_NOT_READY;
1433
1434         cmd.client_if = client_if;
1435         cmd.enable = enable;
1436
1437         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1438                                         HAL_OP_GATT_CLIENT_SCAN_FILTER_ENABLE,
1439                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1440 }
1441
1442 static bt_status_t configure_mtu(int conn_id, int mtu)
1443 {
1444         struct hal_cmd_gatt_client_configure_mtu cmd;
1445
1446         if (!interface_ready())
1447                 return BT_STATUS_NOT_READY;
1448
1449         cmd.conn_id = conn_id;
1450         cmd.mtu = mtu;
1451
1452         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1453                                         HAL_OP_GATT_CLIENT_CONFIGURE_MTU,
1454                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1455 }
1456
1457 static bt_status_t conn_parameter_update(const bt_bdaddr_t *bd_addr,
1458                                                 int min_interval,
1459                                                 int max_interval, int latency,
1460                                                 int timeout)
1461 {
1462         struct hal_cmd_gatt_client_conn_param_update cmd;
1463
1464         if (!interface_ready())
1465                 return BT_STATUS_NOT_READY;
1466
1467         if (!bd_addr)
1468                 return BT_STATUS_PARM_INVALID;
1469
1470         memcpy(cmd.address, bd_addr, sizeof(*bd_addr));
1471         cmd.min_interval = min_interval;
1472         cmd.max_interval = max_interval;
1473         cmd.latency = latency;
1474         cmd.timeout = timeout;
1475
1476         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1477                                         HAL_OP_GATT_CLIENT_CONN_PARAM_UPDATE,
1478                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1479 }
1480
1481 static bt_status_t set_scan_parameters(int scan_interval, int scan_window)
1482 {
1483         struct hal_cmd_gatt_client_set_scan_param cmd;
1484
1485         if (!interface_ready())
1486                 return BT_STATUS_NOT_READY;
1487
1488         cmd.interval = scan_interval;
1489         cmd.window = scan_window;
1490
1491         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1492                                         HAL_OP_GATT_CLIENT_SET_SCAN_PARAM,
1493                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1494 }
1495
1496 static bt_status_t multi_adv_enable(int client_if, int min_interval,
1497                                         int max_interval, int adv_type,
1498                                         int chnl_map, int tx_power,
1499                                         int timeout_s)
1500 {
1501         struct hal_cmd_gatt_client_setup_multi_adv cmd;
1502
1503         if (!interface_ready())
1504                 return BT_STATUS_NOT_READY;
1505
1506         cmd.client_if = client_if;
1507         cmd.min_interval = min_interval;
1508         cmd.max_interval = max_interval;
1509         cmd.type = adv_type;
1510         cmd.channel_map = chnl_map;
1511         cmd.tx_power = tx_power;
1512         cmd.timeout = timeout_s;
1513
1514         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1515                                         HAL_OP_GATT_CLIENT_SETUP_MULTI_ADV,
1516                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1517 }
1518
1519 static bt_status_t multi_adv_update(int client_if, int min_interval,
1520                                         int max_interval, int adv_type,
1521                                         int chnl_map, int tx_power,
1522                                         int timeout_s)
1523 {
1524         struct hal_cmd_gatt_client_update_multi_adv cmd;
1525
1526         if (!interface_ready())
1527                 return BT_STATUS_NOT_READY;
1528
1529         cmd.client_if = client_if;
1530         cmd.min_interval = min_interval;
1531         cmd.max_interval = max_interval;
1532         cmd.type = adv_type;
1533         cmd.channel_map = chnl_map;
1534         cmd.tx_power = tx_power;
1535         cmd.timeout = timeout_s;
1536
1537         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1538                                         HAL_OP_GATT_CLIENT_UPDATE_MULTI_ADV,
1539                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1540 }
1541
1542 static bt_status_t multi_adv_set_inst_data(int client_if, bool set_scan_rsp,
1543                                                 bool include_name,
1544                                                 bool incl_txpower,
1545                                                 int appearance,
1546                                                 int manufacturer_len,
1547                                                 char *manufacturer_data,
1548                                                 int service_data_len,
1549                                                 char *service_data,
1550                                                 int service_uuid_len,
1551                                                 char *service_uuid)
1552 {
1553         char buf[IPC_MTU];
1554         struct hal_cmd_gatt_client_setup_multi_adv_inst *cmd = (void *) buf;
1555         int off = 0;
1556
1557         if (!interface_ready())
1558                 return BT_STATUS_NOT_READY;
1559
1560         if (manufacturer_len > 0 && !manufacturer_data)
1561                 return BT_STATUS_PARM_INVALID;
1562
1563         if (service_data_len > 0 && !service_data)
1564                 return BT_STATUS_PARM_INVALID;
1565
1566         if (service_uuid_len > 0 && !service_uuid)
1567                 return BT_STATUS_PARM_INVALID;
1568
1569         if (sizeof(*cmd) + manufacturer_len + service_data_len
1570                                                 + service_uuid_len > IPC_MTU)
1571                 return BT_STATUS_FAIL;
1572
1573         cmd->client_if = client_if;
1574         cmd->set_scan_rsp = set_scan_rsp;
1575         cmd->include_name = include_name;
1576         cmd->include_tx_power = incl_txpower;
1577         cmd->appearance = appearance;
1578         cmd->manufacturer_data_len = manufacturer_len;
1579         cmd->service_data_len = service_data_len;
1580         cmd->service_uuid_len = service_uuid_len;
1581
1582         if (manufacturer_len > 0) {
1583                 memcpy(cmd->data_service_uuid, manufacturer_data,
1584                                                         manufacturer_len);
1585                 off += manufacturer_len;
1586         }
1587
1588         if (service_data_len > 0) {
1589                 memcpy(cmd->data_service_uuid + off, service_data,
1590                                                         service_data_len);
1591                 off += service_data_len;
1592         }
1593
1594         if (service_uuid_len > 0) {
1595                 memcpy(cmd->data_service_uuid + off, service_uuid,
1596                                                         service_uuid_len);
1597                 off += service_uuid_len;
1598         }
1599
1600         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1601                                 HAL_OP_GATT_CLIENT_SETUP_MULTI_ADV_INST,
1602                                 sizeof(*cmd) + off, cmd, NULL, NULL, NULL);
1603 }
1604
1605 static bt_status_t multi_adv_disable(int client_if)
1606 {
1607         struct hal_cmd_gatt_client_disable_multi_adv_inst cmd;
1608
1609         if (!interface_ready())
1610                 return BT_STATUS_NOT_READY;
1611
1612         cmd.client_if = client_if;
1613
1614         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1615                                 HAL_OP_GATT_CLIENT_DISABLE_MULTI_ADV_INST,
1616                                 sizeof(cmd), &cmd, NULL, NULL, NULL);
1617 }
1618
1619 static bt_status_t batchscan_cfg_storage(int client_if, int batch_scan_full_max,
1620                                                 int batch_scan_trunc_max,
1621                                                 int batch_scan_notify_threshold)
1622 {
1623         struct hal_cmd_gatt_client_configure_batchscan cmd;
1624
1625         if (!interface_ready())
1626                 return BT_STATUS_NOT_READY;
1627
1628         cmd.client_if = client_if;
1629         cmd.full_max = batch_scan_full_max;
1630         cmd.trunc_max = batch_scan_trunc_max;
1631         cmd.notify_threshold = batch_scan_notify_threshold;
1632
1633         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1634                                         HAL_OP_GATT_CLIENT_CONFIGURE_BATCHSCAN,
1635                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1636 }
1637
1638 static bt_status_t batchscan_enb_batch_scan(int client_if, int scan_mode,
1639                                                 int scan_interval,
1640                                                 int scan_window, int addr_type,
1641                                                 int discard_rule)
1642 {
1643         struct hal_cmd_gatt_client_enable_batchscan cmd;
1644
1645         if (!interface_ready())
1646                 return BT_STATUS_NOT_READY;
1647
1648         cmd.client_if = client_if;
1649         cmd.mode = scan_mode;
1650         cmd.interval = scan_interval;
1651         cmd.window = scan_window;
1652         cmd.address_type = addr_type;
1653         cmd.discard_rule = discard_rule;
1654
1655         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1656                                         HAL_OP_GATT_CLIENT_ENABLE_BATCHSCAN,
1657                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1658 }
1659
1660 static bt_status_t batchscan_dis_batch_scan(int client_if)
1661 {
1662         struct hal_cmd_gatt_client_disable_batchscan cmd;
1663
1664         if (!interface_ready())
1665                 return BT_STATUS_NOT_READY;
1666
1667         cmd.client_if = client_if;
1668
1669         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1670                                         HAL_OP_GATT_CLIENT_DISABLE_BATCHSCAN,
1671                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1672 }
1673
1674 static bt_status_t batchscan_read_reports(int client_if, int scan_mode)
1675 {
1676         struct hal_cmd_gatt_client_read_batchscan_reports cmd;
1677
1678         if (!interface_ready())
1679                 return BT_STATUS_NOT_READY;
1680
1681         cmd.client_if = client_if;
1682         cmd.scan_mode = scan_mode;
1683
1684         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1685                                 HAL_OP_GATT_CLIENT_READ_BATCHSCAN_REPORTS,
1686                                 sizeof(cmd), &cmd, NULL, NULL, NULL);
1687 }
1688 #endif
1689
1690 /* Server API */
1691
1692 static bt_status_t register_server(bt_uuid_t *uuid)
1693 {
1694         struct hal_cmd_gatt_server_register cmd;
1695
1696         if (!interface_ready())
1697                 return BT_STATUS_NOT_READY;
1698
1699         memcpy(cmd.uuid, uuid, sizeof(*uuid));
1700
1701         return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_SERVER_REGISTER,
1702                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1703 }
1704
1705 static bt_status_t unregister_server(int server_if)
1706 {
1707         struct hal_cmd_gatt_server_unregister cmd;
1708
1709         if (!interface_ready())
1710                 return BT_STATUS_NOT_READY;
1711
1712         cmd.server_if = server_if;
1713
1714         return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_SERVER_UNREGISTER,
1715                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1716 }
1717
1718 static bt_status_t server_connect_real(int server_if,
1719                                                 const bt_bdaddr_t *bd_addr,
1720                                                 bool is_direct, int transport)
1721 {
1722         struct hal_cmd_gatt_server_connect cmd;
1723
1724         if (!interface_ready())
1725                 return BT_STATUS_NOT_READY;
1726
1727         cmd.server_if = server_if;
1728         cmd.is_direct = is_direct;
1729         cmd.transport = transport;
1730
1731         memcpy(cmd.bdaddr, bd_addr, sizeof(*bd_addr));
1732
1733         return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_SERVER_CONNECT,
1734                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1735 }
1736
1737 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
1738 static bt_status_t server_connect(int server_if, const bt_bdaddr_t *bd_addr,
1739                                                 bool is_direct, int transport)
1740 {
1741         return server_connect_real(server_if, bd_addr, is_direct, transport);
1742 }
1743 #else
1744 static bt_status_t server_connect(int server_if, const bt_bdaddr_t *bd_addr,
1745                                                                 bool is_direct)
1746 {
1747         return server_connect_real(server_if, bd_addr, is_direct,
1748                                                         BT_TRANSPORT_UNKNOWN);
1749 }
1750 #endif
1751
1752 static bt_status_t server_disconnect(int server_if, const bt_bdaddr_t *bd_addr,
1753                                                                 int conn_id)
1754 {
1755         struct hal_cmd_gatt_server_disconnect cmd;
1756
1757         if (!interface_ready())
1758                 return BT_STATUS_NOT_READY;
1759
1760         cmd.server_if = server_if;
1761         cmd.conn_id = conn_id;
1762
1763         memcpy(cmd.bdaddr, bd_addr, sizeof(*bd_addr));
1764
1765         return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_SERVER_DISCONNECT,
1766                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1767 }
1768
1769 static bt_status_t add_service(int server_if, btgatt_srvc_id_t *srvc_id,
1770                                                                 int num_handles)
1771 {
1772         struct hal_cmd_gatt_server_add_service cmd;
1773
1774         if (!interface_ready())
1775                 return BT_STATUS_NOT_READY;
1776
1777         cmd.server_if = server_if;
1778         cmd.num_handles = num_handles;
1779
1780         srvc_id_to_hal(&cmd.srvc_id, srvc_id);
1781
1782         return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_SERVER_ADD_SERVICE,
1783                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1784 }
1785
1786 static bt_status_t add_included_service(int server_if, int service_handle,
1787                                                 int included_handle)
1788 {
1789         struct hal_cmd_gatt_server_add_inc_service cmd;
1790
1791         if (!interface_ready())
1792                 return BT_STATUS_NOT_READY;
1793
1794         cmd.server_if = server_if;
1795         cmd.service_handle = service_handle;
1796         cmd.included_handle = included_handle;
1797
1798         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1799                                         HAL_OP_GATT_SERVER_ADD_INC_SERVICE,
1800                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1801 }
1802
1803 static bt_status_t add_characteristic(int server_if, int service_handle,
1804                                                 bt_uuid_t *uuid, int properties,
1805                                                 int permissions)
1806 {
1807         struct hal_cmd_gatt_server_add_characteristic cmd;
1808
1809         if (!interface_ready())
1810                 return BT_STATUS_NOT_READY;
1811
1812         cmd.server_if = server_if;
1813         cmd.service_handle = service_handle;
1814         cmd.properties = properties;
1815         cmd.permissions = permissions;
1816
1817         memcpy(cmd.uuid, uuid, sizeof(*uuid));
1818
1819         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1820                                         HAL_OP_GATT_SERVER_ADD_CHARACTERISTIC,
1821                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1822 }
1823
1824 static bt_status_t add_descriptor(int server_if, int service_handle,
1825                                         bt_uuid_t *uuid, int permissions)
1826 {
1827         struct hal_cmd_gatt_server_add_descriptor cmd;
1828
1829         if (!interface_ready())
1830                 return BT_STATUS_NOT_READY;
1831
1832         cmd.server_if = server_if;
1833         cmd.service_handle = service_handle;
1834         cmd.permissions = permissions;
1835
1836         memcpy(cmd.uuid, uuid, sizeof(*uuid));
1837
1838         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1839                                         HAL_OP_GATT_SERVER_ADD_DESCRIPTOR,
1840                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1841 }
1842
1843 static bt_status_t start_service_real(int server_if, int service_handle,
1844                                                                 int transport)
1845 {
1846         struct hal_cmd_gatt_server_start_service cmd;
1847
1848         if (!interface_ready())
1849                 return BT_STATUS_NOT_READY;
1850
1851         cmd.server_if = server_if;
1852         cmd.service_handle = service_handle;
1853         cmd.transport = transport;
1854
1855         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1856                                         HAL_OP_GATT_SERVER_START_SERVICE,
1857                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1858 }
1859
1860 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
1861 static bt_status_t start_service(int server_if, int service_handle,
1862                                                                 int transport)
1863 {
1864         return start_service_real(server_if, service_handle, transport);
1865 }
1866 #else
1867 static bt_status_t start_service(int server_if, int service_handle,
1868                                                                 int transport)
1869 {
1870         int transport_mask = 0;
1871
1872         /* Android 5 changes transport enum to bit mask. */
1873         switch (transport) {
1874         case 0:
1875                 transport_mask = GATT_SERVER_TRANSPORT_LE_BIT;
1876                 break;
1877         case 1:
1878                 transport_mask = GATT_SERVER_TRANSPORT_BREDR_BIT;
1879                 break;
1880         case 2:
1881                 transport_mask = GATT_SERVER_TRANSPORT_LE_BIT |
1882                                                 GATT_SERVER_TRANSPORT_BREDR_BIT;
1883                 break;
1884         }
1885
1886         return start_service_real(server_if, service_handle, transport_mask);
1887 }
1888 #endif
1889
1890 static bt_status_t stop_service(int server_if, int service_handle)
1891 {
1892         struct hal_cmd_gatt_server_stop_service cmd;
1893
1894         if (!interface_ready())
1895                 return BT_STATUS_NOT_READY;
1896
1897         cmd.server_if = server_if;
1898         cmd.service_handle = service_handle;
1899
1900         return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_SERVER_STOP_SERVICE,
1901                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1902 }
1903
1904 static bt_status_t delete_service(int server_if, int service_handle)
1905 {
1906         struct hal_cmd_gatt_server_delete_service cmd;
1907
1908         if (!interface_ready())
1909                 return BT_STATUS_NOT_READY;
1910
1911         cmd.server_if = server_if;
1912         cmd.service_handle = service_handle;
1913
1914         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1915                                         HAL_OP_GATT_SERVER_DELETE_SERVICE,
1916                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1917 }
1918
1919 static bt_status_t send_indication(int server_if, int attribute_handle,
1920                                         int conn_id, int len, int confirm,
1921                                         char *p_value)
1922 {
1923         char buf[IPC_MTU];
1924         struct hal_cmd_gatt_server_send_indication *cmd = (void *) buf;
1925         size_t cmd_len = sizeof(*cmd) + len;
1926
1927         if (!interface_ready())
1928                 return BT_STATUS_NOT_READY;
1929
1930         cmd->server_if = server_if;
1931         cmd->attribute_handle = attribute_handle;
1932         cmd->conn_id = conn_id;
1933         cmd->len = len;
1934         cmd->confirm = confirm;
1935
1936         memcpy(cmd->value, p_value, len);
1937
1938         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1939                                         HAL_OP_GATT_SERVER_SEND_INDICATION,
1940                                         cmd_len, cmd, NULL, NULL, NULL);
1941 }
1942
1943 static bt_status_t send_response(int conn_id, int trans_id, int status,
1944                                                 btgatt_response_t *response)
1945 {
1946         char buf[IPC_MTU];
1947         struct hal_cmd_gatt_server_send_response *cmd = (void *) buf;
1948         size_t cmd_len = sizeof(*cmd) + sizeof(*response);
1949
1950         memset(buf, 0 , IPC_MTU);
1951
1952         if (!interface_ready())
1953                 return BT_STATUS_NOT_READY;
1954
1955         cmd->conn_id = conn_id;
1956         cmd->trans_id = trans_id;
1957         cmd->status = status;
1958         cmd->handle = response->attr_value.handle;
1959         cmd->offset = response->attr_value.offset;
1960         cmd->auth_req = response->attr_value.auth_req;
1961         cmd->len = response->attr_value.len;
1962
1963         memcpy(cmd->data, response->attr_value.value, cmd->len);
1964
1965         return hal_ipc_cmd(HAL_SERVICE_ID_GATT,
1966                                         HAL_OP_GATT_SERVER_SEND_RESPONSE,
1967                                         cmd_len, cmd, NULL, NULL, NULL);
1968 }
1969
1970 static bt_status_t init(const btgatt_callbacks_t *callbacks)
1971 {
1972         struct hal_cmd_register_module cmd;
1973         int ret;
1974
1975         DBG("");
1976
1977         if (interface_ready())
1978                 return BT_STATUS_DONE;
1979
1980         cbs = callbacks;
1981
1982         hal_ipc_register(HAL_SERVICE_ID_GATT, ev_handlers,
1983                                 sizeof(ev_handlers)/sizeof(ev_handlers[0]));
1984
1985         cmd.service_id = HAL_SERVICE_ID_GATT;
1986         cmd.mode = HAL_MODE_DEFAULT;
1987         cmd.max_clients = 1;
1988
1989         ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
1990                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
1991
1992         if (ret != BT_STATUS_SUCCESS) {
1993                 cbs = NULL;
1994                 hal_ipc_unregister(HAL_SERVICE_ID_GATT);
1995         }
1996
1997         return ret;
1998 }
1999
2000 static void cleanup(void)
2001 {
2002         struct hal_cmd_unregister_module cmd;
2003
2004         DBG("");
2005
2006         if (!interface_ready())
2007                 return;
2008
2009         cmd.service_id = HAL_SERVICE_ID_GATT;
2010
2011         hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
2012                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
2013
2014         hal_ipc_unregister(HAL_SERVICE_ID_GATT);
2015
2016         cbs = NULL;
2017 }
2018
2019 static btgatt_client_interface_t client_iface = {
2020         .register_client = register_client,
2021         .unregister_client = unregister_client,
2022         .scan = scan,
2023         .connect = connect,
2024         .disconnect = disconnect,
2025         .listen = listen,
2026         .refresh = refresh,
2027         .search_service = search_service,
2028         .get_included_service = get_included_service,
2029         .get_characteristic = get_characteristic,
2030         .get_descriptor = get_descriptor,
2031         .read_characteristic = read_characteristic,
2032         .write_characteristic = write_characteristic,
2033         .read_descriptor = read_descriptor,
2034         .write_descriptor = write_descriptor,
2035         .execute_write = execute_write,
2036         .register_for_notification = register_for_notification,
2037         .deregister_for_notification = deregister_for_notification,
2038         .read_remote_rssi = read_remote_rssi,
2039 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
2040         .scan_filter_param_setup = scan_filter_param_setup,
2041         .scan_filter_add_remove = scan_filter_add_remove,
2042         .scan_filter_clear = scan_filter_clear,
2043         .scan_filter_enable = scan_filter_enable,
2044 #endif
2045         .get_device_type = get_device_type,
2046         .set_adv_data = set_adv_data,
2047 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
2048         .configure_mtu = configure_mtu,
2049         .conn_parameter_update = conn_parameter_update,
2050         .set_scan_parameters = set_scan_parameters,
2051         .multi_adv_enable = multi_adv_enable,
2052         .multi_adv_update = multi_adv_update,
2053         .multi_adv_set_inst_data = multi_adv_set_inst_data,
2054         .multi_adv_disable = multi_adv_disable,
2055         .batchscan_cfg_storage = batchscan_cfg_storage,
2056         .batchscan_enb_batch_scan = batchscan_enb_batch_scan,
2057         .batchscan_dis_batch_scan = batchscan_dis_batch_scan,
2058         .batchscan_read_reports = batchscan_read_reports,
2059 #endif
2060         .test_command = test_command,
2061 };
2062
2063 static btgatt_server_interface_t server_iface = {
2064         .register_server = register_server,
2065         .unregister_server = unregister_server,
2066         .connect = server_connect,
2067         .disconnect = server_disconnect,
2068         .add_service = add_service,
2069         .add_included_service = add_included_service,
2070         .add_characteristic = add_characteristic,
2071         .add_descriptor = add_descriptor,
2072         .start_service = start_service,
2073         .stop_service = stop_service,
2074         .delete_service = delete_service,
2075         .send_indication = send_indication,
2076         .send_response = send_response,
2077 };
2078
2079 static btgatt_interface_t iface = {
2080         .size = sizeof(iface),
2081         .init = init,
2082         .cleanup = cleanup,
2083         .client = &client_iface,
2084         .server = &server_iface,
2085 };
2086
2087 btgatt_interface_t *bt_get_gatt_interface(void)
2088 {
2089         return &iface;
2090 }