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

📄 komunikator.cpp

📁 s/w handheld terminal ( based on Cygnal 8051f230)
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    pTrPoruka->PostaviKomponentu( KP_START ,        START_PORUKE );
    pTrPoruka->PostaviKomponentu( KP_KOMANDA,       IDkomande );
    pTrPoruka->PostaviKomponentu( KP_SERIJSKI_BROJ,   
                                  ( KKorisno::Instance()->KonvertIntUBCD( nSerijskiBroj, 4 ) ).cString );
    pTrPoruka->PostaviKomponentu( KP_SUMA,          0 );
    transakcija.DodajPoruku( *pTrPoruka );
}


// Pomocna procedura : dodaje prijemnu poruku u transakciju
void KKomunikator::DodajPorukuZaOdgovor( unsigned int nDuzinaOdgovora, bool bKodirajSadrzaj,
                                         IDFormataPoruke formatOdgovora ){
    KTransankcionaPoruka* pTrPoruka;
    pTrPoruka = new KTransankcionaPoruka( KOpisTPoruke( KOMANDA_PRIMI, nDuzinaOdgovora, bKodirajSadrzaj ), 
                                          formatOdgovora );
    transakcija.DodajPoruku( *pTrPoruka );
}


// Pomocna procedura : u transakciju dodaje poruku sa podacima za slanje terminalu
void KKomunikator::DodajPorukuPodatakaZaTerminal( EIDKomande IDkomande, bool bKodirajSadrzaj,
                                                  string cPodaciZaTerminal ){
    KTransankcionaPoruka* pTrPoruka = new KTransankcionaPoruka( KOpisTPoruke( KOMANDA_POSALJI, 0, bKodirajSadrzaj ),
                                                                FP_PODACI_TERMINAL );
    pTrPoruka->PostaviKomponentu( KP_START ,    START_PORUKE );
    pTrPoruka->PostaviKomponentu( KP_KOMANDA,   IDkomande );
    pTrPoruka->PostaviKomponentu( KP_SADRZAJ,   cPodaciZaTerminal );
    pTrPoruka->PostaviKomponentu( KP_SUMA,      0 );
    transakcija.DodajPoruku( *pTrPoruka );
}

// Pomocna procedura : izvrsava transakciju i izdvaja korisne podatke.
// U slucaju neuspeha vraca false;
bool KKomunikator::ProcitajPodatkeSaTerminala( string& cKorisniPodaci ){
    bool izlaz = false;

    if ( IzvrsiTransakciju() ) { 
        cKorisniPodaci.erase();
        DajPodatkeIzTransakcije( cKorisniPodaci );
        izlaz = true;
    }

    return izlaz;
}

// Ocitavanje podataka sa terminala, za brojilo sa datim serijskim brojem.
// Ocitane podatke vraca preko parametra cKorisniPodaci. U slucaju neuspeha vraca false.
// Ako je nDuzinaOdg==0, uzima se duzina odgovora definisana u spisku komandi.
bool KKomunikator::OcitajPodatak( EIDKomande ID, unsigned int nSerijskiBroj, string& cKorisniPodaci,
                                  unsigned int nDuzinaOdg ){
    bool izlaz = false;

    KKomanda komanda;
    // Uzima u obzir samo komande iz spiska ( 'podrzane' komande )
    if ( KSpisakKomandi::Instance()->DajKomandu( ID, komanda ) ) {

        // Inicijalizuj transakciju
        ResetujTransakciju( string( "Ocitavanje podatka" ) );

        // Formiraj komandu ( poruku formata FP_KOMANDA_TERMINALU ) koja se salje terminalu
        DodajKomandnuPoruku( ID, false, nSerijskiBroj );

        // Formiraj poruku za odgovor od terminala
        if ( nDuzinaOdg == 0 ) {
            if ( adminInfo.bDodatniOpisRT ) {
                // nova verzija
                DodajPorukuZaOdgovor( komanda.nDuzinaOdgovora + 1, false, komanda.formatOdgovora );
            }
            else {
                // stara verzija
                DodajPorukuZaOdgovor( komanda.nDuzinaOdgovora, false, komanda.formatOdgovora );
            }
        }
        else {
            // Ako je duzina odgovora zadata ( npr za 'admin info' i za 'opis terminala' ),
            // ne modifikujem je :
            DodajPorukuZaOdgovor( nDuzinaOdg, false, komanda.formatOdgovora );
        }

        // Izvrsi transakciju
        izlaz = ProcitajPodatkeSaTerminala( cKorisniPodaci );
    }

    return izlaz;
}

