if-hf-client.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  1. // SPDX-License-Identifier: Apache-2.0
  2. /*
  3. * Copyright (C) 2014 Intel Corporation
  4. *
  5. */
  6. #define _GNU_SOURCE
  7. #include "if-main.h"
  8. #include "../hal-utils.h"
  9. const bthf_client_interface_t *if_hf_client = NULL;
  10. static char last_addr[MAX_ADDR_STR_LEN];
  11. SINTMAP(bthf_client_connection_state_t, -1, "(unknown)")
  12. DELEMENT(BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED),
  13. DELEMENT(BTHF_CLIENT_CONNECTION_STATE_CONNECTING),
  14. DELEMENT(BTHF_CLIENT_CONNECTION_STATE_CONNECTED),
  15. DELEMENT(BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED),
  16. DELEMENT(BTHF_CLIENT_CONNECTION_STATE_DISCONNECTING),
  17. ENDMAP
  18. SINTMAP(bthf_client_audio_state_t, -1, "(unknown)")
  19. DELEMENT(BTHF_CLIENT_AUDIO_STATE_DISCONNECTED),
  20. DELEMENT(BTHF_CLIENT_AUDIO_STATE_CONNECTING),
  21. DELEMENT(BTHF_CLIENT_AUDIO_STATE_CONNECTED),
  22. DELEMENT(BTHF_CLIENT_AUDIO_STATE_CONNECTED_MSBC),
  23. ENDMAP
  24. SINTMAP(bthf_client_vr_state_t, -1, "(unknown)")
  25. DELEMENT(BTHF_CLIENT_VR_STATE_STOPPED),
  26. DELEMENT(BTHF_CLIENT_VR_STATE_STARTED),
  27. ENDMAP
  28. SINTMAP(bthf_client_network_state_t, -1, "(unknown)")
  29. DELEMENT(BTHF_CLIENT_NETWORK_STATE_NOT_AVAILABLE),
  30. DELEMENT(BTHF_CLIENT_NETWORK_STATE_AVAILABLE),
  31. ENDMAP
  32. SINTMAP(bthf_client_service_type_t, -1, "(unknown)")
  33. DELEMENT(BTHF_CLIENT_SERVICE_TYPE_HOME),
  34. DELEMENT(BTHF_CLIENT_SERVICE_TYPE_ROAMING),
  35. ENDMAP
  36. SINTMAP(bthf_client_call_t, -1, "(unknown)")
  37. DELEMENT(BTHF_CLIENT_CALL_NO_CALLS_IN_PROGRESS),
  38. DELEMENT(BTHF_CLIENT_CALL_CALLS_IN_PROGRESS),
  39. ENDMAP
  40. SINTMAP(bthf_client_callsetup_t, -1, "(unknown)")
  41. DELEMENT(BTHF_CLIENT_CALLSETUP_NONE),
  42. DELEMENT(BTHF_CLIENT_CALLSETUP_INCOMING),
  43. DELEMENT(BTHF_CLIENT_CALLSETUP_OUTGOING),
  44. DELEMENT(BTHF_CLIENT_CALLSETUP_ALERTING),
  45. ENDMAP
  46. SINTMAP(bthf_client_callheld_t, -1, "(unknown)")
  47. DELEMENT(BTHF_CLIENT_CALLHELD_NONE),
  48. DELEMENT(BTHF_CLIENT_CALLHELD_HOLD_AND_ACTIVE),
  49. DELEMENT(BTHF_CLIENT_CALLHELD_HOLD),
  50. ENDMAP
  51. SINTMAP(bthf_client_resp_and_hold_t, -1, "(unknown)")
  52. DELEMENT(BTHF_CLIENT_RESP_AND_HOLD_HELD),
  53. DELEMENT(BTRH_CLIENT_RESP_AND_HOLD_ACCEPT),
  54. DELEMENT(BTRH_CLIENT_RESP_AND_HOLD_REJECT),
  55. ENDMAP
  56. SINTMAP(bthf_client_call_direction_t, -1, "(unknown)")
  57. DELEMENT(BTHF_CLIENT_CALL_DIRECTION_OUTGOING),
  58. DELEMENT(BTHF_CLIENT_CALL_DIRECTION_INCOMING),
  59. ENDMAP
  60. SINTMAP(bthf_client_call_state_t, -1, "(unknown)")
  61. DELEMENT(BTHF_CLIENT_CALL_STATE_ACTIVE),
  62. DELEMENT(BTHF_CLIENT_CALL_STATE_HELD),
  63. DELEMENT(BTHF_CLIENT_CALL_STATE_DIALING),
  64. DELEMENT(BTHF_CLIENT_CALL_STATE_ALERTING),
  65. DELEMENT(BTHF_CLIENT_CALL_STATE_INCOMING),
  66. DELEMENT(BTHF_CLIENT_CALL_STATE_WAITING),
  67. DELEMENT(BTHF_CLIENT_CALL_STATE_HELD_BY_RESP_HOLD),
  68. ENDMAP
  69. SINTMAP(bthf_client_call_mpty_type_t, -1, "(unknown)")
  70. DELEMENT(BTHF_CLIENT_CALL_MPTY_TYPE_SINGLE),
  71. DELEMENT(BTHF_CLIENT_CALL_MPTY_TYPE_MULTI),
  72. ENDMAP
  73. SINTMAP(bthf_client_volume_type_t, -1, "(unknown)")
  74. DELEMENT(BTHF_CLIENT_VOLUME_TYPE_SPK),
  75. DELEMENT(BTHF_CLIENT_VOLUME_TYPE_MIC),
  76. ENDMAP
  77. SINTMAP(bthf_client_cmd_complete_t, -1, "(unknown)")
  78. DELEMENT(BTHF_CLIENT_CMD_COMPLETE_OK),
  79. DELEMENT(BTHF_CLIENT_CMD_COMPLETE_ERROR),
  80. DELEMENT(BTHF_CLIENT_CMD_COMPLETE_ERROR_NO_CARRIER),
  81. DELEMENT(BTHF_CLIENT_CMD_COMPLETE_ERROR_BUSY),
  82. DELEMENT(BTHF_CLIENT_CMD_COMPLETE_ERROR_NO_ANSWER),
  83. DELEMENT(BTHF_CLIENT_CMD_COMPLETE_ERROR_DELAYED),
  84. DELEMENT(BTHF_CLIENT_CMD_COMPLETE_ERROR_BLACKLISTED),
  85. DELEMENT(BTHF_CLIENT_CMD_COMPLETE_ERROR_CME),
  86. ENDMAP
  87. SINTMAP(bthf_client_subscriber_service_type_t, -1, "(unknown)")
  88. DELEMENT(BTHF_CLIENT_SERVICE_UNKNOWN),
  89. DELEMENT(BTHF_CLIENT_SERVICE_VOICE),
  90. DELEMENT(BTHF_CLIENT_SERVICE_FAX),
  91. ENDMAP
  92. SINTMAP(bthf_client_in_band_ring_state_t, -1, "(unknown)")
  93. DELEMENT(BTHF_CLIENT_IN_BAND_RINGTONE_NOT_PROVIDED),
  94. DELEMENT(BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED),
  95. ENDMAP
  96. SINTMAP(bthf_client_call_action_t, -1, "(unknown)")
  97. DELEMENT(BTHF_CLIENT_CALL_ACTION_CHLD_0),
  98. DELEMENT(BTHF_CLIENT_CALL_ACTION_CHLD_1),
  99. DELEMENT(BTHF_CLIENT_CALL_ACTION_CHLD_2),
  100. DELEMENT(BTHF_CLIENT_CALL_ACTION_CHLD_3),
  101. DELEMENT(BTHF_CLIENT_CALL_ACTION_CHLD_4),
  102. DELEMENT(BTHF_CLIENT_CALL_ACTION_CHLD_1x),
  103. DELEMENT(BTHF_CLIENT_CALL_ACTION_CHLD_2x),
  104. DELEMENT(BTHF_CLIENT_CALL_ACTION_ATA),
  105. DELEMENT(BTHF_CLIENT_CALL_ACTION_CHUP),
  106. DELEMENT(BTHF_CLIENT_CALL_ACTION_BTRH_0),
  107. DELEMENT(BTHF_CLIENT_CALL_ACTION_BTRH_1),
  108. DELEMENT(BTHF_CLIENT_CALL_ACTION_BTRH_2),
  109. ENDMAP
  110. /* Callbacks */
  111. static char features_str[512];
  112. static const char *pear_features_t2str(int feat)
  113. {
  114. memset(features_str, 0, sizeof(features_str));
  115. sprintf(features_str, "BTHF_CLIENT_PEER_FEAT_3WAY: %s,\n"
  116. "BTHF_CLIENT_PEER_FEAT_ECNR: %s,\n"
  117. "BTHF_CLIENT_PEER_FEAT_VREC: %s,\n"
  118. "BTHF_CLIENT_PEER_FEAT_INBAND: %s,\n"
  119. "BTHF_CLIENT_PEER_FEAT_VTAG: %s,\n"
  120. "BTHF_CLIENT_PEER_FEAT_REJECT: %s,\n"
  121. "BTHF_CLIENT_PEER_FEAT_ECS: %s,\n"
  122. "BTHF_CLIENT_PEER_FEAT_ECC: %s,\n"
  123. "BTHF_CLIENT_PEER_FEAT_EXTERR: %s,\n"
  124. "BTHF_CLIENT_PEER_FEAT_CODEC: %s,\n",
  125. feat & BTHF_CLIENT_PEER_FEAT_3WAY ? "True" : "False",
  126. feat & BTHF_CLIENT_PEER_FEAT_ECNR ? "True" : "False",
  127. feat & BTHF_CLIENT_PEER_FEAT_VREC ? "True" : "False",
  128. feat & BTHF_CLIENT_PEER_FEAT_INBAND ? "True" : "False",
  129. feat & BTHF_CLIENT_PEER_FEAT_VTAG ? "True" : "False",
  130. feat & BTHF_CLIENT_PEER_FEAT_REJECT ? "True" : "False",
  131. feat & BTHF_CLIENT_PEER_FEAT_ECS ? "True" : "False",
  132. feat & BTHF_CLIENT_PEER_FEAT_ECC ? "True" : "False",
  133. feat & BTHF_CLIENT_PEER_FEAT_EXTERR ? "True" : "False",
  134. feat & BTHF_CLIENT_PEER_FEAT_CODEC ? "True" : "False");
  135. return features_str;
  136. }
  137. static const char *chld_features_t2str(int feat)
  138. {
  139. memset(features_str, 0, sizeof(features_str));
  140. sprintf(features_str,
  141. "BTHF_CLIENT_CHLD_FEAT_REL: %s,\n"
  142. "BTHF_CLIENT_CHLD_FEAT_REL_ACC: %s,\n"
  143. "BTHF_CLIENT_CHLD_FEAT_REL_X: %s,\n"
  144. "BTHF_CLIENT_CHLD_FEAT_HOLD_ACC: %s,\n"
  145. "BTHF_CLIENT_CHLD_FEAT_PRIV_X: %s,\n"
  146. "BTHF_CLIENT_CHLD_FEAT_MERGE: %s,\n"
  147. "BTHF_CLIENT_CHLD_FEAT_MERGE_DETACH: %s,\n",
  148. feat & BTHF_CLIENT_CHLD_FEAT_REL ? "True" : "False",
  149. feat & BTHF_CLIENT_CHLD_FEAT_REL_ACC ? "True" : "False",
  150. feat & BTHF_CLIENT_CHLD_FEAT_REL_X ? "True" : "False",
  151. feat & BTHF_CLIENT_CHLD_FEAT_HOLD_ACC ? "True" : "False",
  152. feat & BTHF_CLIENT_CHLD_FEAT_PRIV_X ? "True" : "False",
  153. feat & BTHF_CLIENT_CHLD_FEAT_MERGE ? "True" : "False",
  154. feat & BTHF_CLIENT_CHLD_FEAT_MERGE_DETACH ? "True" : "False");
  155. return features_str;
  156. }
  157. /* Callback for connection state change. */
  158. static void hf_client_connection_state_callback(
  159. bthf_client_connection_state_t state,
  160. unsigned int peer_feat,
  161. unsigned int chld_feat,
  162. bt_bdaddr_t *bd_addr)
  163. {
  164. haltest_info("%s: state=%s bd_addr=%s\n", __func__,
  165. bthf_client_connection_state_t2str(state),
  166. bt_bdaddr_t2str(bd_addr, last_addr));
  167. if (state != BTHF_CLIENT_CONNECTION_STATE_CONNECTED)
  168. return;
  169. haltest_info("\tpeer_features%s\n", pear_features_t2str(peer_feat));
  170. haltest_info("\tchld_feat=%s\n", chld_features_t2str(chld_feat));
  171. }
  172. /* Callback for audio connection state change. */
  173. static void hf_client_audio_state_callback(bthf_client_audio_state_t state,
  174. bt_bdaddr_t *bd_addr)
  175. {
  176. haltest_info("%s: state=%s bd_addr=%s\n", __func__,
  177. bthf_client_audio_state_t2str(state),
  178. bt_bdaddr_t2str(bd_addr, last_addr));
  179. }
  180. /* Callback for VR connection state change. */
  181. static void hf_client_vr_cmd_callback(bthf_client_vr_state_t state)
  182. {
  183. haltest_info("%s: vr_state=%s\n", __func__,
  184. bthf_client_vr_state_t2str(state));
  185. }
  186. /* Callback for network state change */
  187. static void hf_client_network_state_callback(bthf_client_network_state_t state)
  188. {
  189. haltest_info("%s: network_state=%s\n", __func__,
  190. bthf_client_network_state_t2str(state));
  191. }
  192. /* Callback for network roaming status change */
  193. static void hf_client_network_roaming_callback(bthf_client_service_type_t type)
  194. {
  195. haltest_info("%s: service_type=%s\n", __func__,
  196. bthf_client_service_type_t2str(type));
  197. }
  198. /* Callback for signal strength indication */
  199. static void hf_client_network_signal_callback(int signal_strength)
  200. {
  201. haltest_info("%s: signal strength=%d\n", __func__, signal_strength);
  202. }
  203. /* Callback for battery level indication */
  204. static void hf_client_battery_level_callback(int battery_level)
  205. {
  206. haltest_info("%s: battery_lvl=%d\n", __func__, battery_level);
  207. }
  208. /* Callback for current operator name */
  209. static void hf_client_current_operator_callback(const char *name)
  210. {
  211. haltest_info("%s: operator_name=%s\n", __func__, name);
  212. }
  213. /* Callback for call indicator */
  214. static void hf_client_call_callback(bthf_client_call_t call)
  215. {
  216. haltest_info("%s: call_state=%s\n", __func__,
  217. bthf_client_call_t2str(call));
  218. }
  219. /* Callback for callsetup indicator */
  220. static void hf_client_callsetup_callback(bthf_client_callsetup_t callsetup)
  221. {
  222. haltest_info("%s: callsetup=%s\n", __func__,
  223. bthf_client_callsetup_t2str(callsetup));
  224. }
  225. /* Callback for callheld indicator */
  226. static void hf_client_callheld_callback(bthf_client_callheld_t callheld)
  227. {
  228. haltest_info("%s: callheld=%s\n", __func__,
  229. bthf_client_callheld_t2str(callheld));
  230. }
  231. /* Callback for response and hold */
  232. static void hf_client_resp_and_hold_callback(
  233. bthf_client_resp_and_hold_t resp_and_hold)
  234. {
  235. haltest_info("%s: resp_and_hold=%s\n", __func__,
  236. bthf_client_resp_and_hold_t2str(resp_and_hold));
  237. }
  238. /* Callback for Calling Line Identification notification */
  239. static void hf_client_clip_callback(const char *number)
  240. {
  241. haltest_info("%s: number=%s\n", __func__, number);
  242. }
  243. /* Callback for Call Waiting notification */
  244. static void hf_client_call_waiting_callback(const char *number)
  245. {
  246. haltest_info("%s: number=%s\n", __func__, number);
  247. }
  248. /* Callback for listing current calls. Can be called multiple time. */
  249. static void hf_client_current_calls_callback(int index,
  250. bthf_client_call_direction_t dir,
  251. bthf_client_call_state_t state,
  252. bthf_client_call_mpty_type_t mpty,
  253. const char *number)
  254. {
  255. haltest_info("%s: index=%d, direction=%s, state=%s, m_party=%s\n",
  256. __func__, index,
  257. bthf_client_call_direction_t2str(dir),
  258. bthf_client_call_state_t2str(state),
  259. bthf_client_call_mpty_type_t2str(mpty));
  260. if (number)
  261. haltest_info("%s: number=%s\n", __func__, number);
  262. }
  263. /* Callback for audio volume change */
  264. static void hf_client_volume_change_callback(bthf_client_volume_type_t type,
  265. int volume)
  266. {
  267. haltest_info("%s: vol_type=%s, value=%d\n", __func__,
  268. bthf_client_volume_type_t2str(type), volume);
  269. }
  270. /* Callback for command complete event */
  271. static void hf_client_cmd_complete_callback(bthf_client_cmd_complete_t type,
  272. int cme)
  273. {
  274. haltest_info("%s: type=%s, cme=%d\n", __func__,
  275. bthf_client_cmd_complete_t2str(type), cme);
  276. }
  277. /* Callback for subscriber information */
  278. static void hf_client_subscriber_info_callback(const char *name,
  279. bthf_client_subscriber_service_type_t type)
  280. {
  281. haltest_info("%s: name=%s, type=%s\n", __func__, name,
  282. bthf_client_subscriber_service_type_t2str(type));
  283. }
  284. /* Callback for in-band ring tone settings */
  285. static void hf_client_in_band_ring_tone_callback(
  286. bthf_client_in_band_ring_state_t state)
  287. {
  288. haltest_info("%s: state=%s\n", __func__,
  289. bthf_client_in_band_ring_state_t2str(state));
  290. }
  291. /* Callback for requested number from AG */
  292. static void hf_client_last_voice_tag_number_callback(const char *number)
  293. {
  294. haltest_info("%s: number=%s\n", __func__, number);
  295. }
  296. /* Callback for sending ring indication to app */
  297. static void hf_client_ring_indication_callback(void)
  298. {
  299. haltest_info("%s\n", __func__);
  300. }
  301. static bthf_client_callbacks_t hf_client_cbacks = {
  302. .size = sizeof(hf_client_cbacks),
  303. .connection_state_cb = hf_client_connection_state_callback,
  304. .audio_state_cb = hf_client_audio_state_callback,
  305. .vr_cmd_cb = hf_client_vr_cmd_callback,
  306. .network_state_cb = hf_client_network_state_callback,
  307. .network_roaming_cb = hf_client_network_roaming_callback,
  308. .network_signal_cb = hf_client_network_signal_callback,
  309. .battery_level_cb = hf_client_battery_level_callback,
  310. .current_operator_cb = hf_client_current_operator_callback,
  311. .call_cb = hf_client_call_callback,
  312. .callsetup_cb = hf_client_callsetup_callback,
  313. .callheld_cb = hf_client_callheld_callback,
  314. .resp_and_hold_cb = hf_client_resp_and_hold_callback,
  315. .clip_cb = hf_client_clip_callback,
  316. .call_waiting_cb = hf_client_call_waiting_callback,
  317. .current_calls_cb = hf_client_current_calls_callback,
  318. .volume_change_cb = hf_client_volume_change_callback,
  319. .cmd_complete_cb = hf_client_cmd_complete_callback,
  320. .subscriber_info_cb = hf_client_subscriber_info_callback,
  321. .in_band_ring_tone_cb = hf_client_in_band_ring_tone_callback,
  322. .last_voice_tag_number_callback =
  323. hf_client_last_voice_tag_number_callback,
  324. .ring_indication_cb = hf_client_ring_indication_callback,
  325. };
  326. /* init */
  327. static void init_p(int argc, const char **argv)
  328. {
  329. RETURN_IF_NULL(if_hf_client);
  330. EXEC(if_hf_client->init, &hf_client_cbacks);
  331. }
  332. static void connect_c(int argc, const char **argv, enum_func *enum_func,
  333. void **user)
  334. {
  335. if (argc == 3) {
  336. *user = NULL;
  337. *enum_func = enum_devices;
  338. }
  339. }
  340. /* connect to audio gateway */
  341. static void connect_p(int argc, const char **argv)
  342. {
  343. bt_bdaddr_t addr;
  344. RETURN_IF_NULL(if_hf_client);
  345. VERIFY_ADDR_ARG(2, &addr);
  346. EXEC(if_hf_client->connect, &addr);
  347. }
  348. /*
  349. * This completion function will be used for several methods
  350. * returning recently connected address
  351. */
  352. static void connected_addr_c(int argc, const char **argv, enum_func *enum_func,
  353. void **user)
  354. {
  355. if (argc == 3) {
  356. *user = last_addr;
  357. *enum_func = enum_one_string;
  358. }
  359. }
  360. /* Map completion to connected_addr_c */
  361. #define disconnect_c connected_addr_c
  362. /* disconnect from audio gateway */
  363. static void disconnect_p(int argc, const char **argv)
  364. {
  365. bt_bdaddr_t addr;
  366. RETURN_IF_NULL(if_hf_client);
  367. VERIFY_ADDR_ARG(2, &addr);
  368. EXEC(if_hf_client->disconnect, &addr);
  369. }
  370. static void connect_audio_c(int argc, const char **argv, enum_func *enum_func,
  371. void **user)
  372. {
  373. if (argc == 3) {
  374. *user = NULL;
  375. *enum_func = enum_devices;
  376. }
  377. }
  378. /* create an audio connection */
  379. static void connect_audio_p(int argc, const char **argv)
  380. {
  381. bt_bdaddr_t addr;
  382. RETURN_IF_NULL(if_hf_client);
  383. VERIFY_ADDR_ARG(2, &addr);
  384. EXEC(if_hf_client->connect_audio, &addr);
  385. }
  386. /* Map completion to connected_addr_c */
  387. #define disconnect_audio_c connected_addr_c
  388. /* close the audio connection */
  389. static void disconnect_audio_p(int argc, const char **argv)
  390. {
  391. bt_bdaddr_t addr;
  392. RETURN_IF_NULL(if_hf_client);
  393. VERIFY_ADDR_ARG(2, &addr);
  394. EXEC(if_hf_client->disconnect_audio, &addr);
  395. }
  396. /* start voice recognition */
  397. static void start_voice_recognition_p(int argc, const char **argv)
  398. {
  399. RETURN_IF_NULL(if_hf_client);
  400. EXEC(if_hf_client->start_voice_recognition);
  401. }
  402. /* stop voice recognition */
  403. static void stop_voice_recognition_p(int argc, const char **argv)
  404. {
  405. RETURN_IF_NULL(if_hf_client);
  406. EXEC(if_hf_client->stop_voice_recognition);
  407. }
  408. static void volume_control_c(int argc, const char **argv, enum_func *enum_func,
  409. void **user)
  410. {
  411. if (argc == 3) {
  412. *user = TYPE_ENUM(bthf_client_volume_type_t);
  413. *enum_func = enum_defines;
  414. }
  415. }
  416. /* volume control */
  417. static void volume_control_p(int argc, const char **argv)
  418. {
  419. bthf_client_volume_type_t type;
  420. int volume;
  421. RETURN_IF_NULL(if_hf_client);
  422. /* volume type */
  423. if (argc <= 2) {
  424. haltest_error("No volume type specified\n");
  425. return;
  426. }
  427. type = str2bthf_client_volume_type_t(argv[2]);
  428. /* volume */
  429. if (argc <= 3) {
  430. haltest_error("No volume specified\n");
  431. return;
  432. }
  433. volume = atoi(argv[3]);
  434. EXEC(if_hf_client->volume_control, type, volume);
  435. }
  436. /* place a call with number a number */
  437. static void dial_p(int argc, const char **argv)
  438. {
  439. RETURN_IF_NULL(if_hf_client);
  440. /* number string */
  441. if (argc <= 2) {
  442. haltest_info("Number not specified. Redial\n");
  443. EXEC(if_hf_client->dial, NULL);
  444. return;
  445. }
  446. EXEC(if_hf_client->dial, argv[2]);
  447. }
  448. /* place a call with number specified by location (speed dial) */
  449. static void dial_memory_p(int argc, const char **argv)
  450. {
  451. RETURN_IF_NULL(if_hf_client);
  452. /* memory index */
  453. if (argc <= 2) {
  454. haltest_error("No memory index specified\n");
  455. return;
  456. }
  457. EXEC(if_hf_client->dial_memory, atoi(argv[2]));
  458. }
  459. static void handle_call_action_c(int argc, const char **argv,
  460. enum_func *enum_func, void **user)
  461. {
  462. if (argc == 3) {
  463. *user = TYPE_ENUM(bthf_client_call_action_t);
  464. *enum_func = enum_defines;
  465. }
  466. }
  467. /* perform specified call related action */
  468. static void handle_call_action_p(int argc, const char **argv)
  469. {
  470. bthf_client_call_action_t action;
  471. int index = 0;
  472. RETURN_IF_NULL(if_hf_client);
  473. /* action */
  474. if (argc <= 2) {
  475. haltest_error("No action specified\n");
  476. return;
  477. }
  478. action = str2bthf_client_call_action_t(argv[2]);
  479. /* call index */
  480. if (action == BTHF_CLIENT_CALL_ACTION_CHLD_1x ||
  481. action == BTHF_CLIENT_CALL_ACTION_CHLD_2x) {
  482. if (argc <= 3) {
  483. haltest_error("No call index specified\n");
  484. return;
  485. }
  486. index = atoi(argv[3]);
  487. }
  488. EXEC(if_hf_client->handle_call_action, action, index);
  489. }
  490. /* query list of current calls */
  491. static void query_current_calls_p(int argc, const char **argv)
  492. {
  493. RETURN_IF_NULL(if_hf_client);
  494. EXEC(if_hf_client->query_current_calls);
  495. }
  496. /* query name of current selected operator */
  497. static void query_current_operator_name_p(int argc, const char **argv)
  498. {
  499. RETURN_IF_NULL(if_hf_client);
  500. EXEC(if_hf_client->query_current_operator_name);
  501. }
  502. /* Retrieve subscriber information */
  503. static void retrieve_subscriber_info_p(int argc, const char **argv)
  504. {
  505. RETURN_IF_NULL(if_hf_client);
  506. EXEC(if_hf_client->retrieve_subscriber_info);
  507. }
  508. /* Send DTMF code*/
  509. static void send_dtmf_p(int argc, const char **argv)
  510. {
  511. RETURN_IF_NULL(if_hf_client);
  512. EXEC(if_hf_client->send_dtmf, *argv[2]);
  513. }
  514. /* Request a phone number from AG corresponding to last voice tag recorded */
  515. static void request_last_voice_tag_number_p(int argc, const char **argv)
  516. {
  517. RETURN_IF_NULL(if_hf_client);
  518. EXEC(if_hf_client->request_last_voice_tag_number);
  519. }
  520. /* Closes the interface. */
  521. static void cleanup_p(int argc, const char **argv)
  522. {
  523. RETURN_IF_NULL(if_hf_client);
  524. EXECV(if_hf_client->cleanup);
  525. if_hf_client = NULL;
  526. }
  527. static struct method methods[] = {
  528. STD_METHOD(init),
  529. STD_METHODCH(connect, "<addr>"),
  530. STD_METHODCH(disconnect, "<addr>"),
  531. STD_METHODCH(connect_audio, "<addr>"),
  532. STD_METHODCH(disconnect_audio, "<addr>"),
  533. STD_METHOD(start_voice_recognition),
  534. STD_METHOD(stop_voice_recognition),
  535. STD_METHODCH(volume_control, "<volume_type> <value>"),
  536. STD_METHODH(dial, "<destination_number>"),
  537. STD_METHODH(dial_memory, "<memory_location>"),
  538. STD_METHODCH(handle_call_action, "<call_action> <call_index>"),
  539. STD_METHOD(query_current_calls),
  540. STD_METHOD(query_current_operator_name),
  541. STD_METHOD(retrieve_subscriber_info),
  542. STD_METHODH(send_dtmf, "<code>"),
  543. STD_METHOD(request_last_voice_tag_number),
  544. STD_METHOD(cleanup),
  545. END_METHOD
  546. };
  547. const struct interface hf_client_if = {
  548. .name = "handsfree_client",
  549. .methods = methods
  550. };