upload code

This commit is contained in:
Nick Leeman 2022-01-24 17:15:40 +01:00
parent 07bf94d362
commit 0fadcf5676
21 changed files with 1171 additions and 0 deletions

5
Securitas/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

7
Securitas/.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
]
}

7
Securitas/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
"files.associations": {
"cstddef": "cpp",
"ranges": "cpp",
"functional": "cpp"
}
}

39
Securitas/include/README Normal file
View File

@ -0,0 +1,39 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

46
Securitas/lib/README Normal file
View File

@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

23
Securitas/platformio.ini Normal file
View File

@ -0,0 +1,23 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:wemos_d1_mini32]
platform = espressif8266
board = d1_mini_pro
framework = arduino
lib_deps =
https://git.aterve.com/Frozenverse/SimpleSerialProtocol.git
https://git.aterve.com/Frozenverse/KeyValueEEPROM.git
adafruit/Adafruit Fingerprint Sensor Library@^2.0.7
plerup/EspSoftwareSerial@^6.15.2
adafruit/Adafruit GFX Library@^1.10.12
adafruit/Adafruit SSD1306@^2.5.1
adafruit/Adafruit BusIO@^1.10.1

127
Securitas/src/connections.h Normal file
View File

@ -0,0 +1,127 @@
#pragma once
#include <Arduino.h>
#include <display.h>
#include <SimpleSerialProtocol.h>
#include <passwords.h>
#include <fingersensor.h>
#define SERIAL_PACKET_BUFFER_SIZE 25
namespace Connections {
void init();
void handle();
void sendPacket(char *id, char *type, char *data);
void onSerialPacket(Packet packet);
long lastPacketTransmit = 0;
Packet serialPackets[SERIAL_PACKET_BUFFER_SIZE];
SimpleSerialProtocol device;
Packet *name_packet;
}
void Connections::init() {
Display::drawStatus("Init serial: ...");
for (int i = 0; i < SERIAL_PACKET_BUFFER_SIZE; i++) {
serialPackets[i].id = "--";
serialPackets[i].type = "--";
serialPackets[i].data = "--";
}
Connections::device.init(Serial, 9600);
Display::drawStatus("Init serial: ok!");
Serial.print("!***!");
delay(750);
}
void Connections::handle() {
device.receivePackets(Connections::onSerialPacket);
for (int i = 0; i < SERIAL_PACKET_BUFFER_SIZE; i++) {
if (!(strcmp(serialPackets[i].id, "--") == 0)) {
if ((millis() - lastPacketTransmit) > 500) {
device.sendPacket(serialPackets[i].id, serialPackets[i].type, serialPackets[i].data);
serialPackets[i].id = "--";
serialPackets[i].type = "--";
serialPackets[i].data = "--";
lastPacketTransmit = millis();
break;
}
}
}
}
void Connections::sendPacket(char *id, char *type, char *data) {
for (int i = 0; i < SERIAL_PACKET_BUFFER_SIZE; i++) {
if (strcmp(serialPackets[i].id, "--") == 0) {
serialPackets[i].id = id;
serialPackets[i].type = type;
serialPackets[i].data = data;
break;
}
}
}
void Connections::onSerialPacket(Packet packet) {
if (strcmp(packet.id, "test") == 0) {
Connections::sendPacket("received", "received", "received");
}
if (strcmp(packet.id, "passwords") == 0 && strcmp(packet.type, "available") == 0) {
char* passwords = (char*)Passwords::available();
Connections::sendPacket("passwords", "available_passwords", passwords);
}
if (strcmp(packet.id, "fingerprint") == 0 && strcmp(packet.type, "enroll") == 0) {
int id = atoi(packet.data);
bool status = FingerPrintSensor::enroll(id);
if (status) {
Connections::sendPacket("fingerprint", "auth_status", "valid");
} else {
Connections::sendPacket("fingerprint", "auth_status", "invalid");
}
// char* status = (char*)char(enroll_status);
Connections::sendPacket("fingerprint", "enroll_status", "");
}
if (strcmp(packet.id, "fingerprint") == 0 && strcmp(packet.type, "auth") == 0) {
int status = FingerPrintSensor::authenticate();
if (status) {
Connections::sendPacket("fingerprint", "auth_status", "valid");
Display::drawStatus("Ready!");
FingerPrintSensor::color(2);
} else {
Connections::sendPacket("fingerprint", "auth_status", "invalid");
Display::drawStatus("Not authenticated!");
FingerPrintSensor::color(1);
}
}
if (strcmp(packet.id, "passwords") == 0 && strcmp(packet.type, "available") == 0) {
const char * data = Passwords::available();
Connections::sendPacket("passwords", "available_passwords", (char*)data);
}
if (strcmp(packet.id, "new_password") == 0) {
Passwords::store(packet.type, packet.data);
}
if (strcmp(packet.id, "passwords") == 0 && strcmp(packet.type, "new_available") == 0) {
Passwords::setAvailable(packet.data);
}
if (strcmp(packet.id, "passwords") == 0 && strcmp(packet.type, "load") == 0) {
const char* password = Passwords::get(packet.data);
// const char* password = "ds";
Connections::sendPacket("passwords", "password", (char*)password);
}
}

