/* Program czyta dane z czytników RFID wpietych do portow * szeregowych (rowniez wirtualnych), sprawdza uprawnienia w bazie MysQL * uruchamia bramke lub szlaban, zapisuje ten fakt w bazie MySQL * Dane z czytnikow wysylane sa w porcjach po 5 bajtow, program * jest odporny na zaklocenia, ignoruje niepelne i przeklamane sekwencje * Parametry portow szeregowych zapisane sa w zbiorze 'paramport'. * Adres hosta bazy danych, nazwa bazy danych, uzytkownik i jego * zaszyfrowane haslo jest w zbiorze 'param' * Kompilacja: * cc port_read.c -L/usr/lib/mysql -lmysqlclient -o czytaj * chmod 770 czytaj * Uruchomienie * ./czytaj & * Autor Boguslaw Kempny, kempny@stanpol.com.pl */ #include #include #include #include #include #include #include #include #include #include #include #include #define maxlinii 16 /* maksymalna liczba linii szeregowych */ #define zn_z_czytn 13 /* tyle ma znakow zgloszenie karty */ #define TRUE 1 #define SEPARATOR1 '*' #define SEPARATOR2 '&' #define MAXCZAS 1999999999 #define BL_PARAM 1 // Bledne parametry wywolania programu #define BL_BAZY 2 // Blad otwarcia bazy danych #define BL_ZB 5 // Brak zbioru #define SIZE 256 /* zmienne */ int l_linii = 0; int z, i, j; size_t wyn; FILE *fp; int fd[maxlinii]; char buf[520]; char buffer[SIZE]; char data[SIZE]; char wczytane[maxlinii][2 * zn_z_czytn + 4]; /* bufor znakow z kolejnych czytnikow dluzszy o dwa, bo separatory i dwa na wszelki wypadek */ int ind_wczyt[maxlinii]; /* indeks do poloz. znaku do wczytania w buforze */ char urzadzenia[maxlinii][35]; /* numer portu, nazwa portu. */ char predkosci[maxlinii][25]; /* numer portu, predkosc portu. */ speed_t predkosc; unsigned char znaki[maxlinii][255]; int n, m, p; char nazdev[80]; unsigned char znak; time_t czas[maxlinii]; time_t czas1; time_t czas2; struct tm *loctime; int wewy; // czytnik wejsciowy czy wyjsciowy, <128 to wejscie struct termios opcje; /* rozkazy do czytnikow */ /* opis: @ @ adres kod_rozk przkaznik led_nb led_cz led_zie led_zol beep_niski beep_wysoki podswietl */ /* w ukladach: ff - nie zmieniaj, hex251 - wlacz na stale, 00 - wylacz, xx - wlacz na xx/10 sekund */ unsigned char rozk_tak[20] = { 0x40, 0x40, 0x01, 0x21, 0x05, 0xff, 0xff, 0x05, 0xff, 0xff, 0x02, 0xff }; unsigned char rozk_nie[20] = { 0x40, 0x40, 0x01, 0x21, 0xff, 0xff, 0x05, 0xff, 0xff, 0x05, 0xff, 0xff }; int ile = 12; //znakow do wyslania bez sumy kontrolnej unsigned char sumakontr = 0; /* zmienne bazy danych */ MYSQL mysql; MYSQL_RES *res; MYSQL_ROW row; char buf_sql[255]; char user[32]; char pass[32]; char pracownik[40]; char karta[15]; union par { struct param { char host_sql[25]; char user_sql[25]; char pass_sql[25]; char datab_sql[25]; } pars; char tab_par[4][25]; } paru; union pass { char pass_c; unsigned int pass_n; } passu; char pass1[80]; /* S T A R T */ main (argc, argv) int argc; char *argv[]; { fp = fopen ("../html/conf/param", "r"); // odczytaj parametry, hasla itp if (fp == NULL) { fprintf (stderr, "Blad - Brak zbioru \"param\"\n"); exit (BL_ZB); } n = 0; while ((fgets (buf, 79, fp) != NULL) && n < 4) { if (buf[0] != '\n' && buf[0] != '#') { strcpy (paru.tab_par[n], buf); paru.tab_par[n][strlen (buf) - 1] = '\0'; n++; } } fclose (fp); for (n = 0; n < strlen (paru.pars.pass_sql); n = n + 2) { pass1[n / 2] = ((int) paru.pars.pass_sql[n] & 0x0F ^ 0x5) | ((int) paru.pars. pass_sql[n + 1] << 4 ^ 0x50); } pass1[n / 2] = '\0'; strcpy (paru.pars.pass_sql, pass1); /* wczytaj parametry - nazwy i liczbe urzadzen specjalnych opusc wiersze zaczynajace sie od spacji i od znaku # umiesc nazwy urzadzen w tabeli urzadzenia, otworz urzadzenia, liczbe wczytanych i otwartych urzadzen zapisz w zmiennej m */ fp = fopen ("../html/conf/paramport", "r"); m = 1; //kolejna linia szeregowa while (fgets (nazdev, 79, fp) != NULL) { sscanf (nazdev, "%s %s", &urzadzenia[m][0], &predkosci[m][0]); if (urzadzenia[m][0] != '\n' && urzadzenia[m][0] != '#') { printf ("\notwieram port %s -------> ", &urzadzenia[m][0]); if ((fd[m] = open (&urzadzenia[m][0], O_NOCTTY | O_RDWR | O_NONBLOCK | O_NDELAY)) != -1) { tcgetattr (fd[m], &opcje); printf("m=%x fd=%x ", m, fd[m]); /* Zaprogramuj predkosc transmisji */ if (!(strcmp (&predkosci[m][0], "B300"))) predkosc = B300; else if (!(strcmp (&predkosci[m][0], "B1200"))) predkosc = B1200; else if (!(strcmp (&predkosci[m][0], "B2400"))) predkosc = B2400; else if (!(strcmp (&predkosci[m][0], "B4800"))) predkosc = B4800; else if (!(strcmp (&predkosci[m][0], "B9600"))) predkosc = B9600; else if (!(strcmp (&predkosci[m][0], "B19200"))) predkosc = B19200; cfsetspeed (&opcje, predkosc); /* Ustaw tryb raw, potem bez parzystosci i znak osmiobitowy */ opcje.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); opcje.c_cflag &= ~PARENB; opcje.c_cflag &= ~PARODD; opcje.c_cflag &= ~CSTOPB; opcje.c_cflag &= ~CSIZE; opcje.c_cflag |= CS8; opcje.c_iflag &= ~IXON; opcje.c_iflag &= ~IXOFF; tcsetattr (fd[m], TCSANOW, &opcje); m++; } //od if open port else { printf ("Blad, Nazwa: %s\n", &urzadzenia[m][0]); perror ("Blad otwarcia: "); } } //od if linia nie komentarza } //od while m--; l_linii = m; fclose (fp); // Otworz baze danych mysql_init (&mysql); if (!mysql_real_connect (&mysql, paru.pars.host_sql, paru.pars.user_sql, paru.pars.pass_sql, paru.pars.datab_sql, 0, NULL, 0)) { printf ("Nie moge sie polaczyc z baza danych:\nBlad: %s\n", mysql_error (&mysql)); return (BL_BAZY); } printf ("\n\n**************** system gotowy do odczytu danych z czytnikow ******************\n\n"); fflush(0); // Zainicjuj tablice buforow znakow for (n = 1; n <= l_linii; n++) { ind_wczyt[n] = 1; wczytane[n][0] = SEPARATOR1; wczytane[n][2 * zn_z_czytn + 1] = SEPARATOR2; czas[n] = MAXCZAS; } time (&czas1); loctime = localtime (&czas1); strftime (data, SIZE, "%Y-%m-%d", loctime); // czytaj kolejno linie szeregowe while (TRUE) { time (&czas1); // moment wykonania petli na potrzeby timeout if (czas1%3600 == 0) { mysql_ping(&mysql); // wyswietlaj czas //if (czas1%600 == 0) if (czas2!= czas1) { loctime = localtime (&czas1); strftime (buffer, SIZE, " Czas: %H:%M \n", loctime); strftime (data, SIZE, "%Y-%m-%d", loctime); fputs (data, stdout); fputs (buffer, stdout); fflush(0); czas2=czas1; } } for (n = 1; n <= l_linii; n++) { if (czas1 - czas[n] > 1) //znak nie przyszedl ponad sekunde { ind_wczyt[n] = 1; if (czas[n] != MAXCZAS) printf ("Timeout linia %d \n", n); fflush(0); czas[n] = MAXCZAS; } } for (n = 1; n <= l_linii; n++) { // Czytaj port if ((read (fd[n], &znak, 1)) != -1) { sprintf (&wczytane[n][ind_wczyt[n]], "%02x", znak); znaki[n][ind_wczyt[n]] = znak; czas[n] = czas1; if (ind_wczyt[n]>25) {printf ("!!! ind_wczytdla n=%d za duzy, = %d\n",n, ind_wczyt[n]); fflush(0);} if (ind_wczyt[n] >= 25) { ind_wczyt[n] = 1; czas[n] = MAXCZAS; //jesli to co dostal to zgloszenie karty if (znaki[n][1] == '$' && znaki[n][3] == '$' && znaki[n][7] == 1) { // printf (", adres:%i\n", znaki[n][5]); fflush(0); wczytane[n][2 * zn_z_czytn + 1] = SEPARATOR2; if (znaki[n][5] < 128) wewy = 1; else wewy = 0; strcpy (&buf_sql[0], "select idk, idp from kadry where idk=\""); strncpy (&buf_sql[38], &wczytane[n][9], 10); strcpy (&buf_sql[48], "\" and zezw=1 and data_waz >=\"\0"); strcat (buf_sql, data ); strcat (buf_sql, "\"" ); // printf ("buf:%s\n", buf_sql); fflush(0); if (mysql_query (&mysql, &buf_sql[0])) { printf ("Nie moge czytac z bazy danych:\nBlad: %s\n", mysql_error (&mysql)); fflush(0); } else { if (res = mysql_store_result (&mysql)) { if (mysql_num_rows (res)) { row = mysql_fetch_row (res); strcpy (pracownik, row[1]); strncpy (karta, &wczytane[n][9], 10); karta[10]='\0'; mysql_free_result (res); sprintf (buf_sql, "insert into czytnik set idk=\"%s\", idp=\"%s\", wejwyj=\"%d\",linia=%d, czytnik=%d", karta, pracownik, wewy, n, znaki[n][5]); if (mysql_query (&mysql, &buf_sql[0])) { printf ("Nie moge pisac do bazy danych:\nBlad: %s\n", mysql_error (&mysql)); fflush(0); } else { sprintf (buf_sql, "insert into czytnik_rob set idk=\"%s\", idp=\"%s\", wejwyj=\"%d\",linia=%d, czytnik=%d", karta, pracownik, wewy, n, znaki[n][5]); if (mysql_query (&mysql, &buf_sql[0])) { printf ("Nie moge pisac do bazy danych:\nBlad: %s\n", mysql_error (&mysql)); fflush(0); } else { //otwarcie bramki sumakontr = 0; rozk_tak[2] = znaki[n][5]; //dopisuje adr. czytn. for (i = 0; i < ile; i++) //oblicz sume kontr. sumakontr = sumakontr ^ rozk_tak[i]; wyn = write (fd[n], rozk_tak, ile); //rozkaz wyn = write (fd[n], &sumakontr, 1); //suma kont. if (wyn < 0) { printf ("Write: zapis nieudany\n"); fflush(0); } } } ind_wczyt[n] = 1; czas[n] = MAXCZAS; } else { mysql_free_result (res); //czerwone swiatlo sumakontr = 0; rozk_nie[2] = znaki[n][5]; //dopisz adr. czytnika for (i = 0; i < ile; i++) //oblicz sume kontrolna sumakontr = sumakontr ^ rozk_nie[i]; wyn = write (fd[n], rozk_nie, ile); //rozkaz wyn = write (fd[n], &sumakontr, 1); //suma kontr. if (wyn < 0) { printf ("Write: zapis nieudany"); fflush(0); } ind_wczyt[n] = 1; czas[n] = MAXCZAS; } } } } } else { ind_wczyt[n]++; ind_wczyt[n]++; } } //od if read } //od for } //od while(TRUE) } // od main