You are on page 1of 22

PRAXE

4 SPŠ CHOMUTOV MALÝ

21.2.2023 PŘÍSTUPOVÝ SYSTÉM S RFID V4


Zadání:
S využitím periferie čteček RFID čipů připojené pomocí USB / sériového rozhraní sestavte
aplikaci, která bude na základě informací uložených v SQLite databázi vyhodnocovat oprávněnost
požadavku na přístup z daného místa. Výsledné řešení musí obsahovat následující funkcionalitu:

• Obsluha dvou čteček připojených na periferii pomocí RS485 rozhraní


• Identifikace čtečky a způsobu načtení informace (načtení čipu, manuální zadání kódu
na klávesnici). Simulujte tři místa události (klávesnice u vstupu, čip v místě A, čip v
místě B)
• Identifikace vlastníka a vyhodnocení oprávněnosti přístupu a základě místa události,
aktuálního času a dne v týdnu
• Uživatelsky použitelné rozhraní pro nastavení údajů do databáze (vlastník, členství ve
skupinách, nastavení přístupových oprávnění a pravidel pro přístup)
• Zobrazení výsledku vyhodnocení žádosti a logování všech událostí do tabulky databáze
ve formátu umožňujícím prohledávání na úrovni SQL dotazu (zamyslete se jak by
mohlo např. vypadat dohledání vstupů do konkrétní kanceláře)

Teorie:
RFID (Radio Frequency Identification) je technologie, která umožňuje bezdrátové a
bezkontaktní identifikaci objektů pomocí rádiových vln. RFID systém se skládá z dvou hlavních
komponent: RFID čtečky a RFID tagů. Existují dva hlavní typy RFID tagů: pasivní a aktivní. Pasivní RFID
tagy nevyžadují žádné napájení a využívají energii z rádiových vln, které vysílá RFID čtečka. Aktivní RFID
tagy jsou napájeny vlastní baterií.
RFID technologie také přináší rizika související s ochranou osobních údajů a bezpečností. RFID
tagy mohou být nelegálně skenovány a čteny, což může vést k úniku citlivých informací. Proto je
důležité, aby byly používány bezpečnostní opatření jako například šifrování dat.
Program je realizován v programovacím jazyce C# s pomocí frameworku WFA, který je
používán pro grafickou část aplikace a je postaven na frameworku .NET, je tedy nutné k realizaci
projektu mít znalost tohoto programovacího jazyka.
Aplikace využívá SQlite databázi. Jedná se o relační databázový systém, kdy na rozdíl od
řešení klient-server není databázový klient spuštěn jako samostatný proces a jedná se o samotnou
knihovnu, kterou řídí samostatná aplikace. Takováto databáze je uložena v jednom soubor, který je
nezávislý na zařízení a umožňuje tedy snadnou přenositelnost.
Pro komunikaci s SQLite databází jsme využili knihovnu System.Data.SQLite, která využívá
ADO.NET, což je technologie pro přístup k databázi z .NET frameworku.

Popis programu:
Program má samostatnou třídu Db, pro práci s databází, která je uložena v souboru Db.cs,
která má jako parametr název databázového souboru.
Po spuštění programu se inicializují objekty formuláře, nastaví se parametry sériové
komunikace a otevře se port pro komunikaci. Program je opatřen eventem, který se spustí po
přijmutí dat sériovou linkou, kdy je po obdržení všech dat zavolána metoda buffer_parser(), která
podle délky a struktury přijatého paketu vrátí číslo místnosti a kód naskenovaného čipu (zadaného
kódu).
Pokud je úspěšně získané číslo místnosti a kód, tak je zavolána metoda check_reader(), která
zkontroluje dle databáze, zdali má osoba s tímto kódem oprávnění přístupu. Vrátí jméno tohoto
člověka a bool hodnotu, dle toho, zdali má uživatel přístup či nikoliv.
Aplikace je opatřena timerem, při každém tiknutí je zavolána metoda drawForm(), která dle
vrácených hodnot z check_reader() vykreslí do formuláře požadované informace.
Aplikace má několik dalším formů, pomocí kterých se provádí jednoduché přidávání nových
záznamů do databázových tabulek a jejich vypisování.

Rozbor proměnných a funkcí (metod):


TYP PROMĚNNÁ ÚČEL
internal class Db