// Ocitavanje grupe podataka sa terminala, za brojilo sa datim serijskim brojem.
// Grupa podataka je definisana flegovima.
// Ocitane podatke vraca preko parametra cKorisniPodaci. U slucaju neuspeha vraca false.
bool KKomunikator::OcitajGrupuPodataka( unsigned int nFlegovi, unsigned int nSerijskiBroj, 
                                        string& cKorisniPodaci ){
    bool izlaz = false;

    // Inicijalizuj transakciju
    ResetujTransakciju( string( "Ocitavanje svih podataka" ) );

    // Formiraj komandu ( poruku formata FP_KOMANDA_TERMINALU ) koja se salje terminalu
    DodajKomandnuPoruku( KT_OCITAJ_SVE_PODATKE, false, nSerijskiBroj );

    // Prodji kroz spisak komandi i uzmi one koje se traze
    TSpisakKomandi::iterator sk_iter    = KSpisakKomandi::Instance()->SpisakKomandi.begin();
    TSpisakKomandi::iterator sk_iterEnd = KSpisakKomandi::Instance()->SpisakKomandi.end();
    KKomanda komanda;
    while ( sk_iter != sk_iterEnd ) {
        if ( sk_iter->nPodatakFleg & nFlegovi ) {
            unsigned int nDuzinaOdgovora;
            IDFormataPoruke formatOdgovora;
            unsigned int nPodatakFleg;
            // Formiraj poruku za odgovor od terminala
            KSpisakKomandi::Instance()->DajOpisKomande( sk_iter->IDkomande, adminInfo,
                                                        nDuzinaOdgovora, 
                                                        formatOdgovora, 
                                                        nPodatakFleg );
            if ( adminInfo.bDodatniOpisRT ) {
                // Nova verzija :
                //  odgovor od terminala je poruka koja se sastoji od sledecih komponenti :
                //      - poruka pocinje sa start bajtom i ID-om;
                //      - zatim sledi 1 bajt koji definise duzinu ocitanog podatka;
                //      - iza toga slede bajtovi samog podatka; duzina ovog dela 
                //        se dobija iz 'opisa rucnog terminala' ( opisTerminala )
                //      - na kraju ide 1 bajt za sumu
                // Znaci, duzina odgovora je :
                nDuzinaOdgovora = OVERH + opisTerminala.DuzinaPodataka( sk_iter->nPodatakFleg );
                DodajPorukuZaOdgovor( nDuzinaOdgovora, false, formatOdgovora );
            }
            else {
                // Stara verzija
                DodajPorukuZaOdgovor( nDuzinaOdgovora, false, formatOdgovora );
            }
        }
        sk_iter ++;
    }

    // Izvrsi transakciju
    izlaz = ProcitajPodatkeSaTerminala( cKorisniPodaci );

    return izlaz;
}

// Preuzima 'administrativne' informacije sa rucnog terminala.
// U slucaju neuspeha vraca false.
// nDuzinaOdg ( duzina odgovora ) zavisi od verzije softvera na rucnom terminalu.
bool KKomunikator::OcitajOpisRT( void ) {
    bool izlaz = false;

    // Procitaj ADMIN_INFO sa terminala
    string cPodaci;

    // NAPOMENA: pri pozivu procedure OcitajPodatak moram da zadam duzinu odgovora
    // ( u suprotnom, procedura ce da poveca duzinu za 1 pa ocitavanje nece da uspe )
    if ( OcitajPodatak( KT_OCITAVANJE_OPISA_RT, 0, cPodaci, OVERH+BROJ_BAJTOVA_ZA_OPIS_RT ) ) {
        KInterpret::Instance()->IzdvojiOpisRT( cPodaci, opisTerminala );
        izlaz = true;
    }
    else {
        opisTerminala.Reset();
    }

    return izlaz;
}

// Preuzima 'administrativne' informacije sa rucnog terminala.
// U slucaju neuspeha vraca false.
bool KKomunikator::OcitajAdminInfo( void ) {
    bool izlaz = false;

    // Najpre pokusaj najnoviju verziju
    izlaz = OcitajAdminInfoDateDuzine( OVERH + BROJ_BAJTOVA_ZA_ADMIN_INFO_11 );

    // Ako ne uspe, probaj staru verziju
    if ( !izlaz ) izlaz = OcitajAdminInfoDateDuzine( OVERH + BROJ_BAJTOVA_ZA_ADMIN_INFO_10 );

    return izlaz;
}

