/*
 * (llc_util.c)- Utility functions used throughout LLC layer
 * 
 * All functions should know nothing about their caller; parameters passed
 * to each function are simple data types only; pointers to user-defined
 * structure data types is not allowed (despite the fact that we have a
 * bunch of 'include' files linked in; these satisfy 'llc_pdu.h')
 *
 * 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_UTIL_H

#include <linux/netdevice.h>      
#include <net/cm_types.h>     
#include <net/cm_mm.h>
#include <net/cm_dll.h>
#include <net/cm_frame.h>
#include <net/llc_pdu.h>
#include <net/llc_if.h>
#include <net/llc_sap.h>
#include <net/llc_conn.h>
#include <net/llc_util.h>
#include <net/llc_mac.h>
#include <net/llc_dbg.h>

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

extern us16 circular_between(us8, us8, us8);


/*
 * Function: llc_util_ns_inside_rx_window
 *
 * Description:
 *  Checks if sequence number of received PDU is in range of receive window.
 *
 * Parameters:
 *  us8 ns : This argument is sequence number of received pdu.
 *  us8 vr : This argument is sequence number which receiver expectes 
 *  	to receive.
 *  us8 rw : This argument is receive window size of receiver.
 *
 * Returns:
 *  0 : success 
 *  1 : failure
 */

us16 
llc_util_ns_inside_rx_window (us8 ns, us8 vr, us8 rw)
{
	return (!circular_between(vr, ns, (vr + rw - 1) % 
			LLC_2_SEQ_NBR_MODULO));
}


/*
 * Function: llc_util_nr_inside_tx_window
 *
 * Description:
 *  This routine checks if N(R) of received PDU is in range of transmit 
 *  window; on the other hand checks if received PDU acknowledges some 
 *  outstanding PDUs that are in transmit window.
 *
 * Parameters:
 *  connection_t *conn : This argument points to current connection.
 *  us8 nr : This argument is N(R) of received PDU.
 *
 * Returns:
 *  0 : success 
 *  1 : failure
 */

us16 
llc_util_nr_inside_tx_window (connection_t *conn, us8 nr)
{
	us8 nr1, nr2;
	frame_t *frame;
	pdu_sn_t *pdu;

	if (is_loopback(conn->local_dev) == 0) 
		return 0;
	if ( dll_peek(&conn->pdu_unack_q, (void **) &frame, DLL_WHERE_HEAD) )
		return 1;
	pdu = (pdu_sn_t *) frame->llc_hdr;
	nr1 = LLC_I_GET_NS(pdu);
	dll_peek(&conn->pdu_unack_q, (void **) &frame, DLL_WHERE_TAIL );
	pdu = (pdu_sn_t *) frame->llc_hdr;
	nr2 = LLC_I_GET_NS(pdu);
	return (!circular_between(nr1, nr, (nr2 + 1) % LLC_2_SEQ_NBR_MODULO));
	
}
