Compare commits
14 commits
b055ec3822
...
4cd1434d0e
Author | SHA1 | Date | |
---|---|---|---|
embr | 4cd1434d0e | ||
Laura Hausmann | ac34813571 | ||
Laura Hausmann | f5d6a55b97 | ||
Laura Hausmann | 72ae2d0c75 | ||
Laura Hausmann | b10df2bc20 | ||
Laura Hausmann | da8572d76f | ||
Laura Hausmann | 83f9b57b56 | ||
Laura Hausmann | 30a69aaf00 | ||
Laura Hausmann | da50b2ab99 | ||
Laura Hausmann | 94ca5da794 | ||
Laura Hausmann | 7b487bc137 | ||
Laura Hausmann | de2a3ec163 | ||
Lilian | 40286250dc | ||
Lilian | a8de987d5b |
3593
AfRApay.MateCard/.uncrustify.cfg
Normal file
3593
AfRApay.MateCard/.uncrustify.cfg
Normal file
File diff suppressed because it is too large
Load diff
10
AfRApay.MateCard/README.md
Normal file
10
AfRApay.MateCard/README.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
# AfRApay.MateCard
|
||||
This is the software that runs on the MateCard terminal, powered by an ESP32.
|
||||
|
||||
## Setting up dev environment
|
||||
This project uses PlatformIO. Quick setup guide:
|
||||
- Install PlatformIO (macOS: `brew install platformio` / Arch Linux: `yay -S platformio` / Other: [platformio.org](https://platformio.org/install/cli))
|
||||
- To compile, run `pio run`
|
||||
- To compile and upload, run `pio run -t upload`
|
||||
- To run clang-tidy, run `pio check`.
|
||||
- Please run `uncrustify --no-backup -c .uncrustify.cfg src/*.cpp include/*.h` before commiting. To install it as a pre-commit hook, run `ln -s ../../hooks/pre-commit.hook ../.git/hooks/pre-commit` in this directory.
|
28
AfRApay.MateCard/include/cardReader.h
Normal file
28
AfRApay.MateCard/include/cardReader.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
#include <Arduino.h>
|
||||
#include <MFRC522.h>
|
||||
#include <rdm6300.h>
|
||||
|
||||
class CardReader {
|
||||
public:
|
||||
virtual bool isNewCardPresent() = 0;
|
||||
virtual String getCardUid() = 0;
|
||||
};
|
||||
|
||||
class MFRC522CardReader : public CardReader {
|
||||
private:
|
||||
MFRC522* iReader;
|
||||
public:
|
||||
explicit MFRC522CardReader(MFRC522 *reader);
|
||||
bool isNewCardPresent() override;
|
||||
String getCardUid() override;
|
||||
};
|
||||
|
||||
class RDM6300CardReader : public CardReader {
|
||||
private:
|
||||
Rdm6300* iReader;
|
||||
public:
|
||||
explicit RDM6300CardReader(Rdm6300 *reader);
|
||||
bool isNewCardPresent() override;
|
||||
String getCardUid() override;
|
||||
};
|
|
@ -1,155 +1,152 @@
|
|||
#ifndef AFRAPAY_LOGOS_H
|
||||
#define AFRAPAY_LOGOS_H
|
||||
#pragma once
|
||||
|
||||
enum e_logo {
|
||||
LOGO_AFRAPAY, LOGO_CONTACTLESS, LOGO_MATECARD, LOGO_PENDING, LOGO_SUCCESS, LOGO_FAILURE
|
||||
LOGO_AFRAPAY, LOGO_CONTACTLESS, LOGO_MATECARD, LOGO_PENDING, LOGO_SUCCESS, LOGO_FAILURE
|
||||
};
|
||||
|
||||
#define contactless_width 88
|
||||
#define contactless_height 52
|
||||
static unsigned char contactless_bits[] = {
|
||||
0x00, 0x00, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xE0, 0x07, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C,
|
||||
0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00,
|
||||
0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00,
|
||||
0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x30, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x80, 0x01,
|
||||
0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x06, 0x00, 0x00,
|
||||
0x60, 0x00, 0x00, 0x00, 0x06, 0x0F, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x20,
|
||||
0x00, 0x00, 0x00, 0x0E, 0x1E, 0xE0, 0x00, 0x18, 0x00, 0x00, 0x30, 0x00,
|
||||
0x00, 0x00, 0x1E, 0x1E, 0xB0, 0x3F, 0x10, 0x00, 0x00, 0x18, 0x00, 0x00,
|
||||
0x00, 0x1E, 0x1E, 0x10, 0xE0, 0x33, 0x00, 0x00, 0x08, 0x00, 0x00, 0x1C,
|
||||
0x3C, 0x3C, 0x18, 0x00, 0x66, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x3C, 0x3C,
|
||||
0x3C, 0x08, 0x00, 0x46, 0x00, 0x00, 0x04, 0x00, 0x00, 0x3C, 0x3C, 0x3C,
|
||||
0x08, 0x06, 0xFE, 0x01, 0x00, 0x06, 0x00, 0x30, 0x78, 0x78, 0x38, 0x88,
|
||||
0x1F, 0xFE, 0x07, 0x00, 0x02, 0x00, 0x78, 0x78, 0x78, 0x78, 0x88, 0x70,
|
||||
0x02, 0x0C, 0x00, 0x03, 0x00, 0xF0, 0x78, 0x78, 0x78, 0x8C, 0xC0, 0x03,
|
||||
0x18, 0x00, 0x03, 0x00, 0xF0, 0xF0, 0x70, 0x78, 0x84, 0x00, 0x07, 0x10,
|
||||
0x00, 0x03, 0x00, 0xE0, 0xF0, 0x70, 0x78, 0x84, 0x01, 0x0C, 0x20, 0x00,
|
||||
0x03, 0x00, 0xE0, 0xF1, 0x70, 0x78, 0x04, 0x03, 0x30, 0x60, 0x00, 0x03,
|
||||
0x00, 0xE0, 0xF1, 0x70, 0x78, 0x0C, 0x04, 0xC0, 0x40, 0x00, 0x03, 0x00,
|
||||
0xE0, 0xF1, 0x70, 0x78, 0xF8, 0x1D, 0x80, 0x81, 0x00, 0x03, 0x00, 0xE0,
|
||||
0xF1, 0x70, 0x78, 0x00, 0x3F, 0x00, 0x80, 0x01, 0x03, 0x00, 0xE0, 0xF0,
|
||||
0x70, 0x78, 0x00, 0x68, 0x00, 0x00, 0x01, 0x03, 0x00, 0xF0, 0xF0, 0x70,
|
||||
0x78, 0x00, 0xC4, 0x00, 0x00, 0x02, 0x03, 0x00, 0xF0, 0x70, 0x78, 0x78,
|
||||
0x00, 0x0C, 0x03, 0x00, 0x06, 0x02, 0x00, 0x78, 0x78, 0x78, 0x78, 0x00,
|
||||
0x18, 0x06, 0x00, 0x04, 0x06, 0x00, 0x30, 0x78, 0x78, 0x38, 0x00, 0x30,
|
||||
0x0C, 0x00, 0x08, 0x04, 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x00, 0x60, 0x18,
|
||||
0x00, 0x18, 0x0C, 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x00, 0x90, 0x31, 0x00,
|
||||
0x10, 0x0C, 0x00, 0x00, 0x1C, 0x3C, 0x3C, 0x00, 0x10, 0x3F, 0x00, 0x20,
|
||||
0x18, 0x00, 0x00, 0x00, 0x1E, 0x1E, 0x00, 0x10, 0x60, 0x00, 0x60, 0x30,
|
||||
0x00, 0x00, 0x00, 0x1E, 0x1E, 0x00, 0x60, 0x40, 0x00, 0x40, 0x30, 0x00,
|
||||
0x00, 0x00, 0x0E, 0x1E, 0x00, 0x80, 0xF3, 0x00, 0x80, 0x60, 0x00, 0x00,
|
||||
0x00, 0x06, 0x0F, 0x00, 0x00, 0x9E, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0F, 0x00, 0x00, 0x06, 0x01, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,
|
||||
0x07, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07,
|
||||
0x00, 0x80, 0x01, 0x1C, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xE0, 0x00, 0x30, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
|
||||
0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00,
|
||||
0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xE0, 0x07, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00,};
|
||||
0x00, 0x00, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xE0, 0x07, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C,
|
||||
0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00,
|
||||
0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00,
|
||||
0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x30, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x80, 0x01,
|
||||
0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x06, 0x00, 0x00,
|
||||
0x60, 0x00, 0x00, 0x00, 0x06, 0x0F, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x20,
|
||||
0x00, 0x00, 0x00, 0x0E, 0x1E, 0xE0, 0x00, 0x18, 0x00, 0x00, 0x30, 0x00,
|
||||
0x00, 0x00, 0x1E, 0x1E, 0xB0, 0x3F, 0x10, 0x00, 0x00, 0x18, 0x00, 0x00,
|
||||
0x00, 0x1E, 0x1E, 0x10, 0xE0, 0x33, 0x00, 0x00, 0x08, 0x00, 0x00, 0x1C,
|
||||
0x3C, 0x3C, 0x18, 0x00, 0x66, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x3C, 0x3C,
|
||||
0x3C, 0x08, 0x00, 0x46, 0x00, 0x00, 0x04, 0x00, 0x00, 0x3C, 0x3C, 0x3C,
|
||||
0x08, 0x06, 0xFE, 0x01, 0x00, 0x06, 0x00, 0x30, 0x78, 0x78, 0x38, 0x88,
|
||||
0x1F, 0xFE, 0x07, 0x00, 0x02, 0x00, 0x78, 0x78, 0x78, 0x78, 0x88, 0x70,
|
||||
0x02, 0x0C, 0x00, 0x03, 0x00, 0xF0, 0x78, 0x78, 0x78, 0x8C, 0xC0, 0x03,
|
||||
0x18, 0x00, 0x03, 0x00, 0xF0, 0xF0, 0x70, 0x78, 0x84, 0x00, 0x07, 0x10,
|
||||
0x00, 0x03, 0x00, 0xE0, 0xF0, 0x70, 0x78, 0x84, 0x01, 0x0C, 0x20, 0x00,
|
||||
0x03, 0x00, 0xE0, 0xF1, 0x70, 0x78, 0x04, 0x03, 0x30, 0x60, 0x00, 0x03,
|
||||
0x00, 0xE0, 0xF1, 0x70, 0x78, 0x0C, 0x04, 0xC0, 0x40, 0x00, 0x03, 0x00,
|
||||
0xE0, 0xF1, 0x70, 0x78, 0xF8, 0x1D, 0x80, 0x81, 0x00, 0x03, 0x00, 0xE0,
|
||||
0xF1, 0x70, 0x78, 0x00, 0x3F, 0x00, 0x80, 0x01, 0x03, 0x00, 0xE0, 0xF0,
|
||||
0x70, 0x78, 0x00, 0x68, 0x00, 0x00, 0x01, 0x03, 0x00, 0xF0, 0xF0, 0x70,
|
||||
0x78, 0x00, 0xC4, 0x00, 0x00, 0x02, 0x03, 0x00, 0xF0, 0x70, 0x78, 0x78,
|
||||
0x00, 0x0C, 0x03, 0x00, 0x06, 0x02, 0x00, 0x78, 0x78, 0x78, 0x78, 0x00,
|
||||
0x18, 0x06, 0x00, 0x04, 0x06, 0x00, 0x30, 0x78, 0x78, 0x38, 0x00, 0x30,
|
||||
0x0C, 0x00, 0x08, 0x04, 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x00, 0x60, 0x18,
|
||||
0x00, 0x18, 0x0C, 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x00, 0x90, 0x31, 0x00,
|
||||
0x10, 0x0C, 0x00, 0x00, 0x1C, 0x3C, 0x3C, 0x00, 0x10, 0x3F, 0x00, 0x20,
|
||||
0x18, 0x00, 0x00, 0x00, 0x1E, 0x1E, 0x00, 0x10, 0x60, 0x00, 0x60, 0x30,
|
||||
0x00, 0x00, 0x00, 0x1E, 0x1E, 0x00, 0x60, 0x40, 0x00, 0x40, 0x30, 0x00,
|
||||
0x00, 0x00, 0x0E, 0x1E, 0x00, 0x80, 0xF3, 0x00, 0x80, 0x60, 0x00, 0x00,
|
||||
0x00, 0x06, 0x0F, 0x00, 0x00, 0x9E, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0F, 0x00, 0x00, 0x06, 0x01, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,
|
||||
0x07, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07,
|
||||
0x00, 0x80, 0x01, 0x1C, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xE0, 0x00, 0x30, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
|
||||
0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00,
|
||||
0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xE0, 0x07, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00,};
|
||||
#define failure_width 40
|
||||
#define failure_height 40
|
||||
static unsigned char failure_bits[] = {
|
||||
0x00, 0x80, 0xFF, 0x01, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0xFC,
|
||||
0xFF, 0x3F, 0x00, 0x00, 0xFE, 0xFF, 0x7F, 0x00, 0x80, 0xFF, 0xFF, 0xFF,
|
||||
0x01, 0xC0, 0xFF, 0xFF, 0xFF, 0x03, 0xE0, 0xFF, 0xFF, 0xFF, 0x07, 0xF0,
|
||||
0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF,
|
||||
0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F,
|
||||
0xFE, 0x7F, 0xFF, 0xFE, 0x7F, 0xFE, 0x3F, 0x7E, 0xFC, 0x7F, 0xFE, 0x1F,
|
||||
0x3C, 0xF8, 0x7F, 0xFF, 0x0F, 0x18, 0xF0, 0xFF, 0xFF, 0x1F, 0x00, 0xF8,
|
||||
0xFF, 0xFF, 0x3F, 0x00, 0xFC, 0xFF, 0xFF, 0x7F, 0x00, 0xFE, 0xFF, 0xFF,
|
||||
0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x7F, 0x00,
|
||||
0xFE, 0xFF, 0xFF, 0x3F, 0x00, 0xFC, 0xFF, 0xFF, 0x1F, 0x00, 0xF8, 0xFF,
|
||||
0xFF, 0x0F, 0x18, 0xF0, 0xFF, 0xFE, 0x1F, 0x3C, 0xF8, 0x7F, 0xFE, 0x3F,
|
||||
0x7E, 0xFC, 0x7F, 0xFE, 0x7F, 0xFF, 0xFE, 0x7F, 0xFC, 0xFF, 0xFF, 0xFF,
|
||||
0x3F, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF0,
|
||||
0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF,
|
||||
0xFF, 0x07, 0xC0, 0xFF, 0xFF, 0xFF, 0x03, 0x80, 0xFF, 0xFF, 0xFF, 0x01,
|
||||
0x00, 0xFE, 0xFF, 0x7F, 0x00, 0x00, 0xFC, 0xFF, 0x3F, 0x00, 0x00, 0xF0,
|
||||
0xFF, 0x0F, 0x00, 0x00, 0x80, 0xFF, 0x01, 0x00,};
|
||||
0x00, 0x80, 0xFF, 0x01, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0xFC,
|
||||
0xFF, 0x3F, 0x00, 0x00, 0xFE, 0xFF, 0x7F, 0x00, 0x80, 0xFF, 0xFF, 0xFF,
|
||||
0x01, 0xC0, 0xFF, 0xFF, 0xFF, 0x03, 0xE0, 0xFF, 0xFF, 0xFF, 0x07, 0xF0,
|
||||
0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF,
|
||||
0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F,
|
||||
0xFE, 0x7F, 0xFF, 0xFE, 0x7F, 0xFE, 0x3F, 0x7E, 0xFC, 0x7F, 0xFE, 0x1F,
|
||||
0x3C, 0xF8, 0x7F, 0xFF, 0x0F, 0x18, 0xF0, 0xFF, 0xFF, 0x1F, 0x00, 0xF8,
|
||||
0xFF, 0xFF, 0x3F, 0x00, 0xFC, 0xFF, 0xFF, 0x7F, 0x00, 0xFE, 0xFF, 0xFF,
|
||||
0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x7F, 0x00,
|
||||
0xFE, 0xFF, 0xFF, 0x3F, 0x00, 0xFC, 0xFF, 0xFF, 0x1F, 0x00, 0xF8, 0xFF,
|
||||
0xFF, 0x0F, 0x18, 0xF0, 0xFF, 0xFE, 0x1F, 0x3C, 0xF8, 0x7F, 0xFE, 0x3F,
|
||||
0x7E, 0xFC, 0x7F, 0xFE, 0x7F, 0xFF, 0xFE, 0x7F, 0xFC, 0xFF, 0xFF, 0xFF,
|
||||
0x3F, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF0,
|
||||
0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF,
|
||||
0xFF, 0x07, 0xC0, 0xFF, 0xFF, 0xFF, 0x03, 0x80, 0xFF, 0xFF, 0xFF, 0x01,
|
||||
0x00, 0xFE, 0xFF, 0x7F, 0x00, 0x00, 0xFC, 0xFF, 0x3F, 0x00, 0x00, 0xF0,
|
||||
0xFF, 0x0F, 0x00, 0x00, 0x80, 0xFF, 0x01, 0x00,};
|
||||
#define pending_width 40
|
||||
#define pending_height 40
|
||||
static unsigned char pending_bits[] = {
|
||||
0x00, 0x80, 0xFF, 0x01, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0xFC,
|
||||
0xFF, 0x3F, 0x00, 0x00, 0xFE, 0xFF, 0x7F, 0x00, 0x80, 0xFF, 0xFF, 0xFF,
|
||||
0x01, 0xC0, 0xFF, 0xFF, 0xFF, 0x03, 0xE0, 0xFF, 0xFF, 0xFF, 0x07, 0xF0,
|
||||
0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF,
|
||||
0xFF, 0x1F, 0xFC, 0xFF, 0xE3, 0xFF, 0x3F, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F,
|
||||
0xFE, 0xFF, 0xC3, 0xFF, 0x7F, 0xFE, 0xFF, 0xC3, 0xFF, 0x7F, 0xFE, 0xFF,
|
||||
0xC3, 0xFF, 0x7F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0x03,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0xF0, 0xFF,
|
||||
0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFE, 0xFF, 0x3F, 0xE0, 0x7F, 0xFE, 0xFF,
|
||||
0x7F, 0xF0, 0x7F, 0xFE, 0xFF, 0xFF, 0xF1, 0x7F, 0xFC, 0xFF, 0xFF, 0xFF,
|
||||
0x3F, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF0,
|
||||
0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF,
|
||||
0xFF, 0x07, 0xC0, 0xFF, 0xFF, 0xFF, 0x03, 0x80, 0xFF, 0xFF, 0xFF, 0x01,
|
||||
0x00, 0xFE, 0xFF, 0x7F, 0x00, 0x00, 0xFC, 0xFF, 0x3F, 0x00, 0x00, 0xF0,
|
||||
0xFF, 0x0F, 0x00, 0x00, 0x80, 0xFF, 0x01, 0x00,};
|
||||
0x00, 0x80, 0xFF, 0x01, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0xFC,
|
||||
0xFF, 0x3F, 0x00, 0x00, 0xFE, 0xFF, 0x7F, 0x00, 0x80, 0xFF, 0xFF, 0xFF,
|
||||
0x01, 0xC0, 0xFF, 0xFF, 0xFF, 0x03, 0xE0, 0xFF, 0xFF, 0xFF, 0x07, 0xF0,
|
||||
0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF,
|
||||
0xFF, 0x1F, 0xFC, 0xFF, 0xE3, 0xFF, 0x3F, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F,
|
||||
0xFE, 0xFF, 0xC3, 0xFF, 0x7F, 0xFE, 0xFF, 0xC3, 0xFF, 0x7F, 0xFE, 0xFF,
|
||||
0xC3, 0xFF, 0x7F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0x03,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0xF0, 0xFF,
|
||||
0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFE, 0xFF, 0x3F, 0xE0, 0x7F, 0xFE, 0xFF,
|
||||
0x7F, 0xF0, 0x7F, 0xFE, 0xFF, 0xFF, 0xF1, 0x7F, 0xFC, 0xFF, 0xFF, 0xFF,
|
||||
0x3F, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF0,
|
||||
0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF,
|
||||
0xFF, 0x07, 0xC0, 0xFF, 0xFF, 0xFF, 0x03, 0x80, 0xFF, 0xFF, 0xFF, 0x01,
|
||||
0x00, 0xFE, 0xFF, 0x7F, 0x00, 0x00, 0xFC, 0xFF, 0x3F, 0x00, 0x00, 0xF0,
|
||||
0xFF, 0x0F, 0x00, 0x00, 0x80, 0xFF, 0x01, 0x00,};
|
||||
#define success_width 40
|
||||
#define success_height 40
|
||||
static unsigned char success_bits[] = {
|
||||
0x00, 0x80, 0xFF, 0x01, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0xFC,
|
||||
0xFF, 0x3F, 0x00, 0x00, 0xFE, 0xFF, 0x7F, 0x00, 0x80, 0xFF, 0xFF, 0xFF,
|
||||
0x01, 0xC0, 0xFF, 0xFF, 0xFF, 0x03, 0xE0, 0xFF, 0xFF, 0xFF, 0x07, 0xF0,
|
||||
0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF,
|
||||
0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F,
|
||||
0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0xF3, 0x7F, 0xFE, 0xFF,
|
||||
0xFF, 0xE0, 0x7F, 0xFF, 0xFF, 0x7F, 0xE0, 0xFF, 0xFF, 0xFF, 0x3F, 0xE0,
|
||||
0xFF, 0xFF, 0xFF, 0x3F, 0xF0, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF,
|
||||
0x8F, 0x0F, 0xFC, 0xFF, 0xFF, 0x07, 0x07, 0xFE, 0xFF, 0xFF, 0x07, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0x0F, 0x80, 0xFF, 0xFF, 0xFF, 0x1F, 0xC0, 0xFF, 0xFF,
|
||||
0xFF, 0x3F, 0xE0, 0xFF, 0xFF, 0xFE, 0x7F, 0xF0, 0xFF, 0x7F, 0xFE, 0xFF,
|
||||
0xF8, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0xFF,
|
||||
0x3F, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF0,
|
||||
0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF,
|
||||
0xFF, 0x07, 0xC0, 0xFF, 0xFF, 0xFF, 0x03, 0x80, 0xFF, 0xFF, 0xFF, 0x01,
|
||||
0x00, 0xFE, 0xFF, 0x7F, 0x00, 0x00, 0xFC, 0xFF, 0x3F, 0x00, 0x00, 0xF0,
|
||||
0xFF, 0x0F, 0x00, 0x00, 0x80, 0xFF, 0x01, 0x00,};
|
||||
0x00, 0x80, 0xFF, 0x01, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0xFC,
|
||||
0xFF, 0x3F, 0x00, 0x00, 0xFE, 0xFF, 0x7F, 0x00, 0x80, 0xFF, 0xFF, 0xFF,
|
||||
0x01, 0xC0, 0xFF, 0xFF, 0xFF, 0x03, 0xE0, 0xFF, 0xFF, 0xFF, 0x07, 0xF0,
|
||||
0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF,
|
||||
0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F,
|
||||
0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0xF3, 0x7F, 0xFE, 0xFF,
|
||||
0xFF, 0xE0, 0x7F, 0xFF, 0xFF, 0x7F, 0xE0, 0xFF, 0xFF, 0xFF, 0x3F, 0xE0,
|
||||
0xFF, 0xFF, 0xFF, 0x3F, 0xF0, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF,
|
||||
0x8F, 0x0F, 0xFC, 0xFF, 0xFF, 0x07, 0x07, 0xFE, 0xFF, 0xFF, 0x07, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0x0F, 0x80, 0xFF, 0xFF, 0xFF, 0x1F, 0xC0, 0xFF, 0xFF,
|
||||
0xFF, 0x3F, 0xE0, 0xFF, 0xFF, 0xFE, 0x7F, 0xF0, 0xFF, 0x7F, 0xFE, 0xFF,
|
||||
0xF8, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0xFF,
|
||||
0x3F, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF0,
|
||||
0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF,
|
||||
0xFF, 0x07, 0xC0, 0xFF, 0xFF, 0xFF, 0x03, 0x80, 0xFF, 0xFF, 0xFF, 0x01,
|
||||
0x00, 0xFE, 0xFF, 0x7F, 0x00, 0x00, 0xFC, 0xFF, 0x3F, 0x00, 0x00, 0xF0,
|
||||
0xFF, 0x0F, 0x00, 0x00, 0x80, 0xFF, 0x01, 0x00,};
|
||||
|
||||
#define matecard_width 65
|
||||
#define matecard_height 40
|
||||
static unsigned char matecard_bits[] = {
|
||||
0x00, 0x80, 0xBE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xEB,
|
||||
0x0F, 0x00, 0x55, 0x05, 0x00, 0x00, 0x00, 0xB8, 0x5E, 0x1B, 0x20, 0x88,
|
||||
0x10, 0x00, 0x00, 0x00, 0xEE, 0xF7, 0xF6, 0x90, 0x22, 0x44, 0x00, 0x00,
|
||||
0x00, 0xBB, 0xDA, 0xAF, 0x4A, 0x94, 0x12, 0x01, 0x00, 0x80, 0xDF, 0xFF,
|
||||
0xFA, 0x12, 0x42, 0x44, 0x00, 0x00, 0xE0, 0x7A, 0x55, 0x57, 0x45, 0x09,
|
||||
0x91, 0x02, 0x00, 0xA0, 0xAF, 0xFF, 0xBD, 0x2A, 0xA2, 0x24, 0x08, 0x00,
|
||||
0xF0, 0xFA, 0xAA, 0x57, 0x95, 0x08, 0x92, 0x02, 0x00, 0x78, 0x5F, 0xFF,
|
||||
0xAD, 0x2A, 0xA4, 0x44, 0x14, 0x00, 0xA8, 0xF5, 0x55, 0x57, 0x95, 0x12,
|
||||
0x11, 0x21, 0x00, 0xFC, 0xBF, 0xFE, 0xAB, 0xAA, 0x40, 0x88, 0x08, 0x00,
|
||||
0x54, 0xD5, 0xAB, 0x56, 0x55, 0x8A, 0x22, 0x25, 0x00, 0xFE, 0xFF, 0xFD,
|
||||
0xAB, 0x2A, 0x51, 0x48, 0x48, 0x00, 0xAA, 0xAA, 0x56, 0xD5, 0x56, 0x82,
|
||||
0x12, 0x21, 0x00, 0xFE, 0xFF, 0xFF, 0xAB, 0xAA, 0x54, 0x44, 0x8A, 0x00,
|
||||
0x55, 0x55, 0x55, 0x55, 0xB5, 0x80, 0x88, 0x10, 0x00, 0xFE, 0xFF, 0xFF,
|
||||
0xAD, 0xAA, 0x2A, 0x52, 0xA4, 0x00, 0xAB, 0xAA, 0xAA, 0x55, 0x55, 0x44,
|
||||
0x81, 0x12, 0x01, 0xFE, 0xFF, 0x7F, 0xAB, 0xAA, 0x22, 0x28, 0x44, 0x00,
|
||||
0xAB, 0xAA, 0xEA, 0x6A, 0x55, 0x49, 0x45, 0x11, 0x01, 0xFD, 0xFF, 0xBF,
|
||||
0xAB, 0xAA, 0x10, 0x20, 0x44, 0x00, 0x57, 0x55, 0xF5, 0xAA, 0x6D, 0xA5,
|
||||
0x8A, 0x28, 0x01, 0xFA, 0xFF, 0xAF, 0x55, 0x95, 0x08, 0x21, 0x05, 0x00,
|
||||
0xAE, 0xAA, 0x7E, 0xAB, 0x6A, 0x22, 0x4A, 0xA8, 0x00, 0xF6, 0xFF, 0xD5,
|
||||
0x56, 0x55, 0x91, 0x10, 0x05, 0x00, 0x5A, 0x55, 0xFF, 0x55, 0x55, 0x44,
|
||||
0x22, 0xA8, 0x00, 0xFC, 0xFF, 0x57, 0xAF, 0x2A, 0x29, 0x49, 0x05, 0x00,
|
||||
0x54, 0x55, 0xFD, 0x6A, 0x55, 0x84, 0x04, 0x28, 0x00, 0xF8, 0xFF, 0x57,
|
||||
0xAF, 0xAA, 0x22, 0x51, 0x05, 0x00, 0xA8, 0xAA, 0xFE, 0x55, 0x15, 0x88,
|
||||
0x84, 0x10, 0x00, 0xF0, 0xFF, 0xAB, 0xBE, 0x96, 0x52, 0x28, 0x0A, 0x00,
|
||||
0xA0, 0xAA, 0xFE, 0xAB, 0x4A, 0x04, 0x41, 0x00, 0x00, 0xC0, 0xFF, 0x57,
|
||||
0xDD, 0x12, 0xA2, 0x94, 0x0A, 0x00, 0x80, 0xAA, 0xFE, 0x77, 0x45, 0x09,
|
||||
0x21, 0x00, 0x00, 0x00, 0xFF, 0xAB, 0xBA, 0x21, 0x50, 0x8A, 0x02, 0x00,
|
||||
0x00, 0xAA, 0xFE, 0x6F, 0x94, 0x82, 0x10, 0x00, 0x00, 0x00, 0xF8, 0xAB,
|
||||
0x1A, 0x80, 0x28, 0x4A, 0x00, 0x00, 0x00, 0x40, 0xFF, 0x0B, 0x20, 0xA2,
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0xAA, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
|
||||
0x00, 0x80, 0xBE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xEB,
|
||||
0x0F, 0x00, 0x55, 0x05, 0x00, 0x00, 0x00, 0xB8, 0x5E, 0x1B, 0x20, 0x88,
|
||||
0x10, 0x00, 0x00, 0x00, 0xEE, 0xF7, 0xF6, 0x90, 0x22, 0x44, 0x00, 0x00,
|
||||
0x00, 0xBB, 0xDA, 0xAF, 0x4A, 0x94, 0x12, 0x01, 0x00, 0x80, 0xDF, 0xFF,
|
||||
0xFA, 0x12, 0x42, 0x44, 0x00, 0x00, 0xE0, 0x7A, 0x55, 0x57, 0x45, 0x09,
|
||||
0x91, 0x02, 0x00, 0xA0, 0xAF, 0xFF, 0xBD, 0x2A, 0xA2, 0x24, 0x08, 0x00,
|
||||
0xF0, 0xFA, 0xAA, 0x57, 0x95, 0x08, 0x92, 0x02, 0x00, 0x78, 0x5F, 0xFF,
|
||||
0xAD, 0x2A, 0xA4, 0x44, 0x14, 0x00, 0xA8, 0xF5, 0x55, 0x57, 0x95, 0x12,
|
||||
0x11, 0x21, 0x00, 0xFC, 0xBF, 0xFE, 0xAB, 0xAA, 0x40, 0x88, 0x08, 0x00,
|
||||
0x54, 0xD5, 0xAB, 0x56, 0x55, 0x8A, 0x22, 0x25, 0x00, 0xFE, 0xFF, 0xFD,
|
||||
0xAB, 0x2A, 0x51, 0x48, 0x48, 0x00, 0xAA, 0xAA, 0x56, 0xD5, 0x56, 0x82,
|
||||
0x12, 0x21, 0x00, 0xFE, 0xFF, 0xFF, 0xAB, 0xAA, 0x54, 0x44, 0x8A, 0x00,
|
||||
0x55, 0x55, 0x55, 0x55, 0xB5, 0x80, 0x88, 0x10, 0x00, 0xFE, 0xFF, 0xFF,
|
||||
0xAD, 0xAA, 0x2A, 0x52, 0xA4, 0x00, 0xAB, 0xAA, 0xAA, 0x55, 0x55, 0x44,
|
||||
0x81, 0x12, 0x01, 0xFE, 0xFF, 0x7F, 0xAB, 0xAA, 0x22, 0x28, 0x44, 0x00,
|
||||
0xAB, 0xAA, 0xEA, 0x6A, 0x55, 0x49, 0x45, 0x11, 0x01, 0xFD, 0xFF, 0xBF,
|
||||
0xAB, 0xAA, 0x10, 0x20, 0x44, 0x00, 0x57, 0x55, 0xF5, 0xAA, 0x6D, 0xA5,
|
||||
0x8A, 0x28, 0x01, 0xFA, 0xFF, 0xAF, 0x55, 0x95, 0x08, 0x21, 0x05, 0x00,
|
||||
0xAE, 0xAA, 0x7E, 0xAB, 0x6A, 0x22, 0x4A, 0xA8, 0x00, 0xF6, 0xFF, 0xD5,
|
||||
0x56, 0x55, 0x91, 0x10, 0x05, 0x00, 0x5A, 0x55, 0xFF, 0x55, 0x55, 0x44,
|
||||
0x22, 0xA8, 0x00, 0xFC, 0xFF, 0x57, 0xAF, 0x2A, 0x29, 0x49, 0x05, 0x00,
|
||||
0x54, 0x55, 0xFD, 0x6A, 0x55, 0x84, 0x04, 0x28, 0x00, 0xF8, 0xFF, 0x57,
|
||||
0xAF, 0xAA, 0x22, 0x51, 0x05, 0x00, 0xA8, 0xAA, 0xFE, 0x55, 0x15, 0x88,
|
||||
0x84, 0x10, 0x00, 0xF0, 0xFF, 0xAB, 0xBE, 0x96, 0x52, 0x28, 0x0A, 0x00,
|
||||
0xA0, 0xAA, 0xFE, 0xAB, 0x4A, 0x04, 0x41, 0x00, 0x00, 0xC0, 0xFF, 0x57,
|
||||
0xDD, 0x12, 0xA2, 0x94, 0x0A, 0x00, 0x80, 0xAA, 0xFE, 0x77, 0x45, 0x09,
|
||||
0x21, 0x00, 0x00, 0x00, 0xFF, 0xAB, 0xBA, 0x21, 0x50, 0x8A, 0x02, 0x00,
|
||||
0x00, 0xAA, 0xFE, 0x6F, 0x94, 0x82, 0x10, 0x00, 0x00, 0x00, 0xF8, 0xAB,
|
||||
0x1A, 0x80, 0x28, 0x4A, 0x00, 0x00, 0x00, 0x40, 0xFF, 0x0B, 0x20, 0xA2,
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0xAA, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,15 +1,11 @@
|
|||
#pragma once
|
||||
#include "Arduino.h"
|
||||
#include <U8g2lib.h>
|
||||
#include "logos.h"
|
||||
#include "utils.h"
|
||||
|
||||
#ifndef AFRAPAY_OLED_H
|
||||
#define AFRAPAY_OLED_H
|
||||
|
||||
void drawLogo(U8G2 u8g2, e_logo logo);
|
||||
void drawStatusText(U8G2 u8g2, String status, String statusRightAligned = "");
|
||||
|
||||
void updateOLED(U8G2 u8g2, e_state state, String statusText, String statusTextRightAligned = "");
|
||||
void updateOLED(U8G2 u8g2, e_state state);
|
||||
|
||||
#endif
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef AFRAPAY_PITCHES_H
|
||||
#define AFRAPAY_PITCHES_H
|
||||
#pragma once
|
||||
|
||||
#define NOTE_NONE 0
|
||||
#define NOTE_B0 31
|
||||
|
@ -91,5 +90,3 @@
|
|||
#define NOTE_CS8 4435
|
||||
#define NOTE_D8 4699
|
||||
#define NOTE_DS8 4978
|
||||
|
||||
#endif
|
|
@ -1,26 +1,24 @@
|
|||
#pragma once
|
||||
#include <Arduino.h>
|
||||
#include <HTTPClient.h>
|
||||
|
||||
#ifndef AFRAPAY_UTILS_H
|
||||
#define AFRAPAY_UTILS_H
|
||||
unsigned long cooldownSecondsRemaining(unsigned long timeout, unsigned long timer);
|
||||
String byteArrayAsHexString(byte *buffer, byte bufferSize);
|
||||
String uint32AsHexString(uint32_t input);
|
||||
String cardLink(WiFiClient* wifi, HTTPClient* http, String apiUrl, String cardId);
|
||||
String cardBalance(WiFiClient* wifi, HTTPClient* http, String apiUrl, String cardId);
|
||||
String cardTransaction(WiFiClient* wifi, HTTPClient* http, String apiUrl, String cardId, String amount);
|
||||
String splitString(String data, char separator, int index);
|
||||
|
||||
enum e_state {
|
||||
STATE_IDLE,
|
||||
STATE_TRANSACT_CARDSCAN,
|
||||
STATE_TRANSACT_VERIFY,
|
||||
STATE_LINK_CARDSCAN,
|
||||
STATE_LINK_VERIFY,
|
||||
STATE_BALANCE_CARDSCAN,
|
||||
STATE_BALANCE_VERIFY,
|
||||
STATE_RESULT_SUCCESS,
|
||||
STATE_RESULT_FAILURE,
|
||||
STATE_RESULT_DISPLAY,
|
||||
STATE_IDLE,
|
||||
STATE_TRANSACT_CARDSCAN,
|
||||
STATE_TRANSACT_VERIFY,
|
||||
STATE_LINK_CARDSCAN,
|
||||
STATE_LINK_VERIFY,
|
||||
STATE_BALANCE_CARDSCAN,
|
||||
STATE_BALANCE_VERIFY,
|
||||
STATE_RESULT_SUCCESS,
|
||||
STATE_RESULT_FAILURE,
|
||||
STATE_RESULT_DISPLAY,
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,9 +1,6 @@
|
|||
#ifndef AFRAPAY_WIFIFIX_H
|
||||
#define AFRAPAY_WIFIFIX_H
|
||||
#pragma once
|
||||
|
||||
class WiFiClientFixed : public WiFiClient {
|
||||
public:
|
||||
void flush() override;
|
||||
void flush() override;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -20,3 +20,7 @@ lib_deps =
|
|||
miguelbalboa/MFRC522@^1.4.10
|
||||
arduino-libraries/NTPClient@^3.2.1
|
||||
mcxiaoke/ESPDateTime@^1.0.4
|
||||
arduino12/rdm6300@^2.0.0
|
||||
check_tool = clangtidy
|
||||
check_flags =
|
||||
clangtidy: --checks=*,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers,-modernize-macro-to-enum
|
||||
|
|
32
AfRApay.MateCard/src/cardReader.cpp
Normal file
32
AfRApay.MateCard/src/cardReader.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
#include <Arduino.h>
|
||||
#include <MFRC522.h>
|
||||
#include <rdm6300.h>
|
||||
#include "utils.h"
|
||||
#include "cardReader.h"
|
||||
|
||||
MFRC522CardReader::MFRC522CardReader(MFRC522 *reader) {
|
||||
iReader = reader;
|
||||
}
|
||||
|
||||
bool MFRC522CardReader::isNewCardPresent() {
|
||||
return iReader->PICC_IsNewCardPresent() && iReader->PICC_ReadCardSerial();
|
||||
}
|
||||
|
||||
String MFRC522CardReader::getCardUid() {
|
||||
return byteArrayAsHexString(iReader->uid.uidByte, iReader->uid.size);
|
||||
}
|
||||
|
||||
RDM6300CardReader::RDM6300CardReader(Rdm6300 *reader) {
|
||||
iReader = reader;
|
||||
}
|
||||
|
||||
bool RDM6300CardReader::isNewCardPresent() {
|
||||
return iReader->get_new_tag_id();
|
||||
}
|
||||
|
||||
String RDM6300CardReader::getCardUid() {
|
||||
auto uid = iReader->get_tag_id();
|
||||
char buf[16];
|
||||
sprintf(buf, "%010u", uid);
|
||||
return {buf};
|
||||
}
|
|
@ -9,24 +9,44 @@
|
|||
#include <MFRC522.h>
|
||||
#include <ESPDateTime.h>
|
||||
#include <DateTimeTZ.h>
|
||||
#include <rdm6300.h>
|
||||
|
||||
#include "wifiFix.h"
|
||||
#include "pitches.h"
|
||||
#include "utils.h"
|
||||
#include "oled.h"
|
||||
#include "cardReader.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma ide diagnostic ignored "OCUnusedMacroInspection"
|
||||
|
||||
//MFRC522 pinout (front) 3V3 RST GND IRQ MISO MOSI SCK SDA
|
||||
//MFRC522 pinout (rear) SDA SCK MOSI MISO IRQ GND RST 3V3
|
||||
|
||||
#define HSPI_RST 4
|
||||
#define HSPI_MISO 12
|
||||
#define HSPI_MOSI 13
|
||||
#define HSPI_SCLK 14
|
||||
#define HSPI_SS 15
|
||||
#define HSPI_RST 16
|
||||
|
||||
#define BUZZER_PIN 26
|
||||
#define PIN_HWSERIAL_RX 16
|
||||
#define PIN_HWSERIAL_TX 17
|
||||
#define PIN_BUZZER 19
|
||||
#define PIN_OLED_SDA 21
|
||||
#define PIN_OLED_SCL 22
|
||||
#define PIN_INTERRUPT_TRANSACT 26
|
||||
#define PIN_INTERRUPT_BALANCE 25
|
||||
#define PIN_INTERRUPT_LINK 33
|
||||
#define PIN_INTERRUPT_CANCEL 32
|
||||
|
||||
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
|
||||
MFRC522 mfrc522(HSPI_SS, HSPI_RST);
|
||||
WiFiClient *wifi = new WiFiClientFixed();
|
||||
HTTPClient *http = new HTTPClient();
|
||||
Rdm6300 rdm6300;
|
||||
|
||||
auto mfrc522reader = MFRC522CardReader(&mfrc522);
|
||||
auto rdm6300reader = RDM6300CardReader(&rdm6300);
|
||||
CardReader* readers[2] = {&mfrc522reader, &rdm6300reader};
|
||||
|
||||
e_state state = STATE_IDLE;
|
||||
String apiUrl = "";
|
||||
|
@ -36,179 +56,190 @@ const int scanTimeout = 15000;
|
|||
String scannedCardId = "";
|
||||
String lastStatusText = "";
|
||||
|
||||
bool interruptFired = false;
|
||||
unsigned long timer = 0;
|
||||
|
||||
void IRAM_ATTR TransactInterruptHandler() {
|
||||
if (state != STATE_IDLE) {
|
||||
return;
|
||||
}
|
||||
timer = millis();
|
||||
state = STATE_TRANSACT_CARDSCAN;
|
||||
if (interruptFired || state != STATE_IDLE) {
|
||||
return;
|
||||
}
|
||||
interruptFired = true;
|
||||
state = STATE_TRANSACT_CARDSCAN;
|
||||
}
|
||||
|
||||
void IRAM_ATTR LinkInterruptHandler() {
|
||||
if (state != STATE_IDLE) {
|
||||
return;
|
||||
}
|
||||
timer = millis();
|
||||
state = STATE_LINK_CARDSCAN;
|
||||
if (interruptFired || state != STATE_IDLE) {
|
||||
return;
|
||||
}
|
||||
interruptFired = true;
|
||||
state = STATE_LINK_CARDSCAN;
|
||||
}
|
||||
|
||||
void IRAM_ATTR BalanceInterruptHandler() {
|
||||
if (state != STATE_IDLE) {
|
||||
return;
|
||||
}
|
||||
timer = millis();
|
||||
state = STATE_BALANCE_CARDSCAN;
|
||||
if (interruptFired || state != STATE_IDLE) {
|
||||
return;
|
||||
}
|
||||
interruptFired = true;
|
||||
state = STATE_BALANCE_CARDSCAN;
|
||||
}
|
||||
|
||||
bool cooldownCheck(long timeout) {
|
||||
if (millis() - timer > timeout) {
|
||||
state = STATE_IDLE;
|
||||
updateOLED(u8g2, state);
|
||||
return true;
|
||||
}
|
||||
if (millis() - timer > timeout) {
|
||||
state = STATE_IDLE;
|
||||
updateOLED(u8g2, state);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
u8g2.begin();
|
||||
drawLogo(u8g2, LOGO_MATECARD);
|
||||
u8g2.sendBuffer();
|
||||
SPI.begin(HSPI_SCLK, HSPI_MISO, HSPI_MOSI);
|
||||
SPIFFS.begin(true);
|
||||
WiFiSettings.hostname = "afrapay-";
|
||||
apiUrl = WiFiSettings.string("AfRApay.Web API", "http://192.168.50.170:5296");
|
||||
WiFiSettings.connect();
|
||||
mfrc522.PCD_Init();
|
||||
DateTime.setTimeZone(TZ_Europe_Berlin);
|
||||
DateTime.begin();
|
||||
updateOLED(u8g2, state);
|
||||
Serial.begin(115200);
|
||||
Serial2.begin(115200, SERIAL_8N1, PIN_HWSERIAL_RX, PIN_HWSERIAL_TX);
|
||||
u8g2.begin();
|
||||
drawLogo(u8g2, LOGO_MATECARD);
|
||||
u8g2.sendBuffer();
|
||||
SPI.begin(HSPI_SCLK, HSPI_MISO, HSPI_MOSI);
|
||||
SPIFFS.begin(true);
|
||||
WiFiSettings.hostname = "afrapay-";
|
||||
apiUrl = WiFiSettings.string("AfRApay.Web API", "http://192.168.50.170:5296");
|
||||
WiFiSettings.connect();
|
||||
rdm6300.begin(PIN_HWSERIAL_RX);
|
||||
mfrc522.PCD_Init();
|
||||
mfrc522.PCD_DumpVersionToSerial();
|
||||
DateTime.setTimeZone(TZ_Europe_Berlin);
|
||||
DateTime.begin();
|
||||
updateOLED(u8g2, state);
|
||||
|
||||
ledcSetup(0, 5000, 12);
|
||||
pinMode(25, INPUT_PULLUP);
|
||||
pinMode(32, INPUT_PULLUP);
|
||||
pinMode(33, INPUT_PULLUP);
|
||||
attachInterrupt(25, BalanceInterruptHandler, FALLING);
|
||||
attachInterrupt(32, LinkInterruptHandler, FALLING);
|
||||
attachInterrupt(33, TransactInterruptHandler, FALLING);
|
||||
ledcSetup(0, 5000, 12);
|
||||
pinMode(PIN_INTERRUPT_TRANSACT, INPUT_PULLUP);
|
||||
pinMode(PIN_INTERRUPT_BALANCE, INPUT_PULLUP);
|
||||
pinMode(PIN_INTERRUPT_CANCEL, INPUT_PULLUP);
|
||||
pinMode(PIN_INTERRUPT_LINK, INPUT_PULLUP);
|
||||
attachInterrupt(PIN_INTERRUPT_TRANSACT, TransactInterruptHandler, FALLING);
|
||||
attachInterrupt(PIN_INTERRUPT_BALANCE, BalanceInterruptHandler, FALLING);
|
||||
attachInterrupt(PIN_INTERRUPT_LINK, LinkInterruptHandler, FALLING);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
updateOLED(u8g2, state, "WiFi disconnected :(");
|
||||
state = STATE_IDLE;
|
||||
WiFi.reconnect();
|
||||
delay(50);
|
||||
return;
|
||||
}
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
updateOLED(u8g2, state, "WiFi disconnected :(");
|
||||
state = STATE_IDLE;
|
||||
WiFi.reconnect();
|
||||
delay(50);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case STATE_IDLE:
|
||||
updateOLED(u8g2, state);
|
||||
break;
|
||||
case STATE_TRANSACT_CARDSCAN:
|
||||
if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
|
||||
scannedCardId = byteArrayAsHexString(mfrc522.uid.uidByte, mfrc522.uid.size);
|
||||
mfrc522.PICC_HaltA();
|
||||
lastStatusText = "Card #" + scannedCardId;
|
||||
state = STATE_TRANSACT_VERIFY;
|
||||
return;
|
||||
} else {
|
||||
if (!cooldownCheck(scanTimeout)) {
|
||||
updateOLED(u8g2, state, String("1.50€"), String(cooldownSecondsRemaining(scanTimeout, timer)));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STATE_TRANSACT_VERIFY:
|
||||
updateOLED(u8g2, state, lastStatusText);
|
||||
tone(BUZZER_PIN, NOTE_A5, 25);
|
||||
tone(BUZZER_PIN, NOTE_NONE, 150);
|
||||
lastStatusText = cardTransaction(wifi, http, apiUrl, scannedCardId, "1.50");
|
||||
if (lastStatusText.startsWith("S:")) {
|
||||
tone(BUZZER_PIN, NOTE_C7, 650);
|
||||
lastStatusText += "€";
|
||||
state = STATE_RESULT_SUCCESS;
|
||||
} else {
|
||||
tone(BUZZER_PIN, NOTE_CS5, 100);
|
||||
tone(BUZZER_PIN, NOTE_NONE, 25);
|
||||
tone(BUZZER_PIN, NOTE_CS5, 400);
|
||||
state = STATE_RESULT_FAILURE;
|
||||
}
|
||||
lastStatusText = lastStatusText.substring(2);
|
||||
timer = millis();
|
||||
return;
|
||||
case STATE_LINK_CARDSCAN:
|
||||
if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
|
||||
scannedCardId = byteArrayAsHexString(mfrc522.uid.uidByte, mfrc522.uid.size);
|
||||
mfrc522.PICC_HaltA();
|
||||
lastStatusText = "Card #" + scannedCardId;
|
||||
state = STATE_LINK_VERIFY;
|
||||
return;
|
||||
} else {
|
||||
if (!cooldownCheck(scanTimeout)) {
|
||||
updateOLED(u8g2, state, "Link", String(cooldownSecondsRemaining(scanTimeout, timer)));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STATE_LINK_VERIFY:
|
||||
updateOLED(u8g2, state, lastStatusText);
|
||||
tone(BUZZER_PIN, NOTE_A5, 25);
|
||||
tone(BUZZER_PIN, NOTE_NONE, 150);
|
||||
lastStatusText = cardLink(wifi, http, apiUrl, scannedCardId);
|
||||
if (lastStatusText.startsWith("S:")) {
|
||||
tone(BUZZER_PIN, NOTE_C6, 100);
|
||||
tone(BUZZER_PIN, NOTE_NONE, 10);
|
||||
tone(BUZZER_PIN, NOTE_C6, 100);
|
||||
state = STATE_RESULT_SUCCESS;
|
||||
} else {
|
||||
tone(BUZZER_PIN, NOTE_CS5, 100);
|
||||
tone(BUZZER_PIN, NOTE_NONE, 25);
|
||||
tone(BUZZER_PIN, NOTE_CS5, 400);
|
||||
state = STATE_RESULT_FAILURE;
|
||||
}
|
||||
lastStatusText = lastStatusText.substring(2);
|
||||
timer = millis();
|
||||
return;
|
||||
case STATE_BALANCE_CARDSCAN:
|
||||
if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
|
||||
scannedCardId = byteArrayAsHexString(mfrc522.uid.uidByte, mfrc522.uid.size);
|
||||
mfrc522.PICC_HaltA();
|
||||
lastStatusText = "Card #" + scannedCardId;
|
||||
state = STATE_BALANCE_VERIFY;
|
||||
return;
|
||||
} else {
|
||||
if (!cooldownCheck(scanTimeout)) {
|
||||
updateOLED(u8g2, state, "Balance", String(cooldownSecondsRemaining(scanTimeout, timer)));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STATE_BALANCE_VERIFY:
|
||||
updateOLED(u8g2, state, lastStatusText);
|
||||
tone(BUZZER_PIN, NOTE_A5, 25);
|
||||
tone(BUZZER_PIN, NOTE_NONE, 150);
|
||||
lastStatusText = cardBalance(wifi, http, apiUrl, scannedCardId);
|
||||
if (lastStatusText.startsWith("S:")) {
|
||||
lastStatusText = lastStatusText + ":Card #" + scannedCardId;
|
||||
state = STATE_RESULT_DISPLAY;
|
||||
} else {
|
||||
tone(BUZZER_PIN, NOTE_CS5, 100);
|
||||
tone(BUZZER_PIN, NOTE_NONE, 25);
|
||||
tone(BUZZER_PIN, NOTE_CS5, 400);
|
||||
state = STATE_RESULT_FAILURE;
|
||||
}
|
||||
lastStatusText = lastStatusText.substring(2);
|
||||
timer = millis();
|
||||
case STATE_RESULT_SUCCESS:
|
||||
case STATE_RESULT_FAILURE:
|
||||
case STATE_RESULT_DISPLAY:
|
||||
if (!cooldownCheck(gTimeout)) {
|
||||
updateOLED(u8g2, state, lastStatusText, String(cooldownSecondsRemaining(gTimeout, timer)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (interruptFired) {
|
||||
timer = millis();
|
||||
interruptFired = false;
|
||||
}
|
||||
|
||||
delay(50);
|
||||
}
|
||||
switch (state) {
|
||||
case STATE_IDLE:
|
||||
updateOLED(u8g2, state);
|
||||
break;
|
||||
case STATE_TRANSACT_CARDSCAN:
|
||||
for (CardReader *reader : readers) {
|
||||
if (reader->isNewCardPresent()) {
|
||||
scannedCardId = reader->getCardUid();
|
||||
lastStatusText = "Card #" + scannedCardId;
|
||||
state = STATE_TRANSACT_VERIFY;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!cooldownCheck(scanTimeout)) {
|
||||
updateOLED(u8g2, state, String("1.50€"), String(cooldownSecondsRemaining(scanTimeout, timer)));
|
||||
}
|
||||
break;
|
||||
case STATE_TRANSACT_VERIFY:
|
||||
updateOLED(u8g2, state, lastStatusText);
|
||||
tone(PIN_BUZZER, NOTE_A5, 25);
|
||||
tone(PIN_BUZZER, NOTE_NONE, 150);
|
||||
lastStatusText = cardTransaction(wifi, http, apiUrl, scannedCardId, "1.50");
|
||||
if (lastStatusText.startsWith("S:")) {
|
||||
tone(PIN_BUZZER, NOTE_C7, 650);
|
||||
lastStatusText += "€";
|
||||
state = STATE_RESULT_SUCCESS;
|
||||
} else {
|
||||
tone(PIN_BUZZER, NOTE_CS5, 100);
|
||||
tone(PIN_BUZZER, NOTE_NONE, 25);
|
||||
tone(PIN_BUZZER, NOTE_CS5, 400);
|
||||
state = STATE_RESULT_FAILURE;
|
||||
}
|
||||
lastStatusText = lastStatusText.substring(2);
|
||||
timer = millis();
|
||||
return;
|
||||
case STATE_LINK_CARDSCAN:
|
||||
for (CardReader *reader : readers) {
|
||||
if (reader->isNewCardPresent()) {
|
||||
scannedCardId = reader->getCardUid();
|
||||
lastStatusText = "Card #" + scannedCardId;
|
||||
state = STATE_LINK_VERIFY;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!cooldownCheck(scanTimeout)) {
|
||||
updateOLED(u8g2, state, "Link", String(cooldownSecondsRemaining(scanTimeout, timer)));
|
||||
}
|
||||
break;
|
||||
case STATE_LINK_VERIFY:
|
||||
updateOLED(u8g2, state, lastStatusText);
|
||||
tone(PIN_BUZZER, NOTE_A5, 25);
|
||||
tone(PIN_BUZZER, NOTE_NONE, 150);
|
||||
lastStatusText = cardLink(wifi, http, apiUrl, scannedCardId);
|
||||
if (lastStatusText.startsWith("S:")) {
|
||||
tone(PIN_BUZZER, NOTE_C6, 100);
|
||||
tone(PIN_BUZZER, NOTE_NONE, 10);
|
||||
tone(PIN_BUZZER, NOTE_C6, 100);
|
||||
state = STATE_RESULT_SUCCESS;
|
||||
} else {
|
||||
tone(PIN_BUZZER, NOTE_CS5, 100);
|
||||
tone(PIN_BUZZER, NOTE_NONE, 25);
|
||||
tone(PIN_BUZZER, NOTE_CS5, 400);
|
||||
state = STATE_RESULT_FAILURE;
|
||||
}
|
||||
lastStatusText = lastStatusText.substring(2);
|
||||
timer = millis();
|
||||
return;
|
||||
case STATE_BALANCE_CARDSCAN:
|
||||
for (CardReader *reader : readers) {
|
||||
if (reader->isNewCardPresent()) {
|
||||
scannedCardId = reader->getCardUid();
|
||||
lastStatusText = "Card #" + scannedCardId;
|
||||
state = STATE_BALANCE_VERIFY;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!cooldownCheck(scanTimeout)) {
|
||||
updateOLED(u8g2, state, "Balance", String(cooldownSecondsRemaining(scanTimeout, timer)));
|
||||
}
|
||||
break;
|
||||
case STATE_BALANCE_VERIFY:
|
||||
updateOLED(u8g2, state, lastStatusText);
|
||||
tone(PIN_BUZZER, NOTE_A5, 25);
|
||||
tone(PIN_BUZZER, NOTE_NONE, 150);
|
||||
lastStatusText = cardBalance(wifi, http, apiUrl, scannedCardId);
|
||||
if (lastStatusText.startsWith("S:")) {
|
||||
lastStatusText = lastStatusText + ":Card #" + scannedCardId;
|
||||
state = STATE_RESULT_DISPLAY;
|
||||
} else {
|
||||
tone(PIN_BUZZER, NOTE_CS5, 100);
|
||||
tone(PIN_BUZZER, NOTE_NONE, 25);
|
||||
tone(PIN_BUZZER, NOTE_CS5, 400);
|
||||
state = STATE_RESULT_FAILURE;
|
||||
}
|
||||
lastStatusText = lastStatusText.substring(2);
|
||||
timer = millis();
|
||||
case STATE_RESULT_SUCCESS:
|
||||
case STATE_RESULT_FAILURE:
|
||||
case STATE_RESULT_DISPLAY:
|
||||
if (!cooldownCheck(gTimeout)) {
|
||||
updateOLED(u8g2, state, lastStatusText, String(cooldownSecondsRemaining(gTimeout, timer)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
delay(50);
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
|
|
@ -6,125 +6,125 @@
|
|||
#include "utils.h"
|
||||
|
||||
void drawCurvedLineV(U8G2 u8g2, int xStart, int yStart, int vert, int horiz) {
|
||||
u8g2.drawVLine(xStart, yStart + 1, vert);
|
||||
u8g2.drawVLine(xStart + 1, yStart, vert);
|
||||
u8g2.drawVLine(xStart, yStart + 1, vert);
|
||||
u8g2.drawVLine(xStart + 1, yStart, vert);
|
||||
|
||||
u8g2.drawHLine(xStart, yStart + vert, horiz);
|
||||
u8g2.drawHLine(xStart + 1, yStart + vert + 1, horiz);
|
||||
u8g2.drawHLine(xStart, yStart + vert, horiz);
|
||||
u8g2.drawHLine(xStart + 1, yStart + vert + 1, horiz);
|
||||
}
|
||||
|
||||
void drawCurvedLine(U8G2 u8g2, int xStart, int yStart, int horiz, int vert) {
|
||||
u8g2.drawHLine(xStart, yStart, horiz);
|
||||
u8g2.drawHLine(xStart, yStart + 1, horiz);
|
||||
u8g2.drawHLine(xStart, yStart, horiz);
|
||||
u8g2.drawHLine(xStart, yStart + 1, horiz);
|
||||
|
||||
u8g2.drawVLine(xStart + horiz, yStart, vert);
|
||||
u8g2.drawVLine(xStart + horiz + 1, yStart + 1, vert);
|
||||
u8g2.drawVLine(xStart + horiz, yStart, vert);
|
||||
u8g2.drawVLine(xStart + horiz + 1, yStart + 1, vert);
|
||||
}
|
||||
|
||||
void drawLogoAfraPay(U8G2 u8g2) {
|
||||
u8g2.setFontMode(1);
|
||||
u8g2.setFontDirection(0);
|
||||
u8g2.setFontMode(1);
|
||||
u8g2.setFontDirection(0);
|
||||
|
||||
int xOffset = 12;
|
||||
int yOffset = 23;
|
||||
int xOffset = 12;
|
||||
int yOffset = 23;
|
||||
|
||||
u8g2.setFont(u8g2_font_maniac_tr);
|
||||
u8g2.drawStr(xOffset, yOffset, "AfRA");
|
||||
u8g2.setFont(u8g2_font_maniac_tr);
|
||||
u8g2.drawStr(xOffset, yOffset, "AfRA");
|
||||
|
||||
u8g2.setFont(u8g2_font_tenthinguys_tr);
|
||||
u8g2.drawStr(xOffset + 73, yOffset + 3, "pay");
|
||||
u8g2.setFont(u8g2_font_tenthinguys_tr);
|
||||
u8g2.drawStr(xOffset + 73, yOffset + 3, "pay");
|
||||
|
||||
// uncomment to verify distance to screen gap is equal on both sides
|
||||
//u8g2.drawHLine(0, yOffset-12, xOffset);
|
||||
//u8g2.drawHLine(127-xOffset-1, yOffset, xOffset);
|
||||
// uncomment to verify distance to screen gap is equal on both sides
|
||||
//u8g2.drawHLine(0, yOffset-12, xOffset);
|
||||
//u8g2.drawHLine(127-xOffset-1, yOffset, xOffset);
|
||||
|
||||
drawCurvedLineV(u8g2, xOffset + 69, yOffset, 7, 32);
|
||||
drawCurvedLine(u8g2, xOffset + 73, yOffset - 8, 28, 15);
|
||||
u8g2.drawPixel(xOffset + 101, yOffset + 7);
|
||||
drawCurvedLineV(u8g2, xOffset + 69, yOffset, 7, 32);
|
||||
drawCurvedLine(u8g2, xOffset + 73, yOffset - 8, 28, 15);
|
||||
u8g2.drawPixel(xOffset + 101, yOffset + 7);
|
||||
}
|
||||
|
||||
void drawLogoBitmap(U8G2 u8g2, int width, int height, unsigned char bits[], int yOffset = 0) {
|
||||
int offset = (128 - width) / 2;
|
||||
u8g2.drawXBM(offset, yOffset, width, height, bits);
|
||||
int offset = (128 - width) / 2;
|
||||
u8g2.drawXBM(offset, yOffset, width, height, bits);
|
||||
}
|
||||
|
||||
void drawLogo(U8G2 u8g2, e_logo logo) {
|
||||
switch (logo) {
|
||||
case LOGO_AFRAPAY:
|
||||
drawLogoAfraPay(u8g2);
|
||||
break;
|
||||
case LOGO_CONTACTLESS:
|
||||
drawLogoBitmap(u8g2, contactless_width, contactless_height, contactless_bits);
|
||||
break;
|
||||
case LOGO_MATECARD:
|
||||
drawLogoBitmap(u8g2, matecard_width, matecard_height, matecard_bits, 5);
|
||||
u8g2.setFont(u8g2_font_bpixeldouble_tr);
|
||||
u8g2.drawStr((126 - u8g2.getStrWidth("matecard")) / 2, 57, "matecard");
|
||||
break;
|
||||
case LOGO_PENDING:
|
||||
drawLogoBitmap(u8g2, pending_width, pending_height, pending_bits, 5);
|
||||
break;
|
||||
case LOGO_SUCCESS:
|
||||
drawLogoBitmap(u8g2, success_width, success_height, success_bits, 5);
|
||||
break;
|
||||
case LOGO_FAILURE:
|
||||
drawLogoBitmap(u8g2, failure_width, failure_height, failure_bits, 5);
|
||||
break;
|
||||
}
|
||||
switch (logo) {
|
||||
case LOGO_AFRAPAY:
|
||||
drawLogoAfraPay(u8g2);
|
||||
break;
|
||||
case LOGO_CONTACTLESS:
|
||||
drawLogoBitmap(u8g2, contactless_width, contactless_height, contactless_bits);
|
||||
break;
|
||||
case LOGO_MATECARD:
|
||||
drawLogoBitmap(u8g2, matecard_width, matecard_height, matecard_bits, 5);
|
||||
u8g2.setFont(u8g2_font_bpixeldouble_tr);
|
||||
u8g2.drawStr((126 - u8g2.getStrWidth("matecard")) / 2, 57, "matecard");
|
||||
break;
|
||||
case LOGO_PENDING:
|
||||
drawLogoBitmap(u8g2, pending_width, pending_height, pending_bits, 5);
|
||||
break;
|
||||
case LOGO_SUCCESS:
|
||||
drawLogoBitmap(u8g2, success_width, success_height, success_bits, 5);
|
||||
break;
|
||||
case LOGO_FAILURE:
|
||||
drawLogoBitmap(u8g2, failure_width, failure_height, failure_bits, 5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void drawStatusText(U8G2 u8g2, String status, String statusRightAligned = "") {
|
||||
u8g2.setFont(u8g2_font_bpixel_te);
|
||||
u8g2.drawUTF8(0, 61, status.c_str());
|
||||
u8g2.setFont(u8g2_font_bpixel_te);
|
||||
u8g2.drawUTF8(0, 61, status.c_str());
|
||||
|
||||
if (!statusRightAligned.isEmpty()) {
|
||||
int textWidth = u8g2.getUTF8Width(statusRightAligned.c_str());
|
||||
u8g2.drawUTF8(126 - textWidth, 61, statusRightAligned.c_str());
|
||||
}
|
||||
if (!statusRightAligned.isEmpty()) {
|
||||
int textWidth = u8g2.getUTF8Width(statusRightAligned.c_str());
|
||||
u8g2.drawUTF8(126 - textWidth, 61, statusRightAligned.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void drawFullScreenText(U8G2 u8g2, String textTop, String textBottom) {
|
||||
u8g2.setFont(u8g2_font_chargen_92_tr);
|
||||
u8g2.drawUTF8((127-u8g2.getUTF8Width(textTop.c_str()))/2, 13, textTop.c_str());
|
||||
u8g2.setFont(u8g2_font_maniac_te);
|
||||
u8g2.drawUTF8((127-u8g2.getUTF8Width(textBottom.c_str()))/2, 45, textBottom.c_str());
|
||||
u8g2.setFont(u8g2_font_chargen_92_tr);
|
||||
u8g2.drawUTF8((127-u8g2.getUTF8Width(textTop.c_str()))/2, 13, textTop.c_str());
|
||||
u8g2.setFont(u8g2_font_maniac_te);
|
||||
u8g2.drawUTF8((127-u8g2.getUTF8Width(textBottom.c_str()))/2, 45, textBottom.c_str());
|
||||
}
|
||||
|
||||
void updateOLED(U8G2 u8g2, e_state state, String statusText, String statusTextRightAligned = "") {
|
||||
u8g2.clearBuffer();
|
||||
u8g2.clearBuffer();
|
||||
|
||||
switch (state) {
|
||||
case STATE_IDLE:
|
||||
drawLogo(u8g2, LOGO_AFRAPAY);
|
||||
break;
|
||||
case STATE_TRANSACT_CARDSCAN:
|
||||
case STATE_BALANCE_CARDSCAN:
|
||||
case STATE_LINK_CARDSCAN:
|
||||
drawLogo(u8g2, LOGO_CONTACTLESS);
|
||||
break;
|
||||
case STATE_RESULT_SUCCESS:
|
||||
drawLogo(u8g2, LOGO_SUCCESS);
|
||||
break;
|
||||
case STATE_RESULT_FAILURE:
|
||||
drawLogo(u8g2, LOGO_FAILURE);
|
||||
break;
|
||||
case STATE_RESULT_DISPLAY:
|
||||
drawFullScreenText(u8g2, splitString(statusText, ':', 0), splitString(statusText, ':', 1) + "€");
|
||||
drawStatusText(u8g2, splitString(statusText, ':', 2), statusTextRightAligned);
|
||||
u8g2.sendBuffer();
|
||||
return;
|
||||
case STATE_TRANSACT_VERIFY:
|
||||
case STATE_BALANCE_VERIFY:
|
||||
case STATE_LINK_VERIFY:
|
||||
drawLogo(u8g2, LOGO_PENDING);
|
||||
break;
|
||||
}
|
||||
switch (state) {
|
||||
case STATE_IDLE:
|
||||
drawLogo(u8g2, LOGO_AFRAPAY);
|
||||
break;
|
||||
case STATE_TRANSACT_CARDSCAN:
|
||||
case STATE_BALANCE_CARDSCAN:
|
||||
case STATE_LINK_CARDSCAN:
|
||||
drawLogo(u8g2, LOGO_CONTACTLESS);
|
||||
break;
|
||||
case STATE_RESULT_SUCCESS:
|
||||
drawLogo(u8g2, LOGO_SUCCESS);
|
||||
break;
|
||||
case STATE_RESULT_FAILURE:
|
||||
drawLogo(u8g2, LOGO_FAILURE);
|
||||
break;
|
||||
case STATE_RESULT_DISPLAY:
|
||||
drawFullScreenText(u8g2, splitString(statusText, ':', 0), splitString(statusText, ':', 1) + "€");
|
||||
drawStatusText(u8g2, splitString(statusText, ':', 2), statusTextRightAligned);
|
||||
u8g2.sendBuffer();
|
||||
return;
|
||||
case STATE_TRANSACT_VERIFY:
|
||||
case STATE_BALANCE_VERIFY:
|
||||
case STATE_LINK_VERIFY:
|
||||
drawLogo(u8g2, LOGO_PENDING);
|
||||
break;
|
||||
}
|
||||
|
||||
drawStatusText(u8g2, statusText, statusTextRightAligned);
|
||||
u8g2.sendBuffer();
|
||||
drawStatusText(u8g2, statusText, statusTextRightAligned);
|
||||
u8g2.sendBuffer();
|
||||
}
|
||||
|
||||
void updateOLED(U8G2 u8g2, e_state state) {
|
||||
String time = DateTime.format(DateFormatter::TIME_ONLY);
|
||||
updateOLED(u8g2, state, time, WiFi.localIP().toString());
|
||||
}
|
||||
String time = DateTime.format(DateFormatter::TIME_ONLY);
|
||||
updateOLED(u8g2, state, time, WiFi.localIP().toString());
|
||||
}
|
||||
|
|
|
@ -3,78 +3,82 @@
|
|||
#include <HTTPClient.h>
|
||||
|
||||
String byteArrayAsHexString(byte *buffer, byte bufferSize) {
|
||||
String s = "";
|
||||
for (byte i = 0; i < bufferSize; i++) {
|
||||
s += (buffer[i] < 0x10 ? "0" : "");
|
||||
s += String(buffer[i], HEX);
|
||||
}
|
||||
return s;
|
||||
String s = "";
|
||||
for (byte i = 0; i < bufferSize; i++) {
|
||||
s += (buffer[i] < 0x10 ? "0" : "");
|
||||
s += String(buffer[i], HEX);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
String uint32AsHexString(uint32_t input) {
|
||||
return byteArrayAsHexString(reinterpret_cast<byte *>(&input), sizeof input);
|
||||
}
|
||||
|
||||
unsigned long cooldownSecondsRemaining(unsigned long timeout, unsigned long timer) {
|
||||
return (timeout - (millis() - timer)) / 1000 + 1;
|
||||
return (timeout - (millis() - timer)) / 1000 + 1;
|
||||
}
|
||||
|
||||
String splitString(String data, char separator, int index) {
|
||||
int found = 0;
|
||||
int strIndex[] = {0, -1};
|
||||
int maxIndex = data.length() - 1;
|
||||
int found = 0;
|
||||
int strIndex[] = {0, -1};
|
||||
int maxIndex = data.length() - 1;
|
||||
|
||||
for (int i = 0; i <= maxIndex && found <= index; i++) {
|
||||
if (data.charAt(i) == separator || i == maxIndex) {
|
||||
found++;
|
||||
strIndex[0] = strIndex[1] + 1;
|
||||
strIndex[1] = (i == maxIndex) ? i + 1 : i;
|
||||
}
|
||||
}
|
||||
return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
|
||||
for (int i = 0; i <= maxIndex && found <= index; i++) {
|
||||
if (data.charAt(i) == separator || i == maxIndex) {
|
||||
found++;
|
||||
strIndex[0] = strIndex[1] + 1;
|
||||
strIndex[1] = (i == maxIndex) ? i + 1 : i;
|
||||
}
|
||||
}
|
||||
return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
|
||||
}
|
||||
|
||||
|
||||
String cardLink(WiFiClient *wifi, HTTPClient *http, String apiUrl, String cardId) {
|
||||
String finalRequestUrl = apiUrl + "/api/card/link?card=" + cardId;
|
||||
http->begin(*wifi, finalRequestUrl.c_str());
|
||||
int httpResponseCode = http->GET();
|
||||
if (httpResponseCode == 200) {
|
||||
String payload = http->getString();
|
||||
http->end();
|
||||
return payload;
|
||||
}
|
||||
http->end();
|
||||
if (httpResponseCode > 0) {
|
||||
return String("E:HTTP Error ") + httpResponseCode;
|
||||
}
|
||||
return String("E:Internal Error ") + httpResponseCode;
|
||||
String finalRequestUrl = apiUrl + "/api/card/link?card=" + cardId;
|
||||
http->begin(*wifi, finalRequestUrl.c_str());
|
||||
int httpResponseCode = http->GET();
|
||||
if (httpResponseCode == 200) {
|
||||
String payload = http->getString();
|
||||
http->end();
|
||||
return payload;
|
||||
}
|
||||
http->end();
|
||||
if (httpResponseCode > 0) {
|
||||
return String("E:HTTP Error ") + httpResponseCode;
|
||||
}
|
||||
return String("E:Internal Error ") + httpResponseCode;
|
||||
}
|
||||
|
||||
String cardBalance(WiFiClient *wifi, HTTPClient *http, String apiUrl, String cardId) {
|
||||
String finalRequestUrl = apiUrl + "/api/card/balance?card=" + cardId;
|
||||
http->begin(*wifi, finalRequestUrl.c_str());
|
||||
int httpResponseCode = http->GET();
|
||||
if (httpResponseCode == 200) {
|
||||
String payload = http->getString();
|
||||
http->end();
|
||||
return payload;
|
||||
}
|
||||
http->end();
|
||||
if (httpResponseCode > 0) {
|
||||
return String("E:HTTP Error ") + httpResponseCode;
|
||||
}
|
||||
return String("E:Internal Error ") + httpResponseCode;
|
||||
String finalRequestUrl = apiUrl + "/api/card/balance?card=" + cardId;
|
||||
http->begin(*wifi, finalRequestUrl.c_str());
|
||||
int httpResponseCode = http->GET();
|
||||
if (httpResponseCode == 200) {
|
||||
String payload = http->getString();
|
||||
http->end();
|
||||
return payload;
|
||||
}
|
||||
http->end();
|
||||
if (httpResponseCode > 0) {
|
||||
return String("E:HTTP Error ") + httpResponseCode;
|
||||
}
|
||||
return String("E:Internal Error ") + httpResponseCode;
|
||||
}
|
||||
|
||||
String cardTransaction(WiFiClient *wifi, HTTPClient *http, String apiUrl, String cardId, String amount) {
|
||||
String finalRequestUrl = apiUrl + "/api/card/transaction?card=" + cardId + "&amount=" + amount;
|
||||
http->begin(*wifi, finalRequestUrl.c_str());
|
||||
int httpResponseCode = http->GET();
|
||||
if (httpResponseCode == 200) {
|
||||
String payload = http->getString();
|
||||
http->end();
|
||||
return payload;
|
||||
}
|
||||
http->end();
|
||||
if (httpResponseCode > 0) {
|
||||
return String("E:HTTP Error ") + httpResponseCode;
|
||||
}
|
||||
return String("E:Internal Error ") + httpResponseCode;
|
||||
}
|
||||
String finalRequestUrl = apiUrl + "/api/card/transaction?card=" + cardId + "&amount=" + amount;
|
||||
http->begin(*wifi, finalRequestUrl.c_str());
|
||||
int httpResponseCode = http->GET();
|
||||
if (httpResponseCode == 200) {
|
||||
String payload = http->getString();
|
||||
http->end();
|
||||
return payload;
|
||||
}
|
||||
http->end();
|
||||
if (httpResponseCode > 0) {
|
||||
return String("E:HTTP Error ") + httpResponseCode;
|
||||
}
|
||||
return String("E:Internal Error ") + httpResponseCode;
|
||||
}
|
||||
|
|
|
@ -1,34 +1,29 @@
|
|||
#include <WiFi.h>
|
||||
#include <lwip/sockets.h>
|
||||
#include "wifiFix.h"
|
||||
|
||||
#define WIFI_CLIENT_FLUSH_BUFFER_SIZE (1024)
|
||||
|
||||
class WiFiClientFixed : public WiFiClient {
|
||||
public:
|
||||
void flush() override;
|
||||
};
|
||||
|
||||
void WiFiClientFixed::flush() {
|
||||
int res;
|
||||
size_t a = available(), toRead = 0;
|
||||
if (!a) {
|
||||
return;//nothing to flush
|
||||
}
|
||||
uint8_t *buf = (uint8_t *) malloc(WIFI_CLIENT_FLUSH_BUFFER_SIZE);
|
||||
if (!buf) {
|
||||
return;//memory error
|
||||
}
|
||||
while (a) {
|
||||
toRead = (a > WIFI_CLIENT_FLUSH_BUFFER_SIZE) ? WIFI_CLIENT_FLUSH_BUFFER_SIZE : a;
|
||||
// override broken WiFiClient flush method, ref https://github.com/espressif/arduino-esp32/issues/6129#issuecomment-1237417915
|
||||
//res = recv(fd(), buf, toRead, MSG_DONTWAIT);
|
||||
res = read(buf, a);
|
||||
if (res < 0) {
|
||||
log_e("fail on fd %d, errno: %d, \"%s\"", fd(), errno, strerror(errno));
|
||||
stop();
|
||||
break;
|
||||
}
|
||||
a -= res;
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
int res;
|
||||
size_t a = available();
|
||||
if (!a) {
|
||||
return;//nothing to flush
|
||||
}
|
||||
auto *buf = (uint8_t *) malloc(WIFI_CLIENT_FLUSH_BUFFER_SIZE);
|
||||
if (!buf) {
|
||||
return;//memory error
|
||||
}
|
||||
while (a) {
|
||||
// override broken WiFiClient flush method, ref https://github.com/espressif/arduino-esp32/issues/6129#issuecomment-1237417915
|
||||
//res = recv(fd(), buf, toRead, MSG_DONTWAIT);
|
||||
res = read(buf, a);
|
||||
if (res < 0) {
|
||||
log_e("fail on fd %d, errno: %d, \"%s\"", fd(), errno, strerror(errno));
|
||||
stop();
|
||||
break;
|
||||
}
|
||||
a -= res;
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
|
|
|
@ -4,11 +4,15 @@
|
|||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<NoWarn>$(NoWarn);1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="linq2db" Version="4.4.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="7.0.2" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.6" />
|
||||
<PackageReference Include="System.Data.SQLite" Version="1.0.115" />
|
||||
<PackageReference Include="System.Data.SQLite.Core.osx.arm64" Version="1.0.117" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System.Reflection;
|
||||
using AfRApay.Web.Backend;
|
||||
using LinqToDB.Data;
|
||||
|
||||
|
@ -6,8 +7,11 @@ Migrations.RunMigrations();
|
|||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddRazorPages();
|
||||
builder.Services.AddSwaggerGen(options => {
|
||||
var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
||||
options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
|
||||
});
|
||||
|
||||
#if (DEBUG)
|
||||
builder.Services.AddControllers().AddRazorRuntimeCompilation();
|
||||
|
@ -18,14 +22,13 @@ builder.Services.AddControllers();
|
|||
|
||||
var app = builder.Build();
|
||||
|
||||
if (!app.Environment.IsDevelopment()) {
|
||||
app.UseExceptionHandler("/Error");
|
||||
app.UseHsts();
|
||||
if (app.Environment.IsDevelopment()) {
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
}
|
||||
|
||||
app.UseStatusCodePagesWithReExecute("/error");
|
||||
app.UseStatusCodePagesWithReExecute("/Error");
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseRouting();
|
||||
|
|
15
AfRApay.Web/Controllers/Schema/ErrorResponse.cs
Normal file
15
AfRApay.Web/Controllers/Schema/ErrorResponse.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
using System.ComponentModel;
|
||||
using AfRApay.Web.Backend.Tables;
|
||||
using J = System.Text.Json.Serialization.JsonPropertyNameAttribute;
|
||||
|
||||
namespace AfRApay.Web.Controllers.Schema;
|
||||
|
||||
public class ErrorResponse {
|
||||
[J("status")] [DefaultValue("error")] public string Status { get; set; }
|
||||
[J("message")] public string Message { get; set; }
|
||||
|
||||
public ErrorResponse(string message) {
|
||||
Status = "error";
|
||||
Message = message;
|
||||
}
|
||||
}
|
15
AfRApay.Web/Controllers/Schema/UserResponse.cs
Normal file
15
AfRApay.Web/Controllers/Schema/UserResponse.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
using System.ComponentModel;
|
||||
using AfRApay.Web.Backend.Tables;
|
||||
using J = System.Text.Json.Serialization.JsonPropertyNameAttribute;
|
||||
|
||||
namespace AfRApay.Web.Controllers.Schema;
|
||||
|
||||
public class UserResponse {
|
||||
[J("data")] public User? Data { get; set; }
|
||||
[J("status")] [DefaultValue("success")] public string Status { get; set; } = "success";
|
||||
[J("message")] [DefaultValue("")] public string Message { get; set; } = "";
|
||||
|
||||
public UserResponse(User data) {
|
||||
Data = data;
|
||||
}
|
||||
}
|
37
AfRApay.Web/Controllers/UserController.cs
Normal file
37
AfRApay.Web/Controllers/UserController.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
using AfRApay.Web.Backend;
|
||||
using AfRApay.Web.Controllers.Schema;
|
||||
using LinqToDB;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Swashbuckle.AspNetCore.Filters;
|
||||
|
||||
namespace AfRApay.Web.Controllers;
|
||||
|
||||
[ApiController]
|
||||
public class UserController : Controller {
|
||||
/// <summary>
|
||||
/// Renames the specified user.
|
||||
/// </summary>
|
||||
/// <param name="uid">The ID of the user to be renamed</param>
|
||||
/// <param name="newName">The new name of the user</param>
|
||||
/// <response code="200">Returns 200 if user was renamed successfully</response>
|
||||
/// <response code="400">Returns 400 if newName isn't unique</response>
|
||||
/// <response code="404">Returns 404 if no user matching the UID was found</response>
|
||||
[HttpPut]
|
||||
[Produces("application/json")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(UserResponse))]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ErrorResponse))]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(ErrorResponse))]
|
||||
//[SwaggerResponseExample(400, typeof(new )]
|
||||
[Route("/api/user/{uid:int}/name")]
|
||||
public async Task<IActionResult> Rename(int uid, [FromQuery] string newName) {
|
||||
var db = new Database.DbConn();
|
||||
if (db.Users.Any(p => p.Id == uid)) {
|
||||
var user = db.Users.First(p => p.Id == uid);
|
||||
user.Nickname = newName;
|
||||
await db.UpdateAsync(user);
|
||||
return new OkObjectResult(new UserResponse(user));
|
||||
}
|
||||
|
||||
return NotFound(new ErrorResponse("Unknown user"));
|
||||
}
|
||||
}
|
|
@ -23,8 +23,8 @@
|
|||
<label for="nickname" class="form-label">Nickname</label>
|
||||
<input type="text" maxlength="10" class="form-control" id="nickname" name="nickname" value="@user.Nickname" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" name="action" value="save">Save</button>
|
||||
<button type="button" class="btn btn-danger" name="action" data-bs-toggle="modal" data-bs-target="#deleteConfirmModal">Delete</button> <!-- Calls the below modal dialog to confirm user deletetion -->
|
||||
<button type="submit" class="btn btn-lg btn-primary" name="action" value="save">Save</button>
|
||||
<button type="button" class="btn btn-lg btn-danger" name="action" data-bs-toggle="modal" data-bs-target="#deleteConfirmModal">Delete</button> <!-- Calls the below modal dialog to confirm user deletetion -->
|
||||
</form>
|
||||
|
||||
<!-- Modal dialog to confirm user deletion -->
|
||||
|
@ -39,8 +39,8 @@
|
|||
Are you sure you want to delete this user?<br>This cannot be undone.
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="submit" form="change_user" class="btn btn-danger" name="action" value="delete">Delete User</button>
|
||||
<button type="button" class="btn btn-lg btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="submit" form="change_user" class="btn btn-lg btn-danger" name="action" value="delete">Delete User</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -48,18 +48,13 @@
|
|||
|
||||
<br/>
|
||||
<h3 class="text-center">Cards</h3>
|
||||
@if (!cards.Any()) {
|
||||
<div>
|
||||
No linked cards found.
|
||||
</div>
|
||||
}
|
||||
else {
|
||||
@{ <!-- We add all the cards here! -->
|
||||
<div class="row justify-content-center">
|
||||
@foreach (var card in cards) {
|
||||
<div class="fake-card-wrapper m-2">
|
||||
<div class="fake-card-wrapper blur-true m-2">
|
||||
<div class="fake-card">
|
||||
<div class="hover-overlay"></div>
|
||||
<button type="button" class="btn btn-danger btn-lg hover-button">Delete</button>
|
||||
<a class="btn btn-danger btn-lg hover-button">Delete</a>
|
||||
<div class="face-card front">
|
||||
<div class="chip">
|
||||
<div>
|
||||
|
@ -87,5 +82,35 @@ else {
|
|||
</div>
|
||||
</div>
|
||||
}
|
||||
<!-- Here we display a faded placholder card, with the add button at its center -->
|
||||
<div class="fake-card-wrapper m-2">
|
||||
<div class="fake-card">
|
||||
<a class="btn btn-success btn-lg add-card-button" href="/LinkCard/@user.Id">Add Card</a>
|
||||
<div class="face-card ghost-card front">
|
||||
<div class="chip">
|
||||
<div>
|
||||
<div>
|
||||
<div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h2 class="card-number">Awooo!</h2>
|
||||
<h3 class="card-holder">@user.Nickname</h3>
|
||||
<span class="validity">
|
||||
<span class="small">VALID<br>THRU</span>
|
||||
<span>01/2038</span>
|
||||
</span>
|
||||
|
||||
<div class="fake-card-logo-top">
|
||||
<img src="/img/afra.png" class="fake-card-logo-inner" alt="">
|
||||
</div>
|
||||
<div class="fake-card-logo-bottom">
|
||||
<img src="/img/matecard.png" class="fake-card-logo-inner" alt="">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -67,15 +67,14 @@
|
|||
<td> <!-- Displayed when in big layout -->
|
||||
<div class="d-none d-md-flex btn-group btn-group-lg" role="group">
|
||||
<!-- Make sure these buttons match the small/mobile layout ones below -->
|
||||
<a class="btn px-auto btn-danger" href="/UpdateBalance/@user.Id/-1.50">-1.50€</a>
|
||||
<a class="btn px-auto btn-success" href="/UpdateBalance/@user.Id/5">+5€</a>
|
||||
<a class="btn px-auto btn-success" href="/UpdateBalance/@user.Id/10">+10€</a>
|
||||
<a class="btn px-2 btn-secondary text-nowrap" href="/LinkCard/@user.Id">Link card</a>
|
||||
<a class="btn px-3 btn-danger" href="/UpdateBalance/@user.Id/-1.50">-1.50€</a>
|
||||
<a class="btn px-3 btn-success" href="/UpdateBalance/@user.Id/5">+5€</a>
|
||||
<a class="btn px-3 btn-success" href="/UpdateBalance/@user.Id/10">+10€</a>
|
||||
<a class="btn px-2 btn-primary" href="/EditUser/@user.Id">Edit</a>
|
||||
</div>
|
||||
<!-- Displayed when in compact/phone layout -->
|
||||
<div class="dropdown d-md-none">
|
||||
<a class="btn btn-secondary dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<a class="btn btn-lg px-1 btn-secondary dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
Actions
|
||||
</a>
|
||||
<div class="dropdown-menu p-1" aria-labelledby="dropdownMenuLink" style="min-width: max-content;"> <!-- Inline CSS, sets minimum width of drop down to maxium size of content -->
|
||||
|
@ -84,7 +83,6 @@
|
|||
<a class="btn btn-lg btn-danger" href="/UpdateBalance/@user.Id/-1.50">-1.50€</a>
|
||||
<a class="btn btn-lg btn-success" href="/UpdateBalance/@user.Id/5">+5€</a>
|
||||
<a class="btn btn-lg btn-success" href="/UpdateBalance/@user.Id/10">+10€</a>
|
||||
<a class="btn btn-lg btn-secondary" href="/LinkCard/@user.Id">Link card</a>
|
||||
<a class="btn btn-lg btn-primary" href="/EditUser/@user.Id">Edit</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -8,15 +8,6 @@
|
|||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": false,
|
||||
"applicationUrl": "https://0.0.0.0:7115;http://localhost:5296",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -258,6 +258,17 @@ button.accept-policy {
|
|||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
.ghost-card {
|
||||
filter:grayscale(100%) blur(4px);
|
||||
}
|
||||
.add-card-button {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 2;
|
||||
filter: grayscale(0%)
|
||||
}
|
||||
.hover-button {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
|
@ -268,20 +279,13 @@ button.accept-policy {
|
|||
transition: .5s ease;
|
||||
z-index: 2;
|
||||
}
|
||||
.hover-overlay {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
opacity: 0;
|
||||
border-radius: 15px;
|
||||
transition: .5s ease;
|
||||
background-color: #808080;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.fake-card-wrapper:hover .hover-button {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
.fake-card-wrapper:hover .hover-overlay {
|
||||
opacity: 0.75;
|
||||
|
||||
.fake-card-wrapper:hover.blur-true .face-card{
|
||||
transition: 0.3s ease;
|
||||
filter:blur(4px) grayscale(100%);
|
||||
}
|
40
hooks/pre-commit.hook
Executable file
40
hooks/pre-commit.hook
Executable file
|
@ -0,0 +1,40 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Regexp for grep to only choose some file extensions for formatting
|
||||
exts="\.\(cpp\|h\)$"
|
||||
|
||||
# The formatter to use
|
||||
formatter=`which uncrustify`
|
||||
|
||||
# Check availability of the formatter
|
||||
if [ -z "$formatter" ]
|
||||
then
|
||||
1>&2 echo "$formatter not found. Pre-commit formatting will not be done."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Format staged files
|
||||
for file in `git diff --cached --name-only --diff-filter=ACMR | grep $exts`
|
||||
do
|
||||
echo "Formatting $file"
|
||||
# get tmpfile
|
||||
tmpfile="${file//.cpp/.tmp.cpp}"
|
||||
tmpfile="${file//.h/.tmp.h}"
|
||||
# Get the file from index
|
||||
git show ":$file" > "$tmpfile"
|
||||
# Format it
|
||||
"$formatter" --no-backup -c AfRApay.MateCard/.uncrustify.cfg "$tmpfile"
|
||||
# Create a blob object from the formatted file
|
||||
hash=`git hash-object -w "$tmpfile"`
|
||||
# Add it back to index
|
||||
git update-index --add --cacheinfo 100644 "$hash" "$file"
|
||||
# Remove the tmp file
|
||||
rm "$tmpfile"
|
||||
done
|
||||
|
||||
# If no files left in index after formatting - fail
|
||||
ret=0
|
||||
if [ ! "`git diff --cached --name-only`" ]; then
|
||||
1>&2 echo "No files left after formatting"
|
||||
exit 1
|
||||
fi
|
Loading…
Reference in a new issue