diff --git a/main.cpp b/main.cpp index 566d3677..81a4bd42 100644 --- a/main.cpp +++ b/main.cpp @@ -63,7 +63,7 @@ void timerEvent(void * data, int delim) { cout << " tick from constuctor, delimiter = " << delim << ", data = " << data << endl; }; -bool +bool t2 = false; void timerEvent2(void * data, int delim) { t2 = true; @@ -116,7 +116,67 @@ public: bool d; }; + + +#pragma pack(push, 1) +struct Data { + ushort header; + int counter; + float f0; + float f1; + ushort checksum; +}; +#pragma pack(pop) + +class Prot: public PIProtocol { +public: + Prot() { + setReceiverDevice("/dev/ttyS0", PISerial::S115200, true); + setReceiverDataHeader(&rec, 2); + setReceiverData(&rec.counter, sizeof(rec) - 2); + setSenderData(&send, sizeof(send)); + setExpectedFrequency(20.f); + setSenderFrequency(20.f); + send.header = 0xAABB; + rec.header = 0xAABB; + start(); + } + + virtual bool validate() { + if (rec.checksum != PIByteArray(&rec, sizeof(rec)-2).checksumCRC16()) return false; + return true; + } + virtual bool aboutSend() { + send.counter++; + send.checksum = PIByteArray(&send, sizeof(send)-2).checksumCRC16(); + return true; + } + + Data send, rec; +}; + +Prot p; + +void key(char k, void*) { + switch (k) { + case '0': p.setSenderData(&p.send, sizeof(p.send)); break; + case '1': p.setSenderData(&p.send, sizeof(p.send) - 1); break; + case '2': p.send.header = 0xAABB; break; + case '3': p.send.header = 0xACBD; break; + } +} + +PIConsole c(false, key); int main(int argc, char * argv[]) { + c.enableExitCapture(); + c.addVariable("prot", &p); + if (argc > 1) c.start(); + c.waitForFinish(); + c.stop(); + exit(0); + + + bool r_string = true, r_thread = true, r_mutex = true, r_timer = true, r_file = true, r_eval = true, r_event = true; bool succ = true; cout << "== PIP test program ==" << endl; @@ -145,7 +205,7 @@ int main(int argc, char * argv[]) { else cout << " complex convertions fail" << endl; if (r_string) cout << "== Success ==" << endl; else cout << "== Fail ==" << endl; - + cout << endl << "== Thread test ==" << endl; ThreadTest thread; thread.start(100); @@ -154,7 +214,7 @@ int main(int argc, char * argv[]) { r_thread = thread.b && thread.r && thread.e && thread.cnt == 10; if (r_thread) cout << "== Success ==" << endl; else cout << "== Fail ==" << endl; - + cout << endl << "== Mutex test ==" << endl << " "; MutexTest thread_m; MutexTest2 thread_m2; @@ -166,7 +226,7 @@ int main(int argc, char * argv[]) { r_mutex = gm < 5; if (r_mutex) cout << "== Success ==" << endl; else cout << "== Fail ==" << endl; - + cout << endl << "== Timer test ==" << endl; PITimer timer(timerEvent, (void*)255); timer.addDelimiter(2); @@ -177,7 +237,7 @@ int main(int argc, char * argv[]) { r_timer = t && t2; if (r_timer) cout << "== Success ==" << endl; else cout << "== Fail ==" << endl; - + cout << endl << "== File test ==" << endl; PIFile file(" file_test", PIFile::New | PIFile::ReadWrite); cout << " file \"" << file.path() << "\" is "; @@ -192,7 +252,7 @@ int main(int argc, char * argv[]) { file.remove(); if (r_file) cout << "== Success ==" << endl; else cout << "== Fail ==" << endl; - + cout << endl << "== Evaluator test ==" << endl; PIEvaluator evaluator; evaluator.setVariable("x", complexd(2., 1.)); @@ -206,7 +266,7 @@ int main(int argc, char * argv[]) { r_eval = round(evaluator.lastResult()) == complexd(9., 12.); if (r_eval) cout << "== Success ==" << endl; else cout << "== Fail ==" << endl; - + cout << endl << "== Event test ==" << endl; ObjectTest object("obj"); ObjectTest2 object2("obj2"); @@ -232,7 +292,7 @@ int main(int argc, char * argv[]) { r_event = object.h && object.hi && object.ht && cd.a && cd.b && cd.c && cd.d; if (r_event) cout << "== Success ==" << endl; else cout << "== Fail ==" << endl; - + cout << endl << "== Results ==" << endl; cout << "= String " << r_string << " =" << endl; cout << "= Thread " << r_thread << " =" << endl; diff --git a/piconsole.cpp b/piconsole.cpp index 783e27b2..746d0ba0 100644 --- a/piconsole.cpp +++ b/piconsole.cpp @@ -217,7 +217,7 @@ PIString PIConsole::fstr(PIFlags f) { if (f[PIConsole::Magenta]) ts += ";35"; if (f[PIConsole::Cyan]) ts += ";36"; if (f[PIConsole::White]) ts += ";37"; - + if (f[PIConsole::BackBlack]) ts += ";40"; if (f[PIConsole::BackRed]) ts += ";41"; if (f[PIConsole::BackGreen]) ts += ";42"; @@ -226,7 +226,7 @@ PIString PIConsole::fstr(PIFlags f) { if (f[PIConsole::BackMagenta]) ts += ";45"; if (f[PIConsole::BackCyan]) ts += ";46"; if (f[PIConsole::BackWhite]) ts += ";47"; - + return ts + "m"; #endif } @@ -467,6 +467,7 @@ void PIConsole::addVariable(const PIString & name, PIProtocol * ptr, int column, addVariable("Sended count", ptr->sendCount_ptr(), column, format); addVariable("Received count", ptr->receiveCount_ptr(), column, format); addVariable("Invalid count", ptr->wrongCount_ptr(), column, format); + addVariable("Missed count", ptr->missedCount_ptr(), column, format); addVariable("Immediate Frequency, Hz", ptr->immediateFrequency_ptr(), column, format); addVariable("Integral Frequency, Hz", ptr->integralFrequency_ptr(), column, format); addVariable("Disconnect Timeout, s", ptr->disconnectTimeout_ptr(), column, format); diff --git a/piethernet.cpp b/piethernet.cpp index 5f5d4ba1..5b5ae6ce 100644 --- a/piethernet.cpp +++ b/piethernet.cpp @@ -182,7 +182,7 @@ bool PIEthernet::send(PIString ip, int port, char * data, int size) { } -bool PIEthernet::send(char * data, int size) { +bool PIEthernet::send(uchar * data, int size) { if (sock_s == -1) { //cout << "[PIEthernet] Can`t send to uninitialized socket" << endl; return false; diff --git a/piethernet.h b/piethernet.h index 945b248a..cb24377b 100644 --- a/piethernet.h +++ b/piethernet.h @@ -38,12 +38,12 @@ #define BUFFER_SIZE 4096 -typedef bool (*EthernetFunc)(void * , char * , int ); +typedef bool (*EthernetFunc)(void * , uchar * , int ); class PIEthernet: public PIThread { public: - // slot is any function format "bool (void*, char*, int)" + // slot is any function format "bool (void*, uchar*, int)" PIEthernet(PIString ip = "", int port = 0, void * data = 0, EthernetFunc slot = 0); ~PIEthernet(); @@ -53,13 +53,13 @@ public: void setSendAddress(PIString ip, int port) {ip_s = ip; port_s = port;} bool send(PIString ip, int port, char * data, int size); - bool send(char * data, int size); + bool send(uchar * data, int size); bool init(); bool initSend(); bool receiverInitialized() const {return sock != -1;} bool senderInitialized() const {return sock_s != -1;} void terminate(); - const char * buffer() const {return buffer_;} + const uchar * buffer() const {return buffer_;} private: void begin(); @@ -71,7 +71,7 @@ private: PIString ip_, ip_s; EthernetFunc ret_func; void * data; - char buffer_[BUFFER_SIZE]; + uchar buffer_[BUFFER_SIZE]; }; diff --git a/pievaluator.cpp b/pievaluator.cpp index ef3e2626..b3ef9283 100644 --- a/pievaluator.cpp +++ b/pievaluator.cpp @@ -622,7 +622,7 @@ PIEvaluatorTypes::Operation PIEvaluator::operationInOrder(const int & index) { int PIEvaluator::parse(const PIString & string, int offset) { - int slen = string.length(), facnt, farg, bcnt, k; + int slen = string.length(), /*facnt,*/ farg, bcnt, k; PIChar cc; PIEvaluatorTypes::Element ce; PIEvaluatorTypes::Function cfunc; @@ -647,7 +647,7 @@ int PIEvaluator::parse(const PIString & string, int offset) { case PIEvaluatorTypes::etFunction: i++; cfunc = content.function(ce.var_num); - facnt = cfunc.arguments; + //facnt = cfunc.arguments; atmp.clear(); bcnt = farg = 1; ///qDebug() << "function: " + cfunc.identifier; diff --git a/piincludes.h b/piincludes.h index dbfeb075..5f53af69 100644 --- a/piincludes.h +++ b/piincludes.h @@ -20,7 +20,7 @@ #ifndef PIINCLUDES_H #define PIINCLUDES_H -#define PIP_VERSION 0x000101 +#define PIP_VERSION 0x000102 #define PIP_VERSION_MAJOR (PIP_VERSION & 0xFF0000) >> 16 #define PIP_VERSION_MINOR (PIP_VERSION & 0xFF00) >> 8 #define PIP_VERSION_REVISION PIP_VERSION & 0xFF diff --git a/piprotocol.cpp b/piprotocol.cpp index d56308ec..cde5ed91 100644 --- a/piprotocol.cpp +++ b/piprotocol.cpp @@ -118,7 +118,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re } type_rec = PIProtocol::Serial; type_send = PIProtocol::Serial; - ser = new PISerial(dev, this, receiveEvent); + ser = new PISerial(dev, this, receiveEvent, headerValidateEvent); setReceiverDevice(dev, (PISerial::Speed)ps); setSenderDevice(dev, (PISerial::Speed)ps); ser->setInSpeed((PISerial::Speed)ps); @@ -256,7 +256,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re return; } type_send = PIProtocol::Serial; - if (ser == 0) ser = new PISerial(dev, this, receiveEvent); + if (ser == 0) ser = new PISerial(dev, this, receiveEvent, headerValidateEvent); setSenderDevice(dev, (PISerial::Speed)ps); ser->setOutSpeed((PISerial::Speed)ps); ser->setParameters(pp); @@ -353,7 +353,7 @@ void PIProtocol::init() { timeout_ = 3.f; sendTimer = new PITimer(sendEvent, this); diagTimer = new PITimer(diagEvent, this); - wrong_count = receive_count = send_count = 0; + wrong_count = receive_count = send_count = missed_count = 0; immediate_freq = integral_freq = 0.f; headerPtr = dataPtr = sendDataPtr = 0; headerSize = dataSize = sendDataSize = 0; @@ -378,13 +378,14 @@ void PIProtocol::init() { void PIProtocol::setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force) { if (force) { - type_rec = PIProtocol::Serial; - if (ser == 0) ser = new PISerial("", this, receiveEvent); + type_send = type_rec = PIProtocol::Serial; + if (ser == 0) ser = new PISerial("", this, receiveEvent, headerValidateEvent); } if (type_rec == PIProtocol::Serial && ser != 0) { ser->setDevice(device); ser->setSpeed(speed); devReceiverName = device; + devSenderName = device; } } @@ -404,8 +405,8 @@ void PIProtocol::setReceiverAddress(const PIString & ip, int port, bool force) { void PIProtocol::setSenderDevice(const PIString & device, PISerial::Speed speed, bool force) { if (force) { - type_send = PIProtocol::Serial; - if (ser == 0) ser = new PISerial("", this, receiveEvent); + type_send = type_rec = PIProtocol::Serial; + if (ser == 0) ser = new PISerial("", this, receiveEvent, headerValidateEvent); } if (type_send == PIProtocol::Serial && ser != 0) { ser->setDevice(device); @@ -469,7 +470,7 @@ void PIProtocol::stopReceive() { } -bool PIProtocol::receiveEvent(void * t, char * data, int size) { +bool PIProtocol::receiveEvent(void * t, uchar * data, int size) { PIProtocol * p = (PIProtocol * )t; if (!p->receive(data, size)) return false; p->work = true; @@ -495,11 +496,19 @@ bool PIProtocol::receiveEvent(void * t, char * 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->ser->missedPackets(); } @@ -586,10 +595,10 @@ void PIProtocol::send(const void * data, int size) { history_rsize_send.setReadableSize(history_file_send.pos()); } if (type_send == PIProtocol::Serial) - if (ser->send((char * )data, size)) + if (ser->send((uchar * )data, size)) send_count++; if (type_send == PIProtocol::Ethernet) - if (eth->send((char * )data, size)) + if (eth->send((uchar * )data, size)) send_count++; } @@ -605,9 +614,9 @@ void PIProtocol::send() { history_rsize_send.setReadableSize(history_file_send.pos()); } if (type_send == PIProtocol::Serial) - if (ser->send((char * )sendDataPtr, sendDataSize)) + if (ser->send((uchar * )sendDataPtr, sendDataSize)) send_count++; if (type_send == PIProtocol::Ethernet) - if (eth->send((char * )sendDataPtr, sendDataSize)) + if (eth->send((uchar * )sendDataPtr, sendDataSize)) send_count++; } diff --git a/piprotocol.h b/piprotocol.h index cc1f0767..479a36d8 100644 --- a/piprotocol.h +++ b/piprotocol.h @@ -37,10 +37,10 @@ public: ~PIMultiProtocolBase() {;} protected: - virtual void received(PIProtocol * prot, bool corrected, char * data, int size) {;} + virtual void received(PIProtocol * prot, bool corrected, uchar * data, int size) {;} private: - static void receiveEvent(PIMultiProtocolBase * p, PIProtocol * prot, bool corrected, char * data, int size) {p->mutex_receive.lock(); p->received(prot, corrected, data, size); p->mutex_receive.unlock();} + static void receiveEvent(PIMultiProtocolBase * p, PIProtocol * prot, bool corrected, uchar * data, int size) {p->mutex_receive.lock(); p->received(prot, corrected, data, size); p->mutex_receive.unlock();} PIMutex mutex_receive; @@ -68,7 +68,7 @@ public: 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; if (type_rec == PIProtocol::Serial || type_send == PIProtocol::Serial) ser->setReadData(headerPtr, headerSize, dataSize);} - void setReceiverDataHeader(void * headerPtr, int headerSize) {this->headerPtr = (uchar * )dataPtr; this->headerSize = headerSize; if (type_rec == PIProtocol::Serial || type_send == PIProtocol::Serial) ser->setReadData(headerPtr, headerSize, dataSize);} + void setReceiverDataHeader(void * headerPtr, int headerSize) {this->headerPtr = (uchar * )headerPtr; this->headerSize = headerSize; if (type_rec == PIProtocol::Serial || type_send == PIProtocol::Serial) ser->setReadData(headerPtr, headerSize, dataSize);} void setReceiverAddress(const PIString & ip, int port, bool force = false); // for Ethernet void setReceiverParameters(PIFlags parameters) {if (type_rec == PIProtocol::Serial || type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial void setReceiveSlot(ReceiveFunc slot) {ret_func = slot;} @@ -104,6 +104,8 @@ public: ullong * wrongCount_ptr() {return &wrong_count;} ullong sendCount() const {return send_count;} ullong * sendCount_ptr() {return &send_count;} + ullong missedCount() const {return missed_count;} + ullong * missedCount_ptr() {return &missed_count;} PIProtocol::Quality quality() const {return net_diag;} // receive quality int * quality_ptr() {return (int * )&net_diag;} // receive quality pointer PIString receiverDeviceName() const {return devReceiverName;} @@ -125,11 +127,11 @@ public: void * sendData() {return sendDataPtr;} PIByteArray lastHeader() {if (ser != 0) return ser->lastHeader(); return PIByteArray();} - PIByteArray internalBuffer() {if (ser != 0) return ser->internalBuffer(); return PIByteArray();} protected: - virtual bool receive(char * data, int size) {if (dataPtr != 0) memcpy(dataPtr, data, size); return true;} // executed when raw data received, break if 'false' return + 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 virtual bool validate() {return true;} // function for validate algorithm and save data from dataPtr to external struct + virtual bool headerValidate(uchar * src, uchar * rec, int size) {for (int i = 0; i < size; ++i) if (src[i] != rec[i]) return false; return true;} // function for validate header (COM-port and headerSize > 0) virtual uint checksum_i(void * data, int size) { // function for checksum (uint) uint c = 0; for (int i = 0; i < size; ++i) @@ -158,7 +160,8 @@ protected: private: static void sendEvent(void * e, int) {((PIProtocol * )e)->send();} - static bool receiveEvent(void * t, char * data, int size); + static bool receiveEvent(void * t, uchar * data, int size); + static bool headerValidateEvent(void * t, uchar * src, uchar * rec, int size); static void diagEvent(void * t, int); void setMultiProtocolOwner(PIMultiProtocolBase * mp) {mp_owner = mp;} @@ -180,7 +183,7 @@ private: float exp_freq, send_freq, immediate_freq, integral_freq, timeout_; int packets[2], pckt_cnt, pckt_cnt_max; char * packet, cur_pckt; - ullong wrong_count, receive_count, send_count; + ullong wrong_count, receive_count, send_count, missed_count; }; diff --git a/piserial.cpp b/piserial.cpp index 7b355278..f00b9942 100644 --- a/piserial.cpp +++ b/piserial.cpp @@ -20,18 +20,17 @@ #include "piserial.h" -PISerial::PISerial(PIString name, void * data_, SerialFunc slot): PIThread() { +PISerial::PISerial(PIString name, void * data_, SerialFunc slot, SerialHeaderFunc slot_header): PIThread() { piMonitor.serials++; setPriority(piHigh); data = data_; devName = name; fd = -1; + missed = 0; dataSize = headerSize = 0; headerPtr = 0; - hbuffer = pbuffer = 0; ret_func = slot; - memset(buffer, 0, BUFFER_SIZE); - memset(sbuffer, 0, BUFFER_SIZE); + ret_func_header = slot_header; #ifdef WINDOWS hCom = 0; #endif @@ -87,121 +86,59 @@ int PISerial::convertSpeed(PISerial::Speed speed) { void PISerial::begin() { - sbuffIndex = 0; - startIndex = 0; - backIndex = 0; - tryagain = first = false; - hbuffer = new char[headerSize]; - pbuffer = new char[dataSize]; + allReaded = addSize = curInd = 0; + first = false; + packetSize = headerSize + dataSize; + if (headerSize > 0) mheader.resize(headerSize); if (!init()) stop(); } void PISerial::run() { if (dataSize == 0) return; - char b; - uint i = 0; - int j; + while (allReaded < packetSize + addSize) { #ifdef WINDOWS - WaitCommEvent(hCom, 0, 0); - ReadFile(hCom, buffer, dataSize, &readed, 0); + WaitCommEvent(hCom, 0, 0); + ReadFile(hCom, &buffer[allReaded], SERIAL_BUFFER_SIZE, &readed, 0); #else - readed = read(fd, buffer, BUFFER_SIZE); + readed = read(fd, &buffer[allReaded], SERIAL_BUFFER_SIZE); #endif - if (headerSize > 0) - { - while (i < readed) - { - //cout << sbuffIndex << ";" << startIndex << endl; - if (!tryagain) - { - b = buffer[i]; - sbuffer[sbuffIndex] = b; - } else { - backIndex++; - if (backIndex == headerSize + dataSize) tryagain = false; - } - if (first) - { - if (sbuffIndex-startIndex == headerSize + dataSize - 1) - { - //cout << "vsdfgvb" << endl; - memcpy(pbuffer,&sbuffer[startIndex+headerSize],dataSize); - if (ret_func(data, pbuffer, dataSize)) - { - startIndex = 0; - sbuffIndex = -1; - } else { - //startIndex++; - memcpy(sbuffer, hbuffer, headerSize); - memcpy(&sbuffer[headerSize], pbuffer, dataSize); - backIndex = 0; - tryagain = true; - startIndex = 1; - sbuffIndex = -1; - } - first = false; - } - } else { - if (sbuffIndex - startIndex == headerSize - 1) - { - memcpy(hbuffer, &sbuffer[startIndex], headerSize); - for (j = 0; j < headerSize; ++j) { - if (hbuffer[j] != ((char*)headerPtr)[j]) { - startIndex++; - //cout << "no" << endl; - break; - } - } - if (j == headerSize) { - first = true; - mheader.resize(headerSize); - memcpy(mheader.data(),headerPtr,headerSize); - //cout << "yes" << endl; - } - } - } - sbuffIndex++; - if (sbuffIndex >= BUFFER_SIZE) - { - if (first) - { - memcpy(pbuffer, &sbuffer[startIndex + headerSize], BUFFER_SIZE - startIndex - headerSize); - memcpy(sbuffer, hbuffer, headerSize); - memcpy(&sbuffer[headerSize], pbuffer, BUFFER_SIZE - startIndex - headerSize); - sbuffIndex = BUFFER_SIZE - startIndex - 1; - } else { - memcpy(sbuffer, hbuffer, headerSize); - sbuffIndex = headerSize - 1; - startIndex = 0; - } - } - if (!tryagain) i++; + allReaded += readed; + } + if (headerSize > 0) { + if (allReaded + curInd >= SERIAL_BUFFER_SIZE) { + memcpy(sbuffer, buffer, SERIAL_BUFFER_SIZE); + memcpy(buffer, &sbuffer[SERIAL_BUFFER_SIZE - packetSize], allReaded); + allReaded = packetSize; + addSize = curInd = 0; } + while (!ret_func_header(data, (uchar * )headerPtr, &buffer[curInd], headerSize)) { + curInd++; missed++; + if (curInd > addSize) { + addSize += packetSize; + return; + } + } + memcpy(mheader.data(), &buffer[curInd + headerSize], headerSize); + if (!ret_func(data, &buffer[curInd + headerSize], dataSize)) { + curInd++; missed++; + return; + } + memcpy(sbuffer, buffer, allReaded); + memcpy(buffer, &sbuffer[packetSize + curInd], allReaded); + allReaded -= packetSize + curInd; + curInd = addSize = 0; } else { - for (uint i = 0; i < readed; ++i) { - b = buffer[i]; - sbuffer[sbuffIndex] = b; - if (sbuffIndex == dataSize - 1) { - if (ret_func != 0) ret_func(data, sbuffer, dataSize); - sbuffIndex = -1; - } - sbuffIndex++; - } + ret_func(data, buffer, dataSize); + memcpy(sbuffer, buffer, allReaded); + memcpy(buffer, &sbuffer[packetSize], allReaded); + allReaded -= packetSize; } } void PISerial::end() { terminate(); - if (pbuffer != 0) { - delete pbuffer; - pbuffer = 0; - } - if (hbuffer != 0) { - delete hbuffer; - hbuffer = 0; - } } @@ -279,7 +216,7 @@ bool PISerial::init() { } -bool PISerial::send(char * data, int size) { +bool PISerial::send(uchar * data, int size) { //cout << "[PISerial] send size: " << sizeof(data) << endl; if (fd == -1) { //cout << "[PISerial] Can`t write to uninitialized COM" << endl; @@ -292,7 +229,7 @@ bool PISerial::send(char * data, int size) { int wrote; wrote = write(fd, data, size); #endif - if ((int)wrote != size) { + if ((int)wrote != size) { //cout << "[PISerial] Error while sending" << endl; return false; } diff --git a/piserial.h b/piserial.h index dd6fa520..2811390b 100644 --- a/piserial.h +++ b/piserial.h @@ -42,15 +42,16 @@ # define B256000 256000 #endif -#define BUFFER_SIZE 4096 +#define SERIAL_BUFFER_SIZE 4096 -typedef bool (*SerialFunc)(void * , char * , int ); +typedef bool (*SerialFunc)(void * , uchar * , int ); +typedef bool (*SerialHeaderFunc)(void * , uchar * , uchar * , int ); -class PISerial: public PIThread -{ +class PISerial: public PIThread { public: - // slot is any function format "bool (void*, char*, int)" - PISerial(PIString name = "serial", void * data = 0, SerialFunc slot = 0); + // slot is any function format "bool (void*, uchar*, int)" + // slot_header is any function format "bool (void*, uchar*, uchar*, int)" + PISerial(PIString name = "serial", void * data = 0, SerialFunc slot = 0, SerialHeaderFunc slot_header = headerValidate); ~PISerial(); enum Parameters {ParityControl = 0x01, ParityOdd = 0x02, TwoStopBits = 0x04}; @@ -75,20 +76,20 @@ public: void setDevice(const PIString & dev) {devName = dev;} void setParameters(PIFlags parameters) {params = parameters;} void setData(void * d) {data = d;} - void setReadData(void * headerPtr, int headerSize, int dataSize) {this->headerPtr = headerPtr; - this->headerSize = headerSize; - this->dataSize = dataSize;} + void setReadData(void * headerPtr, int headerSize, int dataSize) {this->headerPtr = headerPtr; this->headerSize = headerSize; this->dataSize = dataSize;} - bool send(char * data, int size); + bool send(uchar * data, int size); bool init(); bool initialized() const {return fd != -1;} void terminate(); PIByteArray lastHeader() {return mheader;} - PIByteArray internalBuffer() {return PIByteArray(sbuffer, BUFFER_SIZE);} + ullong missedBytes() const {return missed;} + ullong missedPackets() const {return (packetSize == 0 ? 0 : missed / packetSize);} private: int convertSpeed(PISerial::Speed speed); + static bool headerValidate(void * d, uchar * src, uchar * rec, int size) {for (int i = 0; i < size; ++i) if (src[i] != rec[i]) return false; return true;} void begin(); void run(); @@ -106,12 +107,14 @@ private: PISerial::Speed ospeed, ispeed; PIString devName; SerialFunc ret_func; - char buffer[BUFFER_SIZE], sbuffer[BUFFER_SIZE], * hbuffer, * pbuffer; + SerialHeaderFunc ret_func_header; + uchar buffer[SERIAL_BUFFER_SIZE], sbuffer[SERIAL_BUFFER_SIZE]; PIByteArray mheader; void * headerPtr, * data; - int dataSize, headerSize, sbuffIndex, startIndex, backIndex; + int dataSize, headerSize, packetSize, allReaded, addSize, curInd; + ullong missed; PIFlags params; - bool first, tryagain; + bool first; };