• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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