jablonka.czprosek.czf

crusader

Subversion Repositories:
[/] [trunk/] [crusader_read_rss/] [crusader100_read_rss.c] - Rev 3

Compare with Previous - Blame - Download


/*
 *  crusader100_read_rss
 *
 *  compile: gcc -Wall -D_DEBUG crusader100_read_rss.c -o crusader100_read_rss
 *
 *  Licence: GNU GPL ver.2
 *
 *  Changelog:
 *  2007-01-27/Libor  oprava cteni RSS<100, tj. dvoucifernych
 *  2008-05-23/Libor  zacatek prace na podpore Crusader Aggregator 100M
 *  2008-06-07/Libor  prvni verze se zakladni funkcnosti
 *  2008-07-10/Libor  cte krome hodnot registru vsechny veliciny
 *  2008-07-13/Libor  oprava neinicializovane promenne pro soucet RSS
 *
 */


#include <assert.h>
#include <stdio.h>          /* Standard input/output definitions */
#include <sys/types.h>      
#include <sys/stat.h>       
#include <fcntl.h>          /* File control definitions */
#include <termios.h>
#include <unistd.h>         /* UNIX standard function definitions */
#include <stdlib.h>
#include <limits.h>         /* INT_MAX and others */
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <ctype.h>                      /* isdigit() a.s.o. */
#include <time.h>


static char   *jmeno_seriaku = "";
static time_t  cilovy_cas = 0;
static time_t  cas_startu = 0;

/* baudrate settings are defined in <asm/termbits.h>, which is
   included by <termios.h> */
#define BAUDRATE B38400            
/* change this definition for the correct port */
//#define MODEMDEVICE "/dev/ttyS1"
//#define MODEMDEVICE "crusader.log"
#define _POSIX_SOURCE 1 /* POSIX compliant source */

#define FALSE 0
#define TRUE 1

#ifdef _DEBUG
#       define DEBUG(level, fmt, args...) fprintf(stderr, fmt, ## args)
#       define DBG(fmt, args...) DEBUG(L_DBG, "DEBUG: " fmt, ## args)
#else
#       define DEBUG(level, fmt, args...)
#       define DBG(fmt, args...)
#endif

#define L_ALERT  -3
#define L_CRIT   -2
#define L_ERR    -1
#define L_DEFAULT 0
#define L_WARN    1
#define L_NOTICE  2
#define L_INFO    3
#define L_DBG     4

int otevri_seriak(char *devname)
{
        int fd;
        /*
           Open modem device for reading and writing and not as controlling tty
           because we don't want to get killed if linenoise sends CTRL-C.
         */
        fd = open(devname, O_RDWR | O_NOCTTY | O_NDELAY); 
        if (fd < 0) { perror(devname); }
        return fd;
}


int nastav_seriak(int fd, struct termios *oldtio)
{
        struct termios newtio;

        tcgetattr(fd, oldtio); /* save current serial port settings */
        memset(&newtio, 0, sizeof(newtio)); /* clear struct for new port settings */

        /* 
          BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed.
          CRTSCTS : output hardware flow control (only used if the cable has
                    all necessary lines. See sect. 7 of Serial-HOWTO)
          CS8     : 8n1 (8bit,no parity,1 stopbit)
          CLOCAL  : local connection, no modem contol
          CREAD   : enable receiving characters
        */
        newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
         
        /*
          IGNPAR  : ignore bytes with parity errors
          ICRNL   : map CR to NL (otherwise a CR input on the other computer
                    will not terminate input)
          otherwise make device raw (no other input processing)
        */
        newtio.c_iflag = IGNPAR | ICRNL;
         
        /*
         Raw output.
        */
        newtio.c_oflag = 0;
         
        /*
          ICANON  : enable canonical input
          disable all echo functionality, and don't send signals to calling program
        */
        newtio.c_lflag = ICANON;
         
        /* 
          initialize all control characters 
          default values can be found in /usr/include/termios.h, and are given
          in the comments, but we don't need them here
        */
        newtio.c_cc[VINTR]    = 0;     /* Ctrl-c */ 
        newtio.c_cc[VQUIT]    = 0;     /* Ctrl-\ */
        newtio.c_cc[VERASE]   = 0;     /* del */
        newtio.c_cc[VKILL]    = 0;     /* @ */
        newtio.c_cc[VEOF]     = 4;     /* Ctrl-d */
        newtio.c_cc[VTIME]    = 0;     /* inter-character timer unused */
        newtio.c_cc[VMIN]     = 1;     /* blocking read until 1 character arrives */
        newtio.c_cc[VSWTC]    = 0;     /* '\0' */
        newtio.c_cc[VSTART]   = 0;     /* Ctrl-q */ 
        newtio.c_cc[VSTOP]    = 0;     /* Ctrl-s */
        newtio.c_cc[VSUSP]    = 0;     /* Ctrl-z */
        newtio.c_cc[VEOL]     = 0;     /* '\0' */
        newtio.c_cc[VREPRINT] = 0;     /* Ctrl-r */
        newtio.c_cc[VDISCARD] = 0;     /* Ctrl-u */
        newtio.c_cc[VWERASE]  = 0;     /* Ctrl-w */
        newtio.c_cc[VLNEXT]   = 0;     /* Ctrl-v */
        newtio.c_cc[VEOL2]    = 0;     /* '\0' */

        /*
           now clean the modem line and activate the settings for the port
         */
        tcflush(fd, TCIFLUSH);
        tcsetattr(fd,TCSANOW, &newtio);

        return 0;
}

