05.11.2011 - stable version, 0.1.0, self-test program, work at GCC 2.95 - 4.5, VC 2010, MinGW, Linux, Windows, QNX
This commit is contained in:
122
piprotocol.cpp
122
piprotocol.cpp
@@ -1,9 +1,10 @@
|
||||
#include "piprotocol.h"
|
||||
|
||||
|
||||
PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * recHeaderPtr, int recHeaderSize, void * recDataPtr, int recDataSize, void * sendDataPtr_, int sendDataSize_) {
|
||||
PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * recHeaderPtr, int recHeaderSize, void * recDataPtr, int recDataSize, void * sendDataPtr_, int sendDataSize_): PIObject() {
|
||||
init();
|
||||
protName = name;
|
||||
PIObject::setName(name);
|
||||
PIConfig conf(config, PIFile::Read);
|
||||
if (!conf.isOpened()) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Can`t open \"" << config << "\"!" << endl;
|
||||
@@ -11,13 +12,13 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
return;
|
||||
}
|
||||
int ps;
|
||||
bool ok;
|
||||
bool ok, has_dev = false;
|
||||
PIFlags<PISerial::Parameters> pp;
|
||||
PIConfig::Entry b = conf.getValue(name),
|
||||
rb = b.getValue("receiver"),
|
||||
sb = b.getValue("sender");
|
||||
PIConfig::Entry & b(conf.getValue(name)),
|
||||
& rb(b.getValue("receiver")),
|
||||
& sb(b.getValue("sender"));
|
||||
PIString dev;
|
||||
|
||||
|
||||
/// receiver section
|
||||
if (rb.isEntryExists("ip") && rb.isEntryExists("device")) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl;
|
||||
@@ -35,6 +36,11 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
type_rec = PIProtocol::Ethernet;
|
||||
eth = new PIEthernet(dev, ps, this, receiveEvent);
|
||||
setReceiverAddress(dev, ps);
|
||||
has_dev = true;
|
||||
if (recDataPtr == 0)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl;
|
||||
if (recDataSize == 0)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl;
|
||||
}
|
||||
dev = rb.getValue("device", "", &ok);
|
||||
if (ok) {
|
||||
@@ -54,9 +60,22 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
ser->setInSpeed((PISerial::Speed)ps);
|
||||
ser->setParameters(pp);
|
||||
ser->setReadData(recHeaderPtr, recHeaderSize, recDataSize);
|
||||
has_dev = true;
|
||||
if (recDataPtr == 0)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl;
|
||||
if (recDataSize == 0)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl;
|
||||
}
|
||||
setExpectedFrequency(rb.getValue("frequency", -1.f));
|
||||
|
||||
float freq = rb.getValue("frequency", -1.f);
|
||||
if (freq > 0. && !has_dev)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: no receiver device and not null expected frequency!" << endl;
|
||||
float tm = b.getValue("disconnectTimeout", 3.f);
|
||||
if (tm <= 0.)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: diconnect timeout <= 0 s!" << endl;
|
||||
timeout_ = (tm < 0.) ? 0. : tm;
|
||||
setExpectedFrequency(freq);
|
||||
changeDisconnectTimeout();
|
||||
|
||||
/// sender section
|
||||
if (sb.isEntryExists("ip") && sb.isEntryExists("device")) {
|
||||
cout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl;
|
||||
@@ -64,6 +83,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
return;
|
||||
}
|
||||
dev = sb.getValue("ip", "", &ok);
|
||||
has_dev = false;
|
||||
if (ok) {
|
||||
ps = sb.getValue("port", 0, &ok);
|
||||
if (!ok) {
|
||||
@@ -74,6 +94,11 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
type_send = PIProtocol::Ethernet;
|
||||
if (eth == 0) eth = new PIEthernet(dev, ps, this, receiveEvent);
|
||||
setSenderAddress(dev, ps);
|
||||
has_dev = true;
|
||||
if (sendDataPtr_ == 0)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl;
|
||||
if (sendDataSize_ == 0)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: null send data size!" << endl;
|
||||
}
|
||||
dev = sb.getValue("device", "", &ok);
|
||||
if (ok) {
|
||||
@@ -91,9 +116,17 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
|
||||
ser->setOutSpeed((PISerial::Speed)ps);
|
||||
ser->setParameters(pp);
|
||||
ser->setReadData(recHeaderPtr, recHeaderSize, recDataSize);
|
||||
has_dev = true;
|
||||
if (sendDataPtr_ == 0)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl;
|
||||
if (sendDataSize_ == 0)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: null send data size!" << endl;
|
||||
}
|
||||
setSenderFrequency(sb.getValue("frequency", -1.f));
|
||||
|
||||
freq = sb.getValue("frequency", -1.f);
|
||||
if (freq > 0. && !has_dev)
|
||||
cout << "[PIProtocol \"" << name << "\"] Warning: no sender device and not null send frequency!" << endl;
|
||||
setSenderFrequency(freq);
|
||||
|
||||
headerPtr = (uchar * )recHeaderPtr;
|
||||
headerSize = recHeaderSize;
|
||||
dataPtr = (uchar * )recDataPtr;
|
||||
@@ -122,23 +155,36 @@ PIProtocol::~PIProtocol() {
|
||||
|
||||
void PIProtocol::init() {
|
||||
work = new_mp_prot = false;
|
||||
eth = 0;
|
||||
ser = 0;
|
||||
ret_func = 0;
|
||||
mp_owner = 0;
|
||||
net_diag = PIProtocol::Unknown;
|
||||
cur_pckt = 0;
|
||||
diagTimer = 0;
|
||||
packet = 0;
|
||||
timeout_ = 3.f;
|
||||
sendTimer = new PITimer(sendEvent, this);
|
||||
diagTimer = new PITimer(diagEvent, this);
|
||||
wrong_count = receive_count = send_count = 0;
|
||||
immediateFreq = integralFreq = 0.f;
|
||||
immediate_freq = integral_freq = 0.f;
|
||||
headerPtr = dataPtr = sendDataPtr = 0;
|
||||
headerSize = dataSize = sendDataSize = 0;
|
||||
eth = 0;
|
||||
ser = 0;
|
||||
type_rec = type_send = PIProtocol::None;
|
||||
devSenderState = devReceiverState = "Unknown";
|
||||
devSenderName = devReceiverName = "no device";
|
||||
/*addEvent("receiver started");
|
||||
addEvent("receiver stopped");
|
||||
addEvent("sender started");
|
||||
addEvent("sender stopped");
|
||||
addEvent<bool>("received");
|
||||
addEvent<PIProtocol::Quality>("quality changed");
|
||||
addEventHandler<float>(HANDLER(PIProtocol, startReceive));
|
||||
addEventHandler<float>(HANDLER(PIProtocol, startSend));
|
||||
addEventHandler(HANDLER(PIProtocol, start));
|
||||
addEventHandler(HANDLER(PIProtocol, stopReceive));
|
||||
addEventHandler(HANDLER(PIProtocol, stopSend));
|
||||
addEventHandler(HANDLER(PIProtocol, stop));*/
|
||||
}
|
||||
|
||||
|
||||
@@ -196,8 +242,13 @@ void PIProtocol::setSenderAddress(const PIString & ip, int port, bool force) {
|
||||
|
||||
void PIProtocol::setExpectedFrequency(float frequency) {
|
||||
exp_freq = frequency;
|
||||
if (exp_freq < 10.f / 3.f) pckt_cnt_max = 10;
|
||||
else pckt_cnt_max = uint(round(3.f * exp_freq));
|
||||
changeDisconnectTimeout();
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::changeDisconnectTimeout() {
|
||||
pckt_cnt_max = int(round(timeout_ * exp_freq));
|
||||
if (pckt_cnt_max < 3) pckt_cnt_max = 3;
|
||||
last_packets.resize(pckt_cnt_max);
|
||||
}
|
||||
|
||||
@@ -210,6 +261,7 @@ void PIProtocol::startReceive(float exp_frequency) {
|
||||
setExpectedFrequency(exp_freq);
|
||||
diagTimer->start(1000. / exp_freq);
|
||||
diagTimer->reset();
|
||||
raiseEvent(this, "receiver started");
|
||||
}
|
||||
|
||||
|
||||
@@ -217,6 +269,7 @@ void PIProtocol::startSend(float frequency) {
|
||||
if (frequency > 0.f) send_freq = frequency;
|
||||
if (send_freq <= 0.f) return;
|
||||
sendTimer->start(1000. / send_freq);
|
||||
raiseEvent(this, "sender started");
|
||||
}
|
||||
|
||||
|
||||
@@ -224,6 +277,7 @@ void PIProtocol::stopReceive() {
|
||||
if (type_rec == PIProtocol::Serial) ser->stop();
|
||||
if (type_rec == PIProtocol::Ethernet) eth->stop();
|
||||
diagTimer->stop();
|
||||
raiseEvent(this, "receiver stopped");
|
||||
}
|
||||
|
||||
|
||||
@@ -232,8 +286,8 @@ bool PIProtocol::receiveEvent(void * t, char * data, int size) {
|
||||
if (!p->receive(data, size)) return false;
|
||||
p->work = true;
|
||||
//p->lock();
|
||||
if (p->validate())
|
||||
{
|
||||
if (p->validate()) {
|
||||
raiseEvent<bool>(p, "received", true);
|
||||
//p->unlock();
|
||||
p->receive_count++;
|
||||
p->cur_pckt = 1;
|
||||
@@ -241,6 +295,7 @@ bool PIProtocol::receiveEvent(void * t, char * data, int size) {
|
||||
if (p->mp_owner != 0) PIMultiProtocolBase::receiveEvent(p->mp_owner, p, true, data, size);
|
||||
return true;
|
||||
}
|
||||
raiseEvent<bool>(p, "received", false);
|
||||
//p->unlock();
|
||||
p->wrong_count++;
|
||||
if (p->mp_owner != 0) PIMultiProtocolBase::receiveEvent(p->mp_owner, p, false, data, size);
|
||||
@@ -278,39 +333,54 @@ void PIProtocol::calc_diag() {
|
||||
else if (good_percents <= 20.f) diag = PIProtocol::Bad;
|
||||
else if (good_percents > 20.f && good_percents <= 80.f) diag = PIProtocol::Average;
|
||||
else diag = PIProtocol::Good;
|
||||
if (diag != net_diag) net_diag = diag;
|
||||
if (diag != net_diag) {
|
||||
net_diag = diag;
|
||||
raiseEvent<PIProtocol::Quality>(this, "quality changed", diag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::calc_freq() {
|
||||
tf = float(1000.f / diagTimer->elapsed_m());
|
||||
float tf = float(1000.f / diagTimer->elapsed_m());
|
||||
diagTimer->reset();
|
||||
if (cur_pckt != 1) tf = 0.f;
|
||||
immediateFreq = tf;
|
||||
if (last_freq.size() >= pckt_cnt_max) last_freq.pop_front();
|
||||
immediate_freq = tf;
|
||||
if (last_freq.size_s() >= pckt_cnt_max && last_freq.size_s() > 0) last_freq.pop_front();
|
||||
last_freq.push_back(tf);
|
||||
tf = last_freq[0];
|
||||
for (uint i = 1; i < last_freq.size(); ++i)
|
||||
tf += last_freq[i];
|
||||
integralFreq = tf / last_freq.size();
|
||||
integral_freq = tf / last_freq.size();
|
||||
}
|
||||
|
||||
|
||||
void PIProtocol::check_state() {
|
||||
if (type_rec == PIProtocol::Serial) {
|
||||
if (ser->initialized()) devReceiverState = "Initialized";
|
||||
if (ser != 0) {
|
||||
if (ser->initialized()) devReceiverState = "Initialized";
|
||||
else devReceiverState = "Uninitialized";
|
||||
}
|
||||
else devReceiverState = "Uninitialized";
|
||||
}
|
||||
if (type_rec == PIProtocol::Ethernet) {
|
||||
if (eth->receiverInitialized()) devReceiverState = "Initialized";
|
||||
if (eth != 0) {
|
||||
if (eth->receiverInitialized()) devReceiverState = "Initialized";
|
||||
else devReceiverState = "Uninitialized";
|
||||
}
|
||||
else devReceiverState = "Uninitialized";
|
||||
}
|
||||
if (type_send == PIProtocol::Serial) {
|
||||
if (ser->initialized()) devSenderState = "Initialized";
|
||||
if (ser != 0) {
|
||||
if (ser->initialized()) devSenderState = "Initialized";
|
||||
else devSenderState = "Uninitialized";
|
||||
}
|
||||
else devSenderState = "Uninitialized";
|
||||
}
|
||||
if (type_send == PIProtocol::Ethernet) {
|
||||
if (eth->senderInitialized()) devSenderState = "Initialized";
|
||||
if (eth != 0) {
|
||||
if (eth->senderInitialized()) devSenderState = "Initialized";
|
||||
else devSenderState = "Uninitialized";
|
||||
}
|
||||
else devSenderState = "Uninitialized";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user