esp_avrc_api.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. /*
  2. * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "common/bt_target.h"
  7. #include <string.h>
  8. #include "esp_err.h"
  9. #include "esp_avrc_api.h"
  10. #include "esp_bt_main.h"
  11. #include "btc/btc_manage.h"
  12. #include "btc_avrc.h"
  13. #if BTC_AV_INCLUDED
  14. esp_err_t esp_avrc_ct_register_callback(esp_avrc_ct_cb_t callback)
  15. {
  16. if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
  17. return ESP_ERR_INVALID_STATE;
  18. }
  19. if (callback == NULL) {
  20. return ESP_ERR_INVALID_ARG;
  21. }
  22. btc_profile_cb_set(BTC_PID_AVRC_CT, callback);
  23. return ESP_OK;
  24. }
  25. esp_err_t esp_avrc_ct_init(void)
  26. {
  27. if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
  28. return ESP_ERR_INVALID_STATE;
  29. }
  30. btc_msg_t msg;
  31. msg.sig = BTC_SIG_API_CALL;
  32. msg.pid = BTC_PID_AVRC_CT;
  33. msg.act = BTC_AVRC_CT_API_INIT_EVT;
  34. /* Switch to BTC context */
  35. bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL);
  36. return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
  37. }
  38. esp_err_t esp_avrc_ct_deinit(void)
  39. {
  40. if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
  41. return ESP_ERR_INVALID_STATE;
  42. }
  43. btc_msg_t msg;
  44. msg.sig = BTC_SIG_API_CALL;
  45. msg.pid = BTC_PID_AVRC_CT;
  46. msg.act = BTC_AVRC_CT_API_DEINIT_EVT;
  47. /* Switch to BTC context */
  48. bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL);
  49. return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
  50. }
  51. esp_err_t esp_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t attr_id, uint8_t value_id)
  52. {
  53. if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
  54. return ESP_ERR_INVALID_STATE;
  55. }
  56. if (tl > ESP_AVRC_TRANS_LABEL_MAX || attr_id > ESP_AVRC_PS_MAX_ATTR - 1) {
  57. return ESP_ERR_INVALID_ARG;
  58. }
  59. btc_msg_t msg;
  60. msg.sig = BTC_SIG_API_CALL;
  61. msg.pid = BTC_PID_AVRC_CT;
  62. msg.act = BTC_AVRC_CTRL_API_SND_SET_PLAYER_SETTING_EVT;
  63. btc_avrc_args_t arg;
  64. memset(&arg, 0, sizeof(btc_avrc_args_t));
  65. arg.ps_cmd.tl = tl;
  66. arg.ps_cmd.attr_id = attr_id;
  67. arg.ps_cmd.value_id = value_id;
  68. /* Switch to BTC context */
  69. bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL, NULL);
  70. return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
  71. }
  72. esp_err_t esp_avrc_ct_send_get_rn_capabilities_cmd(uint8_t tl)
  73. {
  74. if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
  75. return ESP_ERR_INVALID_STATE;
  76. }
  77. if (tl > ESP_AVRC_TRANS_LABEL_MAX) {
  78. return ESP_ERR_INVALID_ARG;
  79. }
  80. btc_msg_t msg;
  81. msg.sig = BTC_SIG_API_CALL;
  82. msg.pid = BTC_PID_AVRC_CT;
  83. msg.act = BTC_AVRC_STATUS_API_SND_GET_RN_CAPS_EVT;
  84. btc_avrc_args_t arg;
  85. memset(&arg, 0, sizeof(btc_avrc_args_t));
  86. arg.get_caps_cmd.tl = tl;
  87. /* Switch to BTC context */
  88. bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL, NULL);
  89. return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
  90. }
  91. esp_err_t esp_avrc_ct_send_register_notification_cmd(uint8_t tl, uint8_t event_id, uint32_t event_parameter)
  92. {
  93. if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
  94. return ESP_ERR_INVALID_STATE;
  95. }
  96. if (tl > ESP_AVRC_TRANS_LABEL_MAX || event_id > ESP_AVRC_RN_MAX_EVT - 1) {
  97. return ESP_ERR_INVALID_ARG;
  98. }
  99. if (!btc_avrc_ct_rn_evt_supported(event_id)) {
  100. return ESP_ERR_NOT_SUPPORTED;
  101. }
  102. btc_msg_t msg;
  103. msg.sig = BTC_SIG_API_CALL;
  104. msg.pid = BTC_PID_AVRC_CT;
  105. msg.act = BTC_AVRC_NOTIFY_API_SND_REG_NOTIFY_EVT;
  106. btc_avrc_args_t arg;
  107. memset(&arg, 0, sizeof(btc_avrc_args_t));
  108. arg.rn_cmd.tl = tl;
  109. arg.rn_cmd.event_id = event_id;
  110. arg.rn_cmd.event_parameter = event_parameter;
  111. /* Switch to BTC context */
  112. bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL, NULL);
  113. return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
  114. }
  115. esp_err_t esp_avrc_ct_send_set_absolute_volume_cmd(uint8_t tl, uint8_t volume)
  116. {
  117. if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
  118. return ESP_ERR_INVALID_STATE;
  119. }
  120. if (tl > ESP_AVRC_TRANS_LABEL_MAX) {
  121. return ESP_ERR_INVALID_ARG;
  122. }
  123. if (volume > BTC_AVRC_MAX_VOLUME) {
  124. return ESP_ERR_INVALID_ARG;
  125. }
  126. if (!btc_avrc_ct_rn_evt_supported(ESP_AVRC_RN_VOLUME_CHANGE)) {
  127. return ESP_ERR_NOT_SUPPORTED;
  128. }
  129. btc_msg_t msg;
  130. msg.sig = BTC_SIG_API_CALL;
  131. msg.pid = BTC_PID_AVRC_CT;
  132. msg.act = BTC_AVRC_CTRL_API_SND_SET_ABSOLUTE_VOLUME_EVT;
  133. btc_avrc_args_t arg;
  134. memset(&arg, 0, sizeof(btc_avrc_args_t));
  135. arg.set_abs_vol_cmd.tl = tl;
  136. arg.set_abs_vol_cmd.volume = volume;
  137. /* Switch to BTC context */
  138. bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL, NULL);
  139. return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
  140. }
  141. esp_err_t esp_avrc_ct_send_metadata_cmd(uint8_t tl, uint8_t attr_mask)
  142. {
  143. if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
  144. return ESP_ERR_INVALID_STATE;
  145. }
  146. if (tl > ESP_AVRC_TRANS_LABEL_MAX) {
  147. return ESP_ERR_INVALID_ARG;
  148. }
  149. btc_msg_t msg;
  150. msg.sig = BTC_SIG_API_CALL;
  151. msg.pid = BTC_PID_AVRC_CT;
  152. msg.act = BTC_AVRC_STATUS_API_SND_META_EVT;
  153. btc_avrc_args_t arg;
  154. memset(&arg, 0, sizeof(btc_avrc_args_t));
  155. arg.md_cmd.tl = tl;
  156. arg.md_cmd.attr_mask = attr_mask;
  157. /* Switch to BTC context */
  158. bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL, NULL);
  159. return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
  160. }
  161. esp_err_t esp_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t key_state)
  162. {
  163. if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
  164. return ESP_ERR_INVALID_STATE;
  165. }
  166. if (tl > ESP_AVRC_TRANS_LABEL_MAX || key_state > ESP_AVRC_PT_CMD_STATE_RELEASED) {
  167. return ESP_ERR_INVALID_ARG;
  168. }
  169. btc_msg_t msg;
  170. msg.sig = BTC_SIG_API_CALL;
  171. msg.pid = BTC_PID_AVRC_CT;
  172. msg.act = BTC_AVRC_CTRL_API_SND_PTCMD_EVT;
  173. btc_avrc_args_t arg;
  174. memset(&arg, 0, sizeof(btc_avrc_args_t));
  175. arg.pt_cmd.tl = tl;
  176. arg.pt_cmd.key_code = key_code;
  177. arg.pt_cmd.key_state = key_state;
  178. /* Switch to BTC context */
  179. bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL, NULL);
  180. return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
  181. }
  182. /*********************************************************************************************/
  183. /** following is the API of AVRCP target role **/
  184. /*********************************************************************************************/
  185. esp_err_t esp_avrc_tg_register_callback(esp_avrc_tg_cb_t callback)
  186. {
  187. if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
  188. return ESP_ERR_INVALID_STATE;
  189. }
  190. if (callback == NULL) {
  191. return ESP_ERR_INVALID_ARG;
  192. }
  193. btc_profile_cb_set(BTC_PID_AVRC_TG, callback);
  194. return ESP_OK;
  195. }
  196. esp_err_t esp_avrc_tg_init(void)
  197. {
  198. if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
  199. return ESP_ERR_INVALID_STATE;
  200. }
  201. btc_msg_t msg;
  202. msg.sig = BTC_SIG_API_CALL;
  203. msg.pid = BTC_PID_AVRC_TG;
  204. msg.act = BTC_AVRC_TG_API_INIT_EVT;
  205. /* Switch to BTC context */
  206. bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL);
  207. return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
  208. }
  209. esp_err_t esp_avrc_tg_deinit(void)
  210. {
  211. if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
  212. return ESP_ERR_INVALID_STATE;
  213. }
  214. btc_msg_t msg;
  215. msg.sig = BTC_SIG_API_CALL;
  216. msg.pid = BTC_PID_AVRC_TG;
  217. msg.act = BTC_AVRC_TG_API_DEINIT_EVT;
  218. /* Switch to BTC context */
  219. bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL);
  220. return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
  221. }
  222. bool esp_avrc_psth_bit_mask_operation(esp_avrc_bit_mask_op_t op, esp_avrc_psth_bit_mask_t *psth,
  223. esp_avrc_pt_cmd_t cmd)
  224. {
  225. if (!psth ||
  226. cmd > ESP_AVRC_PT_CMD_VENDOR) {
  227. return false;
  228. }
  229. uint16_t *p = &psth->bits[(uint8_t)cmd >> 4];
  230. uint16_t mask = (uint16_t)1 << ((uint8_t)cmd & 0x0F);
  231. switch (op) {
  232. case ESP_AVRC_BIT_MASK_OP_SET:
  233. *p |= mask;
  234. break;
  235. case ESP_AVRC_BIT_MASK_OP_CLEAR:
  236. *p &= ~mask;
  237. break;
  238. case ESP_AVRC_BIT_MASK_OP_TEST:
  239. return (*p & mask);
  240. default:
  241. return false;
  242. }
  243. return true;
  244. }
  245. esp_err_t esp_avrc_tg_get_psth_cmd_filter(esp_avrc_psth_filter_t filter, esp_avrc_psth_bit_mask_t *cmd_set)
  246. {
  247. if ((esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) ||
  248. (! btc_avrc_tg_init_p())) {
  249. return ESP_ERR_INVALID_STATE;
  250. }
  251. if (filter >= ESP_AVRC_PSTH_FILTER_SUPPORT_MAX ||
  252. cmd_set == NULL) {
  253. return ESP_ERR_INVALID_ARG;
  254. }
  255. if (filter == ESP_AVRC_PSTH_FILTER_ALLOWED_CMD) {
  256. const uint16_t *allowed_cmd_set = btc_avrc_tg_get_allowed_command();
  257. memcpy(cmd_set, allowed_cmd_set, sizeof(esp_avrc_psth_bit_mask_t));
  258. } else if (filter == ESP_AVRC_PSTH_FILTER_SUPPORTED_CMD) {
  259. const uint16_t *supported_cmd_set = btc_avrc_tg_get_supported_command();
  260. memcpy(cmd_set, supported_cmd_set, sizeof(esp_avrc_psth_bit_mask_t));
  261. } else {
  262. }
  263. return ESP_OK;
  264. }
  265. esp_err_t esp_avrc_tg_set_psth_cmd_filter(esp_avrc_psth_filter_t filter, const esp_avrc_psth_bit_mask_t *cmd_set)
  266. {
  267. if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
  268. return ESP_ERR_INVALID_STATE;
  269. }
  270. if (filter >= ESP_AVRC_PSTH_FILTER_SUPPORT_MAX ||
  271. cmd_set == NULL) {
  272. return ESP_ERR_INVALID_ARG;
  273. }
  274. if (filter == ESP_AVRC_PSTH_FILTER_ALLOWED_CMD) {
  275. return ESP_ERR_NOT_SUPPORTED;
  276. }
  277. if (filter == ESP_AVRC_PSTH_FILTER_SUPPORTED_CMD) {
  278. bool allowed = btc_avrc_tg_check_supported_command(cmd_set->bits);
  279. if (!allowed) {
  280. return ESP_ERR_NOT_SUPPORTED;
  281. }
  282. btc_msg_t msg;
  283. msg.sig = BTC_SIG_API_CALL;
  284. msg.pid = BTC_PID_AVRC_TG;
  285. msg.act = BTC_AVRC_TG_API_SET_PSTH_SUPPORTED_CMD_EVT;
  286. btc_avrc_tg_args_t arg;
  287. memset(&arg, 0, sizeof(btc_avrc_tg_args_t));
  288. arg.set_psth_cmd = (uint16_t *)cmd_set->bits;
  289. /* Switch to BTC context */
  290. bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_tg_args_t),
  291. btc_avrc_tg_arg_deep_copy, btc_avrc_tg_arg_deep_free);
  292. return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
  293. } else {
  294. return ESP_FAIL;
  295. }
  296. }
  297. esp_err_t esp_avrc_tg_get_rn_evt_cap(esp_avrc_rn_evt_cap_t cap, esp_avrc_rn_evt_cap_mask_t *evt_set)
  298. {
  299. if ((esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) ||
  300. (! btc_avrc_tg_init_p())) {
  301. return ESP_ERR_INVALID_STATE;
  302. }
  303. if (cap >= ESP_AVRC_RN_CAP_MAX ||
  304. evt_set == NULL) {
  305. return ESP_ERR_INVALID_ARG;
  306. }
  307. if (cap == ESP_AVRC_RN_CAP_ALLOWED_EVT) {
  308. evt_set->bits = btc_avrc_tg_get_rn_allowed_evt();
  309. } else if (cap == ESP_AVRC_RN_CAP_SUPPORTED_EVT) {
  310. evt_set->bits = btc_avrc_tg_get_rn_supported_evt();
  311. } else {
  312. }
  313. return ESP_OK;
  314. }
  315. esp_err_t esp_avrc_tg_set_rn_evt_cap(const esp_avrc_rn_evt_cap_mask_t *evt_set)
  316. {
  317. if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
  318. return ESP_ERR_INVALID_STATE;
  319. }
  320. if (evt_set == NULL) {
  321. return ESP_ERR_INVALID_ARG;
  322. }
  323. bool allowed = btc_avrc_tg_check_rn_supported_evt(evt_set->bits);
  324. if (!allowed) {
  325. return ESP_ERR_NOT_SUPPORTED;
  326. }
  327. btc_msg_t msg;
  328. msg.sig = BTC_SIG_API_CALL;
  329. msg.pid = BTC_PID_AVRC_TG;
  330. msg.act = BTC_AVRC_TG_API_SET_RN_SUPPORTED_EVT;
  331. btc_avrc_tg_args_t arg;
  332. memset(&arg, 0, sizeof(btc_avrc_tg_args_t));
  333. arg.set_rn_evt = evt_set->bits;
  334. /* Switch to BTC context */
  335. bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_tg_args_t), NULL, NULL);
  336. return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
  337. }
  338. bool esp_avrc_rn_evt_bit_mask_operation(esp_avrc_bit_mask_op_t op, esp_avrc_rn_evt_cap_mask_t *events,
  339. esp_avrc_rn_event_ids_t event_id)
  340. {
  341. if (!events ||
  342. event_id >= ESP_AVRC_RN_MAX_EVT) {
  343. return false;
  344. }
  345. uint16_t *p = &events->bits;
  346. uint16_t mask = (uint16_t)1 << ((uint8_t)event_id & 0x0F);
  347. switch (op) {
  348. case ESP_AVRC_BIT_MASK_OP_SET:
  349. *p |= mask;
  350. break;
  351. case ESP_AVRC_BIT_MASK_OP_CLEAR:
  352. *p &= ~mask;
  353. break;
  354. case ESP_AVRC_BIT_MASK_OP_TEST:
  355. return (*p & mask);
  356. default:
  357. return false;
  358. }
  359. return true;
  360. }
  361. esp_err_t esp_avrc_tg_send_rn_rsp(esp_avrc_rn_event_ids_t event_id, esp_avrc_rn_rsp_t rsp,
  362. esp_avrc_rn_param_t *param)
  363. {
  364. if ((esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) ||
  365. (! btc_avrc_tg_connected_p())) {
  366. return ESP_ERR_INVALID_STATE;
  367. }
  368. if ( ! btc_avrc_tg_rn_evt_supported((uint8_t)event_id)) {
  369. return ESP_ERR_NOT_SUPPORTED;
  370. }
  371. btc_msg_t msg;
  372. msg.sig = BTC_SIG_API_CALL;
  373. msg.pid = BTC_PID_AVRC_TG;
  374. msg.act = BTC_AVRC_TG_API_SEND_RN_RSP_EVT;
  375. btc_avrc_tg_args_t arg;
  376. memset(&arg, 0, sizeof(btc_avrc_tg_args_t));
  377. arg.rn_rsp.event_id = event_id;
  378. arg.rn_rsp.rsp = rsp;
  379. memcpy(&arg.rn_rsp.param, param, sizeof(esp_avrc_rn_param_t));
  380. /* Switch to BTC context */
  381. bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_tg_args_t), NULL, NULL);
  382. return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
  383. }
  384. #endif /* #if BTC_AV_INCLUDED */