/* 
 * File:   cKlinkDevice.h
 * Author: john
 *
 * Created on 08 April 2011, 9:30 AM
 */

#ifndef CKLINKDEVICE_H
#define	CKLINKDEVICE_H

#include <stdint.h>
#include <klog.h>

#include <cKlinkFrame.h>
#include <cKlinkPduFrame.h>
#include <cKlinkDebug.h>
#include <cKlinkTimer.h>
#include <cKlinkDeviceListener.h>

class cKlinkDevice : public cKlog
{
public:
        enum eDeviceStatus
    {
        DEVICE_STATUS_MISSING_IN_ACTION,
        DEVICE_STATUS_ADDRESS_PENDING,
        DEVICE_STATUS_OPERATIONAL,
        DEVICE_STATUS_UNKNOWN,
    };

    cKlinkDevice();
    cKlinkDevice(uint32_t);
    cKlinkDevice(const cKlinkDevice& orig);
    virtual ~cKlinkDevice();
    uint8_t getBusAddress();
    uint16_t getDeviceType();
    uint32_t getSerialNumber();
    void setBusAddress(uint8_t);
    cKlinkFrame * getNextFrame();
    void handlePduFrame(cKlinkPduFrame *f);
    eDeviceStatus getDeviceStatus();
    void setDeviceStatus(eDeviceStatus s);
    void serviceTimers();
    void sendAckPDUFrame(cKlinkPdu *pdu);
    virtual void processPdu(cKlinkPdu *pdu) = 0;
    void setDeviceListener(cKlinkDeviceListener *dl);
protected:
    uint32_t mSerialNumber;
    uint16_t mDeviceType;
private:
    uint8_t mBusAddress;
    uint8_t mCurrFrameNumber;
    uint8_t mCurrAckNumber;
    eDeviceStatus mDeviceStatus;
    cKlinkTimer mLinkTimer;
    cKlinkEnumeratedList<cKlinkPdu> mAckPDUQueue;
    cKlinkEnumeratedList<cKlinkPdu> mStreamPDUQueue; 
    void ackPdu(uint8_t ack_num);
    cKlinkDeviceListener * mDeviceListener;
};

#endif	/* CKLINKDEVICE_H */

