An overview of the structure of the ESROP module appears in Figure 2.3.
The USER-IN Interface is the module that deals with ESROP action primitives. userin.c contains the source to this module.
The USER-OUT Interface is the module that deals with ESROP event primitives. userout.c contains the source to this module.
The SAP Map deals with multiplexing of ESROP-Users. esrop_sap.c contains the functions related to this module.
The ESROP Finite State Machine is the heart of ESROP. invokact.c/invact2.c, perfact.c/perfact2.c, clinvktd.c/clinvtd2.c, and clperftd.c/clpertd2.c contain the functions related to this module.
The PDU Formatter deals with encoding of information into PDUs. The pduout.c contains the source to this module.
The PDU Parser deals with decoding of information from PDUs. The pduin.c contains the source to this module.
ESROP has the capability of supporting communication with several entities in the layer above. This is accomplished through the concept of an ESROP-SAP. struct SapInfo is the basic structure used. The SapInfo structure associates a series of event primitives with an ESROP_SapSel.
SapInfo structures are maintained as doubly linked lists. SapInfoSeq contains pointers to the first and last SapInfo structures. ESROP_init creates a pool of ESROP-SAPS SapInfo. ESROP_SAPS is a configuration parameter that specifies the maximum number of ESRO-SAPs supported by ESROP.
Each SapInfo structure maintains a list of active invocations associated with it. The InvokeInfoSeq field of SapInfo structure is the head of this list.
The ESROP Finite State Machine (FSM) is the heart of ESROP. Figure 2.4 ESROP Finite State Machine is a high level diagram of ESROP state machine.
The inputs to the FSM are:
/* User Action Primitives */
#define lsfsm_EvtInvokeReq2
#define lsfsm_EvtErrorReq3
#define lsfsm_EvtResultReq4
#define lsfsm_EvtPduInputInd5
/* In PDU Indications */
#define lsfsm_EvtPduInvoke6
#define lsfsm_EvtPduResult7
#define lsfsm_EvtPduAck8
#define lsfsm_EvtPduFailure9
#define lsfsm_EvtTimerInd10
/* Timer Indications */
#define lsfsm_EvtInvokePduRetranTimer11
#define lsfsm_EvtResultPduRetranTimer12
#define lsfsm_EvtRefNuTimer13
#define lsfsm_EvtInactivityTimer14
#define lsfsm_EvtLastTimer15
#define lsfsm_EvtPerfNoResponseTimer16
Each of these events have some information associated with them:
typedef union FSM_EventInfo {
struct InvokeReq {
ESRO_SapSel remESROSap;
T_SapSel *remTsap;
N_SapAddr *remNsap;
ESROP_OperationValue opValue;
ESROP_EncodingType encodingType;
DU_View parameter;
} invokeReq;
struct ResultReq {
Bool isResultNotError;
ESROP_EncodingType encodingType;
DU_View parameter;
} resultReq;
struct ErrorReq {
Bool isResultNotError;
ESROP_EncodingType encodingType;
ESROP_ErrorValue errorValue;
DU_View parameter;
} errorReq;
struct InternalInfo {
Int expiredTimerName;
} internalInfo;
struct TmrInfo {
Int name;7%)
long subscript;
Int datum;)
} tmrInfo;
} FSM_EventInfo;
Each time one of these events is observed by the USER-IN Interface module, by the ESRO-PDU PARSER module, or by the Timer Management Module, the event code and the information associated with it are passed to the event processor (esropfsm).
PUBLIC Int FSM_runMachine (FSM_Machine *machine, FSM_EventId evtId)
FSM_runMachine contains the information regarding the current state of an ESROS operation. evtId is an event ID corresponding to the event that has been observed.
Each state has an entry and an exit functions associated to it.
typedef struct FSM_State {
Int (*entry)(FSM_Machine *machine,
FSM_UserData *userData,
FSM_EventId evtId);
Int (*exit)(FSM_Machine *machine,
FSM_UserData *userData,
FSM_EventId evtId);
struct FSM_Trans *trans;
String name;
} FSM_State;
Using the information regarding the current state and the observed event, FSM_runMachine looks into the link list of transitions and finds the next state corresponding to the observed event. The transitions are a link list of:
typedef struct FSM_Trans {
FSM_EventId evtId;
Bool (*predicate) (FSM_Machine *machine,
FSM_UserData *userData,
FSM_EventId evtId);
Int (*action)(FSM_Machine *machine,
FSM_UserData *userData,
FSM_EventId evtId);
FSM_State *nextStatePtr;
String name;
} FSM_Trans;
The exit function of the current state is called. Then the action function is executed. After that, the current sate is changed to the next state and the entry function of the next state is called.
Information regarding the state of each invocation is maintained in a structure FSM_State. FSM_State contains various information about the current state of a connection.
typedef struct FSM_State {
Int (*entry)(FSM_Machine *machine,
FSM_UserData *userData,
FSM_EventId evtId);
Int (*exit)(FSM_Machine *machine,
FSM_UserData *userData,
FSM_EventId evtId);
struct FSM_Trans *trans;
String name;
} FSM_State;
The timers of ESROP are statically defined as follows.
lower_dataInd [lowerind.c] delivers an TSDU to ESROP.
inpdu reads the PDU header of an incoming PDU. It constructs the PDU structure and strips the header from the data buffer. If there is no data in the buffer, it frees it. At the completion of inpdu, ESRO-PDU contains the information about the received PDU. This information is then used by finite state machine.
A new machine is created through esrop_invokeInit facility.
Formatting of ESRO-PDUs is accomplished through a set of functions contained in pduout.c.
The sequence of ESROS primitives in a successful operation is next chapters. This section briefly describes the procedures that ESROP performs to invoke an operation. The description here does not deal with all possible state transitions; only the normal state transitions are described to give a general view to the reader. It is recommended that this section be read in conjunction with the source code.
Upon invocation of ESROS-INVOKE.request [userin.c], the invoker ESROP-Provider allocates a new machine and sets up the parameters relating to the invoke request event. Then delivers the ESROS-INVOKE.request event to the event processor FSM_runMachine. The state machine is assumed to be in the start state. The resulting action transition tr_clInvoker01/tr_2clInvoker01 [invokact.c/invact2.c] saves the remote address and the parameter which the user wishes to invoke. An invoke reference number which will be used to identify the invocation is created. The ESRO-INVOKE-PDU is formed and transmitted. A retransmission timer is also initialized. The resulting state is ESRO-INVOKE-PDU Sent state.
In ESRO-INVOKE-PDU Sent state, when the retransmission timer expiration event occurs, it indicates that the retransmission interval has expired since the last ESRO-INOVKE-PDU transmission, or the first transmission after ESROS-INVOKE.request. The resulting action transition tr_clInvoker02/tr_2clInvoker02 (invokact.c/invact2.c) retransmits the ESRO-INVOKE-PDU while the number of retransmissions is less than maximum number of retransmissions (invoke->nuOfRetrans). The retransmission counter is incremented and when the maximum number of retransmissions is reached, the last timer is started. The retransmission continues to await the arrival of the ESRO-RESULT-PDU or ESRO-ERROR-PDU, or last timer time out (maximum number of retransmissions), or receipt of ESRO-FAILURE-PDU.
In ESRO-INVOKE-PDU Sent state, when the last timer expiration event occurs after maximum retransmission of ESRO-INVOKE-PDU's, the tr_clInvoke03/tr_2clInvoker03 (invokact.c/invact2.c) action function issues an ESROS-FAILURE.indication primitive and initializes the reference number timer. The next state is the Invoker Reference Number Wait state that waits for the reference number timer to expire.
On receipt of ESRO-RESULT-PDU or ESRO-ERROR-PDU in the ESRO-INVOKE-PDU Sent state, the action and next state depends on the service mode and eventually 2-Way or 3-Way handshake. In the case of 3-Way handshake, the tr_clInvoker04 (invokact.c) action function sends an ESRO-ACK-PDU, issues ESROS-RESULT.indication or ESROS-ERROR.indication primitive, and initializes the inactivity timer. The resulting state is ESRO-ACK-PDU-Sent state. In the case of 2-Way handshake, the tr_2clInvoker04 (invact2.c) action function issues ESROS-RESULT.indication or ESROS-ERROR.indication primitive, and initializes the reference number timer.
In ESRO-INVOKE-PDU Sent state, on receipt of an ESRO-FAILURE-PDU, the tr_clInvoker05/tr_2clInvoker05 action (invokact.c/invact2.c) issues an ESROS-FAILURE.indication primitive with User Not Responding failure cause, and initializes the reference number timer. The resulting state is wait state for invoker reference number to expire.
In the case of 3-Way handshake, after receiving the ESRO-RESULT-PDU or ESRO-ERROR-PDU and going to ESRO-ACK-PDU send state, the duplicate ESRO-RESULT-PDU or ESRO-ERROR-PDU causes the action function tr_clInvoker07 (invokact.c) to initialize the inactivity timer and send another ESRO-ACK-PDU. The state machine stays in the ESRO-ACK-PDU Send state until the inactivity timer time-out.
In the Invoker RefNu Wait state, when the reference number timer time-out event occurs, the action tr_clInvoker08/tr_2clInvoker07 (invokact.c/invact2.c) releases the invoke reference number and the state machine goes to idle state.
In Invoker Reference Number Wait state, when ESRO-RESULT-PDU or ESRO-ERROR PDU is received, the action function tr_clInvoker09/tr_2clInvoker06 (invokact.c/invact2.c) resets the invoke reference number timer. The machine doesn't change state.
In the case of 3-Way handshake, In ESRO-ACK-PDU Send state, when the inactivity timer expiration event occurs, the action function tr_clInvoker10 (invokact.c) initializes the reference number timer, and the state is changed to Invoker Reference Number Wait state.
When ESROP receives an ESRO-INVOKE-PDU, it parses it, then delivers the INVOKEIND event to the event processor. The state machine is assumed to be in start state. The resulting action transition tr_clPerformer01/tr_2clPerformer01 (perfact.c/perfact2.c) accepts the ESRO-INVOKE-PDU and issues the ESROS-INVOKE.indication event primitive associated with the invoker of the operation. The new state becomes Invoke PDU Received state.
On receipt of an ESROS-RESULT.request primitive from performer user, the action transition tr_clPerformer02/tr_2clPerformer03 (perfact.c/perfact2.c) adds the invoke reference number to the active list, transmits the ESRO-RESULT-PDU or ESRO-ERROR-PDU, and sets the retransmission timer. In the case of 3-Way handshake, the state is changed to ESRO-ACK-PDU Wait state, waiting for ESRO-ACK-PDU. In the case of 2-Way handshake, the Inactivity Timer is set and the state is changed to Result PDU Retransmit.
In the case of 3-Way handshake, on receipt of an ESRO-ACK-PDU in ESRO-ACK-PDU Wait state, the action transition tr_clPerformer03 (perfact.c) initializes the invoke reference number timer and issues an ESROS-RESULT.confirm or an ESROS-ERROR.confirm. The state is changed to Reference Number Wait state.
In the case of 3-Way handshake, when Inactivity Timer expires, the action transition tr_2clPerformer06 (perfact2.c) initializes the invoke reference number timer and issues an ESROS-RESULT.confirm or an ESROS-ERROR.confirm. The state is changed to Reference Number Wait state.
The duplicate ESRO-INVOKE-PDUs in ESRO-INVOKE-PDU received state are ignored, and state machine stays in the same state.
In the case of 3-Way handshake, and in ESRO-ACK-PDU Wait state, when the ESRO-RESULT-PDU or ESRO-ERROR-PDU retransmission timer expires, the action transition tr_clPerformer05 (perfact.c) retransmits the ESRO-RESULT-PDU or ESRO-ERROR-PDU while the number of retransmissions is less than the maximum. The timer for number of retransmissions is incremented. The state machine stays in the ACK-PDU Wait state. The duplicate ESRO-INVOKE-PDUs in ESRO-ACK-PDU Wait state are ignored, and state machine stays in the same state.
In the case of 2-Way handshake, and in Result PDU Retransmit state, when a duplicate Invoke PDU arrives, the action transition tr_2clPerformer05 (perfact2.c) retransmits the ESRO-RESULT-PDU or ESRO-ERROR-PDU and the state machine stays in the same state.
In the ESRO-INVOKE-PDU received state, in the case of any kind of internal failure in ESROP, the action transition tr_clPerformer08/tr_clPerformer04 (perfact.c/perfact2.c) sends an ESRO-FAILURE-PDU. The state is changed to Connectionless Performer Start.
In the case of 2-Way handshake, when Inactivity Timer expires, the action transition tr_clPerformer09 issues an ESROS-FAILURE.indication primitive and initializes the invoke reference number timer. The state is changed to Performer Reference Number Wait state.
In the case of 3-Way handshake and in the ESRO-ACK-PDU Wait state, on expiration of last timer, the action transition tr_clPerformer09 (perfact.c) issues an ESROS-FAILURE.indication primitive and initializes the invoke reference number timer. The state is changed to Performer Reference Number Wait state.
In Performer Reference Number Wait state, the expiration of reference number timer causes the action transition tr_clPerformer10/tr_2clPerformer08 (perfact.c/perfact2.c) to release the invoke reference number. The state is changed to Connectionless Performer Start.
In Performer Reference Number Wait state, on receipt of duplicate ESRO-INVOKE-PDU, the action transition tr_clPerformer7/tr_2clPerformer7 (perfact.c/perfact2.c) resets the invoke reference number timer. The state is not changed.
In the case of 3-Way handshake and in Performer Reference Number Wait state, on receipt of duplicate ESRO-ACK-PDU, the action transition tr_clPerformer11 resets the invoke reference number timer. The state is not changed.