if-hf.c 23 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052
  1. // SPDX-License-Identifier: Apache-2.0
  2. /*
  3. * Copyright (C) 2013 Intel Corporation
  4. *
  5. */
  6. #define _GNU_SOURCE
  7. #include "if-main.h"
  8. #include "../hal-utils.h"
  9. const bthf_interface_t *if_hf = NULL;
  10. SINTMAP(bthf_at_response_t, -1, "(unknown)")
  11. DELEMENT(BTHF_AT_RESPONSE_ERROR),
  12. DELEMENT(BTHF_AT_RESPONSE_OK),
  13. ENDMAP
  14. SINTMAP(bthf_connection_state_t, -1, "(unknown)")
  15. DELEMENT(BTHF_CONNECTION_STATE_DISCONNECTED),
  16. DELEMENT(BTHF_CONNECTION_STATE_CONNECTING),
  17. DELEMENT(BTHF_CONNECTION_STATE_CONNECTED),
  18. DELEMENT(BTHF_CONNECTION_STATE_SLC_CONNECTED),
  19. DELEMENT(BTHF_CONNECTION_STATE_DISCONNECTING),
  20. ENDMAP
  21. SINTMAP(bthf_audio_state_t, -1, "(unknown)")
  22. DELEMENT(BTHF_AUDIO_STATE_DISCONNECTED),
  23. DELEMENT(BTHF_AUDIO_STATE_CONNECTING),
  24. DELEMENT(BTHF_AUDIO_STATE_CONNECTED),
  25. DELEMENT(BTHF_AUDIO_STATE_DISCONNECTING),
  26. ENDMAP
  27. SINTMAP(bthf_vr_state_t, -1, "(unknown)")
  28. DELEMENT(BTHF_VR_STATE_STOPPED),
  29. DELEMENT(BTHF_VR_STATE_STARTED),
  30. ENDMAP
  31. SINTMAP(bthf_volume_type_t, -1, "(unknown)")
  32. DELEMENT(BTHF_VOLUME_TYPE_SPK),
  33. DELEMENT(BTHF_VOLUME_TYPE_MIC),
  34. ENDMAP
  35. SINTMAP(bthf_nrec_t, -1, "(unknown)")
  36. DELEMENT(BTHF_NREC_STOP),
  37. DELEMENT(BTHF_NREC_START),
  38. ENDMAP
  39. SINTMAP(bthf_chld_type_t, -1, "(unknown)")
  40. DELEMENT(BTHF_CHLD_TYPE_RELEASEHELD),
  41. DELEMENT(BTHF_CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD),
  42. DELEMENT(BTHF_CHLD_TYPE_HOLDACTIVE_ACCEPTHELD),
  43. DELEMENT(BTHF_CHLD_TYPE_ADDHELDTOCONF),
  44. ENDMAP
  45. /* Network Status */
  46. SINTMAP(bthf_network_state_t, -1, "(unknown)")
  47. DELEMENT(BTHF_NETWORK_STATE_NOT_AVAILABLE),
  48. DELEMENT(BTHF_NETWORK_STATE_AVAILABLE),
  49. ENDMAP
  50. /* Service type */
  51. SINTMAP(bthf_service_type_t, -1, "(unknown)")
  52. DELEMENT(BTHF_SERVICE_TYPE_HOME),
  53. DELEMENT(BTHF_SERVICE_TYPE_ROAMING),
  54. ENDMAP
  55. SINTMAP(bthf_call_state_t, -1, "(unknown)")
  56. DELEMENT(BTHF_CALL_STATE_ACTIVE),
  57. DELEMENT(BTHF_CALL_STATE_HELD),
  58. DELEMENT(BTHF_CALL_STATE_DIALING),
  59. DELEMENT(BTHF_CALL_STATE_ALERTING),
  60. DELEMENT(BTHF_CALL_STATE_INCOMING),
  61. DELEMENT(BTHF_CALL_STATE_WAITING),
  62. DELEMENT(BTHF_CALL_STATE_IDLE),
  63. ENDMAP
  64. SINTMAP(bthf_call_direction_t, -1, "(unknown)")
  65. DELEMENT(BTHF_CALL_DIRECTION_OUTGOING),
  66. DELEMENT(BTHF_CALL_DIRECTION_INCOMING),
  67. ENDMAP
  68. SINTMAP(bthf_call_mode_t, -1, "(unknown)")
  69. DELEMENT(BTHF_CALL_TYPE_VOICE),
  70. DELEMENT(BTHF_CALL_TYPE_DATA),
  71. DELEMENT(BTHF_CALL_TYPE_FAX),
  72. ENDMAP
  73. SINTMAP(bthf_call_mpty_type_t, -1, "(unknown)")
  74. DELEMENT(BTHF_CALL_MPTY_TYPE_SINGLE),
  75. DELEMENT(BTHF_CALL_MPTY_TYPE_MULTI),
  76. ENDMAP
  77. SINTMAP(bthf_call_addrtype_t, -1, "(unknown)")
  78. DELEMENT(BTHF_CALL_ADDRTYPE_UNKNOWN),
  79. DELEMENT(BTHF_CALL_ADDRTYPE_INTERNATIONAL),
  80. ENDMAP
  81. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  82. SINTMAP(bthf_wbs_config_t, -1, "(unknown)")
  83. DELEMENT(BTHF_WBS_NONE),
  84. DELEMENT(BTHF_WBS_NO),
  85. DELEMENT(BTHF_WBS_YES),
  86. ENDMAP
  87. #endif
  88. /* Callbacks */
  89. static char last_addr[MAX_ADDR_STR_LEN];
  90. /*
  91. * Callback for connection state change.
  92. * state will have one of the values from BtHfConnectionState
  93. */
  94. static void connection_state_cb(bthf_connection_state_t state,
  95. bt_bdaddr_t *bd_addr)
  96. {
  97. haltest_info("%s: state=%s bd_addr=%s\n", __func__,
  98. bthf_connection_state_t2str(state),
  99. bt_bdaddr_t2str(bd_addr, last_addr));
  100. }
  101. /*
  102. * Callback for audio connection state change.
  103. * state will have one of the values from BtHfAudioState
  104. */
  105. static void audio_state_cb(bthf_audio_state_t state, bt_bdaddr_t *bd_addr)
  106. {
  107. haltest_info("%s: state=%s bd_addr=%s\n", __func__,
  108. bthf_audio_state_t2str(state),
  109. bt_bdaddr_t2str(bd_addr, last_addr));
  110. }
  111. /*
  112. * Callback for VR connection state change.
  113. * state will have one of the values from BtHfVRState
  114. */
  115. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  116. static void vr_cmd_cb(bthf_vr_state_t state, bt_bdaddr_t *bd_addr)
  117. {
  118. haltest_info("%s: state=%s bd_addr=%s\n", __func__,
  119. bthf_vr_state_t2str(state),
  120. bt_bdaddr_t2str(bd_addr, last_addr));
  121. }
  122. #else
  123. static void vr_cmd_cb(bthf_vr_state_t state)
  124. {
  125. haltest_info("%s: state=%s\n", __func__, bthf_vr_state_t2str(state));
  126. }
  127. #endif
  128. /* Callback for answer incoming call (ATA) */
  129. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  130. static void answer_call_cmd_cb(bt_bdaddr_t *bd_addr)
  131. {
  132. haltest_info("%s: bd_addr=%s\n", __func__,
  133. bt_bdaddr_t2str(bd_addr, last_addr));
  134. }
  135. #else
  136. static void answer_call_cmd_cb(void)
  137. {
  138. haltest_info("%s\n", __func__);
  139. }
  140. #endif
  141. /* Callback for disconnect call (AT+CHUP) */
  142. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  143. static void hangup_call_cmd_cb(bt_bdaddr_t *bd_addr)
  144. {
  145. haltest_info("%s: bd_addr=%s\n", __func__,
  146. bt_bdaddr_t2str(bd_addr, last_addr));
  147. }
  148. #else
  149. static void hangup_call_cmd_cb(void)
  150. {
  151. haltest_info("%s\n", __func__);
  152. }
  153. #endif
  154. /*
  155. * Callback for disconnect call (AT+CHUP)
  156. * type will denote Speaker/Mic gain (BtHfVolumeControl).
  157. */
  158. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  159. static void volume_cmd_cb(bthf_volume_type_t type, int volume,
  160. bt_bdaddr_t *bd_addr)
  161. {
  162. haltest_info("%s: type=%s volume=%d bd_addr=%s\n", __func__,
  163. bthf_volume_type_t2str(type), volume,
  164. bt_bdaddr_t2str(bd_addr, last_addr));
  165. }
  166. #else
  167. static void volume_cmd_cb(bthf_volume_type_t type, int volume)
  168. {
  169. haltest_info("%s: type=%s volume=%d\n", __func__,
  170. bthf_volume_type_t2str(type), volume);
  171. }
  172. #endif
  173. /*
  174. * Callback for dialing an outgoing call
  175. * If number is NULL, redial
  176. */
  177. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  178. static void dial_call_cmd_cb(char *number, bt_bdaddr_t *bd_addr)
  179. {
  180. haltest_info("%s: number=%s bd_addr=%s\n", __func__, number,
  181. bt_bdaddr_t2str(bd_addr, last_addr));
  182. }
  183. #else
  184. static void dial_call_cmd_cb(char *number)
  185. {
  186. haltest_info("%s: number=%s\n", __func__, number);
  187. }
  188. #endif
  189. /*
  190. * Callback for sending DTMF tones
  191. * tone contains the dtmf character to be sent
  192. */
  193. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  194. static void dtmf_cmd_cb(char tone, bt_bdaddr_t *bd_addr)
  195. {
  196. haltest_info("%s: tone=%d bd_addr=%s\n", __func__, tone,
  197. bt_bdaddr_t2str(bd_addr, last_addr));
  198. }
  199. #else
  200. static void dtmf_cmd_cb(char tone)
  201. {
  202. haltest_info("%s: tone=%d\n", __func__, tone);
  203. }
  204. #endif
  205. /*
  206. * Callback for enabling/disabling noise reduction/echo cancellation
  207. * value will be 1 to enable, 0 to disable
  208. */
  209. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  210. static void nrec_cmd_cb(bthf_nrec_t nrec, bt_bdaddr_t *bd_addr)
  211. {
  212. haltest_info("%s: nrec=%s bd_addr=%s\n", __func__,
  213. bthf_nrec_t2str(nrec),
  214. bt_bdaddr_t2str(bd_addr, last_addr));
  215. }
  216. #else
  217. static void nrec_cmd_cb(bthf_nrec_t nrec)
  218. {
  219. haltest_info("%s: nrec=%s\n", __func__, bthf_nrec_t2str(nrec));
  220. }
  221. #endif
  222. /*
  223. * Callback for call hold handling (AT+CHLD)
  224. * value will contain the call hold command (0, 1, 2, 3)
  225. */
  226. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  227. static void chld_cmd_cb(bthf_chld_type_t chld, bt_bdaddr_t *bd_addr)
  228. {
  229. haltest_info("%s: chld=%s bd_addr=%s\n", __func__,
  230. bthf_chld_type_t2str(chld),
  231. bt_bdaddr_t2str(bd_addr, last_addr));
  232. }
  233. #else
  234. static void chld_cmd_cb(bthf_chld_type_t chld)
  235. {
  236. haltest_info("%s: chld=%s\n", __func__, bthf_chld_type_t2str(chld));
  237. }
  238. #endif
  239. /* Callback for CNUM (subscriber number) */
  240. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  241. static void cnum_cmd_cb(bt_bdaddr_t *bd_addr)
  242. {
  243. haltest_info("%s: bd_addr=%s\n", __func__,
  244. bt_bdaddr_t2str(bd_addr, last_addr));
  245. }
  246. #else
  247. static void cnum_cmd_cb(void)
  248. {
  249. haltest_info("%s\n", __func__);
  250. }
  251. #endif
  252. /* Callback for indicators (CIND) */
  253. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  254. static void cind_cmd_cb(bt_bdaddr_t *bd_addr)
  255. {
  256. haltest_info("%s: bd_addr=%s\n", __func__,
  257. bt_bdaddr_t2str(bd_addr, last_addr));
  258. }
  259. #else
  260. static void cind_cmd_cb(void)
  261. {
  262. haltest_info("%s\n", __func__);
  263. }
  264. #endif
  265. /* Callback for operator selection (COPS) */
  266. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  267. static void cops_cmd_cb(bt_bdaddr_t *bd_addr)
  268. {
  269. haltest_info("%s: bd_addr=%s\n", __func__,
  270. bt_bdaddr_t2str(bd_addr, last_addr));
  271. }
  272. #else
  273. static void cops_cmd_cb(void)
  274. {
  275. haltest_info("%s\n", __func__);
  276. }
  277. #endif
  278. /* Callback for call list (AT+CLCC) */
  279. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  280. static void clcc_cmd_cb(bt_bdaddr_t *bd_addr)
  281. {
  282. haltest_info("%s: bd_addr=%s\n", __func__,
  283. bt_bdaddr_t2str(bd_addr, last_addr));
  284. }
  285. #else
  286. static void clcc_cmd_cb(void)
  287. {
  288. haltest_info("%s\n", __func__);
  289. }
  290. #endif
  291. /*
  292. * Callback for unknown AT command recd from HF
  293. * at_string will contain the unparsed AT string
  294. */
  295. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  296. static void unknown_at_cmd_cb(char *at_string, bt_bdaddr_t *bd_addr)
  297. {
  298. haltest_info("%s: at_string=%s bd_addr=%s\n", __func__, at_string,
  299. bt_bdaddr_t2str(bd_addr, last_addr));
  300. }
  301. #else
  302. static void unknown_at_cmd_cb(char *at_string)
  303. {
  304. haltest_info("%s: at_string=%s\n", __func__, at_string);
  305. }
  306. #endif
  307. /* Callback for keypressed (HSP) event. */
  308. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  309. static void key_pressed_cmd_cb(bt_bdaddr_t *bd_addr)
  310. {
  311. haltest_info("%s: bd_addr=%s\n", __func__,
  312. bt_bdaddr_t2str(bd_addr, last_addr));
  313. }
  314. #else
  315. static void key_pressed_cmd_cb(void)
  316. {
  317. haltest_info("%s\n", __func__);
  318. }
  319. #endif
  320. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  321. static void wbs_cb(bthf_wbs_config_t wbs, bt_bdaddr_t *bd_addr)
  322. {
  323. haltest_info("%s: bd_addr=%s\n", __func__,
  324. bt_bdaddr_t2str(bd_addr, last_addr));
  325. }
  326. #endif
  327. static bthf_callbacks_t hf_cbacks = {
  328. .size = sizeof(hf_cbacks),
  329. .connection_state_cb = connection_state_cb,
  330. .audio_state_cb = audio_state_cb,
  331. .vr_cmd_cb = vr_cmd_cb,
  332. .answer_call_cmd_cb = answer_call_cmd_cb,
  333. .hangup_call_cmd_cb = hangup_call_cmd_cb,
  334. .volume_cmd_cb = volume_cmd_cb,
  335. .dial_call_cmd_cb = dial_call_cmd_cb,
  336. .dtmf_cmd_cb = dtmf_cmd_cb,
  337. .nrec_cmd_cb = nrec_cmd_cb,
  338. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  339. .wbs_cb = wbs_cb,
  340. #endif
  341. .chld_cmd_cb = chld_cmd_cb,
  342. .cnum_cmd_cb = cnum_cmd_cb,
  343. .cind_cmd_cb = cind_cmd_cb,
  344. .cops_cmd_cb = cops_cmd_cb,
  345. .clcc_cmd_cb = clcc_cmd_cb,
  346. .unknown_at_cmd_cb = unknown_at_cmd_cb,
  347. .key_pressed_cmd_cb = key_pressed_cmd_cb,
  348. };
  349. /* init */
  350. static void init_p(int argc, const char **argv)
  351. {
  352. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  353. int max_hf_clients;
  354. #endif
  355. RETURN_IF_NULL(if_hf);
  356. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  357. if (argc <= 2)
  358. max_hf_clients = 1;
  359. else
  360. max_hf_clients = atoi(argv[2]);
  361. EXEC(if_hf->init, &hf_cbacks, max_hf_clients);
  362. #else
  363. EXEC(if_hf->init, &hf_cbacks);
  364. #endif
  365. }
  366. /* connect */
  367. static void connect_c(int argc, const char **argv, enum_func *enum_func,
  368. void **user)
  369. {
  370. if (argc == 3) {
  371. *user = NULL;
  372. *enum_func = enum_devices;
  373. }
  374. }
  375. static void connect_p(int argc, const char **argv)
  376. {
  377. bt_bdaddr_t addr;
  378. RETURN_IF_NULL(if_hf);
  379. VERIFY_ADDR_ARG(2, &addr);
  380. EXEC(if_hf->connect, &addr);
  381. }
  382. /* disconnect */
  383. /*
  384. * This completion function will be used for several methods
  385. * returning recently connected address
  386. */
  387. static void connected_addr_c(int argc, const char **argv, enum_func *enum_func,
  388. void **user)
  389. {
  390. if (argc == 3) {
  391. *user = last_addr;
  392. *enum_func = enum_one_string;
  393. }
  394. }
  395. /* Map completion to connected_addr_c */
  396. #define disconnect_c connected_addr_c
  397. static void disconnect_p(int argc, const char **argv)
  398. {
  399. bt_bdaddr_t addr;
  400. RETURN_IF_NULL(if_hf);
  401. VERIFY_ADDR_ARG(2, &addr);
  402. EXEC(if_hf->disconnect, &addr);
  403. }
  404. /* create an audio connection */
  405. /* Map completion to connected_addr_c */
  406. #define connect_audio_c connected_addr_c
  407. static void connect_audio_p(int argc, const char **argv)
  408. {
  409. bt_bdaddr_t addr;
  410. RETURN_IF_NULL(if_hf);
  411. VERIFY_ADDR_ARG(2, &addr);
  412. EXEC(if_hf->connect_audio, &addr);
  413. }
  414. /* close the audio connection */
  415. /* Map completion to connected_addr_c */
  416. #define disconnect_audio_c connected_addr_c
  417. static void disconnect_audio_p(int argc, const char **argv)
  418. {
  419. bt_bdaddr_t addr;
  420. RETURN_IF_NULL(if_hf);
  421. VERIFY_ADDR_ARG(2, &addr);
  422. EXEC(if_hf->disconnect_audio, &addr);
  423. }
  424. /* start voice recognition */
  425. static void start_voice_recognition_p(int argc, const char **argv)
  426. {
  427. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  428. bt_bdaddr_t addr;
  429. #endif
  430. RETURN_IF_NULL(if_hf);
  431. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  432. VERIFY_ADDR_ARG(2, &addr);
  433. EXEC(if_hf->start_voice_recognition, &addr);
  434. #else
  435. EXEC(if_hf->start_voice_recognition);
  436. #endif
  437. }
  438. /* stop voice recognition */
  439. static void stop_voice_recognition_p(int argc, const char **argv)
  440. {
  441. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  442. bt_bdaddr_t addr;
  443. #endif
  444. RETURN_IF_NULL(if_hf);
  445. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  446. VERIFY_ADDR_ARG(2, &addr);
  447. EXEC(if_hf->stop_voice_recognition, &addr);
  448. #else
  449. EXEC(if_hf->stop_voice_recognition);
  450. #endif
  451. }
  452. /* volume control */
  453. static void volume_control_c(int argc, const char **argv, enum_func *enum_func,
  454. void **user)
  455. {
  456. if (argc == 3) {
  457. *user = TYPE_ENUM(bthf_volume_type_t);
  458. *enum_func = enum_defines;
  459. }
  460. }
  461. static void volume_control_p(int argc, const char **argv)
  462. {
  463. bthf_volume_type_t type;
  464. int volume;
  465. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  466. bt_bdaddr_t addr;
  467. #endif
  468. RETURN_IF_NULL(if_hf);
  469. /* volume type */
  470. if (argc <= 2) {
  471. haltest_error("No volume type specified\n");
  472. return;
  473. }
  474. type = str2bthf_volume_type_t(argv[2]);
  475. /* volume */
  476. if (argc <= 3) {
  477. haltest_error("No volume specified\n");
  478. return;
  479. }
  480. volume = atoi(argv[3]);
  481. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  482. VERIFY_ADDR_ARG(4, &addr);
  483. EXEC(if_hf->volume_control, type, volume, &addr);
  484. #else
  485. EXEC(if_hf->volume_control, type, volume);
  486. #endif
  487. }
  488. /* Combined device status change notification */
  489. static void device_status_notification_c(int argc, const char **argv,
  490. enum_func *enum_func,
  491. void **user)
  492. {
  493. if (argc == 3) {
  494. *user = TYPE_ENUM(bthf_network_state_t);
  495. *enum_func = enum_defines;
  496. } else if (argc == 4) {
  497. *user = TYPE_ENUM(bthf_service_type_t);
  498. *enum_func = enum_defines;
  499. }
  500. }
  501. static void device_status_notification_p(int argc, const char **argv)
  502. {
  503. bthf_network_state_t ntk_state;
  504. bthf_service_type_t svc_type;
  505. int signal;
  506. int batt_chg;
  507. RETURN_IF_NULL(if_hf);
  508. /* network state */
  509. if (argc <= 2) {
  510. haltest_error("No network state specified\n");
  511. return;
  512. }
  513. ntk_state = str2bthf_network_state_t(argv[2]);
  514. /* service type */
  515. if (argc <= 3) {
  516. haltest_error("No service type specified\n");
  517. return;
  518. }
  519. svc_type = str2bthf_service_type_t(argv[3]);
  520. /* signal */
  521. if (argc <= 4) {
  522. haltest_error("No signal specified\n");
  523. return;
  524. }
  525. signal = atoi(argv[4]);
  526. /* batt_chg */
  527. if (argc <= 5) {
  528. haltest_error("No batt_chg specified\n");
  529. return;
  530. }
  531. batt_chg = atoi(argv[5]);
  532. EXEC(if_hf->device_status_notification, ntk_state, svc_type, signal,
  533. batt_chg);
  534. }
  535. /* Response for COPS command */
  536. static void cops_response_p(int argc, const char **argv)
  537. {
  538. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  539. bt_bdaddr_t addr;
  540. #endif
  541. RETURN_IF_NULL(if_hf);
  542. /* response */
  543. if (argc <= 2) {
  544. haltest_error("No cops specified\n");
  545. return;
  546. }
  547. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  548. VERIFY_ADDR_ARG(3, &addr);
  549. EXEC(if_hf->cops_response, argv[2], &addr);
  550. #else
  551. EXEC(if_hf->cops_response, argv[2]);
  552. #endif
  553. }
  554. /* Response for CIND command */
  555. static void cind_response_c(int argc, const char **argv, enum_func *enum_func,
  556. void **user)
  557. {
  558. if (argc == 6) {
  559. *user = TYPE_ENUM(bthf_call_state_t);
  560. *enum_func = enum_defines;
  561. }
  562. }
  563. static void cind_response_p(int argc, const char **argv)
  564. {
  565. int svc;
  566. int num_active;
  567. int num_held;
  568. bthf_call_state_t call_setup_state;
  569. int signal;
  570. int roam;
  571. int batt_chg;
  572. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  573. bt_bdaddr_t addr;
  574. #endif
  575. RETURN_IF_NULL(if_hf);
  576. /* svc */
  577. if (argc <= 2) {
  578. haltest_error("No service specified\n");
  579. return;
  580. }
  581. svc = atoi(argv[2]);
  582. /* num active */
  583. if (argc <= 3) {
  584. haltest_error("No num active specified\n");
  585. return;
  586. }
  587. num_active = atoi(argv[3]);
  588. /* num held */
  589. if (argc <= 4) {
  590. haltest_error("No num held specified\n");
  591. return;
  592. }
  593. num_held = atoi(argv[4]);
  594. /* call setup state */
  595. if (argc <= 5) {
  596. haltest_error("No call setup state specified\n");
  597. return;
  598. }
  599. call_setup_state = str2bthf_call_state_t(argv[5]);
  600. /* signal */
  601. if (argc <= 6) {
  602. haltest_error("No signal specified\n");
  603. return;
  604. }
  605. signal = atoi(argv[6]);
  606. /* roam */
  607. if (argc <= 7) {
  608. haltest_error("No roam specified\n");
  609. return;
  610. }
  611. roam = atoi(argv[7]);
  612. /* batt_chg */
  613. if (argc <= 8) {
  614. haltest_error("No batt_chg specified\n");
  615. return;
  616. }
  617. batt_chg = atoi(argv[8]);
  618. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  619. VERIFY_ADDR_ARG(9, &addr);
  620. EXEC(if_hf->cind_response, svc, num_active, num_held, call_setup_state,
  621. signal, roam, batt_chg, &addr);
  622. #else
  623. EXEC(if_hf->cind_response, svc, num_active, num_held, call_setup_state,
  624. signal, roam, batt_chg);
  625. #endif
  626. }
  627. /* Pre-formatted AT response, typically in response to unknown AT cmd */
  628. static void formatted_at_response_p(int argc, const char **argv)
  629. {
  630. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  631. bt_bdaddr_t addr;
  632. #endif
  633. RETURN_IF_NULL(if_hf);
  634. /* response */
  635. if (argc <= 2) {
  636. haltest_error("No response specified\n");
  637. return;
  638. }
  639. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  640. VERIFY_ADDR_ARG(3, &addr);
  641. EXEC(if_hf->formatted_at_response, argv[2], &addr);
  642. #else
  643. EXEC(if_hf->formatted_at_response, argv[2]);
  644. #endif
  645. }
  646. /* at_response */
  647. static void at_response_c(int argc, const char **argv, enum_func *enum_func,
  648. void **user)
  649. {
  650. if (argc == 3) {
  651. *user = TYPE_ENUM(bthf_at_response_t);
  652. *enum_func = enum_defines;
  653. }
  654. }
  655. static void at_response_p(int argc, const char **argv)
  656. {
  657. bthf_at_response_t response_code;
  658. int error_code;
  659. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  660. bt_bdaddr_t addr;
  661. #endif
  662. RETURN_IF_NULL(if_hf);
  663. /* response type */
  664. if (argc <= 2) {
  665. haltest_error("No response specified\n");
  666. return;
  667. }
  668. response_code = str2bthf_at_response_t(argv[2]);
  669. /* error code */
  670. if (argc <= 3)
  671. error_code = 0;
  672. else
  673. error_code = atoi(argv[3]);
  674. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  675. VERIFY_ADDR_ARG(4, &addr);
  676. EXEC(if_hf->at_response, response_code, error_code, &addr);
  677. #else
  678. EXEC(if_hf->at_response, response_code, error_code);
  679. #endif
  680. }
  681. /* response for CLCC command */
  682. static void clcc_response_c(int argc, const char **argv, enum_func *enum_func,
  683. void **user)
  684. {
  685. if (argc == 4) {
  686. *user = TYPE_ENUM(bthf_call_direction_t);
  687. *enum_func = enum_defines;
  688. } else if (argc == 5) {
  689. *user = TYPE_ENUM(bthf_call_state_t);
  690. *enum_func = enum_defines;
  691. } else if (argc == 6) {
  692. *user = TYPE_ENUM(bthf_call_mode_t);
  693. *enum_func = enum_defines;
  694. } else if (argc == 7) {
  695. *user = TYPE_ENUM(bthf_call_mpty_type_t);
  696. *enum_func = enum_defines;
  697. } else if (argc == 9) {
  698. *user = TYPE_ENUM(bthf_call_addrtype_t);
  699. *enum_func = enum_defines;
  700. }
  701. }
  702. static void clcc_response_p(int argc, const char **argv)
  703. {
  704. int index;
  705. bthf_call_direction_t dir;
  706. bthf_call_state_t state;
  707. bthf_call_mode_t mode;
  708. bthf_call_mpty_type_t mpty;
  709. const char *number;
  710. bthf_call_addrtype_t type;
  711. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  712. bt_bdaddr_t addr;
  713. #endif
  714. RETURN_IF_NULL(if_hf);
  715. /* index */
  716. if (argc <= 2) {
  717. haltest_error("No index specified\n");
  718. return;
  719. }
  720. index = atoi(argv[2]);
  721. /* direction */
  722. if (argc <= 3) {
  723. haltest_error("No direction specified\n");
  724. return;
  725. }
  726. dir = str2bthf_call_direction_t(argv[3]);
  727. /* call state */
  728. if (argc <= 4) {
  729. haltest_error("No call state specified\n");
  730. return;
  731. }
  732. state = str2bthf_call_state_t(argv[4]);
  733. /* call mode */
  734. if (argc <= 5) {
  735. haltest_error("No mode specified\n");
  736. return;
  737. }
  738. mode = str2bthf_call_mode_t(argv[5]);
  739. /* call mpty type */
  740. if (argc <= 6) {
  741. haltest_error("No mpty type specified\n");
  742. return;
  743. }
  744. mpty = str2bthf_call_mpty_type_t(argv[6]);
  745. /* number */
  746. if (argc <= 7) {
  747. haltest_error("No number specified\n");
  748. return;
  749. }
  750. number = argv[7];
  751. /* call mpty type */
  752. if (argc <= 8) {
  753. haltest_error("No address type specified\n");
  754. return;
  755. }
  756. type = str2bthf_call_addrtype_t(argv[8]);
  757. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  758. VERIFY_ADDR_ARG(9, &addr);
  759. EXEC(if_hf->clcc_response, index, dir, state, mode, mpty, number,
  760. type, &addr);
  761. #else
  762. EXEC(if_hf->clcc_response, index, dir, state, mode, mpty, number,
  763. type);
  764. #endif
  765. }
  766. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  767. static void configure_wbs_c(int argc, const char **argv, enum_func *enum_func,
  768. void **user)
  769. {
  770. if (argc == 4) {
  771. *user = TYPE_ENUM(bthf_wbs_config_t);
  772. *enum_func = enum_defines;
  773. }
  774. }
  775. static void configure_wbs_p(int argc, const char **argv)
  776. {
  777. bthf_wbs_config_t wbs;
  778. bt_bdaddr_t addr;
  779. RETURN_IF_NULL(if_hf);
  780. if (argc <= 3) {
  781. haltest_error("Too few parameters specified\n");
  782. return;
  783. }
  784. VERIFY_ADDR_ARG(2, &addr);
  785. wbs = str2bthf_wbs_config_t(argv[3]);
  786. EXEC(if_hf->configure_wbs, &addr, wbs);
  787. }
  788. #endif
  789. /* phone state change */
  790. static void phone_state_change_c(int argc, const char **argv,
  791. enum_func *enum_func, void **user)
  792. {
  793. if (argc == 5) {
  794. *user = TYPE_ENUM(bthf_call_state_t);
  795. *enum_func = enum_defines;
  796. } else if (argc == 7) {
  797. *user = TYPE_ENUM(bthf_call_addrtype_t);
  798. *enum_func = enum_defines;
  799. }
  800. }
  801. static void phone_state_change_p(int argc, const char **argv)
  802. {
  803. int num_active;
  804. int num_held;
  805. bthf_call_state_t call_setup_state;
  806. const char *number;
  807. bthf_call_addrtype_t type;
  808. RETURN_IF_NULL(if_hf);
  809. /* num_active */
  810. if (argc <= 2) {
  811. haltest_error("No num_active specified\n");
  812. return;
  813. }
  814. num_active = atoi(argv[2]);
  815. /* num_held */
  816. if (argc <= 3) {
  817. haltest_error("No num_held specified\n");
  818. return;
  819. }
  820. num_held = atoi(argv[3]);
  821. /* setup state */
  822. if (argc <= 4) {
  823. haltest_error("No call setup state specified\n");
  824. return;
  825. }
  826. call_setup_state = str2bthf_call_state_t(argv[4]);
  827. /* number */
  828. if (argc <= 5) {
  829. haltest_error("No number specified\n");
  830. return;
  831. }
  832. number = argv[5];
  833. /* call mpty type */
  834. if (argc <= 6) {
  835. haltest_error("No address type specified\n");
  836. return;
  837. }
  838. type = str2bthf_call_addrtype_t(argv[6]);
  839. EXEC(if_hf->phone_state_change, num_active, num_held, call_setup_state,
  840. number, type);
  841. }
  842. /* cleanup */
  843. static void cleanup_p(int argc, const char **argv)
  844. {
  845. RETURN_IF_NULL(if_hf);
  846. EXECV(if_hf->cleanup);
  847. if_hf = NULL;
  848. }
  849. static struct method methods[] = {
  850. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  851. STD_METHODH(init, "[<max_hf_clients>]"),
  852. STD_METHODH(start_voice_recognition, "<addr>"),
  853. STD_METHODH(stop_voice_recognition, "<addr>"),
  854. STD_METHODCH(volume_control, "<vol_type> <volume> <addr>"),
  855. STD_METHODH(cops_response, "<cops string> <addr>"),
  856. STD_METHODCH(cind_response,
  857. "<svc> <num_active> <num_held> <setup_state> <signal> "
  858. "<roam> <batt_chg> <addr>"),
  859. STD_METHODH(formatted_at_response, "<at_response> <addr>"),
  860. STD_METHODCH(at_response, "<response_code> [<error_code> <bdaddr>]"),
  861. STD_METHODCH(clcc_response,
  862. "<index> <direction> <state> <mode> <mpty> <number> "
  863. "<type> <addr>"),
  864. STD_METHODCH(configure_wbs, "<addr> <wbs config>"),
  865. #else
  866. STD_METHOD(init),
  867. STD_METHOD(start_voice_recognition),
  868. STD_METHOD(stop_voice_recognition),
  869. STD_METHODCH(volume_control, "<vol_type> <volume>"),
  870. STD_METHODH(cops_response, "<cops string>"),
  871. STD_METHODCH(cind_response,
  872. "<svc> <num_active> <num_held> <setup_state> <signal> "
  873. "<roam> <batt_chg>"),
  874. STD_METHODH(formatted_at_response, "<at_response>"),
  875. STD_METHODCH(at_response, "<response_code> [<error_code>]"),
  876. STD_METHODCH(clcc_response,
  877. "<index> <direction> <state> <mode> <mpty> <number> "
  878. "<type>"),
  879. #endif
  880. STD_METHODCH(connect, "<addr>"),
  881. STD_METHODCH(disconnect, "<addr>"),
  882. STD_METHODCH(connect_audio, "<addr>"),
  883. STD_METHODCH(disconnect_audio, "<addr>"),
  884. STD_METHODCH(device_status_notification,
  885. "<ntk_state> <svt_type> <signal> <batt_chg>"),
  886. STD_METHODCH(phone_state_change,
  887. "<num_active> <num_held> <setup_state> <number> "
  888. "<type>"),
  889. STD_METHOD(cleanup),
  890. END_METHOD
  891. };
  892. const struct interface hf_if = {
  893. .name = "handsfree",
  894. .methods = methods
  895. };