/*
 * (llc_c_ev.c)- Connection component state transition event qualifiers
 * 
 * A 'state' consists of a number of possible event matching functions,
 * the actions associated with each being executed when that event is
 * matched; a 'state machine' accepts events in a serial fashion from an
 * event queue. Each event is passed to each successive event matching
 * function until a match is made (the event matching function returns 
 * success, or '0') or the list of event matching funcions is exhausted.
 * If a match is made, the actions associated with the event are executed
 * and the state is changed to that event's transition state. Before some
 * events are recognized, even after a match has been made, a certain 
 * number of 'event qualifier' functions must also be executed. If these
 * all execute successfully, then the event is finally executed. 
 *
 * These event functions must return 0 for success, to show a matched
 * event, of 1 if the event does not match. Event qualifier functions
 * must return a 0 for success or a non-zero for failure. Each function
 * is simply responsible for verifying one single thing and returning
 * either a success or failure.
 * 
 * All of followed event functions are described in 802.2 LLC Protocol 
 * standard document except two functions that we added that will explain
 * in their comments, at below.
 *
 * Copyright (c) 1997 by Procom Technology,Inc.
 *
 * This program can be redistributed or modified under the terms of the 
 * GNU General Public License as published by the Free Software Foundation.
 * This program is distributed without any warranty or implied warranty
 * of merchantability or fitness for a particular purpose.
 *
 * See the GNU General Public License for more details.
 *
 */


#define LLC_C_EV_C

#include <net/cm_types.h>
#include <net/cm_mm.h>
#include <net/cm_dll.h>
#include <net/cm_frame.h>
#include <net/llc_if.h>
#include <net/llc_sap.h>
#include <net/llc_conn.h>
#include <net/llc_main.h>
#include <net/llc_glob.h>
#include <net/llc_c_ev.h>
#include <net/llc_pdu.h>
#include <net/llc_util.h>
#include <net/llc_dbg.h>

#ifdef LLC_C_EV_DBG
  #define  DBG_MSG(body) { printk body; }
#else
  #define  DBG_MSG(body)  ;
#endif

us16 
conn_ev_connect_request (connection_t *conn, conn_state_event_t *event)
{
	return (((event->data.prim.prim == CONNECT_PRIM) &&
		(event->data.prim.type == PRIM_TYPE_REQUEST)) ? 0 : 1);
}



us16 
conn_ev_connect_response (connection_t *conn, conn_state_event_t *event)
{
	return (((event->data.prim.prim == CONNECT_PRIM) &&
		(event->data.prim.type == PRIM_TYPE_RESPONSE)) ? 0 : 1);
}



us16 
conn_ev_data_request (connection_t *conn, conn_state_event_t *event)
{
	return (((event->data.prim.prim == DATA_PRIM) &&
		(event->data.prim.type == PRIM_TYPE_REQUEST)) ? 0 : 1);
}



us16 
conn_ev_disconnect_request (connection_t *conn, conn_state_event_t *event)
{
	return (((event->data.prim.prim == DISCONNECT_PRIM) &&
		(event->data.prim.type == PRIM_TYPE_REQUEST)) ? 0 : 1);
}


us16 
conn_ev_reset_request (connection_t *conn, conn_state_event_t *event)
{
	return (((event->data.prim.prim == RESET_PRIM) &&
		(event->data.prim.type == PRIM_TYPE_REQUEST)) ? 0 : 1);
}


us16 
conn_ev_reset_response (connection_t *conn, conn_state_event_t *event)
{
	return (((event->data.prim.prim == RESET_PRIM) &&
		(event->data.prim.type == PRIM_TYPE_RESPONSE)) ? 0 : 1);
}


us16 
conn_ev_local_busy_detected (connection_t *conn, conn_state_event_t *event)
{
	return (((event->type == CONN_EV_TYPE_SIMPLE) &&
		(event->data.a.event == CONN_EV_LOCAL_BUSY_DETECTED)) ? 0 : 1);
}



