1 /******************************************************************************
2 *
3 * Copyright (C) 2014-2015 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 #include "bt_target.h"
20
21 #include <string.h>
22 #include "smp_int.h"
23
24 #if BLE_INCLUDED == TRUE
25
26 const char *const smp_br_state_name [SMP_BR_STATE_MAX+1] =
27 {
28 "SMP_BR_STATE_IDLE",
29 "SMP_BR_STATE_WAIT_APP_RSP",
30 "SMP_BR_STATE_PAIR_REQ_RSP",
31 "SMP_BR_STATE_BOND_PENDING",
32 "SMP_BR_STATE_OUT_OF_RANGE"
33 };
34
35 const char *const smp_br_event_name [SMP_BR_MAX_EVT] =
36 {
37 "BR_PAIRING_REQ_EVT",
38 "BR_PAIRING_RSP_EVT",
39 "BR_CONFIRM_EVT",
40 "BR_RAND_EVT",
41 "BR_PAIRING_FAILED_EVT",
42 "BR_ENCRPTION_INFO_EVT",
43 "BR_MASTER_ID_EVT",
44 "BR_ID_INFO_EVT",
45 "BR_ID_ADDR_EVT",
46 "BR_SIGN_INFO_EVT",
47 "BR_SECURITY_REQ_EVT",
48 "BR_PAIR_PUBLIC_KEY_EVT",
49 "BR_PAIR_DHKEY_CHCK_EVT",
50 "BR_PAIR_KEYPR_NOTIF_EVT",
51 "BR_KEY_READY_EVT",
52 "BR_ENCRYPTED_EVT",
53 "BR_L2CAP_CONN_EVT",
54 "BR_L2CAP_DISCONN_EVT",
55 "BR_KEYS_RSP_EVT",
56 "BR_API_SEC_GRANT_EVT",
57 "BR_TK_REQ_EVT",
58 "BR_AUTH_CMPL_EVT",
59 "BR_ENC_REQ_EVT",
60 "BR_BOND_REQ_EVT",
61 "BR_DISCARD_SEC_REQ_EVT",
62 "BR_OUT_OF_RANGE_EVT"
63 };
64
65 const char *smp_get_br_event_name(tSMP_BR_EVENT event);
66 const char *smp_get_br_state_name(tSMP_BR_STATE state);
67
68 #define SMP_BR_SM_IGNORE 0
69 #define SMP_BR_NUM_ACTIONS 2
70 #define SMP_BR_SME_NEXT_STATE 2
71 #define SMP_BR_SM_NUM_COLS 3
72 typedef const UINT8 (*tSMP_BR_SM_TBL)[SMP_BR_SM_NUM_COLS];
73
74 enum
75 {
76 SMP_SEND_PAIR_REQ,
77 SMP_BR_SEND_PAIR_RSP,
78 SMP_SEND_PAIR_FAIL,
79 SMP_SEND_ID_INFO,
80 SMP_BR_PROC_PAIR_CMD,
81 SMP_PROC_PAIR_FAIL,
82 SMP_PROC_ID_INFO,
83 SMP_PROC_ID_ADDR,
84 SMP_PROC_SRK_INFO,
85 SMP_BR_PROC_SEC_GRANT,
86 SMP_BR_PROC_SL_KEYS_RSP,
87 SMP_BR_KEY_DISTRIBUTION,
88 SMP_BR_PAIRING_COMPLETE,
89 SMP_SEND_APP_CBACK,
90 SMP_BR_CHECK_AUTH_REQ,
91 SMP_PAIR_TERMINATE,
92 SMP_IDLE_TERMINATE,
93 SMP_BR_SM_NO_ACTION
94 };
95
96 static const tSMP_ACT smp_br_sm_action[] =
97 {
98 smp_send_pair_req,
99 smp_br_send_pair_response,
100 smp_send_pair_fail,
101 smp_send_id_info,
102 smp_br_process_pairing_command,
103 smp_proc_pair_fail,
104 smp_proc_id_info,
105 smp_proc_id_addr,
106 smp_proc_srk_info,
107 smp_br_process_security_grant,
108 smp_br_process_slave_keys_response,
109 smp_br_select_next_key,
110 smp_br_pairing_complete,
111 smp_send_app_cback,
112 smp_br_check_authorization_request,
113 smp_pair_terminate,
114 smp_idle_terminate
115 };
116
117 static const UINT8 smp_br_all_table[][SMP_BR_SM_NUM_COLS] =
118 {
119 /* Event Action Next State */
120 /* BR_PAIRING_FAILED */ {SMP_PROC_PAIR_FAIL, SMP_BR_PAIRING_COMPLETE, SMP_BR_STATE_IDLE},
121 /* BR_AUTH_CMPL */ {SMP_SEND_PAIR_FAIL, SMP_BR_PAIRING_COMPLETE, SMP_BR_STATE_IDLE},
122 /* BR_L2CAP_DISCONN */ {SMP_PAIR_TERMINATE, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_IDLE}
123 };
124
125 /************ SMP Master FSM State/Event Indirection Table **************/
126 static const UINT8 smp_br_master_entry_map[][SMP_BR_STATE_MAX] =
127 {
128 /* br_state name: Idle WaitApp Pair Bond
129 Rsp ReqRsp Pend */
130 /* BR_PAIRING_REQ */ { 0, 0, 0, 0 },
131 /* BR_PAIRING_RSP */ { 0, 0, 1, 0 },
132 /* BR_CONFIRM */ { 0, 0, 0, 0 },
133 /* BR_RAND */ { 0, 0, 0, 0 },
134 /* BR_PAIRING_FAILED */ { 0, 0x81, 0x81, 0 },
135 /* BR_ENCRPTION_INFO */ { 0, 0, 0, 0 },
136 /* BR_MASTER_ID */ { 0, 0, 0, 0 },
137 /* BR_ID_INFO */ { 0, 0, 0, 1 },
138 /* BR_ID_ADDR */ { 0, 0, 0, 2 },
139 /* BR_SIGN_INFO */ { 0, 0, 0, 3 },
140 /* BR_SECURITY_REQ */ { 0, 0, 0, 0 },
141 /* BR_PAIR_PUBLIC_KEY_EVT */ { 0, 0, 0, 0 },
142 /* BR_PAIR_DHKEY_CHCK_EVT */ { 0, 0, 0, 0 },
143 /* BR_PAIR_KEYPR_NOTIF_EVT */ { 0, 0, 0, 0 },
144 /* BR_KEY_READY */ { 0, 0, 0, 0 },
145 /* BR_ENCRYPTED */ { 0, 0, 0, 0 },
146 /* BR_L2CAP_CONN */ { 1, 0, 0, 0 },
147 /* BR_L2CAP_DISCONN */ { 2, 0x83, 0x83, 0x83 },
148 /* BR_KEYS_RSP */ { 0, 1, 0, 0 },
149 /* BR_API_SEC_GRANT */ { 0, 0, 0, 0 },
150 /* BR_TK_REQ */ { 0, 0, 0, 0 },
151 /* BR_AUTH_CMPL */ { 0, 0x82, 0x82, 0x82 },
152 /* BR_ENC_REQ */ { 0, 0, 0, 0 },
153 /* BR_BOND_REQ */ { 0, 0, 2, 0 },
154 /* BR_DISCARD_SEC_REQ */ { 0, 0, 0, 0 }
155 };
156
157 static const UINT8 smp_br_master_idle_table[][SMP_BR_SM_NUM_COLS] =
158 {
159 /* Event Action Next State */
160 /* BR_L2CAP_CONN */ {SMP_SEND_APP_CBACK, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_WAIT_APP_RSP},
161 /* BR_L2CAP_DISCONN */ {SMP_IDLE_TERMINATE, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_IDLE}
162 };
163
164 static const UINT8 smp_br_master_wait_appln_response_table[][SMP_BR_SM_NUM_COLS] =
165 {
166 /* Event Action Next State */
167 /* BR_KEYS_RSP */{SMP_SEND_PAIR_REQ, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_PAIR_REQ_RSP}
168 };
169
170 static const UINT8 smp_br_master_pair_request_response_table [][SMP_BR_SM_NUM_COLS] =
171 {
172 /* Event Action Next State */
173 /* BR_PAIRING_RSP */ {SMP_BR_PROC_PAIR_CMD, SMP_BR_CHECK_AUTH_REQ, SMP_BR_STATE_PAIR_REQ_RSP},
174 /* BR_BOND_REQ */ {SMP_BR_SM_NO_ACTION, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_BOND_PENDING}
175 };
176
177 static const UINT8 smp_br_master_bond_pending_table[][SMP_BR_SM_NUM_COLS] =
178 {
179 /* Event Action Next State */
180 /* BR_ID_INFO */{SMP_PROC_ID_INFO, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_BOND_PENDING},
181 /* BR_ID_ADDR */{SMP_PROC_ID_ADDR, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_BOND_PENDING},
182 /* BR_SIGN_INFO */{SMP_PROC_SRK_INFO, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_BOND_PENDING}
183 };
184
185 static const UINT8 smp_br_slave_entry_map[][SMP_BR_STATE_MAX] =
186 {
187 /* br_state name: Idle WaitApp Pair Bond
188 Rsp ReqRsp Pend */
189 /* BR_PAIRING_REQ */ { 1, 0, 0, 0 },
190 /* BR_PAIRING_RSP */ { 0, 0, 0, 0 },
191 /* BR_CONFIRM */ { 0, 0, 0, 0 },
192 /* BR_RAND */ { 0, 0, 0, 0 },
193 /* BR_PAIRING_FAILED */ { 0, 0x81, 0x81, 0x81 },
194 /* BR_ENCRPTION_INFO */ { 0, 0, 0, 0 },
195 /* BR_MASTER_ID */ { 0, 0, 0, 0 },
196 /* BR_ID_INFO */ { 0, 0, 0, 1 },
197 /* BR_ID_ADDR */ { 0, 0, 0, 2 },
198 /* BR_SIGN_INFO */ { 0, 0, 0, 3 },
199 /* BR_SECURITY_REQ */ { 0, 0, 0, 0 },
200 /* BR_PAIR_PUBLIC_KEY_EVT */ { 0, 0, 0, 0 },
201 /* BR_PAIR_DHKEY_CHCK_EVT */ { 0, 0, 0, 0 },
202 /* BR_PAIR_KEYPR_NOTIF_EVT */ { 0, 0, 0, 0 },
203 /* BR_KEY_READY */ { 0, 0, 0, 0 },
204 /* BR_ENCRYPTED */ { 0, 0, 0, 0 },
205 /* BR_L2CAP_CONN */ { 0, 0, 0, 0 },
206 /* BR_L2CAP_DISCONN */ { 0, 0x83, 0x83, 0x83 },
207 /* BR_KEYS_RSP */ { 0, 2, 0, 0 },
208 /* BR_API_SEC_GRANT */ { 0, 1, 0, 0 },
209 /* BR_TK_REQ */ { 0, 0, 0, 0 },
210 /* BR_AUTH_CMPL */ { 0, 0x82, 0x82, 0x82 },
211 /* BR_ENC_REQ */ { 0, 0, 0, 0 },
212 /* BR_BOND_REQ */ { 0, 3, 0, 0 },
213 /* BR_DISCARD_SEC_REQ */ { 0, 0, 0, 0 }
214 };
215
216 static const UINT8 smp_br_slave_idle_table[][SMP_BR_SM_NUM_COLS] =
217 {
218 /* Event Action Next State */
219 /* BR_PAIRING_REQ */ {SMP_BR_PROC_PAIR_CMD, SMP_SEND_APP_CBACK, SMP_BR_STATE_WAIT_APP_RSP}
220 };
221
222 static const UINT8 smp_br_slave_wait_appln_response_table [][SMP_BR_SM_NUM_COLS] =
223 {
224 /* Event Action Next State */
225 /* BR_API_SEC_GRANT */ {SMP_BR_PROC_SEC_GRANT, SMP_SEND_APP_CBACK, SMP_BR_STATE_WAIT_APP_RSP},
226 /* BR_KEYS_RSP */{SMP_BR_PROC_SL_KEYS_RSP, SMP_BR_CHECK_AUTH_REQ,SMP_BR_STATE_WAIT_APP_RSP},
227 /* BR_BOND_REQ */ {SMP_BR_KEY_DISTRIBUTION, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_BOND_PENDING}
228 };
229
230 static const UINT8 smp_br_slave_bond_pending_table[][SMP_BR_SM_NUM_COLS] =
231 {
232 /* Event Action Next State */
233 /* BR_ID_INFO */ {SMP_PROC_ID_INFO, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_BOND_PENDING},
234 /* BR_ID_ADDR */ {SMP_PROC_ID_ADDR, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_BOND_PENDING},
235 /* BR_SIGN_INFO */ {SMP_PROC_SRK_INFO, SMP_BR_SM_NO_ACTION, SMP_BR_STATE_BOND_PENDING}
236 };
237
238 static const tSMP_BR_SM_TBL smp_br_state_table[][2] =
239 {
240 /* SMP_BR_STATE_IDLE */
241 {smp_br_master_idle_table, smp_br_slave_idle_table},
242
243 /* SMP_BR_STATE_WAIT_APP_RSP */
244 {smp_br_master_wait_appln_response_table, smp_br_slave_wait_appln_response_table},
245
246 /* SMP_BR_STATE_PAIR_REQ_RSP */
247 {smp_br_master_pair_request_response_table, NULL},
248
249 /* SMP_BR_STATE_BOND_PENDING */
250 {smp_br_master_bond_pending_table, smp_br_slave_bond_pending_table},
251 };
252
253 typedef const UINT8 (*tSMP_BR_ENTRY_TBL)[SMP_BR_STATE_MAX];
254
255 static const tSMP_BR_ENTRY_TBL smp_br_entry_table[] =
256 {
257 smp_br_master_entry_map,
258 smp_br_slave_entry_map
259 };
260
261 #define SMP_BR_ALL_TABLE_MASK 0x80
262
263 /*******************************************************************************
264 ** Function smp_set_br_state
265 ** Returns None
266 *******************************************************************************/
smp_set_br_state(tSMP_BR_STATE br_state)267 void smp_set_br_state(tSMP_BR_STATE br_state)
268 {
269 if (br_state < SMP_BR_STATE_MAX)
270 {
271 SMP_TRACE_DEBUG( "BR_State change: %s(%d) ==> %s(%d)",
272 smp_get_br_state_name(smp_cb.br_state), smp_cb.br_state,
273 smp_get_br_state_name(br_state), br_state );
274 smp_cb.br_state = br_state;
275 }
276 else
277 {
278 SMP_TRACE_DEBUG("%s invalid br_state =%d", __FUNCTION__,br_state );
279 }
280 }
281
282 /*******************************************************************************
283 ** Function smp_get_br_state
284 ** Returns The smp_br state
285 *******************************************************************************/
smp_get_br_state(void)286 tSMP_BR_STATE smp_get_br_state(void)
287 {
288 return smp_cb.br_state;
289 }
290
291 /*******************************************************************************
292 ** Function smp_get_br_state_name
293 ** Returns The smp_br state name.
294 *******************************************************************************/
smp_get_br_state_name(tSMP_BR_STATE br_state)295 const char *smp_get_br_state_name(tSMP_BR_STATE br_state)
296 {
297 const char *p_str = smp_br_state_name[SMP_BR_STATE_MAX];
298
299 if (br_state < SMP_BR_STATE_MAX)
300 p_str = smp_br_state_name[br_state];
301
302 return p_str;
303 }
304 /*******************************************************************************
305 ** Function smp_get_br_event_name
306 ** Returns The smp_br event name.
307 *******************************************************************************/
smp_get_br_event_name(tSMP_BR_EVENT event)308 const char * smp_get_br_event_name(tSMP_BR_EVENT event)
309 {
310 const char * p_str = smp_br_event_name[SMP_BR_MAX_EVT - 1];
311
312 if (event < SMP_BR_MAX_EVT)
313 {
314 p_str = smp_br_event_name[event- 1];
315 }
316 return p_str;
317 }
318
319 /*******************************************************************************
320 **
321 ** Function smp_br_state_machine_event
322 **
323 ** Description Handle events to the state machine. It looks up the entry
324 ** in the smp_br_entry_table array.
325 ** If it is a valid entry, it gets the state table.Set the next state,
326 ** if not NULL state. Execute the action function according to the
327 ** state table. If the state returned by action function is not NULL
328 ** state, adjust the new state to the returned state.
329 **
330 ** Returns void.
331 **
332 *******************************************************************************/
smp_br_state_machine_event(tSMP_CB * p_cb,tSMP_BR_EVENT event,void * p_data)333 void smp_br_state_machine_event(tSMP_CB *p_cb, tSMP_BR_EVENT event, void *p_data)
334 {
335 tSMP_BR_STATE curr_state = p_cb->br_state;
336 tSMP_BR_SM_TBL state_table;
337 UINT8 action, entry;
338 tSMP_BR_ENTRY_TBL entry_table = smp_br_entry_table[p_cb->role];
339
340 SMP_TRACE_EVENT("main %s", __func__);
341 if (curr_state >= SMP_BR_STATE_MAX)
342 {
343 SMP_TRACE_DEBUG( "Invalid br_state: %d", curr_state) ;
344 return;
345 }
346
347 SMP_TRACE_DEBUG( "SMP Role: %s State: [%s (%d)], Event: [%s (%d)]",
348 (p_cb->role == HCI_ROLE_SLAVE) ? "Slave" : "Master",
349 smp_get_br_state_name( p_cb->br_state),
350 p_cb->br_state, smp_get_br_event_name(event), event) ;
351
352 /* look up the state table for the current state */
353 /* lookup entry / w event & curr_state */
354 /* If entry is ignore, return.
355 * Otherwise, get state table (according to curr_state or all_state) */
356 if ((event <= SMP_BR_MAX_EVT) && ( (entry = entry_table[event - 1][curr_state])
357 != SMP_BR_SM_IGNORE ))
358 {
359 if (entry & SMP_BR_ALL_TABLE_MASK)
360 {
361 entry &= ~SMP_BR_ALL_TABLE_MASK;
362 state_table = smp_br_all_table;
363 }
364 else
365 {
366 state_table = smp_br_state_table[curr_state][p_cb->role];
367 }
368 }
369 else
370 {
371 SMP_TRACE_DEBUG( "Ignore event [%s (%d)] in state [%s (%d)]",
372 smp_get_br_event_name(event), event,
373 smp_get_br_state_name(curr_state), curr_state);
374 return;
375 }
376
377 /* Get possible next state from state table. */
378
379 smp_set_br_state(state_table[entry - 1][SMP_BR_SME_NEXT_STATE]);
380
381 /* If action is not ignore, clear param, exec action and get next state.
382 * The action function may set the Param for cback.
383 * Depending on param, call cback or free buffer. */
384 /* execute action functions */
385 for (UINT8 i = 0; i < SMP_BR_NUM_ACTIONS; i++)
386 {
387 if ((action = state_table[entry - 1][i]) != SMP_BR_SM_NO_ACTION)
388 {
389 (*smp_br_sm_action[action])(p_cb, (tSMP_INT_DATA *)p_data);
390 }
391 else
392 {
393 break;
394 }
395 }
396 SMP_TRACE_DEBUG( "result state = %s", smp_get_br_state_name( p_cb->br_state ) ) ;
397 }
398
399 #endif
400