METODY
konstruktor třídy, který přijímá jako parametr jméno
public Db(string databaze)
databáze
addLog(string code, int
public void přidání záznamů do tabulky log
room, bool access)
public List<string> drawLog() vrací list s výpisem z tabulky log
public (string name, bool check_reader(int room, zkontroluje na základě kódu a místnosti, zdali má
is_allowed) string code) uživatel přístup, vrací jméno a bool hodnotu přístupu
public (List<string>,
groups() vrací dva listy všech skupin a jejich id
List<int> id)
public (List<string> room,
rooms() vrací dva listy všech místností a jejich id
List<int> id)
public (List<int> id, getPermissions(int
vrací list všech povolení uživatele podle jeho id
List<string> permission) user_id)
public (List<int> id, getPermissionsGroup(int
vrací list všech povolení skupiny podle její id
List<string> permission) group_id)
addPermission(int
user_id, int day, string
public bool přidání nového povolení uživatele
from_time, string
to_time, int room_id)
addPermissionGroup(int
group_id, int day, string
public bool přidání nového povolení skupiny
from_time, string
to_time, int room_id)
public (int id, string vrátí id a jméno skupiny, které je součástí uživatel
getGroup(int user_id)
group) s požadovaným id
public (List<string>
users() vríti listy se všemi uživateli a jejich id
name, List<int> id)
addUser(string
first_name, string
public void last_name, string code, přidání nového uživatele
string code_keyboard, int
group)
public partial class Form1 : Form

METODY
public (int room, string z přijatých dat ze sériové linky určí kód a
buffer_parser(string buffer)
code) místnost
drawForm(string jmeno, bool
public void vykreslí do formuláře, jestli je povolen přístup
pristup, int room)
com_DataRecieved(object
private void sender, event, reagující na příjem dat ze sériové linky
SerialDataReceivedEventArgs e)
nastaví id zakázky, aby mohla být zahájena
internal void receiveData(int id)
editace zakázky
Timer1_Tick(object sender,
private void event, spouštěný každé tiknutí timeru
EventArgs e)
public void form2Close() metoda, která je volaná při zavření 2. formuláře
PROMĚNNÉ
SerialPort com objekt pro sériovou komunikaci
datová struktura, ve které je uložen poslední
(int room, string code) data
naskenovaný kód a místnost
(string jmeno, bool jméno uživatele a ukazatel, jestli má uživatel
info
pristup) povolen přístup
Db db objekt třídy Db
public partial class Form2 : Form

METODY
public void drawUsers() vykreslí uživatele do listBoxů
vrátí kód naskenovaného čipu, z dat po sériové
public bool buffer_parser(string buffer)
lince
com_DataRecieved(object
private void sender, event, reagující na příjem dat ze sériové linky
SerialDataReceivedEventArgs e)
button1_Click(object sender,
private void event po stisknutí tlačítka pro přidání uživatelů
EventArgs e)
Timer1_Tick(object sender,
private void event spouštěný každé tiknutí timeru
EventArgs e)
Form2_FormClosed(object
private void sender, FormClosedEventArgs event reagující na zavírání formu
e)
PROMĚNNÉ
SerialPort com objekt pro sériovou komunikaci
(List<string> name, datová struktura, obsahující dva listy, se jménem
rooms
List<int> id) a id všech místností
(List<string> name, datová struktura, obsahující dva listy, se jménem
groups
List<int> id) a id všech skupin
(List<string> name, datová struktura, obsahující dva listy, se jménem
users
List<int> id) a id všech uživatelů
Db db objekt třídy Db
int id id uživatele, který je aktuálně zobrazen
string code přiložený kód ke čtečce
string code_keyboard kód napsaný na klávesnici čtečky
Action jako konstruktor formu, metoda může být
Action action
díky tomu volána v jiném formuláři
public partial class Form3 : Form

METODY
public void drawPermissions() vykreslí povolení uživatele do listboxu
btn_send_Click(object sender,
private void event při stisknutí tlačítka pro přidání
EventArgs e)
public partial class Form4 : Form

Stejné jako ve Form4


public partial class Form5 : Form

PROMĚNNÉ
Db db objekt třídy Db
List<string> log list všech záznamů v tabulce log
Vývojový diagram:
Hlavní program:

START

nastavení
parametrů sériové
komunikace

jsou přijatá data


ze čtečky false

true

získání kódu ze
čtečky a číslo
místnosti

SELECT first_name, last_name, from_time, to_time FROM users INNER JOIN