71
Securitas/src/display.h Normal file
View File

@ -0,0 +1,71 @@
#pragma once
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_RESET 0 // GPIO0
#define SCREEN_ADDRESS 0x3C
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
namespace Display
{
Adafruit_SSD1306 _display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, SCREEN_RESET);
void init();
void drawText(int x, int y, char* text);
void drawRectangle(int x, int y, int w, int h);
void drawStatus(char* status);
}
void Display::init() {
// Init screen bus
if(!_display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
return;
}
// Init screen buffer
_display.display();
_display.clearDisplay();
Display::drawRectangle(0, 0, 128, 32);
Display::drawText(24, 3, "Securitas Mk 1");
Display::drawText(8, 16, "Made by Nick Leeman");
delay(750);
}
void Display::drawStatus(char* status) {
_display.clearDisplay();
Display::drawRectangle(0, 0, 128, 32);
Display::drawText(3, 3, "Securitas Mk 1");
Display::drawText(95, 3, "21:28");
Display::drawText(3, 20, status);
}
void Display::drawText(int x, int y, char* text) {
// Normal 1:1 pixel scale
_display.setTextSize(1);
// Draw white text
_display.setTextColor(SSD1306_WHITE);
// Start at top-left corner
_display.setCursor(x, y);
// Use full 256 char 'Code Page 437' font
_display.cp437(true);
// Write text
_display.printf(text);
// Update buffer
_display.display();
}
void Display::drawRectangle(int x, int y, int w, int h) {
_display.drawRect(x, y, w, h, SSD1306_WHITE);
}

View File

