From 44a40fba27716c883b368918b28689f0cfc64a65 Mon Sep 17 00:00:00 2001 From: clay Date: Sun, 21 Nov 2021 11:53:21 -0600 Subject: [PATCH 1/4] fixes weird qrcode and hmac_256 compile issues --- LNURLPoS/LNURLPoS.ino | 6 +- LNURLPoS/libraries/QRCode/LICENSE.txt | 22 - LNURLPoS/libraries/QRCode/README.md | 636 ------------------ .../QRCode/examples/QRCode/QRCode.ino | 56 -- LNURLPoS/libraries/QRCode/keywords.txt | 31 - LNURLPoS/libraries/QRCode/library.properties | 10 - LNURLPoS/libraries/QRCode/tests/BitBuffer.cpp | 63 -- LNURLPoS/libraries/QRCode/tests/BitBuffer.hpp | 76 --- LNURLPoS/libraries/QRCode/tests/QrCode.cpp | 616 ----------------- LNURLPoS/libraries/QRCode/tests/QrCode.hpp | 314 --------- LNURLPoS/libraries/QRCode/tests/QrSegment.cpp | 173 ----- LNURLPoS/libraries/QRCode/tests/QrSegment.hpp | 170 ----- LNURLPoS/libraries/QRCode/tests/README.md | 12 - LNURLPoS/libraries/QRCode/tests/run-tests.cpp | 85 --- LNURLPoS/libraries/QRCode/tests/run.sh | 5 - .../src/qrcode.c => qrhelper/qrhelper.c} | 2 +- .../src/qrcode.h => qrhelper/qrhelper.h} | 6 +- .../uBitcoin/examples/mnemonic/mnemonic.ino | 9 + LNURLPoS/libraries/uBitcoin/library.json | 2 +- .../libraries/uBitcoin/library.properties | 2 +- LNURLPoS/libraries/uBitcoin/src/Bitcoin.cpp | 37 + LNURLPoS/libraries/uBitcoin/src/Bitcoin.h | 10 + .../libraries/uBitcoin/src/Conversion.cpp | 94 +++ LNURLPoS/libraries/uBitcoin/src/Conversion.h | 20 + .../uBitcoin/src/utility/segwit_addr.c | 0 .../uBitcoin/src/utility/segwit_addr.h | 0 .../uBitcoin/src/utility/trezor/address.c | 0 .../uBitcoin/src/utility/trezor/address.h | 0 .../uBitcoin/src/utility/trezor/base58.c | 0 .../uBitcoin/src/utility/trezor/base58.h | 0 .../uBitcoin/src/utility/trezor/bignum.c | 0 .../uBitcoin/src/utility/trezor/bignum.h | 0 .../uBitcoin/src/utility/trezor/bip32.h | 0 .../uBitcoin/src/utility/trezor/bip39.c | 0 .../uBitcoin/src/utility/trezor/bip39.h | 0 .../src/utility/trezor/bip39_english.h | 0 .../uBitcoin/src/utility/trezor/ecdsa.c | 0 .../uBitcoin/src/utility/trezor/ecdsa.h | 0 .../uBitcoin/src/utility/trezor/hasher.c | 0 .../uBitcoin/src/utility/trezor/hasher.h | 0 .../uBitcoin/src/utility/trezor/hmac.c | 14 +- .../uBitcoin/src/utility/trezor/hmac.h | 0 .../uBitcoin/src/utility/trezor/memzero.c | 0 .../uBitcoin/src/utility/trezor/memzero.h | 0 .../uBitcoin/src/utility/trezor/options.h | 0 .../uBitcoin/src/utility/trezor/pbkdf2.c | 0 .../uBitcoin/src/utility/trezor/pbkdf2.h | 0 .../uBitcoin/src/utility/trezor/rand.c | 0 .../uBitcoin/src/utility/trezor/rand.h | 0 .../uBitcoin/src/utility/trezor/rfc6979.c | 0 .../uBitcoin/src/utility/trezor/rfc6979.h | 0 .../uBitcoin/src/utility/trezor/ripemd160.c | 0 .../uBitcoin/src/utility/trezor/ripemd160.h | 0 .../uBitcoin/src/utility/trezor/secp256k1.c | 0 .../uBitcoin/src/utility/trezor/secp256k1.h | 0 .../src/utility/trezor/secp256k1.table | 0 .../uBitcoin/src/utility/trezor/sha2.c | 0 .../uBitcoin/src/utility/trezor/sha2.h | 0 .../uBitcoin/src/utility/trezor/sha3.c | 0 .../uBitcoin/src/utility/trezor/sha3.h | 0 60 files changed, 188 insertions(+), 2283 deletions(-) delete mode 100644 LNURLPoS/libraries/QRCode/LICENSE.txt delete mode 100644 LNURLPoS/libraries/QRCode/README.md delete mode 100644 LNURLPoS/libraries/QRCode/examples/QRCode/QRCode.ino delete mode 100644 LNURLPoS/libraries/QRCode/keywords.txt delete mode 100644 LNURLPoS/libraries/QRCode/library.properties delete mode 100644 LNURLPoS/libraries/QRCode/tests/BitBuffer.cpp delete mode 100644 LNURLPoS/libraries/QRCode/tests/BitBuffer.hpp delete mode 100644 LNURLPoS/libraries/QRCode/tests/QrCode.cpp delete mode 100644 LNURLPoS/libraries/QRCode/tests/QrCode.hpp delete mode 100644 LNURLPoS/libraries/QRCode/tests/QrSegment.cpp delete mode 100644 LNURLPoS/libraries/QRCode/tests/QrSegment.hpp delete mode 100644 LNURLPoS/libraries/QRCode/tests/README.md delete mode 100644 LNURLPoS/libraries/QRCode/tests/run-tests.cpp delete mode 100644 LNURLPoS/libraries/QRCode/tests/run.sh rename LNURLPoS/libraries/{QRCode/src/qrcode.c => qrhelper/qrhelper.c} (99%) rename LNURLPoS/libraries/{QRCode/src/qrcode.h => qrhelper/qrhelper.h} (97%) mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/segwit_addr.c mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/segwit_addr.h mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/address.c mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/address.h mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/base58.c mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/base58.h mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/bignum.c mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/bignum.h mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/bip32.h mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/bip39.c mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/bip39.h mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/bip39_english.h mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/ecdsa.c mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/ecdsa.h mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/hasher.c mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/hasher.h mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/hmac.c mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/hmac.h mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/memzero.c mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/memzero.h mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/options.h mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/pbkdf2.c mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/pbkdf2.h mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/rand.c mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/rand.h mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/rfc6979.c mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/rfc6979.h mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/ripemd160.c mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/ripemd160.h mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/secp256k1.c mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/secp256k1.h mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/secp256k1.table mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/sha2.c mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/sha2.h mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/sha3.c mode change 100644 => 100755 LNURLPoS/libraries/uBitcoin/src/utility/trezor/sha3.h diff --git a/LNURLPoS/LNURLPoS.ino b/LNURLPoS/LNURLPoS.ino index fc4e379..40ed925 100644 --- a/LNURLPoS/LNURLPoS.ino +++ b/LNURLPoS/LNURLPoS.ino @@ -3,7 +3,8 @@ #include "TFT_eSPI.h" #include #include -#include "qrcode.h" +//#include "qrcode.h" +#include "qrhelper.h" #include "Bitcoin.h" #include #include @@ -88,6 +89,9 @@ int checker = 0; char maxdig[20]; + + + //////////////MAIN/////////////////// void setup(void) { diff --git a/LNURLPoS/libraries/QRCode/LICENSE.txt b/LNURLPoS/libraries/QRCode/LICENSE.txt deleted file mode 100644 index d868305..0000000 --- a/LNURLPoS/libraries/QRCode/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 Richard Moore - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - diff --git a/LNURLPoS/libraries/QRCode/README.md b/LNURLPoS/libraries/QRCode/README.md deleted file mode 100644 index c2e823d..0000000 --- a/LNURLPoS/libraries/QRCode/README.md +++ /dev/null @@ -1,636 +0,0 @@ -QRCode -====== - -A simple library for generating [QR codes](https://en.wikipedia.org/wiki/QR_code) in C, -optimized for processing and memory constrained systems. - -**Features:** - -- Stack-based (no heap necessary; but you can use heap if you want) -- Low-memory foot print (relatively) -- Compile-time stripping of unecessary logic -- MIT License; do with this as you please - - -Installing ----------- - -To install this library, download and save it to your Arduino libraries directory. - -Rename the directory to QRCode (if downloaded from GitHub, the filename may be -qrcode-master; library names may not contain the hyphen, so it must be renamed) - - -API ---- - -**Generate a QR Code** - -```c -// The structure to manage the QR code -QRCode qrcode; - -// Allocate a chunk of memory to store the QR code -uint8_t qrcodeBytes[qrcode_getBufferSize()]; - -qrcode_initText(&qrcode, qrcodeBytes, 3, ECC_LOW, "HELLO WORLD"); -``` - -**Draw a QR Code** - -How a QR code is used will vary greatly from project to project. For example: - -- Display on an OLED screen (128x64 nicely supports 2 side-by-side version 3 QR codes) -- Print as a bitmap on a thermal printer -- Store as a BMP (or with a some extra work, possibly a PNG) on an SD card - -The following example prints a QR code to the Serial Monitor (it likely will -not be scannable, but is just for demonstration purposes). - -```c -for (uint8 y = 0; y < qrcode.size; y++) { - for (uint8 x = 0; x < qrcode.size; x++) { - if (qrcode_getModule(&qrcode, x, y) { - Serial.print("**"); - } else { - Serial.print(" "); - } - } - Serial.print("\n"); -} -``` - - -What is Version, Error Correction and Mode? -------------------------------------------- - -A QR code is composed of many little squares, called **modules**, which represent -encoded data, with additional error correction (allowing partially damaged QR -codes to still be read). - -The **version** of a QR code is a number between 1 and 40 (inclusive), which indicates -the size of the QR code. The width and height of a QR code are always equal (it is -square) and are equal to `4 * version + 17`. - -The level of **error correction** is a number between 0 and 3 (inclusive), or can be -one of the symbolic names ECC_LOW, ECC_MEDIUM, ECC_QUARTILE and ECC_HIGH. Higher -levels of error correction sacrifice data capacity, but allow a larger portion of -the QR code to be damaged or unreadable. - -The **mode** of a QR code is determined by the data being encoded. Each mode is encoded -internally using a compact representation, so lower modes can contain more data. - -- **NUMERIC:** numbers (`0-9`) -- **ALPHANUMERIC:** uppercase letters (`A-Z`), numbers (`0-9`), the space (` `), dollar sign (`$`), percent sign (`%`), asterisk (`*`), plus (`+`), minus (`-`), decimal point (`.`), slash (`/`) and colon (`:`). -- **BYTE:** any character - - -Data Capacities ---------------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
VersionError CorrectionMode
NumericAlphanumericByte
1LOW412517
MEDIUM342014
QUARTILE271611
HIGH17107
2LOW774732
MEDIUM633826
QUARTILE482920
HIGH342014
3LOW1277753
MEDIUM1016142
QUARTILE774732
HIGH583524
4LOW18711478
MEDIUM1499062
QUARTILE1116746
HIGH825034
5LOW255154106
MEDIUM20212284
QUARTILE1448760
HIGH1066444
6LOW322195134
MEDIUM255154106
QUARTILE17810874
HIGH1398458
7LOW370224154
MEDIUM293178122
QUARTILE20712586
HIGH1549364
8LOW461279192
MEDIUM365221152
QUARTILE259157108
HIGH20212284
9LOW552335230
MEDIUM432262180
QUARTILE312189130
HIGH23514398
10LOW652395271
MEDIUM513311213
QUARTILE364221151
HIGH288174119
11LOW772468321
MEDIUM604366251
QUARTILE427259177
HIGH331200137
12LOW883535367
MEDIUM691419287
QUARTILE489296203
HIGH374227155
13LOW1022619425
MEDIUM796483331
QUARTILE580352241
HIGH427259177
14LOW1101667458
MEDIUM871528362
QUARTILE621376258
HIGH468283194
15LOW1250758520
MEDIUM991600412
QUARTILE703426292
HIGH530321220
16LOW1408854586
MEDIUM1082656450
QUARTILE775470322
HIGH602365250
17LOW1548938644
MEDIUM1212734504
QUARTILE876531364
HIGH674408280
18LOW17251046718
MEDIUM1346816560
QUARTILE948574394
HIGH746452310
19LOW19031153792
MEDIUM1500909624
QUARTILE1063644442
HIGH813493338
20LOW20611249858
MEDIUM1600970666
QUARTILE1159702482
HIGH919557382
21LOW22321352929
MEDIUM17081035711
QUARTILE1224742509
HIGH969587403
22LOW240914601003
MEDIUM18721134779
QUARTILE1358823565
HIGH1056640439
23LOW262015881091
MEDIUM20591248857
QUARTILE1468890611
HIGH1108672461
24LOW281217041171
MEDIUM21881326911
QUARTILE1588963661
HIGH1228744511
25LOW305718531273
MEDIUM23951451997
QUARTILE17181041715
HIGH1286779535
26LOW328319901367
MEDIUM254415421059
QUARTILE18041094751
HIGH1425864593
27LOW351721321465
MEDIUM270116371125
QUARTILE19331172805
HIGH1501910625
28LOW366922231528
MEDIUM285717321190
QUARTILE20851263868
HIGH1581958658
29LOW390923691628
MEDIUM303518391264
QUARTILE21811322908
HIGH16771016698
30LOW415825201732
MEDIUM328919941370
QUARTILE23581429982
HIGH17821080742
31LOW441726771840
MEDIUM348621131452
QUARTILE247314991030
HIGH18971150790
32LOW468628401952
MEDIUM369322381538
QUARTILE267016181112
HIGH20221226842
33LOW496530092068
MEDIUM390923691628
QUARTILE280517001168
HIGH21571307898
34LOW525331832188
MEDIUM413425061722
QUARTILE294917871228
HIGH23011394958
35LOW552933512303
MEDIUM434326321809
QUARTILE308118671283
HIGH23611431983
36LOW583635372431
MEDIUM458827801911
QUARTILE324419661351
HIGH252415301051
37LOW615337292563
MEDIUM477528941989
QUARTILE341720711423
HIGH262515911093
38LOW647939272699
MEDIUM503930542099
QUARTILE359921811499
HIGH273516581139
39LOW674340872809
MEDIUM531332202213
QUARTILE379122981579
HIGH292717741219
40LOW708942962953
MEDIUM559633912331
QUARTILE399324201663
HIGH305718521273
- - -Special Thanks --------------- - -A HUGE thank you to [nayuki](https://www.nayuki.io/) for the -[QR code C++ library](https://github.com/nayuki/QR-Code-generator/tree/master/cpp) -which was critical in development of this library. - - -License -------- - -MIT License. diff --git a/LNURLPoS/libraries/QRCode/examples/QRCode/QRCode.ino b/LNURLPoS/libraries/QRCode/examples/QRCode/QRCode.ino deleted file mode 100644 index 9f6a655..0000000 --- a/LNURLPoS/libraries/QRCode/examples/QRCode/QRCode.ino +++ /dev/null @@ -1,56 +0,0 @@ -/** - * QRCode - * - * A quick example of generating a QR code. - * - * This prints the QR code to the serial monitor as solid blocks. Each module - * is two characters wide, since the monospace font used in the serial monitor - * is approximately twice as tall as wide. - * - */ - -#include "qrcode.h" - -void setup() { - Serial.begin(115200); - - // Start time - uint32_t dt = millis(); - - // Create the QR code - QRCode qrcode; - uint8_t qrcodeData[qrcode_getBufferSize(3)]; - qrcode_initText(&qrcode, qrcodeData, 3, 0, "HELLO WORLD"); - - // Delta time - dt = millis() - dt; - Serial.print("QR Code Generation Time: "); - Serial.print(dt); - Serial.print("\n"); - - // Top quiet zone - Serial.print("\n\n\n\n"); - - for (uint8_t y = 0; y < qrcode.size; y++) { - - // Left quiet zone - Serial.print(" "); - - // Each horizontal module - for (uint8_t x = 0; x < qrcode.size; x++) { - - // Print each module (UTF-8 \u2588 is a solid block) - Serial.print(qrcode_getModule(&qrcode, x, y) ? "\u2588\u2588": " "); - - } - - Serial.print("\n"); - } - - // Bottom quiet zone - Serial.print("\n\n\n\n"); -} - -void loop() { - -} diff --git a/LNURLPoS/libraries/QRCode/keywords.txt b/LNURLPoS/libraries/QRCode/keywords.txt deleted file mode 100644 index 5246268..0000000 --- a/LNURLPoS/libraries/QRCode/keywords.txt +++ /dev/null @@ -1,31 +0,0 @@ - -# Datatypes (KEYWORD1) - -bool KEYWORD1 -uint8_t KEYWORD1 -QRCode KEYWORD1 - - -# Methods and Functions (KEYWORD2) - -qrcode_getBufferSize KEYWORD2 -qrcode_initText KEYWORD2 -qrcode_initBytes KEYWORD2 -qrcode_getModule KEYWORD2 - - -# Instances (KEYWORD2) - - -# Constants (LITERAL1) - -false LITERAL1 -true LITERAL1 - -ECC_LOW LITERAL1 -ECC_MEDIUM LITERAL1 -ECC_QUARTILE LITERAL1 -ECC_HIGH LITERAL1 -MODE_NUMERIC LITERAL1 -MODE_ALPHANUMERIC LITERAL1 -MODE_BYTE LITERAL1 diff --git a/LNURLPoS/libraries/QRCode/library.properties b/LNURLPoS/libraries/QRCode/library.properties deleted file mode 100644 index 01fdca2..0000000 --- a/LNURLPoS/libraries/QRCode/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=QRCode -version=0.0.1 -author=Richard Moore -maintainer=Richard Moore -sentence=A simple QR code generation library. -paragraph=A simple QR code generation library. -category=Other -url=https://github.com/ricmoo/qrcode/ -architectures=* -includes=qrcode.h diff --git a/LNURLPoS/libraries/QRCode/tests/BitBuffer.cpp b/LNURLPoS/libraries/QRCode/tests/BitBuffer.cpp deleted file mode 100644 index 4b48cb7..0000000 --- a/LNURLPoS/libraries/QRCode/tests/BitBuffer.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - * QR Code generator library (C++) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/qr-code-generator-library - * - * (MIT License) - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - The Software is provided "as is", without warranty of any kind, express or - * implied, including but not limited to the warranties of merchantability, - * fitness for a particular purpose and noninfringement. In no event shall the - * authors or copyright holders be liable for any claim, damages or other - * liability, whether in an action of contract, tort or otherwise, arising from, - * out of or in connection with the Software or the use or other dealings in the - * Software. - */ - -#include -#include "BitBuffer.hpp" - - -qrcodegen::BitBuffer::BitBuffer() : - data(), - bitLength(0) {} - - -int qrcodegen::BitBuffer::getBitLength() const { - return bitLength; -} - - -std::vector qrcodegen::BitBuffer::getBytes() const { - return data; -} - - -void qrcodegen::BitBuffer::appendBits(uint32_t val, int len) { - if (len < 0 || len > 32 || (len < 32 && (val >> len) != 0)) - throw "Value out of range"; - size_t newBitLen = bitLength + len; - while (data.size() * 8 < newBitLen) - data.push_back(0); - for (int i = len - 1; i >= 0; i--, bitLength++) // Append bit by bit - data.at(bitLength >> 3) |= ((val >> i) & 1) << (7 - (bitLength & 7)); -} - - -void qrcodegen::BitBuffer::appendData(const QrSegment &seg) { - size_t newBitLen = bitLength + seg.bitLength; - while (data.size() * 8 < newBitLen) - data.push_back(0); - for (int i = 0; i < seg.bitLength; i++, bitLength++) { // Append bit by bit - int bit = (seg.data.at(i >> 3) >> (7 - (i & 7))) & 1; - data.at(bitLength >> 3) |= bit << (7 - (bitLength & 7)); - } -} diff --git a/LNURLPoS/libraries/QRCode/tests/BitBuffer.hpp b/LNURLPoS/libraries/QRCode/tests/BitBuffer.hpp deleted file mode 100644 index ee38907..0000000 --- a/LNURLPoS/libraries/QRCode/tests/BitBuffer.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * QR Code generator library (C++) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/qr-code-generator-library - * - * (MIT License) - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - The Software is provided "as is", without warranty of any kind, express or - * implied, including but not limited to the warranties of merchantability, - * fitness for a particular purpose and noninfringement. In no event shall the - * authors or copyright holders be liable for any claim, damages or other - * liability, whether in an action of contract, tort or otherwise, arising from, - * out of or in connection with the Software or the use or other dealings in the - * Software. - */ - -#pragma once - -#include -#include -#include "QrSegment.hpp" - - -namespace qrcodegen { - -/* - * An appendable sequence of bits. Bits are packed in big endian within a byte. - */ -class BitBuffer { - - /*---- Fields ----*/ -private: - - std::vector data; - int bitLength; - - - - /*---- Constructor ----*/ -public: - - // Creates an empty bit buffer (length 0). - BitBuffer(); - - - - /*---- Methods ----*/ -public: - - // Returns the number of bits in the buffer, which is a non-negative value. - int getBitLength() const; - - - // Returns a copy of all bytes, padding up to the nearest byte. - std::vector getBytes() const; - - - // Appends the given number of bits of the given value to this sequence. - // If 0 <= len <= 31, then this requires 0 <= val < 2^len. - void appendBits(uint32_t val, int len); - - - // Appends the data of the given segment to this bit buffer. - void appendData(const QrSegment &seg); - -}; - -} diff --git a/LNURLPoS/libraries/QRCode/tests/QrCode.cpp b/LNURLPoS/libraries/QRCode/tests/QrCode.cpp deleted file mode 100644 index cdb4246..0000000 --- a/LNURLPoS/libraries/QRCode/tests/QrCode.cpp +++ /dev/null @@ -1,616 +0,0 @@ -/* - * QR Code generator library (C++) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/qr-code-generator-library - * - * (MIT License) - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - The Software is provided "as is", without warranty of any kind, express or - * implied, including but not limited to the warranties of merchantability, - * fitness for a particular purpose and noninfringement. In no event shall the - * authors or copyright holders be liable for any claim, damages or other - * liability, whether in an action of contract, tort or otherwise, arising from, - * out of or in connection with the Software or the use or other dealings in the - * Software. - */ - -#include -#include -#include -#include -#include -#include "BitBuffer.hpp" -#include "QrCode.hpp" - - -qrcodegen::QrCode::Ecc::Ecc(int ord, int fb) : - ordinal(ord), - formatBits(fb) {} - - -const qrcodegen::QrCode::Ecc qrcodegen::QrCode::Ecc::LOW (0, 1); -const qrcodegen::QrCode::Ecc qrcodegen::QrCode::Ecc::MEDIUM (1, 0); -const qrcodegen::QrCode::Ecc qrcodegen::QrCode::Ecc::QUARTILE(2, 3); -const qrcodegen::QrCode::Ecc qrcodegen::QrCode::Ecc::HIGH (3, 2); - - -qrcodegen::QrCode qrcodegen::QrCode::encodeText(const char *text, int version, const Ecc &ecl) { - std::vector segs(QrSegment::makeSegments(text)); - return encodeSegments(segs, ecl, version, version, -1, false); -} - - -qrcodegen::QrCode qrcodegen::QrCode::encodeBinary(const std::vector &data, const Ecc &ecl) { - std::vector segs; - segs.push_back(QrSegment::makeBytes(data)); - return encodeSegments(segs, ecl); -} - - -qrcodegen::QrCode qrcodegen::QrCode::encodeSegments(const std::vector &segs, const Ecc &ecl, - int minVersion, int maxVersion, int mask, bool boostEcl) { - if (!(1 <= minVersion && minVersion <= maxVersion && maxVersion <= 40) || mask < -1 || mask > 7) - throw "Invalid value"; - - // Find the minimal version number to use - int version, dataUsedBits; - for (version = minVersion; ; version++) { - int dataCapacityBits = getNumDataCodewords(version, ecl) * 8; // Number of data bits available - dataUsedBits = QrSegment::getTotalBits(segs, version); - if (dataUsedBits != -1 && dataUsedBits <= dataCapacityBits) - break; // This version number is found to be suitable - if (version >= maxVersion) // All versions in the range could not fit the given data - throw "Data too long"; - } - if (dataUsedBits == -1) - throw "Assertion error"; - - // Increase the error correction level while the data still fits in the current version number - const Ecc *newEcl = &ecl; - if (boostEcl) { - if (dataUsedBits <= getNumDataCodewords(version, Ecc::MEDIUM ) * 8) newEcl = &Ecc::MEDIUM ; - if (dataUsedBits <= getNumDataCodewords(version, Ecc::QUARTILE) * 8) newEcl = &Ecc::QUARTILE; - if (dataUsedBits <= getNumDataCodewords(version, Ecc::HIGH ) * 8) newEcl = &Ecc::HIGH ; - } - - // Create the data bit string by concatenating all segments - int dataCapacityBits = getNumDataCodewords(version, *newEcl) * 8; - BitBuffer bb; - for (size_t i = 0; i < segs.size(); i++) { - const QrSegment &seg(segs.at(i)); - bb.appendBits(seg.mode.modeBits, 4); - bb.appendBits(seg.numChars, seg.mode.numCharCountBits(version)); - bb.appendData(seg); - } - - // Add terminator and pad up to a byte if applicable - bb.appendBits(0, std::min(4, dataCapacityBits - bb.getBitLength())); - bb.appendBits(0, (8 - bb.getBitLength() % 8) % 8); - - // Pad with alternate bytes until data capacity is reached - for (uint8_t padByte = 0xEC; bb.getBitLength() < dataCapacityBits; padByte ^= 0xEC ^ 0x11) - bb.appendBits(padByte, 8); - if (bb.getBitLength() % 8 != 0) - throw "Assertion error"; - - // Create the QR Code symbol - return QrCode(version, *newEcl, bb.getBytes(), mask); -} - - -qrcodegen::QrCode::QrCode(int ver, const Ecc &ecl, const std::vector &dataCodewords, int mask) : - // Initialize scalar fields - version(ver), - size(1 <= ver && ver <= 40 ? ver * 4 + 17 : -1), // Avoid signed overflow undefined behavior - errorCorrectionLevel(ecl) { - - // Check arguments - if (ver < 1 || ver > 40 || mask < -1 || mask > 7) - throw "Value out of range"; - - std::vector row(size); - for (int i = 0; i < size; i++) { - modules.push_back(row); - isFunction.push_back(row); - } - - // Draw function patterns, draw all codewords, do masking - drawFunctionPatterns(); - const std::vector allCodewords(appendErrorCorrection(dataCodewords)); - drawCodewords(allCodewords); - this->mask = handleConstructorMasking(mask); -} - - -qrcodegen::QrCode::QrCode(const QrCode &qr, int mask) : - // Copy scalar fields - version(qr.version), - size(qr.size), - errorCorrectionLevel(qr.errorCorrectionLevel) { - - // Check arguments - if (mask < -1 || mask > 7) - throw "Mask value out of range"; - - // Handle grid fields - modules = qr.modules; - isFunction = qr.isFunction; - - // Handle masking - applyMask(qr.mask); // Undo old mask - this->mask = handleConstructorMasking(mask); -} - - -int qrcodegen::QrCode::getMask() const { - return mask; -} - - -int qrcodegen::QrCode::getModule(int x, int y) const { - if (0 <= x && x < size && 0 <= y && y < size) - return modules.at(y).at(x) ? 1 : 0; - else - return 0; // Infinite white border -} - - -std::string qrcodegen::QrCode::toSvgString(int border) const { - if (border < 0) - throw "Border must be non-negative"; - std::ostringstream sb; - sb << "\n"; - sb << "\n"; - sb << "\n"; - sb << "\t\n"; - sb << "\t\n"; - sb << "\n"; - return sb.str(); -} - - -void qrcodegen::QrCode::drawFunctionPatterns() { - // Draw the horizontal and vertical timing patterns - for (int i = 0; i < size; i++) { - setFunctionModule(6, i, i % 2 == 0); - setFunctionModule(i, 6, i % 2 == 0); - } - - // Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules) - drawFinderPattern(3, 3); - drawFinderPattern(size - 4, 3); - drawFinderPattern(3, size - 4); - - // Draw the numerous alignment patterns - const std::vector alignPatPos(getAlignmentPatternPositions(version)); - int numAlign = alignPatPos.size(); - for (int i = 0; i < numAlign; i++) { - for (int j = 0; j < numAlign; j++) { - if ((i == 0 && j == 0) || (i == 0 && j == numAlign - 1) || (i == numAlign - 1 && j == 0)) - continue; // Skip the three finder corners - else - drawAlignmentPattern(alignPatPos.at(i), alignPatPos.at(j)); - } - } - - // Draw configuration data - drawFormatBits(0); // Dummy mask value; overwritten later in the constructor - drawVersion(); -} - - -void qrcodegen::QrCode::drawFormatBits(int mask) { - // Calculate error correction code and pack bits - int data = errorCorrectionLevel.formatBits << 3 | mask; // errCorrLvl is uint2, mask is uint3 - int rem = data; - for (int i = 0; i < 10; i++) - rem = (rem << 1) ^ ((rem >> 9) * 0x537); - data = data << 10 | rem; - data ^= 0x5412; // uint15 - if (data >> 15 != 0) - throw "Assertion error"; - - // Draw first copy - for (int i = 0; i <= 5; i++) - setFunctionModule(8, i, ((data >> i) & 1) != 0); - setFunctionModule(8, 7, ((data >> 6) & 1) != 0); - setFunctionModule(8, 8, ((data >> 7) & 1) != 0); - setFunctionModule(7, 8, ((data >> 8) & 1) != 0); - for (int i = 9; i < 15; i++) - setFunctionModule(14 - i, 8, ((data >> i) & 1) != 0); - - // Draw second copy - for (int i = 0; i <= 7; i++) - setFunctionModule(size - 1 - i, 8, ((data >> i) & 1) != 0); - for (int i = 8; i < 15; i++) - setFunctionModule(8, size - 15 + i, ((data >> i) & 1) != 0); - setFunctionModule(8, size - 8, true); -} - - -void qrcodegen::QrCode::drawVersion() { - if (version < 7) - return; - - // Calculate error correction code and pack bits - int rem = version; // version is uint6, in the range [7, 40] - for (int i = 0; i < 12; i++) - rem = (rem << 1) ^ ((rem >> 11) * 0x1F25); - int data = version << 12 | rem; // uint18 - if (data >> 18 != 0) - throw "Assertion error"; - - // Draw two copies - for (int i = 0; i < 18; i++) { - bool bit = ((data >> i) & 1) != 0; - int a = size - 11 + i % 3, b = i / 3; - setFunctionModule(a, b, bit); - setFunctionModule(b, a, bit); - } -} - - -void qrcodegen::QrCode::drawFinderPattern(int x, int y) { - for (int i = -4; i <= 4; i++) { - for (int j = -4; j <= 4; j++) { - int dist = std::max(std::abs(i), std::abs(j)); // Chebyshev/infinity norm - int xx = x + j, yy = y + i; - if (0 <= xx && xx < size && 0 <= yy && yy < size) - setFunctionModule(xx, yy, dist != 2 && dist != 4); - } - } -} - - -void qrcodegen::QrCode::drawAlignmentPattern(int x, int y) { - for (int i = -2; i <= 2; i++) { - for (int j = -2; j <= 2; j++) - setFunctionModule(x + j, y + i, std::max(std::abs(i), std::abs(j)) != 1); - } -} - - -void qrcodegen::QrCode::setFunctionModule(int x, int y, bool isBlack) { - modules.at(y).at(x) = isBlack; - isFunction.at(y).at(x) = true; -} - - -std::vector qrcodegen::QrCode::appendErrorCorrection(const std::vector &data) const { - if (data.size() != static_cast(getNumDataCodewords(version, errorCorrectionLevel))) - throw "Invalid argument"; - - // Calculate parameter numbers - int numBlocks = NUM_ERROR_CORRECTION_BLOCKS[errorCorrectionLevel.ordinal][version]; - int totalEcc = NUM_ERROR_CORRECTION_CODEWORDS[errorCorrectionLevel.ordinal][version]; - if (totalEcc % numBlocks != 0) - throw "Assertion error"; - int blockEccLen = totalEcc / numBlocks; - int numShortBlocks = numBlocks - getNumRawDataModules(version) / 8 % numBlocks; - int shortBlockLen = getNumRawDataModules(version) / 8 / numBlocks; - - // Split data into blocks and append ECC to each block - std::vector > blocks; - const ReedSolomonGenerator rs(blockEccLen); - for (int i = 0, k = 0; i < numBlocks; i++) { - std::vector dat; - dat.insert(dat.begin(), data.begin() + k, data.begin() + (k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1))); - k += dat.size(); - const std::vector ecc(rs.getRemainder(dat)); - if (i < numShortBlocks) - dat.push_back(0); - dat.insert(dat.end(), ecc.begin(), ecc.end()); - blocks.push_back(dat); - } - - // Interleave (not concatenate) the bytes from every block into a single sequence - std::vector result; - for (int i = 0; static_cast(i) < blocks.at(0).size(); i++) { - for (int j = 0; static_cast(j) < blocks.size(); j++) { - // Skip the padding byte in short blocks - if (i != shortBlockLen - blockEccLen || j >= numShortBlocks) - result.push_back(blocks.at(j).at(i)); - } - } - if (result.size() != static_cast(getNumRawDataModules(version) / 8)) - throw "Assertion error"; - return result; -} - - -void qrcodegen::QrCode::drawCodewords(const std::vector &data) { - if (data.size() != static_cast(getNumRawDataModules(version) / 8)) - throw "Invalid argument"; - - size_t i = 0; // Bit index into the data - // Do the funny zigzag scan - for (int right = size - 1; right >= 1; right -= 2) { // Index of right column in each column pair - if (right == 6) - right = 5; - for (int vert = 0; vert < size; vert++) { // Vertical counter - for (int j = 0; j < 2; j++) { - int x = right - j; // Actual x coordinate - bool upwards = ((right & 2) == 0) ^ (x < 6); - int y = upwards ? size - 1 - vert : vert; // Actual y coordinate - if (!isFunction.at(y).at(x) && i < data.size() * 8) { - modules.at(y).at(x) = ((data.at(i >> 3) >> (7 - (i & 7))) & 1) != 0; - i++; - } - // If there are any remainder bits (0 to 7), they are already - // set to 0/false/white when the grid of modules was initialized - } - } - } - if (static_cast(i) != data.size() * 8) - throw "Assertion error"; -} - - -void qrcodegen::QrCode::applyMask(int mask) { - if (mask < 0 || mask > 7) - throw "Mask value out of range"; - for (int y = 0; y < size; y++) { - for (int x = 0; x < size; x++) { - bool invert; - switch (mask) { - case 0: invert = (x + y) % 2 == 0; break; - case 1: invert = y % 2 == 0; break; - case 2: invert = x % 3 == 0; break; - case 3: invert = (x + y) % 3 == 0; break; - case 4: invert = (x / 3 + y / 2) % 2 == 0; break; - case 5: invert = x * y % 2 + x * y % 3 == 0; break; - case 6: invert = (x * y % 2 + x * y % 3) % 2 == 0; break; - case 7: invert = ((x + y) % 2 + x * y % 3) % 2 == 0; break; - default: throw "Assertion error"; - } - modules.at(y).at(x) = modules.at(y).at(x) ^ (invert & !isFunction.at(y).at(x)); - } - } -} - - -int qrcodegen::QrCode::handleConstructorMasking(int mask) { - if (mask == -1) { // Automatically choose best mask - int32_t minPenalty = INT32_MAX; - for (int i = 0; i < 8; i++) { - drawFormatBits(i); - applyMask(i); - int penalty = getPenaltyScore(); - if (penalty < minPenalty) { - mask = i; - minPenalty = penalty; - } - applyMask(i); // Undoes the mask due to XOR - } - } - if (mask < 0 || mask > 7) - throw "Assertion error"; - drawFormatBits(mask); // Overwrite old format bits - applyMask(mask); // Apply the final choice of mask - return mask; // The caller shall assign this value to the final-declared field -} - - -int qrcodegen::QrCode::getPenaltyScore() const { - int result = 0; - - // Adjacent modules in row having same color - for (int y = 0; y < size; y++) { - bool colorX = modules.at(y).at(0); - for (int x = 1, runX = 1; x < size; x++) { - if (modules.at(y).at(x) != colorX) { - colorX = modules.at(y).at(x); - runX = 1; - } else { - runX++; - if (runX == 5) - result += PENALTY_N1; - else if (runX > 5) - result++; - } - } - } - // Adjacent modules in column having same color - for (int x = 0; x < size; x++) { - bool colorY = modules.at(0).at(x); - for (int y = 1, runY = 1; y < size; y++) { - if (modules.at(y).at(x) != colorY) { - colorY = modules.at(y).at(x); - runY = 1; - } else { - runY++; - if (runY == 5) - result += PENALTY_N1; - else if (runY > 5) - result++; - } - } - } - - // 2*2 blocks of modules having same color - for (int y = 0; y < size - 1; y++) { - for (int x = 0; x < size - 1; x++) { - bool color = modules.at(y).at(x); - if ( color == modules.at(y).at(x + 1) && - color == modules.at(y + 1).at(x) && - color == modules.at(y + 1).at(x + 1)) - result += PENALTY_N2; - } - } - - // Finder-like pattern in rows - for (int y = 0; y < size; y++) { - for (int x = 0, bits = 0; x < size; x++) { - bits = ((bits << 1) & 0x7FF) | (modules.at(y).at(x) ? 1 : 0); - if (x >= 10 && (bits == 0x05D || bits == 0x5D0)) // Needs 11 bits accumulated - result += PENALTY_N3; - } - } - // Finder-like pattern in columns - for (int x = 0; x < size; x++) { - for (int y = 0, bits = 0; y < size; y++) { - bits = ((bits << 1) & 0x7FF) | (modules.at(y).at(x) ? 1 : 0); - if (y >= 10 && (bits == 0x05D || bits == 0x5D0)) // Needs 11 bits accumulated - result += PENALTY_N3; - } - } - - // Balance of black and white modules - int black = 0; - for (int y = 0; y < size; y++) { - for (int x = 0; x < size; x++) { - if (modules.at(y).at(x)) - black++; - } - } - int total = size * size; - // Find smallest k such that (45-5k)% <= dark/total <= (55+5k)% - for (int k = 0; black*20 < (9-k)*total || black*20 > (11+k)*total; k++) - result += PENALTY_N4; - return result; -} - - -std::vector qrcodegen::QrCode::getAlignmentPatternPositions(int ver) { - if (ver < 1 || ver > 40) - throw "Version number out of range"; - else if (ver == 1) - return std::vector(); - else { - int numAlign = ver / 7 + 2; - int step; - if (ver != 32) - step = (ver * 4 + numAlign * 2 + 1) / (2 * numAlign - 2) * 2; // ceil((size - 13) / (2*numAlign - 2)) * 2 - else // C-C-C-Combo breaker! - step = 26; - - std::vector result; - int size = ver * 4 + 17; - for (int i = 0, pos = size - 7; i < numAlign - 1; i++, pos -= step) - result.insert(result.begin(), pos); - result.insert(result.begin(), 6); - return result; - } -} - - -int qrcodegen::QrCode::getNumRawDataModules(int ver) { - if (ver < 1 || ver > 40) - throw "Version number out of range"; - int result = (16 * ver + 128) * ver + 64; - if (ver >= 2) { - int numAlign = ver / 7 + 2; - result -= (25 * numAlign - 10) * numAlign - 55; - if (ver >= 7) - result -= 18 * 2; // Subtract version information - } - return result; -} - - -int qrcodegen::QrCode::getNumDataCodewords(int ver, const Ecc &ecl) { - if (ver < 1 || ver > 40) - throw "Version number out of range"; - return getNumRawDataModules(ver) / 8 - NUM_ERROR_CORRECTION_CODEWORDS[ecl.ordinal][ver]; -} - - -/*---- Tables of constants ----*/ - -const int qrcodegen::QrCode::PENALTY_N1 = 3; -const int qrcodegen::QrCode::PENALTY_N2 = 3; -const int qrcodegen::QrCode::PENALTY_N3 = 40; -const int qrcodegen::QrCode::PENALTY_N4 = 10; - - -const int16_t qrcodegen::QrCode::NUM_ERROR_CORRECTION_CODEWORDS[4][41] = { - // Version: (note that index 0 is for padding, and is set to an illegal value) - //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level - {-1, 7, 10, 15, 20, 26, 36, 40, 48, 60, 72, 80, 96, 104, 120, 132, 144, 168, 180, 196, 224, 224, 252, 270, 300, 312, 336, 360, 390, 420, 450, 480, 510, 540, 570, 570, 600, 630, 660, 720, 750}, // Low - {-1, 10, 16, 26, 36, 48, 64, 72, 88, 110, 130, 150, 176, 198, 216, 240, 280, 308, 338, 364, 416, 442, 476, 504, 560, 588, 644, 700, 728, 784, 812, 868, 924, 980, 1036, 1064, 1120, 1204, 1260, 1316, 1372}, // Medium - {-1, 13, 22, 36, 52, 72, 96, 108, 132, 160, 192, 224, 260, 288, 320, 360, 408, 448, 504, 546, 600, 644, 690, 750, 810, 870, 952, 1020, 1050, 1140, 1200, 1290, 1350, 1440, 1530, 1590, 1680, 1770, 1860, 1950, 2040}, // Quartile - {-1, 17, 28, 44, 64, 88, 112, 130, 156, 192, 224, 264, 308, 352, 384, 432, 480, 532, 588, 650, 700, 750, 816, 900, 960, 1050, 1110, 1200, 1260, 1350, 1440, 1530, 1620, 1710, 1800, 1890, 1980, 2100, 2220, 2310, 2430}, // High -}; - -const int8_t qrcodegen::QrCode::NUM_ERROR_CORRECTION_BLOCKS[4][41] = { - // Version: (note that index 0 is for padding, and is set to an illegal value) - //0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level - {-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25}, // Low - {-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49}, // Medium - {-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68}, // Quartile - {-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81}, // High -}; - - -qrcodegen::QrCode::ReedSolomonGenerator::ReedSolomonGenerator(int degree) : - coefficients() { - if (degree < 1 || degree > 255) - throw "Degree out of range"; - - // Start with the monomial x^0 - coefficients.resize(degree); - coefficients.at(degree - 1) = 1; - - // Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}), - // drop the highest term, and store the rest of the coefficients in order of descending powers. - // Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D). - int root = 1; - for (int i = 0; i < degree; i++) { - // Multiply the current product by (x - r^i) - for (size_t j = 0; j < coefficients.size(); j++) { - coefficients.at(j) = multiply(coefficients.at(j), static_cast(root)); - if (j + 1 < coefficients.size()) - coefficients.at(j) ^= coefficients.at(j + 1); - } - root = (root << 1) ^ ((root >> 7) * 0x11D); // Multiply by 0x02 mod GF(2^8/0x11D) - } -} - - -std::vector qrcodegen::QrCode::ReedSolomonGenerator::getRemainder(const std::vector &data) const { - // Compute the remainder by performing polynomial division - std::vector result(coefficients.size()); - for (size_t i = 0; i < data.size(); i++) { - uint8_t factor = data.at(i) ^ result.at(0); - result.erase(result.begin()); - result.push_back(0); - for (size_t j = 0; j < result.size(); j++) - result.at(j) ^= multiply(coefficients.at(j), factor); - } - return result; -} - - -uint8_t qrcodegen::QrCode::ReedSolomonGenerator::multiply(uint8_t x, uint8_t y) { - // Russian peasant multiplication - int z = 0; - for (int i = 7; i >= 0; i--) { - z = (z << 1) ^ ((z >> 7) * 0x11D); - z ^= ((y >> i) & 1) * x; - } - if (z >> 8 != 0) - throw "Assertion error"; - return static_cast(z); -} diff --git a/LNURLPoS/libraries/QRCode/tests/QrCode.hpp b/LNURLPoS/libraries/QRCode/tests/QrCode.hpp deleted file mode 100644 index dd4dcc2..0000000 --- a/LNURLPoS/libraries/QRCode/tests/QrCode.hpp +++ /dev/null @@ -1,314 +0,0 @@ -/* - * QR Code generator library (C++) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/qr-code-generator-library - * - * (MIT License) - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - The Software is provided "as is", without warranty of any kind, express or - * implied, including but not limited to the warranties of merchantability, - * fitness for a particular purpose and noninfringement. In no event shall the - * authors or copyright holders be liable for any claim, damages or other - * liability, whether in an action of contract, tort or otherwise, arising from, - * out of or in connection with the Software or the use or other dealings in the - * Software. - */ - -#pragma once - -#include -#include -#include -#include "QrSegment.hpp" - - -namespace qrcodegen { - -/* - * Represents an immutable square grid of black and white cells for a QR Code symbol, and - * provides static functions to create a QR Code from user-supplied textual or binary data. - * This class covers the QR Code model 2 specification, supporting all versions (sizes) - * from 1 to 40, all 4 error correction levels, and only 3 character encoding modes. - */ -class QrCode { - - /*---- Public helper enumeration ----*/ -public: - - /* - * Represents the error correction level used in a QR Code symbol. - */ - class Ecc { - // Constants declared in ascending order of error protection. - public: - const static Ecc LOW, MEDIUM, QUARTILE, HIGH; - - // Fields. - public: - const int ordinal; // (Public) In the range 0 to 3 (unsigned 2-bit integer). - const int formatBits; // (Package-private) In the range 0 to 3 (unsigned 2-bit integer). - - // Constructor. - private: - Ecc(int ord, int fb); - }; - - - - /*---- Public static factory functions ----*/ -public: - - /* - * Returns a QR Code symbol representing the given Unicode text string at the given error correction level. - * As a conservative upper bound, this function is guaranteed to succeed for strings that have 738 or fewer Unicode - * code points (not UTF-16 code units). The smallest possible QR Code version is automatically chosen for the output. - * The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version. - */ - static QrCode encodeText(const char *text, int version, const Ecc &ecl); - - - /* - * Returns a QR Code symbol representing the given binary data string at the given error correction level. - * This function always encodes using the binary segment mode, not any text mode. The maximum number of - * bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output. - * The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version. - */ - static QrCode encodeBinary(const std::vector &data, const Ecc &ecl); - - - /* - * Returns a QR Code symbol representing the given data segments with the given encoding parameters. - * The smallest possible QR Code version within the given range is automatically chosen for the output. - * This function allows the user to create a custom sequence of segments that switches - * between modes (such as alphanumeric and binary) to encode text more efficiently. - * This function is considered to be lower level than simply encoding text or binary data. - */ - static QrCode encodeSegments(const std::vector &segs, const Ecc &ecl, - int minVersion=1, int maxVersion=40, int mask=-1, bool boostEcl=true); // All optional parameters - - - - /*---- Instance fields ----*/ - - // Public immutable scalar parameters -public: - - /* This QR Code symbol's version number, which is always between 1 and 40 (inclusive). */ - const int version; - - /* The width and height of this QR Code symbol, measured in modules. - * Always equal to version × 4 + 17, in the range 21 to 177. */ - const int size; - - /* The error correction level used in this QR Code symbol. */ - const Ecc &errorCorrectionLevel; - - /* The mask pattern used in this QR Code symbol, in the range 0 to 7 (i.e. unsigned 3-bit integer). - * Note that even if a constructor was called with automatic masking requested - * (mask = -1), the resulting object will still have a mask value between 0 and 7. */ -private: - int mask; - - // Private grids of modules/pixels (conceptually immutable) -private: - std::vector > modules; // The modules of this QR Code symbol (false = white, true = black) - std::vector > isFunction; // Indicates function modules that are not subjected to masking - - - - /*---- Constructors ----*/ -public: - - /* - * Creates a new QR Code symbol with the given version number, error correction level, binary data array, - * and mask number. This is a cumbersome low-level constructor that should not be invoked directly by the user. - * To go one level up, see the encodeSegments() function. - */ - QrCode(int ver, const Ecc &ecl, const std::vector &dataCodewords, int mask); - - - /* - * Creates a new QR Code symbol based on the given existing object, but with a potentially - * different mask pattern. The version, error correction level, codewords, etc. of the newly - * created object are all identical to the argument object; only the mask may differ. - */ - QrCode(const QrCode &qr, int mask); - - - - /*---- Public instance methods ----*/ -public: - - int getMask() const; - - - /* - * Returns the color of the module (pixel) at the given coordinates, which is either 0 for white or 1 for black. The top - * left corner has the coordinates (x=0, y=0). If the given coordinates are out of bounds, then 0 (white) is returned. - */ - int getModule(int x, int y) const; - - - /* - * Based on the given number of border modules to add as padding, this returns a - * string whose contents represents an SVG XML file that depicts this QR Code symbol. - * Note that Unix newlines (\n) are always used, regardless of the platform. - */ - std::string toSvgString(int border) const; - - - - /*---- Private helper methods for constructor: Drawing function modules ----*/ -private: - - void drawFunctionPatterns(); - - - // Draws two copies of the format bits (with its own error correction code) - // based on the given mask and this object's error correction level field. - void drawFormatBits(int mask); - - - // Draws two copies of the version bits (with its own error correction code), - // based on this object's version field (which only has an effect for 7 <= version <= 40). - void drawVersion(); - - - // Draws a 9*9 finder pattern including the border separator, with the center module at (x, y). - void drawFinderPattern(int x, int y); - - - // Draws a 5*5 alignment pattern, with the center module at (x, y). - void drawAlignmentPattern(int x, int y); - - - // Sets the color of a module and marks it as a function module. - // Only used by the constructor. Coordinates must be in range. - void setFunctionModule(int x, int y, bool isBlack); - - - /*---- Private helper methods for constructor: Codewords and masking ----*/ -private: - - // Returns a new byte string representing the given data with the appropriate error correction - // codewords appended to it, based on this object's version and error correction level. - std::vector appendErrorCorrection(const std::vector &data) const; - - - // Draws the given sequence of 8-bit codewords (data and error correction) onto the entire - // data area of this QR Code symbol. Function modules need to be marked off before this is called. - void drawCodewords(const std::vector &data); - - - // XORs the data modules in this QR Code with the given mask pattern. Due to XOR's mathematical - // properties, calling applyMask(m) twice with the same value is equivalent to no change at all. - // This means it is possible to apply a mask, undo it, and try another mask. Note that a final - // well-formed QR Code symbol needs exactly one mask applied (not zero, not two, etc.). - void applyMask(int mask); - - - // A messy helper function for the constructors. This QR Code must be in an unmasked state when this - // method is called. The given argument is the requested mask, which is -1 for auto or 0 to 7 for fixed. - // This method applies and returns the actual mask chosen, from 0 to 7. - int handleConstructorMasking(int mask); - - - // Calculates and returns the penalty score based on state of this QR Code's current modules. - // This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score. - int getPenaltyScore() const; - - - - /*---- Private static helper functions ----*/ -private: - - // Returns a set of positions of the alignment patterns in ascending order. These positions are - // used on both the x and y axes. Each value in the resulting array is in the range [0, 177). - // This stateless pure function could be implemented as table of 40 variable-length lists of unsigned bytes. - static std::vector getAlignmentPatternPositions(int ver); - - - // Returns the number of raw data modules (bits) available at the given version number. - // These data modules are used for both user data codewords and error correction codewords. - // This stateless pure function could be implemented as a 40-entry lookup table. - static int getNumRawDataModules(int ver); - - - // Returns the number of 8-bit data (i.e. not error correction) codewords contained in any - // QR Code of the given version number and error correction level, with remainder bits discarded. - // This stateless pure function could be implemented as a (40*4)-cell lookup table. - static int getNumDataCodewords(int ver, const Ecc &ecl); - - - /*---- Private tables of constants ----*/ -private: - - // For use in getPenaltyScore(), when evaluating which mask is best. - static const int PENALTY_N1; - static const int PENALTY_N2; - static const int PENALTY_N3; - static const int PENALTY_N4; - - static const int16_t NUM_ERROR_CORRECTION_CODEWORDS[4][41]; - static const int8_t NUM_ERROR_CORRECTION_BLOCKS[4][41]; - - - - /*---- Private helper class ----*/ -private: - - /* - * Computes the Reed-Solomon error correction codewords for a sequence of data codewords - * at a given degree. Objects are immutable, and the state only depends on the degree. - * This class exists because the divisor polynomial does not need to be recalculated for every input. - */ - class ReedSolomonGenerator { - - /*-- Immutable field --*/ - private: - - // Coefficients of the divisor polynomial, stored from highest to lowest power, excluding the leading term which - // is always 1. For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array {255, 8, 93}. - std::vector coefficients; - - - /*-- Constructor --*/ - public: - - /* - * Creates a Reed-Solomon ECC generator for the given degree. This could be implemented - * as a lookup table over all possible parameter values, instead of as an algorithm. - */ - ReedSolomonGenerator(int degree); - - - /*-- Method --*/ - public: - - /* - * Computes and returns the Reed-Solomon error correction codewords for the given sequence of data codewords. - * The returned object is always a new byte array. This method does not alter this object's state (because it is immutable). - */ - std::vector getRemainder(const std::vector &data) const; - - - /*-- Static function --*/ - private: - - // Returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and result - // are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8. - static uint8_t multiply(uint8_t x, uint8_t y); - - }; - -}; - -} diff --git a/LNURLPoS/libraries/QRCode/tests/QrSegment.cpp b/LNURLPoS/libraries/QRCode/tests/QrSegment.cpp deleted file mode 100644 index 2ae2242..0000000 --- a/LNURLPoS/libraries/QRCode/tests/QrSegment.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - * QR Code generator library (C++) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/qr-code-generator-library - * - * (MIT License) - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - The Software is provided "as is", without warranty of any kind, express or - * implied, including but not limited to the warranties of merchantability, - * fitness for a particular purpose and noninfringement. In no event shall the - * authors or copyright holders be liable for any claim, damages or other - * liability, whether in an action of contract, tort or otherwise, arising from, - * out of or in connection with the Software or the use or other dealings in the - * Software. - */ - -#include -#include "BitBuffer.hpp" -#include "QrSegment.hpp" - - -qrcodegen::QrSegment::Mode::Mode(int mode, int cc0, int cc1, int cc2) : - modeBits(mode) { - numBitsCharCount[0] = cc0; - numBitsCharCount[1] = cc1; - numBitsCharCount[2] = cc2; -} - - -int qrcodegen::QrSegment::Mode::numCharCountBits(int ver) const { - if ( 1 <= ver && ver <= 9) return numBitsCharCount[0]; - else if (10 <= ver && ver <= 26) return numBitsCharCount[1]; - else if (27 <= ver && ver <= 40) return numBitsCharCount[2]; - else throw "Version number out of range"; -} - - -const qrcodegen::QrSegment::Mode qrcodegen::QrSegment::Mode::NUMERIC (0x1, 10, 12, 14); -const qrcodegen::QrSegment::Mode qrcodegen::QrSegment::Mode::ALPHANUMERIC(0x2, 9, 11, 13); -const qrcodegen::QrSegment::Mode qrcodegen::QrSegment::Mode::BYTE (0x4, 8, 16, 16); -const qrcodegen::QrSegment::Mode qrcodegen::QrSegment::Mode::KANJI (0x8, 8, 10, 12); - - - -qrcodegen::QrSegment qrcodegen::QrSegment::makeBytes(const std::vector &data) { - return QrSegment(Mode::BYTE, data.size(), data, data.size() * 8); -} - - -qrcodegen::QrSegment qrcodegen::QrSegment::makeNumeric(const char *digits) { - BitBuffer bb; - int accumData = 0; - int accumCount = 0; - int charCount = 0; - for (; *digits != '\0'; digits++, charCount++) { - char c = *digits; - if (c < '0' || c > '9') - throw "String contains non-numeric characters"; - accumData = accumData * 10 + (c - '0'); - accumCount++; - if (accumCount == 3) { - bb.appendBits(accumData, 10); - accumData = 0; - accumCount = 0; - } - } - if (accumCount > 0) // 1 or 2 digits remaining - bb.appendBits(accumData, accumCount * 3 + 1); - return QrSegment(Mode::NUMERIC, charCount, bb.getBytes(), bb.getBitLength()); -} - - -qrcodegen::QrSegment qrcodegen::QrSegment::makeAlphanumeric(const char *text) { - BitBuffer bb; - int accumData = 0; - int accumCount = 0; - int charCount = 0; - for (; *text != '\0'; text++, charCount++) { - char c = *text; - if (c < ' ' || c > 'Z') - throw "String contains unencodable characters in alphanumeric mode"; - accumData = accumData * 45 + ALPHANUMERIC_ENCODING_TABLE[c - ' ']; - accumCount++; - if (accumCount == 2) { - bb.appendBits(accumData, 11); - accumData = 0; - accumCount = 0; - } - } - if (accumCount > 0) // 1 character remaining - bb.appendBits(accumData, 6); - return QrSegment(Mode::ALPHANUMERIC, charCount, bb.getBytes(), bb.getBitLength()); -} - - -std::vector qrcodegen::QrSegment::makeSegments(const char *text) { - // Select the most efficient segment encoding automatically - std::vector result; - if (*text == '\0'); // Leave the vector empty - else if (QrSegment::isNumeric(text)) - result.push_back(QrSegment::makeNumeric(text)); - else if (QrSegment::isAlphanumeric(text)) - result.push_back(QrSegment::makeAlphanumeric(text)); - else { - std::vector bytes; - for (; *text != '\0'; text++) - bytes.push_back(static_cast(*text)); - result.push_back(QrSegment::makeBytes(bytes)); - } - return result; -} - - -qrcodegen::QrSegment::QrSegment(const Mode &md, int numCh, const std::vector &b, int bitLen) : - mode(md), - numChars(numCh), - data(b), - bitLength(bitLen) { - if (numCh < 0 || bitLen < 0 || b.size() != static_cast((bitLen + 7) / 8)) - throw "Invalid value"; -} - - -int qrcodegen::QrSegment::getTotalBits(const std::vector &segs, int version) { - if (version < 1 || version > 40) - throw "Version number out of range"; - int result = 0; - for (size_t i = 0; i < segs.size(); i++) { - const QrSegment &seg(segs.at(i)); - int ccbits = seg.mode.numCharCountBits(version); - // Fail if segment length value doesn't fit in the length field's bit-width - if (seg.numChars >= (1 << ccbits)) - return -1; - result += 4 + ccbits + seg.bitLength; - } - return result; -} - - -bool qrcodegen::QrSegment::isAlphanumeric(const char *text) { - for (; *text != '\0'; text++) { - char c = *text; - if (c < ' ' || c > 'Z' || ALPHANUMERIC_ENCODING_TABLE[c - ' '] == -1) - return false; - } - return true; -} - - -bool qrcodegen::QrSegment::isNumeric(const char *text) { - for (; *text != '\0'; text++) { - char c = *text; - if (c < '0' || c > '9') - return false; - } - return true; -} - - -const int8_t qrcodegen::QrSegment::ALPHANUMERIC_ENCODING_TABLE[59] = { - // SP, !, ", #, $, %, &, ', (, ), *, +, ,, -, ., /, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, ;, <, =, >, ?, @, // ASCII codes 32 to 64 - 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1, -1, // Array indices 0 to 32 - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, // Array indices 33 to 58 - // A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, // ASCII codes 65 to 90 -}; diff --git a/LNURLPoS/libraries/QRCode/tests/QrSegment.hpp b/LNURLPoS/libraries/QRCode/tests/QrSegment.hpp deleted file mode 100644 index 87ac55c..0000000 --- a/LNURLPoS/libraries/QRCode/tests/QrSegment.hpp +++ /dev/null @@ -1,170 +0,0 @@ -/* - * QR Code generator library (C++) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/qr-code-generator-library - * - * (MIT License) - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - The Software is provided "as is", without warranty of any kind, express or - * implied, including but not limited to the warranties of merchantability, - * fitness for a particular purpose and noninfringement. In no event shall the - * authors or copyright holders be liable for any claim, damages or other - * liability, whether in an action of contract, tort or otherwise, arising from, - * out of or in connection with the Software or the use or other dealings in the - * Software. - */ - -#pragma once - -#include -#include - - -namespace qrcodegen { - -/* - * Represents a character string to be encoded in a QR Code symbol. Each segment has - * a mode, and a sequence of characters that is already encoded as a sequence of bits. - * Instances of this class are immutable. - * This segment class imposes no length restrictions, but QR Codes have restrictions. - * Even in the most favorable conditions, a QR Code can only hold 7089 characters of data. - * Any segment longer than this is meaningless for the purpose of generating QR Codes. - */ -class QrSegment { - - /*---- Public helper enumeration ----*/ - - /* - * The mode field of a segment. Immutable. Provides methods to retrieve closely related values. - */ -public: - class Mode { - - /*-- Constants --*/ - public: - - static const Mode NUMERIC; - static const Mode ALPHANUMERIC; - static const Mode BYTE; - static const Mode KANJI; - - - /*-- Fields --*/ - - /* (Package-private) An unsigned 4-bit integer value (range 0 to 15) representing the mode indicator bits for this mode object. */ - public: - const int modeBits; - - private: - int numBitsCharCount[3]; - - - /*-- Constructor --*/ - - private: - Mode(int mode, int cc0, int cc1, int cc2); - - - /*-- Method --*/ - - /* - * (Package-private) Returns the bit width of the segment character count field for this mode object at the given version number. - */ - public: - int numCharCountBits(int ver) const; - - }; - - - - /*---- Public static factory functions ----*/ -public: - - /* - * Returns a segment representing the given binary data encoded in byte mode. - */ - static QrSegment makeBytes(const std::vector &data); - - - /* - * Returns a segment representing the given string of decimal digits encoded in numeric mode. - */ - static QrSegment makeNumeric(const char *digits); - - - /* - * Returns a segment representing the given text string encoded in alphanumeric mode. The characters allowed are: - * 0 to 9, A to Z (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon. - */ - static QrSegment makeAlphanumeric(const char *text); - - - /* - * Returns a list of zero or more segments to represent the given text string. - * The result may use various segment modes and switch modes to optimize the length of the bit stream. - */ - static std::vector makeSegments(const char *text); - - - /*---- Public static helper functions ----*/ -public: - - /* - * Tests whether the given string can be encoded as a segment in alphanumeric mode. - */ - static bool isAlphanumeric(const char *text); - - - /* - * Tests whether the given string can be encoded as a segment in numeric mode. - */ - static bool isNumeric(const char *text); - - - - /*---- Instance fields ----*/ -public: - - /* The mode indicator for this segment. */ - const Mode mode; - - /* The length of this segment's unencoded data, measured in characters. Always zero or positive. */ - const int numChars; - - /* The bits of this segment packed into a byte array in big endian. */ - const std::vector data; - - /* The length of this segment's encoded data, measured in bits. Satisfies ceil(bitLength / 8) = data.size(). */ - const int bitLength; - - - /*---- Constructor ----*/ -public: - - /* - * Creates a new QR Code data segment with the given parameters and data. - */ - QrSegment(const Mode &md, int numCh, const std::vector &b, int bitLen); - - - // Package-private helper function. - static int getTotalBits(const std::vector &segs, int version); - - - /*---- Private constant ----*/ -private: - - /* Maps shifted ASCII codes to alphanumeric mode character codes. */ - static const int8_t ALPHANUMERIC_ENCODING_TABLE[59]; - -}; - -} diff --git a/LNURLPoS/libraries/QRCode/tests/README.md b/LNURLPoS/libraries/QRCode/tests/README.md deleted file mode 100644 index ce157a3..0000000 --- a/LNURLPoS/libraries/QRCode/tests/README.md +++ /dev/null @@ -1,12 +0,0 @@ -Testing -======= - -The testcases work by using the Nayuki QR code generating library, generating a QR code -in both libraries and comparing them. - -Running -------- - -``` -./run.sh -``` diff --git a/LNURLPoS/libraries/QRCode/tests/run-tests.cpp b/LNURLPoS/libraries/QRCode/tests/run-tests.cpp deleted file mode 100644 index 13565d4..0000000 --- a/LNURLPoS/libraries/QRCode/tests/run-tests.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include -#include - -#include "../src/qrcode.h" -#include "QrCode.hpp" - -static uint32_t check(const qrcodegen::QrCode &nayuki, QRCode *ricmoo) { - uint32_t wrong = 0; - - if (nayuki.size != ricmoo->size) { wrong += (1 << 20); } - - int border = 4; - for (int y = -border; y < nayuki.size + border; y++) { - for (int x = -border; x < nayuki.size + border; x++) { - if (!!nayuki.getModule(x, y) != qrcode_getModule(ricmoo, x, y)) { - wrong++; - } - } - } - - return wrong; -} - -int main() { - std::clock_t t0, totalNayuki, totalRicMoo; - - int total = 0, passed = 0; - for (char version = 1; version <= 40; version++) { - if (LOCK_VERSION != 0 && LOCK_VERSION != version) { continue; } - - for (char ecc = 0; ecc < 4; ecc++) { - const qrcodegen::QrCode::Ecc *errCorLvl; - switch (ecc) { - case 0: - errCorLvl = &qrcodegen::QrCode::Ecc::LOW; - break; - case 1: - errCorLvl = &qrcodegen::QrCode::Ecc::MEDIUM; - break; - case 2: - errCorLvl = &qrcodegen::QrCode::Ecc::QUARTILE; - break; - case 3: - errCorLvl = &qrcodegen::QrCode::Ecc::HIGH; - break; - } - - for (char tc = 0; tc < 3; tc++) { - char *data; - switch(tc) { - case 0: - data = (char*)"HELLO"; - break; - case 1: - data = (char*)"Hello"; - break; - case 2: - data = (char*)"1234"; - break; - } - t0 = std::clock(); - const qrcodegen::QrCode nayuki = qrcodegen::QrCode::encodeText(data, version, *errCorLvl); - totalNayuki += std::clock() - t0; - - t0 = std::clock(); - QRCode ricmoo; - uint8_t ricmooBytes[qrcode_getBufferSize(version)]; - qrcode_initText(&ricmoo, ricmooBytes, version, ecc, data); - totalRicMoo += std::clock() - t0; - - uint32_t badModules = check(nayuki, &ricmoo); - if (badModules) { - printf("Failed test case: version=%d, ecc=%d, data=\"%s\", faliured=%d\n", version, ecc, data, badModules); - } else { - passed++; - } - - total++; - } - } - } - - printf("Tests complete: %d passed (out of %d)\n", passed, total); - printf("Timing: Nayuki=%lu, RicMoo=%lu\n", totalNayuki, totalRicMoo); -} diff --git a/LNURLPoS/libraries/QRCode/tests/run.sh b/LNURLPoS/libraries/QRCode/tests/run.sh deleted file mode 100644 index ff7be5f..0000000 --- a/LNURLPoS/libraries/QRCode/tests/run.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -clang++ run-tests.cpp QrCode.cpp QrSegment.cpp BitBuffer.cpp ../src/qrcode.c -o test && ./test -clang++ run-tests.cpp QrCode.cpp QrSegment.cpp BitBuffer.cpp ../src/qrcode.c -o test -D LOCK_VERSION=3 && ./test - diff --git a/LNURLPoS/libraries/QRCode/src/qrcode.c b/LNURLPoS/libraries/qrhelper/qrhelper.c similarity index 99% rename from LNURLPoS/libraries/QRCode/src/qrcode.c rename to LNURLPoS/libraries/qrhelper/qrhelper.c index 940c06e..1f2c270 100644 --- a/LNURLPoS/libraries/QRCode/src/qrcode.c +++ b/LNURLPoS/libraries/qrhelper/qrhelper.c @@ -29,7 +29,7 @@ * See: https://github.com/nayuki/QR-Code-generator/tree/master/cpp */ -#include "qrcode.h" +#include "qrhelper.h" #include #include diff --git a/LNURLPoS/libraries/QRCode/src/qrcode.h b/LNURLPoS/libraries/qrhelper/qrhelper.h similarity index 97% rename from LNURLPoS/libraries/QRCode/src/qrcode.h rename to LNURLPoS/libraries/qrhelper/qrhelper.h index ef429d7..a817a1a 100644 --- a/LNURLPoS/libraries/QRCode/src/qrcode.h +++ b/LNURLPoS/libraries/qrhelper/qrhelper.h @@ -30,8 +30,8 @@ */ -#ifndef __QRCODE_H_ -#define __QRCODE_H_ +#ifndef __QRHELPER_H_ +#define __QRHELPER_H_ #ifndef __cplusplus typedef unsigned char bool; @@ -92,4 +92,4 @@ bool qrcode_getModule(QRCode *qrcode, uint8_t x, uint8_t y); #endif /* __cplusplus */ -#endif /* __QRCODE_H_ */ +#endif /* __QRHELPER_H_ */ diff --git a/LNURLPoS/libraries/uBitcoin/examples/mnemonic/mnemonic.ino b/LNURLPoS/libraries/uBitcoin/examples/mnemonic/mnemonic.ino index 359a001..8730c21 100644 --- a/LNURLPoS/libraries/uBitcoin/examples/mnemonic/mnemonic.ino +++ b/LNURLPoS/libraries/uBitcoin/examples/mnemonic/mnemonic.ino @@ -37,6 +37,15 @@ void printHD(String mnemonic, String password = ""){ void setup() { Serial.begin(115200); printHD("arch volcano urge cradle turn labor skin secret squeeze denial jacket vintage fix glad lemon", "my secret password"); + + // entropy bytes to mnemonic + uint8_t arr[] = {'1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'}; + String mn = mnemonicFromEntropy(arr, sizeof(arr)); + Serial.println(mn); + uint8_t out[16]; + size_t len = mnemonicToEntropy(mn, out, sizeof(out)); + Serial.println(toHex(out, len)); + } void loop() { diff --git a/LNURLPoS/libraries/uBitcoin/library.json b/LNURLPoS/libraries/uBitcoin/library.json index d9b973d..5372620 100644 --- a/LNURLPoS/libraries/uBitcoin/library.json +++ b/LNURLPoS/libraries/uBitcoin/library.json @@ -1,6 +1,6 @@ { "name": "uBitcoin", - "version": "0.1.1", + "version": "0.1.2", "description": "Brings Bitcoin to embedded devices. Write your own hardware wallet, vending machine or any other bitcoin-powered device. Supports public and private keys, HD wallets, transactions and scripts. Everything required to start working with Bitcoin on microcontrollers.", "keywords": "bitcoin, cryptography", "repository": diff --git a/LNURLPoS/libraries/uBitcoin/library.properties b/LNURLPoS/libraries/uBitcoin/library.properties index 715ec12..224e9a2 100644 --- a/LNURLPoS/libraries/uBitcoin/library.properties +++ b/LNURLPoS/libraries/uBitcoin/library.properties @@ -1,5 +1,5 @@ name=uBitcoin -version=0.1.1 +version=0.1.2 author=Stepan Snigirev maintainer=Stepan Snigirev sentence=Brings Bitcoin to embedded devices diff --git a/LNURLPoS/libraries/uBitcoin/src/Bitcoin.cpp b/LNURLPoS/libraries/uBitcoin/src/Bitcoin.cpp index c8e7582..8a8d979 100644 --- a/LNURLPoS/libraries/uBitcoin/src/Bitcoin.cpp +++ b/LNURLPoS/libraries/uBitcoin/src/Bitcoin.cpp @@ -106,6 +106,43 @@ const char * generateMnemonic(uint8_t numWords, const uint8_t * entropy_data, si size_t len = numWords*4/3; return mnemonic_from_data(hash, len); } + +const char * mnemonicFromEntropy(const uint8_t * entropy_data, size_t dataLen){ + return mnemonic_from_data(entropy_data, dataLen); +} +size_t mnemonicToEntropy(const char * mnemonic, size_t mnemonicLen, uint8_t * output, size_t outputLen){ + int num_words = 1; + for (size_t i = 0; i < strlen(mnemonic); i++){ + if(mnemonic[i] == ' '){ + num_words ++; + } + } + size_t entropy_len = (num_words*4)/3; + if(outputLen < entropy_len){ + return 0; + } + uint8_t res[33] = {0}; + int r = mnemonic_to_entropy(mnemonic, res); + if(r == 0){ + return 0; + } + memcpy(output, res, entropy_len); + return entropy_len; +} +#if USE_ARDUINO_STRING +size_t mnemonicToEntropy(String mnemonic, uint8_t * output, size_t outputLen){ + return mnemonicToEntropy(mnemonic.c_str(), mnemonic.length(), output, outputLen); +} +#elif USE_STD_STRING +size_t mnemonicToEntropy(std::string mnemonic, uint8_t * output, size_t outputLen){ + return mnemonicToEntropy(mnemonic.c_str(), mnemonic.length(), output, outputLen); +} +#else +size_t mnemonicToEntropy(char * mnemonic, uint8_t * output, size_t outputLen){ + return mnemonicToEntropy(mnemonic, strlen(mnemonic), output, outputLen); +} +#endif + const char * generateMnemonic(const uint8_t * entropy_data, size_t dataLen){ return generateMnemonic(24, entropy_data, dataLen); } diff --git a/LNURLPoS/libraries/uBitcoin/src/Bitcoin.h b/LNURLPoS/libraries/uBitcoin/src/Bitcoin.h index 28599b6..9f68406 100644 --- a/LNURLPoS/libraries/uBitcoin/src/Bitcoin.h +++ b/LNURLPoS/libraries/uBitcoin/src/Bitcoin.h @@ -127,6 +127,16 @@ const char * generateMnemonic(const char * entropy_string); bool checkMnemonic(const char * mnemonic); #endif +const char * mnemonicFromEntropy(const uint8_t * entropy_data, size_t dataLen); +size_t mnemonicToEntropy(const char * mnemonic, size_t mnemonic_len, uint8_t * output, size_t outputLen); +#if USE_ARDUINO_STRING +size_t mnemonicToEntropy(String mnemonic, uint8_t * output, size_t outputLen); +#elif USE_STD_STRING +size_t mnemonicToEntropy(std::string mnemonic, uint8_t * output, size_t outputLen); +#else +size_t mnemonicToEntropy(char * mnemonic, uint8_t * output, size_t outputLen); +#endif + /** * PublicKey class. * diff --git a/LNURLPoS/libraries/uBitcoin/src/Conversion.cpp b/LNURLPoS/libraries/uBitcoin/src/Conversion.cpp index e0fe6ad..662f98f 100644 --- a/LNURLPoS/libraries/uBitcoin/src/Conversion.cpp +++ b/LNURLPoS/libraries/uBitcoin/src/Conversion.cpp @@ -121,7 +121,101 @@ size_t fromHex(const char * hex, uint8_t * array, size_t arraySize){ } #endif +/******************** Binary conversion *******************/ +size_t fromBin(const char * bin, size_t binLen, uint8_t * array, size_t arraySize){ + // array is big enough + if(arraySize*8 < binLen){ + return 0; + } + size_t len = binLen/8; + if(binLen % 8 != 0){ + len += 1; // not aligned to 8 bits + } + // zero output array + memset(array, 0, arraySize); + for(size_t i = 0; i < binLen; i++){ + // we go in reverse order (from the end of the string) + uint8_t exp = (i%8); // shift + uint8_t n = (i/8); // current byte from the end + char c = bin[binLen-i-1]; + if(c == '1'){ + // set bit + array[len-n-1] |= (1<> j) & 1) == 1){ + output[8*i+(7-j)] = '1'; + }else{ + output[8*i+(7-j)] = '0'; + } + } + } + return 8*arraySize; +} + +#if USE_ARDUINO_STRING || USE_STD_STRING +String toBin(const uint8_t * array, size_t arraySize){ + char * output; + size_t outputSize = arraySize * 8 + 1; + output = (char *) malloc(outputSize); + + toBin(array, arraySize, output, outputSize); + + String result(output); + + memset(output, 0, outputSize); + free(output); + + return result; +} +#endif +#if USE_ARDUINO_STRING +size_t toBin(uint8_t v, Print &s){ + for(int i=7; i>=0; i--){ + if(((v>>i) & 1)==1){ + s.print('1'); + }else{ + s.print('0'); + } + } + return 8; +} + +size_t toBin(const uint8_t * array, size_t arraySize, Print &s){ + size_t l = 0; + for(int i=0; i Date: Mon, 20 Dec 2021 19:28:47 -0800 Subject: [PATCH 2/4] ready to burn --- .gitignore | 1 + LNURLPoS/LNURLPoS.ino | 36 ++++++++++++++++++++---------------- readserial.py | 14 ++++++++++++++ requirements.txt | 1 + 4 files changed, 36 insertions(+), 16 deletions(-) create mode 100644 .gitignore create mode 100644 readserial.py create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cdb93cd --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.python-version diff --git a/LNURLPoS/LNURLPoS.ino b/LNURLPoS/LNURLPoS.ino index 40ed925..afc95ce 100644 --- a/LNURLPoS/LNURLPoS.ino +++ b/LNURLPoS/LNURLPoS.ino @@ -3,7 +3,6 @@ #include "TFT_eSPI.h" #include #include -//#include "qrcode.h" #include "qrhelper.h" #include "Bitcoin.h" #include @@ -14,9 +13,13 @@ ////////CHANGE! USE LNURLPoS EXTENSION IN LNBITS//////// //////////////////////////////////////////////////////// -String server = "https://legend.lnbits.com"; -String posId = "JXMhZd8iQFWV9inTsb6vKc"; -String key = "Enrt4QzajadmSu6hbwTxFz"; +//{'currency': 'USD', 'id': 'G6wTqxZyNr5HktBUSxq3zq', +//'key': 'hdZd2A8pCuyYwiJiUaykQb', 'timestamp': 1640057015, +//'title': 'rapaygp POS'} + +String server = "https://api.rapaygo.com"; +String posId = "G6wTqxZyNr5HktBUSxq3zq"; +String key = "hdZd2A8pCuyYwiJiUaykQb"; String currency = "USD"; //////////////////////////////////////////////////////// @@ -61,10 +64,11 @@ String preparedURL; TFT_eSPI tft = TFT_eSPI(); SHA256 h; -//////////////KEYPAD/////////////////// + + const byte rows = 4; //four rows -const byte cols = 3; //three columns +const byte cols = 3; //four columns char keys[rows][cols] = { {'1','2','3'}, {'4','5','6'}, @@ -77,8 +81,11 @@ char keys[rows][cols] = { //byte colPins[cols] = {17, 22, 21}; //connect to the column pinouts of the keypad // 4 x 4 keypad setup -//byte rowPins[rows] = {21, 22, 17, 2}; //connect to the row pinouts of the keypad -//byte colPins[cols] = {15, 13, 12}; //connect to the column pinouts of the keypad +//byte rowPins[rows] = {37, 38, 39, 32}; //connect to the row pinouts of the keypad +//byte colPins[cols] = {33, 25, 26, 27}; //connect to the column pinouts of the keypad + +// byte rowPins[rows] = {37, 38, 39, 32}; //connect to the row pinouts of the keypad +// byte colPins[cols] = {33, 25, 26}; //connect to the column pinouts of the keypad //Small keypad setup byte rowPins[rows] = {21, 22, 17, 2}; //connect to the row pinouts of the keypad @@ -89,9 +96,6 @@ int checker = 0; char maxdig[20]; - - - //////////////MAIN/////////////////// void setup(void) { @@ -212,12 +216,12 @@ void logo(){ tft.setTextColor(TFT_WHITE, TFT_BLACK); // White characters on black background tft.setFreeFont(BIGFONT); tft.setCursor(7,70); // To be compatible with Adafruit_GFX the cursor datum is always bottom left - tft.print("LNURLPoS"); // Using tft.print means text background is NEVER rendered + tft.print("rapaygo"); // Using tft.print means text background is NEVER rendered - tft.setTextColor(TFT_PURPLE, TFT_BLACK); // White characters on black background + tft.setTextColor(TFT_GREEN, TFT_BLACK); // White characters on black background tft.setFreeFont(SMALLFONT); - tft.setCursor(42,90); // To be compatible with Adafruit_GFX the cursor datum is always bottom left - tft.print("Powered by LNbits"); // Using tft.print means text background is NEVER rendered + tft.setCursor(7,90); // To be compatible with Adafruit_GFX the cursor datum is always bottom left + tft.print("https://rapaygo.com"); // Using tft.print means text background is NEVER rendered } void to_upper(char * arr){ @@ -241,7 +245,7 @@ void makeLNURL(){ } byte payload[8]; encode_data(payload, nonce, randomPin, inputs.toInt()); - preparedURL = server + "/lnurlpos/api/v1/lnurl/"; + preparedURL = server + "/ln/rapaygo/api/v1/lnurl/"; preparedURL += toHex(nonce,8); preparedURL += "/"; preparedURL += toHex(payload, 8); diff --git a/readserial.py b/readserial.py new file mode 100644 index 0000000..1f04228 --- /dev/null +++ b/readserial.py @@ -0,0 +1,14 @@ +import serial +ser = serial.Serial('/dev/ttyACM0') +ser.baudrate = 115200 +ser.flushInput() + +while True: + try: + print('Reading...') + ser_bytes = ser.readline() + decoded_bytes = float(ser_bytes[0:len(ser_bytes)-2].decode("utf-8")) + print(decoded_bytes) + except: + print("Keyboard Interrupt") + break \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..d4d1f9b --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +pyserial \ No newline at end of file From 7ac513b35cffdbdbe1489ddec703e972657cc9bd Mon Sep 17 00:00:00 2001 From: clay Date: Wed, 22 Dec 2021 22:13:58 -0800 Subject: [PATCH 3/4] added hibernate --- LNURLPoS/LNURLPoS.ino | 255 ++++++++++----- LNURLPoS/libraries/Button2/CHANGELOG.md | 94 ++++++ LNURLPoS/libraries/Button2/LICENSE | 21 ++ LNURLPoS/libraries/Button2/README.md | 147 +++++++++ .../LongpressHandler/LongpressHandler.ino | 51 +++ .../examples/MultiHandler/MultiHandler.ino | 54 ++++ .../MultiHandlerTwoButtons.ino | 53 +++ .../MultipleButtons/MultipleButtons.ino | 45 +++ .../examples/SingleButton/SingleButton.ino | 77 +++++ .../SingleButtonSimple/SingleButtonSimple.ino | 51 +++ .../TrackDualButtonClick.ino | 64 ++++ LNURLPoS/libraries/Button2/keywords.txt | 33 ++ LNURLPoS/libraries/Button2/library.json | 17 + LNURLPoS/libraries/Button2/library.properties | 9 + LNURLPoS/libraries/Button2/src/Button2.cpp | 302 ++++++++++++++++++ LNURLPoS/libraries/Button2/src/Button2.h | 122 +++++++ 16 files changed, 1323 insertions(+), 72 deletions(-) create mode 100644 LNURLPoS/libraries/Button2/CHANGELOG.md create mode 100644 LNURLPoS/libraries/Button2/LICENSE create mode 100644 LNURLPoS/libraries/Button2/README.md create mode 100644 LNURLPoS/libraries/Button2/examples/LongpressHandler/LongpressHandler.ino create mode 100644 LNURLPoS/libraries/Button2/examples/MultiHandler/MultiHandler.ino create mode 100644 LNURLPoS/libraries/Button2/examples/MultiHandlerTwoButtons/MultiHandlerTwoButtons.ino create mode 100644 LNURLPoS/libraries/Button2/examples/MultipleButtons/MultipleButtons.ino create mode 100644 LNURLPoS/libraries/Button2/examples/SingleButton/SingleButton.ino create mode 100644 LNURLPoS/libraries/Button2/examples/SingleButtonSimple/SingleButtonSimple.ino create mode 100644 LNURLPoS/libraries/Button2/examples/TrackDualButtonClick/TrackDualButtonClick.ino create mode 100644 LNURLPoS/libraries/Button2/keywords.txt create mode 100644 LNURLPoS/libraries/Button2/library.json create mode 100644 LNURLPoS/libraries/Button2/library.properties create mode 100644 LNURLPoS/libraries/Button2/src/Button2.cpp create mode 100644 LNURLPoS/libraries/Button2/src/Button2.h diff --git a/LNURLPoS/LNURLPoS.ino b/LNURLPoS/LNURLPoS.ino index afc95ce..5f3cd62 100644 --- a/LNURLPoS/LNURLPoS.ino +++ b/LNURLPoS/LNURLPoS.ino @@ -8,19 +8,21 @@ #include #include #include +#include +#include +#include "Button2.h" + //////////////////////////////////////////////////////// ////////CHANGE! USE LNURLPoS EXTENSION IN LNBITS//////// //////////////////////////////////////////////////////// -//{'currency': 'USD', 'id': 'G6wTqxZyNr5HktBUSxq3zq', -//'key': 'hdZd2A8pCuyYwiJiUaykQb', 'timestamp': 1640057015, -//'title': 'rapaygp POS'} + String server = "https://api.rapaygo.com"; -String posId = "G6wTqxZyNr5HktBUSxq3zq"; -String key = "hdZd2A8pCuyYwiJiUaykQb"; -String currency = "USD"; +String posId = "CARSjVUFTmCQhGt5EAHkXS"; +String key = "AQ9eA4iwUg3vg4z5mapeP8"; +String currency = "USD"; //////////////////////////////////////////////////////// ////Note: See lines 75, 97, to adjust to keypad size//// @@ -28,12 +30,17 @@ String currency = "USD"; //////////////VARIABLES/////////////////// + +// app variables +int topButtonState = 0; +int bottomButtonState = 0; + String dataId = ""; bool paid = false; bool shouldSaveConfig = false; bool down = false; const char* spiffcontent = ""; -String spiffing; +String spiffing; String lnurl; String choice; String payhash; @@ -42,7 +49,7 @@ String cntr = "0"; String inputs; int keysdec; int keyssdec; -float temp; +float temp; String fiat; float satoshis; String nosats; @@ -53,6 +60,9 @@ int randomPin; bool settle = false; String preparedURL; +int countIdleMSecs = 0; +int THREE_MIN = 180000; + #include "MyFont.h" #define BIGFONT &FreeMonoBold24pt7b @@ -61,33 +71,28 @@ String preparedURL; #define SMALLFONT &FreeMonoBold9pt7b #define TINYFONT &TomThumb + +Button2 button; +#define BUTTON_TOP 35 + TFT_eSPI tft = TFT_eSPI(); SHA256 h; - +//////////////BATTERY/////////////////// +const bool shouldDisplayBatteryLevel = true; // Display the battery level on the display? const byte rows = 4; //four rows const byte cols = 3; //four columns char keys[rows][cols] = { - {'1','2','3'}, - {'4','5','6'}, - {'7','8','9'}, - {'*','0','#'} + {'1', '2', '3'}, + {'4', '5', '6'}, + {'7', '8', '9'}, + {'*', '0', '#'} }; -//Big keypad setup -//byte rowPins[rows] = {12, 13, 15, 2}; //connect to the row pinouts of the keypad -//byte colPins[cols] = {17, 22, 21}; //connect to the column pinouts of the keypad - -// 4 x 4 keypad setup -//byte rowPins[rows] = {37, 38, 39, 32}; //connect to the row pinouts of the keypad -//byte colPins[cols] = {33, 25, 26, 27}; //connect to the column pinouts of the keypad -// byte rowPins[rows] = {37, 38, 39, 32}; //connect to the row pinouts of the keypad -// byte colPins[cols] = {33, 25, 26}; //connect to the column pinouts of the keypad - -//Small keypad setup +//regular keypad setup byte rowPins[rows] = {21, 22, 17, 2}; //connect to the row pinouts of the keypad byte colPins[cols] = {15, 13, 12}; //connect to the column pinouts of the keypad @@ -100,11 +105,15 @@ char maxdig[20]; void setup(void) { Serial.begin(115200); + + button.begin(BUTTON_TOP); + button.setLongClickHandler(longpress); + pinMode (2, OUTPUT); digitalWrite(2, HIGH); h.begin(); tft.begin(); - + //Set to 3 for bigger keypad tft.setRotation(1); logo(); @@ -112,68 +121,116 @@ void setup(void) { } void loop() { + Serial.println("loop"); inputs = ""; settle = false; - displaySats(); + displaySats(); bool cntr = false; - while (cntr != true){ - char key = keypad.getKey(); - if (key != NO_KEY){ - virtkey = String(key); - if (virtkey == "#"){ + while (cntr != true) { + + + + char key = keypad.getKey(); + + if (key != NO_KEY) { + countIdleMSecs = 0; + virtkey = String(key); + if (virtkey == "#") { makeLNURL(); qrShowCode(); int counta = 0; - while (settle != true){ - virtkey = String(keypad.getKey()); - if (virtkey == "*"){ + while (settle != true) { + virtkey = String(keypad.getKey()); + if (virtkey == "*") { tft.fillScreen(TFT_BLACK); settle = true; cntr = true; - } - else if (virtkey == "#"){ + } + else if (virtkey == "#") { showPin(); - } - } - } - - else if (virtkey == "*"){ + } + } + } + + else if (virtkey == "*") { tft.fillScreen(TFT_BLACK); tft.setCursor(0, 0); tft.setTextColor(TFT_WHITE); key_val = ""; - inputs = ""; + inputs = ""; nosats = ""; virtkey = ""; cntr = "2"; } - displaySats(); + displaySats(); + + } else { + button.loop(); + + countIdle(); + + // hibernate timeout + if (countIdleMSecs>THREE_MIN) { + esp_deep_sleep_start(); + } } } } +void countIdle() { + countIdleMSecs = countIdleMSecs+50; +// Serial.println("count "+String(countIdleMSecs)); + delay(50); +} + +void longpress(Button2& btn) { + unsigned int time = btn.wasPressedFor(); + Serial.print("You clicked "); + + //3 secs to sleep + if (time > 3000) { + Serial.println("Going to sleep now"); + delay(1000); + Serial.flush(); + esp_deep_sleep_start(); + } else if (time > 1500) { + Serial.print("a really really long time."); + + } else if (time > 1000) { + Serial.print("a really long time."); + } else if (time > 500) { + Serial.print("a long time."); + } else { + Serial.print("long."); + } + Serial.print(" ("); + Serial.print(time); + Serial.println(" ms)"); +} + + ///////////DISPLAY/////////////// -void qrShowCode(){ +void qrShowCode() { tft.fillScreen(TFT_WHITE); lnurl.toUpperCase(); const char* lnurlChar = lnurl.c_str(); QRCode qrcode; uint8_t qrcodeData[qrcode_getBufferSize(20)]; qrcode_initText(&qrcode, qrcodeData, 6, 0, lnurlChar); - for (uint8_t y = 0; y < qrcode.size; y++) { - - // Each horizontal module - for (uint8_t x = 0; x < qrcode.size; x++) { - if(qrcode_getModule(&qrcode, x, y)){ - tft.fillRect(60+3*x, 5+3*y, 3, 3, TFT_BLACK); - } - else{ - tft.fillRect(60+3*x, 5+3*y, 3, 3, TFT_WHITE); - } - } + for (uint8_t y = 0; y < qrcode.size; y++) { + + // Each horizontal module + for (uint8_t x = 0; x < qrcode.size; x++) { + if (qrcode_getModule(&qrcode, x, y)) { + tft.fillRect(60 + 3 * x, 5 + 3 * y, 3, 3, TFT_BLACK); + } + else { + tft.fillRect(60 + 3 * x, 5 + 3 * y, 3, 3, TFT_WHITE); + } } + } } void showPin() @@ -184,12 +241,12 @@ void showPin() tft.setCursor(0, 20); tft.println("PAYMENT PROOF PIN"); tft.setCursor(60, 80); - tft.setTextColor(TFT_RED, TFT_BLACK); + tft.setTextColor(TFT_RED, TFT_BLACK); tft.setFreeFont(BIGFONT); tft.println(randomPin); } -void displaySats(){ +void displaySats() { tft.fillScreen(TFT_BLACK); tft.setTextColor(TFT_WHITE, TFT_BLACK); // White characters on black background tft.setFreeFont(MIDFONT); @@ -198,7 +255,7 @@ void displaySats(){ tft.setCursor(60, 130); tft.setFreeFont(SMALLFONT); tft.println("TO RESET PRESS *"); - + inputs += virtkey; float amount = float(inputs.toInt()) / 100; tft.setFreeFont(MIDFONT); @@ -207,46 +264,79 @@ void displaySats(){ tft.setFreeFont(MIDBIGFONT); tft.setTextColor(TFT_GREEN, TFT_BLACK); tft.println(amount); + displayBatteryVoltage(); delay(100); virtkey = ""; + + } -void logo(){ +void logo() { tft.fillScreen(TFT_BLACK); tft.setTextColor(TFT_WHITE, TFT_BLACK); // White characters on black background tft.setFreeFont(BIGFONT); - tft.setCursor(7,70); // To be compatible with Adafruit_GFX the cursor datum is always bottom left + tft.setCursor(7, 70); // To be compatible with Adafruit_GFX the cursor datum is always bottom left tft.print("rapaygo"); // Using tft.print means text background is NEVER rendered tft.setTextColor(TFT_GREEN, TFT_BLACK); // White characters on black background tft.setFreeFont(SMALLFONT); - tft.setCursor(7,90); // To be compatible with Adafruit_GFX the cursor datum is always bottom left + tft.setCursor(7, 90); // To be compatible with Adafruit_GFX the cursor datum is always bottom left tft.print("https://rapaygo.com"); // Using tft.print means text background is NEVER rendered + displayBatteryVoltage(); } -void to_upper(char * arr){ +void to_upper(char * arr) { for (size_t i = 0; i < strlen(arr); i++) { - if(arr[i] >= 'a' && arr[i] <= 'z'){ + if (arr[i] >= 'a' && arr[i] <= 'z') { arr[i] = arr[i] - 'a' + 'A'; } } } +/** + Display the battery voltage +*/ +void displayBatteryVoltage() { + if (shouldDisplayBatteryLevel) { + delay(10); + uint16_t v1 = analogRead(34); + float v1Voltage = ((float)v1 / 4095.0f) * 2.0f * 3.3f * (1100.0f / 1000.0f); + + + // 80% + if (v1Voltage >= 4.02) { + tft.setTextColor(TFT_GREEN, TFT_BLACK); + } + // 50% + else if (v1Voltage >= 3.84) { + tft.setTextColor(TFT_YELLOW, TFT_BLACK); + } else { + tft.setTextColor(TFT_RED, TFT_BLACK); + } + tft.setFreeFont(SMALLFONT); + tft.setCursor(195, 16); + + int percent = round(((float)v1Voltage / 5.0f) * 100.0f); + String batteryPercent = String(percent); + tft.print(batteryPercent); + } +} + //////////LNURL AND CRYPTO/////////////// ////VERY KINDLY DONATED BY SNIGIREV!///// -void makeLNURL(){ - randomPin = random(1000,9999); +void makeLNURL() { + randomPin = random(1000, 9999); byte nonce[8]; - for(int i = 0; i < 8;i++){ + for (int i = 0; i < 8; i++) { nonce[i] = random(9); } byte payload[8]; encode_data(payload, nonce, randomPin, inputs.toInt()); preparedURL = server + "/ln/rapaygo/api/v1/lnurl/"; - preparedURL += toHex(nonce,8); + preparedURL += toHex(nonce, 8); preparedURL += "/"; preparedURL += toHex(payload, 8); preparedURL += "/"; @@ -255,25 +345,46 @@ void makeLNURL(){ char Buf[200]; preparedURL.toCharArray(Buf, 200); char *url = Buf; - byte * data = (byte *)calloc(strlen(url)*2, sizeof(byte)); + byte * data = (byte *)calloc(strlen(url) * 2, sizeof(byte)); size_t len = 0; int res = convert_bits(data, &len, 5, (byte *)url, strlen(url), 8, 1); - char * charLnurl = (char *)calloc(strlen(url)*2, sizeof(byte)); + char * charLnurl = (char *)calloc(strlen(url) * 2, sizeof(byte)); bech32_encode(charLnurl, "lnurl", data, len); to_upper(charLnurl); lnurl = charLnurl; Serial.println(lnurl); } -void encode_data(byte output[8], byte nonce[8], int pin, int amount_in_cents){ +void encode_data(byte output[8], byte nonce[8], int pin, int amount_in_cents) { SHA256 h; h.write(nonce, 8); h.write((byte *)key.c_str(), key.length()); h.end(output); output[0] = output[0] ^ ((byte)(pin & 0xFF)); output[1] = output[1] ^ ((byte)(pin >> 8)); - for(int i=0; i<4; i++){ - output[2+i] = output[2+i] ^ ((byte)(amount_in_cents & 0xFF)); + for (int i = 0; i < 4; i++) { + output[2 + i] = output[2 + i] ^ ((byte)(amount_in_cents & 0xFF)); amount_in_cents = amount_in_cents >> 8; } } + + +/* +Method to print the reason by which ESP32 +has been awaken from sleep +*/ +void print_wakeup_reason(){ + esp_sleep_wakeup_cause_t wakeup_reason; + + wakeup_reason = esp_sleep_get_wakeup_cause(); + + switch(wakeup_reason) + { + case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break; + case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break; + case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break; + case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break; + case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break; + default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break; + } +} diff --git a/LNURLPoS/libraries/Button2/CHANGELOG.md b/LNURLPoS/libraries/Button2/CHANGELOG.md new file mode 100644 index 0000000..f102fa2 --- /dev/null +++ b/LNURLPoS/libraries/Button2/CHANGELOG.md @@ -0,0 +1,94 @@ +# Changelog +- + +## Unreleased + +## [1.6.5] - 2021-09-12 +- Fixed problem with `std::function` as found by [ItsFlo](https://github.com/ItsFlo) in pull request [#29](https://github.com/LennartHennigs/Button2/pull/29) + +## [1.6.4] - 2021-09-12 +- Use `std::function` to allow C++ 11 lambda functions as suggested by [jacobdekeizer](https://github.com/jacobdekeizer) in pull request [#29](https://github.com/LennartHennigs/Button2/pull/29) + +## [1.6.3] - 2021-09-12 +- added two new examples: `[MultiHandlerTwoButtons.ino](https://github.com/LennartHennigs/Button2/blob/master/examples/MultiHandlerTwoButtons/MultiHandlerTwoButtons.ino)` and `[TrackDualButtonClick.ino](https://github.com/LennartHennigs/Button2/blob/master/examples/TrackDualButtonClick/TrackDualButtonClick.ino.ino)` +- added examples to the [README.md](https://github.com/LennartHennigs/Button2/blob/master/README.md) +- initialized `pin` in `_getState()` +- a bit of variable clean up +- updated setting of inital state of `state` and `prev_state` + +## [1.6.2] - 2021-06-22 +- initialized `pin` property to 255 instead of -1, as pointed out by [rin67630](https://github.com/rin67630) in issue [#26](https://github.com/LennartHennigs/Button2/issues/26) + + +## [1.6.1] - 2021-03-22 +- updated [README.md](https://github.com/LennartHennigs/Button2/blob/master/README.md) +- added `const` to getter functions + + +## [1.6.0] - 2021-02-10 +- added getter/setter functions for debounce, longclick and doubleclick timeouts +- removed debounce timeout parameter from `contructor` and `begin()` + + +## [1.5.4] - 2021-02-08 +- Added `getAttachPin()` function, as suggested by [madivad](https://github.com/madivad) in issue [#23](https://github.com/LennartHennigs/Button2/issues/23) + + +## [1.5.3] - 2021-01-26 +- Fixed a bug in the constructor, as suggested by [alex-s-v](https://github.com/alex-s-v) in pull request [#22](https://github.com/LennartHennigs/Button2/pull/22) + + +## [1.5.2] - 2021-01-26 +- Fixed a bug in the `isPressed()` function, as suggested by [zenturacp](https://github.com/zenturacp) in [#21](https://github.com/LennartHennigs/Button2/issues/21) + + +## [1.5.1] - 2021-01-04 +- Fixed a bug in the `loop()` function + + +## [1.5.0] - 2021-01-03 +- Added default constructor and `begin()` function +- Added pull request by [skelstar](https://github.com/skelstar) to add the `setLongClickDetectedHandler()` function which is triggered as soon as the longclick timeout has passed + + +## [1.4.1] - 2020-12-19 +- Moved activeLow outside of isCapacitive condition (as suggested by [Wai Lin](https://github.com/w4ilun) in [#18](https://github.com/LennartHennigs/Button2/pull/18) + + +## [1.4.0] - 2020-11-06 +- Updated LongpressHandler example - changed variable name to from `button` to `button` +- toggled `pressed` and `released` (as suggesed by [TommyC81](https://github.com/TommyC81) in [#16](https://github.com/LennartHennigs/Button2/issues/16)) +- added debug function `isPressedRaw()` (as suggesed by [TommyC81](https://github.com/TommyC81) in [#16](https://github.com/LennartHennigs/Button2/issues/16)) +- fixed bug with `click_count` (as suggesed by [TommyC81](https://github.com/TommyC81) in [#16](https://github.com/LennartHennigs/Button2/issues/16)) +- changed return types of `getNumberOfClicks()` and `getClickType()` to `byte` + + +## [1.3.0] - 2020-11-06 +- Added capacitive touch sensor capabilties (for ESP32) (as suggested by [qubolino](https://github.com/qubolino) in [#11](https://github.com/LennartHennigs/Button2/issues/11)) +- Removed deprecated entry in the library.properties file (as suggested by [SangLe](https://github.com/SNL5943)) in [#15](https://github.com/LennartHennigs/Button2/issues/15) +- Added `const` modifier to functions (as suggested by [Anton-V-K](https://github.com/Anton-V-K) in [#13](https://github.com/LennartHennigs/Button2/issues/13)) + + +## [1.2.0] - 2020-04-16 +- Added possibility to define your own timeouts for clicks (as suggested by [cmeldas](https://github.com/cmeldas) in [#10](https://github.com/LennartHennigs/Button2/issues/10)) +- Removed `yield()` in main `loop()` since it caused some problems +- Created and added CHANGELOG.md + + +## [1.1.0] - 2020-03-27 +- Changed the private functions to protected (as suggested by [Nagymadar](https://github.com/Nagymadar) in [#9](https://github.com/LennartHennigs/Button2/issues/9)) +- Added support for active high buttons (as suggested by [Nagymadar](https://github.com/Nagymadar) in [#8](https://github.com/LennartHennigs/Button2/issues/8)) +- Added `reset()` function to unset all functions (as suggested by [Nagymadar](https://github.com/Nagymadar) in [#7](https://github.com/LennartHennigs/Button2/issues/7)) +- Added a `yield()` command to the main `loop()` +- Changed the times for double and triple click +- Fixed error in `SingleButton.ino` (as suggested by [alexthe-red](https://github.com/alexthe-red) in [#3](https://github.com/LennartHennigs/Button2/issues/3)) +- Added the library to the Arduino IDE + + +## [1.0.0] - 2017-11-09 +- initial release + + +## Note +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). diff --git a/LNURLPoS/libraries/Button2/LICENSE b/LNURLPoS/libraries/Button2/LICENSE new file mode 100644 index 0000000..0317d66 --- /dev/null +++ b/LNURLPoS/libraries/Button2/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017-2021 Lennart Hennigs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/LNURLPoS/libraries/Button2/README.md b/LNURLPoS/libraries/Button2/README.md new file mode 100644 index 0000000..3da49d6 --- /dev/null +++ b/LNURLPoS/libraries/Button2/README.md @@ -0,0 +1,147 @@ +Button2 +====== + +Arduino/ESP library to simplify working with buttons. + +* Author: Lennart Hennigs (https://www.lennarthennigs.de) +* Copyright (C) 2017-2021 Lennart Hennigs. +* Released under the MIT license. + +Description +----------- +This library allows you to use callback functions to track single, double, triple and long clicks. It takes care of debouncing. Using this lib will reduce and simplify your source code significantly. + +It has been tested with Arduino, ESP8266 and ESP32 devices. + +How To Use +---------- + +This library allows you to define a button and uses callback functions to detect different types of button interactions. + +__Definition__ +- Define the button either using the ```constructor``` or the ```begin()``` function. +- Per default the button pins are defined as ```INPUT_PULLUP```. You can override this upon creation. +- On an ESP32 you can use it with the built-in capacitive button pins. + + +__Callback Handler__ +- You can define callback functions to track various types of clicks: + - ```setTapHandler()``` will be be called when any click occurs. + - ```setLongClickHandler()``` will be called after the button has released. + - ```setLongClickDetectedHandler()``` will be called as soon as the long click timeout has passed. + - ```setDoubleClickHandler()``` and ```setTripleClickHandler()``` detect complex interactions. + - ```setChangedHandler()```, ```setPressedHandler()``` and ```setReleasedHandler()``` allow to detect basic interactions. + +- The callback function needs a ```Button2``` reference parameter. There the reference to the triggered button is stored. This can used to call status fuctions, e.g. ```wasPressedFor()```. + +- Please take a look at the included examples to get an overview over the different callback handlers. + +__Timeouts__ +- You can define your own timeouts by using these setter functions: + + - ```void setDebounceTime(unsigned int ms);``` + - ```void setLongClickTime(unsigned int ms);``` + - ```void setDoubleClickTime(unsigned int ms);``` + + +__The Loop__ +- For the class to work, you need to call the button's `loop()` member function in your sketch's `loop()` function. +- Please see the examples for more details. + +Examples +----- +- [SingleButtonSimple](https://github.com/LennartHennigs/Button2/blob/master/examples/SingleButtonSimple/SingleButtonSimple.ino) – the most basic example, shows how to assign event handlers +- [LongpressHandler](https://github.com/LennartHennigs/Button2/blob/master/examples/LongpressHandler/LongpressHandler.ino) – shows how determine the time of a button press +- [SingleButton](https://github.com/LennartHennigs/Button2/blob/master/examples/SingleButton/SingleButton.ino) – shows the different event handlers +- [MultipleButtons](https://github.com/LennartHennigs/Button2/blob/master/examples/MultipleButtons/MultipleButtons.ino) – how to use two buttons +- [MultiHandler](https://github.com/LennartHennigs/Button2/blob/master/examples/MultiHandler/MultiHandler.ino) – how to use a single handler for multiple events +- [MultiHandlerTwoButtons](https://github.com/LennartHennigs/Button2/blob/master/examples/MultiHandlerTwoButtons/MultiHandlerTwoButtons.ino) – a single handler for multiple buttons +- [TrackDualButtonClick](https://github.com/LennartHennigs/Button2/blob/master/examples/TrackDualButtonClick/TrackDualButtonClick.ino) – how to detect when two buttons are clicked at the same time + +Notes +----- + +- To see the latest changes to the library please take a look at the [Changelog](https://github.com/LennartHennigs/Button2/blob/master/CHANGELOG.md). + +- And if you find this library helpful, please consider giving it a star at [GitHub](https://github.com/LennartHennigs/Button2). Thanks! + + + +Class Definition +---------------- + +These are the constructors and the member functions the library provides: + +``` +Button2(); +Button2(byte attachTo, byte buttonMode = INPUT_PULLUP, boolean isCapacitive = false, boolean activeLow = true); + +void begin(byte attachTo, byte buttonMode = INPUT_PULLUP, boolean isCapacitive = false , boolean activeLow = true); + +void setDebounceTime(unsigned int ms); +void setLongClickTime(unsigned int ms); +void setDoubleClickTime(unsigned int ms); + +unsigned int getDebounceTime(); +unsigned int getLongClickTime(); +unsigned int getDoubleClickTime(); +byte getAttachPin(); + +void setLongClickDetectedRetriggerable(bool retriggerable); + +void reset(); + +void setChangedHandler(CallbackFunction f); +void setPressedHandler(CallbackFunction f); +void setReleasedHandler(CallbackFunction f); + +void setTapHandler(CallbackFunction f); +void setClickHandler(CallbackFunction f); +void setDoubleClickHandler(CallbackFunction f); +void setTripleClickHandler(CallbackFunction f); + +void setLongClickHandler(CallbackFunction f); +void setLongClickDetectedHandler(CallbackFunction f); + +unsigned int wasPressedFor() const; +boolean isPressed() const; +boolean isPressedRaw() const; + +byte getNumberOfClicks() const; +byte getClickType() const; + +bool operator==(Button2 &rhs); + +void loop(); +``` + +Installation +------------ +Open the Arduino IDE choose "Sketch > Include Library" and search for "Button2". +Or download the ZIP archive (https://github.com/lennarthennigs/Button2/zipball/master), and choose "Sketch > Include Library > Add .ZIP Library..." and select the downloaded file. + + +License +------- + +MIT License + +Copyright (c) 2017-2021 Lennart Hennigs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/LNURLPoS/libraries/Button2/examples/LongpressHandler/LongpressHandler.ino b/LNURLPoS/libraries/Button2/examples/LongpressHandler/LongpressHandler.ino new file mode 100644 index 0000000..ae54231 --- /dev/null +++ b/LNURLPoS/libraries/Button2/examples/LongpressHandler/LongpressHandler.ino @@ -0,0 +1,51 @@ +///////////////////////////////////////////////////////////////// + +#include "Button2.h" + +///////////////////////////////////////////////////////////////// + +#define BUTTON_PIN 2 + +///////////////////////////////////////////////////////////////// + +Button2 button; + +///////////////////////////////////////////////////////////////// + +void setup() { + Serial.begin(9600); + while (!Serial) { + delay(20); + } + Serial.println("\n\nLongpress Handler Demo"); + + button.begin(BUTTON_PIN); + button.setLongClickHandler(longpress); +} + +///////////////////////////////////////////////////////////////// + +void loop() { + button.loop(); +} + +///////////////////////////////////////////////////////////////// + +void longpress(Button2& btn) { + unsigned int time = btn.wasPressedFor(); + Serial.print("You clicked "); + if (time > 1500) { + Serial.print("a really really long time."); + } else if (time > 1000) { + Serial.print("a really long time."); + } else if (time > 500) { + Serial.print("a long time."); + } else { + Serial.print("long."); + } + Serial.print(" ("); + Serial.print(time); + Serial.println(" ms)"); +} + +///////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/LNURLPoS/libraries/Button2/examples/MultiHandler/MultiHandler.ino b/LNURLPoS/libraries/Button2/examples/MultiHandler/MultiHandler.ino new file mode 100644 index 0000000..eb6ea1d --- /dev/null +++ b/LNURLPoS/libraries/Button2/examples/MultiHandler/MultiHandler.ino @@ -0,0 +1,54 @@ +///////////////////////////////////////////////////////////////// + +#include "Button2.h" + +///////////////////////////////////////////////////////////////// + +#define BUTTON_PIN 2 + +///////////////////////////////////////////////////////////////// + +Button2 button; + +///////////////////////////////////////////////////////////////// + +void setup() { + Serial.begin(9600); + delay(50); + Serial.println("\n\nMulti Handler Demo"); + + button.begin(BUTTON_PIN); + button.setClickHandler(handler); + button.setLongClickHandler(handler); + button.setDoubleClickHandler(handler); + button.setTripleClickHandler(handler); +} + +///////////////////////////////////////////////////////////////// + +void loop() { + button.loop(); +} + +///////////////////////////////////////////////////////////////// + +void handler(Button2& btn) { + switch (btn.getClickType()) { + case SINGLE_CLICK: + break; + case DOUBLE_CLICK: + Serial.print("double "); + break; + case TRIPLE_CLICK: + Serial.print("triple "); + break; + case LONG_CLICK: + Serial.print("long"); + break; + } + Serial.print("click"); + Serial.print(" ("); + Serial.print(btn.getNumberOfClicks()); + Serial.println(")"); +} +///////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/LNURLPoS/libraries/Button2/examples/MultiHandlerTwoButtons/MultiHandlerTwoButtons.ino b/LNURLPoS/libraries/Button2/examples/MultiHandlerTwoButtons/MultiHandlerTwoButtons.ino new file mode 100644 index 0000000..c681f23 --- /dev/null +++ b/LNURLPoS/libraries/Button2/examples/MultiHandlerTwoButtons/MultiHandlerTwoButtons.ino @@ -0,0 +1,53 @@ +///////////////////////////////////////////////////////////////// + +#include "Button2.h" + +///////////////////////////////////////////////////////////////// + +#define BUTTON_PIN_1 3 +#define BUTTON_PIN_2 4 + +///////////////////////////////////////////////////////////////// + +Button2 button_1, button_2; + +///////////////////////////////////////////////////////////////// + +void setup() { + Serial.begin(9600); + delay(50); + Serial.println("\n\nMulti Handler Demo w/ 2 buttons"); + + button_1.begin(BUTTON_PIN_1); + button_1.setClickHandler(handler); + button_1.setDoubleClickHandler(handler); + + button_2.begin(BUTTON_PIN_2); + button_2.setClickHandler(handler); + button_2.setDoubleClickHandler(handler); + +} + +///////////////////////////////////////////////////////////////// + +void loop() { + button_1.loop(); + button_2.loop(); +} + +///////////////////////////////////////////////////////////////// + +void handler(Button2& btn) { + switch (btn.getClickType()) { + case SINGLE_CLICK: + break; + case DOUBLE_CLICK: + Serial.print("double "); + break; + } + Serial.print("click "); + Serial.print("on button #"); + Serial.print((btn == button_1) ? "1" : "2"); + Serial.println(); +} +///////////////////////////////////////////////////////////////// diff --git a/LNURLPoS/libraries/Button2/examples/MultipleButtons/MultipleButtons.ino b/LNURLPoS/libraries/Button2/examples/MultipleButtons/MultipleButtons.ino new file mode 100644 index 0000000..3b505b2 --- /dev/null +++ b/LNURLPoS/libraries/Button2/examples/MultipleButtons/MultipleButtons.ino @@ -0,0 +1,45 @@ +///////////////////////////////////////////////////////////////// + +#include "Button2.h" + +///////////////////////////////////////////////////////////////// + +#define BUTTON_A_PIN 2 +#define BUTTON_B_PIN 0 + +///////////////////////////////////////////////////////////////// + +Button2 buttonA, buttonB; + +///////////////////////////////////////////////////////////////// + +void setup() { + Serial.begin(9600); + delay(50); + Serial.println("\n\nMultiple Buttons Demo"); + + buttonA.begin(BUTTON_A_PIN); + buttonA.setClickHandler(click); + + buttonB.begin(BUTTON_B_PIN); + buttonB.setClickHandler(click); +} + +///////////////////////////////////////////////////////////////// + +void loop() { + buttonA.loop(); + buttonB.loop(); +} + +///////////////////////////////////////////////////////////////// + +void click(Button2& btn) { + if (btn == buttonA) { + Serial.println("A clicked"); + } else if (btn == buttonB) { + Serial.println("B clicked"); + } +} + +///////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/LNURLPoS/libraries/Button2/examples/SingleButton/SingleButton.ino b/LNURLPoS/libraries/Button2/examples/SingleButton/SingleButton.ino new file mode 100644 index 0000000..0a85337 --- /dev/null +++ b/LNURLPoS/libraries/Button2/examples/SingleButton/SingleButton.ino @@ -0,0 +1,77 @@ +///////////////////////////////////////////////////////////////// + +#include "Button2.h" + +///////////////////////////////////////////////////////////////// + +#define BUTTON_PIN 2 + +///////////////////////////////////////////////////////////////// + +Button2 button; + +///////////////////////////////////////////////////////////////// + +void setup() { + Serial.begin(9600); + delay(50); + Serial.println("\n\nButton Demo"); + + button.begin(BUTTON_PIN); + // button.setLongClickTime(1000); + // button.setDoubleClickTime(400); + + Serial.println(" Longpress Time: " + String(button.getLongClickTime()) + "ms"); + Serial.println(" DoubleClick Time: " + String(button.getDoubleClickTime()) + "ms"); + + // button.setChangedHandler(changed); + // button.setPressedHandler(pressed); + button.setReleasedHandler(released); + + // button.setTapHandler(tap); + button.setClickHandler(click); + button.setLongClickDetectedHandler(longClickDetected); + button.setLongClickHandler(longClick); + + button.setDoubleClickHandler(doubleClick); + button.setTripleClickHandler(tripleClick); +} + +///////////////////////////////////////////////////////////////// + +void loop() { + button.loop(); +} + +///////////////////////////////////////////////////////////////// + +void pressed(Button2& btn) { + Serial.println("pressed"); +} +void released(Button2& btn) { + Serial.print("released: "); + Serial.println(btn.wasPressedFor()); +} +void changed(Button2& btn) { + Serial.println("changed"); +} +void click(Button2& btn) { + Serial.println("click\n"); +} +void longClickDetected(Button2& btn) { + Serial.println("long click detected\n"); +} +void longClick(Button2& btn) { + Serial.println("long click\n"); +} +void doubleClick(Button2& btn) { + Serial.println("double click\n"); +} +void tripleClick(Button2& btn) { + Serial.println("triple click\n"); +} +void tap(Button2& btn) { + Serial.println("tap"); +} + +///////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/LNURLPoS/libraries/Button2/examples/SingleButtonSimple/SingleButtonSimple.ino b/LNURLPoS/libraries/Button2/examples/SingleButtonSimple/SingleButtonSimple.ino new file mode 100644 index 0000000..9d5b999 --- /dev/null +++ b/LNURLPoS/libraries/Button2/examples/SingleButtonSimple/SingleButtonSimple.ino @@ -0,0 +1,51 @@ +///////////////////////////////////////////////////////////////// + +#include "Button2.h" + +///////////////////////////////////////////////////////////////// + +#define BUTTON_PIN 2 + +///////////////////////////////////////////////////////////////// + +Button2 button; + +///////////////////////////////////////////////////////////////// + +void setup() { + Serial.begin(9600); + delay(50); + Serial.println("\n\nButton Demo"); + + button.begin(BUTTON_PIN); + button.setChangedHandler(changed); + //button.setPressedHandler(pressed); + //button.setReleasedHandler(released); + + // setTapHandler() is called by any type of click, longpress or shortpress + button.setTapHandler(tap); +} + +///////////////////////////////////////////////////////////////// + +void loop() { + button.loop(); +} + +///////////////////////////////////////////////////////////////// + +void pressed(Button2& btn) { + Serial.println("pressed"); +} +void released(Button2& btn) { + Serial.print("released: "); + Serial.println(btn.wasPressedFor()); +} +void changed(Button2& btn) { + Serial.println("changed"); +} +void tap(Button2& btn) { + Serial.println("tap"); +} +///////////////////////////////////////////////////////////////// + diff --git a/LNURLPoS/libraries/Button2/examples/TrackDualButtonClick/TrackDualButtonClick.ino b/LNURLPoS/libraries/Button2/examples/TrackDualButtonClick/TrackDualButtonClick.ino new file mode 100644 index 0000000..400c288 --- /dev/null +++ b/LNURLPoS/libraries/Button2/examples/TrackDualButtonClick/TrackDualButtonClick.ino @@ -0,0 +1,64 @@ +///////////////////////////////////////////////////////////////// + +#include "Button2.h" + +///////////////////////////////////////////////////////////////// + +#define BUTTON_PIN_1 3 +#define BUTTON_PIN_2 4 + +///////////////////////////////////////////////////////////////// + +Button2 button_1, button_2; + +unsigned long now = 0; +byte counter = 0; + +///////////////////////////////////////////////////////////////// + +void setup() { + Serial.begin(9600); + delay(50); + Serial.println("\n\nTrack dual button press & release"); + + button_1.begin(BUTTON_PIN_1); + button_1.setPressedHandler(pressed); + button_1.setReleasedHandler(released); + + button_2.begin(BUTTON_PIN_2); + button_2.setPressedHandler(pressed); + button_2.setReleasedHandler(released); +} + +///////////////////////////////////////////////////////////////// + +void loop() { + button_1.loop(); + button_2.loop(); +} + +///////////////////////////////////////////////////////////////// + +void pressed(Button2& btn) { + counter++; + if (counter == 2) { + now = millis(); + Serial.println("now!"); + } +} + +///////////////////////////////////////////////////////////////// + +void released(Button2& btn) { + counter--; + if (counter == 0) { + if (now != 0) { + Serial.print("Pressed for: "); + Serial.print(millis() - now); + Serial.println("ms"); + } + now = 0; + } +} + +///////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/LNURLPoS/libraries/Button2/keywords.txt b/LNURLPoS/libraries/Button2/keywords.txt new file mode 100644 index 0000000..5889c38 --- /dev/null +++ b/LNURLPoS/libraries/Button2/keywords.txt @@ -0,0 +1,33 @@ +Button2 KEYWORD1 +begin KEYWORD2 +setDebounceTime KEYWORD2 +setLongClickTime KEYWORD2 +setDoubleClickTime KEYWORD2 +getDebounceTime KEYWORD2 +getLongClickTime KEYWORD2 +getDoubleClickTime KEYWORD2 +getAttachPin KEYWORD2 +setLongClickDetectedRetriggerable KEYWORD2 +reset KEYWORD2 +setChangedHandler KEYWORD2 +setPressedHandler KEYWORD2 +setReleasedHandler KEYWORD2 +setTapHandler KEYWORD2 +setClickHandler KEYWORD2 +setDoubleClickHandler KEYWORD2 +setTripleClickHandler KEYWORD2 +setLongClickHandler KEYWORD2 +setLongClickDetectedHandler KEYWORD2 +wasPressedFor KEYWORD2 +isPressed KEYWORD2 +isPressedRaw KEYWORD2 +getNumberOfClicks KEYWORD2 +getClickType KEYWORD2 +loop KEYWORD2 +DEBOUNCE_MS LITERAL1 +LONGCLICK_MS LITERAL1 +DOUBLECLICK_MS LITERAL1 +SINGLE_CLICK LITERAL1 +DOUBLE_CLICK LITERAL1 +TRIPLE_CLICK LITERAL1 +LONG_CLICK LITERAL1 diff --git a/LNURLPoS/libraries/Button2/library.json b/LNURLPoS/libraries/Button2/library.json new file mode 100644 index 0000000..2c69d98 --- /dev/null +++ b/LNURLPoS/libraries/Button2/library.json @@ -0,0 +1,17 @@ +{ + "name": "Button2", + "version": "1.6.5", + "keywords": "button", + "description": "Arduino Library to simplify working with buttons.", + "homepage": "https://github.com/LennartHennigs/Button2", + "repository": { + "type": "git", + "url": "https://github.com/LennartHennigs/Button2" + }, + "authors": { + "name": "Lennart Hennigs", + "url": "https://lennarthennigs.de" + }, + "frameworks": "arduino", + "platforms": "*" +} diff --git a/LNURLPoS/libraries/Button2/library.properties b/LNURLPoS/libraries/Button2/library.properties new file mode 100644 index 0000000..47c72aa --- /dev/null +++ b/LNURLPoS/libraries/Button2/library.properties @@ -0,0 +1,9 @@ +name=Button2 +version=1.6.5 +author=Lennart Hennigs +maintainer=Lennart Hennigs +sentence=Arduino/ESP library to simplify working with buttons. +paragraph=It allows you to use callback functions to track single, double, triple and long clicks. It takes care of debouncing. It will reduce and simplify your souce code significantly. Tested with Arduino, ESP8266 and ESP32. +category=Communication +url=https://github.com/LennartHennigs/Button2 +architectures=* diff --git a/LNURLPoS/libraries/Button2/src/Button2.cpp b/LNURLPoS/libraries/Button2/src/Button2.cpp new file mode 100644 index 0000000..fd6c696 --- /dev/null +++ b/LNURLPoS/libraries/Button2/src/Button2.cpp @@ -0,0 +1,302 @@ +///////////////////////////////////////////////////////////////// +/* + Button2.cpp - Arduino Library to simplify working with buttons. + Created by Lennart Hennigs. +*/ +///////////////////////////////////////////////////////////////// + +#include "Button2.h" + +///////////////////////////////////////////////////////////////// + +Button2::Button2() { + pin = UNDEFINED_PIN; +} + +///////////////////////////////////////////////////////////////// + +Button2::Button2(byte attachTo, byte buttonMode /* = INPUT_PULLUP */, boolean isCapacitive /* = false */, boolean activeLow /* = true */) { + begin(attachTo, buttonMode, isCapacitive, activeLow); +} + +///////////////////////////////////////////////////////////////// + +void Button2::begin(byte attachTo, byte buttonMode /* = INPUT_PULLUP */, boolean isCapacitive /* = false */, boolean activeLow /* = true */) { + pin = attachTo; + longclick_detected_retriggerable = false; + _pressedState = activeLow ? LOW : HIGH; + setDebounceTime(DEBOUNCE_MS); + setLongClickTime(LONGCLICK_MS); + setDoubleClickTime(DOUBLECLICK_MS); + if (!isCapacitive) { + pinMode(attachTo, buttonMode); + } else { + is_capacitive = true; + } + // state = activeLow ? HIGH : LOW; + state = _getState(); + prev_state = state ; +} + +///////////////////////////////////////////////////////////////// + +void Button2::setDebounceTime(unsigned int ms) { + debounce_time_ms = ms; +} + +///////////////////////////////////////////////////////////////// + +void Button2::setLongClickTime(unsigned int ms) { + longclick_time_ms = ms; +} + +///////////////////////////////////////////////////////////////// + +void Button2::setDoubleClickTime(unsigned int ms) { + doubleclick_time_ms = ms; +} + +///////////////////////////////////////////////////////////////// + +unsigned int Button2::getDebounceTime() const { + return debounce_time_ms; +} + +///////////////////////////////////////////////////////////////// + +unsigned int Button2::getLongClickTime() const { + return longclick_time_ms; +} + +///////////////////////////////////////////////////////////////// + +unsigned int Button2::getDoubleClickTime() const { + return doubleclick_time_ms; +} + +///////////////////////////////////////////////////////////////// + +byte Button2::getAttachPin() const { + return pin; +} + +///////////////////////////////////////////////////////////////// + +bool Button2::operator == (Button2 &rhs) { + return (this==&rhs); +} + +///////////////////////////////////////////////////////////////// + +void Button2::setLongClickDetectedRetriggerable(bool retriggerable) { + longclick_detected_retriggerable = retriggerable; +} +///////////////////////////////////////////////////////////////// + +void Button2::setChangedHandler(CallbackFunction f) { + change_cb = f; +} + +///////////////////////////////////////////////////////////////// + +void Button2::setPressedHandler(CallbackFunction f) { + pressed_cb = f; +} + +///////////////////////////////////////////////////////////////// + +void Button2::setReleasedHandler(CallbackFunction f) { + released_cb = f; +} + +///////////////////////////////////////////////////////////////// + +void Button2::setClickHandler(CallbackFunction f) { + click_cb = f; +} + +///////////////////////////////////////////////////////////////// + +void Button2::setTapHandler(CallbackFunction f) { + tap_cb = f; +} + +///////////////////////////////////////////////////////////////// + +void Button2::setLongClickHandler(CallbackFunction f) { + long_cb = f; +} + +///////////////////////////////////////////////////////////////// + +void Button2::setDoubleClickHandler(CallbackFunction f) { + double_cb = f; +} + +///////////////////////////////////////////////////////////////// + +void Button2::setTripleClickHandler(CallbackFunction f) { + triple_cb = f; +} + +///////////////////////////////////////////////////////////////// + +void Button2::setLongClickDetectedHandler(CallbackFunction f) { + longclick_detected_cb = f; +} + +///////////////////////////////////////////////////////////////// + +unsigned int Button2::wasPressedFor() const { + return down_time_ms; +} + +///////////////////////////////////////////////////////////////// + +boolean Button2::isPressed() const { + return (state == _pressedState); +} + +///////////////////////////////////////////////////////////////// + +boolean Button2::isPressedRaw() const { + return (digitalRead(pin) == _pressedState); +} + +///////////////////////////////////////////////////////////////// + +byte Button2::getNumberOfClicks() const { + return click_count; +} + +///////////////////////////////////////////////////////////////// + +byte Button2::getClickType() const { + return last_click_type; +} + +///////////////////////////////////////////////////////////////// + +byte Button2::_getState() { + byte state = 0; + if (!is_capacitive) { + state = digitalRead(pin); + } else { + #if defined(ARDUINO_ARCH_ESP32) + int capa = touchRead(pin); + state = capa < CAPACITIVE_TOUCH_THRESHOLD ? LOW : HIGH; + #endif + } + return state; +} + +///////////////////////////////////////////////////////////////// + +void Button2::loop() { + if (pin != UNDEFINED_PIN) { + prev_state = state; + unsigned long now = millis(); + state = _getState(); + // is button pressed? + if (state == _pressedState && prev_state != _pressedState) { + down_ms = now; + pressed_triggered = false; + click_ms = down_ms; + + // trigger pressed event (after debounce has passed) + } else if (state == _pressedState && !pressed_triggered && (now - down_ms >= debounce_time_ms)) { + pressed_triggered = true; + click_count++; + if (change_cb != NULL) change_cb (*this); + if (pressed_cb != NULL) pressed_cb (*this); + + // is the button released? + } else if (state != _pressedState && prev_state == _pressedState) { + down_time_ms = now - down_ms; + // is it beyond debounce time? + if (down_time_ms >= debounce_time_ms) { + // trigger release + if (change_cb != NULL) change_cb (*this); + if (released_cb != NULL) released_cb (*this); + // trigger tap + if (tap_cb != NULL) tap_cb (*this); + // was it a longclick? (preceeds single / double / triple clicks) + if (down_time_ms >= longclick_time_ms) { + longclick_detected = true; + } + } + + // is the button released and the time has passed for multiple clicks? + } else if (state != _pressedState && now - click_ms > doubleclick_time_ms) { + // was there a longclick? + if (longclick_detected) { + // was it part of a combination? + if (click_count == 1) { + last_click_type = LONG_CLICK; + if (long_cb != NULL) long_cb (*this); + } + longclick_detected = false; + longclick_detected_reported = false; + longclick_detected_counter = 0; + // determine the number of single clicks + } else if (click_count > 0) { + switch (click_count) { + case 1: + last_click_type = SINGLE_CLICK; + if (click_cb != NULL) click_cb (*this); + break; + case 2: + last_click_type = DOUBLE_CLICK; + if (double_cb != NULL) double_cb (*this); + break; + case 3: + last_click_type = TRIPLE_CLICK; + if (triple_cb != NULL) triple_cb (*this); + break; + } + } + click_count = 0; + click_ms = 0; + } + + bool longclick_period_detected = now - down_ms >= (longclick_time_ms * (longclick_detected_counter + 1)); + + // check to see that the longclick_ms period has been exceeded and call the appropriate callback + if (state == _pressedState && longclick_period_detected && !longclick_detected_reported) { + longclick_detected_reported = true; + longclick_detected = true; + if (longclick_detected_retriggerable) { + // if it's retriggerable then we bump the counter and reset the "reported" flag (as the counter will stop the false trigger) + longclick_detected_counter++; + longclick_detected_reported = false; + } +// longpress_detected_ms = now; + if (longclick_detected_cb != NULL) + longclick_detected_cb(*this); + } + } +} + +///////////////////////////////////////////////////////////////// + +void Button2::reset() { + pin = UNDEFINED_PIN; + click_count = 0; + last_click_type = 0; + down_time_ms = 0; + pressed_triggered = false; + longclick_detected = false; + longclick_detected_reported = false; + + pressed_cb = NULL; + released_cb = NULL; + change_cb = NULL; + tap_cb = NULL; + click_cb = NULL; + long_cb = NULL; + double_cb = NULL; + triple_cb = NULL; + longclick_detected_cb = NULL; +} + +///////////////////////////////////////////////////////////////// diff --git a/LNURLPoS/libraries/Button2/src/Button2.h b/LNURLPoS/libraries/Button2/src/Button2.h new file mode 100644 index 0000000..b60f60a --- /dev/null +++ b/LNURLPoS/libraries/Button2/src/Button2.h @@ -0,0 +1,122 @@ +///////////////////////////////////////////////////////////////// +/* + Button2.h - Arduino Library to simplify working with buttons. + Created by Lennart Hennigs. +*/ +///////////////////////////////////////////////////////////////// +#pragma once + +#ifndef Button2_h +#define Button2_h + +///////////////////////////////////////////////////////////////// +#if defined(ARDUINO_ARCH_ESP32) || defined(ESP8266) + #include +#endif +#include "Arduino.h" + +///////////////////////////////////////////////////////////////// + +#define DEBOUNCE_MS 50 +#define LONGCLICK_MS 200 +#define DOUBLECLICK_MS 300 +#define CAPACITIVE_TOUCH_THRESHOLD 35 + +#define SINGLE_CLICK 1 +#define DOUBLE_CLICK 2 +#define TRIPLE_CLICK 3 +#define LONG_CLICK 4 + +#define UNDEFINED_PIN 255 + +///////////////////////////////////////////////////////////////// + +class Button2 { +protected: + byte pin; + byte state; + byte prev_state; + byte click_count = 0; + byte last_click_type = 0; + byte _pressedState; + bool is_capacitive = false; + unsigned long click_ms; + unsigned long down_ms; + + bool longclick_detected_retriggerable; + uint16_t longclick_detected_counter; + bool longclick_detected = false; + bool longclick_detected_reported = false; + + unsigned int debounce_time_ms; + unsigned int longclick_time_ms; + unsigned int doubleclick_time_ms; + + unsigned int down_time_ms = 0; + bool pressed_triggered = false; + +#if defined(ARDUINO_ARCH_ESP32) || defined(ESP8266) + typedef std::function CallbackFunction; +#else + typedef void (*CallbackFunction)(Button2 &); +#endif + + CallbackFunction pressed_cb = NULL; + CallbackFunction released_cb = NULL; + CallbackFunction change_cb = NULL; + CallbackFunction tap_cb = NULL; + CallbackFunction click_cb = NULL; + CallbackFunction long_cb = NULL; + CallbackFunction double_cb = NULL; + CallbackFunction triple_cb = NULL; + CallbackFunction longclick_detected_cb = NULL; + +public: + Button2(); + Button2(byte attachTo, byte buttonMode = INPUT_PULLUP, boolean isCapacitive = false, boolean activeLow = true); + + void begin(byte attachTo, byte buttonMode = INPUT_PULLUP, boolean isCapacitive = false , boolean activeLow = true); + + void setDebounceTime(unsigned int ms); + void setLongClickTime(unsigned int ms); + void setDoubleClickTime(unsigned int ms); + + unsigned int getDebounceTime() const; + unsigned int getLongClickTime() const; + unsigned int getDoubleClickTime() const; + byte getAttachPin() const; + + void setLongClickDetectedRetriggerable(bool retriggerable); + + void reset(); + + void setChangedHandler(CallbackFunction f); + void setPressedHandler(CallbackFunction f); + void setReleasedHandler(CallbackFunction f); + + void setTapHandler(CallbackFunction f); + void setClickHandler(CallbackFunction f); + void setDoubleClickHandler(CallbackFunction f); + void setTripleClickHandler(CallbackFunction f); + + void setLongClickHandler(CallbackFunction f); + void setLongClickDetectedHandler(CallbackFunction f); + + unsigned int wasPressedFor() const; + boolean isPressed() const; + boolean isPressedRaw() const; + + byte getNumberOfClicks() const; + byte getClickType() const; + + bool operator == (Button2 &rhs); + + void loop(); + +private: + byte _getState(); + +}; +///////////////////////////////////////////////////////////////// +#endif +///////////////////////////////////////////////////////////////// From 6db970de23a134c77f58e51c3437e52b369816b7 Mon Sep 17 00:00:00 2001 From: clay Date: Thu, 23 Dec 2021 09:44:57 -0800 Subject: [PATCH 4/4] delete old demo --- LNURLPoS/LNURLPoS.ino | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/LNURLPoS/LNURLPoS.ino b/LNURLPoS/LNURLPoS.ino index 5f3cd62..b77cd2a 100644 --- a/LNURLPoS/LNURLPoS.ino +++ b/LNURLPoS/LNURLPoS.ino @@ -17,12 +17,13 @@ ////////CHANGE! USE LNURLPoS EXTENSION IN LNBITS//////// //////////////////////////////////////////////////////// - - String server = "https://api.rapaygo.com"; -String posId = "CARSjVUFTmCQhGt5EAHkXS"; -String key = "AQ9eA4iwUg3vg4z5mapeP8"; +String posId = "sooper"; +String key = "secret"; String currency = "USD"; +String walletId = "a1627"; + + //////////////////////////////////////////////////////// ////Note: See lines 75, 97, to adjust to keypad size//// @@ -282,6 +283,9 @@ void logo() { tft.setFreeFont(SMALLFONT); tft.setCursor(7, 90); // To be compatible with Adafruit_GFX the cursor datum is always bottom left tft.print("https://rapaygo.com"); // Using tft.print means text background is NEVER rendered + tft.setCursor(7, 105); + tft.setTextColor(TFT_WHITE, TFT_BLACK); + tft.print("id: "+String(walletId)); displayBatteryVoltage(); } @@ -318,6 +322,9 @@ void displayBatteryVoltage() { tft.setCursor(195, 16); int percent = round(((float)v1Voltage / 5.0f) * 100.0f); + if(percent>100){ + percent = 100; + } String batteryPercent = String(percent); tft.print(batteryPercent); }