smp_l2c.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /******************************************************************************
  2. *
  3. * Copyright 1999-2012 Broadcom Corporation
  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. /******************************************************************************
  19. *
  20. * This file contains functions for the SMP L2Cap interface
  21. *
  22. ******************************************************************************/
  23. #include <cutils/log.h>
  24. #include "bt_target.h"
  25. #include <string.h>
  26. #include "btm_ble_api.h"
  27. #include "common/metrics.h"
  28. #include "l2c_api.h"
  29. #include "smp_int.h"
  30. static void smp_tx_complete_callback(uint16_t cid, uint16_t num_pkt);
  31. static void smp_connect_callback(uint16_t channel, const RawAddress& bd_addr,
  32. bool connected, uint16_t reason,
  33. tBT_TRANSPORT transport);
  34. static void smp_data_received(uint16_t channel, const RawAddress& bd_addr,
  35. BT_HDR* p_buf);
  36. static void smp_br_connect_callback(uint16_t channel, const RawAddress& bd_addr,
  37. bool connected, uint16_t reason,
  38. tBT_TRANSPORT transport);
  39. static void smp_br_data_received(uint16_t channel, const RawAddress& bd_addr,
  40. BT_HDR* p_buf);
  41. /*******************************************************************************
  42. *
  43. * Function smp_l2cap_if_init
  44. *
  45. * Description This function is called during the SMP task startup
  46. * to register interface functions with L2CAP.
  47. *
  48. ******************************************************************************/
  49. void smp_l2cap_if_init(void) {
  50. tL2CAP_FIXED_CHNL_REG fixed_reg;
  51. SMP_TRACE_EVENT("SMDBG l2c %s", __func__);
  52. fixed_reg.fixed_chnl_opts.mode = L2CAP_FCR_BASIC_MODE;
  53. fixed_reg.fixed_chnl_opts.max_transmit = 0;
  54. fixed_reg.fixed_chnl_opts.rtrans_tout = 0;
  55. fixed_reg.fixed_chnl_opts.mon_tout = 0;
  56. fixed_reg.fixed_chnl_opts.mps = 0;
  57. fixed_reg.fixed_chnl_opts.tx_win_sz = 0;
  58. fixed_reg.pL2CA_FixedConn_Cb = smp_connect_callback;
  59. fixed_reg.pL2CA_FixedData_Cb = smp_data_received;
  60. fixed_reg.pL2CA_FixedTxComplete_Cb = smp_tx_complete_callback;
  61. fixed_reg.pL2CA_FixedCong_Cb =
  62. NULL; /* do not handle congestion on this channel */
  63. fixed_reg.default_idle_tout =
  64. 60; /* set 60 seconds timeout, 0xffff default idle timeout */
  65. L2CA_RegisterFixedChannel(L2CAP_SMP_CID, &fixed_reg);
  66. fixed_reg.pL2CA_FixedConn_Cb = smp_br_connect_callback;
  67. fixed_reg.pL2CA_FixedData_Cb = smp_br_data_received;
  68. L2CA_RegisterFixedChannel(L2CAP_SMP_BR_CID, &fixed_reg);
  69. }
  70. /*******************************************************************************
  71. *
  72. * Function smp_connect_callback
  73. *
  74. * Description This callback function is called by L2CAP to indicate that
  75. * SMP channel is
  76. * connected (conn = true)/disconnected (conn = false).
  77. *
  78. ******************************************************************************/
  79. static void smp_connect_callback(uint16_t channel, const RawAddress& bd_addr,
  80. bool connected, uint16_t reason,
  81. tBT_TRANSPORT transport) {
  82. tSMP_CB* p_cb = &smp_cb;
  83. tSMP_INT_DATA int_data;
  84. SMP_TRACE_EVENT("%s: SMDBG l2c: bd_addr=%s, p_cb->pairing_bda=%s", __func__,
  85. bd_addr.ToString().c_str(),
  86. p_cb->pairing_bda.ToString().c_str());
  87. if (transport == BT_TRANSPORT_BR_EDR || bd_addr.IsEmpty()) return;
  88. if (bd_addr == p_cb->pairing_bda) {
  89. VLOG(2) << __func__ << " for pairing BDA: " << bd_addr
  90. << " Event: " << ((connected) ? "connected" : "disconnected");
  91. if (connected) {
  92. if (!p_cb->connect_initialized) {
  93. p_cb->connect_initialized = true;
  94. /* initiating connection established */
  95. p_cb->role = L2CA_GetBleConnRole(bd_addr);
  96. /* initialize local i/r key to be default keys */
  97. p_cb->local_r_key = p_cb->local_i_key = SMP_SEC_DEFAULT_KEY;
  98. p_cb->loc_auth_req = p_cb->peer_auth_req = SMP_DEFAULT_AUTH_REQ;
  99. p_cb->cb_evt = SMP_IO_CAP_REQ_EVT;
  100. smp_sm_event(p_cb, SMP_L2CAP_CONN_EVT, NULL);
  101. }
  102. } else {
  103. int_data.reason = reason;
  104. /* Disconnected while doing security */
  105. smp_sm_event(p_cb, SMP_L2CAP_DISCONN_EVT, &int_data);
  106. }
  107. }
  108. }
  109. /*******************************************************************************
  110. *
  111. * Function smp_data_received
  112. *
  113. * Description This function is called when data is received from L2CAP on
  114. * SMP channel.
  115. *
  116. *
  117. * Returns void
  118. *
  119. ******************************************************************************/
  120. static void smp_data_received(uint16_t channel, const RawAddress& bd_addr,
  121. BT_HDR* p_buf) {
  122. tSMP_CB* p_cb = &smp_cb;
  123. uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
  124. uint8_t cmd;
  125. if (p_buf->len < 1) {
  126. android_errorWriteLog(0x534e4554, "111215315");
  127. SMP_TRACE_WARNING("%s: smp packet length %d too short: must be at least 1",
  128. __func__, p_buf->len);
  129. osi_free(p_buf);
  130. return;
  131. }
  132. STREAM_TO_UINT8(cmd, p);
  133. SMP_TRACE_EVENT("%s: SMDBG l2c, cmd=0x%x", __func__, cmd);
  134. /* sanity check */
  135. if ((SMP_OPCODE_MAX < cmd) || (SMP_OPCODE_MIN > cmd)) {
  136. SMP_TRACE_WARNING("Ignore received command with RESERVED code 0x%02x", cmd);
  137. osi_free(p_buf);
  138. return;
  139. }
  140. /* reject the pairing request if there is an on-going SMP pairing */
  141. if (SMP_OPCODE_PAIRING_REQ == cmd || SMP_OPCODE_SEC_REQ == cmd) {
  142. if ((p_cb->state == SMP_STATE_IDLE) &&
  143. (p_cb->br_state == SMP_BR_STATE_IDLE) &&
  144. !(p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD)) {
  145. p_cb->role = L2CA_GetBleConnRole(bd_addr);
  146. p_cb->pairing_bda = bd_addr;
  147. } else if (bd_addr != p_cb->pairing_bda) {
  148. osi_free(p_buf);
  149. smp_reject_unexpected_pairing_command(bd_addr);
  150. return;
  151. }
  152. /* else, out of state pairing request/security request received, passed into
  153. * SM */
  154. }
  155. if (bd_addr == p_cb->pairing_bda) {
  156. alarm_set_on_mloop(p_cb->smp_rsp_timer_ent, SMP_WAIT_FOR_RSP_TIMEOUT_MS,
  157. smp_rsp_timeout, NULL);
  158. smp_log_metrics(p_cb->pairing_bda, false /* incoming */,
  159. p_buf->data + p_buf->offset, p_buf->len);
  160. if (cmd == SMP_OPCODE_CONFIRM) {
  161. SMP_TRACE_DEBUG(
  162. "in %s cmd = 0x%02x, peer_auth_req = 0x%02x,"
  163. "loc_auth_req = 0x%02x",
  164. __func__, cmd, p_cb->peer_auth_req, p_cb->loc_auth_req);
  165. if ((p_cb->peer_auth_req & SMP_SC_SUPPORT_BIT) &&
  166. (p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT)) {
  167. cmd = SMP_OPCODE_PAIR_COMMITM;
  168. }
  169. }
  170. p_cb->rcvd_cmd_code = cmd;
  171. p_cb->rcvd_cmd_len = (uint8_t)p_buf->len;
  172. tSMP_INT_DATA smp_int_data;
  173. smp_int_data.p_data = p;
  174. smp_sm_event(p_cb, cmd, &smp_int_data);
  175. }
  176. osi_free(p_buf);
  177. }
  178. /*******************************************************************************
  179. *
  180. * Function smp_tx_complete_callback
  181. *
  182. * Description SMP channel tx complete callback
  183. *
  184. ******************************************************************************/
  185. static void smp_tx_complete_callback(uint16_t cid, uint16_t num_pkt) {
  186. tSMP_CB* p_cb = &smp_cb;
  187. if (p_cb->total_tx_unacked >= num_pkt)
  188. p_cb->total_tx_unacked -= num_pkt;
  189. else
  190. SMP_TRACE_ERROR("Unexpected %s: num_pkt = %d", __func__, num_pkt);
  191. if (p_cb->total_tx_unacked == 0 && p_cb->wait_for_authorization_complete) {
  192. tSMP_INT_DATA smp_int_data;
  193. smp_int_data.status = SMP_SUCCESS;
  194. if (cid == L2CAP_SMP_CID) {
  195. smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
  196. } else {
  197. smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &smp_int_data);
  198. }
  199. }
  200. }
  201. /*******************************************************************************
  202. *
  203. * Function smp_br_connect_callback
  204. *
  205. * Description This callback function is called by L2CAP to indicate that
  206. * SMP BR channel is
  207. * connected (conn = true)/disconnected (conn = false).
  208. *
  209. ******************************************************************************/
  210. static void smp_br_connect_callback(uint16_t channel, const RawAddress& bd_addr,
  211. bool connected, uint16_t reason,
  212. tBT_TRANSPORT transport) {
  213. tSMP_CB* p_cb = &smp_cb;
  214. tSMP_INT_DATA int_data;
  215. SMP_TRACE_EVENT("%s", __func__);
  216. if (transport != BT_TRANSPORT_BR_EDR) {
  217. SMP_TRACE_WARNING("%s is called on unexpected transport %d", __func__,
  218. transport);
  219. return;
  220. }
  221. VLOG(1) << __func__ << " for pairing BDA: " << bd_addr
  222. << ", pairing_bda:" << p_cb->pairing_bda
  223. << " Event: " << ((connected) ? "connected" : "disconnected");
  224. if (bd_addr != p_cb->pairing_bda) return;
  225. if (connected) {
  226. if (!p_cb->connect_initialized) {
  227. p_cb->connect_initialized = true;
  228. /* initialize local i/r key to be default keys */
  229. p_cb->local_r_key = p_cb->local_i_key = SMP_BR_SEC_DEFAULT_KEY;
  230. p_cb->loc_auth_req = p_cb->peer_auth_req = 0;
  231. p_cb->cb_evt = SMP_BR_KEYS_REQ_EVT;
  232. smp_br_state_machine_event(p_cb, SMP_BR_L2CAP_CONN_EVT, NULL);
  233. }
  234. } else {
  235. int_data.reason = reason;
  236. /* Disconnected while doing security */
  237. smp_br_state_machine_event(p_cb, SMP_BR_L2CAP_DISCONN_EVT, &int_data);
  238. }
  239. }
  240. /*******************************************************************************
  241. *
  242. * Function smp_br_data_received
  243. *
  244. * Description This function is called when data is received from L2CAP on
  245. * SMP BR channel.
  246. *
  247. * Returns void
  248. *
  249. ******************************************************************************/
  250. static void smp_br_data_received(uint16_t channel, const RawAddress& bd_addr,
  251. BT_HDR* p_buf) {
  252. tSMP_CB* p_cb = &smp_cb;
  253. uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
  254. uint8_t cmd;
  255. SMP_TRACE_EVENT("SMDBG l2c %s", __func__);
  256. if (p_buf->len < 1) {
  257. android_errorWriteLog(0x534e4554, "111215315");
  258. SMP_TRACE_WARNING("%s: smp packet length %d too short: must be at least 1",
  259. __func__, p_buf->len);
  260. osi_free(p_buf);
  261. return;
  262. }
  263. STREAM_TO_UINT8(cmd, p);
  264. /* sanity check */
  265. if ((SMP_OPCODE_MAX < cmd) || (SMP_OPCODE_MIN > cmd)) {
  266. SMP_TRACE_WARNING("Ignore received command with RESERVED code 0x%02x", cmd);
  267. osi_free(p_buf);
  268. return;
  269. }
  270. /* reject the pairing request if there is an on-going SMP pairing */
  271. if (SMP_OPCODE_PAIRING_REQ == cmd) {
  272. if ((p_cb->state == SMP_STATE_IDLE) &&
  273. (p_cb->br_state == SMP_BR_STATE_IDLE)) {
  274. p_cb->role = HCI_ROLE_SLAVE;
  275. p_cb->smp_over_br = true;
  276. p_cb->pairing_bda = bd_addr;
  277. } else if (bd_addr != p_cb->pairing_bda) {
  278. osi_free(p_buf);
  279. smp_reject_unexpected_pairing_command(bd_addr);
  280. return;
  281. }
  282. /* else, out of state pairing request received, passed into State Machine */
  283. }
  284. if (bd_addr == p_cb->pairing_bda) {
  285. alarm_set_on_mloop(p_cb->smp_rsp_timer_ent, SMP_WAIT_FOR_RSP_TIMEOUT_MS,
  286. smp_rsp_timeout, NULL);
  287. smp_log_metrics(p_cb->pairing_bda, false /* incoming */,
  288. p_buf->data + p_buf->offset, p_buf->len);
  289. p_cb->rcvd_cmd_code = cmd;
  290. p_cb->rcvd_cmd_len = (uint8_t)p_buf->len;
  291. tSMP_INT_DATA smp_int_data;
  292. smp_int_data.p_data = p;
  293. smp_br_state_machine_event(p_cb, cmd, &smp_int_data);
  294. }
  295. osi_free(p_buf);
  296. }