@ -0,0 +1,356 @@
#pragma once
#include <SoftwareSerial.h>
#include <Adafruit_Fingerprint.h>
namespace FingerPrintSensor
{
SoftwareSerial fingerSensorSerial(12, 14);
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&fingerSensorSerial);
bool authenticated = false;
void init();
bool enroll(int id);
bool authenticate();
void color(int type);
}
void FingerPrintSensor::init() {
Display::drawStatus("Init fingerprint: ...");
// set the data rate for the sensor serial port
finger.begin(57600);
delay(50);
if (!finger.verifyPassword()) {
Display::drawStatus("Init fingerprint: err!");
return;
}
finger.getParameters();
Display::drawStatus("Init fingerprint: ok!");
delay(750);
}
bool FingerPrintSensor::enroll(int id) {
Display::drawStatus("Enrolling process");
delay(1000);
int status = -1;
while (status != FINGERPRINT_OK) {
status = finger.getImage();
switch (status) {
case FINGERPRINT_OK:
Display::drawStatus("Image captured!");
delay(1000);
break;
case FINGERPRINT_NOFINGER:
Display::drawStatus("Place finger...");
delay(250);
break;
case FINGERPRINT_PACKETRECIEVEERR:
Display::drawStatus("Comms error...");
delay(1000);
break;
case FINGERPRINT_IMAGEFAIL:
Display::drawStatus("Image error!");
delay(1000);
break;
default:
Display::drawStatus("Unknown error!");
delay(1000);
break;
}
}
status = finger.image2Tz(1);
switch (status) {
case FINGERPRINT_OK:
Display::drawStatus("Image Converted!");
delay(1000);
break;
case FINGERPRINT_IMAGEMESS:
Display::drawStatus("Bad image quality!");
delay(1000);
return false;
case FINGERPRINT_PACKETRECIEVEERR:
Display::drawStatus("Comms error...");
delay(1000);
return false;
case FINGERPRINT_FEATUREFAIL:
Display::drawStatus("No features!");
delay(1000);
return false;
case FINGERPRINT_INVALIDIMAGE:
Display::drawStatus("Invalid features!");
delay(1000);
return false;
default:
Display::drawStatus("Unknown error!");
delay(1000);
return false;
}
status = 0;
while (status != FINGERPRINT_NOFINGER) {
status = finger.getImage();
}
status = -1;
Display::drawStatus("Place finger again!");
delay(1000);
while (status != FINGERPRINT_OK) {
status = finger.getImage();
switch (status) {
case FINGERPRINT_OK:
Display::drawStatus("Image captured!");
delay(1000);
break;
case FINGERPRINT_NOFINGER:
Display::drawStatus("Place finger...");
delay(250);
break;
case FINGERPRINT_PACKETRECIEVEERR:
Display::drawStatus("Comms error...");
delay(1000);
break;
case FINGERPRINT_IMAGEFAIL:
Display::drawStatus("Image error!");
delay(1000);
break;
default:
Display::drawStatus("Unknown error!");
delay(1000);
break;
}
}
status = finger.image2Tz(2);
switch (status) {
case FINGERPRINT_OK:
Display::drawStatus("Image converted!");
delay(1000);
break;
case FINGERPRINT_IMAGEMESS:
Display::drawStatus("Bad image quality!");
delay(1000);
return false;
case FINGERPRINT_PACKETRECIEVEERR:
Display::drawStatus("Comms error...");
delay(1000);
return false;
case FINGERPRINT_FEATUREFAIL:
Display::drawStatus("No features!");
delay(1000);
return false;
case FINGERPRINT_INVALIDIMAGE:
Display::drawStatus("Invalid features!");
delay(1000);
return false;
default:
Display::drawStatus("Unknown error!");
delay(1000);
return false;
}
Display::drawStatus("Creating model...");
delay(1000);
status = finger.createModel();
if (status == FINGERPRINT_OK) {
Display::drawStatus("Enroll match!");
delay(1000);
}
else if (status == FINGERPRINT_PACKETRECIEVEERR) {
Display::drawStatus("Comms error...");
delay(1000);
return false;
}
else if (status == FINGERPRINT_ENROLLMISMATCH) {
Display::drawStatus("Finger mismatch!");
delay(1000);
return false;
}
else {
Display::drawStatus("Unknown error!");
delay(1000);
return false;
}
Serial.print("ID "); Serial.println(id);
status = finger.storeModel(id);
if (status == FINGERPRINT_OK) {
Display::drawStatus("Enroll success!");
delay(1000);
}
else if (status == FINGERPRINT_PACKETRECIEVEERR) {
Display::drawStatus("Comms error...");
delay(1000);
return false;
}
else if (status == FINGERPRINT_BADLOCATION) {
Display::drawStatus("Invalid id!");
delay(1000);
return false;
}
else if (status == FINGERPRINT_FLASHERR) {
Display::drawStatus("Invalid flash!");
delay(1000);
return false;
}
else {
Display::drawStatus("Unknown error!");
delay(1000);
return false;
}
return true;
}
bool FingerPrintSensor::authenticate() {
uint8_t status = finger.getImage();
while (status != FINGERPRINT_OK)
{
status = finger.getImage();
switch (status) {
case FINGERPRINT_OK:
Display::drawStatus("Finger scanned!");
delay(1000);
break;
case FINGERPRINT_NOFINGER:
Display::drawStatus("Place finger...");
delay(1000);
break;
case FINGERPRINT_PACKETRECIEVEERR:
Display::drawStatus("Comms error...");
delay(1000);
return false;
case FINGERPRINT_IMAGEFAIL:
Display::drawStatus("Image error!");
delay(1000);
return false;
default:
Display::drawStatus("Unknown error!");
delay(1000);
return false;
}
}
// OK success!
status = finger.image2Tz();
switch (status) {
case FINGERPRINT_OK:
Display::drawStatus("Image converted!");
delay(1000);
break;
case FINGERPRINT_IMAGEMESS:
Display::drawStatus("Bad image quality!");
delay(1000);
return false;
case FINGERPRINT_PACKETRECIEVEERR:
Display::drawStatus("Comms error...");
delay(1000);
return false;
case FINGERPRINT_FEATUREFAIL:
Display::drawStatus("Invalid features!");
delay(1000);
return false;
case FINGERPRINT_INVALIDIMAGE:
Display::drawStatus("Invalid features!");
delay(1000);
return false;
default:
Display::drawStatus("Unknown error!");
delay(1000);
return false;
}
// OK converted!
status = finger.fingerSearch();
if (status == FINGERPRINT_OK) {
Display::drawStatus("Fingerprint valid!");
authenticated = true;
delay(1000);
return true;
}
else if (status == FINGERPRINT_PACKETRECIEVEERR) {
Display::drawStatus("Comms error!");
delay(1000);
return false;
}
else if (status == FINGERPRINT_NOTFOUND) {
Display::drawStatus("No match found!");
delay(1000);
return false;
}
else {
Display::drawStatus("Unknown error!");
delay(1000);
return false;
}
}
void FingerPrintSensor::color(int type) {
switch (type)
{
case 0:
finger.LEDcontrol(FINGERPRINT_LED_OFF, 0, FINGERPRINT_LED_RED);
break;
case 1:
finger.LEDcontrol(FINGERPRINT_LED_ON, 0, FINGERPRINT_LED_RED);
break;
case 2:
finger.LEDcontrol(FINGERPRINT_LED_ON, 0, FINGERPRINT_LED_BLUE);
break;
}
}

