#ident "$Id: x25pti.c,v 1.2 1995/04/06 16:50:27 garyp Exp $"
/*****************************************************************************
 * Copyright (c) 1988-95 Digi International Inc., All Rights Reserved
 * 
 * This  software  contains  proprietary  and  confidential   information   of
 * Digi International  Inc.   By  accepting  transfer  of this copy, Recipient
 * agrees to retain this software in  confidence,  to  prevent  disclosure  to
 * others,  and  to make no  use of this software other than that for which it
 * was delivered.  This is an unpublished copyright work  Digi   International
 * Inc.    Except   as   permitted   by  federal  law,  17 USC 117, copying is
 * strictly prohibited.
 * 
 * Digi  International  Inc.  CONFIDENTIAL  -   (Digi    International    Inc.
 * Confidential  when   combined   with   the   aggregated  modules  for  this
 * product) OBJECT CODE ONLY SOURCE MATERIALS
 * 
 * (C) COPYRIGHT Digi International Inc. 1995
 * 
 * All Rights Reserved
 * 
 * US   Government   Users   Restricted   Rights   -   Use,   duplication   or
 * disclosure  restricted by GSA ADP Schedule Contract with Digi International
 * Inc.
 * 
 *****************************************************************************/

/*******************************************************************
 *
 *  SpiderX25 X25 PLP Driver
 *
 *  Copyright 1991 Spider Systems Limited
 *
 *  X25PTI.C
 *
 *
 *******************************************************************/

/*
 *	x25pti.c
 *	 /projects/common/PBRAIN/SCCS/pbrainF/dev/sys/x25/0/s.x25pti.c
 *	@(#)x25pti.c	1.18
 *
 *	Last delta created	14:31:33 11/10/91
 *	This file extracted	18:33:02 11/19/92
 *
 */

#define  PTIDECLARED  1     /* Preprocessor - do not include extern */

#include "x25_inc.h"
#include "x25pti.h"

/* --------------------------------------------------------------------
        Functions IDnnPKT and ID00Pkt:

   Decode the X25 packet type identifier in a received frame.  Priority
   is given to data, being the first to be checked.  Analysis depends
   on whether the LGN/LCN pair is zero or otherwise, and differing
   routines are provided in order to ease transition to alternative
   VC allocation schemes in the DTE/DTE environment.

   In both routines, it is assumed that the gfi has been checked in as
   much that is satisfies the test gfi & 0x30 == 'THISGFI'.  Note that
   the gfi is located in the top nibble (as it comes off the line).
   --------------------------------------------------------------------
*/

/************************************************************************/
int IDnnPkt(lsp,gfi,pti)
/************************************************************************/

/*
    The non-zero lcn lgn case.
    The PTI must aways be present in the packet, otherwise
    the type 'Undefined or not supported' should be returned
    Also, length of packet must be >= 2 octets.  This routine
    does not detect  Invalid packet type on VC (eg outgoing
    channel receives CALL).  Changes will be required if an
    alternative allocation scheme is employed for virtual
    circuit allocation (eg source/destination scheme).
*/

struct lsformat *lsp;
register unsigned char pti, gfi;

{
    register unsigned char test, conf;

    /*
	Data first, gfi has been checked
    */
    if( (pti & 1) == 0 )
	return(X_DATA);
	
    else if( (pti & 0x02)==0 )
    {
	/*
	    RR, RNR, REJ, DIAGNOSTIC
	    Note that the DIAGNOSTIC here is in error,
	    having a non-zero logical channel identifier
	    
	    Modulo 8 and 128 handled through configuration
	    and previous external check on gfi correct
	*/
	if( gfi == G_8 )
	{
	    test=pti&0x1F;   /* Strip out a possible NR for modulo 8 */
	}
	else if( gfi == G_128 )
	{
	    test=pti;        /* Nothing to strip, test pti itself */
	}
	else
	    return(X_BADGFI);

	if( test==0x01)
	    return(X_RR);

	else if (test==0x05)
	    return(X_RNR);
	    
	else if (test==0x09)
	    return(X_REJ);   /* ?? X_BADnnPTI */
	    
	else if ( pti==0xF1 && (lsp->lbase->psdn_local.SNMODES&DISC_NZ_DIAG) )
	    return(X_BADDIAG);
	    
        else
	    return(X_BADnnPTI);
    }
    else
    {
	/*
	    All other packets must have GFI of G_8 or G_128
	    except for the Call Setup packets with A-bit or D-bit
	    and Call Clear/Confirm packets with A-bit.
	*/
	conf=(pti & 0x04);
	pti &=0xFB;

	if (pti==0x0B)
	{
	    /*
		N.B. bits 8,7 may be either 0 or 1 with TOA/NPI format
	    */
	    return(conf ? X_CAA : X_CALL);
	}
	else if(pti==0x13)
	{
	    if( (gfi&0x40)==0 )
		return(conf ? X_CLC : X_CLR );
	    else
		return(X_BADGFI);
	}
	else if( gfi==G_8 || gfi==G_128 )
	{
	    if(pti==0x23)
		return(conf ? X_INC : X_INT );
	    else if(pti==0x1B)
		return(conf ? X_RSC : X_RST);
		
	    else if(pti==0xFB || pti==0xF3 )
		return(X_VCNOT0);
		
	    else
		return(X_BADnnPTI);
	}
	else
	    return(X_BADGFI);
    }
} 


/************************************************************************/
int ID00Pkt(lsp,gfi,pti)
/************************************************************************/

/*
    Zero LCN LGN Case. Smilar comments as above.
    RESTART, DIAGNOSTIC, REGISTRATION
    
*/

struct lsformat *lsp;
register unsigned char gfi,pti;

{
    register unsigned char conf, test;

    conf=(pti & 0x04);
    test=(pti & 0xFB);

    if(gfi==G_8 || gfi==G_128)
    {
	if( test==0xFB)
	    return(conf ? X_REC : X_RES);

	else if( pti==0xF1 && !(lsp->lbase->psdn_local.SNMODES&BAR_DIAG) )
	    return(X_DIAG);

	/* Check link type before 1984 packets */
	else if (lsp->ldomain == WAN80 )
	    return(X_BAD00PTI);

        else if(test==0xF3)
	    return(conf ? X_REGC : X_REG);

	else
	    return(X_BAD00PTI);
    }
    else
	return(X_BADGFI);
}
