package thundernet.afp;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  AFPpacket.java                     Copyright (c) ThunderNet Productions  */
/*                                     2001.  All rights reserved.           */
/*                                                                           */
/*  Defines the AFPpacket data structure.                                    */
/*                                                                           */
/*  Public Methods:                                                          */
/*      AFPpacket()                                                          */
/*      assemble()                                                           */
/*      clear()                                                              */
/*      recv()                                                               */
/*      send()                                                               */
/*      toString()                                                           */
/*                                                                           */
/*  Date      Who  Comment                                                   */
/*  -----------------------------------------------------------------------  */
/*  24mar01   acp  initial creation                                          */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

import  thundernet.util.tools;
import  java.io.*;



public class AFPpacket
{

    public static final byte    CMD_AUTHENTICATE= (byte)0x03;
    public static final byte    CMD_LOGIN_ERROR = (byte)0x04;
    public static final byte    CMD_OK_TO_SEND  = (byte)0x05;
    public static final byte    CMD_EDX_MESSAGE = (byte)0x06;
    public static final byte    CMD_QUERY       = (byte)0x07;
    public static final byte    CMD_EVENT       = (byte)0x08;
    public static final byte    CMD_ACK         = (byte)0x80;
    public static final byte    CMD_RESPONSE    = (byte)0x81;
    public static final byte    CMD_NACK        = (byte)0x82;
    public static final byte    EOT             = (byte)0x04;
    public static final byte    PRIORITY_EDX    = (byte)0x01;
    public static final byte    PRIORITY_EVENT  = (byte)0x02;
    public static final byte    PRIORITY_QUERY  = (byte)0x03;
    public static final byte    VERSION_1_0     = (byte)0x10;
    public static final byte    TYPE_EDX_MSG    = (byte)0xf1;
    public static final byte    TYPE_QUERY_MSG  = (byte)0xf2;

    //
    // public attributes
    //
    public  byte    type;
    public  byte[]  ID = new byte[6];
    public  byte    version;
    public  byte    cmd;
    public  byte    priority;
    public  byte[]  length = new byte[8];
    public  byte[]  body;
    public  byte    eot;

