| /****************************************************************************** |
| *(C) Copyright 2011 Marvell International Ltd. |
| * All Rights Reserved |
| ******************************************************************************/ |
| /*-------------------------------------------------------------------------------------------------------------------- |
| * ------------------------------------------------------------------------------------------------------------------- |
| * |
| * Filename: tcp_state_machine.c |
| * |
| * Description: The APIs to handle TCP state machine. |
| * |
| * History: |
| * Aug, 13 2012 - Haili Wang(hlw@marvell.com) Creation of file |
| * |
| * Notes: |
| * |
| ******************************************************************************/ |
| |
| #include "utlStateMachine.h" |
| #include "tcp_state_machine.h" |
| //#include "diag_state_machine.h" |
| #include "tcp_api.h" |
| //#include "diag_config.h" |
| #include "pxa_dbg.h" |
| |
| |
| #define STATE_START utlDEFINE_STATE_ID(1) |
| #define STATE_PREPARING utlDEFINE_STATE_ID(2) |
| #define STATE_ACCEPTING utlDEFINE_STATE_ID(3) |
| #define STATE_ACCEPTED utlDEFINE_STATE_ID(4) |
| |
| static utlStateMachine_P state_machine_p; |
| |
| static utlRelativeTime_T preparing_timeout = {1,0}; // 100ms |
| static unsigned int preparing_retries = 20; |
| |
| static int disconnecting = 1; //todo, is it a better machnism or not ? |
| |
| |
| utlEVENT_HANDLER(TCPReset, arg_p, va_arg_p) |
| { |
| F_ENTER(); |
| return utlSET_STATE(utlSTATE_ID_BOOT); |
| } |
| |
| utlEVENT_HANDLER(TCPStart, arg_p, va_arg_p) |
| { |
| F_ENTER(); |
| return utlSET_STATE(STATE_START); |
| } |
| |
| utlEVENT_HANDLER(TCPPrepareRetry, arg_p, va_arg_p) |
| { |
| F_ENTER(); |
| if(prepareListenSocket() < 0 ) |
| { |
| return utlSET_STATE(STATE_PREPARING); |
| } |
| else |
| { |
| return utlEVENT(EVENT_PREPARED); |
| } |
| |
| } |
| |
| utlEVENT_HANDLER(TCPPrepareGiveUp, arg_p, va_arg_p) |
| { |
| F_ENTER(); |
| return utlSET_STATE(utlSTATE_ID_BOOT); |
| } |
| |
| |
| utlEVENT_HANDLER(TCPPrepared, arg_p, va_arg_p) |
| { |
| |
| return utlSET_STATE(STATE_ACCEPTING); |
| } |
| |
| |
| utlEVENT_HANDLER(TCPAccepted, arg_p, va_arg_p) |
| { |
| |
| return utlSET_STATE(STATE_ACCEPTED); |
| } |
| |
| utlEVENT_HANDLER(TCPDisconnected, arg_p, va_arg_p) |
| { |
| |
| return utlSET_STATE(STATE_START); |
| } |
| |
| |
| utlEVENT_HANDLER(TCPEventDefault, arg_p, va_arg_p) |
| { |
| //do nothing if the event is not for such state. |
| return utlSUCCESS; |
| } |
| |
| /*------------------------------------*/ |
| utlSTATE_CHANGE_HANDLER(TCPEnterBoot, arg_p) |
| { |
| return utlSUCCESS; |
| } |
| |
| utlSTATE_CHANGE_HANDLER(TCPEnterStart, arg_p) |
| { |
| configInterface(); |
| createListenSocket(); |
| return utlSET_STATE(STATE_PREPARING); |
| } |
| |
| utlSTATE_CHANGE_HANDLER(TCPEnterPreparing, arg_p) |
| { |
| return utlSUCCESS; |
| } |
| |
| utlSTATE_CHANGE_HANDLER(TCPEnterAccepting, arg_p) |
| { |
| |
| return utlSUCCESS; |
| } |
| |
| utlSTATE_CHANGE_HANDLER(TCPLeaveAccepting, arg_p) |
| { |
| //close listen socket since we support only one client |
| closeListenSocket(); |
| return utlSUCCESS; |
| } |
| |
| utlSTATE_CHANGE_HANDLER(TCPEnterAccepted, arg_p) |
| { |
| #if 0 |
| LogcatTaskResume(diagTCPConnection); |
| #endif |
| disconnecting = 0; |
| #if 0 |
| DiagSwitch(); |
| #endif |
| |
| return utlSUCCESS; |
| } |
| |
| utlSTATE_CHANGE_HANDLER(TCPLeaveAccepted, arg_p) |
| { |
| disconnecting = 1; |
| #if 0 |
| DiagSwitch(); |
| #endif |
| closeDataSocket(); |
| #if 0 |
| LogcatTaskSuspend(diagTCPConnection); |
| #endif |
| return utlSUCCESS; |
| } |
| |
| static utlStateMachineEvent_T boot_events[] = { |
| utlDEFINE_EVENT_HANDLER_RESET(TCPReset), |
| utlDEFINE_EVENT_HANDLER_START(TCPStart), |
| utlDEFINE_EVENT_HANDLER_DEFAULT(TCPEventDefault), |
| utlDEFINE_EVENT_HANDLER_NULL() }; |
| |
| static utlStateMachineEvent_T start_events[] = { |
| utlDEFINE_EVENT_HANDLER_DEFAULT(TCPEventDefault), |
| utlDEFINE_EVENT_HANDLER_NULL() }; |
| |
| static utlStateMachineEvent_T preparing_events[] = { |
| utlDEFINE_EVENT_HANDLER_RETRY(TCPPrepareRetry), |
| utlDEFINE_EVENT_HANDLER_GIVE_UP(TCPPrepareGiveUp), |
| utlDEFINE_EVENT_HANDLER(EVENT_PREPARED, "TCP SOCKET PREPARED", TCPPrepared), |
| utlDEFINE_EVENT_HANDLER_DEFAULT(TCPEventDefault), |
| utlDEFINE_EVENT_HANDLER_NULL() }; |
| |
| static utlStateMachineEvent_T accpeting_events[] = { |
| utlDEFINE_EVENT_HANDLER(EVENT_ACCEPTED, "TCP SOCKET ACCEPTED", TCPAccepted), |
| utlDEFINE_EVENT_HANDLER_DEFAULT(TCPEventDefault), |
| utlDEFINE_EVENT_HANDLER_NULL() }; |
| |
| static utlStateMachineEvent_T accpeted_events[] = { |
| utlDEFINE_EVENT_HANDLER(EVENT_DISCONNECTED, "TCP SOCKET DISCONNECTED", TCPDisconnected), |
| utlDEFINE_EVENT_HANDLER_DEFAULT(TCPEventDefault), |
| utlDEFINE_EVENT_HANDLER_NULL() }; |
| |
| |
| static utlStateMachineState_T tcp_states[] ={ |
| utlDEFINE_STATE_BOOT( boot_events, NULL, NULL, TCPEnterBoot, NULL), |
| utlDEFINE_STATE(STATE_START, "TCP Start", start_events, NULL, NULL, TCPEnterStart, NULL), |
| utlDEFINE_STATE(STATE_PREPARING, "TCP Preparing", preparing_events, &preparing_timeout, &preparing_retries, TCPEnterPreparing, NULL), |
| utlDEFINE_STATE(STATE_ACCEPTING, "TCP Accepting", accpeting_events, NULL, NULL, TCPEnterAccepting, TCPLeaveAccepting), |
| utlDEFINE_STATE(STATE_ACCEPTED, "TCP Accepted", accpeted_events, NULL, NULL, TCPEnterAccepted, TCPLeaveAccepted), |
| utlDEFINE_STATE_NULL()}; |
| |
| |
| int InitTCPMachine(void) |
| { |
| F_ENTER(); |
| state_machine_p = utlOpenStateMachine("TCP Machine", 0, tcp_states, NULL); |
| F_LEAVE(); |
| if(state_machine_p) |
| return 0; |
| else |
| return -1; |
| } |
| |
| |
| int StartTCPMachine(void) |
| { |
| if(state_machine_p) |
| { |
| return utlStateMachineEvent(state_machine_p, utlSTATE_EVENT_ID_START, NULL); |
| } |
| return -1; |
| } |
| |
| |
| int StopTCPMachine(void) |
| { |
| if(state_machine_p) |
| { |
| return utlSetStateMachineState(state_machine_p, utlSTATE_ID_BOOT, NULL); |
| } |
| return -1; |
| } |
| |
| |
| int TCPAccept(void) |
| { |
| if(state_machine_p) |
| { |
| |
| return utlStateMachineEvent(state_machine_p, EVENT_ACCEPTED, NULL); |
| } |
| return -1; |
| } |
| |
| int TCPDisconnect(void) |
| { |
| if(state_machine_p) |
| { |
| |
| return utlStateMachineEvent(state_machine_p, EVENT_DISCONNECTED, NULL); |
| } |
| return -1; |
| } |
| |
| int TCPIsConnected(void) |
| { |
| if(state_machine_p) |
| { |
| return !disconnecting; |
| } |
| return 0; |
| } |
| |