1 /******************************************************************************
2 *
3 * Copyright (C) 2003-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 #include "bt_target.h"
20
21 #if SMP_INCLUDED == TRUE
22
23 #include <string.h>
24 #include "smp_int.h"
25
26
27 const char * const smp_state_name [] =
28 {
29 "SMP_ST_IDLE",
30 "SMP_ST_WAIT_APP_RSP",
31 "SMP_ST_SEC_REQ_PENDING",
32 "SMP_ST_PAIR_REQ_RSP",
33 "SMP_ST_WAIT_CONFIRM",
34 "SMP_ST_CONFIRM",
35 "SMP_ST_RAND",
36 "SMP_ST_ENC_PENDING",
37 "SMP_ST_BOND_PENDING",
38 "SMP_ST_RELEASE_DELAY",
39 "SMP_ST_MAX"
40 };
41 const char * const smp_event_name [] =
42 {
43 "PAIRING_REQ_EVT",
44 "PAIRING_RSP_EVT",
45 "CONFIRM_EVT",
46 "RAND_EVT",
47 "PAIRING_FAILED_EVT",
48 "ENC_INFO_EVT",
49 "MASTER_ID_EVT",
50 "ID_INFO_EVT",
51 "ID_ADDR_EVT",
52 "SIGN_INFO_EVT",
53 "SECURITY_REQ_EVT",
54 "KEY_READY_EVT",
55 "ENCRYPTED_EVT",
56 "L2CAP_CONN_EVT",
57 "L2CAP_DISCONN_EVT",
58 "API_IO_RSP_EVT",
59 "API_SEC_GRANT_EVT",
60 "TK_REQ_EVT",
61 "AUTH_CMPL_EVT",
62 "ENC_REQ_EVT",
63 "BOND_REQ_EVT",
64 "DISCARD_SEC_REQ_EVT",
65 "RELEASE_DELAY_EVT",
66 "RELEASE_DELAY_TOUT_EVT",
67 "MAX_EVT"
68 };
69 const char * smp_get_event_name(tSMP_EVENT event);
70 const char * smp_get_state_name(tSMP_STATE state);
71
72 #define SMP_SM_IGNORE 0
73 #define SMP_NUM_ACTIONS 2
74 #define SMP_SME_NEXT_STATE 2
75 #define SMP_SM_NUM_COLS 3
76 typedef const UINT8 (*tSMP_SM_TBL)[SMP_SM_NUM_COLS];
77
78 enum
79 {
80 SMP_PROC_SEC_REQ,
81 SMP_SEND_PAIR_REQ,
82 SMP_SEND_PAIR_RSP,
83 SMP_SEND_CONFIRM,
84 SMP_SEND_PAIR_FAIL,
85 SMP_SEND_INIT,
86 SMP_SEND_SECU_INFO,
87 SMP_SEND_ID_INFO,
88 SMP_SEND_LTK_REPLY,
89 SMP_PROC_PAIR_CMD,
90 SMP_PROC_PAIR_FAIL,
91 SMP_PROC_CONFIRM,
92 SMP_PROC_INIT,
93 SMP_PROC_ENC_INFO,
94 SMP_PROC_MASTER_ID,
95 SMP_PROC_ID_INFO,
96 SMP_PROC_ID_ADDR,
97 SMP_PROC_SRK_INFO,
98 SMP_PROC_SEC_GRANT,
99 SMP_PROC_SL_KEY,
100 SMP_PROC_COMPARE,
101 SMP_PROC_IO_RSP,
102 SMP_GENERATE_COMPARE,
103 SMP_GENERATE_CONFIRM,
104 SMP_GENERATE_STK,
105 SMP_KEY_DISTRIBUTE,
106 SMP_START_ENC,
107 SMP_PAIRING_CMPL,
108 SMP_DECIDE_ASSO_MODEL,
109 SMP_SEND_APP_CBACK,
110 SMP_CHECK_AUTH_REQ,
111 SMP_PAIR_TERMINATE,
112 SMP_ENC_CMPL,
113 SMP_PROC_DISCARD,
114 SMP_PROC_REL_DELAY,
115 SMP_PROC_REL_DELAY_TOUT,
116 SMP_DELAY_TERMINATE,
117 SMP_IDLE_TERMINATE,
118 SMP_FAST_CONN_PARAM,
119 SMP_SM_NO_ACTION
120 };
121
122 static const tSMP_ACT smp_sm_action[] =
123 {
124 smp_proc_sec_req,
125 smp_send_pair_req,
126 smp_send_pair_rsp,
127 smp_send_confirm,
128 smp_send_pair_fail,
129 smp_send_init,
130 smp_send_enc_info,
131 smp_send_id_info,
132 smp_send_ltk_reply,
133 smp_proc_pair_cmd,
134 smp_proc_pair_fail,
135 smp_proc_confirm,
136 smp_proc_init,
137 smp_proc_enc_info,
138 smp_proc_master_id,
139 smp_proc_id_info,
140 smp_proc_id_addr,
141 smp_proc_srk_info,
142 smp_proc_sec_grant,
143 smp_proc_sl_key,
144 smp_proc_compare,
145 smp_proc_io_rsp,
146 smp_generate_compare,
147 smp_generate_confirm,
148 smp_generate_stk,
149 smp_key_distribution,
150 smp_start_enc,
151 smp_pairing_cmpl,
152 smp_decide_asso_model,
153 smp_send_app_cback,
154 smp_check_auth_req,
155 smp_pair_terminate,
156 smp_enc_cmpl,
157 smp_proc_discard,
158 smp_proc_release_delay,
159 smp_proc_release_delay_tout,
160 smp_delay_terminate,
161 smp_idle_terminate,
162 smp_fast_conn_param
163 };
164 /************ SMP Master FSM State/Event Indirection Table **************/
165 static const UINT8 smp_ma_entry_map[][SMP_ST_MAX] =
166 {
167 /* state name: Idle WaitApp SecReq Pair Wait Confirm Init Enc Bond Rel
168 Rsp Pend ReqRsp Cfm Pend Pend Delay */
169 /* PAIR_REQ */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
170 /* PAIR_RSP */{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
171 /* CONFIRM */{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
172 /* INIT */{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
173 /* PAIR_FAIL */{ 0, 0x81, 0, 0x81, 0x81,0x81, 0x81,0, 0, 0 },
174 /* ENC_INFO */{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 },
175 /* MASTER_ID */{ 0, 0, 0, 0, 0, 0, 0, 0, 4, 0 },
176 /* ID_INFO */{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 0 },
177 /* ID_ADDR */{ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0 },
178 /* SIGN_INFO */{ 0, 0, 0, 0, 0, 0, 0, 0, 3, 0 },
179 /* SEC_REQ */{ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
180 /* KEY_READY */{ 0, 3, 0, 3, 1, 0, 2, 1, 6, 0 },
181 /* ENC_CMPL */{ 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 },
182 /* L2C_CONN */{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
183 /* L2C_DISC */{ 3, 0x83, 0, 0x83, 0x83,0x83, 0x83,0x83, 0x83, 3 },
184 /* IO_RSP */{ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0 },
185 /* SEC_GRANT */{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
186 /* TK_REQ */{ 0, 0, 0, 2, 0, 0, 0, 0, 0, 0 },
187 /* AUTH_CMPL */{ 0, 0x82, 0, 0x82, 0x82,0x82, 0x82,0x82, 0x82, 0 },
188 /* ENC_REQ */{ 0, 4, 0, 0, 0, 0, 3, 0, 0, 0 },
189 /* BOND_REQ */{ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 },
190 /* DISCARD_SEC_REQ */{ 0, 5, 0, 0, 0, 0, 0, 3, 0, 0 },
191 /* RELEASE_DELAY */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
192 /* RELEASE_DELAY_TOUT */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 },
193 };
194
195 static const UINT8 smp_all_table[][SMP_SM_NUM_COLS] = {
196 /* Event Action Next State */
197 /* PAIR_FAIL */ {SMP_PROC_PAIR_FAIL, SMP_PROC_REL_DELAY_TOUT, SMP_ST_IDLE},
198 /* AUTH_CMPL */ {SMP_SEND_PAIR_FAIL, SMP_PAIRING_CMPL, SMP_ST_RELEASE_DELAY},
199 /* L2C_DISC */ {SMP_PAIR_TERMINATE, SMP_SM_NO_ACTION, SMP_ST_IDLE}
200 };
201
202 static const UINT8 smp_ma_idle_table[][SMP_SM_NUM_COLS] = {
203 /* Event Action Next State */
204 /* L2C_CONN */ {SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_ST_WAIT_APP_RSP},
205 /* SEC_REQ */ {SMP_PROC_SEC_REQ, SMP_SEND_APP_CBACK, SMP_ST_WAIT_APP_RSP},
206 /* L2C_DISC */ {SMP_IDLE_TERMINATE, SMP_SM_NO_ACTION, SMP_ST_IDLE}
207 };
208
209 static const UINT8 smp_ma_wait_app_rsp_table[][SMP_SM_NUM_COLS] = {
210 /* Event Action Next State */
211 /* SEC_GRANT */ { SMP_PROC_SEC_GRANT, SMP_SEND_APP_CBACK, SMP_ST_WAIT_APP_RSP},
212 /* IO_RSP */ { SMP_SEND_PAIR_REQ, SMP_FAST_CONN_PARAM, SMP_ST_PAIR_REQ_RSP},
213 /* KEY_READY */ { SMP_GENERATE_CONFIRM, SMP_SM_NO_ACTION, SMP_ST_WAIT_CONFIRM},/* TK ready */
214 /* ENC_REQ */ { SMP_START_ENC, SMP_FAST_CONN_PARAM, SMP_ST_ENC_PENDING},/* start enc mode setup */
215 /* DISCARD_SEC_REQ */ { SMP_PROC_DISCARD, SMP_SM_NO_ACTION, SMP_ST_IDLE}
216 };
217
218 static const UINT8 smp_ma_pair_req_rsp_table [][SMP_SM_NUM_COLS] = {
219 /* Event Action Next State */
220 /* PAIR_RSP */ { SMP_PROC_PAIR_CMD, SMP_DECIDE_ASSO_MODEL, SMP_ST_PAIR_REQ_RSP},
221 /* TK_REQ */ { SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_ST_WAIT_APP_RSP},
222 /* KEY_READY */{ SMP_GENERATE_CONFIRM, SMP_SM_NO_ACTION, SMP_ST_WAIT_CONFIRM} /* TK ready */
223 };
224
225 static const UINT8 smp_ma_wait_confirm_table[][SMP_SM_NUM_COLS] = {
226 /* Event Action Next State */
227 /* KEY_READY*/ {SMP_SEND_CONFIRM, SMP_SM_NO_ACTION, SMP_ST_CONFIRM}/* CONFIRM ready */
228 };
229
230 static const UINT8 smp_ma_confirm_table [][SMP_SM_NUM_COLS] = {
231 /* Event Action Next State */
232 /* CONFIRM */ { SMP_PROC_CONFIRM, SMP_SEND_INIT, SMP_ST_RAND}
233 };
234
235 static const UINT8 smp_ma_init_table [][SMP_SM_NUM_COLS] = {
236 /* Event Action Next State */
237 /* INIT */ { SMP_PROC_INIT, SMP_GENERATE_COMPARE, SMP_ST_RAND},
238 /* KEY_READY*/ { SMP_PROC_COMPARE, SMP_SM_NO_ACTION, SMP_ST_RAND}, /* Compare ready */
239 /* ENC_REQ */ { SMP_GENERATE_STK, SMP_SM_NO_ACTION, SMP_ST_ENC_PENDING}
240 };
241 static const UINT8 smp_ma_enc_pending_table[][SMP_SM_NUM_COLS] = {
242 /* Event Action Next State */
243 /* KEY_READY */ { SMP_START_ENC, SMP_SM_NO_ACTION, SMP_ST_ENC_PENDING}, /* STK ready */
244 /* ENCRYPTED */ { SMP_CHECK_AUTH_REQ, SMP_SM_NO_ACTION, SMP_ST_ENC_PENDING},
245 /* BOND_REQ */ { SMP_KEY_DISTRIBUTE, SMP_SM_NO_ACTION, SMP_ST_BOND_PENDING}
246 };
247 static const UINT8 smp_ma_bond_pending_table[][SMP_SM_NUM_COLS] = {
248 /* Event Action Next State */
249 /* ENC_INFO */ { SMP_PROC_ENC_INFO, SMP_SM_NO_ACTION, SMP_ST_BOND_PENDING},
250 /* ID_INFO */ { SMP_PROC_ID_INFO, SMP_SM_NO_ACTION, SMP_ST_BOND_PENDING},
251 /* SIGN_INFO*/ { SMP_PROC_SRK_INFO, SMP_SM_NO_ACTION, SMP_ST_BOND_PENDING},
252 /* MASTER_ID*/ { SMP_PROC_MASTER_ID, SMP_SM_NO_ACTION, SMP_ST_BOND_PENDING},
253 /* ID_ADDR */ { SMP_PROC_ID_ADDR, SMP_SM_NO_ACTION, SMP_ST_BOND_PENDING},
254 /* KEY_READY */ {SMP_SEND_SECU_INFO, SMP_SM_NO_ACTION, SMP_ST_BOND_PENDING} /* LTK ready */
255 };
256
257 static const UINT8 smp_ma_rel_delay_table[][SMP_SM_NUM_COLS] = {
258 /* Event Action Next State */
259 /* RELEASE_DELAY*/ {SMP_PROC_REL_DELAY, SMP_SM_NO_ACTION, SMP_ST_RELEASE_DELAY},
260 /* RELEASE_DELAY_TOUT*/ {SMP_PROC_REL_DELAY_TOUT, SMP_SM_NO_ACTION, SMP_ST_IDLE},
261 /* L2C_DISC*/ {SMP_DELAY_TERMINATE, SMP_SM_NO_ACTION, SMP_ST_IDLE}
262 };
263
264
265 /************ SMP Slave FSM State/Event Indirection Table **************/
266 static const UINT8 smp_sl_entry_map[][SMP_ST_MAX] =
267 {
268 /* state name: Idle Wait SecReq Pair Wait Confirm Init Enc Bond Rel
269 AppRsp Pend ReqRsp Cfm Pend Pend Delay */
270 /* PAIR_REQ */ { 2, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
271 /* PAIR_RSP */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
272 /* CONFIRM */ { 0, 4, 0, 1, 1, 0, 0, 0, 0, 0 },
273 /* INIT */ { 0, 0, 0, 0, 0, 1, 2, 0, 0, 0 },
274 /* PAIR_FAIL*/ { 0, 0x81, 0x81, 0x81, 0x81,0x81, 0x81,0x81, 0, 0 },
275 /* ENC_INFO */ { 0, 0, 0, 0, 0, 0, 0, 0, 3, 0 },
276 /* MASTER_ID*/ { 0, 0, 0, 0, 0, 0, 0, 0, 5, 0 },
277 /* ID_INFO */ { 0, 0, 0, 0, 0, 0, 0, 0, 4, 0 },
278 /* ID_ADDR */ { 0, 0, 0, 0, 0, 0, 0, 0, 6, 0 },
279 /* SIGN_INFO*/ { 0, 0, 0, 0, 0, 0, 0, 0, 2, 0 },
280 /* SEC_REQ */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
281
282 /* KEY_READY*/ { 0, 3, 0, 3, 2, 2, 1, 2, 1, 0 },
283 /* ENC_CMPL */ { 0, 0, 2, 0, 0, 0, 0, 3, 0, 0 },
284 /* L2C_CONN */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
285 /* L2C_DISC */ { 0, 0x83, 0x83, 0x83, 0x83,0x83, 0x83,0x83, 0x83, 2 },
286 /* IO_RSP */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
287 /* SEC_GRANT*/ { 0, 2, 0, 0, 0, 0, 0, 0, 0, 0 },
288
289 /* TK_REQ */ { 0, 0, 0, 2, 0, 0, 0, 0, 0, 0 },
290 /* AUTH_CMPL*/ { 0, 0x82, 0x82, 0x82, 0x82,0x82, 0x82,0x82, 0x82, 0 },
291 /* ENC_REQ */ { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
292 /* BOND_REQ */ { 0, 0, 0, 0, 0, 0, 0, 4, 0, 0 },
293 /* DISCARD_SEC_REQ */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
294 /* RELEASE_DELAY */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
295 /* RELEASE_DELAY_TOUT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 },
296 };
297
298 static const UINT8 smp_sl_idle_table[][SMP_SM_NUM_COLS] = {
299 /* Event Action Next State */
300 /* L2C_CONN */ {SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_ST_WAIT_APP_RSP},
301 /* PAIR_REQ */ {SMP_PROC_PAIR_CMD, SMP_SEND_APP_CBACK, SMP_ST_WAIT_APP_RSP}
302 };
303
304 static const UINT8 smp_sl_wait_app_rsp_table [][SMP_SM_NUM_COLS] = {
305 /* Event Action Next State */
306 /* IO_RSP */ {SMP_PROC_IO_RSP, SMP_SM_NO_ACTION, SMP_ST_PAIR_REQ_RSP},
307 /* SEC_GRANT */ {SMP_PROC_SEC_GRANT, SMP_SEND_APP_CBACK, SMP_ST_WAIT_APP_RSP},
308 /* KEY_READY */ {SMP_PROC_SL_KEY, SMP_SM_NO_ACTION, SMP_ST_WAIT_APP_RSP},/* TK ready */
309 /* CONFIRM */ {SMP_PROC_CONFIRM, SMP_SM_NO_ACTION, SMP_ST_CONFIRM}
310 };
311
312 static const UINT8 smp_sl_sec_request_table[][SMP_SM_NUM_COLS] = {
313 /* Event Action Next State */
314 /* PAIR_REQ */{SMP_PROC_PAIR_CMD, SMP_SEND_PAIR_RSP, SMP_ST_PAIR_REQ_RSP},
315 /* ENCRYPTED*/{SMP_ENC_CMPL, SMP_SM_NO_ACTION, SMP_ST_PAIR_REQ_RSP},
316 };
317
318 static const UINT8 smp_sl_pair_req_rsp_table[][SMP_SM_NUM_COLS] = {
319 /* Event Action Next State */
320 /* CONFIRM */ {SMP_PROC_CONFIRM, SMP_SM_NO_ACTION, SMP_ST_CONFIRM},
321 /* TK_REQ */ {SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_ST_WAIT_APP_RSP},
322 /* KEY_READY */{SMP_PROC_SL_KEY, SMP_SM_NO_ACTION, SMP_ST_PAIR_REQ_RSP} /* TK/Confirm ready */
323
324 };
325
326 static const UINT8 smp_sl_wait_confirm_table[][SMP_SM_NUM_COLS] = {
327 /* Event Action Next State */
328 /* CONFIRM */ {SMP_PROC_CONFIRM, SMP_SEND_CONFIRM, SMP_ST_CONFIRM},
329 /* KEY_READY*/ {SMP_PROC_SL_KEY, SMP_SM_NO_ACTION, SMP_ST_WAIT_CONFIRM}
330 };
331 static const UINT8 smp_sl_confirm_table [][SMP_SM_NUM_COLS] = {
332 /* Event Action Next State */
333 /* INIT_EVT */{ SMP_PROC_INIT, SMP_GENERATE_COMPARE, SMP_ST_RAND},
334 /* KEY_READY*/ {SMP_PROC_SL_KEY, SMP_SM_NO_ACTION, SMP_ST_CONFIRM} /* TK/Confirm ready */
335 };
336 static const UINT8 smp_sl_init_table [][SMP_SM_NUM_COLS] = {
337 /* Event Action Next State */
338 /* KEY_READY */ {SMP_PROC_COMPARE, SMP_SM_NO_ACTION, SMP_ST_RAND}, /* compare match */
339 /* INIT_EVT */ {SMP_SEND_INIT, SMP_SM_NO_ACTION, SMP_ST_ENC_PENDING}
340 };
341 static const UINT8 smp_sl_enc_pending_table[][SMP_SM_NUM_COLS] = {
342 /* Event Action Next State */
343 /* ENC_REQ */ {SMP_GENERATE_STK, SMP_SM_NO_ACTION, SMP_ST_ENC_PENDING},
344 /* KEY_READY */ {SMP_SEND_LTK_REPLY, SMP_SM_NO_ACTION, SMP_ST_ENC_PENDING},/* STK ready */
345 /* ENCRYPTED */ {SMP_CHECK_AUTH_REQ, SMP_SM_NO_ACTION, SMP_ST_ENC_PENDING},
346 /* BOND_REQ */ {SMP_KEY_DISTRIBUTE, SMP_SM_NO_ACTION, SMP_ST_BOND_PENDING}
347 };
348 static const UINT8 smp_sl_bond_pending_table[][SMP_SM_NUM_COLS] = {
349 /* Event Action Next State */
350 /* KEY_READY */ {SMP_SEND_SECU_INFO, SMP_SM_NO_ACTION, SMP_ST_BOND_PENDING}, /* LTK ready */
351 /* SIGN_INFO */ {SMP_PROC_SRK_INFO, SMP_SM_NO_ACTION, SMP_ST_BOND_PENDING}, /* rev SRK */
352 /* ENC_INFO */ { SMP_PROC_ENC_INFO, SMP_SM_NO_ACTION, SMP_ST_BOND_PENDING},
353 /* ID_INFO */ { SMP_PROC_ID_INFO, SMP_SM_NO_ACTION, SMP_ST_BOND_PENDING},
354 /* MASTER_ID*/ { SMP_PROC_MASTER_ID, SMP_SM_NO_ACTION, SMP_ST_BOND_PENDING},
355 /* ID_ADDR */ { SMP_PROC_ID_ADDR, SMP_SM_NO_ACTION, SMP_ST_BOND_PENDING}
356
357 };
358
359 static const UINT8 smp_sl_rel_delay_table[][SMP_SM_NUM_COLS] = {
360 /* Event Action Next State */
361 /* RELEASE_DELAY*/ {SMP_PROC_REL_DELAY, SMP_SM_NO_ACTION, SMP_ST_RELEASE_DELAY},
362 /* RELEASE_DELAY_TOUT*/ {SMP_PROC_REL_DELAY_TOUT, SMP_SM_NO_ACTION, SMP_ST_IDLE}
363 };
364
365 static const tSMP_SM_TBL smp_state_table[][2] = {
366 {smp_ma_idle_table, smp_sl_idle_table}, /* SMP_ST_IDLE*/
367 {smp_ma_wait_app_rsp_table, smp_sl_wait_app_rsp_table}, /* SMP_ST_WAIT_APP_RSP */
368 {NULL, smp_sl_sec_request_table}, /* SMP_ST_SEC_REQ_PENDING */
369 {smp_ma_pair_req_rsp_table, smp_sl_pair_req_rsp_table}, /* SMP_ST_PAIR_REQ_RSP */
370 {smp_ma_wait_confirm_table, smp_sl_wait_confirm_table}, /* SMP_ST_WAIT_CONFIRM */
371 {smp_ma_confirm_table, smp_sl_confirm_table}, /* SMP_ST_CONFIRM */
372 {smp_ma_init_table, smp_sl_init_table}, /* SMP_ST_RAND */
373 {smp_ma_enc_pending_table, smp_sl_enc_pending_table}, /* SMP_ST_ENC_PENDING */
374 {smp_ma_bond_pending_table, smp_sl_bond_pending_table}, /* SMP_ST_BOND_PENDING */
375 {smp_ma_rel_delay_table, smp_sl_rel_delay_table} /* SMP_ST_RELEASE_DELAY */
376 };
377
378 typedef const UINT8 (*tSMP_ENTRY_TBL)[SMP_ST_MAX];
379 static const tSMP_ENTRY_TBL smp_entry_table[] ={
380 smp_ma_entry_map,
381 smp_sl_entry_map
382 };
383
384 #if SMP_DYNAMIC_MEMORY == FALSE
385 tSMP_CB smp_cb;
386 #endif
387 #define SMP_ALL_TBL_MASK 0x80
388
389
390 /*******************************************************************************
391 ** Function smp_set_state
392 ** Returns None
393 *******************************************************************************/
smp_set_state(tSMP_STATE state)394 void smp_set_state(tSMP_STATE state)
395 {
396 if (state < SMP_ST_MAX)
397 {
398 SMP_TRACE_DEBUG( "State change: %s(%d) ==> %s(%d)",
399 smp_get_state_name(smp_cb.state), smp_cb.state,
400 smp_get_state_name(state), state );
401 smp_cb.state = state;
402 }
403 else
404 {
405 SMP_TRACE_DEBUG("smp_set_state invalid state =%d", state );
406 }
407 }
408
409 /*******************************************************************************
410 ** Function smp_get_state
411 ** Returns The smp state
412 *******************************************************************************/
smp_get_state(void)413 tSMP_STATE smp_get_state(void)
414 {
415 return smp_cb.state;
416 }
417
418
419 /*******************************************************************************
420 **
421 ** Function smp_sm_event
422 **
423 ** Description Handle events to the state machine. It looks up the entry
424 ** in the smp_entry_table array.
425 ** If it is a valid entry, it gets the state table.Set the next state,
426 ** if not NULL state.Execute the action function according to the
427 ** state table. If the state returned by action function is not NULL
428 ** state, adjust the new state to the returned state.If (api_evt != MAX),
429 ** call callback function.
430 **
431 ** Returns void.
432 **
433 *******************************************************************************/
smp_sm_event(tSMP_CB * p_cb,tSMP_EVENT event,void * p_data)434 void smp_sm_event(tSMP_CB *p_cb, tSMP_EVENT event, void *p_data)
435 {
436 UINT8 curr_state = p_cb->state;
437 tSMP_SM_TBL state_table;
438 UINT8 action, entry, i;
439 tSMP_ENTRY_TBL entry_table = smp_entry_table[p_cb->role];
440
441 SMP_TRACE_EVENT("main smp_sm_event");
442 if (curr_state >= SMP_ST_MAX)
443 {
444 SMP_TRACE_DEBUG( "Invalid state: %d", curr_state) ;
445 return;
446 }
447
448 SMP_TRACE_DEBUG( "SMP Role: %s State: [%s (%d)], Event: [%s (%d)]",\
449 (p_cb->role == 0x01) ?"Slave" : "Master", smp_get_state_name( p_cb->state),
450 p_cb->state, smp_get_event_name(event), event) ;
451
452 /* look up the state table for the current state */
453 /* lookup entry /w event & curr_state */
454 /* If entry is ignore, return.
455 * Otherwise, get state table (according to curr_state or all_state) */
456 if ((event < SMP_MAX_EVT) && ( (entry = entry_table[event - 1][curr_state]) != SMP_SM_IGNORE ))
457 {
458 if (entry & SMP_ALL_TBL_MASK)
459 {
460 entry &= ~SMP_ALL_TBL_MASK;
461 state_table = smp_all_table;
462 }
463 else
464 state_table = smp_state_table[curr_state][p_cb->role];
465 }
466 else
467 {
468 SMP_TRACE_DEBUG( "Ignore event [%s (%d)] in state [%s (%d)]",
469 smp_get_event_name(event), event, smp_get_state_name(curr_state), curr_state);
470 return;
471 }
472
473 /* Get possible next state from state table. */
474
475 smp_set_state(state_table[entry-1][SMP_SME_NEXT_STATE]);
476
477 /* If action is not ignore, clear param, exec action and get next state.
478 * The action function may set the Param for cback.
479 * Depending on param, call cback or free buffer. */
480 /* execute action */
481 /* execute action functions */
482 for (i = 0; i < SMP_NUM_ACTIONS; i++)
483 {
484 if ((action = state_table[entry-1][i]) != SMP_SM_NO_ACTION)
485 {
486 (*smp_sm_action[action])(p_cb, (tSMP_INT_DATA *)p_data);
487 }
488 else
489 {
490 break;
491 }
492 }
493 SMP_TRACE_DEBUG( "result state = %s", smp_get_state_name( p_cb->state ) ) ;
494 }
495
496
497 /*******************************************************************************
498 ** Function smp_get_state_name
499 ** Returns The smp state name.
500 *******************************************************************************/
smp_get_state_name(tSMP_STATE state)501 const char * smp_get_state_name(tSMP_STATE state)
502 {
503 const char * p_str = smp_state_name[SMP_ST_MAX];
504
505 if (state < SMP_ST_MAX)
506 {
507 p_str = smp_state_name[state];
508 }
509 return p_str;
510 }
511 /*******************************************************************************
512 ** Function smp_get_event_name
513 ** Returns The smp event name.
514 *******************************************************************************/
smp_get_event_name(tSMP_EVENT event)515 const char * smp_get_event_name(tSMP_EVENT event)
516 {
517 const char * p_str = smp_event_name[SMP_MAX_EVT - 1];
518
519 if (event < SMP_MAX_EVT)
520 {
521 p_str = smp_event_name[event- 1];
522 }
523 return p_str;
524 }
525 #endif
526
527