⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 komunikator.cpp

📁 s/w handheld terminal ( based on Cygnal 8051f230)
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#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 + -