// $Id: epacket.h,v 1.35 2013/03/22 17:37:17 lpoulsen Exp $
// Copyright (C) 2001 Wi_LAN Technologies, Inc
//
// $Log: epacket.h,v $
// Revision 1.35  2013/03/22 17:37:17  lpoulsen
// Allow "econ -r name" to make one connection with the named radio
//     without ever entering the Econsole> command prompt.
//
// Revision 1.34  2012/05/08 18:24:00  lpoulsen
// Compile all modules with -pthread on Linux
// Clean up all compiler warnings
// Count packets in OUT OF MEMORY message
//
// Revision 1.33  2011/10/07 00:54:08  lpoulsen
// Add "diagnose" command.
// Handle automatic adding of the correct extension for a download file
//    in networks with mixed radio types.
//
// Revision 1.32  2011/05/19 00:39:42  lpoulsen
// Tighten types to avoid warning
//
// Revision 1.31  2011/02/22 00:02:23  lpoulsen
// Show device table after F4 disconnect
// Clear device table before new discovery
// Use device type = 0x8086 for PCs
//
// Revision 1.30  2011/02/08 22:07:02  lpoulsen
// evived the LINUX build of ECON - now ECON-PLUS
//
// Revision 1.29  2011/02/04 22:29:07  lpoulsen
// Many little fixes.
//
// Revision 1.28  2011/01/22 01:29:05  lpoulsen
// Release candidate:
// - allow "show first=1 max=45" to support large systems
// - allow "sort by=distance" to support "connect all reboot"
// - improve download efficiency
//
// Revision 1.27  2011/01/11 00:51:13  lpoulsen
// When operating in batch mode,
// - print progress after each session (2 of 5)
// - save session result code to device table to be printed with "show"
//
// Revision 1.26  2010/12/28 20:07:11  lpoulsen
// Fix several problems in download command
//
// Revision 1.25  2010/12/22 17:36:33  lpoulsen
// Select/Deselect list of ranges
// Expand to up to 511 radios
// Protocol fixes
//
// Revision 1.24  2008/08/21 18:23:41  lpoulsen
// Works with scripts on v4 embedded protocols
//
// Revision 1.23  2008/08/19 00:38:29  lpoulsen
// Rewritten core protocol module
//
// Revision 1.22  2008/08/05 23:58:37  lpoulsen
// User interface updates.
//
// Revision 1.21  2008/07/26 02:00:48  lpoulsen
// Econ protocol version 4 - prompt bit
//
// Revision 1.20  2008/07/11 20:14:10  lpoulsen
// Resolve many compiler warnings on Linux
//
// Revision 1.19  2008/07/11 16:28:46  lpoulsen
// Econ 4.00 release candidate supports UPDATE and SELECT commands.
//
// Revision 1.18  2008/05/31 00:35:09  lpoulsen
// Econ 4.x preview - now with command shell
//
// Revision 1.17  2008/05/10 01:17:37  lpoulsen
// Making econ -x filename work (not yet complete)
//
// Revision 1.16  2006/06/06 02:03:29  lpoulsen
// First attempt at compiling on MAC OS X
//
// Revision 1.15  2006/02/21 01:04:09  lpoulsen
// Now compiles on linux as well as on Windows with Visual Studio 2005 Express
//
// Revision 1.14  2006/02/21 00:48:49  lpoulsen
// Update to work with libnet 1.1 - much easier and modern.
//
// Revision 1.13  2005/06/23 00:13:30  lpoulsen
// Reduce dependency on pthread.h implementation specifics.
//
// Revision 1.12  2004/01/16 02:10:38  lpoulsen
// Use malloc instead of static for stored packet
//
// Revision 1.11  2003/12/23 22:28:42  lpoulsen
// Fix BOOL for Linux build.
//
// Revision 1.10  2003/12/23 21:38:05  lpoulsen
// Display firmware version if available
//
// Revision 1.9  2003/12/23 04:35:42  lpoulsen
// EConsole protocol version 2 support.
// Respond to IDENTIFY_REQUEST (version 1 and version 2 format) with
//      version 2 format IDENTIFY_RESPONSE.
//
// Revision 1.8  2003/08/25 20:20:15  lpoulsen
// Remove obsolete prototype.
//
// Revision 1.7  2003/08/22 01:46:32  lpoulsen
// Make econ compile on Linux again.
//
// Revision 1.6  2003/08/21 23:46:51  lpoulsen
// Improved handling of -r option to allow selection by name
// Miscellaneous minor cleanup
//
// Revision 1.5  2003/03/11 01:14:13  lpoulsen
// Correct compile errors found in Calgary.
//
// Revision 1.4  2002/10/16 16:59:47  mourlouk
// Improved way of retrieving MAC addresses - VAL support
//
// Revision 1.3  2002/04/19 19:04:44  mourlouk
// Release 1.15 - It fixes a bug that was introduced in version 1.13 (econ unable to
// read properly multiple MAC addresses)
//
// Revision 1.2  2001/10/30 01:07:45  lpoulsen
// Add "module ID" statement, audit trail generator and copyright line
// Remove "win_or_linux.h" and use a -D in Linux makefile instead.
//
#ifndef _EPACKET_H
#define _EPACKET_H

