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

102
piprotocol.h 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
@@ -34,7 +34,7 @@ class PIMultiProtocolBase
friend class PIProtocol;
public:
PIMultiProtocolBase() {;}
~PIMultiProtocolBase() {;}
virtual ~PIMultiProtocolBase() {;}
protected:
virtual void received(PIProtocol * prot, bool corrected, uchar * data, int size) {;}
@@ -48,6 +48,23 @@ private:
typedef void (*ReceiveFunc)(void * );
/// events:
/// void receiverStarted()
/// void receiverStopped()
/// void senderStarted()
/// void senderStopped()
/// void received(bool validate_is_ok)
/// void qualityChanged(PIProtocol::Quality old_quality, PIProtocol::Quality new_quality)
///
/// handlers:
/// void startReceive(float exp_frequency = -1.f)
/// void stopReceive()
/// void startSend(float frequency = -1.f)
/// void stopSend()
/// void start()
/// void stop()
/// void send()
/// void send(const void * data, int size, bool direct = false)
class PIProtocol: public PIObject
{
friend class PIMultiProtocolBase;
@@ -58,7 +75,7 @@ public:
PIProtocol(): PIObject() {init();}
PIProtocol(const PIString & config, const PIString & name, void * recHeaderPtr = 0, int recHeaderSize = 0,
void * recDataPtr = 0, int recDataSize = 0, void * sendDataPtr = 0, int sendDataSize = 0); // from config
~PIProtocol();
virtual ~PIProtocol();
enum Quality {Unknown = 1, Failure = 2, Bad = 3, Average = 4, Good = 5};
@@ -67,8 +84,8 @@ public:
EVENT_HANDLER0(PIProtocol, void, stopReceive);
void setExpectedFrequency(float frequency); // for connection quality diagnostic
void setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial
void setReceiverData(void * dataPtr, int dataSize) {this->dataPtr = (uchar * )dataPtr; this->dataSize = dataSize; packet_ext.setPacketData(headerPtr, headerSize, dataSize);}
void setReceiverDataHeader(void * headerPtr, int headerSize) {this->headerPtr = (uchar * )headerPtr; this->headerSize = headerSize; packet_ext.setPacketData(headerPtr, headerSize, dataSize);}
void setReceiverData(void * dataPtr, int dataSize) {this->dataPtr = (uchar * )dataPtr; this->dataSize = dataSize; packet_ext->setPacketData(headerPtr, headerSize, dataSize);}
void setReceiverDataHeader(void * headerPtr, int headerSize) {this->headerPtr = (uchar * )headerPtr; this->headerSize = headerSize; packet_ext->setPacketData(headerPtr, headerSize, dataSize);}
void setReceiverAddress(const PIString & ip, int port, bool force = false); // for Ethernet
void setReceiverParameters(PIFlags<PISerial::Parameters> parameters) {if (type_rec == PIProtocol::Serial || type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial
void setReceiveSlot(ReceiveFunc slot) {ret_func = slot;}
@@ -76,11 +93,13 @@ public:
EVENT_HANDLER0(PIProtocol, void, startSend) {startSend(-1.f);} // if "frequency = -1" used last passed value
EVENT_HANDLER1(PIProtocol, void, startSend, float, frequency); // if "frequency = -1" used last passed value
EVENT_HANDLER0(PIProtocol, void, stopSend) {sendTimer->stop(); raiseEvent(this, "sender stopped");}
EVENT_HANDLER0(PIProtocol, void, stopSend) {sendTimer->stop(); senderStopped();}
void setSenderFrequency(float frequency) {send_freq = frequency;}
void setSenderDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial
void setSenderData(void * dataPtr, int dataSize) {sendDataPtr = (uchar * )dataPtr; sendDataSize = dataSize;}
void setSenderAddress(const PIString & ip, int port, bool force = false); // for Ethernet
void setSenderIP(const PIString & ip, bool force = false); // for Ethernet
void setSenderPort(int port, bool force = false); // for Ethernet
void setSenderParameters(PIFlags<PISerial::Parameters> parameters) {if (type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial
float senderFrequency() const {return send_freq;}
@@ -94,40 +113,60 @@ public:
PIString name() const {return protName;}
void setDisconnectTimeout(float timeout) {timeout_ = timeout; changeDisconnectTimeout();}
float disconnectTimeout() const {return timeout_;}
float * disconnectTimeout_ptr() {return &timeout_;}
const float * disconnectTimeout_ptr() const {return &timeout_;}
float immediateFrequency() const {return immediate_freq;}
float integralFrequency() const {return integral_freq;}
float * immediateFrequency_ptr() {return &immediate_freq;}
float * integralFrequency_ptr() {return &integral_freq;}
const float * immediateFrequency_ptr() const {return &immediate_freq;}
const float * integralFrequency_ptr() const {return &integral_freq;}
ullong receiveCountPerSec() const {return packets_in_sec;}
const ullong * receiveCountPerSec_ptr() const {return &packets_in_sec;}
ullong sendCountPerSec() const {return packets_out_sec;}
const ullong * sendCountPerSec_ptr() const {return &packets_out_sec;}
ullong receiveBytesPerSec() const {return bytes_in_sec;}
const ullong * receiveBytesPerSec_ptr() const {return &bytes_in_sec;}
ullong sendBytesPerSec() const {return bytes_out_sec;}
const ullong * sendBytesPerSec_ptr() const {return &bytes_out_sec;}
ullong receiveCount() const {return receive_count;}
ullong * receiveCount_ptr() {return &receive_count;}
const ullong * receiveCount_ptr() const {return &receive_count;}
ullong wrongCount() const {return wrong_count;}
ullong * wrongCount_ptr() {return &wrong_count;}
const ullong * wrongCount_ptr() const {return &wrong_count;}
ullong sendCount() const {return send_count;}
ullong * sendCount_ptr() {return &send_count;}
const ullong * sendCount_ptr() const {return &send_count;}
ullong missedCount() const {return missed_count;}
ullong * missedCount_ptr() {return &missed_count;}
const ullong * missedCount_ptr() const {return &missed_count;}
PIProtocol::Quality quality() const {return net_diag;} // receive quality
int * quality_ptr() {return (int * )&net_diag;} // receive quality pointer
const int * quality_ptr() const {return (int * )&net_diag;} // receive quality pointer
PIString receiverDeviceName() const {return devReceiverName;}
PIString senderDeviceName() const {return devSenderName;}
PIString receiverDeviceState() const {return devReceiverState;}
PIString * receiverDeviceState_ptr() {return &devReceiverState;}
const PIString * receiverDeviceState_ptr() const {return &devReceiverState;}
PIString senderDeviceState() const {return devSenderState;}
PIString * senderDeviceState_ptr() {return &devSenderState;}
const PIString * senderDeviceState_ptr() const {return &devSenderState;}
PIString receiveSpeed() const {return speedIn;}
const PIString * receiveSpeed_ptr() const {return &speedIn;}
PIString sendSpeed() const {return speedOut;}
const PIString * sendSpeed_ptr() const {return &speedOut;}
PIString receiverHistorySize() const {return history_rsize_rec;}
PIString * receiverHistorySize_ptr() {return &history_rsize_rec;}
const PIString * receiverHistorySize_ptr() const {return &history_rsize_rec;}
PIString senderHistorySize() const {return history_rsize_send;}
PIString * senderHistorySize_ptr() {return &history_rsize_send;}
const PIString * senderHistorySize_ptr() const {return &history_rsize_send;}
bool writeReceiverHistory() const {return history_write_rec;}
bool * writeReceiverHistory_ptr() {return &history_write_rec;}
const bool * writeReceiverHistory_ptr() const {return &history_write_rec;}
bool writeSenderHistory() const {return history_write_send;}
bool * writeSenderHistory_ptr() {return &history_write_send;}
const bool * writeSenderHistory_ptr() const {return &history_write_send;}
void * receiveData() {return dataPtr;}
void * sendData() {return sendDataPtr;}
PIByteArray lastHeader() {return packet_ext.lastHeader();}
PIPacketExtractor * packetExtractor() {return packet_ext;}
PIByteArray lastHeader() {return packet_ext->lastHeader();}
EVENT0(PIProtocol, receiverStarted)
EVENT0(PIProtocol, receiverStopped)
EVENT0(PIProtocol, senderStarted)
EVENT0(PIProtocol, senderStopped)
EVENT1(PIProtocol, received, bool, validate_is_ok)
EVENT2(PIProtocol, qualityChanged, PIProtocol::Quality, old_quality, PIProtocol::Quality, new_quality)
protected:
virtual bool receive(uchar * data, int size) {if (dataPtr != 0) memcpy(dataPtr, data, size); return true;} // executed when raw data received, break if 'false' return
@@ -137,15 +176,13 @@ protected:
uint c = 0;
for (int i = 0; i < size; ++i)
c += ((uchar*)data)[i];
c = ~(c + 1);
return c;
return ~(c + 1);
}
virtual uchar checksum_c(void * data, int size) { // function for checksum (uchar)
uchar c = 0;
for (int i = 0; i < size; ++i)
c += ((uchar*)data)[i];
c = ~(c + 1);
return c;
return ~(c + 1);
}
virtual bool aboutSend() {return true;} // executed before send data, if return 'false' then data is not sending
@@ -162,30 +199,31 @@ protected:
private:
static void sendEvent(void * e, int) {((PIProtocol * )e)->send();}
static bool receiveEvent(void * t, uchar * data, int size);
static bool headerValidateEvent(void * t, uchar * src, uchar * rec, int size);
static bool headerValidateEvent(void * t, uchar * src, uchar * rec, int size) {return ((PIProtocol * )t)->headerValidate(src, rec, size);}
static void diagEvent(void * t, int);
static void secEvent(void * t, int);
void setMultiProtocolOwner(PIMultiProtocolBase * mp) {mp_owner = mp;}
PIMultiProtocolBase * multiProtocolOwner() const {return mp_owner;}
void changeDisconnectTimeout();
ReceiveFunc ret_func;
PIPacketExtractor packet_ext;
PITimer * diagTimer, * sendTimer;
PIPacketExtractor * packet_ext;
PITimer * diagTimer, * sendTimer, * secTimer;
PIMultiProtocolBase * mp_owner;
PIProtocol::Type type_send, type_rec;
PIProtocol::Quality net_diag;
PIDeque<float> last_freq;
PIDeque<char> last_packets;
PIString protName, devReceiverName, devReceiverState, devSenderName, devSenderState;
PIString protName, devReceiverName, devReceiverState, devSenderName, devSenderState, speedIn, speedOut;
PIString history_path_rec, history_path_send, history_rsize_rec, history_rsize_send;
PIFile history_file_rec, history_file_send;
ushort history_id_rec, history_id_send;
bool work, new_mp_prot, history_write_rec, history_write_send;
float exp_freq, send_freq, immediate_freq, integral_freq, timeout_;
float exp_freq, send_freq, ifreq, immediate_freq, integral_freq, timeout_;
int packets[2], pckt_cnt, pckt_cnt_max;
char * packet, cur_pckt;
ullong wrong_count, receive_count, send_count, missed_count;
char cur_pckt;
ullong wrong_count, receive_count, send_count, missed_count, packets_in_sec, packets_out_sec, bytes_in_sec, bytes_out_sec;
};