if-rc.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. // SPDX-License-Identifier: Apache-2.0
  2. /*
  3. * Copyright (C) 2014 Intel Corporation
  4. *
  5. */
  6. #define _GNU_SOURCE
  7. #include <stdio.h>
  8. #include <ctype.h>
  9. #include <string.h>
  10. #include <hardware/bluetooth.h>
  11. #include <hardware/bt_hh.h>
  12. #include "if-main.h"
  13. #include "pollhandler.h"
  14. #include "../hal-utils.h"
  15. const btrc_interface_t *if_rc = NULL;
  16. SINTMAP(btrc_play_status_t, -1, "(unknown)")
  17. DELEMENT(BTRC_PLAYSTATE_STOPPED),
  18. DELEMENT(BTRC_PLAYSTATE_PLAYING),
  19. DELEMENT(BTRC_PLAYSTATE_PAUSED),
  20. DELEMENT(BTRC_PLAYSTATE_FWD_SEEK),
  21. DELEMENT(BTRC_PLAYSTATE_REV_SEEK),
  22. DELEMENT(BTRC_PLAYSTATE_ERROR),
  23. ENDMAP
  24. SINTMAP(btrc_media_attr_t, -1, "(unknown)")
  25. DELEMENT(BTRC_MEDIA_ATTR_TITLE),
  26. DELEMENT(BTRC_MEDIA_ATTR_ARTIST),
  27. DELEMENT(BTRC_MEDIA_ATTR_ALBUM),
  28. DELEMENT(BTRC_MEDIA_ATTR_TRACK_NUM),
  29. DELEMENT(BTRC_MEDIA_ATTR_NUM_TRACKS),
  30. DELEMENT(BTRC_MEDIA_ATTR_GENRE),
  31. DELEMENT(BTRC_MEDIA_ATTR_PLAYING_TIME),
  32. ENDMAP
  33. SINTMAP(btrc_status_t, -1, "(unknown)")
  34. DELEMENT(BTRC_STS_BAD_CMD),
  35. DELEMENT(BTRC_STS_BAD_PARAM),
  36. DELEMENT(BTRC_STS_NOT_FOUND),
  37. DELEMENT(BTRC_STS_INTERNAL_ERR),
  38. DELEMENT(BTRC_STS_NO_ERROR),
  39. ENDMAP
  40. SINTMAP(btrc_event_id_t, -1, "(unknown)")
  41. DELEMENT(BTRC_EVT_PLAY_STATUS_CHANGED),
  42. DELEMENT(BTRC_EVT_TRACK_CHANGE),
  43. DELEMENT(BTRC_EVT_TRACK_REACHED_END),
  44. DELEMENT(BTRC_EVT_TRACK_REACHED_START),
  45. DELEMENT(BTRC_EVT_PLAY_POS_CHANGED),
  46. DELEMENT(BTRC_EVT_APP_SETTINGS_CHANGED),
  47. ENDMAP
  48. SINTMAP(btrc_notification_type_t, -1, "(unknown)")
  49. DELEMENT(BTRC_NOTIFICATION_TYPE_INTERIM),
  50. DELEMENT(BTRC_NOTIFICATION_TYPE_CHANGED),
  51. ENDMAP
  52. static char last_addr[MAX_ADDR_STR_LEN];
  53. static void remote_features_cb(bt_bdaddr_t *bd_addr,
  54. btrc_remote_features_t features)
  55. {
  56. haltest_info("%s: remote_bd_addr=%s features=%u\n", __func__,
  57. bt_bdaddr_t2str(bd_addr, last_addr), features);
  58. }
  59. static void get_play_status_cb(void)
  60. {
  61. haltest_info("%s\n", __func__);
  62. }
  63. static void list_player_app_attr_cb(void)
  64. {
  65. haltest_info("%s\n", __func__);
  66. }
  67. static void list_player_app_values_cb(btrc_player_attr_t attr_id)
  68. {
  69. haltest_info("%s, attr_id=%d\n", __func__, attr_id);
  70. }
  71. static void get_player_app_value_cb(uint8_t num_attr,
  72. btrc_player_attr_t *p_attrs)
  73. {
  74. int i;
  75. haltest_info("%s, num_attr=%d\n", __func__, num_attr);
  76. for (i = 0; i < num_attr; i++)
  77. haltest_info("attribute=%u\n", p_attrs[i]);
  78. }
  79. static void get_player_app_attrs_text_cb(uint8_t num_attr,
  80. btrc_player_attr_t *p_attrs)
  81. {
  82. int i;
  83. haltest_info("%s, num_attr=%d\n", __func__, num_attr);
  84. for (i = 0; i < num_attr; i++)
  85. haltest_info("attribute=%u\n", p_attrs[i]);
  86. }
  87. static void get_player_app_values_text_cb(uint8_t attr_id, uint8_t num_val,
  88. uint8_t *p_vals)
  89. {
  90. haltest_info("%s, attr_id=%d num_val=%d values=%p\n", __func__,
  91. attr_id, num_val, p_vals);
  92. }
  93. static void set_player_app_value_cb(btrc_player_settings_t *p_vals)
  94. {
  95. int i;
  96. haltest_info("%s, num_attr=%u\n", __func__, p_vals->num_attr);
  97. for (i = 0; i < p_vals->num_attr; i++)
  98. haltest_info("attr id=%u, values=%u\n", p_vals->attr_ids[i],
  99. p_vals->attr_values[i]);
  100. }
  101. static void get_element_attr_cb(uint8_t num_attr, btrc_media_attr_t *attrs)
  102. {
  103. uint8_t i;
  104. haltest_info("%s, num_of_attributes=%d\n", __func__, num_attr);
  105. for (i = 0; i < num_attr; i++)
  106. haltest_info("attr id=%s\n", btrc_media_attr_t2str(attrs[i]));
  107. }
  108. static void register_notification_cb(btrc_event_id_t event_id, uint32_t param)
  109. {
  110. haltest_info("%s, event=%u param=%u\n", __func__, event_id, param);
  111. }
  112. static void volume_change_cb(uint8_t volume, uint8_t ctype)
  113. {
  114. haltest_info("%s, volume=%d ctype=%d\n", __func__, volume, ctype);
  115. }
  116. static void passthrough_cmd_cb(int id, int key_state)
  117. {
  118. haltest_info("%s, id=%d key_state=%d\n", __func__, id, key_state);
  119. }
  120. static btrc_callbacks_t rc_cbacks = {
  121. .size = sizeof(rc_cbacks),
  122. .remote_features_cb = remote_features_cb,
  123. .get_play_status_cb = get_play_status_cb,
  124. .list_player_app_attr_cb = list_player_app_attr_cb,
  125. .list_player_app_values_cb = list_player_app_values_cb,
  126. .get_player_app_value_cb = get_player_app_value_cb,
  127. .get_player_app_attrs_text_cb = get_player_app_attrs_text_cb,
  128. .get_player_app_values_text_cb = get_player_app_values_text_cb,
  129. .set_player_app_value_cb = set_player_app_value_cb,
  130. .get_element_attr_cb = get_element_attr_cb,
  131. .register_notification_cb = register_notification_cb,
  132. .volume_change_cb = volume_change_cb,
  133. .passthrough_cmd_cb = passthrough_cmd_cb,
  134. };
  135. /* init */
  136. static void init_p(int argc, const char **argv)
  137. {
  138. RETURN_IF_NULL(if_rc);
  139. EXEC(if_rc->init, &rc_cbacks);
  140. }
  141. /* get_play_status_rsp */
  142. static void get_play_status_rsp_c(int argc, const char **argv,
  143. enum_func *enum_func, void **user)
  144. {
  145. if (argc == 3) {
  146. *user = TYPE_ENUM(btrc_play_status_t);
  147. *enum_func = enum_defines;
  148. }
  149. }
  150. static void get_play_status_rsp_p(int argc, const char **argv)
  151. {
  152. btrc_play_status_t play_status;
  153. uint32_t song_len, song_pos;
  154. RETURN_IF_NULL(if_rc);
  155. if (argc <= 2) {
  156. haltest_error("No play status specified");
  157. return;
  158. }
  159. if (argc <= 3) {
  160. haltest_error("No song length specified");
  161. return;
  162. }
  163. if (argc <= 4) {
  164. haltest_error("No song position specified");
  165. return;
  166. }
  167. play_status = str2btrc_play_status_t(argv[2]);
  168. song_len = (uint32_t) atoi(argv[3]);
  169. song_pos = (uint32_t) atoi(argv[4]);
  170. EXEC(if_rc->get_play_status_rsp, play_status, song_len, song_pos);
  171. }
  172. /* get_element_attr_rsp */
  173. static void get_element_attr_rsp_c(int argc, const char **argv,
  174. enum_func *enum_func, void **user)
  175. {
  176. if (argc == 4) {
  177. *user = TYPE_ENUM(btrc_media_attr_t);
  178. *enum_func = enum_defines;
  179. }
  180. }
  181. static void get_element_attr_rsp_p(int argc, const char **argv)
  182. {
  183. uint8_t num_attr;
  184. btrc_element_attr_val_t attrs;
  185. RETURN_IF_NULL(if_rc);
  186. if (argc <= 2) {
  187. haltest_error("No number of attributes specified");
  188. return;
  189. }
  190. if (argc <= 4) {
  191. haltest_error("No attr id and value specified");
  192. return;
  193. }
  194. num_attr = (uint8_t) atoi(argv[2]);
  195. attrs.attr_id = str2btrc_media_attr_t(argv[3]);
  196. strcpy((char *)attrs.text, argv[4]);
  197. EXEC(if_rc->get_element_attr_rsp, num_attr, &attrs);
  198. }
  199. /* set_volume */
  200. static void set_volume_c(int argc, const char **argv,
  201. enum_func *enum_func, void **user)
  202. {
  203. }
  204. static void set_volume_p(int argc, const char **argv)
  205. {
  206. uint8_t volume;
  207. RETURN_IF_NULL(if_rc);
  208. if (argc <= 2) {
  209. haltest_error("No volume specified");
  210. return;
  211. }
  212. volume = (uint8_t) atoi(argv[2]);
  213. EXEC(if_rc->set_volume, volume);
  214. }
  215. /* set_player_app_value_rsp */
  216. static void set_player_app_value_rsp_c(int argc, const char **argv,
  217. enum_func *enum_func, void **user)
  218. {
  219. if (argc == 3) {
  220. *user = TYPE_ENUM(btrc_status_t);
  221. *enum_func = enum_defines;
  222. }
  223. }
  224. static void set_player_app_value_rsp_p(int argc, const char **argv)
  225. {
  226. btrc_status_t rsp_status;
  227. RETURN_IF_NULL(if_rc);
  228. if (argc <= 2) {
  229. haltest_error("No response status specified");
  230. return;
  231. }
  232. rsp_status = str2btrc_status_t(argv[2]);
  233. EXEC(if_rc->set_player_app_value_rsp, rsp_status);
  234. }
  235. /* register_notification_rsp */
  236. static void register_notification_rsp_c(int argc, const char **argv,
  237. enum_func *enum_func, void **user)
  238. {
  239. if (argc == 3) {
  240. *user = TYPE_ENUM(btrc_event_id_t);
  241. *enum_func = enum_defines;
  242. }
  243. if (argc == 4) {
  244. *user = TYPE_ENUM(btrc_notification_type_t);
  245. *enum_func = enum_defines;
  246. }
  247. }
  248. static void register_notification_rsp_p(int argc, const char **argv)
  249. {
  250. btrc_event_id_t event_id;
  251. btrc_notification_type_t type;
  252. btrc_register_notification_t reg;
  253. uint32_t song_pos;
  254. uint64_t track;
  255. RETURN_IF_NULL(if_rc);
  256. memset(&reg, 0, sizeof(reg));
  257. event_id = str2btrc_event_id_t(argv[2]);
  258. type = str2btrc_notification_type_t(argv[3]);
  259. switch (event_id) {
  260. case BTRC_EVT_PLAY_STATUS_CHANGED:
  261. reg.play_status = str2btrc_play_status_t(argv[4]);
  262. break;
  263. case BTRC_EVT_TRACK_CHANGE:
  264. track = strtoull(argv[5], NULL, 10);
  265. memcpy(reg.track, &track, sizeof(btrc_uid_t));
  266. break;
  267. case BTRC_EVT_TRACK_REACHED_END:
  268. case BTRC_EVT_TRACK_REACHED_START:
  269. break;
  270. case BTRC_EVT_PLAY_POS_CHANGED:
  271. song_pos = strtoul(argv[4], NULL, 10);
  272. memcpy(&reg.song_pos, &song_pos, sizeof(uint32_t));
  273. break;
  274. case BTRC_EVT_APP_SETTINGS_CHANGED:
  275. haltest_error("not supported");
  276. return;
  277. }
  278. EXEC(if_rc->register_notification_rsp, event_id, type, &reg);
  279. }
  280. /* cleanup */
  281. static void cleanup_p(int argc, const char **argv)
  282. {
  283. RETURN_IF_NULL(if_rc);
  284. EXECV(if_rc->cleanup);
  285. if_rc = NULL;
  286. }
  287. static struct method methods[] = {
  288. STD_METHOD(init),
  289. STD_METHODCH(get_play_status_rsp,
  290. "<play_status> <song_len> <song_pos>"),
  291. STD_METHODCH(get_element_attr_rsp, "<num_attr> <attrs_id> <value>"),
  292. STD_METHODCH(set_player_app_value_rsp, "<rsp_status>"),
  293. STD_METHODCH(set_volume, "<volume>"),
  294. STD_METHODCH(register_notification_rsp,
  295. "<event_id> <type> <respective_data...>\n"
  296. "BTRC_EVT_PLAY_STATUS_CHANGED <type> <play_status>\n"
  297. "BTRC_EVT_TRACK_CHANGE <type> <track>\n"
  298. "BTRC_EVT_TRACK_REACHED_END <type>\n"
  299. "BTRC_EVT_TRACK_REACHED_START <type>\n"
  300. "BTRC_EVT_PLAY_POS_CHANGED <type> <song_pos>\n"),
  301. STD_METHOD(cleanup),
  302. END_METHOD
  303. };
  304. const struct interface rc_if = {
  305. .name = "rc",
  306. .methods = methods
  307. };