- maksymalna liczba użytkowników: 40 (+ administrator),
- maksymalna liczba zdarzeń: 1000,
- czas automatycznego wylogowania Administratora: 60 s,
- czas automatycznego wygaszenia podświetlenia: 40 s bezczynności użytkownika,
- czas automatycznego wyjścia do menu głównego: 30 s bezczynności użytkownika,
- maksymalny prąd styków przekaźnika wykonawczego: 1 A/220 VAC (szczegóły w dokumentacji elementu),
- napięcie zasilania: 9 VDC,
- maksymalny pobór prądu (przekaźnik wyłączony/załączony): 90/110 mA.
Funkcjonowanie systemu
Przejdźmy zatem do ciekawych zagadnień dotyczących funkcjonowania systemu, zwłaszcza w zakresie autoryzacji kart i użytkowników. Po pierwsze w zakresie interfejsu użytkownika zdefiniowano szereg zasad:
- zmiana ustawień zegara czasu rzeczywistego RTC, edycja nazwy oraz usuwanie zdefiniowanego wcześniej użytkownika możliwe jest wyłącznie po zalogowaniu karty Administratora;
- usuwanie zdefiniowanych wcześniej użytkowników możliwe jest wyłącznie wtedy, gdy na liście zdarzeń nie zanotowano żadnego zdarzenia z identyfikatorem usuwanego użytkownika;
- nie jest możliwe usuwanie zdarzeń z listy zdarzeń, zaś sama lista ma charakter kołowy, tzn. gdy wyczerpana zostanie maksymalna liczba zarejestrowanych zdarzeń (1000), nowo rejestrowane zdarzenia zastępują zdarzenia najstarsze;
- rejestrowane są również zdarzenia zalogowania/wylogowania Administratora jak i zdarzenia prób logowania niezarejestrowanych użytkowników (używających niezarejestrowanych kart);
- wbudowano mechanizm samowylogowywania się Administratora po czasie 60 sekund, co zapobiega nieautoryzowanym zmianom, w przypadku niewylogowania się Administratora;
- wbudowano mechanizm automatycznego powrotu do ekranu głównego urządzenia po czasie 30 sekund bezczynności ze strony użytkownika;
- dodawanie nowego użytkownika poprzedzone jest każdorazowym sprawdzeniem obecności numeru seryjnego nowej karty na liście użytkowników;
- w procesie dodawania nowego użytkownika przyznawany jest automatycznie najniższy, wolny identyfikator ID z listy użytkowników zachowanej w pamięci EEPROM mikrokontrolera;
- obsługa logowania kart dostępna jest jedynie z Menu głównego urządzenia. Każda inna pozycja Menu automatycznie uniemożliwia sprawdzanie zbliżanych kart RFID;
- wbudowano mechanizm wygaszania podświetlenia wyświetlacza graficznego po czasie 30 sekund bezczynności klawiatury w celu ograniczenia poboru mocy.
W związku z powyższym aplikacja programu obsługi wyświetla dodatkowe komunikaty dotyczące następujących zdarzeń:
- braku uprawnień do zmiany nastaw przeznaczonych wyłącznie dla Administratora;
- istnieniu użytkownika na liście użytkowników o numerze karty, która ma zostać dodana jako nowa;
- osiągnięciu maksymalnej, dopuszczalnej liczby (40) użytkowników na liście zdefiniowanych użytkowników;
- braku możliwości usunięcia użytkownika z listy użytkowników w przypadku istnienia identyfikatora tegoż użytkownika na liście zdarzeń;
- zalogowaniu i wylogowaniu (w tym automatycznym wylogowaniu) klucza administratora;
- wyczyszczeniu listy zdarzeń lub zapamiętaniu klucza administratora (wyłącznie podczas włączania urządzenia);
- braku zdarzeń na liście zdarzeń;
- braku użytkowników na liście użytkowników.
W tym miejscu przejdźmy zatem do szczegółów. Program obsługi aplikacji urządzenia SAS2 realizuje kilka głównych procesów, jeśli chodzi o obsługę kart RFID użytkowników. Są to następujące procesy:
- dodawanie nowej karty, czyli poniekąd dodawanie nowego użytkownika,
- usuwanie karty użytkownika,
- dodawanie karty Administratora,
- usuwanie karty Administratora,
- obsługa kart w procesie logowania.
Jako, że obsługa karty Administratora przebiega w bardzo zbliżony sposób, jak obsługa kart zwykłego użytkownika (poza brakiem konieczności nadawania nazwy użytkownika), tyle tylko że możliwa jest wyłącznie podczas włączania urządzenia (i przyciśnięcia przycisku „ADMIN”), nie będę jej opisywał oddzielnie, zaś skupię się na pozostałych procesach wskazując dla jasności odpowiednie grafy funkcjonalne.
Zacznijmy od procesu obejmującego dodawanie karty użytkownika, którego to graf pokazano na rysunku 4. Jak widać, możliwe jest wyłącznie dodanie nowej, jeszcze nieobsługiwanej karty RFID. Cały proces rozpoczyna się od przyłożenia karty RFID/urządzenia NFC do czytnika. Następnie urządzenie przechodzi do nadania nazwy użytkownika (za pomocą interfejsu GUI), po czym karta autoryzowana jest kluczem domyślnym. Następnie generowany jest przez system SAS2 unikalny klucz dostępowy karty RFID (klucz A), który zapisywany jest zarówno w pamięci EEPROM mikrokontrolera jak i pamięci EEPROM karty RFID. Dalej proces podlega finalizacji poprzez dodanie rekordu nowego użytkownika do listy obsługiwanych użytkowników. Warto podkreślić, i co nasuwa się z lektury grafu funkcjonalnego, iż obecność karty w przypadku tego procesu niezbędna jest dwukrotnie, a mianowicie podczas pierwszego odczytu numeru seryjnego karty (UID) oraz drugi raz po przeprowadzeniu edycji nazwy użytkownika i zapisu kluczy dostępu. Fragment kodu aplikacji, który odpowiedzialny za proces dodawania użytkownika pokazano na listingu 9.
//Czekamy na przyłożenie karty
while(cardReadUID(UID) != NO_ERROR){
}
//Uwierzytelniamy kartę kluczem defaultowym i odczytanym wcześniej numerem UID
//Na tym etapie znamy już User.userID, User.userName i User.UID
if(cardAuthenticate(User.UID, defaultKey) == NO_ERROR){
//Generujemy klucz
cardGenerateKey(User.Key);
//Zapisujemy nowy klucz na karcie
if(cardWriteKey(User.Key) == NO_ERROR){
//Zapisujemy nowego użytkownika (wraz z danymi klucza)
eeprom_write_block(&User, &UserEE[User.userID], sizeof(User));
usersNumber++; //Zwiększenie liczby użytkowników
}
}
Kolejny proces to proces usuwania użytkownika z listy użytkowników, którego graf pokazano na rysunku 5. Jak widać możliwe jest usunięcie wyłącznie tych kart użytkowników, dla których nie zarejestrowano zdarzeń w dzienniku zdarzeń, zaś do przeprowadzenia samego procesu, co oczywiste, niezbędna jest obecność karty, którą chcemy usunąć. Karta taka w pierwszej kolejności autoryzowana jest kluczem odczytanym z rekordu użytkownika o podanym numerze seryjnym (UID), następnie klucz dostępowy na karcie aktualizowany jest wartością domyślną (jak dla fabrycznie nowej karty) a rekord użytkownika usunięty z listy obsługiwanych użytkowników. Nasuwa się pytanie, czy nie wystarczyłoby usunięcie samego rekordu użytkownika bez operacji na karcie RFID? Dla samego systemu SAS2 taka operacja byłaby z pewnością wystarczająca, jednak w takim wypadku na karcie RFID pozostałby unikalny klucz, który zostałby usunięty z pamięci EEPROM mikrokontrolera. Jak mielibyśmy ponownie autoryzować (dodać) taką kartę bez znajomości klucza, którego z niej samej nie można odczytać? Stałaby się ona bezużyteczna dla naszego systemu kontroli dostępu (co nie znaczy, że dla innych urządzeń też), dlatego trzeba ją odpowiednio przygotować.
Uważny Czytelnik zada sobie z pewnością pytanie, co w przypadku zagubienia karty RFID znanego użytkownika? Czy już nigdy nie będziemy mogli usunąć go z listy użytkowników, skoro nie mamy karty? Przewidziałem taką możliwość i Menu systemu SAS2 udostępnia opcję usunięcia użytkownika (i danych jego karty) bez posiadania karty RFID, pod warunkiem, jak zawsze, iż usuwany użytkownik nie widnieje na liście zdarzeń systemu. Aby tego dokonać należy podczas oczekiwania na zbliżenie karty RFID nacisnąć i przytrzymać przycisk DOWN. Fragment kodu aplikacji, który odpowiedzialny jest za proces usuwania użytkownika pokazano na listingu 10.
//Sprawdzamy czy użytkownik, którego chcemy właśnie usunąć nie znajduje się na liście Event,
//bo jeśli się znajduje (czyli się logował) to nie możemy go usunąć – takie przyjęliśmy założenia
commonPos = 0; //Wskaźnik, że można usunąć użytkownika – zmienna tymczasowa
//Wczytujemy dane tego Usera kierując się numerem relatywnym i jednocześnie zapamiętujemy numer bezwzględny
//w tablicy Userów, którego dotyczy ten numer relatywny, by go później wykasować w odpowiednim miejscu
absoluteUserNumber = readRelativeUserNr(userListStartPos+userHighlightPos);
for(uint16_t idx=0; idx<eventsNumber; ++idx){
FRAMreadBlock(idx, &Event);
if(Event.userID == User.userID) {commonPos = 1; break;} //Znaleziono go na liście
}
if(!commonPos){
//Czekamy na przyłożenie karty lub przycisk DOWN, który usuwa użytkownika bez obecności karty
while(cardReadUID(UID) != NO_ERROR){
if(KeyPressed(&DOWN_PIN, DOWN_KEY, &keyDown, 1) == LONG) goto DELETE_USER;
}
//Sprawdzamy czy wczytana karta należy do użytkownika, którego chcemy usunąć
if(memcmp(UID, User.UID, 8) == 0){
//Uwierzytelniamy kartę kluczem i numerem UID
if(cardAuthenticate(User.UID, User.Key) == NO_ERROR){
//Zapisujemy na karcie defaultowy klucz uwalniając ją z obsługiwanych kart
if(cardWriteKey(defaultKey) == NO_ERROR){
DELETE_USER:
//Użytkownika kasujemy pod jego bezwzględnym adresem w tabeli
//User – zapamiętany powyżej
User.userID = EMPTY_USER;
eeprom_write_block(&User, &UserEE[absoluteUserNumber], sizeof(User));
usersNumber--; //Zmniejszamy liczbę użytkowników
}
}
}
}
Funkcja powyższa korzysta z dość ciekawej funkcji narzędziowej o nazwie readRelativeUserNr(), której zadaniem jest odczyt danych użytkownika o relatywnym numerze w tablicy użytkowników czyli funkcja ta pomija wszystkich nieaktywnych użytkowników pomiędzy istniejącymi i zwraca bezwzględny numer elementu tablicy, w którym znajduje się względny numer użytkownika. Ciało wspomnianej funkcji pokazano na listingu 11.
uint8_t readRelativeUserNr(uint8_t relativeUserNr){
uint8_t idx, userCounter = 0;
for(idx=0; idx<MAX_USERS; ++idx){
eeprom_read_block(&User, &UserEE[idx], sizeof(User));
if(User.userID != EMPTY_USER){
userCounter++;
if((userCounter-1) == relativeUserNr) break; else User.userID = EMPTY_USER;
}
}
return idx;
}
Ostatni proces, o którym należy wspomnieć to proces „normalnej” obsługi karty realizowany na ekranie głównym urządzenia, który ma na celu rejestrację zdarzeń z użyciem kart RFID oraz otwieranie rygla zamka podłączonego do złącza LOCK urządzenia. Graf tego procesu pokazano na rysunku 6. Proces obsługi karty użytkownika rozpoczyna się z chwilą zbliżenia karty do czytnika i powoduje odczytanie jej numeru seryjnego UID. Jeśli numer UID jest dla naszego systemu nieznany to na liście zdarzeń urządzenia SAS2 zapisywane jest zdarzenie (ze znacznikiem czasowym) nieautoryzowanego dostępu do systemu. W innym przypadku proces przechodzi do autoryzacji bieżącej karty kluczem dostępu odczytanym z rekordu użytkownika (ze znanym numerem UID). Nieudanej autoryzacji towarzyszy, jak poprzednio, dodanie zdarzenia nieautoryzowanego dostępu do systemu, w przeciwnym razie proces przechodzi do następnego kroku, w którym sprawdzane jest czy autoryzowana karta nie jest przypadkiem kartą Administratora systemu. Jeśli jest kartą Administratora to stosowne zdarzenie (wylogowania/zalogowania Administratora) zapisywane jest w dzienniku zdarzeń, zaś system przechodzi w tryb uprawnień Administratora (możliwe jest wykonanie dodatkowych operacji dostępnych wyłącznie dla Administratora). Jeśli autoryzowany użytkownik jest z kolei „zwykłym” użytkownikiem to fakt jego logowania zapisywany jest, jak poprzednio, w dzienniku zdarzeń po czym rygiel zamka podłączonego do złącza LOCK uruchamiany jest na czas 1,5 sekundy.
Kilka słów uwagi na temat dodawania/usuwania karty Administratora. Tak, jak wspomniano na wstępie, proces dodawania czy usuwania karty Administratora możemy zainicjować wyłącznie podczas włączania urządzenia przy naciśniętym przycisku ADMIN. Jeśli w urządzeniu nie zapisano jeszcze karty Administratora i zbliżona karta będzie nową kartą dla systemu SAS2 to zostanie ona zapamiętana, jako karta Administratora. Aby ją usunąć należy ponownie zbliżyć ją do czytnika podczas włączania urządzenia z wciśniętym, jak poprzednio, przyciskiem ADMIN, co spowoduje odpowiednie jest „sformatowanie” i możliwość ponownego użycia w systemie SAS2 (jako karty Administratora lub użytkownika). Fragment kodu aplikacji, który odpowiedzialny jest za proces obsługi karty pokazano na listingu 12.
//Sprawdzamy obecność karty – tylko na ekranie głównym
if(workMode == MODE_NORMAL && cardReadUID(UID) == NO_ERROR){
//Sprawdzamy rodzaj przyłożonej karty – w zmiennej globalnej User pojawią się
//ewentualne dane użytkownika
switch(findUserUID(UID)){
case USER_NOT_FOUND:
foundUserID = UNKNOWN_USER;
break;
case USER_FOUND:
//Uwierzytelniamy kartę odczytanym kluczem i numerem UID
if(cardAuthenticate(User.UID, User.Key) == NO_ERROR)
foundUserID = User.userID;
else foundUserID = UNKNOWN_USER;
break;
case USER_IS_ADMIN:
//Uwierzytelniamy kartę odczytanym kluczem i numerem UID
if(cardAuthenticate(User.UID, User.Key) == NO_ERROR){
//Przyłożona karta to numer ADMINa,
//więc zmieniamy wartość zmiennej logowania
adminLoggedin ^= 0x01;
if(adminLoggedin) foundUserID = ADMIN_LOGIN;
else foundUserID = ADMIN_LOGOUT;
}
break;
}
//Przygotowyjemy dane struktury Event do zapisania zdarzenia w pamięci EEPROM
Event.userID = foundUserID; //ID znalezionego Usera, USER_UNKNOWN, ADMIN_LOGIN lub
//ADMIN_LOGOUT
RTCreadDateTime(&Event.dateTime); //Bieżący znacznik czasu
Event.Status = NEW_EVENT; //Znacznik nowego zdarzenia, jeszcze nie przeglądanego
//Zapis struktury pod bieżącym adresem zdarzenia
EEPROMwriteBlock(newEventPointer, &Event);
//Ustawienie nowego wskaźnika miejsca do kolejnego zapisu.
//Zapętlenie rejestru zdarzeń, jeśli osiągnięto koniec rejestru
if(++newEventPointer == MAX_EVENTS) newEventPointer = 0;
//Zwiększenie liczby zdarzeń. Jeśli osiągnięto maksymalną liczbę zdarzeń to nie
//przekraczamy jej,
//bo lista zacznie się wypełniać od góry
if(++eventsNumber > MAX_EVENTS) eventsNumber = MAX_EVENTS;
//Zapisujemy wskaźnik do najbliższego wolnego miejsca i liczbę zdarzeń w EEPROM
EEPROMwriteWord(EVENT_POINTER_ADDR, newEventPointer);
EEPROMwriteWord(EVENT_NR_ADDR, eventsNumber);
//W przypadku znanego użytkownika załączamy przekaźnik
if(foundUserID != UNKNOWN_USER && foundUserID != ADMIN_LOGIN && foundUserID != ADMIN_LOGOUT){
Beep(BUZZER_SHORT); //Piknięcie buzzera
RELAY_ON;
_delay_ms(1500);
RELAY_OFF;
}
}
Kilka słów uwagi należy się potencjalnej możliwości obsługi urządzeń NFC w rodzaju telefonu komórkowego. Jak wiadomo niektóre z tych urządzeń wyposażono w interfejs NFC umożliwiający wymianę danych lub obsługę płatności zbliżeniowych. Czy nasz system będzie w stanie odczytać numer seryjny takiego urządzenia? Oczywiście, że tak, bo musi ono spełniać standardy protokołu NFC. Problem jednak w tym, że systemy operacyjne telefonów komórkowych generują losowe numery seryjne (tzw. RID – Random ID), w związku z czym ich zapamiętywanie nie ma większego sensu, gdyż podczas kolejnego połączenia z takim urządzeniem wygeneruje ono zupełnie inny numer seryjny. Zachowanie to można zmienić, ale przynajmniej w Androidzie nie jest to takie proste i wymaga modyfikacji firmware lub użycia specjalnych aplikacji. Ponoć zdarzają się telefony z statycznym numerem UID (takie informacje odnalazłem na specjalistycznych forach), lecz ja na takie nie natrafiłem, więc należy założyć, iż standardowo generują one losowe numery RID.
Obsługa urządzenia
Tyle o procesach, przejdźmy zatem do Menu samego urządzenia i sposobu jego obsługi. Projektując Menu systemu SAS2 oraz sposób obsługi tego urządzenia przyjąłem, że ergonomia i prostota jego użytkowania jak i czytelność interfejsu użytkownika powinna być najważniejszym kryterium przy konstruowaniu stosownych procedur sterujących. Zgodnie z tymi podstawowymi założeniami, na płytce sterownika przewidziano aż 7 przycisków sterujących dających bezpośredni dostęp do podstawowej funkcjonalności. Jako że Menu obsługi urządzenia udostępnia wiele funkcji, stosowne przyciski mają różnoraką funkcjonalność zależną od miejsca w układzie Menu, przy czym ich podstawowe znaczenie przedstawia się następująco:
- przyciski oznaczone jako NEXT, PREV służą do zmiany pozycji edytowanego elementu;
- przyciski oznaczone jako UP, DOWN służą do zmiany wartości edytowanego elementu oraz poruszania się po kolejnych opcjach Menu urządzenia;
- przycisk oznaczony jako OK służy do zatwierdzania wyboru zarówno w zakresie opcji Menu jak i zmiany parametrów poddawanych edycji;
- przycisk oznaczony jako MENU służy do wejścia w system Menu jak i wyjścia do Menu nadrzędnego bez zmiany parametrów edytowanego elementu (w przypadku Menu umożliwiającego edycję). Dodatkowo, długie przytrzymanie tego przycisku powoduje każdorazowo wyjście do ekranu głównego aplikacji;
- przycisk oznaczony jako ADMIN służy do realizacji funkcji administracyjnych: kasowania całej pamięci zdarzeń i wejścia w tryb zapamiętywania/usuwania klucza Administratora.
Wszystkie wymienione operacje możliwe są do wykonania wyłącznie podczas włączania urządzenia, zaś sam przycisk ADMIN z założenia nie powinien być dostępny na panelu obsługi urządzenia (stąd też zastosowano dla niego przełącznik microswitch z bardzo krótką ośką). Jako że lista dostępnych opcji systemu Menu urządzenia SAS2 jest dość obszerna, na rysunku 7 pokazano diagram prezentujący kompletny algorytm obsługi, zaś na rysunku 8 pokazano wygląd ekranu interfejsu użytkownika dla głównych trybów pracy systemu Menu. Warto zauważyć, iż w przypadku edycji nazwy użytkownika w ramach procesu dodawania nowego użytkownika długie przyciśnięcie przycisków UP/DOWN powoduje szybkie zmiany edytowanych liter, co ma ułatwić stosowną edycję.
Montaż i uruchomienie
Schemat płytki PCB systemu SAS2 pokazano na rysunku 9. Jak widać, zaprojektowano bardzo zwartą konstrukcję obwodu drukowanego z zastosowaniem elementów THT, po to, by całe urządzenie wymiarami nie przekraczało niezbędnego, minimalnego obszaru dla wykonania interfejsu użytkownika. W tym celu w wybranych miejscach zastosowano montaż „piętrowy”, w związku z czym kolejność implementacji ma tutaj szczególne znaczenie.
Warto również podkreślić, iż dla zminimalizowania zakłóceń, na płytce urządzenia poprowadzono obszerne pola masy po obu stronach obwodu drukowanego oraz zastosowano szereg przelotek pomiędzy nimi w celu zmniejszenia pojemności pasożytniczych. Montaż urządzenia rozpoczynamy od przylutowania wszystkich układów scalonych, następnie lutujemy pozostałe półprzewodniki, dalej elementy bierne a na samym końcu peryferia mechaniczne. Kondensatory ceramiczne znajdujące się docelowo pod płytką modułu RFID (C1, C2, C6 i C7) montujemy poziomo by w ten sposób zmniejszyć wysokość tej „warstwy” elementów. Następnie przylutowujemy moduł czytnika RFID najbliżej jak to się da od obwodu drukowanego urządzenia. W tym momencie ustawiamy w odpowiednich pozycjach przełączniki SMD umieszczone na module RFID, dzięki którym wybieramy aktywny interfejs komunikacyjny (w naszym wypadku SPI). Aby przygotować moduł do pracy z interfejsem SPI przełączamy przełącznik oznaczony jako ON w pozycję On (blisko znacznika „1”) zaś przełącznik oznaczony, jako KE w pozycję Off (blisko znacznika „KE”).
W ostatnim kroku montujemy wyświetlacz graficzny COG łącznie z podświetleniem kierując się zasadą, iż powinien on znaleźć się jak najbliżej płaszczyzny modułu RFID, jak to tylko możliwe. Montując ten element możemy również posłużyć się gniazdem goldpin (żeńskim) co pozwoli na jego delikatne odsunięcie od płaszczyzny modułu RFID. Sam wyświetlacz przysłoni co prawda moduł RFID, lecz testy praktyczne wykazały, iż nie zawiera on elementów, które w sposób znaczący mogłyby zaburzyć funkcjonowanie anteny umieszczonej na tym peryferium.
Poprawnie zmontowany układ nie wymaga żadnych regulacji (poza koniecznością zamontowania baterii CR1220 podtrzymującej zegar RTC) i powinien działać tuż po włączeniu zasilania. Jedynym zabiegiem, jaki należy wykonać przed użytkowaniem urządzenia jest sformatowanie i wyczyszczenie pamięci zdarzeń EEPROM, do czego przewidziano odpowiednią opcję Menu (dostępną wyłącznie podczas włączania urządzenia).
Na fotografii 1 pokazano wygląd obwodu drukowanego urządzenia SAS2 tuż przed przylutowaniem modułu RFID i wyświetlacza COG.
Robert Wołgajew, EP