us16 
conn_ev_local_busy_cleared (connection_t *conn, conn_state_event_t *event)
{
	return (((event->type == CONN_EV_TYPE_SIMPLE) &&
		(event->data.a.event == CONN_EV_LOCAL_BUSY_CLEARED)) ? 0 : 1);
}


us16 
conn_ev_rx_bad_pdu (connection_t *conn, conn_state_event_t *event)
{
	return 1;
}


us16 
conn_ev_rx_disc_cmd_pbit_set_x (connection_t *conn, conn_state_event_t *event)
{
	pdu_un_t *pdu = (pdu_un_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_CMD(pdu)) &&     
		(!LLC_PDU_TYPE_IS_U(pdu)) &&  
		(LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC)) ? 0 : 1);
}


us16 
conn_ev_rx_dm_rsp_fbit_set_x (connection_t *conn, conn_state_event_t *event)
{
	pdu_un_t *pdu = (pdu_un_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_RSP(pdu)) &&    
		(!LLC_PDU_TYPE_IS_U(pdu)) &&  
		(LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM)) ? 0 : 1);
}


us16 
conn_ev_rx_frmr_rsp_fbit_set_x (connection_t *conn, conn_state_event_t *event)
{
	pdu_un_t *pdu = (pdu_un_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_RSP(pdu)) &&   
		(!LLC_PDU_TYPE_IS_U(pdu)) &&  
		(LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR)) ? 0 : 1);
}


us16 
conn_ev_rx_i_cmd_pbit_set_0 (connection_t *conn, conn_state_event_t *event)
{
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_CMD(pdu)) &&   
		(!LLC_PDU_TYPE_IS_I(pdu)) && 
		(!LLC_I_PF_IS_0(pdu)) &&    
		(LLC_I_GET_NS(pdu) == conn->vR) ) ? 0 : 1);
}


us16 
conn_ev_rx_i_cmd_pbit_set_1 (connection_t *conn, conn_state_event_t *event)
{
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_CMD(pdu)) &&     
		(!LLC_PDU_TYPE_IS_I(pdu)) && 
		(!LLC_I_PF_IS_1(pdu)) &&   
		(LLC_I_GET_NS(pdu) == conn->vR) ) ? 0 : 1); 
}


us16 
conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns (connection_t *conn, 
					conn_state_event_t *event)
{
	us8 ns;
	us8 vr;
	us16 rc;	
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	vr = conn->vR;
	ns = LLC_I_GET_NS(pdu);

	rc = (((!LLC_PDU_IS_CMD(pdu)) &&     
		(!LLC_PDU_TYPE_IS_I(pdu)) &&    
		(!LLC_I_PF_IS_0(pdu)) &&        
		(ns != vr) &&           
		(!llc_util_ns_inside_rx_window (ns, vr, conn->rw))) ? 0 : 1);
	
	return (rc);
}


us16 
conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns (connection_t *conn,
					conn_state_event_t *event)
{
	us8 ns;
	us8 vr;
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	vr = conn->vR;
	ns = LLC_I_GET_NS(pdu);

	return (((!LLC_PDU_IS_CMD(pdu)) &&   
		(!LLC_PDU_TYPE_IS_I(pdu)) && 
		(!LLC_I_PF_IS_1(pdu)) &&   
		(ns != vr) &&     
		(!llc_util_ns_inside_rx_window (ns, vr, conn->rw))) ? 0 : 1);
}



