1 /******************************************************************************
2 *
3 * Copyright (C) 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 *
21 * This file contains functions for the SMP L2CAP utility functions
22 *
23 ******************************************************************************/
24 #include "bt_target.h"
25
26 #if SMP_INCLUDED == TRUE
27
28 #include "bt_types.h"
29 #include "bt_utils.h"
30 #include <string.h>
31 #include <ctype.h>
32 #include "hcidefs.h"
33 #include "btm_ble_api.h"
34 #include "l2c_api.h"
35 #include "l2c_int.h"
36 #include "smp_int.h"
37 #include "device/include/controller.h"
38 #include "btm_int.h"
39
40 #define SMP_PAIRING_REQ_SIZE 7
41 #define SMP_CONFIRM_CMD_SIZE (BT_OCTET16_LEN + 1)
42 #define SMP_RAND_CMD_SIZE (BT_OCTET16_LEN + 1)
43 #define SMP_INIT_CMD_SIZE (BT_OCTET16_LEN + 1)
44 #define SMP_ENC_INFO_SIZE (BT_OCTET16_LEN + 1)
45 #define SMP_MASTER_ID_SIZE (BT_OCTET8_LEN + 2 + 1)
46 #define SMP_ID_INFO_SIZE (BT_OCTET16_LEN + 1)
47 #define SMP_ID_ADDR_SIZE (BD_ADDR_LEN + 1 + 1)
48 #define SMP_SIGN_INFO_SIZE (BT_OCTET16_LEN + 1)
49 #define SMP_PAIR_FAIL_SIZE 2
50 #define SMP_SECURITY_REQUEST_SIZE 2
51 #define SMP_PAIR_PUBL_KEY_SIZE (1 /* opcode */ + (2*BT_OCTET32_LEN))
52 #define SMP_PAIR_COMMITM_SIZE (1 /* opcode */ + BT_OCTET16_LEN /*Commitment*/)
53 #define SMP_PAIR_DHKEY_CHECK_SIZE (1 /* opcode */ + BT_OCTET16_LEN /*DHKey Check*/)
54 #define SMP_PAIR_KEYPR_NOTIF_SIZE (1 /* opcode */ + 1 /*Notif Type*/)
55
56 /* SMP command sizes per spec */
57 static const UINT8 smp_cmd_size_per_spec[] =
58 {
59 0,
60 SMP_PAIRING_REQ_SIZE, /* 0x01: pairing request */
61 SMP_PAIRING_REQ_SIZE, /* 0x02: pairing response */
62 SMP_CONFIRM_CMD_SIZE, /* 0x03: pairing confirm */
63 SMP_RAND_CMD_SIZE, /* 0x04: pairing random */
64 SMP_PAIR_FAIL_SIZE, /* 0x05: pairing failed */
65 SMP_ENC_INFO_SIZE, /* 0x06: encryption information */
66 SMP_MASTER_ID_SIZE, /* 0x07: master identification */
67 SMP_ID_INFO_SIZE, /* 0x08: identity information */
68 SMP_ID_ADDR_SIZE, /* 0x09: identity address information */
69 SMP_SIGN_INFO_SIZE, /* 0x0A: signing information */
70 SMP_SECURITY_REQUEST_SIZE, /* 0x0B: security request */
71 SMP_PAIR_PUBL_KEY_SIZE, /* 0x0C: pairing public key */
72 SMP_PAIR_DHKEY_CHECK_SIZE, /* 0x0D: pairing dhkey check */
73 SMP_PAIR_KEYPR_NOTIF_SIZE, /* 0x0E: pairing keypress notification */
74 SMP_PAIR_COMMITM_SIZE /* 0x0F: pairing commitment */
75 };
76
77 static BOOLEAN smp_parameter_unconditionally_valid(tSMP_CB *p_cb);
78 static BOOLEAN smp_parameter_unconditionally_invalid(tSMP_CB *p_cb);
79
80 /* type for SMP command length validation functions */
81 typedef BOOLEAN (*tSMP_CMD_LEN_VALID)(tSMP_CB *p_cb);
82
83 static BOOLEAN smp_command_has_valid_fixed_length(tSMP_CB *p_cb);
84
85 static const tSMP_CMD_LEN_VALID smp_cmd_len_is_valid[] =
86 {
87 smp_parameter_unconditionally_invalid,
88 smp_command_has_valid_fixed_length, /* 0x01: pairing request */
89 smp_command_has_valid_fixed_length, /* 0x02: pairing response */
90 smp_command_has_valid_fixed_length, /* 0x03: pairing confirm */
91 smp_command_has_valid_fixed_length, /* 0x04: pairing random */
92 smp_command_has_valid_fixed_length, /* 0x05: pairing failed */
93 smp_command_has_valid_fixed_length, /* 0x06: encryption information */
94 smp_command_has_valid_fixed_length, /* 0x07: master identification */
95 smp_command_has_valid_fixed_length, /* 0x08: identity information */
96 smp_command_has_valid_fixed_length, /* 0x09: identity address information */
97 smp_command_has_valid_fixed_length, /* 0x0A: signing information */
98 smp_command_has_valid_fixed_length, /* 0x0B: security request */
99 smp_command_has_valid_fixed_length, /* 0x0C: pairing public key */
100 smp_command_has_valid_fixed_length, /* 0x0D: pairing dhkey check */
101 smp_command_has_valid_fixed_length, /* 0x0E: pairing keypress notification */
102 smp_command_has_valid_fixed_length /* 0x0F: pairing commitment */
103 };
104
105 /* type for SMP command parameter ranges validation functions */
106 typedef BOOLEAN (*tSMP_CMD_PARAM_RANGES_VALID)(tSMP_CB *p_cb);
107
108 static BOOLEAN smp_pairing_request_response_parameters_are_valid(tSMP_CB *p_cb);
109 static BOOLEAN smp_pairing_keypress_notification_is_valid(tSMP_CB *p_cb);
110
111 static const tSMP_CMD_PARAM_RANGES_VALID smp_cmd_param_ranges_are_valid[] =
112 {
113 smp_parameter_unconditionally_invalid,
114 smp_pairing_request_response_parameters_are_valid, /* 0x01: pairing request */
115 smp_pairing_request_response_parameters_are_valid, /* 0x02: pairing response */
116 smp_parameter_unconditionally_valid, /* 0x03: pairing confirm */
117 smp_parameter_unconditionally_valid, /* 0x04: pairing random */
118 smp_parameter_unconditionally_valid, /* 0x05: pairing failed */
119 smp_parameter_unconditionally_valid, /* 0x06: encryption information */
120 smp_parameter_unconditionally_valid, /* 0x07: master identification */
121 smp_parameter_unconditionally_valid, /* 0x08: identity information */
122 smp_parameter_unconditionally_valid, /* 0x09: identity address information */
123 smp_parameter_unconditionally_valid, /* 0x0A: signing information */
124 smp_parameter_unconditionally_valid, /* 0x0B: security request */
125 smp_parameter_unconditionally_valid, /* 0x0C: pairing public key */
126 smp_parameter_unconditionally_valid, /* 0x0D: pairing dhkey check */
127 smp_pairing_keypress_notification_is_valid, /* 0x0E: pairing keypress notification */
128 smp_parameter_unconditionally_valid /* 0x0F: pairing commitment */
129 };
130
131 /* type for action functions */
132 typedef BT_HDR * (*tSMP_CMD_ACT)(UINT8 cmd_code, tSMP_CB *p_cb);
133
134 static BT_HDR *smp_build_pairing_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
135 static BT_HDR *smp_build_confirm_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
136 static BT_HDR *smp_build_rand_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
137 static BT_HDR *smp_build_pairing_fail(UINT8 cmd_code, tSMP_CB *p_cb);
138 static BT_HDR *smp_build_identity_info_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
139 static BT_HDR *smp_build_encrypt_info_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
140 static BT_HDR *smp_build_security_request(UINT8 cmd_code, tSMP_CB *p_cb);
141 static BT_HDR *smp_build_signing_info_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
142 static BT_HDR *smp_build_master_id_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
143 static BT_HDR *smp_build_id_addr_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
144 static BT_HDR *smp_build_pair_public_key_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
145 static BT_HDR *smp_build_pairing_commitment_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
146 static BT_HDR *smp_build_pair_dhkey_check_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
147 static BT_HDR *smp_build_pairing_keypress_notification_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
148
149 static const tSMP_CMD_ACT smp_cmd_build_act[] =
150 {
151 NULL,
152 smp_build_pairing_cmd, /* 0x01: pairing request */
153 smp_build_pairing_cmd, /* 0x02: pairing response */
154 smp_build_confirm_cmd, /* 0x03: pairing confirm */
155 smp_build_rand_cmd, /* 0x04: pairing random */
156 smp_build_pairing_fail, /* 0x05: pairing failure */
157 smp_build_encrypt_info_cmd, /* 0x06: encryption information */
158 smp_build_master_id_cmd, /* 0x07: master identification */
159 smp_build_identity_info_cmd, /* 0x08: identity information */
160 smp_build_id_addr_cmd, /* 0x09: identity address information */
161 smp_build_signing_info_cmd, /* 0x0A: signing information */
162 smp_build_security_request, /* 0x0B: security request */
163 smp_build_pair_public_key_cmd, /* 0x0C: pairing public key */
164 smp_build_pair_dhkey_check_cmd, /* 0x0D: pairing DHKey check */
165 smp_build_pairing_keypress_notification_cmd, /* 0x0E: pairing keypress notification */
166 smp_build_pairing_commitment_cmd /* 0x0F: pairing commitment */
167 };
168
169 static const UINT8 smp_association_table[2][SMP_IO_CAP_MAX][SMP_IO_CAP_MAX] =
170 {
171 /* display only */ /* Display Yes/No */ /* keyboard only */
172 /* No Input/Output */ /* keyboard display */
173
174 /* initiator */
175 /* model = tbl[peer_io_caps][loc_io_caps] */
176 /* Display Only */
177 {{SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_PASSKEY,
178 SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_PASSKEY},
179
180 /* Display Yes/No */
181 {SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_PASSKEY,
182 SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_PASSKEY},
183
184 /* Keyboard only */
185 {SMP_MODEL_KEY_NOTIF, SMP_MODEL_KEY_NOTIF, SMP_MODEL_PASSKEY,
186 SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_KEY_NOTIF},
187
188 /* No Input No Output */
189 {SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY,
190 SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY},
191
192 /* keyboard display */
193 {SMP_MODEL_KEY_NOTIF, SMP_MODEL_KEY_NOTIF, SMP_MODEL_PASSKEY,
194 SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_KEY_NOTIF}},
195
196 /* responder */
197 /* model = tbl[loc_io_caps][peer_io_caps] */
198 /* Display Only */
199 {{SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_KEY_NOTIF,
200 SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_KEY_NOTIF},
201
202 /* Display Yes/No */
203 {SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_KEY_NOTIF,
204 SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_KEY_NOTIF},
205
206 /* keyboard only */
207 {SMP_MODEL_PASSKEY, SMP_MODEL_PASSKEY, SMP_MODEL_PASSKEY,
208 SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_PASSKEY},
209
210 /* No Input No Output */
211 {SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY,
212 SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY},
213
214 /* keyboard display */
215 {SMP_MODEL_PASSKEY, SMP_MODEL_PASSKEY, SMP_MODEL_KEY_NOTIF,
216 SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_PASSKEY}}
217 };
218
219 static const UINT8 smp_association_table_sc[2][SMP_IO_CAP_MAX][SMP_IO_CAP_MAX] =
220 {
221 /* display only */ /* Display Yes/No */ /* keyboard only */
222 /* No InputOutput */ /* keyboard display */
223
224 /* initiator */
225 /* model = tbl[peer_io_caps][loc_io_caps] */
226
227 /* Display Only */
228 {{SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_PASSKEY_ENT,
229 SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_PASSKEY_ENT},
230
231 /* Display Yes/No */
232 {SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_NUM_COMP, SMP_MODEL_SEC_CONN_PASSKEY_ENT,
233 SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_NUM_COMP},
234
235 /* keyboard only */
236 {SMP_MODEL_SEC_CONN_PASSKEY_DISP, SMP_MODEL_SEC_CONN_PASSKEY_DISP, SMP_MODEL_SEC_CONN_PASSKEY_ENT,
237 SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_PASSKEY_DISP},
238
239 /* No Input No Output */
240 {SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_JUSTWORKS,
241 SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_JUSTWORKS},
242
243 /* keyboard display */
244 {SMP_MODEL_SEC_CONN_PASSKEY_DISP, SMP_MODEL_SEC_CONN_NUM_COMP, SMP_MODEL_SEC_CONN_PASSKEY_ENT,
245 SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_NUM_COMP}},
246
247 /* responder */
248 /* model = tbl[loc_io_caps][peer_io_caps] */
249
250 /* Display Only */
251 {{SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_PASSKEY_DISP,
252 SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_PASSKEY_DISP},
253
254 /* Display Yes/No */
255 {SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_NUM_COMP, SMP_MODEL_SEC_CONN_PASSKEY_DISP,
256 SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_NUM_COMP},
257
258 /* keyboard only */
259 {SMP_MODEL_SEC_CONN_PASSKEY_ENT, SMP_MODEL_SEC_CONN_PASSKEY_ENT, SMP_MODEL_SEC_CONN_PASSKEY_ENT,
260 SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_PASSKEY_ENT},
261
262 /* No Input No Output */
263 {SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_JUSTWORKS,
264 SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_JUSTWORKS},
265
266 /* keyboard display */
267 {SMP_MODEL_SEC_CONN_PASSKEY_ENT, SMP_MODEL_SEC_CONN_NUM_COMP, SMP_MODEL_SEC_CONN_PASSKEY_DISP,
268 SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_NUM_COMP}}
269 };
270
271 static tSMP_ASSO_MODEL smp_select_legacy_association_model(tSMP_CB *p_cb);
272 static tSMP_ASSO_MODEL smp_select_association_model_secure_connections(tSMP_CB *p_cb);
273
274 /*******************************************************************************
275 **
276 ** Function smp_send_msg_to_L2CAP
277 **
278 ** Description Send message to L2CAP.
279 **
280 *******************************************************************************/
smp_send_msg_to_L2CAP(BD_ADDR rem_bda,BT_HDR * p_toL2CAP)281 BOOLEAN smp_send_msg_to_L2CAP(BD_ADDR rem_bda, BT_HDR *p_toL2CAP)
282 {
283 UINT16 l2cap_ret;
284 UINT16 fixed_cid = L2CAP_SMP_CID;
285
286 if (smp_cb.smp_over_br)
287 {
288 fixed_cid = L2CAP_SMP_BR_CID;
289 }
290
291 SMP_TRACE_EVENT("%s", __FUNCTION__);
292 smp_cb.total_tx_unacked += 1;
293
294 if ((l2cap_ret = L2CA_SendFixedChnlData (fixed_cid, rem_bda, p_toL2CAP)) == L2CAP_DW_FAILED)
295 {
296 smp_cb.total_tx_unacked -= 1;
297 SMP_TRACE_ERROR("SMP failed to pass msg:0x%0x to L2CAP",
298 *((UINT8 *)(p_toL2CAP + 1) + p_toL2CAP->offset));
299 return FALSE;
300 }
301 else
302 return TRUE;
303 }
304
305 /*******************************************************************************
306 **
307 ** Function smp_send_cmd
308 **
309 ** Description send a SMP command on L2CAP channel.
310 **
311 *******************************************************************************/
smp_send_cmd(UINT8 cmd_code,tSMP_CB * p_cb)312 BOOLEAN smp_send_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
313 {
314 BT_HDR *p_buf;
315 BOOLEAN sent = FALSE;
316 UINT8 failure = SMP_PAIR_INTERNAL_ERR;
317 SMP_TRACE_EVENT("smp_send_cmd on l2cap cmd_code=0x%x", cmd_code);
318 if ( cmd_code <= (SMP_OPCODE_MAX + 1 /* for SMP_OPCODE_PAIR_COMMITM */) &&
319 smp_cmd_build_act[cmd_code] != NULL)
320 {
321 p_buf = (*smp_cmd_build_act[cmd_code])(cmd_code, p_cb);
322
323 if (p_buf != NULL &&
324 smp_send_msg_to_L2CAP(p_cb->pairing_bda, p_buf))
325 {
326 sent = TRUE;
327
328 btu_stop_timer (&p_cb->rsp_timer_ent);
329 btu_start_timer (&p_cb->rsp_timer_ent, BTU_TTYPE_SMP_PAIRING_CMD,
330 SMP_WAIT_FOR_RSP_TOUT);
331 }
332 }
333
334 if (!sent)
335 {
336 if (p_cb->smp_over_br)
337 {
338 smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &failure);
339 }
340 else
341 {
342 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
343 }
344 }
345 return sent;
346 }
347
348 /*******************************************************************************
349 **
350 ** Function smp_rsp_timeout
351 **
352 ** Description Called when SMP wait for SMP command response timer expires
353 **
354 ** Returns void
355 **
356 *******************************************************************************/
smp_rsp_timeout(TIMER_LIST_ENT * p_tle)357 void smp_rsp_timeout(TIMER_LIST_ENT *p_tle)
358 {
359 tSMP_CB *p_cb = &smp_cb;
360 UINT8 failure = SMP_RSP_TIMEOUT;
361 UNUSED(p_tle);
362
363 SMP_TRACE_EVENT("%s state:%d br_state:%d", __FUNCTION__, p_cb->state, p_cb->br_state);
364
365 if (p_cb->smp_over_br)
366 {
367 smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &failure);
368 }
369 else
370 {
371 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
372 }
373 }
374
375 /*******************************************************************************
376 **
377 ** Function smp_build_pairing_req_cmd
378 **
379 ** Description Build pairing request command.
380 **
381 *******************************************************************************/
smp_build_pairing_cmd(UINT8 cmd_code,tSMP_CB * p_cb)382 BT_HDR * smp_build_pairing_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
383 {
384 BT_HDR *p_buf = NULL ;
385 UINT8 *p;
386
387 SMP_TRACE_EVENT("smp_build_pairing_cmd");
388 if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_PAIRING_REQ_SIZE + L2CAP_MIN_OFFSET)) != NULL)
389 {
390 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
391
392 UINT8_TO_STREAM (p, cmd_code);
393 UINT8_TO_STREAM (p, p_cb->local_io_capability);
394 UINT8_TO_STREAM (p, p_cb->loc_oob_flag);
395 UINT8_TO_STREAM (p, p_cb->loc_auth_req);
396 UINT8_TO_STREAM (p, p_cb->loc_enc_size);
397 UINT8_TO_STREAM (p, p_cb->local_i_key);
398 UINT8_TO_STREAM (p, p_cb->local_r_key);
399
400 p_buf->offset = L2CAP_MIN_OFFSET;
401 /* 1B ERR_RSP op code + 1B cmd_op_code + 2B handle + 1B status */
402 p_buf->len = SMP_PAIRING_REQ_SIZE;
403 }
404
405 return p_buf;
406 }
407
408 /*******************************************************************************
409 **
410 ** Function smp_build_confirm_cmd
411 **
412 ** Description Build confirm request command.
413 **
414 *******************************************************************************/
smp_build_confirm_cmd(UINT8 cmd_code,tSMP_CB * p_cb)415 static BT_HDR * smp_build_confirm_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
416 {
417 BT_HDR *p_buf = NULL ;
418 UINT8 *p;
419 UNUSED(cmd_code);
420
421 SMP_TRACE_EVENT("smp_build_confirm_cmd");
422 if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_CONFIRM_CMD_SIZE + L2CAP_MIN_OFFSET)) != NULL)
423 {
424 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
425
426 UINT8_TO_STREAM (p, SMP_OPCODE_CONFIRM);
427 ARRAY_TO_STREAM (p, p_cb->confirm, BT_OCTET16_LEN);
428
429 p_buf->offset = L2CAP_MIN_OFFSET;
430 p_buf->len = SMP_CONFIRM_CMD_SIZE;
431 }
432
433 return p_buf;
434 }
435 /*******************************************************************************
436 **
437 ** Function smp_build_rand_cmd
438 **
439 ** Description Build Random command.
440 **
441 *******************************************************************************/
smp_build_rand_cmd(UINT8 cmd_code,tSMP_CB * p_cb)442 static BT_HDR * smp_build_rand_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
443 {
444 BT_HDR *p_buf = NULL ;
445 UINT8 *p;
446 UNUSED(cmd_code);
447
448 SMP_TRACE_EVENT("%s", __func__);
449 if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_RAND_CMD_SIZE + L2CAP_MIN_OFFSET))
450 != NULL)
451 {
452 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
453
454 UINT8_TO_STREAM (p, SMP_OPCODE_RAND);
455 ARRAY_TO_STREAM (p, p_cb->rand, BT_OCTET16_LEN);
456
457 p_buf->offset = L2CAP_MIN_OFFSET;
458 p_buf->len = SMP_RAND_CMD_SIZE;
459 }
460
461 return p_buf;
462 }
463 /*******************************************************************************
464 **
465 ** Function smp_build_encrypt_info_cmd
466 **
467 ** Description Build security information command.
468 **
469 *******************************************************************************/
smp_build_encrypt_info_cmd(UINT8 cmd_code,tSMP_CB * p_cb)470 static BT_HDR * smp_build_encrypt_info_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
471 {
472 BT_HDR *p_buf = NULL ;
473 UINT8 *p;
474 UNUSED(cmd_code);
475
476 SMP_TRACE_EVENT("smp_build_encrypt_info_cmd");
477 if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_ENC_INFO_SIZE + L2CAP_MIN_OFFSET)) != NULL)
478 {
479 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
480
481 UINT8_TO_STREAM (p, SMP_OPCODE_ENCRYPT_INFO);
482 ARRAY_TO_STREAM (p, p_cb->ltk, BT_OCTET16_LEN);
483
484 p_buf->offset = L2CAP_MIN_OFFSET;
485 p_buf->len = SMP_ENC_INFO_SIZE;
486 }
487
488 return p_buf;
489 }
490
491 /*******************************************************************************
492 **
493 ** Function smp_build_master_id_cmd
494 **
495 ** Description Build security information command.
496 **
497 *******************************************************************************/
smp_build_master_id_cmd(UINT8 cmd_code,tSMP_CB * p_cb)498 static BT_HDR * smp_build_master_id_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
499 {
500 BT_HDR *p_buf = NULL ;
501 UINT8 *p;
502 UNUSED(cmd_code);
503
504 SMP_TRACE_EVENT("%s", __func__);
505
506 if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_MASTER_ID_SIZE + L2CAP_MIN_OFFSET)) != NULL)
507 {
508 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
509
510 UINT8_TO_STREAM (p, SMP_OPCODE_MASTER_ID);
511 UINT16_TO_STREAM (p, p_cb->ediv);
512 ARRAY_TO_STREAM (p, p_cb->enc_rand, BT_OCTET8_LEN);
513
514 p_buf->offset = L2CAP_MIN_OFFSET;
515 p_buf->len = SMP_MASTER_ID_SIZE;
516 }
517
518 return p_buf;
519 }
520
521 /*******************************************************************************
522 **
523 ** Function smp_build_identity_info_cmd
524 **
525 ** Description Build identity information command.
526 **
527 *******************************************************************************/
smp_build_identity_info_cmd(UINT8 cmd_code,tSMP_CB * p_cb)528 static BT_HDR * smp_build_identity_info_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
529 {
530 BT_HDR *p_buf = NULL ;
531 UINT8 *p;
532 BT_OCTET16 irk;
533 UNUSED(cmd_code);
534 UNUSED(p_cb);
535
536 SMP_TRACE_EVENT("smp_build_identity_info_cmd");
537 if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_ID_INFO_SIZE + L2CAP_MIN_OFFSET)) != NULL)
538 {
539 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
540
541 BTM_GetDeviceIDRoot(irk);
542
543 UINT8_TO_STREAM (p, SMP_OPCODE_IDENTITY_INFO);
544 ARRAY_TO_STREAM (p, irk, BT_OCTET16_LEN);
545
546 p_buf->offset = L2CAP_MIN_OFFSET;
547 p_buf->len = SMP_ID_INFO_SIZE;
548 }
549
550 return p_buf;
551 }
552
553 /*******************************************************************************
554 **
555 ** Function smp_build_id_addr_cmd
556 **
557 ** Description Build identity address information command.
558 **
559 *******************************************************************************/
smp_build_id_addr_cmd(UINT8 cmd_code,tSMP_CB * p_cb)560 static BT_HDR * smp_build_id_addr_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
561 {
562 BT_HDR *p_buf = NULL;
563 UINT8 *p;
564
565 UNUSED(cmd_code);
566 UNUSED(p_cb);
567 SMP_TRACE_EVENT("smp_build_id_addr_cmd");
568 if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_ID_ADDR_SIZE + L2CAP_MIN_OFFSET)) != NULL)
569 {
570 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
571
572 UINT8_TO_STREAM (p, SMP_OPCODE_ID_ADDR);
573 UINT8_TO_STREAM (p, 0);
574 BDADDR_TO_STREAM (p, controller_get_interface()->get_address()->address);
575
576 p_buf->offset = L2CAP_MIN_OFFSET;
577 p_buf->len = SMP_ID_ADDR_SIZE;
578 }
579
580 return p_buf;
581 }
582
583 /*******************************************************************************
584 **
585 ** Function smp_build_signing_info_cmd
586 **
587 ** Description Build signing information command.
588 **
589 *******************************************************************************/
smp_build_signing_info_cmd(UINT8 cmd_code,tSMP_CB * p_cb)590 static BT_HDR * smp_build_signing_info_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
591 {
592 BT_HDR *p_buf = NULL ;
593 UINT8 *p;
594 UNUSED(cmd_code);
595
596 SMP_TRACE_EVENT("smp_build_signing_info_cmd");
597 if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_SIGN_INFO_SIZE + L2CAP_MIN_OFFSET)) != NULL)
598 {
599 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
600
601 UINT8_TO_STREAM (p, SMP_OPCODE_SIGN_INFO);
602 ARRAY_TO_STREAM (p, p_cb->csrk, BT_OCTET16_LEN);
603
604 p_buf->offset = L2CAP_MIN_OFFSET;
605 p_buf->len = SMP_SIGN_INFO_SIZE;
606 }
607
608 return p_buf;
609 }
610
611 /*******************************************************************************
612 **
613 ** Function smp_build_pairing_fail
614 **
615 ** Description Build Pairing Fail command.
616 **
617 *******************************************************************************/
smp_build_pairing_fail(UINT8 cmd_code,tSMP_CB * p_cb)618 static BT_HDR * smp_build_pairing_fail(UINT8 cmd_code, tSMP_CB *p_cb)
619 {
620 BT_HDR *p_buf = NULL ;
621 UINT8 *p;
622 UNUSED(cmd_code);
623
624 SMP_TRACE_EVENT("%s", __func__);
625 if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_PAIR_FAIL_SIZE + L2CAP_MIN_OFFSET)) != NULL)
626 {
627 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
628
629 UINT8_TO_STREAM (p, SMP_OPCODE_PAIRING_FAILED);
630 UINT8_TO_STREAM (p, p_cb->failure);
631
632 p_buf->offset = L2CAP_MIN_OFFSET;
633 p_buf->len = SMP_PAIR_FAIL_SIZE;
634 }
635
636 return p_buf;
637 }
638
639 /*******************************************************************************
640 **
641 ** Function smp_build_security_request
642 **
643 ** Description Build security request command.
644 **
645 *******************************************************************************/
smp_build_security_request(UINT8 cmd_code,tSMP_CB * p_cb)646 static BT_HDR *smp_build_security_request(UINT8 cmd_code, tSMP_CB *p_cb)
647 {
648 BT_HDR *p_buf = NULL ;
649 UINT8 *p;
650 UNUSED(cmd_code);
651
652 SMP_TRACE_EVENT("%s", __func__);
653 if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + 2 + L2CAP_MIN_OFFSET)) != NULL)
654 {
655 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
656
657 UINT8_TO_STREAM (p, SMP_OPCODE_SEC_REQ);
658 UINT8_TO_STREAM (p, p_cb->loc_auth_req);
659
660 p_buf->offset = L2CAP_MIN_OFFSET;
661 p_buf->len = SMP_SECURITY_REQUEST_SIZE;
662
663 SMP_TRACE_EVENT("opcode=%d auth_req=0x%x",SMP_OPCODE_SEC_REQ, p_cb->loc_auth_req );
664 }
665
666 return p_buf;
667
668 }
669
670 /*******************************************************************************
671 **
672 ** Function smp_build_pair_public_key_cmd
673 **
674 ** Description Build pairing public key command.
675 **
676 *******************************************************************************/
smp_build_pair_public_key_cmd(UINT8 cmd_code,tSMP_CB * p_cb)677 static BT_HDR *smp_build_pair_public_key_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
678 {
679 BT_HDR *p_buf = NULL ;
680 UINT8 *p;
681 UINT8 publ_key[2*BT_OCTET32_LEN];
682 UINT8 *p_publ_key = publ_key;
683 UNUSED(cmd_code);
684
685 SMP_TRACE_EVENT("%s", __FUNCTION__);
686
687 memcpy(p_publ_key, p_cb->loc_publ_key.x, BT_OCTET32_LEN);
688 memcpy(p_publ_key + BT_OCTET32_LEN, p_cb->loc_publ_key.y, BT_OCTET32_LEN);
689
690 if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) +
691 SMP_PAIR_PUBL_KEY_SIZE + L2CAP_MIN_OFFSET)) != NULL)
692 {
693 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
694
695 UINT8_TO_STREAM (p, SMP_OPCODE_PAIR_PUBLIC_KEY);
696 ARRAY_TO_STREAM (p, p_publ_key, 2*BT_OCTET32_LEN);
697
698 p_buf->offset = L2CAP_MIN_OFFSET;
699 p_buf->len = SMP_PAIR_PUBL_KEY_SIZE;
700 }
701
702 return p_buf;
703 }
704
705 /*******************************************************************************
706 **
707 ** Function smp_build_pairing_commitment_cmd
708 **
709 ** Description Build pairing commitment command.
710 **
711 *******************************************************************************/
smp_build_pairing_commitment_cmd(UINT8 cmd_code,tSMP_CB * p_cb)712 static BT_HDR *smp_build_pairing_commitment_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
713 {
714 BT_HDR *p_buf = NULL;
715 UINT8 *p;
716 UNUSED(cmd_code);
717
718 SMP_TRACE_EVENT("%s", __func__);
719 if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_PAIR_COMMITM_SIZE + L2CAP_MIN_OFFSET))
720 != NULL)
721 {
722 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
723
724 UINT8_TO_STREAM (p, SMP_OPCODE_CONFIRM);
725 ARRAY_TO_STREAM (p, p_cb->commitment, BT_OCTET16_LEN);
726
727 p_buf->offset = L2CAP_MIN_OFFSET;
728 p_buf->len = SMP_PAIR_COMMITM_SIZE;
729 }
730
731 return p_buf;
732 }
733
734 /*******************************************************************************
735 **
736 ** Function smp_build_pair_dhkey_check_cmd
737 **
738 ** Description Build pairing DHKey check command.
739 **
740 *******************************************************************************/
smp_build_pair_dhkey_check_cmd(UINT8 cmd_code,tSMP_CB * p_cb)741 static BT_HDR *smp_build_pair_dhkey_check_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
742 {
743 BT_HDR *p_buf = NULL;
744 UINT8 *p;
745 UNUSED(cmd_code);
746
747 SMP_TRACE_EVENT("%s", __FUNCTION__);
748 if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) +
749 SMP_PAIR_DHKEY_CHECK_SIZE + L2CAP_MIN_OFFSET)) != NULL)
750 {
751 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
752
753 UINT8_TO_STREAM (p, SMP_OPCODE_PAIR_DHKEY_CHECK);
754 ARRAY_TO_STREAM (p, p_cb->dhkey_check, BT_OCTET16_LEN);
755
756 p_buf->offset = L2CAP_MIN_OFFSET;
757 p_buf->len = SMP_PAIR_DHKEY_CHECK_SIZE;
758 }
759
760 return p_buf;
761 }
762
763 /*******************************************************************************
764 **
765 ** Function smp_build_pairing_keypress_notification_cmd
766 **
767 ** Description Build keypress notification command.
768 **
769 *******************************************************************************/
smp_build_pairing_keypress_notification_cmd(UINT8 cmd_code,tSMP_CB * p_cb)770 static BT_HDR * smp_build_pairing_keypress_notification_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
771 {
772 BT_HDR *p_buf = NULL ;
773 UINT8 *p;
774 UNUSED(cmd_code);
775
776 SMP_TRACE_EVENT("%s", __FUNCTION__);
777 if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR)\
778 + SMP_PAIR_KEYPR_NOTIF_SIZE + L2CAP_MIN_OFFSET)) != NULL)
779 {
780 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
781
782 UINT8_TO_STREAM (p, SMP_OPCODE_PAIR_KEYPR_NOTIF);
783 UINT8_TO_STREAM (p, p_cb->local_keypress_notification);
784
785 p_buf->offset = L2CAP_MIN_OFFSET;
786 p_buf->len = SMP_PAIR_KEYPR_NOTIF_SIZE;
787 }
788
789 return p_buf;
790 }
791
792 /*******************************************************************************
793 **
794 ** Function smp_convert_string_to_tk
795 **
796 ** Description This function is called to convert a 6 to 16 digits numeric
797 ** character string into SMP TK.
798 **
799 **
800 ** Returns void
801 **
802 *******************************************************************************/
smp_convert_string_to_tk(BT_OCTET16 tk,UINT32 passkey)803 void smp_convert_string_to_tk(BT_OCTET16 tk, UINT32 passkey)
804 {
805 UINT8 *p = tk;
806 tSMP_KEY key;
807 SMP_TRACE_EVENT("smp_convert_string_to_tk");
808 UINT32_TO_STREAM(p, passkey);
809
810 key.key_type = SMP_KEY_TYPE_TK;
811 key.p_data = tk;
812
813 smp_sm_event(&smp_cb, SMP_KEY_READY_EVT, &key);
814 }
815
816 /*******************************************************************************
817 **
818 ** Function smp_mask_enc_key
819 **
820 ** Description This function is called to mask off the encryption key based
821 ** on the maximum encryption key size.
822 **
823 **
824 ** Returns void
825 **
826 *******************************************************************************/
smp_mask_enc_key(UINT8 loc_enc_size,UINT8 * p_data)827 void smp_mask_enc_key(UINT8 loc_enc_size, UINT8 * p_data)
828 {
829 SMP_TRACE_EVENT("smp_mask_enc_key");
830 if (loc_enc_size < BT_OCTET16_LEN)
831 {
832 for (; loc_enc_size < BT_OCTET16_LEN; loc_enc_size ++)
833 * (p_data + loc_enc_size) = 0;
834 }
835 return;
836 }
837
838 /*******************************************************************************
839 **
840 ** Function smp_xor_128
841 **
842 ** Description utility function to do an biteise exclusive-OR of two bit
843 ** strings of the length of BT_OCTET16_LEN.
844 **
845 ** Returns void
846 **
847 *******************************************************************************/
smp_xor_128(BT_OCTET16 a,BT_OCTET16 b)848 void smp_xor_128(BT_OCTET16 a, BT_OCTET16 b)
849 {
850 UINT8 i, *aa = a, *bb = b;
851
852 SMP_TRACE_EVENT("smp_xor_128");
853 for (i = 0; i < BT_OCTET16_LEN; i++)
854 {
855 aa[i] = aa[i] ^ bb[i];
856 }
857 }
858
859 /*******************************************************************************
860 **
861 ** Function smp_cb_cleanup
862 **
863 ** Description Clean up SMP control block
864 **
865 ** Returns void
866 **
867 *******************************************************************************/
smp_cb_cleanup(tSMP_CB * p_cb)868 void smp_cb_cleanup(tSMP_CB *p_cb)
869 {
870 tSMP_CALLBACK *p_callback = p_cb->p_callback;
871 UINT8 trace_level = p_cb->trace_level;
872
873 SMP_TRACE_EVENT("smp_cb_cleanup");
874
875 memset(p_cb, 0, sizeof(tSMP_CB));
876 p_cb->p_callback = p_callback;
877 p_cb->trace_level = trace_level;
878 }
879
880 /*******************************************************************************
881 **
882 ** Function smp_remove_fixed_channel
883 **
884 ** Description This function is called to remove the fixed channel
885 **
886 ** Returns void
887 **
888 *******************************************************************************/
smp_remove_fixed_channel(tSMP_CB * p_cb)889 void smp_remove_fixed_channel(tSMP_CB *p_cb)
890 {
891 SMP_TRACE_DEBUG("%s", __func__);
892
893 if (p_cb->smp_over_br)
894 L2CA_RemoveFixedChnl (L2CAP_SMP_BR_CID, p_cb->pairing_bda);
895 else
896 L2CA_RemoveFixedChnl (L2CAP_SMP_CID, p_cb->pairing_bda);
897 }
898
899 /*******************************************************************************
900 **
901 ** Function smp_reset_control_value
902 **
903 ** Description This function is called to reset the control block value when
904 ** pairing procedure finished.
905 **
906 **
907 ** Returns void
908 **
909 *******************************************************************************/
smp_reset_control_value(tSMP_CB * p_cb)910 void smp_reset_control_value(tSMP_CB *p_cb)
911 {
912 SMP_TRACE_EVENT("smp_reset_control_value");
913 btu_stop_timer (&p_cb->rsp_timer_ent);
914 p_cb->flags = 0;
915 /* set the link idle timer to drop the link when pairing is done
916 usually service discovery will follow authentication complete, to avoid
917 racing condition for a link down/up, set link idle timer to be
918 SMP_LINK_TOUT_MIN to guarantee SMP key exchange */
919 L2CA_SetIdleTimeoutByBdAddr(p_cb->pairing_bda, SMP_LINK_TOUT_MIN, BT_TRANSPORT_LE);
920
921 /* We can tell L2CAP to remove the fixed channel (if it has one) */
922 smp_remove_fixed_channel(p_cb);
923 smp_cb_cleanup(p_cb);
924 }
925
926 /*******************************************************************************
927 **
928 ** Function smp_proc_pairing_cmpl
929 **
930 ** Description This function is called to process pairing complete
931 **
932 **
933 ** Returns void
934 **
935 *******************************************************************************/
smp_proc_pairing_cmpl(tSMP_CB * p_cb)936 void smp_proc_pairing_cmpl(tSMP_CB *p_cb)
937 {
938 tSMP_EVT_DATA evt_data = {0};
939 tSMP_CALLBACK *p_callback = p_cb->p_callback;
940 BD_ADDR pairing_bda;
941
942 SMP_TRACE_DEBUG ("smp_proc_pairing_cmpl ");
943
944 evt_data.cmplt.reason = p_cb->status;
945 evt_data.cmplt.smp_over_br = p_cb->smp_over_br;
946
947 if (p_cb->status == SMP_SUCCESS)
948 evt_data.cmplt.sec_level = p_cb->sec_level;
949
950 evt_data.cmplt.is_pair_cancel = FALSE;
951
952 if (p_cb->is_pair_cancel)
953 evt_data.cmplt.is_pair_cancel = TRUE;
954
955
956 SMP_TRACE_DEBUG ("send SMP_COMPLT_EVT reason=0x%0x sec_level=0x%0x",
957 evt_data.cmplt.reason,
958 evt_data.cmplt.sec_level );
959
960 memcpy (pairing_bda, p_cb->pairing_bda, BD_ADDR_LEN);
961
962 smp_reset_control_value(p_cb);
963
964 if (p_callback)
965 (*p_callback) (SMP_COMPLT_EVT, pairing_bda, &evt_data);
966 }
967
968 /*******************************************************************************
969 **
970 ** Function smp_command_has_invalid_parameters
971 **
972 ** Description Checks if the received SMP command has invalid parameters i.e.
973 ** if the command length is valid and the command parameters are
974 ** inside specified range.
975 ** It returns TRUE if the command has invalid parameters.
976 **
977 ** Returns TRUE if the command has invalid parameters, FALSE otherwise.
978 **
979 *******************************************************************************/
smp_command_has_invalid_parameters(tSMP_CB * p_cb)980 BOOLEAN smp_command_has_invalid_parameters(tSMP_CB *p_cb)
981 {
982 UINT8 cmd_code = p_cb->rcvd_cmd_code;
983
984 SMP_TRACE_DEBUG("%s for cmd code 0x%02x", __func__, cmd_code);
985
986 if ((cmd_code > (SMP_OPCODE_MAX + 1 /* for SMP_OPCODE_PAIR_COMMITM */)) ||
987 (cmd_code < SMP_OPCODE_MIN))
988 {
989 SMP_TRACE_WARNING("Somehow received command with the RESERVED code 0x%02x", cmd_code);
990 return TRUE;
991 }
992
993 if (!(*smp_cmd_len_is_valid[cmd_code])(p_cb))
994 return TRUE;
995
996 if (!(*smp_cmd_param_ranges_are_valid[cmd_code])(p_cb))
997 return TRUE;
998
999 return FALSE;
1000 }
1001
1002 /*******************************************************************************
1003 **
1004 ** Function smp_command_has_valid_fixed_length
1005 **
1006 ** Description Checks if the received command size is equal to the size
1007 ** according to specs.
1008 **
1009 ** Returns TRUE if the command size is as expected, FALSE otherwise.
1010 **
1011 ** Note The command is expected to have fixed length.
1012 *******************************************************************************/
smp_command_has_valid_fixed_length(tSMP_CB * p_cb)1013 BOOLEAN smp_command_has_valid_fixed_length(tSMP_CB *p_cb)
1014 {
1015 UINT8 cmd_code = p_cb->rcvd_cmd_code;
1016
1017 SMP_TRACE_DEBUG("%s for cmd code 0x%02x", __func__, cmd_code);
1018
1019 if (p_cb->rcvd_cmd_len != smp_cmd_size_per_spec[cmd_code])
1020 {
1021 SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with invalid length\
1022 0x%02x (per spec the length is 0x%02x).",
1023 cmd_code, p_cb->rcvd_cmd_len, smp_cmd_size_per_spec[cmd_code]);
1024 return FALSE;
1025 }
1026
1027 return TRUE;
1028 }
1029
1030 /*******************************************************************************
1031 **
1032 ** Function smp_pairing_request_response_parameters_are_valid
1033 **
1034 ** Description Validates parameter ranges in the received SMP command
1035 ** pairing request or pairing response.
1036 ** The parameters to validate:
1037 ** IO capability,
1038 ** OOB data flag,
1039 ** Bonding_flags in AuthReq
1040 ** Maximum encryption key size.
1041 ** Returns FALSE if at least one of these parameters is out of range.
1042 **
1043 *******************************************************************************/
smp_pairing_request_response_parameters_are_valid(tSMP_CB * p_cb)1044 BOOLEAN smp_pairing_request_response_parameters_are_valid(tSMP_CB *p_cb)
1045 {
1046 UINT8 io_caps = p_cb->peer_io_caps;
1047 UINT8 oob_flag = p_cb->peer_oob_flag;
1048 UINT8 bond_flag = p_cb->peer_auth_req & 0x03; //0x03 is gen bond with appropriate mask
1049 UINT8 enc_size = p_cb->peer_enc_size;
1050
1051 SMP_TRACE_DEBUG("%s for cmd code 0x%02x", __func__, p_cb->rcvd_cmd_code);
1052
1053 if (io_caps >= BTM_IO_CAP_MAX)
1054 {
1055 SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with IO Capabilty \
1056 value (0x%02x) out of range).",
1057 p_cb->rcvd_cmd_code, io_caps);
1058 return FALSE;
1059 }
1060
1061 if (!((oob_flag == SMP_OOB_NONE) || (oob_flag == SMP_OOB_PRESENT)))
1062 {
1063 SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with OOB data flag value \
1064 (0x%02x) out of range).",
1065 p_cb->rcvd_cmd_code, oob_flag);
1066 return FALSE;
1067 }
1068
1069 if (!((bond_flag == SMP_AUTH_NO_BOND) || (bond_flag == SMP_AUTH_BOND)))
1070 {
1071 SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with Bonding_Flags value (0x%02x)\
1072 out of range).",
1073 p_cb->rcvd_cmd_code, bond_flag);
1074 return FALSE;
1075 }
1076
1077 if ((enc_size < SMP_ENCR_KEY_SIZE_MIN) || (enc_size > SMP_ENCR_KEY_SIZE_MAX))
1078 {
1079 SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with Maximum Encryption \
1080 Key value (0x%02x) out of range).",
1081 p_cb->rcvd_cmd_code, enc_size);
1082 return FALSE;
1083 }
1084
1085 return TRUE;
1086 }
1087
1088 /*******************************************************************************
1089 **
1090 ** Function smp_pairing_keypress_notification_is_valid
1091 **
1092 ** Description Validates Notification Type parameter range in the received SMP command
1093 ** pairing keypress notification.
1094 ** Returns FALSE if this parameter is out of range.
1095 **
1096 *******************************************************************************/
smp_pairing_keypress_notification_is_valid(tSMP_CB * p_cb)1097 BOOLEAN smp_pairing_keypress_notification_is_valid(tSMP_CB *p_cb)
1098 {
1099 tBTM_SP_KEY_TYPE keypress_notification = p_cb->peer_keypress_notification;
1100
1101 SMP_TRACE_DEBUG("%s for cmd code 0x%02x", __func__, p_cb->rcvd_cmd_code);
1102
1103 if (keypress_notification >= BTM_SP_KEY_OUT_OF_RANGE)
1104 {
1105 SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with Pairing Keypress \
1106 Notification value (0x%02x) out of range).",
1107 p_cb->rcvd_cmd_code, keypress_notification);
1108 return FALSE;
1109 }
1110
1111 return TRUE;
1112 }
1113
1114 /*******************************************************************************
1115 **
1116 ** Function smp_parameter_unconditionally_valid
1117 **
1118 ** Description Always returns TRUE.
1119 **
1120 *******************************************************************************/
smp_parameter_unconditionally_valid(tSMP_CB * p_cb)1121 BOOLEAN smp_parameter_unconditionally_valid(tSMP_CB *p_cb)
1122 {
1123 return TRUE;
1124 }
1125
1126 /*******************************************************************************
1127 **
1128 ** Function smp_parameter_unconditionally_invalid
1129 **
1130 ** Description Always returns FALSE.
1131 **
1132 *******************************************************************************/
smp_parameter_unconditionally_invalid(tSMP_CB * p_cb)1133 BOOLEAN smp_parameter_unconditionally_invalid(tSMP_CB *p_cb)
1134 {
1135 return FALSE;
1136 }
1137
1138 /*******************************************************************************
1139 **
1140 ** Function smp_reject_unexpected_pairing_command
1141 **
1142 ** Description send pairing failure to an unexpected pairing command during
1143 ** an active pairing process.
1144 **
1145 ** Returns void
1146 **
1147 *******************************************************************************/
smp_reject_unexpected_pairing_command(BD_ADDR bd_addr)1148 void smp_reject_unexpected_pairing_command(BD_ADDR bd_addr)
1149 {
1150 BT_HDR *p_buf;
1151 UINT8 *p;
1152
1153 SMP_TRACE_DEBUG ("%s", __FUNCTION__);
1154
1155 if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) +\
1156 SMP_PAIR_FAIL_SIZE + L2CAP_MIN_OFFSET)) != NULL)
1157 {
1158 p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
1159
1160 UINT8_TO_STREAM (p, SMP_OPCODE_PAIRING_FAILED);
1161 UINT8_TO_STREAM (p, SMP_PAIR_NOT_SUPPORT);
1162
1163 p_buf->offset = L2CAP_MIN_OFFSET;
1164 p_buf->len = SMP_PAIR_FAIL_SIZE;
1165
1166 smp_send_msg_to_L2CAP(bd_addr, p_buf);
1167 }
1168 }
1169
1170 /*******************************************************************************
1171 ** Function smp_select_association_model
1172 **
1173 ** Description This function selects association model to use for STK
1174 ** generation. Selection is based on both sides' io capability,
1175 ** oob data flag and authentication request.
1176 **
1177 ** Note If Secure Connections Only mode is required locally then we
1178 ** come to this point only if both sides support Secure Connections
1179 ** mode, i.e. if p_cb->secure_connections_only_mode_required = TRUE then we come
1180 ** to this point only if
1181 ** (p_cb->peer_auth_req & SMP_SC_SUPPORT_BIT) ==
1182 ** (p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT) ==
1183 ** SMP_SC_SUPPORT_BIT
1184 **
1185 *******************************************************************************/
smp_select_association_model(tSMP_CB * p_cb)1186 tSMP_ASSO_MODEL smp_select_association_model(tSMP_CB *p_cb)
1187 {
1188 tSMP_ASSO_MODEL model = SMP_MODEL_OUT_OF_RANGE;
1189 p_cb->le_secure_connections_mode_is_used = FALSE;
1190
1191 SMP_TRACE_EVENT("%s", __FUNCTION__);
1192 SMP_TRACE_DEBUG("%s p_cb->peer_io_caps = %d p_cb->local_io_capability = %d",
1193 __FUNCTION__, p_cb->peer_io_caps, p_cb->local_io_capability);
1194 SMP_TRACE_DEBUG("%s p_cb->peer_oob_flag = %d p_cb->loc_oob_flag = %d",
1195 __FUNCTION__, p_cb->peer_oob_flag, p_cb->loc_oob_flag);
1196 SMP_TRACE_DEBUG("%s p_cb->peer_auth_req = 0x%02x p_cb->loc_auth_req = 0x%02x",
1197 __FUNCTION__, p_cb->peer_auth_req, p_cb->loc_auth_req);
1198 SMP_TRACE_DEBUG("%s p_cb->secure_connections_only_mode_required = %s",
1199 __FUNCTION__, p_cb->secure_connections_only_mode_required ?
1200 "TRUE" : "FALSE");
1201
1202 if ((p_cb->peer_auth_req & SMP_SC_SUPPORT_BIT) && (p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT))
1203 {
1204 p_cb->le_secure_connections_mode_is_used = TRUE;
1205 }
1206
1207 SMP_TRACE_DEBUG("use_sc_process = %d", p_cb->le_secure_connections_mode_is_used);
1208
1209 if (p_cb->le_secure_connections_mode_is_used)
1210 {
1211 model = smp_select_association_model_secure_connections(p_cb);
1212 }
1213 else
1214 {
1215 model = smp_select_legacy_association_model(p_cb);
1216 }
1217 return model;
1218 }
1219
1220 /*******************************************************************************
1221 ** Function smp_select_legacy_association_model
1222 **
1223 ** Description This function is called to select association mode if at least
1224 ** one side doesn't support secure connections.
1225 **
1226 *******************************************************************************/
smp_select_legacy_association_model(tSMP_CB * p_cb)1227 tSMP_ASSO_MODEL smp_select_legacy_association_model(tSMP_CB *p_cb)
1228 {
1229 tSMP_ASSO_MODEL model = SMP_MODEL_OUT_OF_RANGE;
1230
1231 SMP_TRACE_DEBUG("%s", __func__);
1232 /* if OOB data is present on both devices, then use OOB association model */
1233 if (p_cb->peer_oob_flag == SMP_OOB_PRESENT && p_cb->loc_oob_flag == SMP_OOB_PRESENT)
1234 return SMP_MODEL_OOB;
1235
1236 /* else if neither device requires MITM, then use Just Works association model */
1237 if (SMP_NO_MITM_REQUIRED (p_cb->peer_auth_req) && SMP_NO_MITM_REQUIRED(p_cb->loc_auth_req))
1238 return SMP_MODEL_ENCRYPTION_ONLY;
1239
1240 /* otherwise use IO capability to select association model */
1241 if (p_cb->peer_io_caps < SMP_IO_CAP_MAX && p_cb->local_io_capability < SMP_IO_CAP_MAX)
1242 {
1243 if (p_cb->role == HCI_ROLE_MASTER)
1244 {
1245 model = smp_association_table[p_cb->role][p_cb->peer_io_caps]
1246 [p_cb->local_io_capability];
1247 }
1248 else
1249 {
1250 model = smp_association_table[p_cb->role][p_cb->local_io_capability]
1251 [p_cb->peer_io_caps];
1252 }
1253 }
1254
1255 return model;
1256 }
1257
1258 /*******************************************************************************
1259 ** Function smp_select_association_model_secure_connections
1260 **
1261 ** Description This function is called to select association mode if both
1262 ** sides support secure connections.
1263 **
1264 *******************************************************************************/
smp_select_association_model_secure_connections(tSMP_CB * p_cb)1265 tSMP_ASSO_MODEL smp_select_association_model_secure_connections(tSMP_CB *p_cb)
1266 {
1267 tSMP_ASSO_MODEL model = SMP_MODEL_OUT_OF_RANGE;
1268
1269 SMP_TRACE_DEBUG("%s", __func__);
1270 /* if OOB data is present on at least one device, then use OOB association model */
1271 if (p_cb->peer_oob_flag == SMP_OOB_PRESENT || p_cb->loc_oob_flag == SMP_OOB_PRESENT)
1272 return SMP_MODEL_SEC_CONN_OOB;
1273
1274 /* else if neither device requires MITM, then use Just Works association model */
1275 if (SMP_NO_MITM_REQUIRED (p_cb->peer_auth_req) && SMP_NO_MITM_REQUIRED(p_cb->loc_auth_req))
1276 return SMP_MODEL_SEC_CONN_JUSTWORKS;
1277
1278 /* otherwise use IO capability to select association model */
1279 if (p_cb->peer_io_caps < SMP_IO_CAP_MAX && p_cb->local_io_capability < SMP_IO_CAP_MAX)
1280 {
1281 if (p_cb->role == HCI_ROLE_MASTER)
1282 {
1283 model = smp_association_table_sc[p_cb->role][p_cb->peer_io_caps]
1284 [p_cb->local_io_capability];
1285 }
1286 else
1287 {
1288 model = smp_association_table_sc[p_cb->role][p_cb->local_io_capability]
1289 [p_cb->peer_io_caps];
1290 }
1291 }
1292
1293 return model;
1294 }
1295
1296 /*******************************************************************************
1297 ** Function smp_reverse_array
1298 **
1299 ** Description This function reverses array bytes
1300 **
1301 *******************************************************************************/
smp_reverse_array(UINT8 * arr,UINT8 len)1302 void smp_reverse_array(UINT8 *arr, UINT8 len)
1303 {
1304 UINT8 i =0, tmp;
1305
1306 SMP_TRACE_DEBUG("smp_reverse_array");
1307
1308 for (i = 0; i < len/2; i ++)
1309 {
1310 tmp = arr[i];
1311 arr[i] = arr[len -1 - i];
1312 arr[len -1 - i] = tmp;
1313 }
1314 }
1315
1316 /*******************************************************************************
1317 ** Function smp_calculate_random_input
1318 **
1319 ** Description This function returns random input value to be used in commitment
1320 ** calculation for SC passkey entry association mode
1321 ** (if bit["round"] in "random" array == 1 then returns 0x81
1322 ** else returns 0x80).
1323 **
1324 ** Returns ri value
1325 **
1326 *******************************************************************************/
smp_calculate_random_input(UINT8 * random,UINT8 round)1327 UINT8 smp_calculate_random_input(UINT8 *random, UINT8 round)
1328 {
1329 UINT8 i = round/8;
1330 UINT8 j = round%8;
1331 UINT8 ri;
1332
1333 SMP_TRACE_DEBUG("random: 0x%02x, round: %d, i: %d, j: %d", random[i], round, i, j);
1334 ri = ((random[i] >> j) & 1) | 0x80;
1335 SMP_TRACE_DEBUG("%s ri=0x%02x", __func__, ri);
1336 return ri;
1337 }
1338
1339 /*******************************************************************************
1340 ** Function smp_collect_local_io_capabilities
1341 **
1342 ** Description This function puts into IOcap array local device
1343 ** IOCapability, OOB data, AuthReq.
1344 **
1345 ** Returns void
1346 **
1347 *******************************************************************************/
smp_collect_local_io_capabilities(UINT8 * iocap,tSMP_CB * p_cb)1348 void smp_collect_local_io_capabilities(UINT8 *iocap, tSMP_CB *p_cb)
1349 {
1350 SMP_TRACE_DEBUG("%s", __func__);
1351
1352 iocap[0] = p_cb->local_io_capability;
1353 iocap[1] = p_cb->loc_oob_flag;
1354 iocap[2] = p_cb->loc_auth_req;
1355 }
1356
1357 /*******************************************************************************
1358 ** Function smp_collect_peer_io_capabilities
1359 **
1360 ** Description This function puts into IOcap array peer device
1361 ** IOCapability, OOB data, AuthReq.
1362 **
1363 ** Returns void
1364 **
1365 *******************************************************************************/
smp_collect_peer_io_capabilities(UINT8 * iocap,tSMP_CB * p_cb)1366 void smp_collect_peer_io_capabilities(UINT8 *iocap, tSMP_CB *p_cb)
1367 {
1368 SMP_TRACE_DEBUG("%s", __func__);
1369
1370 iocap[0] = p_cb->peer_io_caps;
1371 iocap[1] = p_cb->peer_oob_flag;
1372 iocap[2] = p_cb->peer_auth_req;
1373 }
1374
1375 /*******************************************************************************
1376 ** Function smp_collect_local_ble_address
1377 **
1378 ** Description This function puts into le_addr array local device le address:
1379 ** le_addr[0-5] = local BD ADDR,
1380 ** le_addr[6] = local le address type (PUBLIC/RANDOM).
1381 **
1382 ** Returns void
1383 **
1384 *******************************************************************************/
smp_collect_local_ble_address(UINT8 * le_addr,tSMP_CB * p_cb)1385 void smp_collect_local_ble_address(UINT8 *le_addr, tSMP_CB *p_cb)
1386 {
1387 tBLE_ADDR_TYPE addr_type = 0;
1388 BD_ADDR bda;
1389 UINT8 *p = le_addr;
1390
1391 SMP_TRACE_DEBUG("%s", __func__);
1392
1393 BTM_ReadConnectionAddr( p_cb->pairing_bda, bda, &addr_type);
1394 BDADDR_TO_STREAM(p, bda);
1395 UINT8_TO_STREAM(p, addr_type);
1396 }
1397
1398 /*******************************************************************************
1399 ** Function smp_collect_peer_ble_address
1400 **
1401 ** Description This function puts into le_addr array peer device le address:
1402 ** le_addr[0-5] = peer BD ADDR,
1403 ** le_addr[6] = peer le address type (PUBLIC/RANDOM).
1404 **
1405 ** Returns void
1406 **
1407 *******************************************************************************/
smp_collect_peer_ble_address(UINT8 * le_addr,tSMP_CB * p_cb)1408 void smp_collect_peer_ble_address(UINT8 *le_addr, tSMP_CB *p_cb)
1409 {
1410 tBLE_ADDR_TYPE addr_type = 0;
1411 BD_ADDR bda;
1412 UINT8 *p = le_addr;
1413
1414 SMP_TRACE_DEBUG("%s", __func__);
1415
1416 if (!BTM_ReadRemoteConnectionAddr(p_cb->pairing_bda, bda, &addr_type))
1417 {
1418 SMP_TRACE_ERROR("can not collect peer le addr information for unknown device");
1419 return;
1420 }
1421
1422 BDADDR_TO_STREAM(p, bda);
1423 UINT8_TO_STREAM(p, addr_type);
1424 }
1425
1426 /*******************************************************************************
1427 ** Function smp_check_commitment
1428 **
1429 ** Description This function compares peer commitment values:
1430 ** - expected (i.e. calculated locally),
1431 ** - received from the peer.
1432 **
1433 ** Returns TRUE if the values are the same
1434 ** FALSE otherwise
1435 **
1436 *******************************************************************************/
smp_check_commitment(tSMP_CB * p_cb)1437 BOOLEAN smp_check_commitment(tSMP_CB *p_cb)
1438 {
1439 BT_OCTET16 expected;
1440
1441 SMP_TRACE_DEBUG("%s", __func__);
1442
1443 smp_calculate_peer_commitment(p_cb, expected);
1444 print128(expected, (const UINT8 *)"calculated peer commitment");
1445 print128(p_cb->remote_commitment, (const UINT8 *)"received peer commitment");
1446
1447 if (memcmp(p_cb->remote_commitment, expected, BT_OCTET16_LEN))
1448 {
1449 SMP_TRACE_WARNING("Commitment check fails");
1450 return FALSE;
1451 }
1452
1453 SMP_TRACE_DEBUG("Commitment check succeeds");
1454 return TRUE;
1455 }
1456
1457 /*******************************************************************************
1458 **
1459 ** Function smp_save_secure_connections_long_term_key
1460 **
1461 ** Description The function saves SC LTK as BLE key for future use as local
1462 ** and/or peer key.
1463 **
1464 ** Returns void
1465 **
1466 *******************************************************************************/
smp_save_secure_connections_long_term_key(tSMP_CB * p_cb)1467 void smp_save_secure_connections_long_term_key(tSMP_CB *p_cb)
1468 {
1469 tBTM_LE_LENC_KEYS lle_key;
1470 tBTM_LE_PENC_KEYS ple_key;
1471
1472 SMP_TRACE_DEBUG("%s-Save LTK as local LTK key", __func__);
1473 memcpy(lle_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
1474 lle_key.div = 0;
1475 lle_key.key_size = p_cb->loc_enc_size;
1476 lle_key.sec_level = p_cb->sec_level;
1477 btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LENC, (tBTM_LE_KEY_VALUE *)&lle_key, TRUE);
1478
1479 SMP_TRACE_DEBUG("%s-Save LTK as peer LTK key", __func__);
1480 ple_key.ediv = 0;
1481 memset(ple_key.rand, 0, BT_OCTET8_LEN);
1482 memcpy(ple_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
1483 ple_key.sec_level = p_cb->sec_level;
1484 ple_key.key_size = p_cb->loc_enc_size;
1485 btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PENC, (tBTM_LE_KEY_VALUE *)&ple_key, TRUE);
1486 }
1487
1488 /*******************************************************************************
1489 **
1490 ** Function smp_calculate_f5_mackey_and_long_term_key
1491 **
1492 ** Description The function calculates MacKey and LTK and saves them in CB.
1493 ** To calculate MacKey and LTK it calls smp_calc_f5(...).
1494 ** MacKey is used in dhkey calculation, LTK is used to encrypt
1495 ** the link.
1496 **
1497 ** Returns FALSE if out of resources, TRUE otherwise.
1498 **
1499 *******************************************************************************/
smp_calculate_f5_mackey_and_long_term_key(tSMP_CB * p_cb)1500 BOOLEAN smp_calculate_f5_mackey_and_long_term_key(tSMP_CB *p_cb)
1501 {
1502 UINT8 a[7];
1503 UINT8 b[7];
1504 UINT8 *p_na;
1505 UINT8 *p_nb;
1506
1507 SMP_TRACE_DEBUG("%s", __func__);
1508
1509 if (p_cb->role == HCI_ROLE_MASTER)
1510 {
1511 smp_collect_local_ble_address(a, p_cb);
1512 smp_collect_peer_ble_address(b, p_cb);
1513 p_na = p_cb->rand;
1514 p_nb = p_cb->rrand;
1515 }
1516 else
1517 {
1518 smp_collect_local_ble_address(b, p_cb);
1519 smp_collect_peer_ble_address(a, p_cb);
1520 p_na = p_cb->rrand;
1521 p_nb = p_cb->rand;
1522 }
1523
1524 if(!smp_calculate_f5(p_cb->dhkey, p_na, p_nb, a, b, p_cb->mac_key, p_cb->ltk))
1525 {
1526 SMP_TRACE_ERROR("%s failed", __func__);
1527 return FALSE;
1528 }
1529
1530 SMP_TRACE_EVENT ("%s is completed", __func__);
1531 return TRUE;
1532 }
1533
1534 /*******************************************************************************
1535 **
1536 ** Function smp_request_oob_data
1537 **
1538 ** Description Requests application to provide OOB data.
1539 **
1540 ** Returns TRUE - OOB data has to be provided by application
1541 ** FALSE - otherwise (unexpected)
1542 **
1543 *******************************************************************************/
smp_request_oob_data(tSMP_CB * p_cb)1544 BOOLEAN smp_request_oob_data(tSMP_CB *p_cb)
1545 {
1546 tSMP_OOB_DATA_TYPE req_oob_type = SMP_OOB_INVALID_TYPE;
1547
1548 SMP_TRACE_DEBUG("%s", __func__);
1549
1550 if (p_cb->peer_oob_flag == SMP_OOB_PRESENT && p_cb->loc_oob_flag == SMP_OOB_PRESENT)
1551 {
1552 /* both local and peer rcvd data OOB */
1553 req_oob_type = SMP_OOB_BOTH;
1554 }
1555 else if (p_cb->peer_oob_flag == SMP_OOB_PRESENT)
1556 {
1557 /* peer rcvd OOB local data, local didn't receive OOB peer data */
1558 req_oob_type = SMP_OOB_LOCAL;
1559 }
1560 else if (p_cb->loc_oob_flag == SMP_OOB_PRESENT)
1561 {
1562 req_oob_type = SMP_OOB_PEER;
1563 }
1564
1565 SMP_TRACE_DEBUG("req_oob_type = %d", req_oob_type);
1566
1567 if (req_oob_type == SMP_OOB_INVALID_TYPE)
1568 return FALSE;
1569
1570 p_cb->req_oob_type = req_oob_type;
1571 p_cb->cb_evt = SMP_SC_OOB_REQ_EVT;
1572 smp_sm_event(p_cb, SMP_TK_REQ_EVT, &req_oob_type);
1573
1574 return TRUE;
1575 }
1576
1577
1578 #endif
1579
1580