23
Securitas/src/main.cpp Normal file
View File

@ -0,0 +1,23 @@
#include <Arduino.h>
#include <passwords.h>
#include <connections.h>
#include <display.h>
#include <fingersensor.h>
void setup()
{
Display::init();
Connections::init();
Passwords::init();
FingerPrintSensor::init();
Connections::sendPacket("device", "init", "ready");
FingerPrintSensor::color(1);
Display::drawStatus("Not authenticated!");
}
void loop() {
Connections::handle();
}

53
Securitas/src/passwords.h Normal file
View File

@ -0,0 +1,53 @@
#pragma once
#include <display.h>
#include <KeyValueEEPROM.h>
#include <fingersensor.h>
namespace Passwords
{
void init();
const char* available();
void setAvailable(char * passwords);
void store(char* name, char* password);
const char* get(char* name);
}
void Passwords::init() {
Display::drawStatus("Init Passwords...");
KeyValueEEPROM.begin();
if(!KeyValueEEPROM.exists("stored-passwords")) {
KeyValueEEPROM.set<char*>("stored-passwords", "");
}
delay(750);
}
const char* Passwords::available() {
if (FingerPrintSensor::authenticated) {
char * key = "stored-passwords";
return KeyValueEEPROM.get<const char*>(key);
} else {
return "-";
}
}
void Passwords::setAvailable(char * passwords) {
if (FingerPrintSensor::authenticated) {
KeyValueEEPROM.set("stored-passwords", passwords);
}
}
void Passwords::store(char* name, char* password) {
if (FingerPrintSensor::authenticated) {
KeyValueEEPROM.set(name, password);
}
}
const char* Passwords::get(char* name) {
if (FingerPrintSensor::authenticated) {
return KeyValueEEPROM.get<const char*>(name, "--");
}
return "-";
}