permissions ON id_user user_id ERE (code kód OR code_keyboard kód)
AND day dnešní_číslo_dne AND (room_id číslo_místnosti OR room_id 4)
SELECT oěření
přístupu
SELECT first_name, last_name, from_time, to_time FROM users INNER JOIN
permissions ON users.group_id permissions.group_id ERE (code kód
OR code_keyboard kód) AND day číslo_dnešního_dne AND (room_id
číslo_místnosti OR room_id 4)
int i i počet záznamů i

true
aktuální čas from_time
aktuální čas to_time

false

konec smyčky

out: přístup zamítnut out: přístup povolen


Získání kódu ze čtečky

START

false
první znak x 2
druhý znak x 4

true

Odstraň první dva false


znaky a poslední tři
znaky první znak x 2

true

Odstraň první znak


a vyber 2. až . znak

out: kód

ONEC

Návrh databáze:
Schéma zapojení:
Komentovaný výpis programu:
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Diagnostics;
using System.Drawing.Text;
using System.Threading;

namespace rfid
{

public partial class Form1 : Form


{
SerialPort com;
(int room, string code) data;
(string jmeno, bool pristup) info;
Db db = new Db("data.db"); //inicializace onjektu pro práci s databází
public Form1()
{
InitializeComponent();
//parametry sériové linky
com = new SerialPort("COM11", 19200, Parity.None, 8, StopBits.One);
com.Handshake = Handshake.None;
//event handler pro příjem dat sériovou linkou
com.DataReceived += new SerialDataReceivedEventHandler(com_DataRecieved);
com.WriteTimeout = 500;
com.Open(); //otebření sériového portu
}
//metoda pro získání kódu ze čtečky
public (int room, string code) buffer_parser(string buffer)
{
//velká čtečka
if (buffer[0] == 0x02 && buffer[1] == 0x04)
{
if (buffer.Length == 9)
{
//čtečka
buffer = buffer.Remove(0, 2);
buffer = buffer.Remove(4, 3);
return (3, buffer);
}
//klávesnice
buffer = buffer.Remove(0, 2);
buffer = buffer.Remove(8, 3);
return (1, buffer);
}
//malá čtečka
else if (buffer[0] == 0x02)
{
buffer = buffer.Remove(0, 1);
buffer = buffer.Substring(0,8);
return (2, buffer);
}
return (0, String.Empty);
}
public void drawForm(string jmeno, bool pristup, int room)
{
//uživatel má přístup
if (pristup)
{
//na základě místosti se vybere formulář, který se zbarví
switch (room)
{
case 1:
textBox1.BackColor = Color.LimeGreen;
textBox1.Text = jmeno + Environment.NewLine + "PŘÍSTUP POVOLEN";
break;
case 2:
textBox2.BackColor = Color.LimeGreen;
textBox2.Text = jmeno + Environment.NewLine + "PŘÍSTUP POVOLEN";
break;
case 3:
textBox3.BackColor = Color.LimeGreen;
textBox3.Text = jmeno + Environment.NewLine + "PŘÍSTUP POVOLEN";
break;
}
}
//nemá přístup
else
{
switch (room)
{
case 1:
textBox1.BackColor = Color.PaleVioletRed;
textBox1.Text = jmeno + Environment.NewLine + "PŘÍSTUP ZAMÍTNUT";
break;
case 2:
textBox2.BackColor = Color.PaleVioletRed;
textBox2.Text = jmeno + Environment.NewLine + "PŘÍSTUP ZAMÍTNUT";
break;
case 3:
textBox3.BackColor = Color.PaleVioletRed;
textBox3.Text = jmeno + Environment.NewLine + "PŘÍSTUP ZAMÍTNUT";
break;
}
}
}
//event na příjem dat sériovou linkou
private void com_DataRecieved(object sender, SerialDataReceivedEventArgs e)
{
string buffer = String.Empty;
//dokud nejsou přečtena všechna data
while (com.BytesToRead > 0)
{
//přičíta další data
buffer += com.ReadExisting();
}
//získa se kód a číslo místnosti
data = buffer_parser(buffer);
//pokud nejsou data poškozená
if (data.room > 0 || !string.IsNullOrEmpty(data.code))
{
//zkontrolujte zda má uživatel přístup
info = db.check_reader(data.room, data.code);
//přidá do logu informace
db.addLog(data.code, data.room, info.pristup);
}
}

//každé tiknutí hodin vykreslí přístup


private void Timer1_Tick(object sender, EventArgs e)
{
drawForm(info.jmeno, info.pristup, data.room);
}

//když je zavřen form2, tak je znovu otevřen port pro sériovou komunikaci
public void form2Close()
{
com.Open();
}

//kliknutí v menu na nastavení uživateků


private void nastaveníUživatelůToolStripMenuItem_Click(object sender, EventArgs e)
{
com.Close();
Form2 form2 = new Form2(form2Close);
form2.ShowDialog();
}
//kliknutí v menu na nastavení skupin
private void nastaveníSkupinToolStripMenuItem_Click(object sender, EventArgs e)
{
Form4 form4 = new Form4(0);
form4.ShowDialog();
}
//kliknutí v menu na log
private void logToolStripMenuItem_Click(object sender, EventArgs e)
{
Form5 form5 = new Form5();
form5.ShowDialog();
}

}
}
Form2.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace rfid
{
public partial class Form2 : Form
{
//inicializace objektu pro práci s databází
Db db = new Db("data.db");
SerialPort com;
string code; //kód ze čtečky
string code_keyboard; //kód z klávesnice čtečky
Action action; //action na zavření formu
(List<string> name, List<int> id) groups; //skupiny
(List<string> name, List<int> id) users; //uživatelé
public Form2(Action action)
{
InitializeComponent();
listBox2.MouseDoubleClick += new MouseEventHandler(listBox1_MouseDoubleClick);
//event handler na dvojité kliknutí listboxu
this.action = action; //action jako parametr formuláře
users = db.users(); //select uživatelů z databáze
//parametry sériové komunikace
com = new SerialPort("COM11", 19200, Parity.None, 8, StopBits.One);
com.Handshake = Handshake.None;
com.DataReceived += new SerialDataReceivedEventHandler(com_DataRecieved); //event
handler na příjem dat sériovou linkou
com.WriteTimeout = 500;
groups = db.groups(); //select skuoin
com.Open(); //otevření portu
//přidání skupin do comboboxů
foreach (string name in groups.name)
{
combo_group.Items.Add(name);
}
//vykreslení uživatelů
drawUsers();
}
//metoda pro vykreslení uživatelů do listboxů
public void drawUsers()
{
users = db.users();
listBox1.Items.Clear();
listBox2.Items.Clear();
for (int i = 0; i < users.name.Count; i++)
{
listBox1.Items.Add(users.id[i]);
listBox2.Items.Add(users.name[i]);
}
}

//získá kód z dat sériovou linkou


public bool buffer_parser(string buffer)
{
if (buffer[0] == 0x02 && buffer[1] == 0x04)
{
if (buffer.Length == 9)
{
buffer = buffer.Remove(0, 2);
buffer = buffer.Remove(4, 3);
code_keyboard = buffer;
return true;
}
buffer = buffer.Remove(0, 2);
buffer = buffer.Remove(8, 3);
code = buffer;
return true;
}
else if (buffer[0] == 0x02)
{
buffer = buffer.Remove(0, 1);
buffer = buffer.Substring(0, 8);
code = buffer;
return true;
}
return false;
}
//příjem dat sériovou linkou
private void com_DataRecieved(object sender, SerialDataReceivedEventArgs e)
{
string buffer = String.Empty;
while (com.BytesToRead > 0)
{
buffer += com.ReadExisting();
}
buffer_parser(buffer);
}
//kliknutí na tlačítko pro přidání
private void button1_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txt_jmeno.Text) ||
string.IsNullOrEmpty(txt_prijmeni.Text) || (string.IsNullOrEmpty(txt_kod.Text) &&
string.IsNullOrEmpty(txt_klavesnice.Text))) {
MessageBox.Show("Nejsou vyplněna všechna pole");
}
else
{
if (combo_group.SelectedIndex == -1)
{
db.addUser(txt_jmeno.Text, txt_prijmeni.Text, txt_kod.Text,
txt_klavesnice.Text, 0);
}
else
{
db.addUser(txt_jmeno.Text, txt_prijmeni.Text, txt_kod.Text,
txt_klavesnice.Text, groups.id[combo_group.SelectedIndex]);
}
drawUsers();
txt_jmeno.Clear();
txt_prijmeni.Clear();
code = string.Empty;
code_keyboard = string.Empty;
}
}
//tiknutí timeru přidá kódy do textboxu
private void timer1_Tick(object sender, EventArgs e)
{
txt_kod.Text = code;
txt_klavesnice.Text = code_keyboard;
}
//zavření formu, zavolá action, který je nastaven na metodu ve formu 1
private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
com.Close();
action();
}

