smp_api.c revision e448862a47c08eb23185aaed574b39264f5005fc
1/*****************************************************************************
2**
3**  Name:           smp_api.c
4**
5**  Description:    This file contains the implementation of the SMP
6**                  interface used by applications that can run over an SMP.
7**
8**
9**  Copyright (c) 2008-2009, Broadcom Corp., All Rights Reserved.
10**  Broadcom Bluetooth Core. Proprietary and confidential.
11******************************************************************************/
12#include <string.h>
13
14#include "bt_target.h"
15#if SMP_INCLUDED == TRUE
16    #include "smp_int.h"
17    #include "smp_api.h"
18    #include "l2cdefs.h"
19    #include "l2c_int.h"
20    #include "btm_int.h"
21    #include "hcimsgs.h"
22
23    #include "btu.h"
24
25
26/*******************************************************************************
27**
28** Function         SMP_Init
29**
30** Description      This function initializes the SMP unit.
31**
32** Returns          void
33**
34*******************************************************************************/
35void SMP_Init(void)
36{
37
38    SMP_TRACE_EVENT0 ("SMP_Init");
39    memset(&smp_cb, 0, sizeof(tSMP_CB));
40
41#if defined(SMP_INITIAL_TRACE_LEVEL)
42    smp_cb.trace_level = SMP_INITIAL_TRACE_LEVEL;
43#else
44    smp_cb.trace_level = BT_TRACE_LEVEL_NONE;    /* No traces */
45#endif
46
47    smp_l2cap_if_init();
48}
49
50
51/*******************************************************************************
52**
53** Function         SMP_SetTraceLevel
54**
55** Description      This function sets the trace level for SMP.  If called with
56**                  a value of 0xFF, it simply returns the current trace level.
57**
58**                  Input Parameters:
59**                      level:  The level to set the GATT tracing to:
60**                      0xff-returns the current setting.
61**                      0-turns off tracing.
62**                      >= 1-Errors.
63**                      >= 2-Warnings.
64**                      >= 3-APIs.
65**                      >= 4-Events.
66**                      >= 5-Debug.
67**
68** Returns          The new or current trace level
69**
70*******************************************************************************/
71SMP_API extern UINT8 SMP_SetTraceLevel (UINT8 new_level)
72{
73    if (new_level != 0xFF)
74        smp_cb.trace_level = new_level;
75
76    return(smp_cb.trace_level);
77}
78
79
80/*******************************************************************************
81**
82** Function         SMP_Register
83**
84** Description      This function register for the SMP services callback.
85**
86** Returns          void
87**
88*******************************************************************************/
89BOOLEAN SMP_Register (tSMP_CALLBACK *p_cback)
90{
91    SMP_TRACE_EVENT1 ("SMP_Register state=%d", smp_cb.state);
92
93    if (smp_cb.p_callback != NULL)
94    {
95        SMP_TRACE_ERROR0 ("SMP_Register: duplicate registration, overwrite it");
96    }
97    smp_cb.p_callback = p_cback;
98
99    return(TRUE);
100
101}
102
103/*******************************************************************************
104**
105** Function         SMP_Pair
106**
107** Description      This function call to perform a SMP pairing with peer device.
108**                  Device support one SMP pairing at one time.
109**
110** Parameters       bd_addr - peer device bd address.
111**
112** Returns          None
113**
114*******************************************************************************/
115tSMP_STATUS SMP_Pair (BD_ADDR bd_addr)
116{
117    tSMP_CB   *p_cb = &smp_cb;
118    UINT8     status = SMP_PAIR_INTERNAL_ERR;
119
120    BTM_TRACE_EVENT2 ("SMP_Pair state=%d flag=0x%x ", p_cb->state, p_cb->flags);
121    if (p_cb->state != SMP_ST_IDLE || p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD)
122    {
123        /* pending security on going, reject this one */
124        return SMP_BUSY;
125    }
126    else
127    {
128        p_cb->flags = SMP_PAIR_FLAGS_WE_STARTED_DD;
129
130        memcpy (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN);
131
132        if (!L2CA_ConnectFixedChnl (L2CAP_SMP_CID, bd_addr))
133        {
134            SMP_TRACE_ERROR0("SMP_Pair: L2C connect fixed channel failed.");
135            smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status);
136            return status;
137        }
138
139        return SMP_STARTED;
140    }
141}
142
143
144/*******************************************************************************
145**
146** Function         SMP_PairCancel
147**
148** Description      This function call to cancel a SMP pairing with peer device.
149**
150** Parameters       bd_addr - peer device bd address.
151**
152** Returns          TRUE - Pairining is cancelled
153**
154*******************************************************************************/
155BOOLEAN SMP_PairCancel (BD_ADDR bd_addr)
156{
157    tSMP_CB   *p_cb = &smp_cb;
158    UINT8     err_code = SMP_PAIR_FAIL_UNKNOWN;
159    BOOLEAN   status = FALSE;
160
161    BTM_TRACE_EVENT2 ("SMP_CancelPair state=%d flag=0x%x ", p_cb->state, p_cb->flags);
162    if ( (p_cb->state != SMP_ST_IDLE)  &&
163         (!memcmp (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN)) )
164    {
165        p_cb->is_pair_cancel = TRUE;
166        SMP_TRACE_DEBUG0("Cancel Pairing: set fail reason Unknown");
167        smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &err_code);
168        status = TRUE;
169    }
170
171    return status;
172}
173/*******************************************************************************
174**
175** Function         SMP_SecurityGrant
176**
177** Description      This function is called to grant security process.
178**
179** Parameters       bd_addr - peer device bd address.
180**                  res     - result of the operation SMP_SUCCESS if success.
181**                            Otherwise, SMP_REPEATED_ATTEMPTS is too many attempts.
182**
183** Returns          None
184**
185*******************************************************************************/
186void SMP_SecurityGrant(BD_ADDR bd_addr, UINT8 res)
187{
188    SMP_TRACE_EVENT0 ("SMP_SecurityGrant ");
189    if (smp_cb.state != SMP_ST_WAIT_APP_RSP ||
190        smp_cb.cb_evt != SMP_SEC_REQUEST_EVT ||
191        memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN))
192        return;
193
194    smp_sm_event(&smp_cb, SMP_API_SEC_GRANT_EVT, &res);
195}
196
197/*******************************************************************************
198**
199** Function         SMP_PasskeyReply
200**
201** Description      This function is called after Security Manager submitted
202**                  passkey request to the application.
203**
204** Parameters:      bd_addr      - Address of the device for which passkey was requested
205**                  res          - result of the operation SMP_SUCCESS if success
206**                  passkey - numeric value in the range of
207**                  BTM_MIN_PASSKEY_VAL(0) - BTM_MAX_PASSKEY_VAL(999999(0xF423F)).
208**
209*******************************************************************************/
210void SMP_PasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey)
211{
212    tSMP_CB *p_cb = & smp_cb;
213    UINT8   failure = SMP_PASSKEY_ENTRY_FAIL;
214    tBTM_SEC_DEV_REC *p_dev_rec;
215
216    SMP_TRACE_EVENT2 ("SMP_PasskeyReply: Key: %d  Result:%d",
217                      passkey, res);
218
219    /* If timeout already expired or has been canceled, ignore the reply */
220    if (p_cb->cb_evt != SMP_PASSKEY_REQ_EVT)
221    {
222        SMP_TRACE_WARNING1 ("SMP_PasskeyReply() - Wrong State: %d", p_cb->state);
223        return;
224    }
225
226    if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0)
227    {
228        SMP_TRACE_ERROR0 ("SMP_PasskeyReply() - Wrong BD Addr");
229        return;
230    }
231
232    if ((p_dev_rec = btm_find_dev (bd_addr)) == NULL)
233    {
234        SMP_TRACE_ERROR0 ("SMP_PasskeyReply() - no dev CB");
235        return;
236    }
237
238
239    if (passkey > BTM_MAX_PASSKEY_VAL || res != SMP_SUCCESS)
240    {
241        SMP_TRACE_WARNING1 ("SMP_PasskeyReply() - Wrong key len: %d or passkey entry fail", passkey);
242        /* send pairing failure */
243        smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
244
245    }
246    else
247    {
248        smp_convert_string_to_tk(p_cb->tk, passkey);
249    }
250
251    return;
252}
253
254/*******************************************************************************
255**
256** Function         SMP_OobDataReply
257**
258** Description      This function is called to provide the OOB data for
259**                  SMP in response to SMP_OOB_REQ_EVT
260**
261** Parameters:      bd_addr     - Address of the peer device
262**                  res         - result of the operation SMP_SUCCESS if success
263**                  p_data      - simple pairing Randomizer  C.
264**
265*******************************************************************************/
266void SMP_OobDataReply(BD_ADDR bd_addr, tSMP_STATUS res, UINT8 len, UINT8 *p_data)
267{
268    tSMP_CB *p_cb = & smp_cb;
269    UINT8   failure = SMP_OOB_FAIL;
270    tSMP_KEY        key;
271
272    SMP_TRACE_EVENT2 ("SMP_OobDataReply State: %d  res:%d",
273                      smp_cb.state, res);
274
275    /* If timeout already expired or has been canceled, ignore the reply */
276    if (p_cb->state != SMP_ST_WAIT_APP_RSP || p_cb->cb_evt != SMP_OOB_REQ_EVT)
277        return;
278
279    if (res != SMP_SUCCESS || len == 0 || !p_data)
280    {
281        smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
282    }
283    else
284    {
285        if (len > BT_OCTET16_LEN)
286            len = BT_OCTET16_LEN;
287
288        memcpy(p_cb->tk, p_data, len);
289
290        key.key_type    = SMP_KEY_TYPE_TK;
291        key.p_data      = p_cb->tk;
292
293        smp_sm_event(&smp_cb, SMP_KEY_READY_EVT, &key);
294    }
295}
296
297/*******************************************************************************
298**
299** Function         SMP_Encrypt
300**
301** Description      This function is called to encrypt the data with the specified
302**                  key
303**
304** Parameters:      key                 - Pointer to key key[0] conatins the MSB
305**                  key_len             - key length
306**                  plain_text          - Pointer to data to be encrypted
307**                                        plain_text[0] conatins the MSB
308**                  pt_len              - plain text length
309**                  p_out                - output of the encrypted texts
310**
311**  Returns         Boolean - request is successful
312*******************************************************************************/
313BOOLEAN SMP_Encrypt (UINT8 *key, UINT8 key_len,
314                     UINT8 *plain_text, UINT8 pt_len,
315                     tSMP_ENC *p_out)
316
317{
318    BOOLEAN status=FALSE;
319    status = smp_encrypt_data(key, key_len, plain_text, pt_len, p_out);
320    return status;
321}
322#endif /* SMP_INCLUDED */
323
324
325