bt_l2cap.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. /****************************************************************************
  2. * wireless/bluetooth/bt_l2cap.c
  3. * L2CAP handling
  4. *
  5. * Copyright (C) 2018 Gregory Nutt. All rights reserved.
  6. * Author: Gregory Nutt <gnutt@nuttx.org>
  7. *
  8. * Ported from the Intel/Zephyr arduino101_firmware_source-v1.tar package
  9. * where the code was released with a compatible 3-clause BSD license:
  10. *
  11. * Copyright (c) 2016, Intel Corporation
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions are
  16. * met:
  17. *
  18. * 1. Redistributions of source code must retain the above copyright notice,
  19. * this list of conditions and the following disclaimer.
  20. *
  21. * 2. Redistributions in binary form must reproduce the above copyright
  22. * notice, this list of conditions and the following disclaimer in the
  23. * documentation and/or other materials provided with the distribution.
  24. *
  25. * 3. Neither the name of the copyright holder nor the names of its
  26. * contributors may be used to endorse or promote products derived from
  27. * this software without specific prior written permission.
  28. *
  29. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  30. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  31. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  32. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  33. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  34. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  35. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS
  36. * ; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  37. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  38. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  39. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  40. *
  41. ****************************************************************************/
  42. /****************************************************************************
  43. * Included Files
  44. ****************************************************************************/
  45. #include <nuttx/config.h>
  46. #include <string.h>
  47. #include <errno.h>
  48. #include <debug.h>
  49. #include <nuttx/wireless/bluetooth/bt_hci.h>
  50. #include <nuttx/wireless/bluetooth/bt_core.h>
  51. #include "bt_hcicore.h"
  52. #include "bt_conn.h"
  53. #include "bt_l2cap.h"
  54. #include "bt_att.h"
  55. #include "bt_smp.h"
  56. /****************************************************************************
  57. * Pre-processor Definitions
  58. ****************************************************************************/
  59. #define LE_CONN_MIN_INTERVAL 0x0028
  60. #define LE_CONN_MAX_INTERVAL 0x0038
  61. #define LE_CONN_LATENCY 0x0000
  62. #define LE_CONN_TIMEOUT 0x002a
  63. #define BT_L2CAP_CONN_PARAM_ACCEPTED 0
  64. #define BT_L2CAP_CONN_PARAM_REJECTED 1
  65. /****************************************************************************
  66. * Private Data
  67. ****************************************************************************/
  68. static FAR struct bt_l2cap_chan_s *g_channels;
  69. static FAR struct bt_l2cap_chan_s *g_default;
  70. /****************************************************************************
  71. * Private Functions
  72. ****************************************************************************/
  73. static uint8_t get_ident(FAR struct bt_conn_s *conn)
  74. {
  75. conn->l2cap.ident++;
  76. /* Handle integer overflow (0 is not valid) */
  77. if (!conn->l2cap.ident)
  78. {
  79. conn->l2cap.ident++;
  80. }
  81. return conn->l2cap.ident;
  82. }
  83. void bt_l2cap_chan_register(FAR struct bt_l2cap_chan_s *chan)
  84. {
  85. wlinfo("CID 0x%04x\n", chan->cid);
  86. chan->flink = g_channels;
  87. g_channels = chan;
  88. }
  89. void bt_l2cap_chan_default(FAR struct bt_l2cap_chan_s *chan)
  90. {
  91. g_default = chan;
  92. }
  93. void bt_l2cap_connected(FAR struct bt_conn_s *conn)
  94. {
  95. FAR struct bt_l2cap_chan_s *chan;
  96. /* Notify all registered channels of the connection event */
  97. for (chan = g_channels; chan; chan = chan->flink)
  98. {
  99. if (chan->connected != NULL)
  100. {
  101. chan->connected(conn, chan->context, chan->cid);
  102. }
  103. }
  104. /* Notify any default listener of the connection event */
  105. chan = g_default;
  106. if (chan != NULL && chan->connected != NULL)
  107. {
  108. chan->connected(conn, chan->context, chan->cid);
  109. }
  110. }
  111. void bt_l2cap_disconnected(FAR struct bt_conn_s *conn)
  112. {
  113. FAR struct bt_l2cap_chan_s *chan;
  114. /* Notify all registered channels of the disconnection event */
  115. for (chan = g_channels; chan; chan = chan->flink)
  116. {
  117. if (chan->disconnected != NULL)
  118. {
  119. chan->disconnected(conn, chan->context, chan->cid);
  120. }
  121. }
  122. /* Notify any default listener of the disconnection event */
  123. chan = g_default;
  124. if (chan != NULL && chan->disconnected != NULL)
  125. {
  126. chan->disconnected(conn, chan->context, chan->cid);
  127. }
  128. }
  129. void bt_l2cap_encrypt_change(FAR struct bt_conn_s *conn)
  130. {
  131. FAR struct bt_l2cap_chan_s *chan;
  132. /* Notify all registered channels of the encryption change event */
  133. for (chan = g_channels; chan; chan = chan->flink)
  134. {
  135. if (chan->encrypt_change != NULL)
  136. {
  137. chan->encrypt_change(conn, chan->context, chan->cid);
  138. }
  139. }
  140. /* Notify any default listener of the encryption change event */
  141. chan = g_default;
  142. if (chan != NULL && chan->encrypt_change != NULL)
  143. {
  144. chan->encrypt_change(conn, chan->context, chan->cid);
  145. }
  146. }
  147. struct bt_buf_s *bt_l2cap_create_pdu(FAR struct bt_conn_s *conn)
  148. {
  149. size_t head_reserve = sizeof(struct bt_l2cap_hdr_s) +
  150. sizeof(struct bt_hci_acl_hdr_s) + g_btdev.btdev->head_reserve;
  151. return bt_buf_alloc(BT_ACL_OUT, NULL, head_reserve);
  152. }
  153. void bt_l2cap_send(FAR struct bt_conn_s *conn, uint16_t cid,
  154. FAR struct bt_buf_s *buf)
  155. {
  156. FAR struct bt_l2cap_hdr_s *hdr;
  157. hdr = bt_buf_provide(buf, sizeof(*hdr));
  158. hdr->len = BT_HOST2LE16(buf->len - sizeof(*hdr));
  159. hdr->cid = BT_HOST2LE16(cid);
  160. bt_conn_send(conn, buf);
  161. }
  162. static void rej_not_understood(FAR struct bt_conn_s *conn, uint8_t ident)
  163. {
  164. FAR struct bt_l2cap_cmd_reject_s *rej;
  165. FAR struct bt_l2cap_sig_hdr_s *hdr;
  166. FAR struct bt_buf_s *buf;
  167. buf = bt_l2cap_create_pdu(conn);
  168. if (!buf)
  169. {
  170. return;
  171. }
  172. hdr = bt_buf_extend(buf, sizeof(*hdr));
  173. hdr->code = BT_L2CAP_CMD_REJECT;
  174. hdr->ident = ident;
  175. hdr->len = BT_HOST2LE16(sizeof(*rej));
  176. rej = bt_buf_extend(buf, sizeof(*rej));
  177. rej->reason = BT_HOST2LE16(BT_L2CAP_REJ_NOT_UNDERSTOOD);
  178. bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf);
  179. }
  180. static void le_conn_param_rsp(FAR struct bt_conn_s *conn,
  181. FAR struct bt_buf_s *buf)
  182. {
  183. struct bt_l2cap_conn_param_rsp_s *rsp = (void *)buf->data;
  184. if (buf->len < sizeof(*rsp))
  185. {
  186. wlerr("ERROR: Too small LE conn param rsp\n");
  187. return;
  188. }
  189. wlinfo("LE conn param rsp result %u\n", BT_LE162HOST(rsp->result));
  190. }
  191. static uint16_t le_validate_conn_params(uint16_t min, uint16_t max,
  192. uint16_t latency, uint16_t timeout)
  193. {
  194. uint16_t max_latency;
  195. if (min > max || min < 6 || max > 3200)
  196. {
  197. return BT_L2CAP_CONN_PARAM_REJECTED;
  198. }
  199. if (timeout < 10 || timeout > 3200)
  200. {
  201. return BT_L2CAP_CONN_PARAM_REJECTED;
  202. }
  203. /* Calculation based on BT spec 4.2 [Vol3, PartA, 4.20] max_latency =
  204. * ((timeout * 10)/(max * 1.25 * 2)) - 1;
  205. */
  206. max_latency = (timeout * 4 / max) - 1;
  207. if (latency > 499 || latency > max_latency)
  208. {
  209. return BT_L2CAP_CONN_PARAM_REJECTED;
  210. }
  211. return BT_L2CAP_CONN_PARAM_ACCEPTED;
  212. }
  213. static void le_conn_param_update_req(FAR struct bt_conn_s *conn,
  214. uint8_t ident,
  215. FAR struct bt_buf_s *buf)
  216. {
  217. FAR struct bt_l2cap_sig_hdr_s *hdr;
  218. FAR struct bt_l2cap_conn_param_rsp_s *rsp;
  219. FAR struct bt_l2cap_conn_param_req_s *req = (void *)buf->data;
  220. uint16_t min;
  221. uint16_t max;
  222. uint16_t latency;
  223. uint16_t timeout;
  224. uint16_t result;
  225. if (buf->len < sizeof(*req))
  226. {
  227. wlerr("ERROR: Too small LE conn update param req\n");
  228. return;
  229. }
  230. if (conn->role != BT_HCI_ROLE_MASTER)
  231. {
  232. return;
  233. }
  234. min = BT_LE162HOST(req->min_interval);
  235. max = BT_LE162HOST(req->max_interval);
  236. latency = BT_LE162HOST(req->latency);
  237. timeout = BT_LE162HOST(req->timeout);
  238. wlinfo("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x timeout: 0x%4.4x",
  239. min, max, latency, timeout);
  240. buf = bt_l2cap_create_pdu(conn);
  241. if (!buf)
  242. {
  243. return;
  244. }
  245. result = le_validate_conn_params(min, max, latency, timeout);
  246. hdr = bt_buf_extend(buf, sizeof(*hdr));
  247. hdr->code = BT_L2CAP_CONN_PARAM_RSP;
  248. hdr->ident = ident;
  249. hdr->len = BT_HOST2LE16(sizeof(*rsp));
  250. rsp = bt_buf_extend(buf, sizeof(*rsp));
  251. memset(rsp, 0, sizeof(*rsp));
  252. rsp->result = BT_HOST2LE16(result);
  253. bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf);
  254. if (result == BT_L2CAP_CONN_PARAM_ACCEPTED)
  255. {
  256. bt_conn_le_conn_update(conn, min, max, latency, timeout);
  257. }
  258. }
  259. static void le_sig(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf,
  260. FAR void *context, uint16_t cid)
  261. {
  262. struct bt_l2cap_sig_hdr_s *hdr = (FAR void *)buf->data;
  263. uint16_t len;
  264. if (buf->len < sizeof(*hdr))
  265. {
  266. wlerr("ERROR: Too small L2CAP LE signaling PDU\n");
  267. goto drop;
  268. }
  269. len = BT_LE162HOST(hdr->len);
  270. bt_buf_consume(buf, sizeof(*hdr));
  271. wlinfo("LE signaling code 0x%02x ident %u len %u\n", hdr->code,
  272. hdr->ident, len);
  273. if (buf->len != len)
  274. {
  275. wlerr("ERROR: L2CAP length mismatch (%u != %u)\n", buf->len, len);
  276. goto drop;
  277. }
  278. if (!hdr->ident)
  279. {
  280. wlerr("ERROR: Invalid ident value in L2CAP PDU\n");
  281. goto drop;
  282. }
  283. switch (hdr->code)
  284. {
  285. case BT_L2CAP_CONN_PARAM_RSP:
  286. le_conn_param_rsp(conn, buf);
  287. break;
  288. case BT_L2CAP_CONN_PARAM_REQ:
  289. le_conn_param_update_req(conn, hdr->ident, buf);
  290. break;
  291. default:
  292. wlwarn("Unknown L2CAP PDU code 0x%02x\n", hdr->code);
  293. rej_not_understood(conn, hdr->ident);
  294. break;
  295. }
  296. drop:
  297. bt_buf_release(buf);
  298. }
  299. void bt_l2cap_receive(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf)
  300. {
  301. FAR struct bt_l2cap_hdr_s *hdr = (FAR void *)buf->data;
  302. FAR struct bt_l2cap_chan_s *chan;
  303. uint16_t cid;
  304. if (buf->len < sizeof(*hdr))
  305. {
  306. wlerr("ERROR: Too small L2CAP PDU received\n");
  307. bt_buf_release(buf);
  308. return;
  309. }
  310. cid = BT_LE162HOST(hdr->cid);
  311. bt_buf_consume(buf, sizeof(*hdr));
  312. wlinfo("Packet for CID %u len %u\n", cid, buf->len);
  313. /* Search for a subscriber to this channel */
  314. for (chan = g_channels; chan != NULL; chan = chan->flink)
  315. {
  316. if (chan->cid == cid)
  317. {
  318. break;
  319. }
  320. }
  321. /* If there is no subscriber, then send all received frames to the default
  322. * listener (if one is registered).
  323. */
  324. if (chan == NULL)
  325. {
  326. chan = g_default;
  327. }
  328. if (chan == NULL)
  329. {
  330. wlwarn("WARNING: No subscriber to CID 0x%04x\n", cid);
  331. bt_buf_release(buf);
  332. return;
  333. }
  334. chan->receive(conn, buf, chan->context, cid);
  335. }
  336. void bt_l2cap_update_conn_param(FAR struct bt_conn_s *conn)
  337. {
  338. FAR struct bt_l2cap_sig_hdr_s *hdr;
  339. FAR struct bt_l2cap_conn_param_req_s *req;
  340. FAR struct bt_buf_s *buf;
  341. /* Check if we need to update anything */
  342. if (conn->le_conn_interval >= LE_CONN_MIN_INTERVAL &&
  343. conn->le_conn_interval <= LE_CONN_MAX_INTERVAL)
  344. {
  345. return;
  346. }
  347. buf = bt_l2cap_create_pdu(conn);
  348. if (!buf)
  349. {
  350. return;
  351. }
  352. hdr = bt_buf_extend(buf, sizeof(*hdr));
  353. hdr->code = BT_L2CAP_CONN_PARAM_REQ;
  354. hdr->ident = get_ident(conn);
  355. hdr->len = BT_HOST2LE16(sizeof(*req));
  356. req = bt_buf_extend(buf, sizeof(*req));
  357. req->min_interval = BT_HOST2LE16(LE_CONN_MIN_INTERVAL);
  358. req->max_interval = BT_HOST2LE16(LE_CONN_MAX_INTERVAL);
  359. req->latency = BT_HOST2LE16(LE_CONN_LATENCY);
  360. req->timeout = BT_HOST2LE16(LE_CONN_TIMEOUT);
  361. bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf);
  362. }
  363. int bt_l2cap_init(void)
  364. {
  365. int ret;
  366. static struct bt_l2cap_chan_s chan =
  367. {
  368. .cid = BT_L2CAP_CID_LE_SIG,
  369. .receive = le_sig,
  370. };
  371. bt_att_initialize();
  372. ret = bt_smp_initialize();
  373. if (ret < 0)
  374. {
  375. return ret;
  376. }
  377. bt_l2cap_chan_register(&chan);
  378. return ret;
  379. }