11
Securitas/test/README Normal file
View File

@ -0,0 +1,11 @@
This directory is intended for PlatformIO Unit Testing and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/page/plus/unit-testing.html

32
SecuritasApp/go.mod Normal file
View File

@ -0,0 +1,32 @@
module frozenverse/securitas
go 1.17
require fyne.io/fyne/v2 v2.1.2
require (
github.com/creack/goselect v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 // indirect
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/go-gl/gl v0.0.0-20210813123233-e4099ee2221f // indirect
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be // indirect
github.com/godbus/dbus/v5 v5.0.4 // indirect
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564 // indirect
github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9 // indirect
github.com/stretchr/testify v1.7.0 // indirect
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07
github.com/yuin/goldmark v1.3.8 // indirect
go.bug.st/serial v1.3.4
golang.org/x/image v0.0.0-20200430140353-33d19683fad8 // indirect
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect
golang.org/x/text v0.3.3 // indirect
gopkg.in/yaml.v2 v2.2.8 // indirect
)

98
SecuritasApp/go.sum Normal file
View File

@ -0,0 +1,98 @@
fyne.io/fyne/v2 v2.1.2 h1:avp9CvLAUdvE7fDMtH1tVKyjxEWHWcpow6aI6L7Kvvw=
fyne.io/fyne/v2 v2.1.2/go.mod h1:p+E/Dh+wPW8JwR2DVcsZ9iXgR9ZKde80+Y+40Is54AQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9/go.mod h1:7uhhqiBaR4CpN0k9rMjOtjpcfGd6DG2m04zQxKnWQ0I=
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 h1:FDqhDm7pcsLhhWl1QtD8vlzI4mm59llRvNzrFg6/LAA=
github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3/go.mod h1:CzM2G82Q9BDUvMTGHnXf/6OExw/Dz2ivDj48nVg7Lg8=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/go-gl/gl v0.0.0-20210813123233-e4099ee2221f h1:s0O46d8fPwk9kU4k1jj76wBquMVETx7uveQD9MCIQoU=
github.com/go-gl/gl v0.0.0-20210813123233-e4099ee2221f/go.mod h1:wjpnOv6ONl2SuJSxqCPVaPZibGFdSci9HFocT9qtVYM=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be h1:Z28GdQBfKOL8tNHjvaDn3wHDO7AzTRkmAXvHvnopp98=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff h1:W71vTCKoxtdXgnm1ECDFkfQnpdqAO00zzGXLA5yaEX8=
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff/go.mod h1:wfqRWLHRBsRgkp5dmbG56SA0DmVtwrF5N3oPdI8t+Aw=
github.com/jackmordaunt/icns v0.0.0-20181231085925-4f16af745526/go.mod h1:UQkeMHVoNcyXYq9otUupF7/h/2tmHlhrS2zw7ZVvUqc=
github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lucor/goinfo v0.0.0-20210802170112-c078a2b0f08b/go.mod h1:PRq09yoB+Q2OJReAmwzKivcYyremnibWGbK7WfftHzc=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564 h1:HunZiaEKNGVdhTRQOVpMmj5MQnGnv+e8uZNu3xFLgyM=
github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564/go.mod h1:afMbS0qvv1m5tfENCwnOdZGOF8RGR/FsZ7bvBxQGZG4=
github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9 h1:m59mIOBO4kfcNCEzJNy71UkeF4XIx2EVmL9KLwDQdmM=
github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 h1:UyzmZLoiDWMRywV4DUYb9Fbt8uiOSooupjTq10vpvnU=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.3.8 h1:Nw158Q8QN+CPgTmVRByhVwapp8Mm1e2blinhmx4wx5E=
github.com/yuin/goldmark v1.3.8/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.bug.st/serial v1.3.4 h1:fMpfNEOsPQjYGZ3VHcs/xxsxoaPgbcjrm4YnMkcir3Y=
go.bug.st/serial v1.3.4/go.mod h1:z8CesKorE90Qr/oRSJiEuvzYRKol9r/anJZEb5kt304=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/image v0.0.0-20200430140353-33d19683fad8 h1:6WW6V3x1P/jokJBpRQYUJnMHRP6isStQwCozxnU7XQw=
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf h1:2ucpDCmfkl8Bd/FsLtiD653Wf96cW37s+iGx93zsu4k=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

