/**********************************************************************************************
    Copyright (C) 2007 Oliver Eichler oliver.eichler@gmx.de

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA

  Garmin and MapSource are registered trademarks or trademarks of Garmin Ltd.
  or one of its subsidiaries.

**********************************************************************************************/

#ifndef ILINK_H
#define ILINK_H
#include "Platform.h"

#define GUSB_MAX_BUFFER_SIZE    0x1000
#define GUSB_HEADER_SIZE        0x000C
#define GUSB_PAYLOAD_SIZE       (GUSB_MAX_BUFFER_SIZE - GUSB_HEADER_SIZE)

namespace Garmin
{
#pragma pack(1)
    struct Packet_t
    {
        Packet_t(uint8_t type, uint16_t id)
            : type(type), b1(0), b2(0), b3(0), id(id), b6(0), b7(0), size(0){}
        Packet_t()
            : type(0), b1(0), b2(0), b3(0), id(0), b6(0), b7(0), size(0){}
        uint8_t  type;
        uint8_t  b1;
        uint8_t  b2;
        uint8_t  b3;
        uint16_t id;
        uint8_t  b6;
        uint8_t  b7;
        uint32_t size;
        uint8_t  payload[GUSB_PAYLOAD_SIZE+4];
    };
#ifdef WIN32
#pragma pack()
#else
#pragma pack(0)
#endif

    /// Base class for all link objects
    /**
        Use CUSB and CSerial to exchange messages with your
        device.

        Do not forget that you communicate to a plug-n-play device.
        The user might disconnect without notice. Another
        application might access the device, too. Thus open the link for
        each exchange and close it after the exchange. The _acquire() and
        _release()  method of the driver implementation shoud be a good
        place to use open() and close().

    */
    class ILink
    {
        public:
            ILink();
            virtual ~ILink();

            virtual void open() = 0;
            virtual void close() = 0;

            virtual int read(Packet_t& data) = 0;
            virtual void write(const Packet_t& data) = 0;

    };

}
#endif                           //ILINK_H
