OSDN Git Service

android: fix building errors on android-6.0.1_r52
[android-x86/external-bluetooth-bluez.git] / android / client / if-bt.c
1 /*
2  * Copyright (C) 2013 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 <string.h>
19 #include <inttypes.h>
20
21 #include "if-main.h"
22 #include "terminal.h"
23 #include "../hal-msg.h"
24 #include "../hal-utils.h"
25
26 static hw_device_t *bt_device;
27 const bt_interface_t *if_bluetooth;
28
29 #define VERIFY_PROP_TYPE_ARG(n, typ) \
30         do { \
31                 if (n < argc) \
32                         typ = str2btpropertytype(argv[n]); \
33                 else { \
34                         haltest_error("No property type specified\n"); \
35                         return;\
36                 } \
37         } while (0)
38
39 static bt_scan_mode_t str2btscanmode(const char *str)
40 {
41         bt_scan_mode_t v = str2bt_scan_mode_t(str);
42
43         if ((int) v != -1)
44                 return v;
45
46         haltest_warn("WARN: %s cannot convert %s\n", __func__, str);
47         return (bt_scan_mode_t) atoi(str);
48 }
49
50 static bt_ssp_variant_t str2btsspvariant(const char *str)
51 {
52         bt_ssp_variant_t v = str2bt_ssp_variant_t(str);
53
54         if ((int) v != -1)
55                 return v;
56
57         haltest_warn("WARN: %s cannot convert %s\n", __func__, str);
58         return (bt_ssp_variant_t) atoi(str);
59 }
60
61 static bt_property_type_t str2btpropertytype(const char *str)
62 {
63         bt_property_type_t v = str2bt_property_type_t(str);
64
65         if ((int) v != -1)
66                 return v;
67
68         haltest_warn("WARN: %s cannot convert %s\n", __func__, str);
69         return (bt_property_type_t) atoi(str);
70 }
71
72 static void dump_properties(int num_properties, bt_property_t *properties)
73 {
74         int i;
75
76         for (i = 0; i < num_properties; i++) {
77                 /*
78                  * properities sometimes come unaligned hence memcp to
79                  * aligned buffer
80                  */
81                 bt_property_t prop;
82                 memcpy(&prop, properties + i, sizeof(prop));
83
84                 haltest_info("prop: %s\n", btproperty2str(&prop));
85         }
86 }
87
88 /* Cache for remote devices, stored in sorted array */
89 static bt_bdaddr_t *remote_devices = NULL;
90 static int remote_devices_cnt = 0;
91 static int remote_devices_capacity = 0;
92
93 /* Adds address to remote device set so it can be used in tab completion */
94 void add_remote_device(const bt_bdaddr_t *addr)
95 {
96         int i;
97
98         if (remote_devices == NULL) {
99                 remote_devices = malloc(4 * sizeof(bt_bdaddr_t));
100                 remote_devices_cnt = 0;
101                 if (remote_devices == NULL) {
102                         remote_devices_capacity = 0;
103                         return;
104                 }
105
106                 remote_devices_capacity = 4;
107         }
108
109         /* Array is sorted, search for right place */
110         for (i = 0; i < remote_devices_cnt; ++i) {
111                 int res = memcmp(&remote_devices[i], addr, sizeof(*addr));
112
113                 if (res == 0)
114                         return; /* Already added */
115                 else if (res > 0)
116                         break;
117         }
118
119         /* Realloc space if needed */
120         if (remote_devices_cnt >= remote_devices_capacity) {
121                 bt_bdaddr_t *tmp;
122
123                 remote_devices_capacity *= 2;
124                 /*
125                  * Save reference to previously allocated memory block so that
126                  * it can be freed in case realloc fails.
127                  */
128                 tmp = remote_devices;
129
130                 remote_devices = realloc(remote_devices, sizeof(bt_bdaddr_t) *
131                                                 remote_devices_capacity);
132                 if (remote_devices == NULL) {
133                         free(tmp);
134                         remote_devices_capacity = 0;
135                         remote_devices_cnt = 0;
136                         return;
137                 }
138         }
139
140         if (i < remote_devices_cnt)
141                 memmove(remote_devices + i + 1, remote_devices + i,
142                                 (remote_devices_cnt - i) * sizeof(bt_bdaddr_t));
143         remote_devices[i] = *addr;
144         remote_devices_cnt++;
145 }
146
147 const char *enum_devices(void *v, int i)
148 {
149         static char buf[MAX_ADDR_STR_LEN];
150
151         if (i >= remote_devices_cnt)
152                 return NULL;
153
154         bt_bdaddr_t2str(&remote_devices[i], buf);
155         return buf;
156 }
157
158 static void add_remote_device_from_props(int num_properties,
159                                                 const bt_property_t *properties)
160 {
161         int i;
162
163         for (i = 0; i < num_properties; i++) {
164                 /*
165                  * properities sometimes come unaligned hence memcp to
166                  * aligned buffer
167                  */
168                 bt_property_t property;
169
170                 memcpy(&property, properties + i, sizeof(property));
171                 if (property.type == BT_PROPERTY_BDADDR)
172                         add_remote_device((bt_bdaddr_t *) property.val);
173         }
174 }
175
176 bool close_hw_bt_dev(void)
177 {
178         if (!bt_device)
179                 return false;
180
181         bt_device->close(bt_device);
182         return true;
183 }
184
185 static void adapter_state_changed_cb(bt_state_t state)
186 {
187         haltest_info("%s: state=%s\n", __func__, bt_state_t2str(state));
188 }
189
190 static void adapter_properties_cb(bt_status_t status, int num_properties,
191                                                 bt_property_t *properties)
192 {
193         haltest_info("%s: status=%s num_properties=%d\n", __func__,
194                                 bt_status_t2str(status), num_properties);
195
196         dump_properties(num_properties, properties);
197 }
198
199 static void remote_device_properties_cb(bt_status_t status,
200                                         bt_bdaddr_t *bd_addr,
201                                         int num_properties,
202                                         bt_property_t *properties)
203 {
204         haltest_info("%s: status=%s bd_addr=%s num_properties=%d\n", __func__,
205                         bt_status_t2str(status), bdaddr2str(bd_addr),
206                         num_properties);
207
208         add_remote_device(bd_addr);
209
210         dump_properties(num_properties, properties);
211 }
212
213 static void device_found_cb(int num_properties, bt_property_t *properties)
214 {
215         haltest_info("%s: num_properties=%d\n", __func__, num_properties);
216
217         add_remote_device_from_props(num_properties, properties);
218
219         dump_properties(num_properties, properties);
220 }
221
222 static void discovery_state_changed_cb(bt_discovery_state_t state)
223 {
224         haltest_info("%s: state=%s\n", __func__,
225                                         bt_discovery_state_t2str(state));
226 }
227
228 /*
229  * Buffer for remote addres that came from one of bind request.
230  * It's stored for command completion.
231  */
232 static char last_remote_addr[MAX_ADDR_STR_LEN];
233 static bt_ssp_variant_t last_ssp_variant = (bt_ssp_variant_t) -1;
234
235 static bt_bdaddr_t pin_request_addr;
236 static void pin_request_answer(char *reply)
237 {
238         bt_pin_code_t pin;
239         int accept = 0;
240         int pin_len = strlen(reply);
241
242         if (pin_len > 0) {
243                 accept = 1;
244                 if (pin_len > 16)
245                         pin_len = 16;
246                 memcpy(&pin.pin, reply, pin_len);
247         }
248
249         EXEC(if_bluetooth->pin_reply, &pin_request_addr, accept, pin_len, &pin);
250 }
251
252 static void pin_request_cb(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *bd_name,
253 #if ANDROID_VERSION >= PLATFORM_VER(6, 0, 1)
254                                                         uint32_t cod, bool u)
255 #else
256                                                                 uint32_t cod)
257 #endif
258 {
259         /* Store for command completion */
260         bt_bdaddr_t2str(remote_bd_addr, last_remote_addr);
261         pin_request_addr = *remote_bd_addr;
262
263         haltest_info("%s: remote_bd_addr=%s bd_name=%s cod=%06x\n", __func__,
264                                         last_remote_addr, bd_name->name, cod);
265         terminal_prompt_for("Enter pin: ", pin_request_answer);
266 }
267
268 /* Variables to store information from ssp_request_cb used for ssp_reply */
269 static bt_bdaddr_t ssp_request_addr;
270 static bt_ssp_variant_t ssp_request_variant;
271 static uint32_t ssp_request_pask_key;
272
273 /* Called when user hit enter on prompt for confirmation */
274 static void ssp_request_yes_no_answer(char *reply)
275 {
276         int accept = *reply == 0 || *reply == 'y' || *reply == 'Y';
277
278         if_bluetooth->ssp_reply(&ssp_request_addr, ssp_request_variant, accept,
279                                                         ssp_request_pask_key);
280 }
281
282 static void ssp_request_cb(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *bd_name,
283                                 uint32_t cod, bt_ssp_variant_t pairing_variant,
284                                 uint32_t pass_key)
285 {
286         static char prompt[50];
287
288         /* Store for command completion */
289         bt_bdaddr_t2str(remote_bd_addr, last_remote_addr);
290         last_ssp_variant = pairing_variant;
291
292         haltest_info("%s: remote_bd_addr=%s bd_name=%s cod=%06x pairing_variant=%s pass_key=%d\n",
293                         __func__, last_remote_addr, bd_name->name, cod,
294                         bt_ssp_variant_t2str(pairing_variant), pass_key);
295
296         switch (pairing_variant) {
297         case BT_SSP_VARIANT_PASSKEY_CONFIRMATION:
298                 sprintf(prompt, "Does other device show %d [Y/n] ?", pass_key);
299
300                 ssp_request_addr = *remote_bd_addr;
301                 ssp_request_variant = pairing_variant;
302                 ssp_request_pask_key = pass_key;
303
304                 terminal_prompt_for(prompt, ssp_request_yes_no_answer);
305                 break;
306         case BT_SSP_VARIANT_CONSENT:
307                 sprintf(prompt, "Consent pairing [Y/n] ?");
308
309                 ssp_request_addr = *remote_bd_addr;
310                 ssp_request_variant = pairing_variant;
311                 ssp_request_pask_key = 0;
312
313                 terminal_prompt_for(prompt, ssp_request_yes_no_answer);
314                 break;
315         case BT_SSP_VARIANT_PASSKEY_ENTRY:
316         case BT_SSP_VARIANT_PASSKEY_NOTIFICATION:
317         default:
318                 haltest_info("Not automatically handled\n");
319                 break;
320         }
321 }
322
323 static void bond_state_changed_cb(bt_status_t status,
324                                                 bt_bdaddr_t *remote_bd_addr,
325                                                 bt_bond_state_t state)
326 {
327         haltest_info("%s: status=%s remote_bd_addr=%s state=%s\n", __func__,
328                         bt_status_t2str(status), bdaddr2str(remote_bd_addr),
329                         bt_bond_state_t2str(state));
330 }
331
332 static void acl_state_changed_cb(bt_status_t status,
333                                                 bt_bdaddr_t *remote_bd_addr,
334                                                 bt_acl_state_t state)
335 {
336         haltest_info("%s: status=%s remote_bd_addr=%s state=%s\n", __func__,
337                         bt_status_t2str(status), bdaddr2str(remote_bd_addr),
338                         bt_acl_state_t2str(state));
339 }
340
341 static void thread_evt_cb(bt_cb_thread_evt evt)
342 {
343         haltest_info("%s: evt=%s\n", __func__, bt_cb_thread_evt2str(evt));
344 }
345
346 static void dut_mode_recv_cb(uint16_t opcode, uint8_t *buf, uint8_t len)
347 {
348         haltest_info("%s\n", __func__);
349 }
350
351 static void le_test_mode_cb(bt_status_t status, uint16_t num_packets)
352 {
353         haltest_info("%s %s %d\n", __func__, bt_status_t2str(status),
354                                                                 num_packets);
355 }
356
357 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
358 static void energy_info_cb(bt_activity_energy_info *energy_info)
359 {
360         haltest_info("%s status=%s, ctrl_state=0x%02X, tx_time=0x%jx,"
361                         "rx_time=0x%jx, idle_time=0x%jx, energu_used=0x%jx\n",
362                         __func__, bt_status_t2str(energy_info->status),
363                         energy_info->ctrl_state, energy_info->tx_time,
364                         energy_info->rx_time, energy_info->idle_time,
365                         energy_info->energy_used);
366 }
367 #endif
368
369 static bt_callbacks_t bt_callbacks = {
370         .size = sizeof(bt_callbacks),
371         .adapter_state_changed_cb = adapter_state_changed_cb,
372         .adapter_properties_cb = adapter_properties_cb,
373         .remote_device_properties_cb = remote_device_properties_cb,
374         .device_found_cb = device_found_cb,
375         .discovery_state_changed_cb = discovery_state_changed_cb,
376         .pin_request_cb = pin_request_cb,
377         .ssp_request_cb = ssp_request_cb,
378         .bond_state_changed_cb = bond_state_changed_cb,
379         .acl_state_changed_cb = acl_state_changed_cb,
380         .thread_evt_cb = thread_evt_cb,
381         .dut_mode_recv_cb = dut_mode_recv_cb,
382         .le_test_mode_cb = le_test_mode_cb,
383 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
384         .energy_info_cb = energy_info_cb,
385 #endif
386 };
387
388 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
389 static alarm_cb alarm_cb_p = NULL;
390 static void *alarm_cb_p_data = NULL;
391
392 static bool set_wake_alarm(uint64_t delay_millis, bool should_wake, alarm_cb cb,
393                                                                 void *data)
394 {
395         haltest_info("%s: delay %"PRIu64" should_wake %u cb %p data %p\n",
396                                 __func__, delay_millis, should_wake, cb, data);
397
398         /* TODO call alarm callback after specified delay */
399         alarm_cb_p = cb;
400         alarm_cb_p_data = data;
401
402         return true;
403 }
404
405 static int acquire_wake_lock(const char *lock_name)
406 {
407         haltest_info("%s: %s\n", __func__, lock_name);
408
409         return BT_STATUS_SUCCESS;
410 }
411
412 static int release_wake_lock(const char *lock_name)
413 {
414         haltest_info("%s: %s\n", __func__, lock_name);
415
416         return BT_STATUS_SUCCESS;
417 }
418
419 static bt_os_callouts_t bt_os_callouts = {
420         .size = sizeof(bt_os_callouts),
421         .set_wake_alarm = set_wake_alarm,
422         .acquire_wake_lock = acquire_wake_lock,
423         .release_wake_lock = release_wake_lock,
424 };
425 #endif
426
427 static void init_p(int argc, const char **argv)
428 {
429         int err;
430         const hw_module_t *module;
431
432         err = hw_get_module(BT_HARDWARE_MODULE_ID, &module);
433         if (err) {
434                 haltest_error("he_get_module returned %d\n", err);
435                 return;
436         }
437
438         err = module->methods->open(module, BT_HARDWARE_MODULE_ID, &bt_device);
439         if (err) {
440                 haltest_error("module->methods->open returned %d\n", err);
441                 return;
442         }
443
444         if_bluetooth =
445                 ((bluetooth_device_t *) bt_device)->get_bluetooth_interface();
446         if (!if_bluetooth) {
447                 haltest_error("get_bluetooth_interface returned NULL\n");
448                 return;
449         }
450
451         EXEC(if_bluetooth->init, &bt_callbacks);
452
453 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
454         EXEC(if_bluetooth->set_os_callouts, &bt_os_callouts);
455 #endif
456 }
457
458 static void cleanup_p(int argc, const char **argv)
459 {
460         RETURN_IF_NULL(if_bluetooth);
461
462         EXECV(if_bluetooth->cleanup);
463
464         if_bluetooth = NULL;
465 }
466
467 static void enable_p(int argc, const char **argv)
468 {
469         RETURN_IF_NULL(if_bluetooth);
470
471 #if ANDROID_VERSION >= PLATFORM_VER(6, 0, 1)
472         EXEC(if_bluetooth->enable, false);
473 #else
474         EXEC(if_bluetooth->enable);
475 #endif
476 }
477 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
478 static void read_energy_info_p(int argc, const char **argv)
479 {
480         RETURN_IF_NULL(if_bluetooth);
481
482         EXEC(if_bluetooth->read_energy_info);
483 }
484
485 #define get_connection_state_c complete_addr_c
486
487 static void get_connection_state_p(int argc, const char **argv)
488 {
489         bt_bdaddr_t addr;
490
491         RETURN_IF_NULL(if_bluetooth);
492
493         VERIFY_ADDR_ARG(2, &addr);
494
495         haltest_info("if_bluetooth->get_connection_state : %d\n",
496                                 if_bluetooth->get_connection_state(&addr));
497 }
498 #endif
499
500 static void disable_p(int argc, const char **argv)
501 {
502         RETURN_IF_NULL(if_bluetooth);
503
504         EXEC(if_bluetooth->disable);
505 }
506
507 static void get_adapter_properties_p(int argc, const char **argv)
508 {
509         RETURN_IF_NULL(if_bluetooth);
510
511         EXEC(if_bluetooth->get_adapter_properties);
512 }
513
514 static void get_adapter_property_c(int argc, const char **argv,
515                                         enum_func *enum_func, void **user)
516 {
517         if (argc == 3) {
518                 *user = TYPE_ENUM(bt_property_type_t);
519                 *enum_func = enum_defines;
520         }
521 }
522
523 static void get_adapter_property_p(int argc, const char **argv)
524 {
525         int type;
526
527         RETURN_IF_NULL(if_bluetooth);
528         VERIFY_PROP_TYPE_ARG(2, type);
529
530         EXEC(if_bluetooth->get_adapter_property, type);
531 }
532
533 static const char * const names[] = {
534         "BT_PROPERTY_BDNAME",
535         "BT_PROPERTY_ADAPTER_SCAN_MODE",
536         "BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT",
537         NULL
538 };
539
540 static void set_adapter_property_c(int argc, const char **argv,
541                                         enum_func *enum_func, void **user)
542 {
543         if (argc == 3) {
544                 *user = (void *) names;
545                 *enum_func = enum_strings;
546         } else if (argc == 4) {
547                 if (0 == strcmp(argv[2], "BT_PROPERTY_ADAPTER_SCAN_MODE")) {
548                         *user = TYPE_ENUM(bt_scan_mode_t);
549                         *enum_func = enum_defines;
550                 }
551         }
552 }
553
554 static void set_adapter_property_p(int argc, const char **argv)
555 {
556         bt_property_t property;
557         bt_scan_mode_t mode;
558         int timeout;
559
560         RETURN_IF_NULL(if_bluetooth);
561         VERIFY_PROP_TYPE_ARG(2, property.type);
562
563         if (argc <= 3) {
564                 haltest_error("No property value specified\n");
565                 return;
566         }
567         switch (property.type) {
568         case BT_PROPERTY_BDNAME:
569                 property.len = strlen(argv[3]) + 1;
570                 property.val = (char *) argv[3];
571                 break;
572
573         case BT_PROPERTY_ADAPTER_SCAN_MODE:
574                 mode = str2btscanmode(argv[3]);
575                 property.len = sizeof(bt_scan_mode_t);
576                 property.val = &mode;
577                 break;
578
579         case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
580                 timeout = atoi(argv[3]);
581                 property.val = &timeout;
582                 property.len = sizeof(timeout);
583                 break;
584
585         case BT_PROPERTY_BDADDR:
586         case BT_PROPERTY_UUIDS:
587         case BT_PROPERTY_CLASS_OF_DEVICE:
588         case BT_PROPERTY_TYPE_OF_DEVICE:
589         case BT_PROPERTY_SERVICE_RECORD:
590         case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
591         case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
592         case BT_PROPERTY_REMOTE_RSSI:
593         case BT_PROPERTY_REMOTE_VERSION_INFO:
594         case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP:
595 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
596         case BT_PROPERTY_LOCAL_LE_FEATURES:
597 #endif
598         default:
599                 haltest_error("Invalid property %s\n", argv[3]);
600                 return;
601         }
602
603         EXEC(if_bluetooth->set_adapter_property, &property);
604 }
605
606 /* This function is to be used for completion methods that need only address */
607 static void complete_addr_c(int argc, const char **argv, enum_func *enum_func,
608                                                                 void **user)
609 {
610         if (argc == 3) {
611                 *user = NULL;
612                 *enum_func = enum_devices;
613         }
614 }
615
616 /* Just addres to complete, use complete_addr_c */
617 #define get_remote_device_properties_c complete_addr_c
618
619 static void get_remote_device_properties_p(int argc, const char **argv)
620 {
621         bt_bdaddr_t addr;
622
623         RETURN_IF_NULL(if_bluetooth);
624         VERIFY_ADDR_ARG(2, &addr);
625
626         EXEC(if_bluetooth->get_remote_device_properties, &addr);
627 }
628
629 static void get_remote_device_property_c(int argc, const char **argv,
630                                                         enum_func *enum_func,
631                                                         void **user)
632 {
633         if (argc == 3) {
634                 *user = NULL;
635                 *enum_func = enum_devices;
636         } else if (argc == 4) {
637                 *user = TYPE_ENUM(bt_property_type_t);
638                 *enum_func = enum_defines;
639         }
640 }
641
642 static void get_remote_device_property_p(int argc, const char **argv)
643 {
644         bt_property_type_t type;
645         bt_bdaddr_t addr;
646
647         RETURN_IF_NULL(if_bluetooth);
648         VERIFY_ADDR_ARG(2, &addr);
649         VERIFY_PROP_TYPE_ARG(3, type);
650
651         EXEC(if_bluetooth->get_remote_device_property, &addr, type);
652 }
653
654 /*
655  * Same completion as for get_remote_device_property_c can be used for
656  * set_remote_device_property_c. No need to create separate function.
657  */
658 #define set_remote_device_property_c get_remote_device_property_c
659
660 static void set_remote_device_property_p(int argc, const char **argv)
661 {
662         bt_property_t property;
663         bt_bdaddr_t addr;
664
665         RETURN_IF_NULL(if_bluetooth);
666         VERIFY_ADDR_ARG(2, &addr);
667         VERIFY_PROP_TYPE_ARG(3, property.type);
668
669         switch (property.type) {
670         case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
671                 property.len = strlen(argv[4]);
672                 property.val = (char *) argv[4];
673                 break;
674         case BT_PROPERTY_BDNAME:
675         case BT_PROPERTY_BDADDR:
676         case BT_PROPERTY_UUIDS:
677         case BT_PROPERTY_CLASS_OF_DEVICE:
678         case BT_PROPERTY_TYPE_OF_DEVICE:
679         case BT_PROPERTY_SERVICE_RECORD:
680         case BT_PROPERTY_ADAPTER_SCAN_MODE:
681         case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
682         case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
683         case BT_PROPERTY_REMOTE_RSSI:
684         case BT_PROPERTY_REMOTE_VERSION_INFO:
685         case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP:
686 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
687         case BT_PROPERTY_LOCAL_LE_FEATURES:
688 #endif
689         default:
690                 return;
691         }
692
693         EXEC(if_bluetooth->set_remote_device_property, &addr, &property);
694 }
695
696 /* For now uuid is not autocompleted. Use routine for complete_addr_c */
697 #define get_remote_service_record_c complete_addr_c
698
699 static void get_remote_service_record_p(int argc, const char **argv)
700 {
701         bt_bdaddr_t addr;
702         bt_uuid_t uuid;
703
704         RETURN_IF_NULL(if_bluetooth);
705         VERIFY_ADDR_ARG(2, &addr);
706
707         if (argc <= 3) {
708                 haltest_error("No uuid specified\n");
709                 return;
710         }
711
712         str2bt_uuid_t(argv[3], &uuid);
713
714         EXEC(if_bluetooth->get_remote_service_record, &addr, &uuid);
715 }
716
717 /* Just addres to complete, use complete_addr_c */
718 #define get_remote_services_c complete_addr_c
719
720 static void get_remote_services_p(int argc, const char **argv)
721 {
722         bt_bdaddr_t addr;
723
724         RETURN_IF_NULL(if_bluetooth);
725         VERIFY_ADDR_ARG(2, &addr);
726
727         EXEC(if_bluetooth->get_remote_services, &addr);
728 }
729
730 static void start_discovery_p(int argc, const char **argv)
731 {
732         RETURN_IF_NULL(if_bluetooth);
733
734         EXEC(if_bluetooth->start_discovery);
735 }
736
737 static void cancel_discovery_p(int argc, const char **argv)
738 {
739         RETURN_IF_NULL(if_bluetooth);
740
741         EXEC(if_bluetooth->cancel_discovery);
742 }
743
744 /* Just addres to complete, use complete_addr_c */
745 #define create_bond_c complete_addr_c
746
747 static void create_bond_p(int argc, const char **argv)
748 {
749         bt_bdaddr_t addr;
750 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
751         int transport;
752 #endif
753
754         RETURN_IF_NULL(if_bluetooth);
755         VERIFY_ADDR_ARG(2, &addr);
756
757 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
758         if (argc < 4)
759                 transport = BT_TRANSPORT_UNKNOWN;
760         else
761                 transport = atoi(argv[3]);
762
763         EXEC(if_bluetooth->create_bond, &addr, transport);
764 #else
765         EXEC(if_bluetooth->create_bond, &addr);
766 #endif
767 }
768
769 /* Just addres to complete, use complete_addr_c */
770 #define remove_bond_c complete_addr_c
771
772 static void remove_bond_p(int argc, const char **argv)
773 {
774         bt_bdaddr_t addr;
775
776         RETURN_IF_NULL(if_bluetooth);
777         VERIFY_ADDR_ARG(2, &addr);
778
779         EXEC(if_bluetooth->remove_bond, &addr);
780 }
781
782 /* Just addres to complete, use complete_addr_c */
783 #define cancel_bond_c complete_addr_c
784
785 static void cancel_bond_p(int argc, const char **argv)
786 {
787         bt_bdaddr_t addr;
788
789         RETURN_IF_NULL(if_bluetooth);
790         VERIFY_ADDR_ARG(2, &addr);
791
792         EXEC(if_bluetooth->cancel_bond, &addr);
793 }
794
795 static void pin_reply_c(int argc, const char **argv, enum_func *enum_func,
796                                                                 void **user)
797 {
798         static const char *const completions[] = { last_remote_addr, NULL };
799
800         if (argc == 3) {
801                 *user = (void *) completions;
802                 *enum_func = enum_strings;
803         }
804 }
805
806 static void pin_reply_p(int argc, const char **argv)
807 {
808         bt_bdaddr_t addr;
809         bt_pin_code_t pin;
810         int pin_len = 0;
811         int accept = 0;
812
813         RETURN_IF_NULL(if_bluetooth);
814         VERIFY_ADDR_ARG(2, &addr);
815
816         if (argc > 3) {
817                 accept = 1;
818                 pin_len = strlen(argv[3]);
819                 memcpy(pin.pin, argv[3], pin_len);
820         }
821
822         EXEC(if_bluetooth->pin_reply, &addr, accept, pin_len, &pin);
823 }
824
825 static void ssp_reply_c(int argc, const char **argv, enum_func *enum_func,
826                                                                 void **user)
827 {
828         if (argc == 3) {
829                 *user = last_remote_addr;
830                 *enum_func = enum_one_string;
831         } else if (argc == 5) {
832                 *user = "1";
833                 *enum_func = enum_one_string;
834         } else if (argc == 4) {
835                 if (-1 != (int) last_ssp_variant) {
836                         *user = (void *) bt_ssp_variant_t2str(last_ssp_variant);
837                         *enum_func = enum_one_string;
838                 } else {
839                         *user = TYPE_ENUM(bt_ssp_variant_t);
840                         *enum_func = enum_defines;
841                 }
842         }
843 }
844
845 static void ssp_reply_p(int argc, const char **argv)
846 {
847         bt_bdaddr_t addr;
848         bt_ssp_variant_t var;
849         int accept;
850         int passkey;
851
852         RETURN_IF_NULL(if_bluetooth);
853         VERIFY_ADDR_ARG(2, &addr);
854
855         if (argc < 4) {
856                 haltest_error("No ssp variant specified\n");
857                 return;
858         }
859
860         var = str2btsspvariant(argv[3]);
861         if (argc < 5) {
862                 haltest_error("No accept value specified\n");
863                 return;
864         }
865
866         accept = atoi(argv[4]);
867         passkey = 0;
868
869         if (accept && var == BT_SSP_VARIANT_PASSKEY_ENTRY && argc >= 5)
870                 passkey = atoi(argv[4]);
871
872         EXEC(if_bluetooth->ssp_reply, &addr, var, accept, passkey);
873 }
874
875 static void get_profile_interface_c(int argc, const char **argv,
876                                         enum_func *enum_func, void **user)
877 {
878         static const char *const profile_ids[] = {
879                 BT_PROFILE_HANDSFREE_ID,
880                 BT_PROFILE_ADVANCED_AUDIO_ID,
881                 BT_PROFILE_HEALTH_ID,
882                 BT_PROFILE_SOCKETS_ID,
883                 BT_PROFILE_HIDHOST_ID,
884                 BT_PROFILE_PAN_ID,
885                 BT_PROFILE_GATT_ID,
886                 BT_PROFILE_AV_RC_ID,
887 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
888                 BT_PROFILE_HANDSFREE_CLIENT_ID,
889                 BT_PROFILE_MAP_CLIENT_ID,
890                 BT_PROFILE_AV_RC_CTRL_ID,
891                 BT_PROFILE_ADVANCED_AUDIO_SINK_ID,
892 #endif
893                 NULL
894         };
895
896         if (argc == 3) {
897                 *user = (void *) profile_ids;
898                 *enum_func = enum_strings;
899         }
900 }
901
902 static void get_profile_interface_p(int argc, const char **argv)
903 {
904         const char *id;
905         const void **pif = NULL;
906
907         RETURN_IF_NULL(if_bluetooth);
908         if (argc <= 2) {
909                 haltest_error("No interface specified\n");
910                 return;
911         }
912
913         id = argv[2];
914
915         if (strcmp(BT_PROFILE_HANDSFREE_ID, id) == 0)
916                 pif = (const void **) &if_hf;
917         else if (strcmp(BT_PROFILE_ADVANCED_AUDIO_ID, id) == 0)
918                 pif = (const void **) &if_av;
919         else if (strcmp(BT_PROFILE_HEALTH_ID, id) == 0)
920                 pif = (const void **) &if_hl;
921         else if (strcmp(BT_PROFILE_SOCKETS_ID, id) == 0)
922                 pif = (const void **) &if_sock;
923         else if (strcmp(BT_PROFILE_HIDHOST_ID, id) == 0)
924                 pif = (const void **) &if_hh;
925         else if (strcmp(BT_PROFILE_PAN_ID, id) == 0)
926                 pif = (const void **) &if_pan;
927         else if (strcmp(BT_PROFILE_AV_RC_ID, id) == 0)
928                 pif = (const void **) &if_rc;
929         else if (strcmp(BT_PROFILE_GATT_ID, id) == 0)
930                 pif = (const void **) &if_gatt;
931 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
932         else if (strcmp(BT_PROFILE_AV_RC_CTRL_ID, id) == 0)
933                 pif = (const void **) &if_rc_ctrl;
934         else if (strcmp(BT_PROFILE_HANDSFREE_CLIENT_ID, id) == 0)
935                 pif = (const void **) &if_hf_client;
936         else if (strcmp(BT_PROFILE_MAP_CLIENT_ID, id) == 0)
937                 pif = (const void **) &if_mce;
938         else if (strcmp(BT_PROFILE_ADVANCED_AUDIO_SINK_ID, id) == 0)
939                 pif = (const void **) &if_av_sink;
940 #endif
941         else
942                 haltest_error("%s is not correct for get_profile_interface\n",
943                                                                         id);
944
945         if (pif != NULL) {
946                 *pif = if_bluetooth->get_profile_interface(id);
947                 haltest_info("get_profile_interface(%s) : %p\n", id, *pif);
948         }
949 }
950
951 static void dut_mode_configure_p(int argc, const char **argv)
952 {
953         uint8_t mode;
954
955         RETURN_IF_NULL(if_bluetooth);
956
957         if (argc <= 2) {
958                 haltest_error("No dut mode specified\n");
959                 return;
960         }
961
962         mode = strtol(argv[2], NULL, 0);
963
964         EXEC(if_bluetooth->dut_mode_configure, mode);
965 }
966
967 static void dut_mode_send_p(int argc, const char **argv)
968 {
969         haltest_error("not implemented\n");
970 }
971
972 static void le_test_mode_p(int argc, const char **argv)
973 {
974         haltest_error("not implemented\n");
975 }
976
977 static void config_hci_snoop_log_p(int argc, const char **argv)
978 {
979         uint8_t mode;
980
981         RETURN_IF_NULL(if_bluetooth);
982
983         if (argc <= 2) {
984                 haltest_error("No mode specified\n");
985                 return;
986         }
987
988         mode = strtol(argv[2], NULL, 0);
989
990         EXEC(if_bluetooth->config_hci_snoop_log, mode);
991 }
992
993 static struct method methods[] = {
994         STD_METHOD(init),
995         STD_METHOD(cleanup),
996         STD_METHOD(enable),
997         STD_METHOD(disable),
998         STD_METHOD(get_adapter_properties),
999         STD_METHODCH(get_adapter_property, "<prop_type>"),
1000         STD_METHODCH(set_adapter_property, "<prop_type> <prop_value>"),
1001         STD_METHODCH(get_remote_device_properties, "<addr>"),
1002         STD_METHODCH(get_remote_device_property, "<addr> <property_type>"),
1003         STD_METHODCH(set_remote_device_property,
1004                                         "<addr> <property_type> <value>"),
1005         STD_METHODCH(get_remote_service_record, "<addr> <uuid>"),
1006         STD_METHODCH(get_remote_services, "<addr>"),
1007         STD_METHOD(start_discovery),
1008         STD_METHOD(cancel_discovery),
1009 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
1010         STD_METHODCH(create_bond, "<addr> [<transport>]"),
1011         STD_METHOD(read_energy_info),
1012         STD_METHODCH(get_connection_state, "<addr>"),
1013 #else
1014         STD_METHODCH(create_bond, "<addr>"),
1015 #endif
1016         STD_METHODCH(remove_bond, "<addr>"),
1017         STD_METHODCH(cancel_bond, "<addr>"),
1018         STD_METHODCH(pin_reply, "<address> [<pin>]"),
1019         STD_METHODCH(ssp_reply, "<address> <ssp_veriant> 1|0 [<passkey>]"),
1020         STD_METHODCH(get_profile_interface, "<profile id>"),
1021         STD_METHODH(dut_mode_configure, "<dut mode>"),
1022         STD_METHOD(dut_mode_send),
1023         STD_METHOD(le_test_mode),
1024         STD_METHODH(config_hci_snoop_log, "<mode>"),
1025         END_METHOD
1026 };
1027
1028 const struct interface bluetooth_if = {
1029         .name = "bluetooth",
1030         .methods = methods
1031 };