//** includes ........................................................
#ifdef LINUX
#include <sys/time.h>
#define FALSE false
#define TRUE  true
#else
#include <time.h>
#endif
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

//** types  ..........................................................

typedef enum {
  SESSION_INIT,
  SESSION_REQUEST_WAIT,
  SESSION_RESPONSE_WAIT,
  SESSION_CONNECT_WAIT,
  SESSION_COMMAND_MODE,
  SESSION_FILE_REQUEST,
  SESSION_TRANSFER_MODE,
  SESSION_CLOSE_WAIT,
  SESSION_CLOSED
} session_state;

typedef enum {
  CONSOLE_COMMAND  = 0,
  CONSOLE_TEXT_DATA= 1,
  EMPTY            = 2,
  BREAK            = 3,
  IDENTIFY_REQUEST = 4,
  IDENTIFY_RESPONSE= 5,
  CONNECT_REQUEST  = 6,
  CONNECT_RESPONSE = 7,
  CLOSE_REQUEST    = 8,
  FILE_REQUEST     = 9,
  FILE_RESPONSE    =10,
  FILE_DATA        =11,
  END_OF_DATA      =12,
  GO_AWAY          =13  
} pdu_type;

//** structures .......................................................

#define PROTOCOL_VERSION 4
#define PROTO_POSITION   48

#ifdef LINUX
#define PACK_STRUCT __attribute__((packed))
#else
#pragma pack(push,1)
#endif

typedef struct {
    macAddr epkt_dest;
    macAddr epkt_src;
    uint16  epkt_proto;    // length in SNAP packets
#ifndef WIN32
    char    epkt_payload[0];
#endif
} epkt_header;

#define ECFLAG_FROM_FILE 0x0001
#define ECFLAG_QUEUEDATA 0x0002
#define ECFLAG_WAITING   0x0004
#define ECFLAG_RETRANS   0x0100

#define HW_TYPE_PC       0x8086

typedef struct {
    unsigned char econ_snapid[8];
    uint16        econ_pdu;
    uint16        econ_conn_id;
    uint16        econ_flags;
    uint32        econ_tseq;
    uint32        econ_rseq;
    uint32        econ_nbytes;
    char          econ_data[PROTO_POSITION-1]; // Node name in IDENTIFY_RESPONSE
    uint8         econ_version;
    uint32        econ_ip_addr;
    uint32        econ_uptime;
    char          econ_sw_type[16];
    uint32        econ_hw_type;
}
#ifdef LINUX
  PACK_STRUCT
