/*
 * SmartHome server: Plug-in xbee
 *
 * Copyright (C) 2010 Daniel Pisi <dan.pisi@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License
 * as published by the Free Software Foundation.
 *
 */

/**
 * @file xbinterface.cpp
 * @brief Interfaces Digi XBee2 module via serial port
 * @author Daniel Pisi
 */

#include "xbinterface.h"

// -----------------------------------------------------------------------------

XbInterface::XbInterface(QString param, QObject *parent) : QObject(parent)
{
    mState = 0;
    mSize  = 0;
    mIndex = 0;

    mXbeePort = new QextSerialPort(param, QextSerialPort::EventDriven);
    mXbeePort->setBaudRate(BAUD9600);
    mXbeePort->setFlowControl(FLOW_OFF);
    mXbeePort->setDataBits(DATA_8);
    mXbeePort->setParity(PAR_NONE);
    mXbeePort->setStopBits(STOP_1);

    if (mXbeePort->open(QIODevice::ReadWrite) == true)
    {
        connect(mXbeePort, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
    }
    else
        qWarning(QString("Opening the XBee device failed: %1").arg(mXbeePort->errorString()).toLatin1());
}
// -----------------------------------------------------------------------------

void XbInterface::onReadyRead()
{
    char b;

    while (mXbeePort->bytesAvailable())
    {
        mXbeePort->read(&b, 1);

        switch (mState)
        {
        case 0:
            // start byte
            if (b == 0x7E)
            {
                mBuffer[mIndex++] = b;
                mState = 1;
            }
            break;
        case 1:
            // packet size MSB
            mBuffer[mIndex++] = b;
            mSize = b * 256;
            mState = 2;
            break;
        case 2:
            // packet size LSB
            mBuffer[mIndex++] = b;
            mSize += b;
            mState = 3;
            break;
        case 3:
            // packet data
            mBuffer[mIndex++] = b;
            mSize--;

            if (mSize == 0)
                mState = 4;
            break;
        case 4:
            // checksum
            mBuffer[mIndex++] = b;
            QByteArray data(mBuffer, mIndex);

            if (XbPacket::valid(data))
                emit newPacketReceived(data);

            mState = 0;
            mIndex = 0;
            break;
        }
    }
}
// -----------------------------------------------------------------------------

void XbInterface::sendPacket(XbPacket &packet)
{
    mXbeePort->write(packet.frameData());
}
// -----------------------------------------------------------------------------
