00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef __PANA_FSM_H__
00035 #define __PANA_FSM_H__
00036
00037 #include "framework.h"
00038 #include "pana_node.h"
00039 #include "pana_session.h"
00040 #include "pana_channel.h"
00041
00042 #define PANA_EVENT_DEBUG 0
00043
00044 typedef enum {
00045 PANA_ST_OFFLINE = 0,
00046 PANA_ST_DISCOVER,
00047 PANA_ST_STATEFUL_DISC,
00048 PANA_ST_OPEN,
00049 PANA_ST_SECOND_EAP,
00050 PANA_ST_WAIT_PAA,
00051 PANA_ST_WAIT_EAP,
00052 PANA_ST_WAIT_REAUTH_ANSWER,
00053 PANA_ST_WAIT_AUTH_ANSWER,
00054 PANA_ST_WAIT_SUCCESS_BIND_ANSWER,
00055 PANA_ST_SESSION_TERMINATION,
00056 PANA_ST_AUTH_FAILED
00057 } PANA_ST;
00058
00059 typedef enum {
00060 PANA_SIG_AUTH_USER = 0,
00061 PANA_SIG_REAUTH_USER,
00062 PANA_SIG_EAP_REQUEST,
00063 PANA_SIG_EAP_SUCCESS,
00064 PANA_SIG_EAP_FAILURE,
00065 PANA_SIG_EAP_REAUTH,
00066 PANA_SIG_REAUTH_PAA,
00067 PANA_SIG_TERMINATE_SESSION,
00068
00069 PANA_SIG_MARKER,
00070 } PANA_SIG;
00071
00072 typedef enum {
00073 PANA_RX_DISCOVER = PANA_SIG_MARKER,
00074 PANA_RX_START_REQUEST,
00075 PANA_RX_START_ANSWER,
00076 PANA_RX_START_ANSWER_SR,
00077 PANA_RX_AUTH_REQUEST,
00078 PANA_RX_AUTH_ANSWER,
00079 PANA_RX_REAUTH_REQUEST,
00080 PANA_RX_REAUTH_ANSWER,
00081 PANA_RX_BIND_FAILURE,
00082 PANA_RX_BIND_FIRST,
00083 PANA_RX_BIND_FINAL,
00084 PANA_RX_BIND_ANSWER,
00085 PANA_RX_BIND_ANSWER_2NDEAP,
00086 PANA_RX_TERM_REQUEST,
00087 PANA_RX_TERM_ANSWER,
00088
00089 PANA_RX_MARKER,
00090 } PANA_RX;
00091
00092 typedef enum {
00093 PANA_TM_SESSION_TIMEOUT = PANA_TID_SESSION + PANA_RX_MARKER,
00094 PANA_TM_DISCOVER_TIMEOUT = PANA_TID_DISC_RETRY + PANA_RX_MARKER,
00095 PANA_TM_STARTANSR_TIMEOUT = PANA_TID_PSA_RETRY + PANA_RX_MARKER,
00096 PANA_TM_BINDREQ_TIMEOUT = PANA_TID_PBR_RETRY + PANA_RX_MARKER,
00097 PANA_TM_REAUTHREQ_TIMEOUT = PANA_TID_PRAR_RETRY + PANA_RX_MARKER,
00098 PANA_TM_TERMREQ_TIMEOUT = PANA_TID_PTR_RETRY + PANA_RX_MARKER,
00099 PANA_TM_DISCONNECT = PANA_TID_DISCONNECT + PANA_RX_MARKER
00100 } PANA_TM;
00101
00102 template<class ARG>
00103 class PANA_EXPORT PANA_StateMachine : public AAA_StateMachineWithTimer<ARG>,
00104 AAA_Job
00105 {
00106 public:
00107 class FsmTxChannel : public PANA_SessionTxInterface {
00108 public:
00109 FsmTxChannel(PANA_UdpChannel &ch) : m_Udp(ch) { }
00110 virtual void Send(PANA_Session &s, PANA_Message &msg) {
00111 m_Udp.Send(s, msg);
00112 }
00113 virtual void GetLocalAddress(PANA_DeviceIdContainer &srcDevices) {
00114 m_Udp.GetLocalAddress(srcDevices);
00115 }
00116 private:
00117 PANA_UdpChannel &m_Udp;
00118 };
00119
00120 class FsmTimer : public PANA_SessionTimerInterface {
00121 public:
00122 FsmTimer(PANA_StateMachine &fsm) : m_fsm(fsm) { }
00123 void Schedule(PANA_TID id, ACE_UINT32 sec) {
00124 AAA_Event ev = AAA_Event(id + PANA_RX_MARKER);
00125 m_fsm.ScheduleTimer(ev, sec, 0, ev);
00126 }
00127 void Cancel(PANA_TID id) {
00128 AAA_Event ev = AAA_Event(id + PANA_RX_MARKER);
00129 m_fsm.CancelTimer(ev);
00130 }
00131 private:
00132 PANA_StateMachine &m_fsm;
00133 };
00134
00135 virtual void InitializeMsgMaps() = 0;
00136 virtual void FlushMsgMaps() = 0;
00137
00138 virtual void Notify(AAA_Event event) {
00139 if (! AAA_StateMachineWithTimer<ARG>::Running()) {
00140 return;
00141 }
00142 Wait();
00143 m_EventQueue.push_back(event);
00144 Schedule(this);
00145 }
00146 virtual void Receive(PANA_Message &msg) {
00147 m_MsgHandlers.Receive(msg);
00148 }
00149 virtual void Error(int err) {
00150 Stop();
00151 }
00152 virtual void Stop() {
00153 AAA_StateMachineWithTimer<ARG>::Stop();
00154 AAA_StateMachineWithTimer<ARG>::CancelAllTimer();
00155 while (m_GroupedJob.Job().BacklogSize()) {
00156 Wait();
00157 }
00158 m_GroupedJob.Job().Flush();
00159 }
00160 virtual void Abort() {
00161 Stop();
00162 actionArg.Reset();
00163 }
00164 FsmTxChannel &Channel() {
00165 return m_TxChannel;
00166 }
00167 FsmTimer &Timer() {
00168 return m_Timer;
00169 }
00170 AAA_GroupedJob &Job() {
00171 return m_GroupedJob.Job();
00172 }
00173 void Wait() {
00174 AAA_MutexScopeLock lock(m_FsmMutex);
00175 }
00176
00177 protected:
00178 PANA_StateMachine(ARG &arg,
00179 AAA_StateTable<ARG> &table,
00180 PANA_Node &node,
00181 PANA_UdpChannel &udp) :
00182 AAA_StateMachineWithTimer<ARG>(arg, table, *node.Task().reactor(), "PANA"),
00183 m_GroupedJob(AAA_GroupedJob::Create(node.Job(), (AAA_JobData*)this)),
00184 m_MsgHandlers(m_GroupedJob.Job()),
00185 m_TxChannel(udp),
00186 m_Timer(*this) {
00187 }
00188 virtual ~PANA_StateMachine() { }
00189
00190 virtual int Serve() {
00191 Wait();
00192 AAA_Event ev = m_EventQueue.front();
00193 DumpEvent(ev, "Pre-Event");
00194 try {
00195 AAA_StateMachineWithTimer<ARG>::Event(ev);
00196 }
00197 catch (PANA_Exception &e) {
00198 ACE_DEBUG((LM_ERROR, "(%P|%t) FSM Exception: [%d] %s\n",
00199 e.code(), e.description().data()));
00200 }
00201 catch (...) {
00202 ACE_DEBUG((LM_ERROR, "(%P|%t) Unknown exception in FSM\n"));
00203 }
00204 DumpEvent(ev, "Post-Event");
00205 m_EventQueue.pop_front();
00206 return (0);
00207 }
00208 virtual int Schedule(AAA_Job* job, size_t backlogSize = 1) {
00209 return m_GroupedJob->Schedule(job, backlogSize);
00210 }
00211 virtual void Timeout(AAA_Event ev) {
00212 Notify(ev);
00213 }
00214
00215 std::list<AAA_Event> m_EventQueue;
00216 AAA_JobHandle<AAA_GroupedJob> m_GroupedJob;
00217 PANA_SessionRxInterfaceTable<ARG> m_MsgHandlers;
00218 FsmTxChannel m_TxChannel;
00219 FsmTimer m_Timer;
00220 ACE_Mutex m_FsmMutex;
00221
00222 private:
00223 void DumpEvent(AAA_Event ev, char *prefix) {
00224 #if PANA_EVENT_DEBUG
00225 static char *evStrTable[] = { "PANA_SIG_AUTH_USER",
00226 "PANA_SIG_REAUTH_USER",
00227 "PANA_SIG_EAP_REQUEST",
00228 "PANA_SIG_EAP_SUCCESS",
00229 "PANA_SIG_EAP_FAILURE",
00230 "PANA_SIG_EAP_REAUTH",
00231 "PANA_SIG_REAUTH_PAA",
00232 "PANA_SIG_TERMINATE_SESSION",
00233 "PANA_RX_DISCOVER",
00234 "PANA_RX_START_REQUEST",
00235 "PANA_RX_START_ANSWER",
00236 "PANA_RX_START_ANSWER_SR",
00237 "PANA_RX_AUTH_REQUEST",
00238 "PANA_RX_AUTH_ANSWER",
00239 "PANA_RX_REAUTH_REQUEST",
00240 "PANA_RX_REAUTH_ANSWER",
00241 "PANA_RX_BIND_FAILURE",
00242 "PANA_RX_BIND_FIRST",
00243 "PANA_RX_BIND_FINAL",
00244 "PANA_RX_BIND_ANSWER",
00245 "PANA_RX_BIND_ANSWER_2NDEAP",
00246 "PANA_RX_TERM_REQUEST",
00247 "PANA_RX_TERM_ANSWER",
00248 "PANA_RX_MARKER",
00249 "PANA_TM_SESSION_TIMEOUT",
00250 "PANA_TM_DISCOVER_TIMEOUT",
00251 "PANA_TM_STARTANSR_TIMEOUT",
00252 "PANA_TM_BINDREQ_TIMEOUT",
00253 "PANA_TM_REAUTHREQ_TIMEOUT",
00254 "PANA_TM_TERMREQ_TIMEOUT",
00255 "PANA_TM_DISCONNECT"
00256 };
00257 static char *stStrTable[] = { "PANA_ST_OFFLINE",
00258 "PANA_ST_DISCOVER",
00259 "PANA_ST_STATEFUL_DISC",
00260 "PANA_ST_OPEN",
00261 "PANA_ST_SECOND_EAP",
00262 "PANA_ST_WAIT_PAA",
00263 "PANA_ST_WAIT_EAP",
00264 "PANA_ST_WAIT_REAUTH_ANSWER",
00265 "PANA_ST_WAIT_AUTH_ANSWER",
00266 "PANA_ST_WAIT_SUCCESS_BIND_ANSWER",
00267 "PANA_ST_SESSION_TERMINATION",
00268 "PANA_ST_AUTH_FAILED"
00269 };
00270 ACE_DEBUG((LM_INFO, "(%P|%t) EVENT DEBUG [state=%s, event=%s]: %s\n",
00271 stStrTable[state], evStrTable[ev], prefix));
00272 #endif
00273 }
00274 };
00275
00276 #endif // __PANA_FSM_H__