#endif
               econ_header;

#define ECON_HEADER_SIZE 26
#define MAX_ENET_PACKET_SIZE 1522 // 14+4+1500+4 bytes

typedef struct {
    epkt_header   econ_ehdr;
    econ_header   econ_chdr;
} econ_packet;

typedef struct {
    macAddr     epkt_dest;
    macAddr     epkt_src;
    uint16      epkt_8100;     // constant VLAN identifier
    uint16      epkt_VLAN_tci; // specific VLAN identifier
    uint16      epkt_proto;    // length in SNAP packets
    econ_header econ_chdr;
} econ_packet_vlan;

typedef struct {
    char          econ_nodename[16]; // left-justified, null-padded
    unsigned char econ_proto_vers;   //
} econ_id_vers;


#ifdef LINUX
#else
#pragma pack(pop)
#endif

struct device_entry {
    uint16        device_flags;
    macAddr       mac_address;
    char          radio_name[64];
    char          firmware[16];
    uint16        device_type;
    unsigned char proto_version;
    time_t        datestamp;
    uint32        ip_address;
    uint32        device_uptime;
    int32         connect_result;
    uint16        rtt_ms;
    int16         rtt_cnt;
};
#define DEVFLAG_DO_BATCH   0x0001
#define DEVFLAG_BATCH_DONE 0x0002
#define DEVFLAG_SELECTED   0x0004

struct ether_session {
    session_state state;
    macAddr       destination_address;
    time_t        datestamp;
    unsigned char proto_version;

    char         *filename_in; 
    char         *filename_out;   
    FILE         *file_in;
    FILE         *file_out;
    int           file_in_position;
    int           file_out_position;

    void         *last_rec_pkt;

    uint16        PDU; 
    uint16        ConnectionID;
    uint16        server_flags;
    uint32        TSEQ;
    uint32        RSEQ;
    uint32        last_TSEQ_acked;
    uint32        last_ack_RSEQ;
    uint32        NBytes;
};

struct vlan_tag {
   unsigned short tpid;
   unsigned short tci;
};

typedef struct {
    uint16 put_ix;
    uint16 get_ix;
    uchar  storage[256];
} ringbuf_256;

//** Error codes ...................................................
//** defines/consts

#define MAX_DEVICES       512
#define MIN_PACKET_SIZE   40
#define MAX_PACKET_SIZE   1640
#define VLAN_TAG_SIZE     4

//** global variables ..................................................
extern struct device_entry  afar_device[MAX_DEVICES];
extern struct ether_session active_session, *econ_session;
extern struct vlan_tag      gVLAN_tag;
extern boolean              gVLAN_mode;
extern ringbuf_256          econ_outq;
extern int                  active_device;

//** functions prototypes ..............................................
extern int     add_to_char_q(ringbuf_256 *char_q, uchar *data, int bytes_read);
extern boolean alreadyReceivedPacket(unsigned char *pChar, uint32 NBytes,
                                                     uint32 TSEQ, uint32 RSEQ);
extern void    build_econ_packet(econ_packet *packetbuff,
                              struct ether_session *cur_session,
                              uint8 *data, size_t *data_size);
extern void    connectToServer(int session_id);
extern boolean connect_to_server(int radioID);
extern int     doFileTransfer(struct ether_session *cur_session);
extern boolean ether_send(struct ether_session *cur_session, uint8 *input_data,
                       size_t data_size);
extern boolean isEtherConsolePacket(econ_packet *ecp);
extern int     process_packet(econ_packet *econ_pkt,int packet_size);
extern void    remove_output_buffer(int session_id,int* bytes_sent);
extern void    retranConnectPacket(int session_id);
extern void    retranDiscoveryPacket();
extern void    sendCancelOperationMessage(int sessionId, char *msg);
extern void    startDiscovery();
extern int     start_discovery();

#endif // _EPACKET_H

// End