//dvojité kliknutí na listboxy


private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
{
Form3 form3 = new Form3(Convert.ToInt32(listBox1.SelectedItem),
listBox2.SelectedItem.ToString());
form3.ShowDialog();
}
//změna vybraného indexu v listboxu
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
listBox2.SelectedIndex = listBox1.SelectedIndex;
}

private void listBox2_SelectedIndexChanged(object sender, EventArgs e)


{
listBox1.SelectedIndex = listBox2.SelectedIndex;
}
}
}
Form3.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace rfid
{
public partial class Form3 : Form
{
//objekt pro práci s db
Db db = new Db("data.db");
int id; //id uživatele
(List<string> name, List<int> id) rooms;
(List<int> id_permission, List<string> permission) permissions;
(int id_group, string name) group;
public Form3(int id, string user_name)
{
InitializeComponent();
//formát datetimepickeru
time_from.CustomFormat = "HH:mm";
time_to.CustomFormat = "HH:mm";
Text = user_name;
this.id = id;
group = db.getGroup(id); //získání skupiny uživatele
rooms = db.rooms(); //získání místtností z db
//vypsání všech místností do comboboxu
foreach (string room in rooms.name)
{
combo_mistnost.Items.Add(room);
}
drawPermissions(); //vykreslení povolení
linkLabel1.Text = group.name;
}
//vyosání všech povolení do listboxů
public void drawPermissions()
{
listBox1.Items.Clear();
permissions = db.getPermissions(id);
foreach (string permission in permissions.permission)
{
listBox1.Items.Add(permission);
}
}
//kliknutí na tlačítko pro přidání
private void btn_send_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(time_from.Text) || string.IsNullOrEmpty(time_to.Text) ||
combo_den.SelectedIndex == -1 || combo_mistnost.SelectedIndex == -1)
{
MessageBox.Show("Nejsou vyplněna všechna pole");
}
else
{
int[] days = { 1, 2, 3, 4, 5, 6, 0 };
if (db.addPermission(id, days[combo_den.SelectedIndex], time_from.Text,
time_to.Text, rooms.id[combo_mistnost.SelectedIndex]))
{
drawPermissions();
}
}
}
//kliknutí na link
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
Dispose();
Form4 form4 = new Form4(group.id_group);
form4.ShowDialog();
}
}
}
Form4.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace rfid
{
public partial class Form4 : Form
{
Db db = new Db("data.db"); //objekt pro práci s db
int id; //id skupiny
(List<string> name, List<int> id) rooms;
(List<int> id_permission, List<string> permission) permissions;
(List<string> name, List<int> id) groups;
public Form4(int id)
{
InitializeComponent();
//formát datetimepickeru
time_from.CustomFormat = "HH:mm";
time_to.CustomFormat = "HH:mm";
rooms = db.rooms(); //select mísntostí
groups = db.groups(); //select skupin
//když není vybráno žádné id, tak se zvolí prnví skupina
if (id == 0)
{
id = groups.id.First();
}
this.id = id;
//vypsání všech místností do comboboxu
foreach (string room in rooms.name)
{
combo_mistnost.Items.Add(room);
}
//vypsání všech skupin do comboboxu
foreach (string group in groups.name)
{
combo_skupiny.Items.Add(group);
}
combo_skupiny.SelectedIndex = groups.id.IndexOf(id);
drawPermissions();
}
//vypsánívšech povolení do listboxu
public void drawPermissions()
{
listBox1.Items.Clear();
permissions = db.getPermissionsGroup(id);
foreach (string permission in permissions.permission)
{
listBox1.Items.Add(permission);
}
}
//změna indexu v comboboxu
private void combo_skupiny_SelectedIndexChanged(object sender, EventArgs e)
{
id = groups.id[combo_skupiny.SelectedIndex];
drawPermissions();
}
//kliknutí na button pro odeslání
private void btn_send_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(time_from.Text) || string.IsNullOrEmpty(time_to.Text) ||
combo_den.SelectedIndex == -1 || combo_mistnost.SelectedIndex == -1)
{
MessageBox.Show("Nejsou vyplněna všechna pole");
}
else
{
int[] days = { 1, 2, 3, 4, 5, 6, 0 };
if (db.addPermissionGroup(id, days[combo_den.SelectedIndex], time_from.Text,
time_to.Text, rooms.id[combo_mistnost.SelectedIndex]))
{
drawPermissions();
}
}
}
}
}
Form5.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace rfid
{
public partial class Form5 : Form
{
Db db = new Db("data.db");
public Form5()
{
InitializeComponent();
List<string> log = db.drawLog(); //select celého logu
//vypsání logu do listboxu
foreach (string row in log)
{
listBox1.Items.Add(row);
}
}
}
}
Db.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SQLite;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.Data.SqlClient;
using System.Xml.Linq;

