btsrv_map.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /*
  2. * Copyright (c) 2017 Actions Semi Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file
  8. * @brief btsrvice pbap
  9. */
  10. #define SYS_LOG_DOMAIN "btsrv_map"
  11. #include "btsrv_os_common.h"
  12. #include "btsrv_inner.h"
  13. struct btsrv_map_priv {
  14. struct bt_conn *conn;
  15. uint8_t app_id; /* ID from bt manager */
  16. uint8_t user_id; /* ID from map client */
  17. uint8_t folder_flags;
  18. uint16_t max_list_count;
  19. uint32_t parameter_mask;
  20. char *path;
  21. uint8_t connected:1;
  22. btsrv_map_callback cb;
  23. };
  24. static struct btsrv_map_priv map_priv[CONFIG_MAX_MAP_CONNECT];
  25. static void *btsrv_map_find_free_priv(void)
  26. {
  27. uint8_t i;
  28. for (i = 0; i < CONFIG_MAX_MAP_CONNECT; i++) {
  29. if (map_priv[i].app_id == 0) {
  30. return &map_priv[i];
  31. }
  32. }
  33. return NULL;
  34. }
  35. static void btsrv_map_free_priv(struct btsrv_map_priv *info)
  36. {
  37. memset(info, 0, sizeof(struct btsrv_map_priv));
  38. }
  39. static void *btsrv_map_find_priv_by_app_id(uint8_t app_id)
  40. {
  41. uint8_t i;
  42. for (i = 0; i < CONFIG_MAX_MAP_CONNECT; i++) {
  43. if (map_priv[i].app_id == app_id) {
  44. return &map_priv[i];
  45. }
  46. }
  47. return NULL;
  48. }
  49. static void *btsrv_map_find_priv_by_user_id(struct bt_conn *conn, uint8_t user_id)
  50. {
  51. uint8_t i;
  52. for (i = 0; i < CONFIG_MAX_MAP_CONNECT; i++) {
  53. if (map_priv[i].user_id == user_id && map_priv[i].conn == conn) {
  54. return &map_priv[i];
  55. }
  56. }
  57. return NULL;
  58. }
  59. static void btsrv_map_connect_failed_cb(struct bt_conn *conn, uint8_t user_id)
  60. {
  61. btsrv_event_notify_ext(MSG_BTSRV_MAP, MSG_BTSRV_MAP_CONNECT_FAILED, conn, user_id);
  62. }
  63. static void btsrv_map_connected_cb(struct bt_conn *conn, uint8_t user_id)
  64. {
  65. btsrv_event_notify_ext(MSG_BTSRV_MAP, MSG_BTSRV_MAP_CONNECTED, conn, user_id);
  66. }
  67. void btsrv_map_disconnected_cb(struct bt_conn *conn, uint8_t user_id)
  68. {
  69. btsrv_event_notify_ext(MSG_BTSRV_MAP, MSG_BTSRV_MAP_DISCONNECTED, conn, user_id);
  70. }
  71. static void btsrv_map_set_path_finised_cb(struct bt_conn *conn, uint8_t user_id)
  72. {
  73. struct btsrv_map_priv *info = btsrv_map_find_priv_by_user_id(conn, user_id);
  74. if (!info || !info->cb) {
  75. return;
  76. }
  77. info->cb(BTSRV_MAP_SET_PATH_FINISHED, info->app_id, NULL, 0);
  78. }
  79. void btsrv_map_recv_cb(struct bt_conn *conn, uint8_t user_id, struct parse_messages_result *result, uint8_t array_size)
  80. {
  81. /* Callback by hci_rx thread, in negative priority,
  82. * is better send message to bt service, process by btservice??
  83. */
  84. struct btsrv_map_priv *info = btsrv_map_find_priv_by_user_id(conn, user_id);
  85. if (!info) {
  86. return;
  87. }
  88. info->cb(BTSRV_MAP_MESSAGES_RESULT, info->app_id, result, array_size);
  89. }
  90. static const struct bt_map_client_user_cb map_client_cb = {
  91. .connect_failed = btsrv_map_connect_failed_cb,
  92. .connected = btsrv_map_connected_cb,
  93. .disconnected = btsrv_map_disconnected_cb,
  94. .set_path_finished = btsrv_map_set_path_finised_cb,
  95. .recv = btsrv_map_recv_cb,
  96. };
  97. static void btsrv_map_connect_server(struct bt_map_connect_param *param)
  98. {
  99. struct btsrv_map_priv *info = btsrv_map_find_free_priv();
  100. struct bt_conn *conn = btsrv_rdm_find_conn_by_addr(&param->bd);
  101. if (!info || !conn) {
  102. param->cb(BTSRV_MAP_CONNECT_FAILED, param->app_id, NULL, 0);
  103. return;
  104. }
  105. info->conn = conn;
  106. info->app_id = param->app_id;
  107. info->path = param->map_path;
  108. info->cb = param->cb;
  109. info->user_id = hostif_bt_map_client_connect(info->conn,info->path,
  110. (struct bt_map_client_user_cb *)&map_client_cb);
  111. if (!info->user_id) {
  112. info->cb(BTSRV_MAP_CONNECT_FAILED, param->app_id, NULL, 0);
  113. btsrv_map_free_priv(info);
  114. }
  115. }
  116. static void btsrv_map_get_message(struct bt_map_get_param *param)
  117. {
  118. struct btsrv_map_priv *info = btsrv_map_find_free_priv();
  119. struct bt_conn *conn = btsrv_rdm_find_conn_by_addr(&param->bd);
  120. if (!info || !conn) {
  121. param->cb(BTSRV_MAP_CONNECT_FAILED, param->app_id, NULL, 0);
  122. return;
  123. }
  124. info->conn = conn;
  125. info->app_id = param->app_id;
  126. info->path = param->map_path;
  127. info->cb = param->cb;
  128. info->user_id = hostif_bt_map_client_get_message(info->conn, info->path,
  129. (struct bt_map_client_user_cb *)&map_client_cb);
  130. if (!info->user_id) {
  131. info->cb(BTSRV_MAP_CONNECT_FAILED, param->app_id, NULL, 0);
  132. btsrv_map_free_priv(info);
  133. }
  134. }
  135. static void btsrv_map_abort_get(uint8_t app_id)
  136. {
  137. struct btsrv_map_priv *info = btsrv_map_find_priv_by_app_id(app_id);
  138. if (!info) {
  139. return;
  140. }
  141. hostif_bt_map_client_abort_get(info->conn, info->user_id);
  142. }
  143. static void btsrv_map_client_disconnect(uint8_t app_id)
  144. {
  145. struct btsrv_map_priv *info = btsrv_map_find_priv_by_app_id(app_id);
  146. if (!info) {
  147. return;
  148. }
  149. hostif_bt_map_client_disconnect(info->conn, info->user_id);
  150. }
  151. static void btsrv_map_client_set_folder(struct bt_map_set_folder_param *param)
  152. {
  153. struct btsrv_map_priv *info = btsrv_map_find_priv_by_app_id(param->app_id);
  154. if (!info) {
  155. return;
  156. }
  157. if (!info->connected) {
  158. return;
  159. }
  160. info->path = param->map_path;
  161. info->folder_flags = param->flags;
  162. hostif_bt_map_client_set_folder(info->conn,info->user_id,info->path,info->folder_flags);
  163. }
  164. static void btsrv_map_client_get_folder_listing(uint8_t app_id)
  165. {
  166. struct btsrv_map_priv *info = btsrv_map_find_priv_by_app_id(app_id);
  167. if (!info) {
  168. return;
  169. }
  170. if (!info->connected) {
  171. return;
  172. }
  173. hostif_bt_map_client_get_folder_listing(info->conn,info->user_id);
  174. }
  175. static void btsrv_map_client_get_messages_listing(struct bt_map_get_messages_listing_param * param)
  176. {
  177. struct btsrv_map_priv *info = btsrv_map_find_priv_by_app_id(param->app_id);
  178. if (!info) {
  179. return;
  180. }
  181. if (!info->connected) {
  182. return;
  183. }
  184. info->max_list_count = param->max_list_count;
  185. info->parameter_mask = param->parameter_mask;
  186. hostif_bt_map_client_get_messages_listing(info->conn,info->user_id,info->max_list_count,info->parameter_mask);
  187. }
  188. static void btsrv_map_connect_failed(struct bt_conn *conn, uint8_t user_id)
  189. {
  190. struct btsrv_map_priv *info = btsrv_map_find_priv_by_user_id(conn, user_id);
  191. if (!info) {
  192. return;
  193. }
  194. info->cb(BTSRV_MAP_CONNECT_FAILED, info->app_id, NULL, 0);
  195. btsrv_map_free_priv(info);
  196. }
  197. static void btsrv_map_connected(struct bt_conn *conn, uint8_t user_id)
  198. {
  199. struct btsrv_map_priv *info = btsrv_map_find_priv_by_user_id(conn, user_id);
  200. if (!info) {
  201. return;
  202. }
  203. if (info->connected) {
  204. SYS_LOG_INF("Already connected\n");
  205. return;
  206. }
  207. info->connected = 1;
  208. btsrv_event_notify(MSG_BTSRV_CONNECT, MSG_BTSRV_MAP_CONNECTED, conn);
  209. info->cb(BTSRV_MAP_CONNECTED, info->app_id, NULL, 0);
  210. }
  211. static void btsrv_map_disconnected(struct bt_conn *conn, uint8_t user_id)
  212. {
  213. struct btsrv_map_priv *info = btsrv_map_find_priv_by_user_id(conn, user_id);
  214. if (!info) {
  215. return;
  216. }
  217. info->connected = 0;
  218. btsrv_event_notify(MSG_BTSRV_CONNECT, MSG_BTSRV_MAP_DISCONNECTED, conn);
  219. info->cb(BTSRV_MAP_DISCONNECTED, info->app_id, NULL, 0);
  220. btsrv_map_free_priv(info);
  221. }
  222. int btsrv_map_process(struct app_msg *msg)
  223. {
  224. switch (_btsrv_get_msg_param_cmd(msg)) {
  225. case MSG_BTSRV_MAP_CONNECT:
  226. btsrv_map_connect_server(msg->ptr);
  227. break;
  228. case MSG_BTSRV_MAP_SET_FOLDER:
  229. btsrv_map_client_set_folder(msg->ptr);
  230. break;
  231. case MSG_BTSRV_MAP_GET_FOLDERLISTING:
  232. btsrv_map_client_get_folder_listing((uint8_t)_btsrv_get_msg_param_value(msg));
  233. break;
  234. case MSG_BTSRV_MAP_GET_MESSAGESLISTING:
  235. btsrv_map_client_get_messages_listing(msg->ptr);
  236. break;
  237. case MSG_BTSRV_MAP_GET_MESSAGE:
  238. btsrv_map_get_message(msg->ptr);
  239. break;
  240. case MSG_BTSRV_MAP_ABORT_GET:
  241. btsrv_map_abort_get((uint8_t)_btsrv_get_msg_param_value(msg));
  242. break;
  243. case MSG_BTSRV_MAP_DISCONNECT:
  244. btsrv_map_client_disconnect((uint8_t)_btsrv_get_msg_param_value(msg));
  245. break;
  246. case MSG_BTSRV_MAP_CONNECT_FAILED:
  247. btsrv_map_connect_failed(_btsrv_get_msg_param_ptr(msg), _btsrv_get_msg_param_reserve(msg));
  248. break;
  249. case MSG_BTSRV_MAP_CONNECTED:
  250. btsrv_map_connected(_btsrv_get_msg_param_ptr(msg), _btsrv_get_msg_param_reserve(msg));
  251. break;
  252. case MSG_BTSRV_MAP_DISCONNECTED:
  253. btsrv_map_disconnected(_btsrv_get_msg_param_ptr(msg), _btsrv_get_msg_param_reserve(msg));
  254. break;
  255. default:
  256. break;
  257. }
  258. return 0;
  259. }