252
SecuritasApp/main.go Normal file
View File

@ -0,0 +1,252 @@
package main
import (
"fmt"
"log"
"strings"
"time"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/widget"
"go.bug.st/serial"
"go.bug.st/serial/enumerator"
)
type Packet struct {
Id string
Type string
Data string
}
var serialPort serial.Port
var isAuthenticated bool = false
var application = app.New()
var window = application.NewWindow("Securitas")
var authBtn = widget.NewButton("Authenticate", func() {
go sendPacket("fingerprint", "auth", "-")
})
var loadPasswordsBtn = widget.NewButton("Load Passwords", func() {
go sendPacket("passwords", "available", "-")
})
var addPasswordBtn = widget.NewButton("Add password", func() {
nameEntry := widget.NewEntry()
passwordEntry := widget.NewEntry()
var items = []*widget.FormItem{
{Text: "Name", Widget: nameEntry},
{Text: "Password", Widget: passwordEntry},
}
go dialog.ShowForm("New Password", "Create", "Cancel", items, func(status bool) {
if !status {
return
}
sendPacket("new_password", nameEntry.Text, passwordEntry.Text)
time.Sleep(time.Millisecond * 750)
newPasswordsArray := append(passwordSelector.Options, nameEntry.Text)
newPasswords := strings.Join(newPasswordsArray[:], "-")
sendPacket("passwords", "new_available", newPasswords)
time.Sleep(time.Millisecond * 750)
go sendPacket("passwords", "available", "-")
}, window)
})
var enrollBtn = widget.NewButton("Enroll", func() {
go sendPacket("fingerprint", "enroll", "1")
})
var passwordSelector = widget.NewSelect([]string{}, func(value string) {
log.Println("Select set to", value)
})
var getPasswordBtn = widget.NewButton("Get", func() {
go sendPacket("passwords", "load", passwordSelector.Selected)
})
func main() {
window.Resize(fyne.NewSize(600, 400))
window.CenterOnScreen()
window.SetFixedSize(true)
titleText := widget.NewLabel("Password manager")
titleText.TextStyle.Bold = true
txtResults := widget.NewTextGrid()
txtResults.ShowLineNumbers = true
loadPasswordsBtn.Disable()
// addPasswordBtn.Disable()
enrollBtn.Disable()
cntButtons := container.NewGridWithColumns(4, authBtn, loadPasswordsBtn, addPasswordBtn, enrollBtn)
cntSelection := container.NewGridWithColumns(2, passwordSelector, getPasswordBtn)
cntContent := container.NewGridWithRows(3, titleText, cntSelection, cntButtons)
window.SetContent(cntContent)
go handleSerial()
window.ShowAndRun()
}
func handleSerial() {
ports, err := enumerator.GetDetailedPortsList()
if err != nil {
log.Fatal(err)
}
if len(ports) == 0 {
fmt.Println("No serial ports found!")
return
}
for _, port := range ports {
fmt.Printf("Found port: %s\n", port.Name)
if port.IsUSB {
fmt.Printf(" USB ID %s:%s\n", port.VID, port.PID)
fmt.Printf(" USB serial %s\n", port.SerialNumber)
}
}
fmt.Println("")
for {
var device string = "/dev/ttyUSB0"
fmt.Println("Trying to connect to: ", device)
mode := &serial.Mode{
BaudRate: 9600,
}
port, err := serial.Open(device, mode)
if err != nil {
log.Fatal(err)
time.Sleep(time.Second * 2)
}
serialPort = port
fmt.Println("Connected to: ", device)
fmt.Println("")
reading := false
for {
data := ""
buffer := make([]byte, 512)
for {
n, err := port.Read(buffer)
if err != nil {
fmt.Printf("Error occured: %v", err.Error())
break
}
if n == 0 {
fmt.Println("\nEOF")
break
}
if strings.Contains(string(buffer[:n]), "!***!") {
reading = true
data = ""
buffer = make([]byte, 1024)
}
if !reading {
break
}
data += string(buffer[:n])
if strings.Contains(string(buffer[:n]), "\n") {
fmt.Printf("%#v\n", data)
break
}
}
if !reading {
continue
}
data = strings.ReplaceAll(data, "\x00", "")
data = strings.ReplaceAll(data, "\xb4", "")
data = strings.ReplaceAll(data, "\xc3", "")
data = strings.ReplaceAll(data, "\r\n", "")
pieces := strings.Split(data, "\xc4")
var packet Packet
packet.Id = pieces[0]
packet.Type = pieces[1]
packet.Data = pieces[2]
go handlePacket(&packet)
// fmt.Printf("%#v\n", data)
}
// var newPacket Packet
// err = json.Unmarshal([]byte(`{\"id\":\"fingerprint_init\",\"type\":""\"found\",\"data\":\"true\",\"overflow\""":false}`), &newPacket)
// if err != nil {
// fmt.Println(err)
// }
}
}
func sendPacket(pId string, pType string, pData string) {
n, err := serialPort.Write([]byte("\xb4" + pId + "\xc4" + pType + "\xc4" + pData + "\xc3\r\n"))
if err != nil {
log.Fatal(err)
}
fmt.Println("-------- Send Packet --------")
fmt.Println("ID: ", pId)
fmt.Println("Type: ", pType)
fmt.Println("Data: ", pData)
fmt.Printf("Send %v bytes\n", n)
}
func handlePacket(packet *Packet) {
fmt.Println("-------- New Packet --------")
fmt.Printf("ID: %#v\n", packet.Id)
fmt.Printf("Type: %#v\n", packet.Type)
fmt.Printf("Data: %#v\n", packet.Data)
if packet.Id == "fingerprint" {
if packet.Type == "enroll_status" {
}
if packet.Type == "auth_status" {
if packet.Data == "valid" {
isAuthenticated = true
authBtn.Disable()
loadPasswordsBtn.Enable()
addPasswordBtn.Enable()
enrollBtn.Enable()
} else {
isAuthenticated = false
}
}
}
if packet.Id == "passwords" {
if packet.Type == "available_passwords" {
if len(packet.Data) >= 1 {
passwordSelector.Options = strings.Split(packet.Data, "-")
} else {
var empty [0]string
passwordSelector.Options = empty[:]
}
loadPasswordsBtn.Disable()
}
}
}

BIN
securitas-bottom.stl Normal file

Binary file not shown.

BIN
securitas-casing.stl Normal file

Binary file not shown.

BIN
securitas-top.stl Normal file

Binary file not shown.

BIN
securitas.FCStd Normal file

Binary file not shown.

BIN
securitas.FCStd1 Normal file

Binary file not shown.

21
workspace.code-workspace Normal file
View File

@ -0,0 +1,21 @@
{
"folders": [
{
"path": "SecuritasApp"
},
{
"path": "Securitas"
}
],
"settings": {
"files.associations": {
"array": "cpp",
"string": "cpp",
"string_view": "cpp",
"ranges": "cpp",
"memory": "cpp",
"istream": "cpp",
"functional": "cpp"
}
}
}