us16 
conn_ev_rx_i_cmd_pbit_set_x_inval_ns (connection_t *conn,
					conn_state_event_t *event)
{
	us8 ns;
	us8 vr;
	us16 rc;
	pdu_sn_t * pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	vr = conn->vR;
	ns = LLC_I_GET_NS(pdu);
	
	rc = (((!LLC_PDU_IS_CMD(pdu)) &&                  
		(!LLC_PDU_TYPE_IS_I(pdu)) &&             
		(ns != vr) &&                        
		(llc_util_ns_inside_rx_window (ns, vr, conn->rw))) ? 0 : 1);
	
	if (!rc){
		printk("\n  rx_i_cmd_p_bit_set_x_inval_ns matched,state=%d,
			ns=%d,vr=%d ",conn->state,ns,vr);
	}
	return (rc);
}


us16 
conn_ev_rx_i_rsp_fbit_set_0 (connection_t *conn, conn_state_event_t *event)
{
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_RSP(pdu)) &&      
		(!LLC_PDU_TYPE_IS_I(pdu)) &&    
		(!LLC_I_PF_IS_0(pdu)) &&    
		(LLC_I_GET_NS(pdu) == conn->vR)) ? 0 : 1);

}


us16 
conn_ev_rx_i_rsp_fbit_set_1 (connection_t *conn, conn_state_event_t *event)
{
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_RSP(pdu)) &&     
		(!LLC_PDU_TYPE_IS_I(pdu)) &&  
		(!LLC_I_PF_IS_1(pdu)) &&  
		(LLC_I_GET_NS(pdu) == conn->vR)) ? 0 : 1);

}


us16 
conn_ev_rx_i_rsp_fbit_set_x (connection_t *conn, conn_state_event_t *event)
{
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_RSP(pdu)) &&    
		(!LLC_PDU_TYPE_IS_I(pdu)) &&  
		(LLC_I_GET_NS(pdu) == conn->vR)) ? 0 : 1);

}


us16 
conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns (connection_t *conn,
					conn_state_event_t *event)
{
	us8 ns;
	us8 vr;
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	vr = conn->vR;
	ns = LLC_I_GET_NS(pdu);

	return (((!LLC_PDU_IS_RSP(pdu)) &&     
		(!LLC_PDU_TYPE_IS_I(pdu)) && 
		(!LLC_I_PF_IS_0(pdu)) &&  
		(ns != vr) &&         
		(!llc_util_ns_inside_rx_window (ns, vr, conn->rw))) ? 0 : 1);

}


us16 
conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns (connection_t *conn,
					conn_state_event_t *event)
{
	us8 ns;
	us8 vr;
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	vr = conn->vR;
	ns = LLC_I_GET_NS(pdu);

	return (((!LLC_PDU_IS_RSP(pdu)) &&     
		(!LLC_PDU_TYPE_IS_I(pdu)) &&    
		(!LLC_I_PF_IS_1(pdu)) &&     
		(ns != vr) &&               
		(!llc_util_ns_inside_rx_window (ns, vr, conn->rw))) ? 0 : 1);
}


us16 
conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns (connection_t *conn,
					conn_state_event_t *event)
{
	us8 ns;
	us8 vr;
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	vr = conn->vR;
	ns = LLC_I_GET_NS(pdu);

	return (((!LLC_PDU_IS_RSP(pdu)) &&     
		(!LLC_PDU_TYPE_IS_I(pdu)) &&   
		(ns != vr) &&      
		(!llc_util_ns_inside_rx_window (ns, vr, conn->rw))) ? 0 : 1);

}


us16 
conn_ev_rx_i_rsp_fbit_set_x_inval_ns (connection_t *conn,
					conn_state_event_t *event)
{
	us8 ns;
	us8 vr;
	us16 rc;
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	vr = conn->vR;
	ns = LLC_I_GET_NS(pdu);

	rc = (((!LLC_PDU_IS_RSP(pdu)) &&           
		(!LLC_PDU_TYPE_IS_I(pdu)) &&     
		(ns != vr) &&             
		(llc_util_ns_inside_rx_window (ns, vr, conn->rw))) ? 0 : 1);
	if (!rc){
		printk("\nconn_ev_rx_i_rsp_fbit_set_x_inval_ns matched : 
			state=%d,ns=%d,vr=%d",conn->state,ns,vr);
	}
	
	return rc;
}



us16 
conn_ev_rx_rej_cmd_pbit_set_0 (connection_t *conn, conn_state_event_t *event)
{
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_CMD(pdu)) &&         
		(!LLC_PDU_TYPE_IS_S(pdu)) &&      
		(!LLC_S_PF_IS_0(pdu)) &&      
		(LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ)) ? 0 : 1);
}