namespace rfid
{
internal class Db
{
//deklarace proměnných
public string databeze;
SQLiteConnection c;
SQLiteCommand cmd;
SQLiteDataReader data;
//konstruktor
public Db(string databaze)
{
this.databeze = databaze;
c = new SQLiteConnection();
c.ConnectionString = "Data source=" + databeze;
c.Open();
cmd = new SQLiteCommand(c);
}

//přidání do logu
public void addLog(string code, int room, bool access)
{
try
{
cmd.CommandText = "INSERT INTO log (user_id, room_id, access) SELECT id_user,
@room, @access FROM users WHERE code = @code OR code_keyboard = @code;";
cmd.Parameters.AddWithValue("@room", room);
cmd.Parameters.AddWithValue("@access", access);
cmd.Parameters.AddWithValue("@code", code);
cmd.ExecuteNonQuery();
}
catch { }
}
//vykreslení logu
public List<string> drawLog()
{
List<string> log = new List<string>();
string pristup;
try
{
cmd.CommandText = "SELECT users.first_name, users.last_name, rooms.name, date,
access FROM log INNER JOIN users ON user_id = id_user INNER JOIN rooms on room_id = id_room
ORDER BY date DESC;";
data = cmd.ExecuteReader();
while (data.Read())
{
if(data.GetBoolean(4))
{
pristup = "POVOLEN";
}
else
{
pristup = "ZAMÍTNUT";
}
log.Add(data.GetString(0) + ' ' + data.GetString(1) + " --- " +
data.GetString(2) + " --- " + data.GetDateTime(3) + " --- " + pristup);
}
data.Close();
}
catch
{ }
return log;
}
//zkontroluje zdali má uživatel přístup
public (string name, bool is_allowed) check_reader(int room, string code)
{
int day = (int)DateTime.Now.DayOfWeek;
string jmeno = String.Empty;
List<TimeSpan> times_from = new List<TimeSpan>();
List<TimeSpan> times_to = new List<TimeSpan>();
//vybere uživatele s kódem a s přístupem v požadovaný den
cmd.CommandText = "SELECT first_name, last_name, from_time, to_time FROM users
INNER JOIN permissions ON id_user = user_id WHERE (code = @code OR code_keyboard = @code) AND
day = @day AND (room_id = @room OR room_id = 4);";
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("code", code);
cmd.Parameters.AddWithValue("day", day);
cmd.Parameters.AddWithValue("room", room);

try
{
data = cmd.ExecuteReader();
while (data.Read())
{
jmeno = data.GetString(0) + ' ' + data.GetString(1);
times_from.Add(TimeSpan.Parse(data.GetString(2)));
times_to.Add(TimeSpan.Parse(data.GetString(3)));
}
data.Close();
//zkontroluje jestli nemůže mít přístup na základě příslušnosti k pracovní
skupině
cmd.CommandText = "SELECT first_name, last_name, from_time, to_time FROM users
INNER JOIN permissions ON users.group_id = permissions.group_id WHERE (code = @code OR
code_keyboard = @code) AND day = @day AND (room_id = @room OR room_id = 4);";
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("code", code);
cmd.Parameters.AddWithValue("day", day);
cmd.Parameters.AddWithValue("room", room);
data = cmd.ExecuteReader();
while (data.Read())
{
jmeno = data.GetString(0) + ' ' + data.GetString(1);
times_from.Add(TimeSpan.Parse(data.GetString(2)));
times_to.Add(TimeSpan.Parse(data.GetString(3)));
}
data.Close();
//nyní zkontroluje, jestli je to v rozmezí času, kdy má povolen přístup, jinak
vrátí false
for (int i = 0; i < times_from.Count; i++)
{
if (DateTime.Now.TimeOfDay >= times_from[i] && DateTime.Now.TimeOfDay <
times_to[i])
{
return (jmeno, true);
}
}
}
catch
{
return (String.Empty, false);
}
return (jmeno, false);
}
//select všech skupin
public (List<string>, List<int> id) groups()
{
List<string> groups = new List<string>();
List<int> id = new List<int>();
try
{
cmd.CommandText = "SELECT id_group, name FROM groups;";
data = cmd.ExecuteReader();
while (data.Read())
{
id.Add(data.GetInt32(0));
groups.Add(data.GetString(1));
}
data.Close();
}
catch { };
return (groups, id);
}
//select všech místností
public (List<string> room, List<int> id) rooms()
{
List<string> rooms = new List<string>();
List<int> id = new List<int>();
try
{
cmd.CommandText = "SELECT id_room, name FROM rooms;";
data = cmd.ExecuteReader();
while (data.Read())
{
id.Add(data.GetInt32(0));
rooms.Add(data.GetString(1));
}
data.Close();
}
catch { };
return (rooms, id);
}
//select všech oprávnění uživatele s požadovaným id
public (List<int> id, List<string> permission) getPermissions(int user_id)
{
List<int> id = new List<int>();
List<string> permissions = new List<string>();
string[] days = { "neděle", "pondělí", "úterý", "středa", "čtvrtek", "pátek",
"sobota", "neděle" };
try
{
cmd.CommandText = "SELECT id, day, from_time, to_time, rooms.name FROM
permissions INNER JOIN rooms ON permissions.room_id = rooms.id_room WHERE user_id =
@user_id;";
cmd.Parameters.AddWithValue("@user_id", user_id);
data = cmd.ExecuteReader();
while (data.Read())
{
id.Add(data.GetInt32(0));
permissions.Add(days[data.GetInt32(1)] + " --- " + data.GetString(2) + " -
" + data.GetString(3) + " --- " + data.GetString(4));
}
data.Close();
}
catch { };
return(id, permissions);
}
//select všech oprávnění skupiny s požadovaným id
public (List<int> id, List<string> permission) getPermissionsGroup(int group_id)
{
List<int> id = new List<int>();
List<string> permissions = new List<string>();
string[] days = { "neděle", "pondělí", "úterý", "středa", "čtvrtek", "pátek",
"sobota", "neděle" };
try
{
cmd.CommandText = "SELECT id, day, from_time, to_time, rooms.name FROM
permissions INNER JOIN rooms ON permissions.room_id = rooms.id_room WHERE group_id =
@group_id;";
cmd.Parameters.AddWithValue("@group_id", group_id);
data = cmd.ExecuteReader();
while (data.Read())
{
id.Add(data.GetInt32(0));
permissions.Add(days[data.GetInt32(1)] + " --- " + data.GetString(2) + " -
" + data.GetString(3) + " --- " + data.GetString(4));
}
data.Close();
}
catch { };
return (id, permissions);
}
//přidání oprávnění uživateli
public bool addPermission(int user_id, int day, string from_time, string to_time, int
room_id)
{
try
{
cmd.CommandText = "INSERT INTO permissions (user_id, day, from_time, to_time,
room_id) VALUES(@user_id, @day, @from_time, @to_time, @room_id);";
cmd.Parameters.AddWithValue("@user_id", user_id);
cmd.Parameters.AddWithValue("@day", day);
cmd.Parameters.AddWithValue("@from_time", from_time);
cmd.Parameters.AddWithValue("@to_time", to_time);
cmd.Parameters.AddWithValue("@room_id", room_id);
if (cmd.ExecuteNonQuery() > 0)
{
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
//přidání oprávnění skupině
public bool addPermissionGroup(int group_id, int day, string from_time, string
to_time, int room_id)
{
try
{
cmd.CommandText = "INSERT INTO permissions (day, from_time, to_time, room_id,
group_id) VALUES(@day, @from_time, @to_time, @room_id, @group_id);";
cmd.Parameters.AddWithValue("@group_id", group_id);
cmd.Parameters.AddWithValue("@day", day);
cmd.Parameters.AddWithValue("@from_time", from_time);
cmd.Parameters.AddWithValue("@to_time", to_time);
cmd.Parameters.AddWithValue("@room_id", room_id);
if (cmd.ExecuteNonQuery() > 0)
{
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
//získá skupinu, jaké je uživatel s požadovaným id součástí
public (int id, string group) getGroup(int user_id)
{
int id = 0;
string name = "Žádná";
cmd.CommandText = "SELECT group_id, groups.name FROM users INNER JOIN groups ON
group_id = id_group WHERE id_user = @id_user;";
cmd.Parameters.AddWithValue("@id_user", user_id);
data = cmd.ExecuteReader();
while(data.Read())
{
id = data.GetInt32(0);
name = data.GetString(1);
}
data.Close();
return (id, name);
}
//select všech uživatelů
public (List<string> name, List<int> id) users()
{
List<string> name = new List<string>();
List<int> id = new List<int>();
try
{
cmd.CommandText = "SELECT id_user, first_name, last_name FROM users;";
data = cmd.ExecuteReader();
while (data.Read())
{
id.Add(data.GetInt32(0));
name.Add(data.GetString(1) + ' ' + data.GetString(2));
}
data.Close();
}
catch { };
return (name, id);
}
//přidání uživatele
public void addUser(string first_name, string last_name, string code, string
code_keyboard, int group)
{
cmd.CommandText = "INSERT INTO users (first_name, last_name, code, code_keyboard,
group_id) VALUES (@first_name, @last_name, @code, @code_keyboard, @group_id);";
cmd.Parameters.AddWithValue("first_name", first_name);
cmd.Parameters.AddWithValue("last_name", last_name);
if (string.IsNullOrEmpty(code))
{
cmd.Parameters.AddWithValue("code", DBNull.Value);
}
else
{
cmd.Parameters.AddWithValue("code", code);
}
if (string.IsNullOrEmpty(code_keyboard))
{
cmd.Parameters.AddWithValue("code_keyboard", DBNull.Value);
}
else
{
cmd.Parameters.AddWithValue("code_keyboard", code_keyboard);
}
if (group > 0)
{
cmd.Parameters.AddWithValue("group_id", group);
}
else
{
cmd.Parameters.AddWithValue("group_id", null);
}
try
{
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
if (e.Message.Contains("UNIQUE"))
{
MessageBox.Show("Kód už je použit, přiložte jiný");
}
else
{
MessageBox.Show("Neznámá chyba, zkuste to znovu");
}
}
}
}
}
Odpovědi na otázky:
1. Pro nasazení samostatných čteček např. v rozsáhlejším objektu je možné efektivně
použít rozhraní RS485. Zkuste vysvětlit proč a uvést důležité parametry tohoto
rozhraní. Co musí čtečky pro nasazení na RS485 splňovat
Zařízení mohou komunikovat na větší vzdálenost – až 12 m (RS232 jen 2 m). Výhodou je
také možnost vytváření sítí (sběrnic) až se 32 zařízeními na jednom řídícím zařízení.
Důležitými parametry tohoto rozhraní jsou rychlost přenosu dat, délka přenosového kabelu,
impedance kabelu a maximální počet zařízení připojených k jednomu řídícímu zařízení.
Čtečky musí splňovat určité požadavky, jako jsou například podpora protokolu komunikace přes
RS485, vhodný konektor pro připojení kabelu a schopnost pracovat v prostředí s rušením.1
2. Popište princip, na kterém je technologie RFID identifikace založena
RFID je technologie, která umožňuje bezdrátové a bezkontaktní identifikaci objektů pomocí
rádiových vln. RFID systém se skládá z dvou hlavních komponent: RFID čtečky a RFID tagů.
RFID čtečky jsou zařízení, která vysílají rádiové signály do okolí, aby získaly informace z RFID
tagů. dyž je RFID tag v dosahu čtečky, signál od čtečky indukuje malý proud v anténě tagu a ten
následně odpoví zasláním svých dat zpět k čtečce.
3. Zamyslete se nad možnými bezpečnostními riziky při použití RFID identifikace a
navrhněte konkrétní způsob, kterým byste vybrané riziko zneužití minimalizovali.
Jedním z bezpečnostních rizik může být klonování RFID čipu, kdy je pomocí specializovaného
hardwaru odposlechnut čip a zreprodukován signál, kdy se útočník tváří jako původní čip.
Ochranou proti tomuto by mohlo být pravidelné měnění kódování v čipech, kdy každý čas má
nový a jedinečný kód. Této technice se říká rolling code.2

Závěr:
Úlohu jsme splnili v plném rozsahu a námi navržená struktura tabulek v databázi je dle
mého pohledu ideální a algoritmus odladěný.

1
https://cs.wikipedia.org/wiki/RS-485
2
https://www.techtarget.com/whatis/definition/rolling-code

You might also like