1 // .h
2 typedef int (*state_action)(int state, int event);
3
4 typedef struct state_trans{
5 int next_state;
6 state_action action;
7 } state_trans_t,*pstate_trans_t;
8
9 typedef struct fsm {
10 int curr_state;
11 int event_max;
12 pstate_trans_t *pptrans_tbl;
13 ak_mutex_t mutex;
14 }fsm_t;
15
16
17 int akp_fsm_ctor(fsm_t *this, pstate_trans_t *pptrans_tbl,int event_max);
18
19 int akp_fsm_dector(fsm_t *this);
20
21 int akp_fsm_on_event(fsm_t *this, int event);
22 int akp_fsm_get_curr_status(fsm_t *this);
23
24 // .c
25 int akp_fsm_ctor(fsm_t *this, pstate_trans_t *pptrans_tbl,int event_max)
26 {
27 this->curr_state = 0;
28 this->event_max = event_max;
29 this->pptrans_tbl = pptrans_tbl;
30 ak_thread_mutex_init(&(this->mutex),NULL);
31 }
32
33 int akp_fsm_dector(fsm_t *this)
34 {
35 this->pptrans_tbl = NULL;
36 ak_thread_mutex_destroy(&(this->mutex));
37 }
38
39 int akp_fsm_on_event(fsm_t *this, int event)
40 {
41 int ret = 0;
42
43 if(NULL == this->pptrans_tbl) {
44 ak_print_error_ex("[state]: pptrans_tbl is null,pl ctor fsm\n");
45 return -1;
46 }
47
48 ak_thread_mutex_lock(&(this->mutex));
49 int state = this->curr_state;
50
51 //ak_print_normal("[state]: max=%d state=%d event=%d tbl=0x%x\n",this->event_max,state,event,this->pptrans_tbl);
52 pstate_trans_t ptrans = (*(this->pptrans_tbl+(this->event_max*state+event)));
53 //ak_print_normal("ptrans %x\n",ptrans);
54 if(NULL != ptrans) {
55 this->curr_state = ptrans->next_state;
56 ret = ptrans->action(state,event); // must after change state
57 } // else ignore this case
58 else{
59 ak_print_warning("[fsm]: ignore this case: curr state=%d,event=%d\n",this->curr_state,event);
60 }
61 ak_thread_mutex_unlock(&(this->mutex));
62
63 return ret;
64 }
65
66 int akp_fsm_get_curr_status(fsm_t *this)
67 {
68 return (this->curr_state);
69 }
70
71
72 // use
73 static state_trans_t close2ready = {
74 WIFI_ST_READY, // next state
75 __open // action
76 };
77 static state_trans_t ready2work = {
78 WIFI_ST_WORK,
79 __start
80 };
81 static state_trans_t ready2close = {
82 WIFI_ST_CLOSED,
83 __close
84 };
85 static state_trans_t work2ready = {
86 WIFI_ST_READY,
87 __stop
88 };
89 static state_trans_t work2close = {
90 WIFI_ST_CLOSED,
91 __close
92 };
93 static state_trans_t ignore = {
94 WIFI_ST_CLOSED,
95 __close
96 };
97
98
99 static pstate_trans_t trans_tble[][WIFI_EV_MAX] = {
100 /*EV_OPEN*/ /*EV_START*/ /*EV_STOP*/ /*EV_CLOSE*/
101 /*ST_CLOSED*/ &close2ready, NULL, NULL, NULL,
102 /*ST_READY*/ NULL, &ready2work, NULL, &ready2close,
103 /*ST_WORK*/ NULL, NULL, &work2ready, &work2close
104 };