btsrv_pbap.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  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_pbap"
  11. #include "btsrv_os_common.h"
  12. #include "btsrv_inner.h"
  13. struct btsrv_pbap_priv {
  14. struct bt_conn *conn;
  15. uint8_t app_id; /* ID from bt manager */
  16. uint8_t user_id; /* ID from pbap client */
  17. char *path;
  18. uint8_t connected:1;
  19. btsrv_pbap_callback cb;
  20. };
  21. static struct btsrv_pbap_priv pbap_priv[CONFIG_MAX_PBAP_CONNECT];
  22. static void *btsrv_pbap_find_free_priv(void)
  23. {
  24. int i;
  25. for (i = 0; i < CONFIG_MAX_PBAP_CONNECT; i++) {
  26. if (pbap_priv[i].app_id == 0) {
  27. return &pbap_priv[i];
  28. }
  29. }
  30. return NULL;
  31. }
  32. static void btsrv_pbap_free_priv(struct btsrv_pbap_priv *info)
  33. {
  34. memset(info, 0, sizeof(struct btsrv_pbap_priv));
  35. }
  36. static void *btsrv_pbap_find_priv_by_app_id(uint8_t app_id)
  37. {
  38. int i;
  39. for (i = 0; i < CONFIG_MAX_PBAP_CONNECT; i++) {
  40. if (pbap_priv[i].app_id == app_id) {
  41. return &pbap_priv[i];
  42. }
  43. }
  44. return NULL;
  45. }
  46. static void *btsrv_pbap_find_priv_by_user_id(struct bt_conn *conn, uint8_t user_id)
  47. {
  48. int i;
  49. for (i = 0; i < CONFIG_MAX_PBAP_CONNECT; i++) {
  50. if (pbap_priv[i].user_id == user_id && pbap_priv[i].conn == conn) {
  51. return &pbap_priv[i];
  52. }
  53. }
  54. return NULL;
  55. }
  56. static void btsrv_pbap_connect_failed_cb(struct bt_conn *conn, uint8_t user_id)
  57. {
  58. btsrv_event_notify_ext(MSG_BTSRV_PBAP, MSG_BTSRV_PBAP_CONNECT_FAILED, conn, user_id);
  59. }
  60. static void btsrv_pbap_connected_cb(struct bt_conn *conn, uint8_t user_id)
  61. {
  62. btsrv_event_notify_ext(MSG_BTSRV_PBAP, MSG_BTSRV_PBAP_CONNECTED, conn, user_id);
  63. }
  64. void btsrv_pbap_disconnected_cb(struct bt_conn *conn, uint8_t user_id)
  65. {
  66. btsrv_event_notify_ext(MSG_BTSRV_PBAP, MSG_BTSRV_PBAP_DISCONNECTED, conn, user_id);
  67. }
  68. void btsrv_pbap_recv_cb(struct bt_conn *conn, uint8_t user_id, struct stack_pbap_cb_result *result)
  69. {
  70. /* Callback by hci_rx thread, in negative priority,
  71. * is better send message to bt service, process by btservice??
  72. */
  73. struct btsrv_pbap_priv *info = btsrv_pbap_find_priv_by_user_id(conn, user_id);
  74. if (!info || !result) {
  75. return;
  76. }
  77. switch (result->cb_event) {
  78. case STACK_PBAP_CB_EVENT_MAX_SIZE:
  79. info->cb(BTSRV_PBAP_MAX_SIZE, info->app_id, &result->max_size, sizeof(result->max_size));
  80. break;
  81. case STACK_PBAP_CB_EVENT_VCARD:
  82. info->cb(BTSRV_PBAP_VCARD_RESULT, info->app_id, result->vcard_result, result->array_size);
  83. break;
  84. case STACK_PBAP_CB_EVENT_SETPATH_FINISH:
  85. info->cb(BTSRV_PBAP_SETPATH_FINISH, info->app_id, NULL, 0);
  86. break;
  87. case STACK_PBAP_CB_EVENT_SEARCH_RESULT:
  88. info->cb(BTSRV_PBAP_SEARCH_RESULT, info->app_id, result->vcard_result, result->array_size);
  89. break;
  90. case STACK_PBAP_CB_EVENT_GET_VCARD_FINISH:
  91. info->cb(BTSRV_PBAP_GET_VCARD_FINISH, info->app_id, NULL, 0);
  92. break;
  93. case STACK_PBAP_CB_EVENT_END_OF_BODY:
  94. info->cb(BTSRV_PBAP_END_OF_BODY, info->app_id, NULL, 0);
  95. break;
  96. case STACK_PBAP_CB_EVENT_ABORT_FINISH:
  97. info->cb(BTSRV_PBAP_ABORT_FINISH, info->app_id, NULL, 0);
  98. break;
  99. default:
  100. break;
  101. }
  102. }
  103. static const struct bt_pbap_client_user_cb pbap_client_cb = {
  104. .connect_failed = btsrv_pbap_connect_failed_cb,
  105. .connected = btsrv_pbap_connected_cb,
  106. .disconnected = btsrv_pbap_disconnected_cb,
  107. .recv = btsrv_pbap_recv_cb,
  108. };
  109. static void btsrv_pbap_connect_failed(struct bt_conn *conn, uint8_t user_id)
  110. {
  111. struct btsrv_pbap_priv *info = btsrv_pbap_find_priv_by_user_id(conn, user_id);
  112. if (!info) {
  113. return;
  114. }
  115. info->cb(BTSRV_PBAP_CONNECT_FAILED, info->app_id, NULL, 0);
  116. btsrv_pbap_free_priv(info);
  117. }
  118. static void btsrv_pbap_connected(struct bt_conn *conn, uint8_t user_id)
  119. {
  120. struct btsrv_pbap_priv *info = btsrv_pbap_find_priv_by_user_id(conn, user_id);
  121. if (!info) {
  122. return;
  123. }
  124. if (info->connected) {
  125. SYS_LOG_INF("Already connected\n");
  126. return;
  127. }
  128. info->connected = 1;
  129. btsrv_event_notify(MSG_BTSRV_CONNECT, MSG_BTSRV_PBAP_CONNECTED, conn);
  130. info->cb(BTSRV_PBAP_CONNECTED, info->app_id, NULL, 0);
  131. }
  132. static void btsrv_pbap_disconnected(struct bt_conn *conn, uint8_t user_id)
  133. {
  134. struct btsrv_pbap_priv *info = btsrv_pbap_find_priv_by_user_id(conn, user_id);
  135. if (!info) {
  136. return;
  137. }
  138. if (!info->connected) {
  139. SYS_LOG_INF("Connect failed\n");
  140. }
  141. info->connected = 0;
  142. btsrv_event_notify(MSG_BTSRV_CONNECT, MSG_BTSRV_PBAP_DISCONNECTED, conn);
  143. info->cb(BTSRV_PBAP_DISCONNECTED, info->app_id, NULL, 0);
  144. btsrv_pbap_free_priv(info);
  145. }
  146. static void btsrv_pbap_op_connect(struct bt_pbap_op_param *param)
  147. {
  148. struct btsrv_pbap_priv *info = btsrv_pbap_find_free_priv();
  149. struct bt_conn *conn = btsrv_rdm_find_conn_by_addr(&param->bd);
  150. if (!info || !conn) {
  151. param->cb(BTSRV_PBAP_CONNECT_FAILED, param->app_id, NULL, 0);
  152. return;
  153. }
  154. info->conn = conn;
  155. info->app_id = param->app_id;
  156. info->cb = param->cb;
  157. info->user_id = hostif_bt_pbap_client_connect(info->conn, (struct bt_pbap_client_user_cb *)&pbap_client_cb);
  158. if (!info->user_id) {
  159. info->cb(BTSRV_PBAP_CONNECT_FAILED, param->app_id, NULL, 0);
  160. btsrv_pbap_free_priv(info);
  161. }
  162. }
  163. static void btsrv_pbap_op_disconnect(struct bt_pbap_op_param *param)
  164. {
  165. struct btsrv_pbap_priv *info = btsrv_pbap_find_priv_by_app_id(param->app_id);
  166. if (!info) {
  167. return;
  168. }
  169. hostif_bt_pbap_client_disconnect(info->conn, info->user_id);
  170. }
  171. static void btsrv_pbap_op_get_size(struct bt_pbap_op_param *param)
  172. {
  173. struct stack_pbap_op_param stack_param;
  174. struct btsrv_pbap_priv *info = btsrv_pbap_find_priv_by_app_id(param->app_id);
  175. if (!info) {
  176. return;
  177. }
  178. stack_param.op_cmd = STACK_PBAP_OP_CMD_GET_SIZE;
  179. stack_param.conn = info->conn;
  180. stack_param.user_id = info->user_id;
  181. stack_param.path = param->pb_path;
  182. hostif_bt_pbap_client_op(&stack_param);
  183. }
  184. static void btsrv_pbap_op_get_pb(struct bt_pbap_op_param *param)
  185. {
  186. struct stack_pbap_op_param stack_param;
  187. struct btsrv_pbap_priv *info = btsrv_pbap_find_priv_by_app_id(param->app_id);
  188. if (!info) {
  189. return;
  190. }
  191. stack_param.op_cmd = STACK_PBAP_OP_CMD_GET_PB;
  192. stack_param.conn = info->conn;
  193. stack_param.user_id = info->user_id;
  194. stack_param.path = param->pb_path;
  195. stack_param.filter = param->pb_filter;
  196. hostif_bt_pbap_client_op(&stack_param);
  197. }
  198. static void btsrv_pbap_op_set_path(struct bt_pbap_op_param *param)
  199. {
  200. struct stack_pbap_op_param stack_param;
  201. struct btsrv_pbap_priv *info = btsrv_pbap_find_priv_by_app_id(param->app_id);
  202. if (!info) {
  203. return;
  204. }
  205. stack_param.op_cmd = STACK_PBAP_OP_CMD_SET_PATH;
  206. stack_param.conn = info->conn;
  207. stack_param.user_id = info->user_id;
  208. stack_param.path = param->pb_path;
  209. hostif_bt_pbap_client_op(&stack_param);
  210. }
  211. static void btsrv_pbap_op_get_vcard(struct bt_pbap_op_param *param)
  212. {
  213. struct stack_pbap_op_param stack_param;
  214. struct btsrv_pbap_priv *info = btsrv_pbap_find_priv_by_app_id(param->app_id);
  215. if (!info) {
  216. return;
  217. }
  218. stack_param.op_cmd = STACK_PBAP_OP_CMD_GET_VCARD;
  219. stack_param.conn = info->conn;
  220. stack_param.user_id = info->user_id;
  221. stack_param.vcard_name_len = param->vcard_name_len;
  222. stack_param.filter = param->vc_filter;
  223. if (stack_param.vcard_name_len) {
  224. stack_param.vcard_name = param->vcard_name;
  225. } else {
  226. stack_param.vcard_name = NULL;
  227. }
  228. hostif_bt_pbap_client_op(&stack_param);
  229. }
  230. static void btsrv_pbap_op_get_continue(struct bt_pbap_op_param *param)
  231. {
  232. struct stack_pbap_op_param stack_param;
  233. struct btsrv_pbap_priv *info = btsrv_pbap_find_priv_by_app_id(param->app_id);
  234. if (!info) {
  235. return;
  236. }
  237. stack_param.op_cmd = STACK_PBAP_OP_CMD_GET_CONTINUE;
  238. stack_param.conn = info->conn;
  239. stack_param.user_id = info->user_id;
  240. hostif_bt_pbap_client_op(&stack_param);
  241. }
  242. static void btsrv_pbap_op_listing(struct bt_pbap_op_param *param)
  243. {
  244. struct stack_pbap_op_param stack_param;
  245. struct btsrv_pbap_priv *info = btsrv_pbap_find_priv_by_app_id(param->app_id);
  246. if (!info) {
  247. return;
  248. }
  249. stack_param.op_cmd = STACK_PBAP_OP_CMD_LISTING;
  250. stack_param.conn = info->conn;
  251. stack_param.user_id = info->user_id;
  252. stack_param.order = param->order;
  253. stack_param.search_attr = param->search_attr;
  254. stack_param.search_len = param->search_len;
  255. if (stack_param.search_len) {
  256. stack_param.search_value = param->search_value;
  257. } else {
  258. stack_param.search_value = NULL;
  259. }
  260. hostif_bt_pbap_client_op(&stack_param);
  261. }
  262. static void btsrv_pbap_op_abort(struct bt_pbap_op_param *param)
  263. {
  264. struct stack_pbap_op_param stack_param;
  265. struct btsrv_pbap_priv *info = btsrv_pbap_find_priv_by_app_id(param->app_id);
  266. if (!info) {
  267. return;
  268. }
  269. stack_param.op_cmd = STACK_PBAP_OP_CMD_ABORT;
  270. stack_param.conn = info->conn;
  271. stack_param.user_id = info->user_id;
  272. hostif_bt_pbap_client_op(&stack_param);
  273. }
  274. static void btsrv_pbap_cmd_op(struct bt_pbap_op_param *param)
  275. {
  276. SYS_LOG_INF("PBAP op %d", param->cmd);
  277. switch (param->cmd) {
  278. case BTSRV_PBAP_OP_CMD_CONNECT:
  279. btsrv_pbap_op_connect(param);
  280. break;
  281. case BTSRV_PBAP_OP_CMD_DISCONNECT:
  282. btsrv_pbap_op_disconnect(param);
  283. break;
  284. case BTSRV_PBAP_OP_CMD_GET_SIZE:
  285. btsrv_pbap_op_get_size(param);
  286. break;
  287. case BTSRV_PBAP_OP_CMD_GET_PB:
  288. btsrv_pbap_op_get_pb(param);
  289. break;
  290. case BTSRV_PBAP_OP_CMD_SET_PATH:
  291. btsrv_pbap_op_set_path(param);
  292. break;
  293. case BTSRV_PBAP_OP_CMD_GET_VCARD:
  294. btsrv_pbap_op_get_vcard(param);
  295. break;
  296. case BTSRV_PBAP_OP_CMD_GET_CONTINUE:
  297. btsrv_pbap_op_get_continue(param);
  298. break;
  299. case BTSRV_PBAP_OP_CMD_LISTING:
  300. btsrv_pbap_op_listing(param);
  301. break;
  302. case BTSRV_PBAP_OP_CMD_ABORT:
  303. btsrv_pbap_op_abort(param);
  304. break;
  305. default:
  306. break;
  307. }
  308. }
  309. int btsrv_pbap_process(struct app_msg *msg)
  310. {
  311. switch (_btsrv_get_msg_param_cmd(msg)) {
  312. case MSG_BTSRV_PBAP_CONNECT_FAILED:
  313. btsrv_pbap_connect_failed(_btsrv_get_msg_param_ptr(msg), _btsrv_get_msg_param_reserve(msg));
  314. break;
  315. case MSG_BTSRV_PBAP_CONNECTED:
  316. btsrv_pbap_connected(_btsrv_get_msg_param_ptr(msg), _btsrv_get_msg_param_reserve(msg));
  317. break;
  318. case MSG_BTSRV_PBAP_DISCONNECTED:
  319. btsrv_pbap_disconnected(_btsrv_get_msg_param_ptr(msg), _btsrv_get_msg_param_reserve(msg));
  320. break;
  321. case MSG_BTSRV_PBAP_CMD_OP:
  322. btsrv_pbap_cmd_op(msg->ptr);
  323. break;
  324. default:
  325. break;
  326. }
  327. return 0;
  328. }