XbeeLink.cpp 4.3 KB
Newer Older
Franz's avatar
Franz committed
1 2 3 4 5 6 7 8
#include <qdebug.h>
#include <QThread>
#include <QMutex>
#include <MG.h>
#include<string>
#include "XbeeLink.h"

XbeeLink::XbeeLink(QString portName, int baudRate) : 
Don Gagne's avatar
Don Gagne committed
9 10 11 12 13 14 15
	m_xbeeCon(NULL),
    m_portName(NULL),
    m_portNameLength(0),
    m_baudRate(baudRate),
    m_connected(false),
	m_addrHigh(0),
    m_addrLow(0)
Franz's avatar
Franz committed
16 17 18 19 20 21 22 23 24 25 26 27 28
{

	/* setup the xbee */
	this->setPortName(portName);
}

XbeeLink::~XbeeLink()
{
	if(m_portName)
	{
		delete m_portName;
		m_portName = NULL;
	}
29
	_disconnect();
Franz's avatar
Franz committed
30 31
}

32
QString XbeeLink::getPortName() const
Franz's avatar
Franz committed
33 34 35 36 37 38 39 40 41
{
	QString portName;
	for(unsigned int i = 0;i<this->m_portNameLength;i++)
	{
		portName.append(this->m_portName[i]);
	}
	return portName;
}

42
int XbeeLink::getBaudRate() const
Franz's avatar
Franz committed
43 44 45 46 47 48 49 50 51
{
	return this->m_baudRate;
}

bool XbeeLink::setPortName(QString portName)
{
	bool reconnect(false);
	if(this->m_connected)
	{
52
		_disconnect();
Franz's avatar
Franz committed
53 54 55 56 57 58 59 60 61 62 63 64 65 66
		reconnect = true;
	}
	if(m_portName)
	{
		delete m_portName;
		m_portName = NULL;
	}
	QStringList list = portName.split(QRegExp("\\s+"),QString::SkipEmptyParts);
	if(list.size()>0)
	{
		this->m_portNameLength = list[0].size()+1;
		m_portName = new char[this->m_portNameLength];
		for(int i=0;i<list[0].size();i++)
		{
67
			this->m_portName[i]=list[0][i].toLatin1();
Franz's avatar
Franz committed
68 69 70 71 72 73 74 75 76 77 78 79 80
		}
		this->m_portName[list[0].size()] = '\0';
	}
	else
	{
		this->m_portNameLength = 1;
		m_portName = new char[this->m_portNameLength];
		this->m_portName[0] = '\0';
	}
	
	bool retVal(true);
	if(reconnect)
	{
81
		retVal = _connect();
Franz's avatar
Franz committed
82 83 84 85 86 87 88 89 90 91
	}

	return retVal;
}

bool XbeeLink::setBaudRate(int rate)
{
	bool reconnect(false);
	if(this->m_connected)
	{
92
		_disconnect();
Franz's avatar
Franz committed
93 94 95 96 97 98
		reconnect = true;
	}
	bool retVal(true);
	this->m_baudRate = rate;
	if(reconnect)
	{
99
		retVal = _connect();
Franz's avatar
Franz committed
100 101 102 103
	}
	return retVal;
}

104
QString XbeeLink::getName() const
Franz's avatar
Franz committed
105 106 107 108
{
	return this->m_name;
}

109
bool XbeeLink::isConnected() const
Franz's avatar
Franz committed
110 111 112 113
{
	return this->m_connected;
}

114
qint64 XbeeLink::getConnectionSpeed() const
Franz's avatar
Franz committed
115 116 117
{
	return this->m_baudRate;
}
118 119 120 121 122 123 124 125 126 127 128

qint64 XbeeLink::getCurrentInDataRate() const
{
    return 0;
}

qint64 XbeeLink::getCurrentOutDataRate() const
{
    return 0;
}

