263 lines
6.8 KiB
C++
263 lines
6.8 KiB
C++
// SportIdent.h: interface for the SportIdent class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#if !defined(AFX_SPORTIDENT_H__F13F5795_8FA9_4CE6_8497_7407CD590139__INCLUDED_)
|
|
#define AFX_SPORTIDENT_H__F13F5795_8FA9_4CE6_8497_7407CD590139__INCLUDED_
|
|
|
|
#if _MSC_VER > 1000
|
|
#pragma once
|
|
#endif // _MSC_VER > 1000
|
|
|
|
#include <set>
|
|
|
|
/************************************************************************
|
|
MeOS - Orienteering Software
|
|
Copyright (C) 2009-2022 Melin Software HB
|
|
|
|
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
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
Melin Software HB - software@melin.nu - www.melin.nu
|
|
Eksoppsvägen 16, SE-75646 UPPSALA, Sweden
|
|
|
|
************************************************************************/
|
|
const BYTE STX=0x02;
|
|
const BYTE ETX=0x03;
|
|
const BYTE ACK=0x06;
|
|
const BYTE DLE=0x10;
|
|
const BYTE WAKEUP=0xFF;
|
|
const BYTE NAK=0x15;
|
|
|
|
// This is taken from r56 and checked in on r63
|
|
#include <vector>
|
|
|
|
class gdioutput;
|
|
|
|
struct SICard5Detect
|
|
{
|
|
BYTE code;//Code;
|
|
BYTE len;
|
|
SHORT station;
|
|
DWORD number;
|
|
WORD crc;
|
|
};
|
|
|
|
struct SIPunch {
|
|
DWORD Code;
|
|
DWORD Time;
|
|
|
|
void analyseHour12Time(DWORD zeroTime);
|
|
};
|
|
|
|
enum class ConvertedTimeStatus {
|
|
Unknown = 0,
|
|
Hour12,
|
|
Hour24,
|
|
Done,
|
|
};
|
|
|
|
struct SICard
|
|
{
|
|
SICard(ConvertedTimeStatus status) {
|
|
clear(0);
|
|
convertedTime = status;
|
|
}
|
|
// Clears the card if this == condition or condition is 0
|
|
void clear(const SICard *condition) {
|
|
if (this==condition || condition==0)
|
|
memset(this, 0, sizeof(SICard));
|
|
}
|
|
|
|
void analyseHour12Time(DWORD zeroTime);
|
|
|
|
bool empty() const {return CardNumber==0;}
|
|
DWORD CardNumber;
|
|
SIPunch StartPunch;
|
|
SIPunch FinishPunch;
|
|
SIPunch CheckPunch;
|
|
DWORD nPunch;
|
|
SIPunch Punch[192];
|
|
wchar_t firstName[21];
|
|
wchar_t lastName[21];
|
|
wchar_t club[41];
|
|
int miliVolt; // SIAC voltage
|
|
char readOutTime[32];
|
|
bool punchOnly;
|
|
ConvertedTimeStatus convertedTime;
|
|
// Used for manual time input
|
|
int runnerId;
|
|
int relativeFinishTime;
|
|
bool statusOK;
|
|
bool statusDNF;
|
|
vector<string> codeLogData(gdioutput &converter, int row) const;
|
|
static vector<string> logHeader();
|
|
|
|
unsigned int calculateHash() const;
|
|
bool isManualInput() const {return runnerId != 0;}
|
|
|
|
string serializePunches() const;
|
|
void deserializePunches(const string &arg);
|
|
};
|
|
|
|
struct SI_StationData {
|
|
SI_StationData();
|
|
|
|
int stationNumber;
|
|
int stationMode;
|
|
bool extended;
|
|
bool handShake;
|
|
bool autoSend;
|
|
int radioChannel;
|
|
};
|
|
|
|
struct SI_StationInfo
|
|
{
|
|
SI_StationInfo();
|
|
HANDLE ThreadHandle;
|
|
wstring ComPort;
|
|
HANDLE hComm;
|
|
COMMTIMEOUTS TimeOuts;
|
|
|
|
vector<SI_StationData> data;
|
|
|
|
int stationMode() const {
|
|
if (data.empty())
|
|
return 0;
|
|
else
|
|
return data[0].stationMode;
|
|
}
|
|
|
|
bool extended() const {
|
|
if (data.empty())
|
|
return false;
|
|
bool ext = true;
|
|
for (size_t k = 0; k < data.size(); k++) {
|
|
if (!data[k].extended)
|
|
ext = false;
|
|
}
|
|
return ext;
|
|
}
|
|
//Used for TCP ports
|
|
WORD tcpPort;
|
|
int localZeroTime;
|
|
};
|
|
|
|
|
|
class SportIdent
|
|
{
|
|
protected:
|
|
bool readSI6Block(HANDLE hComm, BYTE *data);
|
|
bool readSystemData(SI_StationInfo *si, int retry=2);
|
|
bool readSystemDataV2(SI_StationInfo &si);
|
|
CRITICAL_SECTION SyncObj;
|
|
|
|
int readByte_delay(BYTE &byte, HANDLE hComm);
|
|
int readBytes_delay(BYTE *byte, DWORD buffSize, DWORD len, HANDLE hComm);
|
|
int readBytesDLE_delay(BYTE *byte, DWORD buffSize, DWORD len, HANDLE hComm);
|
|
|
|
int readByte(BYTE &byte, HANDLE hComm);
|
|
int readBytes(BYTE *byte, DWORD len, HANDLE hComm);
|
|
int readBytesDLE(BYTE *byte, DWORD len, HANDLE hComm);
|
|
|
|
// Returns zero on failure, number of bytes used on success.
|
|
int analyzeStation(BYTE *db, SI_StationData &si);
|
|
|
|
SI_StationInfo SI_Info[32];
|
|
int n_SI_Info; //Number of structures..
|
|
SI_StationInfo *Current_SI_Info; //Current SI_Info in use (for thread startup);
|
|
|
|
WORD calcCRC(BYTE *data, DWORD length);
|
|
bool checkCRC(BYTE *bf, DWORD maxLen);
|
|
void setCRC(BYTE *bf);
|
|
|
|
bool getCard5Data(BYTE *data, SICard &card);
|
|
bool getCard6Data(BYTE *data, SICard &card);
|
|
bool getCard9Data(BYTE *data, SICard &card);
|
|
|
|
DWORD GetExtCardNumber(const BYTE *data) const;
|
|
|
|
void getSI5Data(HANDLE hComm);
|
|
void getSI5DataExt(HANDLE hComm);
|
|
|
|
void getSI6Data(HANDLE hComm);
|
|
void getSI6DataExt(HANDLE hComm);
|
|
void getSI9DataExt(HANDLE hComm);
|
|
|
|
void analyseSI5Time(BYTE *data, DWORD &time, DWORD &control);
|
|
bool analysePunch(BYTE *data, DWORD &time, DWORD &control);
|
|
void analyseTPunch(BYTE *data, DWORD &time, DWORD &control);
|
|
|
|
//Card read waiting to be processed.
|
|
list<SICard> ReadCards;
|
|
HWND hWndNotify;
|
|
DWORD ClassId;
|
|
|
|
volatile int tcpPortOpen;
|
|
volatile size_t serverSocket;
|
|
|
|
bool MonitorTEST(SI_StationInfo &si);
|
|
bool MonitorSI(SI_StationInfo &si);
|
|
int MonitorTCPSI(WORD port, int localZeroTime);
|
|
|
|
struct TestCard {
|
|
int cardNo;
|
|
vector<int> punches;
|
|
|
|
bool operator<(const TestCard &c) const {
|
|
return cardNo < c.cardNo;
|
|
}
|
|
|
|
TestCard(int cardNo, const vector<int> &punches) : cardNo(cardNo),
|
|
punches(punches) {
|
|
}
|
|
};
|
|
|
|
set<TestCard> testCards;
|
|
|
|
bool readVoltage;
|
|
|
|
public:
|
|
SI_StationInfo *findStation(const wstring &com);
|
|
|
|
/** Log debug data. */
|
|
void debugLog(const wchar_t *ptr);
|
|
|
|
void getInfoString(const wstring &com, vector<wstring> &info);
|
|
bool isPortOpen(const wstring &com);
|
|
bool autoDetect(list<int> &ComPorts);
|
|
void stopMonitorThread();
|
|
|
|
void startMonitorThread(const wchar_t *com);
|
|
bool getCard(SICard &sic);
|
|
void addCard(const SICard &sic);
|
|
void addPunch(DWORD Time, int Station, int Card, int Mode=0);
|
|
|
|
void addTestCard(int cardNo, const vector<int> &punches);
|
|
|
|
void EnumrateSerialPorts(list<int> &ports);
|
|
|
|
void closeCom(const wchar_t *com);
|
|
bool openCom(const wchar_t *com);
|
|
bool tcpAddPort(int port, DWORD zeroTime);
|
|
|
|
bool openComListen(const wchar_t *com, DWORD BaudRate);
|
|
|
|
SportIdent(HWND hWnd, DWORD Id, bool readVoltage);
|
|
virtual ~SportIdent();
|
|
friend void start_si_thread(void *ptr);
|
|
|
|
};
|
|
|
|
#endif // !defined(AFX_SPORTIDENT_H__F13F5795_8FA9_4CE6_8497_7407CD590139__INCLUDED_)
|