int restore_seriak(int fd, struct termios *stored_tio)
{
        /* restore the old port settings */
        tcsetattr(fd, TCSANOW, stored_tio);
        return 0;
}

void print_usage()
{
        printf("\nusage: seriak <jmeno seriaku> {<cilovy cas> | +<offset>}\n\n");
}

void check_params( int argc, char *argv[])
{
    int   relative = 0;
    char *nptr = NULL, *endptr = NULL;
    
    if ( argc != 3 || (argc == 3 && ( strcmp("-h", argv[1])==0 || strcmp("--help", argv[1])==0 )) ) {
        print_usage();
        exit(EXIT_FAILURE);
    }
    jmeno_seriaku = argv[1];
    
    nptr = argv[2];
    if ( argv[2][0] == '+' ) {  /* relativni cas */
        if ( strlen(argv[2]) < 1 ) {
            print_usage();
            exit(EXIT_FAILURE);
        }
        nptr++;
        relative = 1;
    }
    cilovy_cas = strtol(argv[2], &endptr, 10);

#ifdef _DEBUG
    fprintf (stderr, "arg[2]: %s, endptr: %p, cilovy_cas: %ld\n", argv[2], endptr, cilovy_cas);
#endif

    if ( !(argv[2] != '\0' && *endptr == '\0') )
    {
        fprintf(stderr, "ERROR: spatny tvar ciloveho casu");
        print_usage();
        exit(EXIT_FAILURE);
    }
    
    if (relative) {
        cilovy_cas += cas_startu;
    }
}

/**
 *  Hleda zda se v prijimacim bufferu buff naleza ocekavany retezec exp_res.
 * @param buf pointer na prijimaci buffer
 * @param buflen delka prijimaciho bufferu
 * @param exp_res ocekavany vysledek, ktery hledame ve vstupnim bufferu
 * @return 0 kdyz je to OK, jinak 1.
 *
 */
int check_response(char *buf, int buflen, char *exp_res)
{
        return 0;
}

/**
 * vypise na stderr obsah daneho bufferu jako text i jako hexakody.
 * misto tisknutelnych znaku se vypisuje tecka
 * @param buf ukazatel na buffer
 * @param bufsize velikost bufferu
 * @param pocet pocet bajtu, ktere se maji vypsat
 */
void print_debug_buffer(char *buf, size_t bufsize, size_t pocet)
{
        time_t cas;
        int i;
        
        assert(bufsize >= 0);
        assert(buf != NULL);
        
        DBG("print_debug_buffer(bufsize=%d, pocet=%d)\n", bufsize, pocet);
        cas = time(0);
        if (pocet > bufsize) {
                fprintf(stderr, "prilis maly buffer, snizuji pocet = bufsize\n");
                pocet = bufsize;
        }
        
        fprintf(stderr, "DEBUG: cas: %ld, buf: '", cas);
        for ( i = 0; i < pocet; ++i )
        {
                if (buf[i] >= ' ') {
                        fprintf(stderr, "%c", buf[i]);
                } else {
                        fprintf(stderr, ".");
                }
        }
        fprintf(stderr, "'  hex: ");
        for ( i = 0; i < pocet; ++i ) {
                fprintf(stderr, "%02x ", buf[i]);
        }
        fprintf(stderr, "\n");
}