Franz's avatar
Franz committed
129 130
bool XbeeLink::hardwareConnect()
{
oberion's avatar
oberion committed
131
	emit tryConnectBegin(true);
Franz's avatar
Franz committed
132 133
	if(this->isConnected())
	{
134
		_disconnect();
Franz's avatar
Franz committed
135 136 137 138 139 140 141 142 143
	}
	if (*this->m_portName == '\0')
	{
		return false;
	}
	if (xbee_setupAPI(this->m_portName,this->m_baudRate,0x2B,0x3E8) == -1) 
		{
		  /* oh no... it failed */
			qDebug() <<"xbee_setup() failed...\n";
oberion's avatar
oberion committed
144
			emit tryConnectEnd(true);
Franz's avatar
Franz committed
145 146 147
			return false;
		}
	this->m_xbeeCon = xbee_newcon('A',xbee2_data,0x13A200,0x403D0935);
oberion's avatar
oberion committed
148
	emit tryConnectEnd(true);
Franz's avatar
Franz committed
149 150 151 152 153
	this->m_connected = true;
	emit connected();
	return true;
}

154
bool XbeeLink::_connect(void)
Franz's avatar
Franz committed
155
{
156
	if (this->isRunning()) _disconnect();
Franz's avatar
Franz committed
157 158 159 160
    this->start(LowPriority);
    return true;
}

161
bool XbeeLink::_disconnect(void)
Franz's avatar
Franz committed
162 163 164 165 166
{
	if(this->isRunning()) this->terminate(); //stop running the thread, restart it upon connect

	if(this->m_xbeeCon)
	{
oberion's avatar
oberion committed
167
		xbee_end();
Franz's avatar
Franz committed
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
		this->m_xbeeCon = NULL;
	}
	this->m_connected = false;

	emit disconnected();
	return true;
}

void XbeeLink::writeBytes(const char *bytes, qint64 length)  // TO DO: delete the data array
{
	char *data;
	data = new char[length];
	for(long i=0;i<length;i++)
	{
		data[i] = bytes[i];
	}
	if(!xbee_nsenddata(this->m_xbeeCon,data,length)) // return value of 0 is successful written
	{
186
		_logOutputDataRate(length, QDateTime::currentMSecsSinceEpoch());
Franz's avatar
Franz committed
187 188 189
	}
	else
	{
190
		_disconnect();
191
		emit communicationError(tr("Link Error"), QString("Error on link: %1. Could not send data - link is disconnected!").arg(getName()));
Franz's avatar
Franz committed
192 193 194 195 196 197 198 199 200 201 202 203 204
	}
}

void XbeeLink::readBytes()
{
	xbee_pkt *xbeePkt;
	xbeePkt = xbee_getpacketwait(this->m_xbeeCon);
	if(!(NULL==xbeePkt))
	{
		QByteArray data;
		for(unsigned int i=0;i<=xbeePkt->datalen;i++)
		{
			data.push_back(xbeePkt->data[i]);
205 206
        }

207 208
		_logInputDataRate(data.length(), QDateTime::currentMSecsSinceEpoch());
		emit bytesReceived(this, data);
Franz's avatar
Franz committed
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
	}
}

void XbeeLink::run()
{
    // Initialize the connection
	if(this->hardwareConnect())
	{
		// Qt way to make clear what a while(1) loop does
		forever 
		{
			this->readBytes();
	    }
	}
}

oberion's avatar
oberion committed
225 226 227 228 229 230 231 232 233 234 235 236
bool XbeeLink::setRemoteAddressHigh(quint32 high)
{
	this->m_addrHigh = high;
	return true;
}

bool XbeeLink::setRemoteAddressLow(quint32 low)
{
	this->m_addrLow = low;
	return true;
}

Franz's avatar
Franz committed
237 238 239 240 241 242 243 244 245
/*
void CALLTYPE XbeeLink::portCallback(xbee_con *xbeeCon, xbee_pkt *XbeePkt)
{
	QByteArray buf;
	for(quint8 i=0;i<XbeePkt->datalen;i++)
	{
		buf.push_back(XbeePkt->data[i]);
	}
	emit bytesReceived(this, buf);
246
}*/