smp_api.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2008-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 the implementation of the SMP interface used by
  21. * applications that can run over an SMP.
  22. *
  23. ******************************************************************************/
  24. #include <string.h>
  25. #include "common/bt_target.h"
  26. //#include "bt_utils.h"
  27. #if SMP_INCLUDED == TRUE
  28. #include "smp_int.h"
  29. #include "stack/smp_api.h"
  30. #include "stack/l2cdefs.h"
  31. #include "l2c_int.h"
  32. #include "btm_int.h"
  33. #include "stack/hcimsgs.h"
  34. #include "stack/btu.h"
  35. #include "p_256_ecc_pp.h"
  36. #include "osi/allocator.h"
  37. /*******************************************************************************
  38. **
  39. ** Function SMP_Init
  40. **
  41. ** Description This function initializes the SMP unit.
  42. **
  43. ** Returns void
  44. **
  45. *******************************************************************************/
  46. void SMP_Init(void)
  47. {
  48. #if SMP_DYNAMIC_MEMORY
  49. smp_cb_ptr = (tSMP_CB *)osi_malloc(sizeof(tSMP_CB));
  50. curve_ptr = (elliptic_curve_t *)osi_malloc(sizeof(elliptic_curve_t));
  51. curve_p256_ptr = (elliptic_curve_t *)osi_malloc(sizeof(elliptic_curve_t));
  52. #endif
  53. memset(&smp_cb, 0, sizeof(tSMP_CB));
  54. memset(&curve, 0, sizeof(elliptic_curve_t));
  55. memset(&curve_p256, 0, sizeof(elliptic_curve_t));
  56. #if defined(SMP_INITIAL_TRACE_LEVEL)
  57. smp_cb.trace_level = SMP_INITIAL_TRACE_LEVEL;
  58. #else
  59. smp_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
  60. #endif
  61. SMP_TRACE_EVENT ("%s", __FUNCTION__);
  62. smp_l2cap_if_init();
  63. /* initialization of P-256 parameters */
  64. p_256_init_curve(KEY_LENGTH_DWORDS_P256);
  65. }
  66. void SMP_Free(void)
  67. {
  68. memset(&smp_cb, 0, sizeof(tSMP_CB));
  69. #if SMP_DYNAMIC_MEMORY
  70. FREE_AND_RESET(smp_cb_ptr);
  71. FREE_AND_RESET(curve_ptr);
  72. FREE_AND_RESET(curve_p256_ptr);
  73. #endif /* #if SMP_DYNAMIC_MEMORY */
  74. }
  75. /*******************************************************************************
  76. **
  77. ** Function SMP_SetTraceLevel
  78. **
  79. ** Description This function sets the trace level for SMP. If called with
  80. ** a value of 0xFF, it simply returns the current trace level.
  81. **
  82. ** Input Parameters:
  83. ** level: The level to set the GATT tracing to:
  84. ** 0xff-returns the current setting.
  85. ** 0-turns off tracing.
  86. ** >= 1-Errors.
  87. ** >= 2-Warnings.
  88. ** >= 3-APIs.
  89. ** >= 4-Events.
  90. ** >= 5-Debug.
  91. **
  92. ** Returns The new or current trace level
  93. **
  94. *******************************************************************************/
  95. extern UINT8 SMP_SetTraceLevel (UINT8 new_level)
  96. {
  97. if (new_level != 0xFF) {
  98. smp_cb.trace_level = new_level;
  99. }
  100. return (smp_cb.trace_level);
  101. }
  102. /*******************************************************************************
  103. **
  104. ** Function SMP_Register
  105. **
  106. ** Description This function register for the SMP services callback.
  107. **
  108. ** Returns void
  109. **
  110. *******************************************************************************/
  111. BOOLEAN SMP_Register (tSMP_CALLBACK *p_cback)
  112. {
  113. SMP_TRACE_EVENT ("SMP_Register state=%d", smp_cb.state);
  114. if (smp_cb.p_callback != NULL) {
  115. SMP_TRACE_ERROR ("SMP_Register: duplicate registration, overwrite it");
  116. }
  117. smp_cb.p_callback = p_cback;
  118. return (TRUE);
  119. }
  120. /*******************************************************************************
  121. **
  122. ** Function SMP_Pair
  123. **
  124. ** Description This function call to perform a SMP pairing with peer device.
  125. ** Device support one SMP pairing at one time.
  126. **
  127. ** Parameters bd_addr - peer device bd address.
  128. **
  129. ** Returns None
  130. **
  131. *******************************************************************************/
  132. tSMP_STATUS SMP_Pair (BD_ADDR bd_addr)
  133. {
  134. tSMP_CB *p_cb = &smp_cb;
  135. UINT8 status = SMP_PAIR_INTERNAL_ERR;
  136. SMP_TRACE_EVENT ("%s state=%d br_state=%d flag=0x%x \n",
  137. __FUNCTION__, p_cb->state, p_cb->br_state, p_cb->flags);
  138. if (p_cb->state != SMP_STATE_IDLE || p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD ||
  139. p_cb->smp_over_br) {
  140. /* pending security on going, reject this one */
  141. return SMP_BUSY;
  142. } else {
  143. p_cb->flags = SMP_PAIR_FLAGS_WE_STARTED_DD;
  144. memcpy (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN);
  145. if (!L2CA_ConnectFixedChnl (L2CAP_SMP_CID, bd_addr, BLE_ADDR_UNKNOWN_TYPE, FALSE)) {
  146. SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.\n", __FUNCTION__);
  147. smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status);
  148. return status;
  149. }
  150. return SMP_STARTED;
  151. }
  152. }
  153. /*******************************************************************************
  154. **
  155. ** Function SMP_BR_PairWith
  156. **
  157. ** Description This function is called to start a SMP pairing over BR/EDR.
  158. ** Device support one SMP pairing at one time.
  159. **
  160. ** Parameters bd_addr - peer device bd address.
  161. **
  162. ** Returns SMP_STARTED if pairing started, otherwise reason for failure.
  163. **
  164. *******************************************************************************/
  165. #if (CLASSIC_BT_INCLUDED == TRUE)
  166. tSMP_STATUS SMP_BR_PairWith (BD_ADDR bd_addr)
  167. {
  168. tSMP_CB *p_cb = &smp_cb;
  169. UINT8 status = SMP_PAIR_INTERNAL_ERR;
  170. SMP_TRACE_EVENT ("%s state=%d br_state=%d flag=0x%x ",
  171. __func__, p_cb->state, p_cb->br_state, p_cb->flags);
  172. if (p_cb->state != SMP_STATE_IDLE ||
  173. p_cb->smp_over_br ||
  174. p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD) {
  175. /* pending security on going, reject this one */
  176. return SMP_BUSY;
  177. }
  178. p_cb->role = HCI_ROLE_MASTER;
  179. p_cb->flags = SMP_PAIR_FLAGS_WE_STARTED_DD;
  180. p_cb->smp_over_br = TRUE;
  181. memcpy (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN);
  182. if (!L2CA_ConnectFixedChnl (L2CAP_SMP_BR_CID, bd_addr, BLE_ADDR_UNKNOWN_TYPE, FALSE)) {
  183. SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.", __FUNCTION__);
  184. smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &status);
  185. return status;
  186. }
  187. return SMP_STARTED;
  188. }
  189. #endif ///CLASSIC_BT_INCLUDED == TRUE
  190. /*******************************************************************************
  191. **
  192. ** Function SMP_PairCancel
  193. **
  194. ** Description This function call to cancel a SMP pairing with peer device.
  195. **
  196. ** Parameters bd_addr - peer device bd address.
  197. **
  198. ** Returns TRUE - Pairining is cancelled
  199. **
  200. *******************************************************************************/
  201. BOOLEAN SMP_PairCancel (BD_ADDR bd_addr)
  202. {
  203. tSMP_CB *p_cb = &smp_cb;
  204. UINT8 err_code = SMP_PAIR_FAIL_UNKNOWN;
  205. BOOLEAN status = FALSE;
  206. BTM_TRACE_EVENT ("SMP_CancelPair state=%d flag=0x%x ", p_cb->state, p_cb->flags);
  207. if ( (p_cb->state != SMP_STATE_IDLE) &&
  208. (!memcmp (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN)) ) {
  209. p_cb->is_pair_cancel = TRUE;
  210. SMP_TRACE_DEBUG("Cancel Pairing: set fail reason Unknown");
  211. smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &err_code);
  212. status = TRUE;
  213. }
  214. return status;
  215. }
  216. /*******************************************************************************
  217. **
  218. ** Function SMP_SecurityGrant
  219. **
  220. ** Description This function is called to grant security process.
  221. **
  222. ** Parameters bd_addr - peer device bd address.
  223. ** res - result of the operation SMP_SUCCESS if success.
  224. ** Otherwise, SMP_REPEATED_ATTEMPTS is too many attempts.
  225. **
  226. ** Returns None
  227. **
  228. *******************************************************************************/
  229. void SMP_SecurityGrant(BD_ADDR bd_addr, UINT8 res)
  230. {
  231. SMP_TRACE_EVENT ("SMP_SecurityGrant ");
  232. #if (CLASSIC_BT_INCLUDED == TRUE)
  233. if (smp_cb.smp_over_br) {
  234. if (smp_cb.br_state != SMP_BR_STATE_WAIT_APP_RSP ||
  235. smp_cb.cb_evt != SMP_SEC_REQUEST_EVT ||
  236. memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN)) {
  237. return;
  238. }
  239. /* clear the SMP_SEC_REQUEST_EVT event after get grant */
  240. /* avoid generating duplicate pair request */
  241. smp_cb.cb_evt = 0;
  242. smp_br_state_machine_event(&smp_cb, SMP_BR_API_SEC_GRANT_EVT, &res);
  243. return;
  244. }
  245. #endif ///CLASSIC_BT_INCLUDED == TRUE
  246. if (smp_cb.state != SMP_STATE_WAIT_APP_RSP ||
  247. smp_cb.cb_evt != SMP_SEC_REQUEST_EVT ||
  248. memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN)) {
  249. return;
  250. }
  251. /* clear the SMP_SEC_REQUEST_EVT event after get grant */
  252. /* avoid generate duplicate pair request */
  253. smp_cb.cb_evt = 0;
  254. smp_sm_event(&smp_cb, SMP_API_SEC_GRANT_EVT, &res);
  255. }
  256. /*******************************************************************************
  257. **
  258. ** Function SMP_PasskeyReply
  259. **
  260. ** Description This function is called after Security Manager submitted
  261. ** passkey request to the application.
  262. **
  263. ** Parameters: bd_addr - Address of the device for which passkey was requested
  264. ** res - result of the operation SMP_SUCCESS if success
  265. ** passkey - numeric value in the range of
  266. ** BTM_MIN_PASSKEY_VAL(0) - BTM_MAX_PASSKEY_VAL(999999(0xF423F)).
  267. **
  268. *******************************************************************************/
  269. void SMP_PasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey)
  270. {
  271. tSMP_CB *p_cb = & smp_cb;
  272. UINT8 failure = SMP_PASSKEY_ENTRY_FAIL;
  273. SMP_TRACE_EVENT ("SMP_PasskeyReply: Key: %d Result:%d",
  274. passkey, res);
  275. /* If timeout already expired or has been canceled, ignore the reply */
  276. if (p_cb->cb_evt != SMP_PASSKEY_REQ_EVT) {
  277. SMP_TRACE_WARNING ("SMP_PasskeyReply() - Wrong State: %d", p_cb->state);
  278. return;
  279. }
  280. if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0) {
  281. SMP_TRACE_ERROR ("SMP_PasskeyReply() - Wrong BD Addr");
  282. return;
  283. }
  284. if (btm_find_dev (bd_addr) == NULL) {
  285. SMP_TRACE_ERROR ("SMP_PasskeyReply() - no dev CB");
  286. return;
  287. }
  288. if (passkey > BTM_MAX_PASSKEY_VAL || res != SMP_SUCCESS) {
  289. SMP_TRACE_WARNING ("SMP_PasskeyReply() - Wrong key len: %d or passkey entry fail", passkey);
  290. /* send pairing failure */
  291. smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
  292. } else if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_PASSKEY_ENT) {
  293. smp_sm_event(&smp_cb, SMP_SC_KEY_READY_EVT, &passkey);
  294. } else {
  295. smp_convert_string_to_tk(p_cb->tk, passkey);
  296. }
  297. return;
  298. }
  299. /*******************************************************************************
  300. **
  301. ** Function SMP_SetStaticPasskey
  302. **
  303. ** Description This function is called to set static passkey
  304. **
  305. **
  306. ** Parameters: add - set static passkey when add is TRUE
  307. ** clear static passkey when add is FALSE
  308. ** passkey - static passkey
  309. **
  310. **
  311. *******************************************************************************/
  312. void SMP_SetStaticPasskey (BOOLEAN add, UINT32 passkey)
  313. {
  314. SMP_TRACE_DEBUG("static passkey %6d", passkey);
  315. tSMP_CB *p_cb = & smp_cb;
  316. if(add) {
  317. p_cb->static_passkey = passkey;
  318. p_cb->use_static_passkey = true;
  319. } else {
  320. p_cb->static_passkey = 0;
  321. p_cb->use_static_passkey = false;
  322. }
  323. }
  324. /*******************************************************************************
  325. **
  326. ** Function SMP_ConfirmReply
  327. **
  328. ** Description This function is called after Security Manager submitted
  329. ** numeric comparison request to the application.
  330. **
  331. ** Parameters: bd_addr - Address of the device with which numeric
  332. ** comparison was requested
  333. ** res - comparison result SMP_SUCCESS if success
  334. **
  335. *******************************************************************************/
  336. void SMP_ConfirmReply (BD_ADDR bd_addr, UINT8 res)
  337. {
  338. tSMP_CB *p_cb = & smp_cb;
  339. UINT8 failure = SMP_NUMERIC_COMPAR_FAIL;
  340. SMP_TRACE_EVENT ("%s: Result:%d", __FUNCTION__, res);
  341. /* If timeout already expired or has been canceled, ignore the reply */
  342. if (p_cb->cb_evt != SMP_NC_REQ_EVT) {
  343. SMP_TRACE_WARNING ("%s() - Wrong State: %d", __FUNCTION__, p_cb->state);
  344. return;
  345. }
  346. if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0) {
  347. SMP_TRACE_ERROR ("%s() - Wrong BD Addr", __FUNCTION__);
  348. return;
  349. }
  350. if (btm_find_dev (bd_addr) == NULL) {
  351. SMP_TRACE_ERROR ("%s() - no dev CB", __FUNCTION__);
  352. return;
  353. }
  354. if (res != SMP_SUCCESS) {
  355. SMP_TRACE_WARNING ("%s() - Numeric Comparison fails", __FUNCTION__);
  356. /* send pairing failure */
  357. smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
  358. } else {
  359. smp_sm_event(p_cb, SMP_SC_NC_OK_EVT, NULL);
  360. }
  361. }
  362. /*******************************************************************************
  363. **
  364. ** Function SMP_OobDataReply
  365. **
  366. ** Description This function is called to provide the OOB data for
  367. ** SMP in response to SMP_OOB_REQ_EVT
  368. **
  369. ** Parameters: bd_addr - Address of the peer device
  370. ** res - result of the operation SMP_SUCCESS if success
  371. ** p_data - simple pairing Randomizer C.
  372. **
  373. *******************************************************************************/
  374. void SMP_OobDataReply(BD_ADDR bd_addr, tSMP_STATUS res, UINT8 len, UINT8 *p_data)
  375. {
  376. tSMP_CB *p_cb = & smp_cb;
  377. UINT8 failure = SMP_OOB_FAIL;
  378. tSMP_KEY key;
  379. SMP_TRACE_EVENT ("%s State: %d res:%d", __FUNCTION__, smp_cb.state, res);
  380. /* If timeout already expired or has been canceled, ignore the reply */
  381. if (p_cb->state != SMP_STATE_WAIT_APP_RSP || p_cb->cb_evt != SMP_OOB_REQ_EVT) {
  382. return;
  383. }
  384. if (res != SMP_SUCCESS || len == 0 || !p_data) {
  385. smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
  386. } else {
  387. if (len > BT_OCTET16_LEN) {
  388. len = BT_OCTET16_LEN;
  389. }
  390. memcpy(p_cb->tk, p_data, len);
  391. key.key_type = SMP_KEY_TYPE_TK;
  392. key.p_data = p_cb->tk;
  393. smp_sm_event(&smp_cb, SMP_KEY_READY_EVT, &key);
  394. }
  395. }
  396. /*******************************************************************************
  397. **
  398. ** Function SMP_SecureConnectionOobDataReply
  399. **
  400. ** Description This function is called to provide the SC OOB data for
  401. ** SMP in response to SMP_SC_OOB_REQ_EVT
  402. **
  403. ** Parameters: p_data - pointer to the data
  404. **
  405. *******************************************************************************/
  406. void SMP_SecureConnectionOobDataReply(UINT8 *p_data)
  407. {
  408. tSMP_CB *p_cb = &smp_cb;
  409. UINT8 failure = SMP_OOB_FAIL;
  410. tSMP_SC_OOB_DATA *p_oob = (tSMP_SC_OOB_DATA *) p_data;
  411. if (!p_oob) {
  412. SMP_TRACE_ERROR("%s received no data", __FUNCTION__);
  413. smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
  414. return;
  415. }
  416. /* Set local oob data when req_oob_type = SMP_OOB_BOTH */
  417. memcpy(&p_oob->loc_oob_data, smp_get_local_oob_data(), sizeof(tSMP_LOC_OOB_DATA));
  418. SMP_TRACE_EVENT ("%s req_oob_type: %d, loc_oob_data.present: %d, "
  419. "peer_oob_data.present: %d",
  420. __FUNCTION__, p_cb->req_oob_type, p_oob->loc_oob_data.present,
  421. p_oob->peer_oob_data.present);
  422. if (p_cb->state != SMP_STATE_WAIT_APP_RSP || p_cb->cb_evt != SMP_SC_OOB_REQ_EVT) {
  423. return;
  424. }
  425. BOOLEAN data_missing = FALSE;
  426. switch (p_cb->req_oob_type) {
  427. case SMP_OOB_PEER:
  428. if (!p_oob->peer_oob_data.present) {
  429. data_missing = TRUE;
  430. }
  431. break;
  432. case SMP_OOB_LOCAL:
  433. if (!p_oob->loc_oob_data.present) {
  434. data_missing = TRUE;
  435. }
  436. break;
  437. case SMP_OOB_BOTH:
  438. if (!p_oob->loc_oob_data.present || !p_oob->peer_oob_data.present) {
  439. data_missing = TRUE;
  440. }
  441. break;
  442. default:
  443. SMP_TRACE_EVENT ("Unexpected OOB data type requested. Fail OOB");
  444. data_missing = TRUE;
  445. break;
  446. }
  447. if (data_missing) {
  448. SMP_TRACE_ERROR("%s data missing", __func__);
  449. smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
  450. return;
  451. }
  452. p_cb->sc_oob_data = *p_oob;
  453. smp_sm_event(&smp_cb, SMP_SC_OOB_DATA_EVT, p_data);
  454. }
  455. /*******************************************************************************
  456. **
  457. ** Function SMP_Encrypt
  458. **
  459. ** Description This function is called to encrypt the data with the specified
  460. ** key
  461. **
  462. ** Parameters: key - Pointer to key key[0] conatins the MSB
  463. ** key_len - key length
  464. ** plain_text - Pointer to data to be encrypted
  465. ** plain_text[0] conatins the MSB
  466. ** pt_len - plain text length
  467. ** p_out - output of the encrypted texts
  468. **
  469. ** Returns Boolean - request is successful
  470. *******************************************************************************/
  471. BOOLEAN SMP_Encrypt (UINT8 *key, UINT8 key_len,
  472. UINT8 *plain_text, UINT8 pt_len,
  473. tSMP_ENC *p_out)
  474. {
  475. BOOLEAN status = FALSE;
  476. status = smp_encrypt_data(key, key_len, plain_text, pt_len, p_out);
  477. return status;
  478. }
  479. /*******************************************************************************
  480. **
  481. ** Function SMP_KeypressNotification
  482. **
  483. ** Description This function is called to notify Security Manager about Keypress Notification.
  484. **
  485. ** Parameters: bd_addr Address of the device to send keypress notification to
  486. ** value Keypress notification parameter value
  487. **
  488. *******************************************************************************/
  489. void SMP_KeypressNotification (BD_ADDR bd_addr, UINT8 value)
  490. {
  491. tSMP_CB *p_cb = &smp_cb;
  492. SMP_TRACE_EVENT ("%s: Value: %d", __FUNCTION__, value);
  493. if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0) {
  494. SMP_TRACE_ERROR ("%s() - Wrong BD Addr", __FUNCTION__);
  495. return;
  496. }
  497. if (btm_find_dev (bd_addr) == NULL) {
  498. SMP_TRACE_ERROR ("%s() - no dev CB", __FUNCTION__);
  499. return;
  500. }
  501. /* Keypress Notification is used by a device with KeyboardOnly IO capabilities */
  502. /* during the passkey entry protocol */
  503. if (p_cb->local_io_capability != SMP_IO_CAP_IN) {
  504. SMP_TRACE_ERROR ("%s() - wrong local IO capabilities %d",
  505. __FUNCTION__, p_cb->local_io_capability);
  506. return;
  507. }
  508. if (p_cb->selected_association_model != SMP_MODEL_SEC_CONN_PASSKEY_ENT) {
  509. SMP_TRACE_ERROR ("%s() - wrong protocol %d", __FUNCTION__,
  510. p_cb->selected_association_model);
  511. return;
  512. }
  513. smp_sm_event(p_cb, SMP_KEYPRESS_NOTIFICATION_EVENT, &value);
  514. }
  515. /*******************************************************************************
  516. **
  517. ** Function SMP_CreateLocalSecureConnectionsOobData
  518. **
  519. ** Description This function is called to start creation of local SC OOB
  520. ** data set (tSMP_LOC_OOB_DATA).
  521. **
  522. ** Returns Boolean - TRUE: creation of local SC OOB data set started.
  523. *******************************************************************************/
  524. BOOLEAN SMP_CreateLocalSecureConnectionsOobData (void)
  525. {
  526. tSMP_CB *p_cb = &smp_cb;
  527. SMP_TRACE_EVENT ("%s state: %u, br_state: %u", __FUNCTION__, p_cb->state, p_cb->br_state);
  528. if ((p_cb->state != SMP_STATE_IDLE) || (p_cb->smp_over_br)) {
  529. SMP_TRACE_WARNING ("%s creation of local OOB data set "\
  530. "starts only in IDLE state", __FUNCTION__);
  531. return FALSE;
  532. }
  533. smp_sm_event(p_cb, SMP_CR_LOC_SC_OOB_DATA_EVT, NULL);
  534. return TRUE;
  535. }
  536. #endif /* SMP_INCLUDED */