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