// Preuzima 'administrativne' informacije sa rucnog terminala.
// U slucaju neuspeha vraca false.
// nDuzinaOdg ( duzina odgovora ) zavisi od verzije softvera na rucnom terminalu.
bool KKomunikator::OcitajAdminInfoDateDuzine( unsigned int nDuzinaOdg ) {
    bool izlaz = false;

    // Procitaj ADMIN_INFO sa terminala
    string cPodaci;
    if ( OcitajPodatak( KT_OCITAJ_ADMIN_INFO, 0, cPodaci, nDuzinaOdg ) ) {
        KInterpret::Instance()->IzdvojiAdminInfo( cPodaci, adminInfo );
        adminInfo.Prikljuci();
        izlaz = true;
    }
    else {
        adminInfo.Reset();
        adminInfo.Otkaci();
    }

    return izlaz;
}

// Ocitavanje tarife koja treba da se setuje na brojilima. U slucaju neuspeha vraca false.
bool KKomunikator::OcitajMasterTarifu( string& cKorisniPodaci ){
    return OcitajPodatak( KT_OCITAJ_MASTER_TARIFU, 0, cKorisniPodaci, 
                          OVERH+BROJ_BAJTOVA_ZA_MASTER_TARIFU );
}

// Ocitavanje sve podataka sa terminala, za brojilo sa datim serijskim brojem.
// Grupu podataka definisu flegovi koje treba setovati pozivom procedure 'OcitajAdminInfo'.
// Ocitane podatke vraca preko parametra cKorisniPodaci. U slucaju neuspeha vraca false.
bool KKomunikator::OcitajSvePodatake( unsigned int nSerijskiBroj, string& cKorisniPodaci ){
    return OcitajGrupuPodataka( adminInfo.nKontrolniFlegovi, nSerijskiBroj, cKorisniPodaci );
}

// Ocitavanje spiska brojila sa rucnog terminala.
// Ocitane podatke vraca preko parametra cKorisniPodaci. U slucaju neuspeha vraca false.
bool KKomunikator::OcitajSpisakBrojila( string& cKorisniPodaci ){
    bool izlaz = false;

    // Terminal salje spisak brojila u delovima ( 'paketima' ). ciju velicinu treba odrediti :
    unsigned int nDuzinaElementaSpiska      = adminInfo.DuzinaElementaSpiska();
    unsigned int nMaxBrElemSpiskaUPaketu    = adminInfo.MaxBrElemSpiskaUPaketu();

    unsigned int nVelicinaCelogPaketa = 3 + nMaxBrElemSpiskaUPaketu * nDuzinaElementaSpiska;
    unsigned int nPotrebanBrojCelihPaketa     = adminInfo.nBrojBrojilaUSpisku / nMaxBrElemSpiskaUPaketu;
    unsigned int nBrojBrojilaZaPoslednjiPaket = adminInfo.nBrojBrojilaUSpisku % nMaxBrElemSpiskaUPaketu;
    unsigned int nVelicinaPoslednjegPaketa = 3 + nBrojBrojilaZaPoslednjiPaket * nDuzinaElementaSpiska;
    KKomanda komanda;
    KSpisakKomandi::Instance()->DajKomandu( KT_OCITAJ_SPISAK_BROJILA, komanda );

    // Inicijalizuj transakciju
    ResetujTransakciju( string( "Ocitavanje spiska brojila" ) );

    // Formiraj komandu ( poruku formata FP_KOMANDA_TERMINALU ) koja se salje terminalu
    DodajKomandnuPoruku( KT_OCITAJ_SPISAK_BROJILA, false );

    // Formiraj poruke za pakete koji se primaju sa terminala :
    //      - najpre za paketa 'pune duzine' :
    for ( int i = 0; i < nPotrebanBrojCelihPaketa; i++ )
        DodajPorukuZaOdgovor( nVelicinaCelogPaketa, false, komanda.formatOdgovora );
    //      - na kraju za paket sa preostalim brojilima
    if ( nBrojBrojilaZaPoslednjiPaket > 0 )
        DodajPorukuZaOdgovor( nVelicinaPoslednjegPaketa, false, komanda.formatOdgovora );

    // Izvrsi transakciju
    izlaz = ProcitajPodatkeSaTerminala( cKorisniPodaci );

    return izlaz;
}