us16 
conn_ev_rx_rej_cmd_pbit_set_1 (connection_t *conn, conn_state_event_t *event)
{
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_CMD(pdu)) &&        
		(!LLC_PDU_TYPE_IS_S(pdu)) &&    
		(!LLC_S_PF_IS_1(pdu)) &&     
		(LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ)) ? 0 : 1);

}


us16 
conn_ev_rx_rej_rsp_fbit_set_0 (connection_t *conn, conn_state_event_t *event)
{
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_RSP(pdu)) &&        
		(!LLC_PDU_TYPE_IS_S(pdu)) &&   
		(!LLC_S_PF_IS_0(pdu)) &&         
		(LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ)) ? 0 : 1);

}


us16 
conn_ev_rx_rej_rsp_fbit_set_1 (connection_t *conn, conn_state_event_t *event)
{
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_RSP(pdu)) &&          
		(!LLC_PDU_TYPE_IS_S(pdu)) &&    
		(!LLC_S_PF_IS_1(pdu)) &&         
		(LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ)) ? 0 : 1);

}


us16 
conn_ev_rx_rej_rsp_fbit_set_x (connection_t *conn, conn_state_event_t *event)
{
	pdu_un_t *pdu = (pdu_un_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_RSP(pdu)) &&    
		(!LLC_PDU_TYPE_IS_S(pdu)) &&  
		(LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ)) ? 0 : 1);

}


us16 
conn_ev_rx_rnr_cmd_pbit_set_0 (connection_t *conn, conn_state_event_t *event)
{
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_CMD(pdu)) &&           
		(!LLC_PDU_TYPE_IS_S(pdu)) &&       
		(!LLC_S_PF_IS_0(pdu)) &&       
		(LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR)) ? 0 : 1);

}


us16 
conn_ev_rx_rnr_cmd_pbit_set_1 (connection_t *conn, conn_state_event_t *event)
{
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_CMD(pdu)) &&        
		(!LLC_PDU_TYPE_IS_S(pdu)) &&   
		(!LLC_S_PF_IS_1(pdu)) &&   
		(LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR)) ? 0 : 1);

}


us16 
conn_ev_rx_rnr_rsp_fbit_set_0 (connection_t *conn, conn_state_event_t *event)
{
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_RSP(pdu)) &&       
		(!LLC_PDU_TYPE_IS_S(pdu)) &&     
		(!LLC_S_PF_IS_0(pdu)) &&   
		(LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR)) ? 0 : 1);

}


us16 
conn_ev_rx_rnr_rsp_fbit_set_1 (connection_t *conn, conn_state_event_t *event)
{
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_RSP(pdu)) &&    
		(!LLC_PDU_TYPE_IS_S(pdu)) &&     
		(!LLC_S_PF_IS_1(pdu)) &&        
		(LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR)) ? 0 : 1);

}


us16 
conn_ev_rx_rr_cmd_pbit_set_0 (connection_t *conn, conn_state_event_t *event)
{
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_CMD(pdu)) &&       
		(!LLC_PDU_TYPE_IS_S(pdu)) &&     
		(!LLC_S_PF_IS_0(pdu)) &&      
		(LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR)) ? 0 : 1);

}


us16 
conn_ev_rx_rr_cmd_pbit_set_1 (connection_t *conn, conn_state_event_t *event)
{
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_CMD(pdu)) &&       
		(!LLC_PDU_TYPE_IS_S(pdu)) &&     
		(!LLC_S_PF_IS_1(pdu)) &&   
		(LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR)) ? 0 : 1);

}


