idm_conn_sm.h revision e42a0851889d583925aa3bd2d9bd139189031cb0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _IDM_CONN_SM_H_
#define _IDM_CONN_SM_H_
#ifdef __cplusplus
extern "C" {
#endif
/*
* IDM connection state machine events. Most events get generated internally
* either by the state machine or by the IDM TX/RX code. For example when IDM
* receives a login request for a target connectionit will generate a
* CE_LOGIN_RCV event. Similarly when the target sends a successful login
* response IDM generate a "CE_LOGIN_SUCCESS_SND" event. The following
* events are not detected on the TX/RX path and must be generated explicitly
* by the client when appropriate:
*
* CE_LOGOUT_OTHER_CONN_RCV
* CE_ASYNC_DROP_CONN_RCV (Only because the message may be received on
* a different connection from the connection being dropped)
* CE_ASYNC_DROP_ALL_CONN_RCV
* CE_LOGOUT_OTHER_CONN_SND
* CE_ASYNC_DROP_ALL_CONN_SND
*
* The following events might occur in any state since they are driven
* by the PDU's that IDM receives:
*
* CE_LOGIN_RCV
* CE_LOGIN_SUCCESS_RCV
* CE_LOGIN_FAIL_RCV
* CE_LOGOUT_SUCCESS_RCV
* CE_LOGOUT_FAIL_RCV
* CE_ASYNC_LOGOUT_RCV
* CE_MISC_RCV
* CE_RX_PROTOCOL_ERROR
*/
#define IDM_LOGIN_SECONDS 20
#define IDM_LOGOUT_SECONDS 20
#define IDM_CLEANUP_SECONDS 0
/* Update idm_ce_name table whenever connection events are modified */
typedef enum {
CE_UNDEFINED = 0,
/* Initiator events */
CE_CONNECT_REQ,
CE_CONNECT_FAIL,
CE_CONNECT_SUCCESS,
CE_LOGIN_SND,
CE_LOGIN_SUCCESS_RCV,
CE_LOGIN_FAIL_RCV,
CE_LOGOUT_THIS_CONN_SND,
CE_LOGOUT_OTHER_CONN_SND,
CE_LOGOUT_SESSION_SND,
CE_LOGOUT_SUCCESS_RCV,
CE_LOGOUT_FAIL_RCV,
CE_ASYNC_LOGOUT_RCV,
CE_ASYNC_DROP_CONN_RCV,
CE_ASYNC_DROP_ALL_CONN_RCV,
/* Target events */
CE_CONNECT_ACCEPT,
CE_CONNECT_REJECT,
CE_LOGIN_RCV,
CE_LOGIN_TIMEOUT,
CE_LOGIN_SUCCESS_SND,
CE_LOGIN_FAIL_SND,
CE_LOGIN_FAIL_SND_DONE,
CE_LOGOUT_THIS_CONN_RCV,
CE_LOGOUT_OTHER_CONN_RCV,
CE_LOGOUT_SESSION_RCV,
CE_LOGOUT_SUCCESS_SND,
CE_LOGOUT_SUCCESS_SND_DONE,
CE_LOGOUT_FAIL_SND,
CE_LOGOUT_FAIL_SND_DONE,
CE_CLEANUP_TIMEOUT,
CE_ASYNC_LOGOUT_SND,
CE_ASYNC_DROP_CONN_SND,
CE_ASYNC_DROP_ALL_CONN_SND,
CE_LOGOUT_TIMEOUT,
/* Common events */
CE_TRANSPORT_FAIL,
CE_MISC_TX,
CE_TX_PROTOCOL_ERROR,
CE_MISC_RX,
CE_RX_PROTOCOL_ERROR,
CE_LOGOUT_SESSION_SUCCESS,
CE_CONN_REINSTATE,
CE_CONN_REINSTATE_SUCCESS,
CE_CONN_REINSTATE_FAIL,
CE_ENABLE_DM_SUCCESS,
CE_ENABLE_DM_FAIL,
/* Add new events above CE_MAX_EVENT */
CE_MAX_EVENT
} idm_conn_event_t;
#ifdef IDM_CONN_SM_STRINGS
/* An array of event text values, for use in logging events */
static const char *idm_ce_name[CE_MAX_EVENT+1] = {
"CE_UNDEFINED",
"CE_CONNECT_REQ",
"CE_CONNECT_FAIL",
"CE_CONNECT_SUCCESS",
"CE_LOGIN_SND",
"CE_LOGIN_SUCCESS_RCV",
"CE_LOGIN_FAIL_RCV",
"CE_LOGOUT_THIS_CONN_SND",
"CE_LOGOUT_OTHER_CONN_SND",
"CE_LOGOUT_SESSION_SND",
"CE_LOGOUT_SUCCESS_RCV",
"CE_LOGOUT_FAIL_RCV",
"CE_ASYNC_LOGOUT_RCV",
"CE_ASYNC_DROP_CONN_RCV",
"CE_ASYNC_DROP_ALL_CONN_RCV",
"CE_CONNECT_ACCEPT",
"CE_CONNECT_REJECT",
"CE_LOGIN_RCV",
"CE_LOGIN_TIMEOUT",
"CE_LOGIN_SUCCESS_SND",
"CE_LOGIN_FAIL_SND",
"CE_LOGIN_FAIL_SND_DONE",
"CE_LOGOUT_THIS_CONN_RCV",
"CE_LOGOUT_OTHER_CONN_RCV",
"CE_LOGOUT_SESSION_RCV",
"CE_LOGOUT_SUCCESS_SND",
"CE_LOGOUT_SUCCESS_SND_DONE",
"CE_LOGOUT_FAIL_SND",
"CE_LOGOUT_FAIL_SND_DONE",
"CE_CLEANUP_TIMEOUT",
"CE_ASYNC_LOGOUT_SND",
"CE_ASYNC_DROP_CONN_SND",
"CE_ASYNC_DROP_ALL_CONN_SND",
"CE_LOGOUT_TIMEOUT",
"CE_TRANSPORT_FAIL",
"CE_MISC_TX",
"CE_TX_PROTOCOL_ERROR",
"CE_MISC_RX",
"CE_RX_PROTOCOL_ERROR",
"CE_LOGOUT_SESSION_SUCCESS",
"CE_CONN_REINSTATE",
"CE_CONN_REINSTATE_SUCCESS",
"CE_CONN_REINSTATE_FAIL",
"CE_ENABLE_DM_SUCCESS",
"CE_ENABLE_DM_FAIL",
"CE_MAX_EVENT"
};
#endif
/* Update idm_cs_name table whenever connection states are modified */
typedef enum {
CS_S0_UNDEFINED = 0,
CS_S1_FREE,
CS_S2_XPT_WAIT,
CS_S3_XPT_UP,
CS_S4_IN_LOGIN,
CS_S5_LOGGED_IN,
CS_S6_IN_LOGOUT,
CS_S7_LOGOUT_REQ,
CS_S8_CLEANUP,
CS_S9_INIT_ERROR,
CS_S9A_REJECTED,
CS_S10_IN_CLEANUP,
CS_S11_COMPLETE,
CS_S12_ENABLE_DM,
/* Add new connection states above CS_MAX_STATE */
CS_MAX_STATE
} idm_conn_state_t;
#ifdef IDM_CONN_SM_STRINGS
/* An array of state text values, for use in logging state transitions */
static const char *idm_cs_name[CS_MAX_STATE+1] = {
"CS_S0_UNDEFINED",
"CS_S1_FREE",
"CS_S2_XPT_WAIT",
"CS_S3_XPT_UP",
"CS_S4_IN_LOGIN",
"CS_S5_LOGGED_IN",
"CS_S6_IN_LOGOUT",
"CS_S7_LOGOUT_REQ",
"CS_S8_CLEANUP",
"CS_S9_INIT_ERROR",
"CS_S9A_REJECTED",
"CS_S10_IN_CLEANUP",
"CS_S11_COMPLETE",
"CS_S12_ENABLE_DM",
"CS_MAX_STATE"
};
#endif
typedef enum {
CT_NONE = 0,
CT_RX_PDU,
CT_TX_PDU
} idm_pdu_event_type_t;
typedef enum {
CA_TX_PROTOCOL_ERROR, /* Send "protocol error" to state machine */
CA_RX_PROTOCOL_ERROR, /* Send "protocol error" to state machine */
CA_FORWARD, /* State machine event and forward to client */
CA_DROP /* Drop PDU */
} idm_pdu_event_action_t;
typedef struct {
struct idm_conn_s *iec_ic;
idm_conn_event_t iec_event;
uintptr_t iec_info;
idm_pdu_event_type_t iec_pdu_event_type;
boolean_t iec_pdu_forwarded;
} idm_conn_event_ctx_t;
idm_status_t
idm_conn_sm_init(struct idm_conn_s *ic);
void
idm_conn_sm_fini(struct idm_conn_s *ic);
idm_status_t
idm_notify_client(struct idm_conn_s *ic, idm_client_notify_t cn,
uintptr_t data);
void
idm_conn_event(struct idm_conn_s *ic, idm_conn_event_t event, uintptr_t data);
void
idm_conn_event(struct idm_conn_s *ic, idm_conn_event_t event, uintptr_t data);
void
idm_conn_event_locked(struct idm_conn_s *ic, idm_conn_event_t event,
uintptr_t event_info, idm_pdu_event_type_t pdu_event_type);
idm_status_t
idm_conn_reinstate_event(struct idm_conn_s *old_ic, struct idm_conn_s *new_ic);
void
idm_conn_tx_pdu_event(struct idm_conn_s *ic, idm_conn_event_t event,
uintptr_t data);
void
idm_conn_rx_pdu_event(struct idm_conn_s *ic, idm_conn_event_t event,
uintptr_t data);
char *
idm_conn_state_str(struct idm_conn_s *ic);
#ifdef __cplusplus
}
#endif
#endif /* _IDM_CONN_SM_H_ */