// TODO check HUGE_VAL, ERANGE, see strtod(3)
int get_double(char *str, int len, double *value)
{
        double v;
        char *eptr;
        
        DBG("get_double(str='%.*s', len=%d)\n", len, str, len);
        eptr = NULL;
        v = strtod(str, &eptr);
        if (*eptr == '\0') {
                DBG("get_double: value = %6.2f\n", v);
                *value = v;
                return 0;
        }
        else {
                DBG("get_double: error in conversion\n");
                *value = 0;
                return -1;
        }
}
int get_long(char *str, int len, long *value)
{
        long v;
        char *eptr;
        
        DBG("get_long(str='%.*s', len=%d)\n", len, str, len);
        eptr = NULL;
        v = strtol(str, &eptr, 10);
        if (*eptr == '\0') {
                DBG("get_long: value = %ld\n", v);
                *value = v;
                return 0;
        }
        else {
                DBG("get_long: error in conversion\n");
                *value = 0;
                return -1;
        }
}

#define CRS_NAMERENO_RSS        1 << 0
#define CRS_NAMERENO_P_LSR      1 << 1
#define CRS_NAMERENO_I_BIAS     1 << 2
#define CRS_NAMERENO_U_APD      1 << 3
#define CRS_NAMERENO_T_APD      1 << 4
#define CRS_NAMERENO_T_CPU      1 << 5
#define CRS_NAMERENO_L  1 << 6
#define CRS_NAMERENO_HEAT       1 << 7

typedef enum {
        RSS_MIN,
        RSS_MAX,
        RSS_SUM,
        RSS_CNT,
        RSS_LAST
} rss_names_t;

/**
  *  Struktura obsahujici prectene udaje. Pokud byl behem merici periody nektery udaj precten vicekrat,
  *  obsahuje naposledy prectenou hodnotu. To se netyka RSS (Received Signal Strength), kde se uchovava
  *  ctene minimum, maximim, soucet a pocet ctenych hodnot. Ze souctu se pak pocita prumerna hodnota.
  *
  */
typedef struct {
        int    namereno;                /// bitove pole obsahujici informaci o tom, ktere hodnoty jsou skutecne zmerene
        long   rss[RSS_LAST];   /// bez prefixu
        double laser_power;             /// Pl [mW], vykon laseru
        double laser_bias;              /// Ib [mA], bias proud laserem
        double apd_voltage;             /// Ua [V]
        double apd_temp;                /// Ta [C]
        double apd_ureg;                /// Ur bezrozmerne, hodnota registru menice APD
        double cpu_temp;                /// T  [C]
        int    da_reg[2];               /// L  bezrozmerne, hodnoty registru D/A prevodniku
} crusader_meas_t;

void clear_value(char* varr, size_t va_size)
{
        memset(varr, 0, va_size);
}

#define KONECNY_STAV    0x1000

/*
 * Stavy prijimaciho automatu
 */
typedef enum {
        ST_START,               /// pocatecni stav automatu, zacina parsovani radky, obvykle po ST_NL nebo kdyz se ocekavaji dalsi hodnoty na radce
        ST_NL,                  /// '\n' new line, synchronizuje automat, prechoazi do ST_START
        ST_KOMENTAR,    /// NL -> '!', oznacuje komentar do dalsiho NL. Komentar '!OK' ma specialni vyznam
        ST_PLUS,
        ST_RSS,                 /// NL -> ' ', zacina cteni RSS, akceptuje cislice 0-9, jiny znak trigruje prechod do ST_KOMENTAR,
                                        ///            tj. ignorujeme RSS protistrany a bargraf
        ST_U,
        ST_U_A,
        ST_U_APD,
        ST_U_R,
        ST_U_REG,
        ST_T,
        ST_T_A,
        ST_T_APD,
        ST_T_CPU,
        ST_P,
        ST_PL,
        ST_PLASER,
        ST_I,
        ST_IB,
        ST_IBIAS,
        ST_H,
        ST_L,
        ST_L1,
        ST_L2,
        ST_ERROR = KONECNY_STAV | 500
        
} state_t;