    //
    // private constants
    //
    private final int           SZ_NOBODY       = 19;



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  AFPpacket()                        Copyright (c) ThunderNet Productions  */
/*                                     2001.  All rights reserved.           */
/*                                                                           */
/*  Primary constructor.  Initializes internal data.                         */
/*                                                                           */
/*  args:                                                                    */
/*       none      no comment                                                */
/*                                                                           */
/*  return:                                                                  */
/*       n/a                                                                 */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
public AFPpacket()
{



}   /* end of method AFPpacket() */



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  assemble()                         Copyright (c) ThunderNet Productions  */
/*                                     2001.  All rights reserved.           */
/*                                                                           */
/*  Assembles the contents of this packet into one byte array and returns it.*/
/*                                                                           */
/*  args:                                                                    */
/*       none      no comment                                                */
/*                                                                           */
/*  return:                                                                  */
/*       byte[]     single assembled packet                                  */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
public byte[] assemble()
{

    byte[]      packet;

    packet = new byte[SZ_NOBODY + ((body != null) ? body.length : 0)];

    packet[0] = type;
    System.arraycopy(ID, 0, packet, 1, ID.length);
    packet[7] = version;
    packet[8] = cmd;
    packet[9] = priority;
    System.arraycopy(length, 0, packet, 10, length.length);
    if (body != null)
    {
        System.arraycopy(body, 0, packet, 18, body.length);
    }
    packet[18 + ((body != null) ? body.length : 0)] = eot;

    return packet;

}   /* end of method assemble() */



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  clear()                            Copyright (c) ThunderNet Productions  */
/*                                     2001.  All rights reserved.           */
/*                                                                           */
/*  Clears out this packet to default values.                                */
/*                                                                           */
/*  args:                                                                    */
/*       none           no comment                                           */
/*                                                                           */
/*  return:                                                                  */
/*       none                                                                */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
public void clear()
{

    type        = (byte)0x00;
    ID[0]       = (byte)0x00;
    ID[1]       = (byte)0x00;
    ID[2]       = (byte)0x00;
    ID[3]       = (byte)0x00;
    ID[4]       = (byte)0x00;
    ID[5]       = (byte)0x00;
    version     = (byte)0x00;
    cmd         = (byte)0x00;
    priority    = (byte)0x00;
    length[0]   = (byte)0x00;
    length[1]   = (byte)0x00;
    length[2]   = (byte)0x00;
    length[3]   = (byte)0x00;
    length[4]   = (byte)0x00;
    length[5]   = (byte)0x00;
    length[6]   = (byte)0x00;
    length[7]   = (byte)0x00;
    body        = null;
    eot         = (byte)0x00;

}   /* end of method clear() */



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  recv()                             Copyright (c) ThunderNet Productions  */
/*                                     2001.  All rights reserved.           */
/*                                                                           */
/*  Receives an AFP packet from the given input stream.                      */
/*      object.  If this method returns true, it only means that it's        */
/*      possible that the received packet is valid, this method does not     */
/*      verify all the depenedencies, etc.                                   */
/*                                                                           */
/*  args:                                                                    */
/*      argIn           stream on which to receive the packet                */
/*                                                                           */
/*  return:                                                                  */
/*       boolean        indicates good/bad packet reception                  */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
public boolean recv(BufferedInputStream in) throws java.io.IOException, java.net.SocketException
{

    byte[]  body;
    int     body_length;
    int     c;          // count of bytes read in via in.read()
    boolean rc = false;

    type = (byte)(in.read() & 0xff);
    if ((type == AFPpacket.TYPE_EDX_MSG) || (type == AFPpacket.TYPE_QUERY_MSG))
    {
        c = in.read(ID, 0, ID.length);
        if (c == ID.length)
        {
            version = (byte)(in.read() & 0xff);
            if (version == AFPpacket.VERSION_1_0)
            {
                cmd = (byte)(in.read() & 0xff);
                if (cmd != -1)
                {
                    priority = (byte)(in.read() & 0xff);
                    if ((priority == AFPpacket.PRIORITY_EDX)
                     || (priority == AFPpacket.PRIORITY_EVENT)
                     || (priority == AFPpacket.PRIORITY_QUERY))
                    {
                        c = in.read(length, 0, length.length);
                        if (c == length.length)
                        {
                            //
                            // calculate body length and read body
                            //
                            body_length = tools.byteArray2Int(length, 4, 1);
                            body = new byte[body_length];
                            c = in.read(body, 0, body_length);
                            if (c == body_length)
                            {
                                body = body;
                                eot = (byte)(in.read() & 0xff);
                                if (eot == AFPpacket.EOT)
                                {
                                    rc = true;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    return rc;

}   /* end of method recv() */



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  send()                             Copyright (c) ThunderNet Productions  */
/*                                     2001.  All rights reserved.           */
/*                                                                           */
/*  Sends this AFP packet to the server on the given stream.                 */
/*                                                                           */
/*  args:                                                                    */
/*      out             output stream to write packet to                     */
/*                                                                           */
/*  return:                                                                  */
/*       none                                                                */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
public void send(OutputStream out) throws java.io.IOException
{

    out.write(assemble());
    out.flush();

}   /* end of method send() */



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  toString()                         Copyright (c) ThunderNet Productions  */
/*                                     2001.  All rights reserved.           */
/*                                                                           */
/*  Formats this packet nicely for output.                                   */
/*                                                                           */
/*  args:                                                                    */
/*      none            no comment                                           */
/*                                                                           */
/*  return:                                                                  */
/*      none                                                                 */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
public String toString()
{

    StringBuffer    buf;
    int             body_length;

    if (body != null)
    {
        buf = new StringBuffer(SZ_NOBODY + body.length);
    }
    else
    {
        buf = new StringBuffer(SZ_NOBODY);
    }

    buf.append("type:     " + new String(tools.byte2hex(type)) + "\n");
    buf.append("ID:       " + new String(tools.byte2hex(ID[0])) + " " +
                              new String(tools.byte2hex(ID[1])) + " " +
                              new String(tools.byte2hex(ID[2])) + " " +
                              new String(tools.byte2hex(ID[3])) + " " +
                              new String(tools.byte2hex(ID[4])) + " " +
                              new String(tools.byte2hex(ID[5])) + "\n");
    buf.append("version:  " + new String(tools.byte2hex(version)) + "\n");
    buf.append("cmd:      " + new String(tools.byte2hex(cmd)) + "\n");
    buf.append("priority: " + new String(tools.byte2hex(priority)) + "\n");
    buf.append("length:   " + new String(tools.byte2hex(length[0])) + " " +
                              new String(tools.byte2hex(length[1])) + " " +
                              new String(tools.byte2hex(length[2])) + " " +
                              new String(tools.byte2hex(length[3])) + " " +
                              new String(tools.byte2hex(length[4])) + " " +
                              new String(tools.byte2hex(length[5])) + " " +
                              new String(tools.byte2hex(length[6])) + " " +
                              new String(tools.byte2hex(length[7])) + "\n");

    if (body != null)
    {
        buf.append("body:     ");
        body_length = body.length;
        for (int i = 0; i < body_length; i++)
        {
            if ((i % 32) == 31)
            {
                buf.append("\n          ");
            }
            buf.append(new String(tools.byte2hex(body[i])) + " ");
        }
        buf.append("\n");
    }

    buf.append("eot:      " + new String(tools.byte2hex(eot)) + "\n");

    return buf.toString();

}   /* end of method toString() */

}   /* end of class AFPpacket */


  Copyright © Thundernet Development Group Inc., 2003.
All rights reserved.