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 "); 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 ",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 ",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 ",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 };