OSDN Git Service

Send a response to an smp security request depending on the callback event
[android-x86/system-bt.git] / stack / smp / smp_api.c
1 /******************************************************************************
2  *
3  *  Copyright (C) 2008-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18
19 /******************************************************************************
20  *
21  *  This file contains the implementation of the SMP interface used by
22  *  applications that can run over an SMP.
23  *
24  ******************************************************************************/
25 #include <string.h>
26
27 #include "bt_target.h"
28 #include "bt_utils.h"
29 #include "stack_config.h"
30
31 #if SMP_INCLUDED == TRUE
32     #include "smp_int.h"
33     #include "smp_api.h"
34     #include "l2cdefs.h"
35     #include "l2c_int.h"
36     #include "btm_int.h"
37     #include "hcimsgs.h"
38
39     #include "btu.h"
40     #include "p_256_ecc_pp.h"
41
42 /*******************************************************************************
43 **
44 ** Function         SMP_Init
45 **
46 ** Description      This function initializes the SMP unit.
47 **
48 ** Returns          void
49 **
50 *******************************************************************************/
51 void SMP_Init(void)
52 {
53     memset(&smp_cb, 0, sizeof(tSMP_CB));
54     smp_cb.smp_rsp_timer_ent = alarm_new("smp.smp_rsp_timer_ent");
55     smp_cb.delayed_auth_timer_ent = alarm_new("smp.delayed_auth_timer_ent");
56
57 #if defined(SMP_INITIAL_TRACE_LEVEL)
58     smp_cb.trace_level = SMP_INITIAL_TRACE_LEVEL;
59 #else
60     smp_cb.trace_level = BT_TRACE_LEVEL_NONE;    /* No traces */
61 #endif
62     SMP_TRACE_EVENT ("%s", __FUNCTION__);
63
64     smp_l2cap_if_init();
65     /* initialization of P-256 parameters */
66     p_256_init_curve(KEY_LENGTH_DWORDS_P256);
67
68     /* Initialize failure case for certification */
69     smp_cb.cert_failure = stack_config_get_interface()->get_pts_smp_failure_case();
70     if (smp_cb.cert_failure)
71         SMP_TRACE_ERROR ("%s PTS FAILURE MODE IN EFFECT (CASE %d)", __func__, smp_cb.cert_failure);
72 }
73
74
75 /*******************************************************************************
76 **
77 ** Function         SMP_SetTraceLevel
78 **
79 ** Description      This function sets the trace level for SMP.  If called with
80 **                  a value of 0xFF, it simply returns the current trace level.
81 **
82 **                  Input Parameters:
83 **                      level:  The level to set the GATT tracing to:
84 **                      0xff-returns the current setting.
85 **                      0-turns off tracing.
86 **                      >= 1-Errors.
87 **                      >= 2-Warnings.
88 **                      >= 3-APIs.
89 **                      >= 4-Events.
90 **                      >= 5-Debug.
91 **
92 ** Returns          The new or current trace level
93 **
94 *******************************************************************************/
95 extern UINT8 SMP_SetTraceLevel (UINT8 new_level)
96 {
97     if (new_level != 0xFF)
98         smp_cb.trace_level = new_level;
99
100     return(smp_cb.trace_level);
101 }
102
103
104 /*******************************************************************************
105 **
106 ** Function         SMP_Register
107 **
108 ** Description      This function register for the SMP services callback.
109 **
110 ** Returns          void
111 **
112 *******************************************************************************/
113 BOOLEAN SMP_Register (tSMP_CALLBACK *p_cback)
114 {
115     SMP_TRACE_EVENT ("SMP_Register state=%d", smp_cb.state);
116
117     if (smp_cb.p_callback != NULL)
118     {
119         SMP_TRACE_ERROR ("SMP_Register: duplicate registration, overwrite it");
120     }
121     smp_cb.p_callback = p_cback;
122
123     return(TRUE);
124
125 }
126
127 /*******************************************************************************
128 **
129 ** Function         SMP_Pair
130 **
131 ** Description      This function call to perform a SMP pairing with peer device.
132 **                  Device support one SMP pairing at one time.
133 **
134 ** Parameters       bd_addr - peer device bd address.
135 **
136 ** Returns          None
137 **
138 *******************************************************************************/
139 tSMP_STATUS SMP_Pair (BD_ADDR bd_addr)
140 {
141     tSMP_CB   *p_cb = &smp_cb;
142     UINT8     status = SMP_PAIR_INTERNAL_ERR;
143
144     SMP_TRACE_EVENT ("%s state=%d br_state=%d flag=0x%x ",
145                       __FUNCTION__, p_cb->state, p_cb->br_state, p_cb->flags);
146     if (p_cb->state != SMP_STATE_IDLE || p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD ||
147         p_cb->smp_over_br)
148     {
149         /* pending security on going, reject this one */
150         return SMP_BUSY;
151     }
152     else
153     {
154         p_cb->flags = SMP_PAIR_FLAGS_WE_STARTED_DD;
155
156         memcpy (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN);
157
158         if (!L2CA_ConnectFixedChnl (L2CAP_SMP_CID, bd_addr))
159         {
160             SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.", __FUNCTION__);
161             smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status);
162             return status;
163         }
164
165         return SMP_STARTED;
166     }
167 }
168
169 /*******************************************************************************
170 **
171 ** Function         SMP_BR_PairWith
172 **
173 ** Description      This function is called to start a SMP pairing over BR/EDR.
174 **                  Device support one SMP pairing at one time.
175 **
176 ** Parameters       bd_addr - peer device bd address.
177 **
178 ** Returns          SMP_STARTED if pairing started, otherwise reason for failure.
179 **
180 *******************************************************************************/
181 tSMP_STATUS SMP_BR_PairWith (BD_ADDR bd_addr)
182 {
183     tSMP_CB   *p_cb = &smp_cb;
184     UINT8     status = SMP_PAIR_INTERNAL_ERR;
185
186     SMP_TRACE_EVENT ("%s state=%d br_state=%d flag=0x%x ",
187                       __func__, p_cb->state, p_cb->br_state, p_cb->flags);
188
189     if (p_cb->state != SMP_STATE_IDLE ||
190         p_cb->smp_over_br ||
191         p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD)
192     {
193         /* pending security on going, reject this one */
194         return SMP_BUSY;
195     }
196
197     p_cb->role = HCI_ROLE_MASTER;
198     p_cb->flags = SMP_PAIR_FLAGS_WE_STARTED_DD;
199     p_cb->smp_over_br = TRUE;
200
201     memcpy (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN);
202
203     if (!L2CA_ConnectFixedChnl (L2CAP_SMP_BR_CID, bd_addr))
204     {
205         SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.",__FUNCTION__);
206         smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &status);
207         return status;
208     }
209
210     return SMP_STARTED;
211 }
212
213 /*******************************************************************************
214 **
215 ** Function         SMP_PairCancel
216 **
217 ** Description      This function call to cancel a SMP pairing with peer device.
218 **
219 ** Parameters       bd_addr - peer device bd address.
220 **
221 ** Returns          TRUE - Pairining is cancelled
222 **
223 *******************************************************************************/
224 BOOLEAN SMP_PairCancel (BD_ADDR bd_addr)
225 {
226     tSMP_CB   *p_cb = &smp_cb;
227     UINT8     err_code = SMP_PAIR_FAIL_UNKNOWN;
228     BOOLEAN   status = FALSE;
229
230     // PTS SMP failure test cases
231     if (p_cb->cert_failure == 7)
232         err_code = SMP_PASSKEY_ENTRY_FAIL;
233     else if (p_cb->cert_failure == 8)
234         err_code = SMP_NUMERIC_COMPAR_FAIL;
235
236     BTM_TRACE_EVENT ("SMP_CancelPair state=%d flag=0x%x ", p_cb->state, p_cb->flags);
237     if ( (p_cb->state != SMP_STATE_IDLE)  &&
238          (!memcmp (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN)) )
239     {
240         p_cb->is_pair_cancel = TRUE;
241         SMP_TRACE_DEBUG("Cancel Pairing: set fail reason Unknown");
242         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &err_code);
243         status = TRUE;
244     }
245
246     return status;
247 }
248 /*******************************************************************************
249 **
250 ** Function         SMP_SecurityGrant
251 **
252 ** Description      This function is called to grant security process.
253 **
254 ** Parameters       bd_addr - peer device bd address.
255 **                  res     - result of the operation SMP_SUCCESS if success.
256 **                            Otherwise, SMP_REPEATED_ATTEMPTS is too many attempts.
257 **
258 ** Returns          None
259 **
260 *******************************************************************************/
261 void SMP_SecurityGrant(BD_ADDR bd_addr, UINT8 res)
262 {
263     SMP_TRACE_EVENT ("SMP_SecurityGrant ");
264
265     // If just showing consent dialog, send response
266     if (smp_cb.cb_evt == SMP_CONSENT_REQ_EVT)
267     {
268         // If JUSTWORKS, this is used to display the consent dialog
269         if (smp_cb.selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS)
270         {
271             if (res == SMP_SUCCESS)
272             {
273                 smp_sm_event(&smp_cb, SMP_SC_NC_OK_EVT, NULL);
274             }
275             else
276             {
277                 SMP_TRACE_WARNING("%s() - Consent dialog fails for JUSTWORKS",
278                                   __func__);
279                 /* send pairing failure */
280                 uint8_t failure = SMP_NUMERIC_COMPAR_FAIL;
281                 smp_sm_event(&smp_cb, SMP_AUTH_CMPL_EVT, &failure);
282             }
283         }
284         else if (smp_cb.selected_association_model == SMP_MODEL_ENCRYPTION_ONLY)
285         {
286             if (res == SMP_SUCCESS)
287             {
288                 smp_cb.sec_level = SMP_SEC_UNAUTHENTICATE;
289
290                 tSMP_KEY key;
291                 tSMP_INT_DATA smp_int_data;
292                 key.key_type = SMP_KEY_TYPE_TK;
293                 key.p_data = smp_cb.tk;
294                 smp_int_data.key = key;
295
296                 memset(smp_cb.tk, 0, BT_OCTET16_LEN);
297                 smp_sm_event(&smp_cb, SMP_KEY_READY_EVT, &smp_int_data);
298             }
299             else
300             {
301                 SMP_TRACE_WARNING("%s() - Consent dialog fails for ENCRYPTION_ONLY",
302                                   __func__);
303                 /* send pairing failure */
304                 uint8_t failure = SMP_NUMERIC_COMPAR_FAIL;
305                 smp_sm_event(&smp_cb, SMP_AUTH_CMPL_EVT, &failure);
306             }
307         }
308         return;
309     }
310
311     if (smp_cb.smp_over_br)
312     {
313         if (smp_cb.br_state != SMP_BR_STATE_WAIT_APP_RSP ||
314             smp_cb.cb_evt != SMP_SEC_REQUEST_EVT ||
315             memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN))
316         {
317             return;
318         }
319
320         /* clear the SMP_SEC_REQUEST_EVT event after get grant */
321         /* avoid generating duplicate pair request */
322         smp_cb.cb_evt = 0;
323         smp_br_state_machine_event(&smp_cb, SMP_BR_API_SEC_GRANT_EVT, &res);
324         return;
325     }
326
327     if (smp_cb.state != SMP_STATE_WAIT_APP_RSP ||
328         smp_cb.cb_evt != SMP_SEC_REQUEST_EVT ||
329         memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN))
330         return;
331     /* clear the SMP_SEC_REQUEST_EVT event after get grant */
332     /* avoid generate duplicate pair request */
333     smp_cb.cb_evt = 0;
334     smp_sm_event(&smp_cb, SMP_API_SEC_GRANT_EVT, &res);
335 }
336
337 /*******************************************************************************
338 **
339 ** Function         SMP_PasskeyReply
340 **
341 ** Description      This function is called after Security Manager submitted
342 **                  passkey request to the application.
343 **
344 ** Parameters:      bd_addr      - Address of the device for which passkey was requested
345 **                  res          - result of the operation SMP_SUCCESS if success
346 **                  passkey - numeric value in the range of
347 **                  BTM_MIN_PASSKEY_VAL(0) - BTM_MAX_PASSKEY_VAL(999999(0xF423F)).
348 **
349 *******************************************************************************/
350 void SMP_PasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey)
351 {
352     tSMP_CB *p_cb = & smp_cb;
353     UINT8   failure = SMP_PASSKEY_ENTRY_FAIL;
354
355     SMP_TRACE_EVENT ("SMP_PasskeyReply: Key: %d  Result:%d",
356                       passkey, res);
357
358     /* If timeout already expired or has been canceled, ignore the reply */
359     if (p_cb->cb_evt != SMP_PASSKEY_REQ_EVT)
360     {
361         SMP_TRACE_WARNING ("SMP_PasskeyReply() - Wrong State: %d", p_cb->state);
362         return;
363     }
364
365     if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0)
366     {
367         SMP_TRACE_ERROR ("SMP_PasskeyReply() - Wrong BD Addr");
368         return;
369     }
370
371     if (btm_find_dev (bd_addr) == NULL)
372     {
373         SMP_TRACE_ERROR ("SMP_PasskeyReply() - no dev CB");
374         return;
375     }
376
377     if (passkey > BTM_MAX_PASSKEY_VAL || res != SMP_SUCCESS)
378     {
379         SMP_TRACE_WARNING ("SMP_PasskeyReply() - Wrong key len: %d or passkey entry fail", passkey);
380         /* send pairing failure */
381         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
382
383     }
384     else if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_PASSKEY_ENT)
385     {
386         smp_sm_event(&smp_cb, SMP_SC_KEY_READY_EVT, &passkey);
387     }
388     else
389     {
390         smp_convert_string_to_tk(p_cb->tk, passkey);
391     }
392
393     return;
394 }
395
396 /*******************************************************************************
397 **
398 ** Function         SMP_ConfirmReply
399 **
400 ** Description      This function is called after Security Manager submitted
401 **                  numeric comparison request to the application.
402 **
403 ** Parameters:      bd_addr      - Address of the device with which numeric
404 **                                 comparison was requested
405 **                  res          - comparison result SMP_SUCCESS if success
406 **
407 *******************************************************************************/
408 void SMP_ConfirmReply (BD_ADDR bd_addr, UINT8 res)
409 {
410     tSMP_CB *p_cb = & smp_cb;
411     UINT8   failure = SMP_NUMERIC_COMPAR_FAIL;
412
413     SMP_TRACE_EVENT ("%s: Result:%d", __FUNCTION__, res);
414
415     /* If timeout already expired or has been canceled, ignore the reply */
416     if (p_cb->cb_evt != SMP_NC_REQ_EVT)
417     {
418         SMP_TRACE_WARNING ("%s() - Wrong State: %d", __FUNCTION__,p_cb->state);
419         return;
420     }
421
422     if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0)
423     {
424         SMP_TRACE_ERROR ("%s() - Wrong BD Addr",__FUNCTION__);
425         return;
426     }
427
428     if (btm_find_dev (bd_addr) == NULL)
429     {
430         SMP_TRACE_ERROR ("%s() - no dev CB",__FUNCTION__);
431         return;
432     }
433
434     if (res != SMP_SUCCESS)
435     {
436         SMP_TRACE_WARNING ("%s() - Numeric Comparison fails",__FUNCTION__);
437         /* send pairing failure */
438         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
439     }
440     else
441     {
442         smp_sm_event(p_cb, SMP_SC_NC_OK_EVT, NULL);
443     }
444 }
445
446 /*******************************************************************************
447 **
448 ** Function         SMP_OobDataReply
449 **
450 ** Description      This function is called to provide the OOB data for
451 **                  SMP in response to SMP_OOB_REQ_EVT
452 **
453 ** Parameters:      bd_addr     - Address of the peer device
454 **                  res         - result of the operation SMP_SUCCESS if success
455 **                  p_data      - simple pairing Randomizer  C.
456 **
457 *******************************************************************************/
458 void SMP_OobDataReply(BD_ADDR bd_addr, tSMP_STATUS res, UINT8 len, UINT8 *p_data)
459 {
460     tSMP_CB *p_cb = & smp_cb;
461     UINT8   failure = SMP_OOB_FAIL;
462     tSMP_KEY        key;
463
464     SMP_TRACE_EVENT ("%s State: %d  res:%d", __FUNCTION__, smp_cb.state, res);
465
466     /* If timeout already expired or has been canceled, ignore the reply */
467     if (p_cb->state != SMP_STATE_WAIT_APP_RSP || p_cb->cb_evt != SMP_OOB_REQ_EVT)
468         return;
469
470     if (res != SMP_SUCCESS || len == 0 || !p_data)
471     {
472         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
473     }
474     else
475     {
476         if (len > BT_OCTET16_LEN)
477             len = BT_OCTET16_LEN;
478
479         memcpy(p_cb->tk, p_data, len);
480
481         key.key_type    = SMP_KEY_TYPE_TK;
482         key.p_data      = p_cb->tk;
483
484         smp_sm_event(&smp_cb, SMP_KEY_READY_EVT, &key);
485     }
486 }
487
488 /*******************************************************************************
489 **
490 ** Function         SMP_SecureConnectionOobDataReply
491 **
492 ** Description      This function is called to provide the SC OOB data for
493 **                  SMP in response to SMP_SC_OOB_REQ_EVT
494 **
495 ** Parameters:      p_data      - pointer to the data
496 **
497 *******************************************************************************/
498 void SMP_SecureConnectionOobDataReply(UINT8 *p_data)
499 {
500     tSMP_CB  *p_cb = &smp_cb;
501
502     UINT8  failure = SMP_OOB_FAIL;
503     tSMP_SC_OOB_DATA  *p_oob = (tSMP_SC_OOB_DATA *) p_data;
504     if (!p_oob)
505     {
506         SMP_TRACE_ERROR("%s received no data",__FUNCTION__);
507         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
508         return;
509     }
510
511     SMP_TRACE_EVENT ("%s req_oob_type: %d, loc_oob_data.present: %d, "
512                        "peer_oob_data.present: %d",
513                        __FUNCTION__, p_cb->req_oob_type, p_oob->loc_oob_data.present,
514                        p_oob->peer_oob_data.present);
515
516     if (p_cb->state != SMP_STATE_WAIT_APP_RSP || p_cb->cb_evt != SMP_SC_OOB_REQ_EVT)
517         return;
518
519     BOOLEAN  data_missing = FALSE;
520     switch (p_cb->req_oob_type)
521     {
522         case SMP_OOB_PEER:
523             if (!p_oob->peer_oob_data.present)
524                 data_missing = TRUE;
525             break;
526         case SMP_OOB_LOCAL:
527             if (!p_oob->loc_oob_data.present)
528                 data_missing = TRUE;
529             break;
530         case SMP_OOB_BOTH:
531             if (!p_oob->loc_oob_data.present || !p_oob->peer_oob_data.present)
532                 data_missing = TRUE;
533             break;
534         default:
535             SMP_TRACE_EVENT ("Unexpected OOB data type requested. Fail OOB");
536             data_missing = TRUE;
537             break;
538     }
539
540     if (data_missing)
541     {
542         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
543         return;
544     }
545
546     p_cb->sc_oob_data = *p_oob;
547
548     smp_sm_event(&smp_cb, SMP_SC_OOB_DATA_EVT, p_data);
549 }
550
551 /*******************************************************************************
552 **
553 ** Function         SMP_Encrypt
554 **
555 ** Description      This function is called to encrypt the data with the specified
556 **                  key
557 **
558 ** Parameters:      key                 - Pointer to key key[0] conatins the MSB
559 **                  key_len             - key length
560 **                  plain_text          - Pointer to data to be encrypted
561 **                                        plain_text[0] conatins the MSB
562 **                  pt_len              - plain text length
563 **                  p_out                - output of the encrypted texts
564 **
565 **  Returns         Boolean - request is successful
566 *******************************************************************************/
567 BOOLEAN SMP_Encrypt (UINT8 *key, UINT8 key_len,
568                      UINT8 *plain_text, UINT8 pt_len,
569                      tSMP_ENC *p_out)
570
571 {
572     BOOLEAN status=FALSE;
573     status = smp_encrypt_data(key, key_len, plain_text, pt_len, p_out);
574     return status;
575 }
576
577 /*******************************************************************************
578 **
579 ** Function         SMP_KeypressNotification
580 **
581 ** Description      This function is called to notify Security Manager about Keypress Notification.
582 **
583 ** Parameters:     bd_addr      Address of the device to send keypress notification to
584 **                 value        Keypress notification parameter value
585 **
586 *******************************************************************************/
587 void SMP_KeypressNotification (BD_ADDR bd_addr, UINT8 value)
588 {
589     tSMP_CB   *p_cb = &smp_cb;
590
591     SMP_TRACE_EVENT ("%s: Value: %d", __FUNCTION__,value);
592
593     if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0)
594     {
595         SMP_TRACE_ERROR ("%s() - Wrong BD Addr",__FUNCTION__);
596         return;
597     }
598
599     if (btm_find_dev (bd_addr) == NULL)
600     {
601         SMP_TRACE_ERROR ("%s() - no dev CB",__FUNCTION__);
602         return;
603     }
604
605     /* Keypress Notification is used by a device with KeyboardOnly IO capabilities */
606     /* during the passkey entry protocol */
607     if (p_cb->local_io_capability != SMP_IO_CAP_IN)
608     {
609         SMP_TRACE_ERROR ("%s() - wrong local IO capabilities %d",
610                           __FUNCTION__, p_cb->local_io_capability);
611         return;
612     }
613
614     if (p_cb->selected_association_model != SMP_MODEL_SEC_CONN_PASSKEY_ENT)
615     {
616         SMP_TRACE_ERROR ("%s() - wrong protocol %d", __FUNCTION__,
617                          p_cb->selected_association_model);
618         return;
619     }
620
621     smp_sm_event(p_cb, SMP_KEYPRESS_NOTIFICATION_EVENT, &value);
622 }
623
624 /*******************************************************************************
625 **
626 ** Function         SMP_CreateLocalSecureConnectionsOobData
627 **
628 ** Description      This function is called to start creation of local SC OOB
629 **                  data set (tSMP_LOC_OOB_DATA).
630 **
631 ** Parameters:      bd_addr      - Address of the device to send OOB data block to
632 **
633 **  Returns         Boolean - TRUE: creation of local SC OOB data set started.
634 *******************************************************************************/
635 BOOLEAN SMP_CreateLocalSecureConnectionsOobData (tBLE_BD_ADDR *addr_to_send_to)
636 {
637     tSMP_CB *p_cb = &smp_cb;
638     UINT8   *bd_addr;
639
640     if (addr_to_send_to == NULL)
641     {
642         SMP_TRACE_ERROR ("%s addr_to_send_to is not provided",__FUNCTION__);
643         return FALSE;
644     }
645
646     bd_addr = addr_to_send_to->bda;
647
648     SMP_TRACE_EVENT ("%s addr type: %u,  BDA: %08x%04x,  state: %u, br_state: %u",
649                       __FUNCTION__, addr_to_send_to->type,
650                       (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8) + bd_addr[3],
651                       (bd_addr[4]<<8)+bd_addr[5],
652                       p_cb->state,
653                       p_cb->br_state);
654
655     if ((p_cb->state != SMP_STATE_IDLE) || (p_cb->smp_over_br))
656     {
657         SMP_TRACE_WARNING ("%s creation of local OOB data set "\
658             "starts only in IDLE state",__FUNCTION__);
659         return FALSE;
660     }
661
662     p_cb->sc_oob_data.loc_oob_data.addr_sent_to = *addr_to_send_to;
663     smp_sm_event(p_cb, SMP_CR_LOC_SC_OOB_DATA_EVT, NULL);
664
665     return TRUE;
666 }
667
668 #endif /* SMP_INCLUDED */