if-bt.c 24 KB

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