us16 
conn_ev_rx_rr_rsp_fbit_set_0 (connection_t *conn, conn_state_event_t *event)
{
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_RSP(pdu)) &&       
		(!LLC_PDU_TYPE_IS_S(pdu)) &&     
		(!LLC_S_PF_IS_0(pdu)) &&    
		(LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR)) ? 0 : 1);

}


us16 
conn_ev_rx_rr_rsp_fbit_set_1 (connection_t *conn, conn_state_event_t *event)
{
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_RSP(pdu)) &&    
		(!LLC_PDU_TYPE_IS_S(pdu)) &&    
		(!LLC_S_PF_IS_1(pdu)) &&     
		(LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR)) ? 0 : 1);

}


us16 
conn_ev_rx_sabme_cmd_pbit_set_x (connection_t *conn, conn_state_event_t *event)
{
	pdu_un_t *pdu = (pdu_un_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_CMD(pdu)) &&        
		(!LLC_PDU_TYPE_IS_U(pdu)) &&     
		(LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME)) ? 0 : 1);

}


us16 
conn_ev_rx_ua_rsp_fbit_set_x (connection_t *conn, conn_state_event_t *event)
{
	pdu_un_t *pdu = (pdu_un_t *) event->data.pdu.frame->llc_hdr;

	return (((!LLC_PDU_IS_RSP(pdu)) &&        
		(!LLC_PDU_TYPE_IS_U(pdu)) &&    
		(LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_UA)) ? 0 : 1);

}


us16 
conn_ev_rx_xxx_cmd_pbit_set_1 (connection_t *conn, conn_state_event_t *event)
{
	us16 rc = 1;
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	if (!LLC_PDU_IS_CMD(pdu)) {
		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
			if (!LLC_I_PF_IS_1(pdu)) {
				rc = 0;
			}
		} else if (!LLC_PDU_TYPE_IS_U(pdu)) {
			if (!LLC_U_PF_IS_1(pdu)) {
				rc = 0;
			}
		}
	}

	return (rc);
}


us16 
conn_ev_rx_xxx_cmd_pbit_set_0 (connection_t *conn, conn_state_event_t *event)
{
	us16 rc = 1;
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	if (!LLC_PDU_IS_CMD(pdu)) {
		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
			if (!LLC_I_PF_IS_0(pdu)) {
				rc = 0;
			}
		} else if (!LLC_PDU_TYPE_IS_U(pdu)) {
			switch (LLC_U_PDU_CMD(pdu)) {
				case LLC_2_PDU_CMD_SABME:
				case LLC_2_PDU_CMD_DISC:

					if (!LLC_U_PF_IS_0(pdu)) {
						rc = 0;
					}
					break;
			}
		}
	}

	return (rc);
}


us16 
conn_ev_rx_xxx_cmd_pbit_set_x (connection_t *conn, conn_state_event_t *event)
{
	us16 rc = 1;
	pdu_un_t *pdu = (pdu_un_t *) event->data.pdu.frame->llc_hdr;

	if (!LLC_PDU_IS_CMD(pdu)) {
		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
			rc = 0;
		} else if (!LLC_PDU_TYPE_IS_U(pdu)) {
			switch (LLC_U_PDU_CMD(pdu)) {
				case LLC_2_PDU_CMD_SABME:
				case LLC_2_PDU_CMD_DISC:
					rc = 0;
					break;
			}
		}
	}

	return (rc);
}


us16 
conn_ev_rx_xxx_rsp_fbit_set_1 (connection_t *conn, conn_state_event_t *event)
{
	us16 rc = 1;
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	if (!LLC_PDU_IS_RSP(pdu)) {
		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
			if (!LLC_I_PF_IS_1(pdu)) {
				rc = 0;
			}
		} else if (!LLC_PDU_TYPE_IS_U(pdu)) {
			switch (LLC_U_PDU_RSP(pdu)) {
				case LLC_2_PDU_RSP_UA:
				case LLC_2_PDU_RSP_DM:
				case LLC_2_PDU_RSP_FRMR:

					if (!LLC_U_PF_IS_1(pdu)) {
						rc = 0;
					}
					break;
			}
		}
	}

	return (rc);
}