int sezer_seriak(int seriak)
{
        ssize_t precteno;
        time_t cas = 0;
        int chyba;
        static char buf[129];
        static size_t bufsize = sizeof(buf);
        int i = 0;
        char *p;

        DBG("sezer_seriak(fd=%d)\n", seriak);   
        precteno = read(seriak, buf, bufsize-1);
        DBG("sezer_seriak: precteno = %d\n", precteno);
        DBG("sezer_seriak: cas = %lu, cilovy_cas = %lu\n", cas, cilovy_cas);
        while (precteno && cas < cilovy_cas) {
                i++;
                cas = time(0);
                DBG("sezer_seriak: i=%2d precteno = %d\n", i, precteno);
                DBG("sezer_seriak: i=%2d cas = %lu, cilovy_cas = %lu\n", i, cas, cilovy_cas);
                if (precteno < 0) {
                        DBG("if (precteno < 0)...\n");
                        chyba = errno;
                        if (chyba == EAGAIN) {
                                fprintf(stderr, "continuing...\n");
                                sleep(1);
                                goto loop_end;
                        }
                        perror("chyba cteni: ");
                        fprintf(stderr, "chyba = %d\n", chyba);
                        fprintf(stderr, "EAGAIN = %d\n", EAGAIN);
                        goto err;
                }
                if (precteno > 0) {
                        for (p = buf; p < buf+precteno; p++) {
                                if (*p == '+') goto end;
                        }
                }
#ifdef _DEBUG
                print_debug_buffer(buf, bufsize, precteno);
#endif
loop_end:
                precteno = read(seriak, buf, bufsize-1);
        }
end:
        DBG("sezer_seriak(), done\n");
        return 0;
err:
        DBG("sezer_seriak(), fail\n");
        return -1;
}

