hal-avrcp.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. // SPDX-License-Identifier: Apache-2.0
  2. /*
  3. * Copyright (C) 2014 Intel Corporation
  4. *
  5. */
  6. #define _GNU_SOURCE
  7. #include <stdbool.h>
  8. #include <stddef.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #include "hal-utils.h"
  12. #include "hal-log.h"
  13. #include "hal.h"
  14. #include "hal-msg.h"
  15. #include "ipc-common.h"
  16. #include "hal-ipc.h"
  17. static const btrc_callbacks_t *cbs = NULL;
  18. static bool interface_ready(void)
  19. {
  20. return cbs != NULL;
  21. }
  22. static void handle_remote_features(void *buf, uint16_t len, int fd)
  23. {
  24. struct hal_ev_avrcp_remote_features *ev = buf;
  25. if (cbs->remote_features_cb)
  26. cbs->remote_features_cb((bt_bdaddr_t *) (ev->bdaddr),
  27. ev->features);
  28. }
  29. static void handle_get_play_status(void *buf, uint16_t len, int fd)
  30. {
  31. if (cbs->get_play_status_cb)
  32. cbs->get_play_status_cb();
  33. }
  34. static void handle_list_player_attrs(void *buf, uint16_t len, int fd)
  35. {
  36. if (cbs->list_player_app_attr_cb)
  37. cbs->list_player_app_attr_cb();
  38. }
  39. static void handle_list_player_values(void *buf, uint16_t len, int fd)
  40. {
  41. struct hal_ev_avrcp_list_player_values *ev = buf;
  42. if (cbs->list_player_app_values_cb)
  43. cbs->list_player_app_values_cb(ev->attr);
  44. }
  45. static void handle_get_player_values(void *buf, uint16_t len, int fd)
  46. {
  47. struct hal_ev_avrcp_get_player_values *ev = buf;
  48. btrc_player_attr_t attrs[4];
  49. int i;
  50. if (!cbs->get_player_app_value_cb)
  51. return;
  52. /* Convert uint8_t array to btrc_player_attr_t array */
  53. for (i = 0; i < ev->number; i++)
  54. attrs[i] = ev->attrs[i];
  55. cbs->get_player_app_value_cb(ev->number, attrs);
  56. }
  57. static void handle_get_player_attrs_text(void *buf, uint16_t len, int fd)
  58. {
  59. struct hal_ev_avrcp_get_player_attrs_text *ev = buf;
  60. btrc_player_attr_t attrs[4];
  61. int i;
  62. if (!cbs->get_player_app_attrs_text_cb)
  63. return;
  64. /* Convert uint8_t array to btrc_player_attr_t array */
  65. for (i = 0; i < ev->number; i++)
  66. attrs[i] = ev->attrs[i];
  67. cbs->get_player_app_attrs_text_cb(ev->number, attrs);
  68. }
  69. static void handle_get_player_values_text(void *buf, uint16_t len, int fd)
  70. {
  71. struct hal_ev_avrcp_get_player_values_text *ev = buf;
  72. if (cbs->get_player_app_values_text_cb)
  73. cbs->get_player_app_values_text_cb(ev->attr, ev->number,
  74. ev->values);
  75. }
  76. static void handle_set_player_value(void *buf, uint16_t len, int fd)
  77. {
  78. struct hal_ev_avrcp_set_player_values *ev = buf;
  79. struct hal_avrcp_player_attr_value *attrs;
  80. btrc_player_settings_t values;
  81. int i;
  82. if (!cbs->set_player_app_value_cb)
  83. return;
  84. attrs = (struct hal_avrcp_player_attr_value *) ev->attrs;
  85. /* Convert to btrc_player_settings_t */
  86. values.num_attr = ev->number;
  87. for (i = 0; i < ev->number; i++) {
  88. values.attr_ids[i] = attrs[i].attr;
  89. values.attr_values[i] = attrs[i].value;
  90. }
  91. cbs->set_player_app_value_cb(&values);
  92. }
  93. static void handle_get_element_attrs(void *buf, uint16_t len, int fd)
  94. {
  95. struct hal_ev_avrcp_get_element_attrs *ev = buf;
  96. btrc_media_attr_t attrs[BTRC_MAX_APP_SETTINGS];
  97. int i;
  98. if (!cbs->get_element_attr_cb)
  99. return;
  100. /* Convert uint8_t array to btrc_media_attr_t array */
  101. for (i = 0; i < ev->number; i++)
  102. attrs[i] = ev->attrs[i];
  103. cbs->get_element_attr_cb(ev->number, attrs);
  104. }
  105. static void handle_register_notification(void *buf, uint16_t len, int fd)
  106. {
  107. struct hal_ev_avrcp_register_notification *ev = buf;
  108. if (cbs->register_notification_cb)
  109. cbs->register_notification_cb(ev->event, ev->param);
  110. }
  111. static void handle_volume_changed(void *buf, uint16_t len, int fd)
  112. {
  113. struct hal_ev_avrcp_volume_changed *ev = buf;
  114. if (cbs->volume_change_cb)
  115. cbs->volume_change_cb(ev->volume, ev->type);
  116. }
  117. static void handle_passthrough_cmd(void *buf, uint16_t len, int fd)
  118. {
  119. struct hal_ev_avrcp_passthrough_cmd *ev = buf;
  120. if (cbs->passthrough_cmd_cb)
  121. cbs->passthrough_cmd_cb(ev->id, ev->state);
  122. }
  123. /*
  124. * handlers will be called from notification thread context,
  125. * index in table equals to 'opcode - HAL_MINIMUM_EVENT'
  126. */
  127. static const struct hal_ipc_handler ev_handlers[] = {
  128. /* HAL_EV_AVRCP_REMOTE_FEATURES */
  129. { handle_remote_features, false,
  130. sizeof(struct hal_ev_avrcp_remote_features) },
  131. /* HAL_EV_AVRCP_GET_PLAY_STATUS */
  132. { handle_get_play_status, false, 0 },
  133. /* HAL_EV_AVRCP_LIST_PLAYER_ATTRS */
  134. { handle_list_player_attrs, false, 0 },
  135. /* HAL_EV_AVRCP_LIST_PLAYER_VALUES */
  136. { handle_list_player_values, false,
  137. sizeof(struct hal_ev_avrcp_list_player_values) },
  138. /* HAL_EV_AVRCP_GET_PLAYER_VALUES */
  139. { handle_get_player_values, true,
  140. sizeof(struct hal_ev_avrcp_get_player_values) },
  141. /* HAL_EV_AVRCP_GET_PLAYER_ATTRS_TEXT */
  142. { handle_get_player_attrs_text, true,
  143. sizeof(struct hal_ev_avrcp_get_player_attrs_text) },
  144. /* HAL_EV_AVRCP_GET_PLAYER_VALUES_TEXT */
  145. { handle_get_player_values_text, true,
  146. sizeof(struct hal_ev_avrcp_get_player_values_text) },
  147. /* HAL_EV_AVRCP_SET_PLAYER_VALUES */
  148. { handle_set_player_value, true,
  149. sizeof(struct hal_ev_avrcp_set_player_values) },
  150. /* HAL_EV_AVRCP_GET_ELEMENT_ATTRS */
  151. { handle_get_element_attrs, true,
  152. sizeof(struct hal_ev_avrcp_get_element_attrs) },
  153. /* HAL_EV_AVRCP_REGISTER_NOTIFICATION */
  154. { handle_register_notification, false,
  155. sizeof(struct hal_ev_avrcp_register_notification) },
  156. /* HAL_EV_AVRCP_VOLUME_CHANGED */
  157. { handle_volume_changed, false,
  158. sizeof(struct hal_ev_avrcp_volume_changed) },
  159. /* HAL_EV_AVRCP_PASSTHROUGH_CMD */
  160. { handle_passthrough_cmd, false,
  161. sizeof(struct hal_ev_avrcp_passthrough_cmd) },
  162. };
  163. static bt_status_t init(btrc_callbacks_t *callbacks)
  164. {
  165. struct hal_cmd_register_module cmd;
  166. int ret;
  167. DBG("");
  168. if (interface_ready())
  169. return BT_STATUS_DONE;
  170. cbs = callbacks;
  171. hal_ipc_register(HAL_SERVICE_ID_AVRCP, ev_handlers,
  172. sizeof(ev_handlers) / sizeof(ev_handlers[0]));
  173. cmd.service_id = HAL_SERVICE_ID_AVRCP;
  174. cmd.mode = HAL_MODE_DEFAULT;
  175. cmd.max_clients = 1;
  176. ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
  177. sizeof(cmd), &cmd, NULL, NULL, NULL);
  178. if (ret != BT_STATUS_SUCCESS) {
  179. cbs = NULL;
  180. hal_ipc_unregister(HAL_SERVICE_ID_AVRCP);
  181. }
  182. return ret;
  183. }
  184. static bt_status_t get_play_status_rsp(btrc_play_status_t status,
  185. uint32_t song_len, uint32_t song_pos)
  186. {
  187. struct hal_cmd_avrcp_get_play_status cmd;
  188. DBG("");
  189. if (!interface_ready())
  190. return BT_STATUS_NOT_READY;
  191. cmd.status = status;
  192. cmd.duration = song_len;
  193. cmd.position = song_pos;
  194. return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAY_STATUS,
  195. sizeof(cmd), &cmd, NULL, NULL, NULL);
  196. }
  197. static bt_status_t list_player_app_attr_rsp(int num_attr,
  198. btrc_player_attr_t *p_attrs)
  199. {
  200. char buf[IPC_MTU];
  201. struct hal_cmd_avrcp_list_player_attrs *cmd = (void *) buf;
  202. size_t len;
  203. DBG("");
  204. if (!interface_ready())
  205. return BT_STATUS_NOT_READY;
  206. if (num_attr < 0)
  207. return BT_STATUS_PARM_INVALID;
  208. len = sizeof(*cmd) + num_attr;
  209. if (len > IPC_MTU)
  210. return BT_STATUS_PARM_INVALID;
  211. cmd->number = num_attr;
  212. memcpy(cmd->attrs, p_attrs, num_attr);
  213. return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
  214. HAL_OP_AVRCP_LIST_PLAYER_ATTRS,
  215. len, cmd, NULL, NULL, NULL);
  216. }
  217. static bt_status_t list_player_app_value_rsp(int num_val, uint8_t *p_vals)
  218. {
  219. char buf[IPC_MTU];
  220. struct hal_cmd_avrcp_list_player_values *cmd = (void *) buf;
  221. size_t len;
  222. DBG("");
  223. if (!interface_ready())
  224. return BT_STATUS_NOT_READY;
  225. if (num_val < 0)
  226. return BT_STATUS_PARM_INVALID;
  227. len = sizeof(*cmd) + num_val;
  228. if (len > IPC_MTU)
  229. return BT_STATUS_PARM_INVALID;
  230. cmd->number = num_val;
  231. memcpy(cmd->values, p_vals, num_val);
  232. return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
  233. HAL_OP_AVRCP_LIST_PLAYER_VALUES,
  234. len, cmd, NULL, NULL, NULL);
  235. }
  236. static bt_status_t get_player_app_value_rsp(btrc_player_settings_t *p_vals)
  237. {
  238. char buf[IPC_MTU];
  239. struct hal_cmd_avrcp_get_player_attrs *cmd = (void *) buf;
  240. size_t len, attrs_len;
  241. int i;
  242. DBG("");
  243. if (!interface_ready())
  244. return BT_STATUS_NOT_READY;
  245. if (!p_vals)
  246. return BT_STATUS_PARM_INVALID;
  247. attrs_len = p_vals->num_attr *
  248. sizeof(struct hal_avrcp_player_attr_value);
  249. len = sizeof(*cmd) + attrs_len;
  250. if (len > IPC_MTU)
  251. return BT_STATUS_PARM_INVALID;
  252. cmd->number = p_vals->num_attr;
  253. for (i = 0; i < p_vals->num_attr; i++) {
  254. cmd->attrs[i].attr = p_vals->attr_ids[i];
  255. cmd->attrs[i].value = p_vals->attr_values[i];
  256. }
  257. return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
  258. HAL_OP_AVRCP_GET_PLAYER_ATTRS,
  259. len, cmd, NULL, NULL, NULL);
  260. }
  261. static int write_text(uint8_t *ptr, uint8_t id, uint8_t *text, size_t *len)
  262. {
  263. struct hal_avrcp_player_setting_text *value = (void *) ptr;
  264. size_t attr_len = sizeof(*value);
  265. if (attr_len + *len > IPC_MTU)
  266. return 0;
  267. value->id = id;
  268. value->len = strnlen((const char *) text, BTRC_MAX_ATTR_STR_LEN);
  269. *len += attr_len;
  270. if (value->len + *len > IPC_MTU)
  271. value->len = IPC_MTU - *len;
  272. memcpy(value->text, text, value->len);
  273. *len += value->len;
  274. return attr_len + value->len;
  275. }
  276. static uint8_t write_player_setting_text(uint8_t *ptr, uint8_t num_attr,
  277. btrc_player_setting_text_t *p_attrs,
  278. size_t *len)
  279. {
  280. int i;
  281. for (i = 0; i < num_attr && *len < IPC_MTU; i++) {
  282. int ret;
  283. ret = write_text(ptr, p_attrs[i].id, p_attrs[i].text, len);
  284. if (ret == 0)
  285. break;
  286. ptr += ret;
  287. }
  288. return i;
  289. }
  290. static bt_status_t get_player_app_attr_text_rsp(int num_attr,
  291. btrc_player_setting_text_t *p_attrs)
  292. {
  293. char buf[IPC_MTU];
  294. struct hal_cmd_avrcp_get_player_attrs_text *cmd = (void *) buf;
  295. uint8_t *ptr;
  296. size_t len;
  297. DBG("");
  298. if (!interface_ready())
  299. return BT_STATUS_NOT_READY;
  300. if (num_attr < 0 || num_attr > BTRC_MAX_APP_SETTINGS)
  301. return BT_STATUS_PARM_INVALID;
  302. len = sizeof(*cmd);
  303. ptr = (uint8_t *) &cmd->attrs[0];
  304. cmd->number = write_player_setting_text(ptr, num_attr, p_attrs, &len);
  305. return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
  306. HAL_OP_AVRCP_GET_PLAYER_ATTRS_TEXT,
  307. len, cmd, NULL, NULL, NULL);
  308. }
  309. static bt_status_t get_player_app_value_text_rsp(int num_val,
  310. btrc_player_setting_text_t *p_vals)
  311. {
  312. char buf[IPC_MTU];
  313. struct hal_cmd_avrcp_get_player_values_text *cmd = (void *) buf;
  314. uint8_t *ptr;
  315. size_t len;
  316. DBG("");
  317. if (!interface_ready())
  318. return BT_STATUS_NOT_READY;
  319. if (num_val < 0)
  320. return BT_STATUS_PARM_INVALID;
  321. len = sizeof(*cmd);
  322. ptr = (uint8_t *) &cmd->values[0];
  323. cmd->number = write_player_setting_text(ptr, num_val, p_vals, &len);
  324. return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
  325. HAL_OP_AVRCP_GET_PLAYER_VALUES_TEXT,
  326. len, cmd, NULL, NULL, NULL);
  327. }
  328. static uint8_t write_element_attr_text(uint8_t *ptr, uint8_t num_attr,
  329. btrc_element_attr_val_t *p_attrs,
  330. size_t *len)
  331. {
  332. int i;
  333. for (i = 0; i < num_attr && *len < IPC_MTU; i++) {
  334. int ret;
  335. ret = write_text(ptr, p_attrs[i].attr_id, p_attrs[i].text, len);
  336. if (ret == 0)
  337. break;
  338. ptr += ret;
  339. }
  340. return i;
  341. }
  342. static bt_status_t get_element_attr_rsp(uint8_t num_attr,
  343. btrc_element_attr_val_t *p_attrs)
  344. {
  345. char buf[IPC_MTU];
  346. struct hal_cmd_avrcp_get_element_attrs_text *cmd = (void *) buf;
  347. size_t len;
  348. uint8_t *ptr;
  349. DBG("");
  350. if (!interface_ready())
  351. return BT_STATUS_NOT_READY;
  352. len = sizeof(*cmd);
  353. ptr = (uint8_t *) &cmd->values[0];
  354. cmd->number = write_element_attr_text(ptr, num_attr, p_attrs, &len);
  355. return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
  356. HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT,
  357. len, cmd, NULL, NULL, NULL);
  358. }
  359. static bt_status_t set_player_app_value_rsp(btrc_status_t rsp_status)
  360. {
  361. struct hal_cmd_avrcp_set_player_attrs_value cmd;
  362. DBG("");
  363. if (!interface_ready())
  364. return BT_STATUS_NOT_READY;
  365. cmd.status = rsp_status;
  366. return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
  367. HAL_OP_AVRCP_SET_PLAYER_ATTRS_VALUE,
  368. sizeof(cmd), &cmd, NULL, NULL, NULL);
  369. }
  370. static bt_status_t play_status_changed_rsp(btrc_notification_type_t type,
  371. btrc_play_status_t *play_status)
  372. {
  373. char buf[IPC_MTU];
  374. struct hal_cmd_avrcp_register_notification *cmd = (void *) buf;
  375. size_t len;
  376. cmd->event = BTRC_EVT_PLAY_STATUS_CHANGED;
  377. cmd->type = type;
  378. cmd->len = 1;
  379. memcpy(cmd->data, play_status, cmd->len);
  380. len = sizeof(*cmd) + cmd->len;
  381. return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
  382. HAL_OP_AVRCP_REGISTER_NOTIFICATION,
  383. len, cmd, NULL, NULL, NULL);
  384. }
  385. static bt_status_t track_change_rsp(btrc_notification_type_t type,
  386. btrc_uid_t *track)
  387. {
  388. char buf[IPC_MTU];
  389. struct hal_cmd_avrcp_register_notification *cmd = (void *) buf;
  390. size_t len;
  391. cmd->event = BTRC_EVT_TRACK_CHANGE;
  392. cmd->type = type;
  393. cmd->len = sizeof(*track);
  394. memcpy(cmd->data, track, cmd->len);
  395. len = sizeof(*cmd) + cmd->len;
  396. return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
  397. HAL_OP_AVRCP_REGISTER_NOTIFICATION,
  398. len, cmd, NULL, NULL, NULL);
  399. }
  400. static bt_status_t track_reached_end_rsp(btrc_notification_type_t type)
  401. {
  402. struct hal_cmd_avrcp_register_notification cmd;
  403. cmd.event = BTRC_EVT_TRACK_REACHED_END;
  404. cmd.type = type;
  405. cmd.len = 0;
  406. return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
  407. HAL_OP_AVRCP_REGISTER_NOTIFICATION,
  408. sizeof(cmd), &cmd, NULL, NULL, NULL);
  409. }
  410. static bt_status_t track_reached_start_rsp(btrc_notification_type_t type)
  411. {
  412. struct hal_cmd_avrcp_register_notification cmd;
  413. cmd.event = BTRC_EVT_TRACK_REACHED_START;
  414. cmd.type = type;
  415. cmd.len = 0;
  416. return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
  417. HAL_OP_AVRCP_REGISTER_NOTIFICATION,
  418. sizeof(cmd), &cmd, NULL, NULL, NULL);
  419. }
  420. static bt_status_t play_pos_changed_rsp(btrc_notification_type_t type,
  421. uint32_t *song_pos)
  422. {
  423. char buf[IPC_MTU];
  424. struct hal_cmd_avrcp_register_notification *cmd = (void *) buf;
  425. size_t len;
  426. cmd->event = BTRC_EVT_PLAY_POS_CHANGED;
  427. cmd->type = type;
  428. cmd->len = sizeof(*song_pos);
  429. memcpy(cmd->data, song_pos, cmd->len);
  430. len = sizeof(*cmd) + cmd->len;
  431. return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
  432. HAL_OP_AVRCP_REGISTER_NOTIFICATION,
  433. len, cmd, NULL, NULL, NULL);
  434. }
  435. static bt_status_t settings_changed_rsp(btrc_notification_type_t type,
  436. btrc_player_settings_t *player_setting)
  437. {
  438. char buf[IPC_MTU];
  439. struct hal_cmd_avrcp_register_notification *cmd = (void *) buf;
  440. struct hal_avrcp_player_attr_value *attrs;
  441. size_t len, param_len;
  442. int i;
  443. param_len = player_setting->num_attr * sizeof(*attrs);
  444. len = sizeof(*cmd) + param_len;
  445. if (len > IPC_MTU)
  446. return BT_STATUS_PARM_INVALID;
  447. cmd->event = BTRC_EVT_APP_SETTINGS_CHANGED;
  448. cmd->type = type;
  449. cmd->len = param_len;
  450. attrs = (struct hal_avrcp_player_attr_value *) &cmd->data[0];
  451. for (i = 0; i < player_setting->num_attr; i++) {
  452. attrs[i].attr = player_setting->attr_ids[i];
  453. attrs[i].value = player_setting->attr_values[i];
  454. }
  455. return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
  456. HAL_OP_AVRCP_REGISTER_NOTIFICATION,
  457. len, cmd, NULL, NULL, NULL);
  458. }
  459. static bt_status_t register_notification_rsp(btrc_event_id_t event_id,
  460. btrc_notification_type_t type,
  461. btrc_register_notification_t *p_param)
  462. {
  463. DBG("");
  464. if (!interface_ready())
  465. return BT_STATUS_NOT_READY;
  466. switch (event_id) {
  467. case BTRC_EVT_PLAY_STATUS_CHANGED:
  468. return play_status_changed_rsp(type, &p_param->play_status);
  469. case BTRC_EVT_TRACK_CHANGE:
  470. return track_change_rsp(type, &p_param->track);
  471. case BTRC_EVT_TRACK_REACHED_END:
  472. return track_reached_end_rsp(type);
  473. case BTRC_EVT_TRACK_REACHED_START:
  474. return track_reached_start_rsp(type);
  475. case BTRC_EVT_PLAY_POS_CHANGED:
  476. return play_pos_changed_rsp(type, &p_param->song_pos);
  477. case BTRC_EVT_APP_SETTINGS_CHANGED:
  478. return settings_changed_rsp(type, &p_param->player_setting);
  479. default:
  480. return BT_STATUS_PARM_INVALID;
  481. }
  482. }
  483. static bt_status_t set_volume(uint8_t volume)
  484. {
  485. struct hal_cmd_avrcp_set_volume cmd;
  486. DBG("");
  487. if (!interface_ready())
  488. return BT_STATUS_NOT_READY;
  489. cmd.value = volume;
  490. return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_VOLUME,
  491. sizeof(cmd), &cmd, NULL, NULL, NULL);
  492. }
  493. static void cleanup(void)
  494. {
  495. struct hal_cmd_unregister_module cmd;
  496. DBG("");
  497. if (!interface_ready())
  498. return;
  499. cmd.service_id = HAL_SERVICE_ID_AVRCP;
  500. hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
  501. sizeof(cmd), &cmd, NULL, NULL, NULL);
  502. hal_ipc_unregister(HAL_SERVICE_ID_AVRCP);
  503. cbs = NULL;
  504. }
  505. static btrc_interface_t iface = {
  506. .size = sizeof(iface),
  507. .init = init,
  508. .get_play_status_rsp = get_play_status_rsp,
  509. .list_player_app_attr_rsp = list_player_app_attr_rsp,
  510. .list_player_app_value_rsp = list_player_app_value_rsp,
  511. .get_player_app_value_rsp = get_player_app_value_rsp,
  512. .get_player_app_attr_text_rsp = get_player_app_attr_text_rsp,
  513. .get_player_app_value_text_rsp = get_player_app_value_text_rsp,
  514. .get_element_attr_rsp = get_element_attr_rsp,
  515. .set_player_app_value_rsp = set_player_app_value_rsp,
  516. .register_notification_rsp = register_notification_rsp,
  517. .set_volume = set_volume,
  518. .cleanup = cleanup
  519. };
  520. btrc_interface_t *bt_get_avrcp_interface(void)
  521. {
  522. return &iface;
  523. }