// Ocitava trazene podatke za sva brojila u spisku 'spisakBrojila'.
// Ocitane podatke vraca preko vektora 'korisniPodaci'. U slucaju neuspeha vraca false.
bool KKomunikator::OcitajPodatkeZaBrojilaIzSpiska( TSpisakBrojila& spisakBrojila, EIDKomande IDkomande, 
                                                   TListaStringova& korisniPodaci ){
    bool izlaz = true;

    korisniPodaci.clear();
    TSpisakBrojila::iterator sb_iter    = spisakBrojila.begin();
    TSpisakBrojila::iterator sb_iterEnd = spisakBrojila.end();
    string cKorisniPodaci;
    while( sb_iter != sb_iterEnd ) {
        unsigned int nSerijskiBroj = sb_iter->nSerijskiBrojBrojila;
        if ( IDkomande == KT_OCITAJ_SVE_PODATKE ) {
            if ( !OcitajSvePodatake( nSerijskiBroj, cKorisniPodaci ) ){
                izlaz = false;
                break;
            }
        }
        else {
            if ( !OcitajPodatak( IDkomande, nSerijskiBroj, cKorisniPodaci ) ){
                izlaz = false;
                break;
            }
        }
        // Na pocetku svakog stringa je serijski broj brojila ( 4 znaka = 8 BCD cifre )
        korisniPodaci.push_back( KKorisno::Instance()->KonvertIntUString( nSerijskiBroj, 4 )
                                 +  cKorisniPodaci );
        sb_iter++;
    }

    return izlaz;
}

// Ocitava trazene podatke za sva brojila u spisku koji se nalazi u rucnom terminalu.
// Ocitane podatke vraca preko vektora 'korisniPodaci'. U slucaju neuspeha vraca false.
bool KKomunikator::OcitajPodatakZaSvaBrojila( EIDKomande IDkomande, TListaStringova& korisniPodaci ){
    bool izlaz = false;

    string cKorisniPodaci;
    if ( OcitajAdminInfo() ) {
        if ( OcitajSpisakBrojila( cKorisniPodaci ) ) {
            TSpisakBrojila spisakBrojila;
            KInterpret::Instance()->IzdvojiSpisakBrojila( cKorisniPodaci, adminInfo,
                                                          spisakBrojila );
            if( OcitajPodatkeZaBrojilaIzSpiska( spisakBrojila, IDkomande, korisniPodaci ) )
                izlaz = true;
        }
    }

    return izlaz;
}

// Izvrsava komandu za snimanje datog podatka na rucni terminal.
// U slucaju neuspeha vraca false.
bool KKomunikator::SnimiNaTerminal( EIDKomande ID, string cPodatak ){
    bool izlaz = false;

    // Inicijalizuj transakciju
    ResetujTransakciju( string( "Setovanje terminala" ) );

    // Formiraj komandu ( poruku formata FP_KOMANDA_TERMINALU ) koja se salje terminalu
    DodajKomandnuPoruku( ID, false );

    // Formiraj poruku za prijem potvrde od terminala da je spreman da primi sledeci podatak
    DodajPorukuZaOdgovor( 3, false, FP_POTVRDA_SA_TERMINALA );

    // Formiraj poruku sa podacima koji se salju terminalu
    DodajPorukuPodatakaZaTerminal( ID, false, cPodatak );

    // Formiraj poruku za potvrdu koju salje terminal da je primio podatke
    DodajPorukuZaOdgovor( 3, false, FP_POTVRDA_SA_TERMINALA );

    // Izvrsi transakciju
    izlaz = IzvrsiTransakciju();

    return izlaz;
}

// Izvrsava komandu za snimanje lozinke na rucni terminal.
// Ako rucni terminal podrzava i proveru 'ID-a PC aplikacije' onda treba zadati i taj ID.
// U slucaju neuspeha vraca false.
bool KKomunikator::SnimiLozinkuNaTerminal( EIDKomande ID, string cLozinke, 
                                           bool PodrzanPCAppID, string cAppID ){
    bool izlaz = false;

    // Inicijalizuj transakciju

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -