l2cap_client.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2014 Google, Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at:
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. ******************************************************************************/
  18. #if (defined(L2CAP_CLIENT_INCLUDED) && L2CAP_CLIENT_INCLUDED == TRUE)
  19. #include <string.h>
  20. #include "bt_trace.h"
  21. #include "bt_defs.h"
  22. #include "bdaddr.h"
  23. #include "gki.h"
  24. #include "allocator.h"
  25. #include "buffer.h"
  26. #include "list.h"
  27. #include "osi.h"
  28. #include "l2cap_client.h"
  29. #include "l2c_api.h"
  30. struct l2cap_client_t {
  31. l2cap_client_callbacks_t callbacks;
  32. void *context;
  33. uint16_t local_channel_id;
  34. uint16_t remote_mtu;
  35. bool configured_self;
  36. bool configured_peer;
  37. bool is_congested;
  38. list_t *outbound_fragments;
  39. };
  40. static void connect_completed_cb(uint16_t local_channel_id, uint16_t error_code);
  41. static void config_request_cb(uint16_t local_channel_id, tL2CAP_CFG_INFO *requested_parameters);
  42. static void config_completed_cb(uint16_t local_channel_id, tL2CAP_CFG_INFO *negotiated_parameters);
  43. static void disconnect_request_cb(uint16_t local_channel_id, bool ack_required);
  44. static void disconnect_completed_cb(uint16_t local_channel_id, uint16_t error_code);
  45. static void congestion_cb(uint16_t local_channel_id, bool is_congested);
  46. static void read_ready_cb(uint16_t local_channel_id, BT_HDR *packet);
  47. static void write_completed_cb(uint16_t local_channel_id, uint16_t packets_completed);
  48. static void fragment_packet(l2cap_client_t *client, buffer_t *packet);
  49. static void dispatch_fragments(l2cap_client_t *client);
  50. static l2cap_client_t *find(uint16_t local_channel_id);
  51. // From the Bluetooth Core specification.
  52. static const uint16_t L2CAP_MTU_DEFAULT = 672;
  53. static const uint16_t L2CAP_MTU_MINIMUM = 48;
  54. static const tL2CAP_APPL_INFO l2cap_callbacks = {
  55. .pL2CA_ConnectCfm_Cb = connect_completed_cb,
  56. .pL2CA_ConfigInd_Cb = config_request_cb,
  57. .pL2CA_ConfigCfm_Cb = config_completed_cb,
  58. .pL2CA_DisconnectInd_Cb = disconnect_request_cb,
  59. .pL2CA_DisconnectCfm_Cb = disconnect_completed_cb,
  60. .pL2CA_CongestionStatus_Cb = congestion_cb,
  61. .pL2CA_DataInd_Cb = read_ready_cb,
  62. .pL2CA_TxComplete_Cb = write_completed_cb,
  63. };
  64. static list_t *l2cap_clients; // A list of l2cap_client_t. Container does not own objects.
  65. buffer_t *l2cap_buffer_new(size_t size)
  66. {
  67. buffer_t *buf = buffer_new(size + L2CAP_MIN_OFFSET);
  68. buffer_t *slice = NULL;
  69. if (buf) {
  70. slice = buffer_new_slice(buf, size);
  71. }
  72. buffer_free(buf);
  73. return slice;
  74. }
  75. l2cap_client_t *l2cap_client_new(const l2cap_client_callbacks_t *callbacks, void *context)
  76. {
  77. assert(callbacks != NULL);
  78. assert(callbacks->connected != NULL);
  79. assert(callbacks->disconnected != NULL);
  80. assert(callbacks->read_ready != NULL);
  81. assert(callbacks->write_ready != NULL);
  82. if (!l2cap_clients) {
  83. l2cap_clients = list_new(NULL);
  84. if (!l2cap_clients) {
  85. LOG_ERROR("%s unable to allocate space for L2CAP client list.", __func__);
  86. return NULL;
  87. }
  88. }
  89. l2cap_client_t *ret = (l2cap_client_t *)osi_calloc(sizeof(l2cap_client_t));
  90. if (!ret) {
  91. LOG_ERROR("%s unable to allocate L2CAP client.", __func__);
  92. goto error;
  93. }
  94. ret->callbacks = *callbacks;
  95. ret->context = context;
  96. ret->remote_mtu = L2CAP_MTU_DEFAULT;
  97. ret->outbound_fragments = list_new(NULL);
  98. if (!ret) {
  99. LOG_ERROR("%s unable to allocate outbound L2CAP fragment list.", __func__);
  100. goto error;
  101. }
  102. list_append(l2cap_clients, ret);
  103. return ret;
  104. error:;
  105. osi_free(ret);
  106. return NULL;
  107. }
  108. void l2cap_client_free(l2cap_client_t *client)
  109. {
  110. if (!client) {
  111. return;
  112. }
  113. list_remove(l2cap_clients, client);
  114. l2cap_client_disconnect(client);
  115. list_free(client->outbound_fragments);
  116. osi_free(client);
  117. }
  118. bool l2cap_client_connect(l2cap_client_t *client, const bt_bdaddr_t *remote_bdaddr, uint16_t psm)
  119. {
  120. assert(client != NULL);
  121. assert(remote_bdaddr != NULL);
  122. assert(psm != 0);
  123. assert(!bdaddr_is_empty(remote_bdaddr));
  124. assert(client->local_channel_id == 0);
  125. assert(!client->configured_self);
  126. assert(!client->configured_peer);
  127. assert(!L2C_INVALID_PSM(psm));
  128. client->local_channel_id = L2CA_ConnectReq(psm, (uint8_t *)remote_bdaddr);
  129. if (!client->local_channel_id) {
  130. LOG_ERROR("%s unable to create L2CAP connection.", __func__);
  131. return false;
  132. }
  133. L2CA_SetConnectionCallbacks(client->local_channel_id, &l2cap_callbacks);
  134. return true;
  135. }
  136. void l2cap_client_disconnect(l2cap_client_t *client)
  137. {
  138. assert(client != NULL);
  139. if (client->local_channel_id && !L2CA_DisconnectReq(client->local_channel_id)) {
  140. LOG_ERROR("%s unable to send disconnect message for LCID 0x%04x.", __func__, client->local_channel_id);
  141. }
  142. client->local_channel_id = 0;
  143. client->remote_mtu = L2CAP_MTU_DEFAULT;
  144. client->configured_self = false;
  145. client->configured_peer = false;
  146. client->is_congested = false;
  147. for (const list_node_t *node = list_begin(client->outbound_fragments); node != list_end(client->outbound_fragments); node = list_next(node)) {
  148. GKI_freebuf(list_node(node));
  149. }
  150. list_clear(client->outbound_fragments);
  151. }
  152. bool l2cap_client_is_connected(const l2cap_client_t *client)
  153. {
  154. assert(client != NULL);
  155. return client->local_channel_id != 0 && client->configured_self && client->configured_peer;
  156. }
  157. bool l2cap_client_write(l2cap_client_t *client, buffer_t *packet)
  158. {
  159. assert(client != NULL);
  160. assert(packet != NULL);
  161. assert(l2cap_client_is_connected(client));
  162. if (client->is_congested) {
  163. return false;
  164. }
  165. fragment_packet(client, packet);
  166. dispatch_fragments(client);
  167. return true;
  168. }
  169. static void connect_completed_cb(uint16_t local_channel_id, uint16_t error_code)
  170. {
  171. assert(local_channel_id != 0);
  172. l2cap_client_t *client = find(local_channel_id);
  173. if (!client) {
  174. LOG_ERROR("%s unable to find L2CAP client for LCID 0x%04x.", __func__, local_channel_id);
  175. return;
  176. }
  177. if (error_code != L2CAP_CONN_OK) {
  178. LOG_ERROR("%s error connecting L2CAP channel: %d.", __func__, error_code);
  179. client->callbacks.disconnected(client, client->context);
  180. return;
  181. }
  182. // Use default L2CAP parameters.
  183. tL2CAP_CFG_INFO desired_parameters = { 0 };
  184. if (!L2CA_ConfigReq(local_channel_id, &desired_parameters)) {
  185. LOG_ERROR("%s error sending L2CAP config parameters.", __func__);
  186. client->callbacks.disconnected(client, client->context);
  187. }
  188. }
  189. static void config_request_cb(uint16_t local_channel_id, tL2CAP_CFG_INFO *requested_parameters)
  190. {
  191. tL2CAP_CFG_INFO response = { 0 };
  192. l2cap_client_t *client = find(local_channel_id);
  193. if (!client) {
  194. LOG_ERROR("%s unable to find L2CAP client matching LCID 0x%04x.", __func__, local_channel_id);
  195. return;
  196. }
  197. response.result = L2CAP_CFG_OK;
  198. if (requested_parameters->mtu_present) {
  199. // Make sure the peer chose an MTU at least as large as the minimum L2CAP MTU defined
  200. // by the Bluetooth Core spec.
  201. if (requested_parameters->mtu < L2CAP_MTU_MINIMUM) {
  202. response.mtu = L2CAP_MTU_MINIMUM;
  203. response.mtu_present = true;
  204. response.result = L2CAP_CFG_UNACCEPTABLE_PARAMS;
  205. } else {
  206. client->remote_mtu = requested_parameters->mtu;
  207. }
  208. }
  209. if (requested_parameters->fcr_present) {
  210. if (requested_parameters->fcr.mode != L2CAP_FCR_BASIC_MODE) {
  211. response.fcr_present = true;
  212. response.fcr = requested_parameters->fcr;
  213. response.fcr.mode = L2CAP_FCR_BASIC_MODE;
  214. response.result = L2CAP_CFG_UNACCEPTABLE_PARAMS;
  215. }
  216. }
  217. if (!L2CA_ConfigRsp(local_channel_id, &response)) {
  218. LOG_ERROR("%s unable to send config response for LCID 0x%04x.", __func__, local_channel_id);
  219. l2cap_client_disconnect(client);
  220. return;
  221. }
  222. // If we've configured both endpoints, let the listener know we've connected.
  223. client->configured_peer = true;
  224. if (l2cap_client_is_connected(client)) {
  225. client->callbacks.connected(client, client->context);
  226. }
  227. }
  228. static void config_completed_cb(uint16_t local_channel_id, tL2CAP_CFG_INFO *negotiated_parameters)
  229. {
  230. l2cap_client_t *client = find(local_channel_id);
  231. if (!client) {
  232. LOG_ERROR("%s unable to find L2CAP client matching LCID 0x%04x.", __func__, local_channel_id);
  233. return;
  234. }
  235. switch (negotiated_parameters->result) {
  236. // We'll get another configuration response later.
  237. case L2CAP_CFG_PENDING:
  238. break;
  239. case L2CAP_CFG_UNACCEPTABLE_PARAMS:
  240. // TODO: see if we can renegotiate parameters instead of dropping the connection.
  241. LOG_WARN("%s dropping L2CAP connection due to unacceptable config parameters.\n", __func__);
  242. l2cap_client_disconnect(client);
  243. break;
  244. case L2CAP_CFG_OK:
  245. // If we've configured both endpoints, let the listener know we've connected.
  246. client->configured_self = true;
  247. if (l2cap_client_is_connected(client)) {
  248. client->callbacks.connected(client, client->context);
  249. }
  250. break;
  251. // Failure, no further parameter negotiation possible.
  252. default:
  253. LOG_WARN("%s L2CAP parameter negotiation failed with error code %d.\n", __func__, negotiated_parameters->result);
  254. l2cap_client_disconnect(client);
  255. break;
  256. }
  257. }
  258. static void disconnect_request_cb(uint16_t local_channel_id, bool ack_required)
  259. {
  260. l2cap_client_t *client = find(local_channel_id);
  261. if (!client) {
  262. LOG_ERROR("%s unable to find L2CAP client with LCID 0x%04x.\n", __func__, local_channel_id);
  263. return;
  264. }
  265. if (ack_required) {
  266. L2CA_DisconnectRsp(local_channel_id);
  267. }
  268. // We already sent a disconnect response so this LCID is now invalid.
  269. client->local_channel_id = 0;
  270. l2cap_client_disconnect(client);
  271. client->callbacks.disconnected(client, client->context);
  272. }
  273. static void disconnect_completed_cb(uint16_t local_channel_id, UNUSED_ATTR uint16_t error_code)
  274. {
  275. assert(local_channel_id != 0);
  276. l2cap_client_t *client = find(local_channel_id);
  277. if (!client) {
  278. LOG_ERROR("%s unable to find L2CAP client with LCID 0x%04x.\n", __func__, local_channel_id);
  279. return;
  280. }
  281. client->local_channel_id = 0;
  282. l2cap_client_disconnect(client);
  283. client->callbacks.disconnected(client, client->context);
  284. }
  285. static void congestion_cb(uint16_t local_channel_id, bool is_congested)
  286. {
  287. assert(local_channel_id != 0);
  288. l2cap_client_t *client = find(local_channel_id);
  289. if (!client) {
  290. LOG_ERROR("%s unable to find L2CAP client matching LCID 0x%04x.\n", __func__, local_channel_id);
  291. return;
  292. }
  293. client->is_congested = is_congested;
  294. if (!is_congested) {
  295. // If we just decongested, dispatch whatever we have left over in our queue.
  296. // Once that's done, if we're still decongested, notify the listener so it
  297. // can start writing again.
  298. dispatch_fragments(client);
  299. if (!client->is_congested) {
  300. client->callbacks.write_ready(client, client->context);
  301. }
  302. }
  303. }
  304. static void read_ready_cb(uint16_t local_channel_id, BT_HDR *packet)
  305. {
  306. assert(local_channel_id != 0);
  307. l2cap_client_t *client = find(local_channel_id);
  308. if (!client) {
  309. LOG_ERROR("%s unable to find L2CAP client matching LCID 0x%04x.\n", __func__, local_channel_id);
  310. return;
  311. }
  312. // TODO(sharvil): eliminate copy from BT_HDR.
  313. buffer_t *buffer = buffer_new(packet->len);
  314. memcpy(buffer_ptr(buffer), packet->data + packet->offset, packet->len);
  315. GKI_freebuf(packet);
  316. client->callbacks.read_ready(client, buffer, client->context);
  317. buffer_free(buffer);
  318. }
  319. static void write_completed_cb(UNUSED_ATTR uint16_t local_channel_id, UNUSED_ATTR uint16_t packets_completed)
  320. {
  321. // Do nothing. We update congestion state based on the congestion callback
  322. // and we've already removed items from outbound_fragments list so we don't
  323. // really care how many packets were successfully dispatched.
  324. }
  325. static void fragment_packet(l2cap_client_t *client, buffer_t *packet)
  326. {
  327. assert(client != NULL);
  328. assert(packet != NULL);
  329. // TODO(sharvil): eliminate copy into BT_HDR.
  330. BT_HDR *bt_packet = GKI_getbuf(buffer_length(packet) + L2CAP_MIN_OFFSET);
  331. bt_packet->offset = L2CAP_MIN_OFFSET;
  332. bt_packet->len = buffer_length(packet);
  333. memcpy(bt_packet->data + bt_packet->offset, buffer_ptr(packet), buffer_length(packet));
  334. for (;;) {
  335. if (bt_packet->len <= client->remote_mtu) {
  336. if (bt_packet->len > 0) {
  337. list_append(client->outbound_fragments, bt_packet);
  338. } else {
  339. GKI_freebuf(bt_packet);
  340. }
  341. break;
  342. }
  343. BT_HDR *fragment = GKI_getbuf(client->remote_mtu + L2CAP_MIN_OFFSET);
  344. fragment->offset = L2CAP_MIN_OFFSET;
  345. fragment->len = client->remote_mtu;
  346. memcpy(fragment->data + fragment->offset, bt_packet->data + bt_packet->offset, client->remote_mtu);
  347. list_append(client->outbound_fragments, fragment);
  348. bt_packet->offset += client->remote_mtu;
  349. bt_packet->len -= client->remote_mtu;
  350. }
  351. }
  352. static void dispatch_fragments(l2cap_client_t *client)
  353. {
  354. assert(client != NULL);
  355. assert(!client->is_congested);
  356. while (!list_is_empty(client->outbound_fragments)) {
  357. BT_HDR *packet = (BT_HDR *)list_front(client->outbound_fragments);
  358. list_remove(client->outbound_fragments, packet);
  359. switch (L2CA_DataWrite(client->local_channel_id, packet)) {
  360. case L2CAP_DW_CONGESTED:
  361. client->is_congested = true;
  362. return;
  363. case L2CAP_DW_FAILED:
  364. LOG_ERROR("%s error writing data to L2CAP connection LCID 0x%04x; disconnecting.", __func__, client->local_channel_id);
  365. l2cap_client_disconnect(client);
  366. return;
  367. case L2CAP_DW_SUCCESS:
  368. break;
  369. }
  370. }
  371. }
  372. static l2cap_client_t *find(uint16_t local_channel_id)
  373. {
  374. assert(local_channel_id != 0);
  375. for (const list_node_t *node = list_begin(l2cap_clients); node != list_end(l2cap_clients); node = list_next(node)) {
  376. l2cap_client_t *client = (l2cap_client_t *)list_node(node);
  377. if (client->local_channel_id == local_channel_id) {
  378. return client;
  379. }
  380. }
  381. return NULL;
  382. }
  383. #endif /*L2CAP_CLIENT_INCLUDED*/