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