int main(int argc, char *argv[])
{
        struct termios old_tio;
        int seriak = -1;
        int chyba;
        ssize_t precteno;
        ssize_t ibuflen;
        char buf[129];
        size_t bufsize = sizeof(buf);
        time_t cas = 0;
        char *p;

        crusader_meas_t mereni;
        mereni.rss[RSS_MIN] = INT_MAX;
        mereni.rss[RSS_MAX] = 0;
        mereni.rss[RSS_CNT] = 0;
        mereni.rss[RSS_SUM] = 0;
        mereni.laser_power  = 0;
        mereni.laser_bias   = 0;
        mereni.apd_voltage  = 0;
        mereni.apd_temp     = 0;
        mereni.cpu_temp     = 0;
        long rss_avg;
        
        state_t state, next_state;
        int vidx;       /// index cislice hodnoty (value)
        char val_arr[16];
        char state_text[128];
        int state_text_len;
        int clear_state_text = 1;
        long int long_val;
        double double_val;
        long long loopcnt = 0;
        int posledni_kus = 0;

        cas_startu = time(0);
        DEBUG(L_INFO, "Cas startu: %ld - %s", cas_startu, ctime(&cas_startu));

        check_params(argc, argv);

        DEBUG(L_INFO, "Cilovy cas: %ld - %s", cilovy_cas, ctime(&cilovy_cas));

        seriak = otevri_seriak(jmeno_seriaku);
        if ( seriak == -1 )
        {
                char msg[256];
                snprintf(msg, sizeof(msg)-1, "Nejde otevrit seriak (%s)", jmeno_seriaku);
                msg[255] = '\0';
                perror(msg);
                free(msg);
                goto error1;
        }
        nastav_seriak(seriak, &old_tio);
        DBG("MAIN: write 'Z'\n");
        write(seriak, "Z\r", 2);
        sezer_seriak(seriak);
        
        DBG("MAIN: write 'E0'\n");
        write(seriak, "E0\r", 3);
        sezer_seriak(seriak);
        
        write(seriak, "#1\r", 3);

        clear_value(val_arr, sizeof(val_arr));

        state_text_len = 0;
        memset(state_text, 0, sizeof(state_text));
        clear_state_text = 1;
        for ( ; cas < cilovy_cas && posledni_kus == 0; cas = time(0) )
        {
                precteno = read(seriak, buf, bufsize-1);    /* one character less for terminating '\0' */
                if (precteno < 0) {
                        chyba = errno;
                        if (chyba == EAGAIN) {
                                DEBUG(L_INFO, "continuing...\n");
                                sleep(1);
                                continue;
                        }
                        perror("chyba cteni: ");
                        fprintf(stderr, "chyba = %d\n", chyba);
                        fprintf(stderr, "EAGAIN = %d\n", EAGAIN);
                        goto error1;
                }

// pouze pri cteni souboru
//              if (precteno != bufsize-1)
//                      posledni_kus = 1;
                
#ifdef _DEBUG
                        fprintf(stderr, "Precteno: %d\n", precteno);
                        print_debug_buffer(buf, bufsize, precteno);
#endif
                
                ibuflen = precteno;
                p = buf;
                state = ST_START;               /// zaciname s cistym stitem, tj. jakoby na novem radku
                next_state = ST_ERROR;  /// pokud se nic nestane, skoncime s chybou
                while (ibuflen > 0)
                {
                        loopcnt++;
                        assert(state_text_len >= 0);
                        assert(state_text_len < sizeof(state_text));
                        
                        state_text[state_text_len] = *p;
                        state_text_len++;
                
                        switch (state) {
                        case ST_START:
                                DBG("ST_START\n");
                        case ST_NL:
                                DBG("ST_NL\n");
                                vidx = 0;
                                switch (*p) {
                                        case '!':
                                                next_state = ST_KOMENTAR;
                                                break;
                                        case '+':
                                                next_state = ST_PLUS;
                                                break;
                                        case 0x0a:
                                                next_state = ST_NL;
                                                break;
                                        default:
                                                next_state = ST_ERROR;
                                }
                                break;
                        case ST_ERROR:
                                DBG("ST_ERROR\n");
                        case ST_KOMENTAR:
                                DBG("ST_KOMENTAR\n");
                                if (*p == 0x0a)
                                        next_state = ST_NL;
                                else
                                        next_state = ST_KOMENTAR;
                                break;
                        case ST_PLUS:
                                DBG("ST_PLUS\n");
                                switch (*p) {
                                case ' ':
                                        next_state = ST_RSS;
                                        break;;
                                case 'U':
                                        next_state = ST_U;
                                        break;
                                case 'P':
                                        next_state = ST_P;
                                        break;
                                case 'T':
                                        next_state = ST_T;
                                        break;
                                case 'I':
                                        next_state = ST_I;
                                        break;
                                case 'L':
                                        next_state = ST_L;
                                        break;
                                case 'H':
                                        next_state = ST_H;
                                        break;
                                default:
                                        next_state = ST_ERROR;
                                }
                                break;
                        case ST_RSS:
                                DBG("ST_RSS\n");
                                // ignore spaces
                                if (*p == ' ' && state_text_len == 1) {
                                        clear_state_text = 1;
                                        break;
                                }
                                // do not read rss yet, wait for space, grr!!!
                                // TODO je potreba vyresit cteni RSS, ktera ma na obou stranach mezeru
                                //      takze ji neni mozne jednoduse bezstavove parsovat
                                //      resenim bude asi dat nove stavy RSSM, M jako mezera,
                                //      RSSMC, C jako cifra a RSSMCM, M jako mezera.
                                //      kdyz se precte druha mezera, prevede se state_text string na cislo
                                if (isdigit(*p)) break;
                                
                                DBG("ST_RSS: *p = '%c'\n", *p);
                                state_text[state_text_len-1] = '\0';
                                if (get_long(state_text, state_text_len, &long_val) < 0) {
                                        fprintf(stderr, "ERROR in conversion, exiting.\n");
                                        exit(1);
                                }
                                mereni.rss[RSS_SUM] += long_val;
                                mereni.rss[RSS_CNT]++;
                                if (long_val < mereni.rss[RSS_MIN]) mereni.rss[RSS_MIN] = long_val;
                                if (long_val > mereni.rss[RSS_MAX]) mereni.rss[RSS_MAX] = long_val;
                                DBG("RSS: cnt=%ld  curr=%ld min=%ld  max=%ld  sum=%ld\n", mereni.rss[RSS_CNT], long_val, mereni.rss[RSS_MIN], mereni.rss[RSS_MAX], mereni.rss[RSS_SUM]);
                                next_state = ST_KOMENTAR;
                                break;
                        case ST_PLASER:
                                DBG("ST_PLASER\n");
                                // ignore spaces
                                if (*p == ' ' && state_text_len == 1) {
                                        clear_state_text = 1;
                                        break;
                                }
                                // hodnota je float
                                // TODO kontrolovat pritomnost pouze jedne tecky
                                if (isdigit(*p) || *p == '.') break;
                                
                                DBG("ST_PLASER: *p = '%c'\n", *p);
                                state_text[state_text_len-1] = '\0';
                                if (get_double(state_text, state_text_len, &double_val) < 0) {
                                        fprintf(stderr, "ERROR in conversion, exiting.\n");
                                        exit(1);
                                }
                                mereni.laser_power = double_val;
                                // jednotky ignorujeme, stejne to jsou vzdy mW
                                next_state = ST_KOMENTAR;
                                break;
                        case ST_IBIAS:
                                DBG("ST_IBIAS\n");
                                // ignore spaces
                                if (*p == ' ' && state_text_len == 1) {
                                        clear_state_text = 1;
                                        break;
                                }
                                // hodnota je float
                                // TODO kontrolovat pritomnost pouze jedne tecky
                                if (isdigit(*p) || *p == '.') break;
                                
                                DBG("ST_IBIAS: *p = '%c'\n", *p);
                                state_text[state_text_len-1] = '\0';
                                if (get_double(state_text, state_text_len, &double_val) < 0) {
                                        fprintf(stderr, "ERROR in conversion, exiting.\n");
                                        exit(1);
                                }
                                mereni.laser_bias = double_val;
                                // jednotky ignorujeme, stejne to jsou vzdy mA
                                next_state = ST_KOMENTAR;
                                break;
                        case ST_T_APD:
                                DBG("ST_T_APD\n");
                                // ignore spaces
                                if (*p == ' ' && state_text_len == 1) {
                                        clear_state_text = 1;
                                        break;
                                }
                                // hodnota je float
                                if (isdigit(*p) || *p == '.') break;
                                
                                DBG("ST_T_APD: *p = '%c'\n", *p);
                                state_text[state_text_len-1] = '\0';
                                if (get_double(state_text, state_text_len, &double_val) < 0) {
                                        fprintf(stderr, "ERROR in conversion, exiting.\n");
                                        exit(1);
                                }
                                mereni.apd_temp = double_val;
                                // jednotky ignorujeme, stejne to jsou vzdy mA
                                next_state = ST_KOMENTAR;
                                break;
                        case ST_T_CPU:
                                DBG("ST_T_CPU\n");
                                // ignore spaces
                                if (*p == ' ' && state_text_len == 1) {
                                        clear_state_text = 1;
                                        break;
                                }
                                // hodnota je float
                                if (isdigit(*p) || *p == '.') break;
                                
                                DBG("ST_T_CPU: *p = '%c'\n", *p);
                                state_text[state_text_len-1] = '\0';
                                if (get_double(state_text, state_text_len, &double_val) < 0) {
                                        fprintf(stderr, "ERROR in conversion, exiting.\n");
                                        exit(1);
                                }
                                mereni.cpu_temp = double_val;
                                // jednotky ignorujeme, stejne to jsou vzdy mA
                                next_state = ST_KOMENTAR;
                                break;
                        case ST_U_APD:
                                DBG("ST_U_APD\n");
                                // ignore spaces
                                if (*p == ' ' && state_text_len == 1) {
                                        clear_state_text = 1;
                                        break;
                                }
                                // hodnota je float
                                if (isdigit(*p) || *p == '.') break;
                                
                                DBG("ST_U_APD: *p = '%c'\n", *p);
                                state_text[state_text_len-1] = '\0';
                                if (get_double(state_text, state_text_len, &double_val) < 0) {
                                        fprintf(stderr, "ERROR in conversion, exiting.\n");
                                        exit(1);
                                }
                                mereni.apd_voltage = double_val;
                                // jednotky ignorujeme, stejne to jsou vzdy mA
                                next_state = ST_KOMENTAR;
                                break;
                        case ST_U:
                                DBG("ST_U\n");
                                switch (*p) {
                                        case 'a':
                                                next_state = ST_U_A;
                                                break;
                                        case 'r':
                                                next_state = ST_U_R;
                                                break;
                                        default:
                                                next_state = ST_ERROR;
                                }
                                break;
                        case ST_P:
                                DBG("ST_P\n");
                                switch (*p) {
                                        case 'l':
                                                next_state = ST_PL;
                                                break;
                                        default:
                                                next_state = ST_ERROR;
                                }
                                break;
                        case ST_PL:
                                DBG("ST_PL\n");
                                switch (*p) {
                                        case '=':
                                                next_state = ST_PLASER;
                                                break;
                                        default:
                                                next_state = ST_ERROR;
                                }
                                break;
                        case ST_T:
                                DBG("ST_T\n");
                                switch (*p) {
                                        case '=':
                                                next_state = ST_T_CPU;
                                                break;
                                        case 'a':
                                                next_state = ST_T_A;
                                                break;
                                        default:
                                                next_state = ST_ERROR;
                                }
                                break;
                        case ST_T_A:
                                DBG("ST_T_TA\n");
                                switch (*p) {
                                        case '=':
                                                next_state = ST_T_APD;
                                                break;
                                        default:
                                                next_state = ST_ERROR;
                                }
                                break;
                        case ST_I:
                                DBG("ST_I\n");
                                switch (*p) {
                                        case 'b':
                                                next_state = ST_IB;
                                                break;
                                        default:
                                                next_state = ST_ERROR;
                                }
                                break;
                        case ST_IB:
                                DBG("ST_IB\n");
                                switch (*p) {
                                        case '=':
                                                next_state = ST_IBIAS;
                                                break;
                                        default:
                                                next_state = ST_ERROR;
                                }
                                break;
                        case ST_U_A:
                                DBG("ST_U_A\n");
                                switch (*p) {
                                        case '=':
                                                next_state = ST_U_APD;
                                                break;
                                        default:
                                                next_state = ST_ERROR;
                                }
                                break;
                        case ST_U_R:
                                DBG("ST_U_R\n");
                                switch (*p) {
                                        case '=':
                                                next_state = ST_U_REG;
                                                break;
                                        default:
                                                next_state = ST_ERROR;
                                }
                                break;
                        case ST_L:
                                DBG("ST_L\n");
                        case ST_H:
                                DBG("ST_H\n");
                                next_state = ST_KOMENTAR;
                                break;
                        default:
                                DBG("default\n");
                                /* nyni H, L */
                                next_state = ST_ERROR;
                        }
                        if (state != next_state || clear_state_text == 1) {
                                state_text_len = 0;
                                clear_state_text = 0;
                        }
                        state = next_state;
                        ibuflen--;
                        p++;
#ifdef _DEBUG
                        fprintf(stderr, "state_text: ");
                        print_debug_buffer(state_text, sizeof(state_text), state_text_len);
#endif

        }
                loopcnt++;
    }
//      restore_seriak(seriak, &old_tio);
        close(seriak);


        rss_avg = mereni.rss[RSS_CNT]>0 ? mereni.rss[RSS_SUM]/mereni.rss[RSS_CNT] : -1;

        fprintf(stderr, "Number of received valid values: %ld\n", mereni.rss[RSS_CNT]);
        fprintf(stderr, "Total sum of RSS: %ld\n", mereni.rss[RSS_SUM]);
        fprintf(stderr, "Average RSS: %ld\n", rss_avg);
        fprintf(stderr, "Maximum RSS: %ld\n", mereni.rss[RSS_MAX]);
        fprintf(stderr, "Minimum RSS: %ld\n", mereni.rss[RSS_MIN]);
        fprintf(stderr, "LASER power: %6.2f\n", mereni.laser_power);
        fprintf(stderr, "LASER bias:  %6.2f\n", mereni.laser_bias);
        fprintf(stderr, "APD voltage: %6.2f\n", mereni.apd_voltage);
        fprintf(stderr, "APD temp:    %6.2f\n", mereni.apd_temp);
        fprintf(stderr, "CPU temp:    %6.2f\n", mereni.cpu_temp);
        fprintf(stderr, "loops: %lld\n", loopcnt);
        printf("%ld %ld %ld %ld %6.2f %6.2f %6.2f %6.2f %6.2f\n", mereni.rss[RSS_CNT], rss_avg, mereni.rss[RSS_MAX], mereni.rss[RSS_MIN], mereni.laser_power, mereni.laser_bias, mereni.apd_voltage, mereni.apd_temp, mereni.cpu_temp);

        return EXIT_SUCCESS;

error1:
        if (seriak >= 0) {
                restore_seriak(seriak, &old_tio);
                close(seriak);
        }
        return EXIT_FAILURE;
}

Powered by WebSVN 2.2.1