📄 komunikator.cpp
字号:
#include "Komunikator.h"
#include "Konfig.h"
#include <iostream>
//******************************** KTransakcija << BEGIN >> *************************************
// Konstruktori
KTransakcija::KTransakcija( string cNaziv, TListaTransakcPoruka& listaPoruka ) {
KTransakcija::naziv = cNaziv;
KTransakcija::listaPoruka = listaPoruka;
IsprazniLog();
}
// Default konstruktor
KTransakcija::KTransakcija( void ){
KTransakcija::naziv = "";
KTransakcija::listaPoruka.clear();
IsprazniLog();
}
// Vraca naziv transakcije
string KTransakcija::DajNaziv( void ){
return naziv;
}
// Postavlja naziv transakcije
void KTransakcija::PostaviNaziv( string cNoviNaziv ){
naziv = cNoviNaziv;
}
// Prazni listu poruka
void KTransakcija::IsprazniListuPoruka( void ){
listaPoruka.clear();
IsprazniLog();
}
// Vraca true ako je lista poruka prazna
bool KTransakcija::PraznaListaPoruka( void ){
return listaPoruka.empty();
}
// Dodaje poruku na kraj liste
void KTransakcija::DodajPoruku( KTransankcionaPoruka trPoruka ){
listaPoruka.push_back( trPoruka );
}
// Obilazi sve poruke transakcije i salje/prima na dati serijski port.
// Ako ne uspe slanje/prijem samo jedne poruke, prekida transakciju i vraca false.
bool KTransakcija::Izvrsi( KSerial& COMPort, double nTajmaut ){
bool izlaz = true;
string cLogPoruka;
IsprazniLog();
TListaTransakcPoruka::iterator tp_iter=listaPoruka.begin();
TListaTransakcPoruka::iterator tp_iterEnd=listaPoruka.end();
// Obidji sve poruke transakcije
while( tp_iter!=tp_iterEnd ) {
if ( tp_iter->PrijemnaPoruka() ) { // Prijem poruke
izlaz = KKomunikator::Instance()->PrimiPoruku( *tp_iter, tp_iter->DajDuzinuTP(),
COMPort, nTajmaut, tp_iter->SadrzajKodiran() );
if ( izlaz ) {
cLogPoruka = "Primio poruku "
+ KKorisno::Instance()->FormatString( tp_iter->Sadrzaj() );
}
else {
cLogPoruka = "Greska u prijemu poruke duzine "
+ KKorisno::Instance()->KonvertIntUString( tp_iter->DajDuzinuTP(), 2 );
break;
}
}
else if ( tp_iter->PorukaZaSlanje() ) { // Slanje poruke
izlaz = KKomunikator::Instance()->PosaljiPoruku( *tp_iter, COMPort, nTajmaut,
tp_iter->SadrzajKodiran() );
if ( izlaz ) {
cLogPoruka = "Poslao poruku "
+ KKorisno::Instance()->FormatString( tp_iter->Sadrzaj() );
}
else {
cLogPoruka = "Greska pri slanju poruke "
+ KKorisno::Instance()->FormatString( tp_iter->Sadrzaj() );
break;
}
}
DodajPorukuULog( cLogPoruka );
tp_iter++;
}
if ( !izlaz ) DodajPorukuULog( cLogPoruka );
return izlaz;
}
// Procedura izdvaja korisne podatke iz poruka primljenih od terminala i smesta u string 'cKorisniPodaci'
void KTransakcija::IzdvojiKorisnePodatke( string& cKorisniPodaci ) {
// Izdvaja SADRZAJ-e svih primljenih poruka i pravi jedan niz bajtova
cKorisniPodaci.erase();
TListaTransakcPoruka::iterator tp_iter=listaPoruka.begin();
TListaTransakcPoruka::iterator tp_iterEnd=listaPoruka.end();
while( tp_iter!=tp_iterEnd ) {
if ( tp_iter->PrijemnaPoruka() ) {
cKorisniPodaci += tp_iter->DajKomponentu( KP_SADRZAJ );
}
tp_iter++;
}
}
// Isprazni 'dnevnik' transakcije
void KTransakcija::IsprazniLog( void ){
log.clear();
}
// Dodaje poruku u 'dnevnik' transakcije
void KTransakcija::DodajPorukuULog( KString cPoruka ){
log.push_back( cPoruka );
}
// Vraca 'dnevnik' transakcije preko parametra log
void KTransakcija::DajLog( TListaStringova& log ){
log = this->log;
}
//********************************* KTransakcija << END >> **************************************
//******************************** KKomunikator << BEGIN >> *************************************
// Konstruktor
KKomunikator::KKomunikator( void ) {
// Parametri za komunikaciju sa terminalom
nBrojPokusaja = 1;
nTajmaut = 0.5;
nTransakcTajmaut = 0.5;
// ADMIN_INFO ( informacije o rucnom terminalu )
adminInfo.Reset();
}
// Procedura za pristup jedinom objektu klase
KKomunikator* KKomunikator::Instance( void ){
static KKomunikator instance;
return &instance;
}
// Procedura za inicijalizaciju :
// - cita konfiguracione parametare iz konfig. fajla koji se nalazi u datom direktorijumu
// - postavlja parametare za transakcije ( broj pokusaja i tajmaut )
void KKomunikator::Init( string cNazivExeDatoteke, string cAppDir,
unsigned int nBrojPokusaja, double nTajmaut ){
// Postavi direktorijum direktorijum aplikacije
KKonfig::Instance()->PostaviAppNazivIDir( cNazivExeDatoteke, cAppDir );
// Postavi direktorijum konfiguiracionog fajla( treba da bude direktorijum aplikacije )
KKonfig::Instance()->PostaviKonfigDir( cAppDir );
// Procitaj konfiguracione parametre iz konfiguracione datoteke
KKonfig::Instance()->ProcitajKonfigDatoteku();
// Postavi parametre za transakcije
PostaviBrojPokusaja( nBrojPokusaja );
PostaviTajmaut( nTajmaut );
}
// Vraca broj pokusaja da izvrsi transakciju pre nego sto javi gresku
unsigned int KKomunikator::DajBrojPokusaja( void ){
return nBrojPokusaja;
}
// Postavlja koliko puta pokusava da izvrsi transakciju pre nego sto javi gresku
void KKomunikator::PostaviBrojPokusaja( unsigned int nBrPokusaja ){
nBrojPokusaja = nBrPokusaja;
}
// Vraca vrednost tajmauta za serijsku komunikaciju.
double KKomunikator::DajTajmaut( void ){
return KKomunikator::nTajmaut;
}
// Vraca vrednost tajmauta izmedju dva pokusaja izvrsenja transakcije.
double KKomunikator::DajTransakcTajmaut( void ){
return KKomunikator::nTransakcTajmaut;
}
// Postavlja vrednost tajmauta za serijsku komunikaciju.
void KKomunikator::PostaviTajmaut( double nSendRcvTajmaut ){
KKomunikator::nTajmaut = nSendRcvTajmaut;
}
// Postavlja vrednost tajmauta izmedju dva pokusaja izvrsenja transakcije.
void KKomunikator::PostaviTransakcTajmaut( double nTerminalTajmaut ){
KKomunikator::nTransakcTajmaut = nTerminalTajmaut;
}
// Vraca vrednosti parametara komunikacije ( tajmauti i broj pokusaja )
void KKomunikator::DajParametreKomunikacije( double& nSendRcvTajmaut, double& nTransakcTajmaut,
unsigned int& nBrPokusaja ){
nSendRcvTajmaut = DajTajmaut();
nTransakcTajmaut = DajTransakcTajmaut();
nBrPokusaja = DajBrojPokusaja();
}
// Postavi vrednosti parametara komunikacije ( tajmauti i broj pokusaja )
void KKomunikator::PostaviParametreKomunikacije( double nSendRcvTajmaut, double nTransakcTajmaut,
unsigned int nBrPokusaja ){
PostaviTajmaut( nSendRcvTajmaut );
PostaviTransakcTajmaut( nTransakcTajmaut );
PostaviBrojPokusaja( nBrPokusaja );
}
// Vraca 'true' ako lista poruka transakcije nije prazna
bool KKomunikator::TransakcijaFormirana( void ){
return !transakcija.PraznaListaPoruka();
}
// Procedura za kodiranje/dekodiranje datog stringa ( niza bajtova )
string KKomunikator::KoDekuj( const string& cStr ){
string cOutStr;
int nLen = cStr.size();
unsigned char cPomChr;
for ( int i=0; i<nLen; i++ ){
cPomChr = nLen - i;
cPomChr ^= 0xAA;
cPomChr ^= cStr[i];
cOutStr.append( 1, cPomChr );
}
return cOutStr;
}
// Prima poruku date duzine sa datog serijskog porta i smesta u promenljivu 'poruka'.
// U slucaju greske vraca 'false'.
// Nakon prijema, sadrzaj poruke se dekodira ako je nDekodirajSadrzaj == true.
bool KKomunikator::PrimiPoruku( KPoruka& poruka, unsigned int nDuzinaOcekivanePoruke,
KSerial& COMPort, double nTajmaut, bool nDekodirajSadrzaj ){
bool izlaz = false;
string cPrimljenaPoruka;
// Najpre cekaj start bajt
if ( COMPort.PrimiBajt( START_PORUKE, nTajmaut ) ) {
// Primi i ostatak poruke
string cPomStr;
if ( COMPort.PrimiPoruku( nDuzinaOcekivanePoruke-1, cPomStr, nTajmaut ) ) {
cPrimljenaPoruka.assign( 1, START_PORUKE );
cPrimljenaPoruka += cPomStr;
poruka.PostaviSadrzaj( cPrimljenaPoruka );
// Proveri sumu ( ako postoji )
if ( poruka.PostojiKomponenta( KP_SUMA ) )
if ( poruka.ProveriSumu() ) izlaz = true;
else
izlaz = true;
// Nakon provere sume, moze da se dekodira sadrzaj( ako treba )
if ( nDekodirajSadrzaj ){
poruka.PostaviKomponentu( KP_SADRZAJ,
KoDekuj( poruka.DajKomponentu( KP_SADRZAJ ) ) );
}
}
}
return izlaz;
}
// Salje datu poruku na dati serijski port. U slucaju neuspeha vraca 'false'.
// Pre slanja, sadrzaj poruke se kodira ako je nKodirajSadrzaj == true.
bool KKomunikator::PosaljiPoruku( KPoruka& poruka, KSerial& COMPort, double nTajmaut,
bool nKodirajSadrzaj ){
bool izlaz = false;
unsigned int nDuzinaPoruke = poruka.Duzina();
// Ako je potrebno, kodiraj sadrzaj
if ( nKodirajSadrzaj ){
string cPomStr = KoDekuj( poruka.DajKomponentu( KP_SADRZAJ ) );
poruka.PostaviKomponentu( KP_SADRZAJ, cPomStr );
}
// Sracunaj sumu ( ako poruka ima komponentu 'SUMA' ).
poruka.PostaviSumu();
// Posalji poruku
if ( nDuzinaPoruke == COMPort.SendData( poruka.Sadrzaj().data(), nDuzinaPoruke ) )
izlaz = true;
return izlaz;
}
// Salje/prima poruke transakcije. U slucaju neuspeha vraca 'false'.
bool KKomunikator::IzvrsiTransakciju( void ){
bool izlaz = false;
if ( TransakcijaFormirana() ){
// Procitaj setovanja za dati serijski port
int nPort, nBaud;
KKonfig::Instance()->DajPortKonfig( KKonfig::Instance()->DajAktivniCOMPort(),
nPort, nBaud );
// Otvori serijski port i izvrsi transakciju
KSerial COMPort;
COMPort.Open( nPort, nBaud );
bool bTransakcUspela = false;
if ( COMPort.IsOpened() ) {
// Proba da izvrsi transakciju
bTransakcUspela = transakcija.Izvrsi( COMPort, KKomunikator::nTajmaut );
// Ako nije uspelo iz prvog pokusaja, probaj jos 'nBrojPokusaja-1' puta
for ( int i = 0; i<nBrojPokusaja-1 && !bTransakcUspela; i++ ) {
// Sacekaj neko vreme ( da terminal bude spreman )
KTime::PauzaSek( this->nTransakcTajmaut );
bTransakcUspela = transakcija.Izvrsi( COMPort, KKomunikator::nTajmaut );
}
COMPort.Close();
}
izlaz = bTransakcUspela;
}
return izlaz;
}
// Vraca podatke primljene tokom izvrsenja date transakcije
void KKomunikator::DajPodatkeIzTransakcije( string& cKorisniPodaci ){
if ( TransakcijaFormirana() )
transakcija.IzdvojiKorisnePodatke( cKorisniPodaci );
else cKorisniPodaci.erase();
}
// Pomocna procedura : inicijalizuje transakciju
void KKomunikator::ResetujTransakciju( string cNaziv ){
transakcija.IsprazniListuPoruka();
transakcija.IsprazniLog();
transakcija.PostaviNaziv( string( cNaziv ) );
}
// Pomocna procedura : dodaje komandu( poruku formata FP_KOMANDA_TERMINALU ) u transakciju.
void KKomunikator::DodajKomandnuPoruku( EIDKomande IDkomande, bool bKodirajSadrzaj,
unsigned int nSerijskiBroj ){
KTransankcionaPoruka* pTrPoruka = new KTransankcionaPoruka( KOpisTPoruke( KOMANDA_POSALJI, 0, bKodirajSadrzaj ),
FP_KOMANDA );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -