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