us16 
conn_ev_rx_xxx_rsp_fbit_set_x (connection_t *conn, conn_state_event_t *event)
{
	us16 rc = 1;

	pdu_un_t *pdu = (pdu_un_t *) event->data.pdu.frame->llc_hdr;

	if (!LLC_PDU_IS_RSP(pdu)) {
		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
			rc = 0;
		} else if (!LLC_PDU_TYPE_IS_U(pdu)) {
			switch (LLC_U_PDU_RSP(pdu)) {
				case LLC_2_PDU_RSP_UA:
				case LLC_2_PDU_RSP_DM:
				case LLC_2_PDU_RSP_FRMR:

					rc = 0;
					break;
			}
		}
	}

	return (rc);
}


us16 
conn_ev_rx_xxx_yyy (connection_t *conn, conn_state_event_t *event)
{
	us16 rc = 1;
	pdu_un_t *pdu = (pdu_un_t *) event->data.pdu.frame->llc_hdr;

	if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
		rc = 0;
	} else if (!LLC_PDU_TYPE_IS_U(pdu)) {
		switch (LLC_U_PDU_CMD(pdu)) {
			case LLC_2_PDU_CMD_SABME:
			case LLC_2_PDU_CMD_DISC:
			case LLC_2_PDU_RSP_UA:
			case LLC_2_PDU_RSP_DM:
			case LLC_2_PDU_RSP_FRMR:

				rc = 0;
				break;
		}
	}

	return (rc);
}


us16 
conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr (connection_t *conn,
						conn_state_event_t *event)
{
	us8 nr;
	us8 vs;
	us16 rc = 1;
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	vs = conn->vS;
	nr = LLC_I_GET_NR(pdu);   

	if (!LLC_PDU_IS_CMD(pdu)) {
		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
			if ((nr != vs) && 
				llc_util_nr_inside_tx_window (conn, nr)) {
				printk(KERN_ERR "\nconn_ev_rx_zzz_cmd_inv_nr 
					matched,state=%d,vs=%d,nr=%d ",
					conn->state,vs,nr);
				rc = 0;
			}
		}
	}

	return (rc);
}


us16 
conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr (connection_t *conn,
						conn_state_event_t *event)
{
	us8 nr;
	us8 vs;
	us16 rc = 1;
	pdu_sn_t *pdu = (pdu_sn_t *) event->data.pdu.frame->llc_hdr;

	vs = conn->vS;
	nr = LLC_I_GET_NR(pdu);  

	if (!LLC_PDU_IS_RSP(pdu)) {
		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
			if ((nr != vs) && 
				llc_util_nr_inside_tx_window (conn, nr)) {
				rc = 0;
				printk(KERN_ERR "\nconn_ev_rx_zzz_fbit_set
					_x_inval_nr matched, state=%d,
					vs=%d,nr=%d ",conn->state,vs,nr);
			}
		}
	}

	return (rc);
}


us16 
conn_ev_rx_any_frame(connection_t *conn, conn_state_event_t *event)
{
	return 0;
}

us16 
conn_ev_p_timer_expired (connection_t *conn, conn_state_event_t *event)
{
	return (((event->type == CONN_EV_TYPE_P_TIMER) ? 0 : 1));
}


us16 
conn_ev_ack_timer_expired (connection_t *conn, conn_state_event_t *event)
{
	return (((event->type == CONN_EV_TYPE_ACK_TIMER) ? 0 : 1));
}


us16 
conn_ev_rej_timer_expired (connection_t *conn, conn_state_event_t *event)
{
	return (((event->type == CONN_EV_TYPE_REJ_TIMER) ? 0 : 1));
}


