summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Rudolph <johannes.rudolph@gmx.com>2018-02-12 23:16:11 +0100
committerSebastian Reichel <sre@ring0.de>2018-06-28 01:53:40 +0200
commitc70d626e473c8cbdbd87125a256ca221c0c3fa23 (patch)
treeb865181b45bbe4a6beba7e8045ec9d98d18d9b41
parent764c39f4facfe42d926cd952dcf0f7e2768097a8 (diff)
downloadserial-barcode-scanner-c70d626e473c8cbdbd87125a256ca221c0c3fa23.tar.bz2
Add RFID support
-rw-r--r--example.cfg3
-rw-r--r--sql/tables.sql1
-rw-r--r--src/database/database.vala46
-rw-r--r--src/database/db-interface.vala6
-rw-r--r--src/input-device/main.vala13
-rw-r--r--src/scanner-session/scannersession-interface.vala1
-rw-r--r--src/scanner-session/scannersession.vala20
-rw-r--r--src/serial-device/main.vala6
-rw-r--r--src/web/csv.vala10
-rw-r--r--src/web/web.vala1
-rw-r--r--systemd/shopsystem-input-device-rfid.rules1
-rw-r--r--templates/users/entry.html1
12 files changed, 97 insertions, 12 deletions
diff --git a/example.cfg b/example.cfg
index 65056d8..a56e074 100644
--- a/example.cfg
+++ b/example.cfg
@@ -6,7 +6,8 @@ spacename = Mainframe
file = /path/to/shop.db
[INPUT]
# use ignore if you have no device (this skips the input feature)
-device = /dev/input/by-id/path-to-barcode-scanner
+barcodescanner = /dev/barcodescanner
+rfidreader = /dev/rfidreader
[MAIL]
server = mail.server.example.com
port = 587
diff --git a/sql/tables.sql b/sql/tables.sql
index fbe4d0e..1518ef2 100644
--- a/sql/tables.sql
+++ b/sql/tables.sql
@@ -9,5 +9,6 @@ CREATE TABLE IF NOT EXISTS supplier(id INTEGER PRIMARY KEY AUTOINCREMENT, name T
CREATE TABLE IF NOT EXISTS cashbox_diff(id INTEGER PRIMARY KEY AUTOINCREMENT, user INTEGER NOT NULL REFERENCES users, amount INTEGER NOT NULL, timestamp INTEGER NOT NULL DEFAULT 0);
CREATE TABLE IF NOT EXISTS ean_aliases (id INTEGER PRIMARY KEY NOT NULL, real_ean INTEGER NOT NULL REFERENCES products);
CREATE TABLE IF NOT EXISTS categories (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT);
+CREATE TABLE IF NOT EXISTS rfid_users (rfid TEXT, user INTEGER NOT NULL REFERENCES users);
CREATE INDEX IF NOT EXISTS invoiceindex ON sales (user ASC, timestamp DESC);
COMMIT;
diff --git a/src/database/database.vala b/src/database/database.vala
index dc636b8..0ce3f87 100644
--- a/src/database/database.vala
+++ b/src/database/database.vala
@@ -138,6 +138,10 @@ public class DataBase : Object {
queries["alias_ean_add"] = "INSERT OR IGNORE INTO ean_aliases (id, real_ean) VALUES (?, ?)";
queries["alias_ean_get"] = "SELECT real_ean FROM ean_aliases WHERE id = ?";
queries["alias_ean_list"] = "SELECT id, real_ean FROM ean_aliases ORDER BY id ASC";
+ queries["userid_rfid"] = "SELECT user FROM rfid_users WHERE rfid = ?";
+ queries["rfid_userid"] = "SELECT rfid FROM rfid_users WHERE user = ?";
+ queries["rfid_insert"] = "INSERT OR REPLACE INTO rfid_users ('user','rfid') VALUES (?,?)";
+ queries["rfid_delete_user"] = "DELETE FROM rfid_users WHERE user = ?";
/* compile queries into statements */
foreach(var entry in queries.entries) {
@@ -632,6 +636,17 @@ public class DataBase : Object {
throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
}
+ statements["rfid_userid"].reset();
+ statements["rfid_userid"].bind_int(1, user);
+ rc = statements["rfid_userid"].step();
+
+ string[] rfid = {};
+ while(rc == Sqlite.ROW) {
+ rfid += statements["rfid_userid"].column_text(0);
+ rc = statements["rfid_userid"].step();
+ }
+ result.rfid = rfid;
+
return result;
}
@@ -894,6 +909,21 @@ public class DataBase : Object {
int rc = statements["user_replace"].step();
if(rc != Sqlite.DONE)
throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+
+ statements["rfid_delete_user"].reset();
+ statements["rfid_delete_user"].bind_int(1, u.id);
+ rc = statements["rfid_delete_user"].step();
+ if(rc != Sqlite.DONE)
+ throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+
+ foreach (string rfid in u.rfid) {
+ statements["rfid_insert"].reset();
+ statements["rfid_insert"].bind_int(1, u.id);
+ statements["rfid_insert"].bind_text(2, rfid);
+ rc = statements["rfid_insert"].step();
+ if(rc != Sqlite.DONE)
+ throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ }
}
public bool user_is_disabled(int user) throws DatabaseError {
@@ -1164,4 +1194,20 @@ public class DataBase : Object {
return bbdlist.data;
}
+
+ public int get_userid_for_rfid(string rfid) throws IOError, DatabaseError {
+ statements["userid_rfid"].reset();
+ statements["userid_rfid"].bind_text(1, rfid);
+
+ int rc = statements["userid_rfid"].step();
+
+ switch(rc) {
+ case Sqlite.ROW:
+ return statements["userid_rfid"].column_int(0);
+ case Sqlite.DONE:
+ throw new DatabaseError.RFID_NOT_FOUND("unknown rfid: %s", rfid);
+ default:
+ throw new DatabaseError.INTERNAL_ERROR("internal error: %d", rc);
+ }
+ }
}
diff --git a/src/database/db-interface.vala b/src/database/db-interface.vala
index de5bbc4..b6d1395 100644
--- a/src/database/db-interface.vala
+++ b/src/database/db-interface.vala
@@ -65,6 +65,9 @@ public interface Database : Object {
public abstract uint64 ean_alias_get(uint64 ean) throws IOError;
public abstract EanAlias[] ean_alias_list() throws IOError;
public abstract BestBeforeEntry[] bestbeforelist() throws IOError;
+ public abstract int get_userid_for_rfid(string rfid) throws IOError, DatabaseError;
+ public abstract void addrfid(string rfid, int user) throws IOError, DatabaseError;
+ public abstract void delete_rfid_for_user(int user) throws IOError, DatabaseError;
}
public struct Category {
@@ -126,6 +129,7 @@ public struct UserInfo {
public bool disabled;
public bool hidden;
public string soundTheme;
+ public string[] rfid;
public bool equals(UserInfo x) {
if(id != x.id) return false;
@@ -140,6 +144,7 @@ public struct UserInfo {
if(joined_at != x.joined_at) return false;
if(disabled != x.disabled) return false;
if(hidden != x.hidden) return false;
+ if(rfid != x.rfid) return false;
return true;
}
@@ -197,4 +202,5 @@ public errordomain DatabaseError {
SESSION_NOT_FOUND,
USER_NOT_FOUND,
CONSTRAINT_FAILED,
+ RFID_NOT_FOUND,
}
diff --git a/src/input-device/main.vala b/src/input-device/main.vala
index 8578033..30119b0 100644
--- a/src/input-device/main.vala
+++ b/src/input-device/main.vala
@@ -13,12 +13,14 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-Device dev;
+Device devScanner;
+Device devRfid;
public static int main(string[] args) {
try {
Config cfg = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Config", "/io/mainframe/shopsystem/config");
- dev = new Device(cfg.get_string("INPUT", "device"));
+ devScanner = new Device(cfg.get_string("INPUT", "barcodescanner"));
+ devRfid = new Device(cfg.get_string("INPUT", "rfidreader"));
} catch(IOError e) {
error("IOError: %s\n", e.message);
} catch(KeyFileError e) {
@@ -40,7 +42,12 @@ public static int main(string[] args) {
void on_bus_aquired(DBusConnection con) {
try {
- con.register_object("/io/mainframe/shopsystem/device", dev);
+ con.register_object("/io/mainframe/shopsystem/device/scanner", devScanner);
+ } catch(IOError e) {
+ stderr.printf("Could not register service\n");
+ }
+ try {
+ con.register_object("/io/mainframe/shopsystem/device/rfid", devRfid);
} catch(IOError e) {
stderr.printf("Could not register service\n");
}
diff --git a/src/scanner-session/scannersession-interface.vala b/src/scanner-session/scannersession-interface.vala
index ff2c2e9..c19a434 100644
--- a/src/scanner-session/scannersession-interface.vala
+++ b/src/scanner-session/scannersession-interface.vala
@@ -31,6 +31,7 @@ public enum ScannerSessionCodeType {
UNDO,
LOGOUT,
EAN,
+ RFIDEM4100,
UNKNOWN
}
diff --git a/src/scanner-session/scannersession.vala b/src/scanner-session/scannersession.vala
index f19d94c..7cc9cc4 100644
--- a/src/scanner-session/scannersession.vala
+++ b/src/scanner-session/scannersession.vala
@@ -23,7 +23,8 @@ public class ScannerSessionImplementation {
private Database db;
private AudioPlayer audio;
- private InputDevice dev;
+ private InputDevice devScanner;
+ private InputDevice devRfid;
private Cli cli;
private ScannerSessionState state = ScannerSessionState.READY;
@@ -35,11 +36,13 @@ public class ScannerSessionImplementation {
public ScannerSessionImplementation() {
try {
db = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Database", "/io/mainframe/shopsystem/database");
- dev = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.InputDevice", "/io/mainframe/shopsystem/device");
+ devScanner = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.InputDevice", "/io/mainframe/shopsystem/device/scanner");
+ devRfid = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.InputDevice", "/io/mainframe/shopsystem/device/rfid");
cli = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Cli", "/io/mainframe/shopsystem/cli");
audio = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.AudioPlayer", "/io/mainframe/shopsystem/audio");
- dev.received_barcode.connect(handle_barcode);
+ devScanner.received_barcode.connect(handle_barcode);
+ devRfid.received_barcode.connect(handle_barcode);
cli.received_barcode.connect(handle_barcode);
} catch(IOError e) {
error("IOError: %s\n", e.message);
@@ -85,6 +88,8 @@ public class ScannerSessionImplementation {
return ScannerSessionCodeType.UNDO;
} else if(scannerdata == "LOGOUT") {
return ScannerSessionCodeType.LOGOUT;
+ } else if(scannerdata.length == 10) {
+ return ScannerSessionCodeType.RFIDEM4100;
} else {
//Handle EAN Code
uint64 id = 0;
@@ -184,6 +189,10 @@ public class ScannerSessionImplementation {
scannerResult.audioType = AudioType.ERROR;
state = ScannerSessionState.READY;
return scannerResult;
+ case ScannerSessionCodeType.RFIDEM4100:
+ int user = db.get_userid_for_rfid(scannerdata);
+ scannerResult.nextScannerdata =@"USER $user";
+ return scannerResult;
default:
state = ScannerSessionState.READY;
return scannerResult;
@@ -249,7 +258,8 @@ public class ScannerSessionImplementation {
break;
case ScannerSessionCodeType.USER:
case ScannerSessionCodeType.GUEST:
- //Logout alten User und akrtikel kaufen
+ case ScannerSessionCodeType.RFIDEM4100:
+ /* Logout old user session (and buy articles) */
scannerResult = logout();
scannerResult.nextScannerdata = scannerdata;
break;
@@ -284,7 +294,7 @@ public class ScannerSessionImplementation {
try {
stdout.printf("scannerdata: %s\n", scannerdata);
if(interpret(scannerdata))
- dev.blink(1000);
+ devScanner.blink(1000);
} catch(IOError e) {
send_message(MessageType.ERROR, "IOError: %s", e.message);
} catch(DatabaseError e) {
diff --git a/src/serial-device/main.vala b/src/serial-device/main.vala
index 0dea907..70d50e2 100644
--- a/src/serial-device/main.vala
+++ b/src/serial-device/main.vala
@@ -13,12 +13,12 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-Device dev;
+Device scanner;
public static int main(string[] args) {
try {
Config cfg = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Config", "/io/mainframe/shopsystem/config");
- dev = new Device(cfg.get_string("INPUT", "device"), 9600, 8, 1);
+ scanner = new Device(cfg.get_string("INPUT", "barcodescanner"), 9600, 8, 1);
} catch(IOError e) {
error("IOError: %s\n", e.message);
} catch(KeyFileError e) {
@@ -40,7 +40,7 @@ public static int main(string[] args) {
void on_bus_aquired(DBusConnection con) {
try {
- con.register_object("/io/mainframe/shopsystem/device", dev);
+ con.register_object("/io/mainframe/shopsystem/devicescanner", scanner);
} catch(IOError e) {
stderr.printf("Could not register service\n");
}
diff --git a/src/web/csv.vala b/src/web/csv.vala
index 299af8d..5d4daba 100644
--- a/src/web/csv.vala
+++ b/src/web/csv.vala
@@ -1,4 +1,5 @@
/* Copyright 2012, Sebastian Reichel <sre@ring0.de>
+ * Copyright 2017-2018, Johannes Rudolph <johannes.rudolph@gmx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -66,6 +67,15 @@ public class CSVMemberFile {
m.pgp = csv_value(linedata[9]);
m.hidden = int.parse(csv_value(linedata[10])) != 0;
m.disabled = int.parse(csv_value(linedata[11])) != 0;
+ string[] rfid = {};
+ if(csv_value(linedata[12]) != "")
+ rfid += csv_value(linedata[12]);
+ if(csv_value(linedata[13]) != "")
+ rfid += csv_value(linedata[13]);
+ if(csv_value(linedata[14]) != "")
+ rfid += csv_value(linedata[14]);
+ m.rfid = rfid;
+
m.soundTheme = "";
if(csv_value(linedata[0]) != "EXTERNEMITGLIEDSNUMMER")
members += m;
diff --git a/src/web/web.vala b/src/web/web.vala
index 37e6edc..f4207ad 100644
--- a/src/web/web.vala
+++ b/src/web/web.vala
@@ -351,6 +351,7 @@ public class WebServer {
t.replace("PGPKEYID", userinfo.pgp);
t.replace("DISABLED", userinfo.disabled ? "true" : "false");
t.replace("HIDDEN", userinfo.hidden ? "true" : "false");
+ t.replace("RFID", string.joinv("<br>",userinfo.rfid));
var userauth = db.get_user_auth(id);
t.replace("ISSUPERUSER", userauth.superuser ? "true" : "false");
diff --git a/systemd/shopsystem-input-device-rfid.rules b/systemd/shopsystem-input-device-rfid.rules
new file mode 100644
index 0000000..aebfbea
--- /dev/null
+++ b/systemd/shopsystem-input-device-rfid.rules
@@ -0,0 +1 @@
+ACTION=="add", ATTRS{idVendor}=="ffff", ATTRS{idProduct}=="0035", MODE="0666", SYMLINK+="rfidreader" TAG+="systemd", ENV{SYSTEMD_WANTS}="shopsystem-input-device"
diff --git a/templates/users/entry.html b/templates/users/entry.html
index 065c4e7..b1477c7 100644
--- a/templates/users/entry.html
+++ b/templates/users/entry.html
@@ -22,6 +22,7 @@
<tr><th>Street</th><td>{{{STREET}}}</td></tr>
<tr><th>PLZ</th><td>{{{POSTALCODE}}}</td></tr>
<tr><th>City</th><td>{{{CITY}}}</td></tr>
+ <tr><th>RFID</th><td>{{{RFID}}}</td></tr>
<tr><th colspan="2">Settings</th></tr>
<tr><th>Sound theme</th>
<td>