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