us16 
conn_ev_busy_timer_expired (connection_t *conn, conn_state_event_t *event)
{
	return (((event->type == CONN_EV_TYPE_BUSY_TIMER) ? 0 : 1));
}


us16 
conn_ev_any_timer_expired (connection_t *conn, conn_state_event_t *event)
{

	return (((event->type == CONN_EV_TYPE_P_TIMER ||
		event->type == CONN_EV_TYPE_ACK_TIMER ||
		event->type == CONN_EV_TYPE_REJ_TIMER ||
		event->type == CONN_EV_TYPE_BUSY_TIMER) ? 0 : 1));

}


us16 
conn_ev_init_p_f_cycle (connection_t *conn, conn_state_event_t *event)
{
	return 1;
}


us16 
conn_ev_tx_buffer_full (connection_t *conn, conn_state_event_t *event)
{
	return (((event->type == CONN_EV_TYPE_SIMPLE) &&
		(event->data.a.event == CONN_EV_TX_BUFF_FULL)) ? 0 : 1);  
}

/* --------------------- EVENT QUALIFIER FUNCTIONS ----------------------- *
 * 
 * these functions simply verify the value of a state flag associated with
 * the connection and return either a 0 for success or a non-zero value
 * for not-success; verify the event is the type we expect
 *
 * ----------------------------------------------------------------------- */


us16 
conn_ev_qlfy_data_flag_eq_1 (connection_t *conn, conn_state_event_t *event)
{
	return ((conn->data_flag == 1) ? 0 : 1);
}


us16 
conn_ev_qlfy_data_flag_eq_0 (connection_t *conn, conn_state_event_t *event)
{
	return ((conn->data_flag == 0) ? 0 : 1);
}


us16 
conn_ev_qlfy_data_flag_eq_2 (connection_t *conn, conn_state_event_t *event)
{
	return ((conn->data_flag == 2) ? 0 : 1);
}


us16 
conn_ev_qlfy_p_flag_eq_1 (connection_t *conn, conn_state_event_t *event)
{
	return ( conn->p_flag == 1 ? 0 : 1);
}


/*
 * Function: conn_ev_qlfy_last_frame_eq_1
 *
 * Description:
 *  This function determines when frame which is sent, is last frame of 
 *  transmit window, if it is then this function return zero else return one.
 *  This function is used for sending last frame of transmit window as 
 *  I-format command with p-bit set to one.
 *
 * Parameters:
 *  connection_t *conn : This argument points to current connection structure.
 *  conn_state_event_t *event : This argument points to current event.
 * 
 * Returns:
 *  0 : If frame is last frame.
 *  1 : If frame isn't last frame.
 */
 

us16 
conn_ev_qlfy_last_frame_eq_1 (connection_t *conn, conn_state_event_t *event)
{
	return ( (dll_query(&conn->pdu_unack_q)+1) == conn->k ? 0 : 1);
}


/*
 * Function: conn_ev_qlfy_last_frame_eq_0
 *
 * Description:
 *  This function determines when frame which is sent, isn't last frame of 
 *  transmit window, if it isn't then this function return zero else return 
 *  one.
 *
 * Parameters:
 *  connection_t *conn : This argument points to current connection structure.
 *  conn_state_event_t *event : This argument points to current event.
 * 
 * Returns:
 *  0 : If frame isn't last frame.
 *  1 : If frame is last frame.
 */

us16 
conn_ev_qlfy_last_frame_eq_0 (connection_t *conn, conn_state_event_t *event)
{
	return ( (dll_query(&conn->pdu_unack_q)+1) == conn->k ? 1 : 0);
}


us16 
conn_ev_qlfy_p_flag_eq_0 (connection_t *conn, conn_state_event_t *event)
{
	return (conn->p_flag == 0 ? 0 : 1);
}


