18.03.2013 - Bug fixes, add in/out speed diagnostic to PIProtocol, fixed PIConsole tab switch segfault, PIObject EVENT / EVENT_HANDLER mechanism update - new EVENT macros that use EVENT_HANDLER with raiseEvent implementation.

This allow compile check event for CONNECT and use EVENT as CONNECT target, also raise event now is simple execute EVENT function.
This commit is contained in:
peri4
2013-03-18 12:07:44 +04:00
parent cfc5eed75e
commit 66c53a27fc
72 changed files with 4407 additions and 960 deletions

145
piprotocol.cpp Executable file → Normal file
View File

@@ -1,7 +1,7 @@
/*
PIP - Platform Independent Primitives
Protocol, input/output channel (COM, UDP)
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com
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
@@ -33,7 +33,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
int ps, gps;
bool ok, gok, flag, gflag, has_dev = false;
float freq, gfreq;
PIFlags<PISerial::Parameters> pp;
PIFlags<PISerial::Parameters> pp(0);
PIConfig::Entry & b(conf.getValue(name)),
& rb(b.getValue("receiver")),
& sb(b.getValue("sender"));
@@ -65,7 +65,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
}
type_rec = PIProtocol::Ethernet;
eth = new PIEthernet();
packet_ext.setDevice(eth);
packet_ext->setDevice(eth);
//setSenderAddress(dev, ps);
setReceiverAddress(dev, ps);
has_dev = true;
@@ -128,7 +128,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
devReceiverState = "Config error";
return;
}
pp |= PISerial::ParityControl;
pp.setFlag(PISerial::ParityControl, flag);
}
flag = rb.getValue("twoStopBits", false, &ok);
gflag = b.getValue("twoStopBits", false, &gok);
@@ -139,12 +139,12 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
devReceiverState = "Config error";
return;
}
pp |= PISerial::TwoStopBits;
pp.setFlag(PISerial::TwoStopBits, flag);
}
type_rec = PIProtocol::Serial;
type_send = PIProtocol::Serial;
ser = new PISerial(dev);
packet_ext.setDevice(ser);
packet_ext->setDevice(ser);
//setSenderDevice(dev, (PISerial::Speed)ps);
setReceiverDevice(dev, (PISerial::Speed)ps);
ser->setInSpeed((PISerial::Speed)ps);
@@ -297,7 +297,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
devSenderState = "Config error";
return;
}
pp |= PISerial::ParityControl;
pp.setFlag(PISerial::ParityControl, flag);
}
flag = sb.getValue("twoStopBits", false, &ok);
gflag = b.getValue("twoStopBits", false, &gok);
@@ -308,7 +308,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
devSenderState = "Config error";
return;
}
pp |= PISerial::TwoStopBits;
pp.setFlag(PISerial::TwoStopBits, flag);
}
} else {
piCout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".sender.speed\" or \"" << name << ".speed\" in \"" << config << "\"!" << endl;
@@ -365,14 +365,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re
dataSize = recDataSize;
sendDataPtr = (uchar * )sendDataPtr_;
sendDataSize = sendDataSize_;
packet_ext.setPacketData(recHeaderPtr, recHeaderSize, recDataSize);
if (type_rec == PIProtocol::Ethernet) {
if (recHeaderPtr != 0) {
dataPtr = (uchar * )recHeaderPtr;
dataSize = recHeaderSize + recDataSize;
if (dataSize > 0) packet = new char[dataSize];
} else if (recDataSize > 0) packet = new char[recDataSize];
} else if (recHeaderSize + recDataSize > 0) packet = new char[recHeaderSize + recDataSize];
packet_ext->setPacketData(recHeaderPtr, recHeaderSize, recDataSize);
}
@@ -394,16 +387,18 @@ PIProtocol::~PIProtocol() {
}
delete diagTimer;
delete sendTimer;
if (packet != 0) delete packet;
delete secTimer;
if (eth != 0) delete eth;
if (ser != 0) delete ser;
delete packet_ext;
}
void PIProtocol::init() {
packet_ext.setThreadedReadData(this);
packet_ext.setThreadedReadSlot(receiveEvent);
packet_ext.setHeaderCheckSlot(headerValidateEvent);
packet_ext = new PIPacketExtractor();
packet_ext->setThreadedReadData(this);
packet_ext->setThreadedReadSlot(receiveEvent);
packet_ext->setHeaderCheckSlot(headerValidateEvent);
work = new_mp_prot = history_write_rec = history_write_send = false;
eth = 0;
ser = 0;
@@ -412,18 +407,20 @@ void PIProtocol::init() {
net_diag = PIProtocol::Unknown;
cur_pckt = 0;
diagTimer = 0;
packet = 0;
timeout_ = 3.f;
sendTimer = new PITimer(sendEvent, this);
diagTimer = new PITimer(diagEvent, this);
secTimer = new PITimer(secEvent, this);
wrong_count = receive_count = send_count = missed_count = 0;
immediate_freq = integral_freq = 0.f;
packets_in_sec = packets_out_sec = bytes_in_sec = bytes_out_sec = 0;
immediate_freq = integral_freq = ifreq = 0.f;
headerPtr = dataPtr = sendDataPtr = 0;
headerSize = dataSize = sendDataSize = 0;
type_rec = type_send = PIProtocol::None;
devSenderState = devReceiverState = "Unknown";
devSenderName = devReceiverName = "no device";
history_rsize_rec = history_rsize_send = "no file";
secTimer->start(1000.);
/*addEvent("receiver started");
addEvent("receiver stopped");
addEvent("sender started");
@@ -444,7 +441,7 @@ void PIProtocol::setReceiverDevice(const PIString & device, PISerial::Speed spee
type_send = type_rec = PIProtocol::Serial;
if (ser == 0) {
ser = new PISerial();
packet_ext.setDevice(ser);
packet_ext->setDevice(ser);
}
}
if (type_rec == PIProtocol::Serial && ser != 0) {
@@ -461,7 +458,7 @@ void PIProtocol::setReceiverAddress(const PIString & ip, int port, bool force) {
type_rec = PIProtocol::Ethernet;
if (eth == 0) {
eth = new PIEthernet();
packet_ext.setDevice(eth);
packet_ext->setDevice(eth);
}
}
if (type_rec == PIProtocol::Ethernet && eth != 0) {
@@ -493,13 +490,38 @@ void PIProtocol::setSenderAddress(const PIString & ip, int port, bool force) {
}
if (type_send == PIProtocol::Ethernet && eth != 0) {
eth->setSendAddress(ip, port);
eth->open();
if (ip.isEmpty()) devSenderName = "no ip";
else devSenderName = ip + ":" + PIString::fromNumber(port);
}
}
void PIProtocol::setSenderIP(const PIString & ip, bool force) {
if (force) {
type_send = PIProtocol::Ethernet;
if (eth == 0) eth = new PIEthernet();
}
if (type_send == PIProtocol::Ethernet && eth != 0) {
eth->setSendIP(ip);
if (ip.isEmpty()) devSenderName = "no ip";
else devSenderName = ip + ":" + PIString::fromNumber(eth->sendPort());
}
}
void PIProtocol::setSenderPort(int port, bool force) {
if (force) {
type_send = PIProtocol::Ethernet;
if (eth == 0) eth = new PIEthernet();
}
if (type_send == PIProtocol::Ethernet && eth != 0) {
eth->setSendPort(port);
if (eth->sendIP().isEmpty()) devSenderName = "no ip";
else devSenderName = eth->sendIP() + ":" + PIString::fromNumber(port);
}
}
void PIProtocol::setExpectedFrequency(float frequency) {
exp_freq = frequency;
changeDisconnectTimeout();
@@ -517,29 +539,35 @@ void PIProtocol::startReceive(float exp_frequency) {
if (exp_frequency > 0.f) exp_freq = exp_frequency;
//if (type_rec == PIProtocol::Serial) ser->start();
//if (type_rec == PIProtocol::Ethernet) eth->start();
packet_ext->startThreadedRead();
msleep(1);
check_state();
if (exp_freq <= 0.f) return;
packet_ext.startThreadedRead();
setExpectedFrequency(exp_freq);
diagTimer->start(1000. / exp_freq);
diagTimer->reset();
raiseEvent(this, "receiver started");
receiverStarted();
}
void PIProtocol::startSend(float frequency) {
//cout << "** start send " << send_freq << ", " << frequency << endl;
if (frequency > 0.f) send_freq = frequency;
msleep(1);
check_state();
if (send_freq <= 0.f) return;
sendTimer->start(1000. / send_freq);
raiseEvent(this, "sender started");
diagTimer->reset();
senderStarted();
}
void PIProtocol::stopReceive() {
//if (type_rec == PIProtocol::Serial) ser->stop();
//if (type_rec == PIProtocol::Ethernet) eth->stop();
packet_ext.stop();
packet_ext->stop();
diagTimer->stop();
raiseEvent(this, "receiver stopped");
receiverStopped();
}
@@ -553,15 +581,20 @@ bool PIProtocol::receiveEvent(void * t, uchar * data, int size) {
p->history_file_rec.writeToBinLog(p->history_id_rec, data, size);
p->history_rsize_rec.setReadableSize(p->history_file_rec.pos());
}
raiseEvent<bool>(p, "received", true);
p->received(true);
//p->unlock();
p->ifreq = p->diagTimer->elapsed_m();
if (p->ifreq > 0.) p->ifreq = 1000. / p->ifreq;
p->diagTimer->reset();
p->receive_count++;
p->packets_in_sec++;
p->bytes_in_sec += size;
p->cur_pckt = 1;
if (p->ret_func != 0) p->ret_func(p);
if (p->mp_owner != 0) PIMultiProtocolBase::receiveEvent(p->mp_owner, p, true, data, size);
return true;
}
raiseEvent<bool>(p, "received", false);
p->received(false);
//p->unlock();
p->wrong_count++;
if (p->mp_owner != 0) PIMultiProtocolBase::receiveEvent(p->mp_owner, p, false, data, size);
@@ -569,19 +602,21 @@ bool PIProtocol::receiveEvent(void * t, uchar * data, int size) {
}
bool PIProtocol::headerValidateEvent(void * t, uchar * src, uchar * rec, int size) {
PIProtocol * p = (PIProtocol * )t;
//cout << "validate\n";
return p->headerValidate(src, rec, size);
}
void PIProtocol::diagEvent(void * t, int) {
PIProtocol * p = (PIProtocol * )t;
p->calc_freq();
p->calc_diag();
p->check_state();
if (p->ser != 0) p->missed_count = p->packet_ext.missedPackets();
if (p->ser != 0) p->missed_count = p->packet_ext->missedPackets();
}
void PIProtocol::secEvent(void * t, int ) {
PIProtocol * p = (PIProtocol * )t;
p->speedIn = PIString::readableSize(p->bytes_in_sec) + "/s";
p->speedOut = PIString::readableSize(p->bytes_out_sec) + "/s";
p->bytes_in_sec = p->bytes_out_sec = p->packets_in_sec = p->packets_out_sec = 0;
if (p->ser != 0) p->missed_count = p->packet_ext->missedPackets();
}
@@ -608,17 +643,16 @@ void PIProtocol::calc_diag() {
else if (good_percents > 20.f && good_percents <= 80.f) diag = PIProtocol::Average;
else diag = PIProtocol::Good;
if (diag != net_diag) {
qualityChanged(net_diag, diag);
net_diag = diag;
raiseEvent<PIProtocol::Quality>(this, "quality changed", diag);
}
}
void PIProtocol::calc_freq() {
float tf = float(1000.f / diagTimer->elapsed_m());
diagTimer->reset();
if (cur_pckt != 1) tf = 0.f;
immediate_freq = tf;
float tf;// = float(1000.f / diagTimer->elapsed_m());
tf = immediate_freq = ifreq;
ifreq = 0.f;
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];
@@ -670,11 +704,17 @@ void PIProtocol::send(const void * data, int size, bool direct) {
history_rsize_send.setReadableSize(history_file_send.pos());
}
if (type_send == PIProtocol::Serial)
if (ser->send(data, size))
if (ser->send(data, size)) {
send_count++;
packets_out_sec++;
bytes_out_sec += size;
}
if (type_send == PIProtocol::Ethernet)
if (eth->send(data, size))
if (eth->send(data, size)) {
send_count++;
packets_out_sec++;
bytes_out_sec += size;
}
}
@@ -682,6 +722,7 @@ void PIProtocol::send() {
//lock();
//memcpy(packet, sendDataPtr, sendDataSize);
//unlock();
//cout << "**send" << endl;
if (!aboutSend()) return;
if (sendDataPtr == 0 || sendDataSize == 0) return;
if (history_write_send) {
@@ -689,9 +730,15 @@ void PIProtocol::send() {
history_rsize_send.setReadableSize(history_file_send.pos());
}
if (type_send == PIProtocol::Serial)
if (ser->send(sendDataPtr, sendDataSize))
if (ser->send(sendDataPtr, sendDataSize)) {
send_count++;
packets_out_sec++;
bytes_out_sec += sendDataSize;
}
if (type_send == PIProtocol::Ethernet)
if (eth->send(sendDataPtr, sendDataSize))
if (eth->send(sendDataPtr, sendDataSize)) {
send_count++;
packets_out_sec++;
bytes_out_sec += sendDataSize;
}
}