us16 
conn_ev_qlfy_p_flag_eq_f (connection_t *conn, conn_state_event_t *event)
{
	us8 f_bit;
	frame_t * frame;  

	if (event->type == CONN_EV_TYPE_PDU) {
		frame = (frame_t *)event->data.pdu.frame;
	} else {
		frame = (frame_t *)((prim_if_block_t *)
			(event->data.prim.data))->data->conn.unit;
		FDBG_ERR_MSG(("\nLLC : conn_ev_qlfy_p_flag_eq_f called with by 
				a request\n"));
	}
	
	pdu_decode_pf_bit (frame, &f_bit);
	
	return (conn->p_flag == f_bit ? 0 : 1);
}


us16 
conn_ev_qlfy_remote_busy_eq_0 (connection_t *conn, conn_state_event_t *event)
{
	return (conn->remote_busy_flag == 0 ? 0 : 1);
}


us16 
conn_ev_qlfy_remote_busy_eq_1 (connection_t *conn, conn_state_event_t *event)
{
	return (conn->remote_busy_flag == 1 ? 0 : 1);
}


us16 
conn_ev_qlfy_retry_count_lt_n2 (connection_t *conn, conn_state_event_t *event)
{
	return((conn->retry_count < conn->n2 ? 0 : 1));
}


us16 
conn_ev_qlfy_retry_count_gte_n2 (connection_t *conn, conn_state_event_t *event)
{
	return (conn->retry_count >= conn->n2 ? 0 : 1);
}


us16 
conn_ev_qlfy_s_flag_eq_1 (connection_t *conn, conn_state_event_t *event)
{
	return (conn->s_flag == 1 ? 0 : 1);
}


us16 
conn_ev_qlfy_s_flag_eq_0 (connection_t *conn, conn_state_event_t *event)
{
	return (conn->s_flag == 0 ? 0 : 1);
}


us16 
conn_ev_qlfy_cause_flag_eq_1 (connection_t *conn, conn_state_event_t *event)
{
	return (conn->cause_flag == 1 ? 0 : 1);
}


us16 
conn_ev_qlfy_cause_flag_eq_0 (connection_t *conn, conn_state_event_t *event)
{
	return (conn->cause_flag == 0 ? 0 : 1);
}


us16 
conn_ev_qlfy_init_p_f_cycle (connection_t *conn, conn_state_event_t *event)
{
	return (0);
}


us16 
conn_ev_qlfy_set_status_connect (connection_t *conn, conn_state_event_t *event)
{
	event->status = CONNECT;
	return (0);
}


us16 
conn_ev_qlfy_set_status_disconnect (connection_t *conn,
					conn_state_event_t *event)
{
	event->status = DISCONNECT;
	return (0);
}


us16 
conn_ev_qlfy_set_status_impossible (connection_t *conn, 
					conn_state_event_t *event)
{
	event->status = IMPOSSIBLE;
	return (0);
}

us16 
conn_ev_qlfy_set_status_failed (connection_t *conn, conn_state_event_t *event)
{
	event->status = FAILED;
	return (0);
}


us16 
conn_ev_qlfy_set_status_remote_busy (connection_t *conn,
					conn_state_event_t *event)
{
	event->status = REMOTE_BUSY;
	return (0);
}


us16 
conn_ev_qlfy_set_status_received (connection_t *conn,
					conn_state_event_t *event)
{
	event->status = RECEIVED;
	return (0);
}


us16 
conn_ev_qlfy_set_status_refuse (connection_t *conn, conn_state_event_t *event)
{
	event->status = REFUSE;
	return (0);
}


us16 
conn_ev_qlfy_set_status_conflict (connection_t *conn,
					conn_state_event_t *event)
{
	event->status = CONFLICT;
	return (0);
}


us16 
conn_ev_qlfy_set_status_reset_done (connection_t *conn,
					conn_state_event_t *event)
{
	event->status = RESET_DONE;
	return (0);
}


