diff --git a/.gitmodules b/.gitmodules index 373bb41d..89a5ec32 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "client/3rd/outline-go-tun2socks"] path = client/3rd/outline-go-tun2socks url = https://github.com/Jigsaw-Code/outline-go-tun2socks.git +[submodule "client/3rd/qzxing"] + path = client/3rd/qzxing + url = https://github.com/ftylitak/qzxing.git diff --git a/client/3rd/QRCodeGenerator/QRCodeGenerator.cpp b/client/3rd/QRCodeGenerator/QRCodeGenerator.cpp deleted file mode 100644 index 6e83fa1e..00000000 --- a/client/3rd/QRCodeGenerator/QRCodeGenerator.cpp +++ /dev/null @@ -1,1802 +0,0 @@ -#include "QRCodeGenerator.h" - -#include -#include -#include //for strlen on linux - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -static QR_VERSIONINFO QR_VersonInfo[] = {{0}, - { 1, // Ver.1 - 26, 19, 16, 13, 9, - 0, 0, 0, 0, 0, 0, 0, - 1, 26, 19, - 1, 26, 16, - 1, 26, 13, - 1, 26, 9, - 0, 0, 0, - 0, 0, 0, - 0, 0, 0, - 0, 0, 0}, - { 2, // Ver.2 - 44, 34, 28, 22, 16, - 1, 18, 0, 0, 0, 0, 0, - 1, 44, 34, - 1, 44, 28, - 1, 44, 22, - 1, 44, 16, - 0, 0, 0, - 0, 0, 0, - 0, 0, 0, - 0, 0, 0}, - { 3, // Ver.3 - 70, 55, 44, 34, 26, - 1, 22, 0, 0, 0, 0, 0, - 1, 70, 55, - 1, 70, 44, - 2, 35, 17, - 2, 35, 13, - 0, 0, 0, - 0, 0, 0, - 0, 0, 0, - 0, 0, 0}, - { 4, // Ver.4 - 100, 80, 64, 48, 36, - 1, 26, 0, 0, 0, 0, 0, - 1, 100, 80, - 2, 50, 32, - 2, 50, 24, - 4, 25, 9, - 0, 0, 0, - 0, 0, 0, - 0, 0, 0, - 0, 0, 0}, - { 5, // Ver.5 - 134, 108, 86, 62, 46, - 1, 30, 0, 0, 0, 0, 0, - 1, 134, 108, - 2, 67, 43, - 2, 33, 15, - 2, 33, 11, - 0, 0, 0, - 0, 0, 0, - 2, 34, 16, - 2, 34, 12}, - { 6, // Ver.6 - 172, 136, 108, 76, 60, - 1, 34, 0, 0, 0, 0, 0, - 2, 86, 68, - 4, 43, 27, - 4, 43, 19, - 4, 43, 15, - 0, 0, 0, - 0, 0, 0, - 0, 0, 0, - 0, 0, 0}, - { 7, // Ver.7 - 196, 156, 124, 88, 66, - 2, 22, 38, 0, 0, 0, 0, - 2, 98, 78, - 4, 49, 31, - 2, 32, 14, - 4, 39, 13, - 0, 0, 0, - 0, 0, 0, - 4, 33, 15, - 1, 40, 14}, - { 8, // Ver.8 - 242, 194, 154, 110, 86, - 2, 24, 42, 0, 0, 0, 0, - 2, 121, 97, - 2, 60, 38, - 4, 40, 18, - 4, 40, 14, - 0, 0, 0, - 2, 61, 39, - 2, 41, 19, - 2, 41, 15}, - { 9, // Ver.9 - 292, 232, 182, 132, 100, - 2, 26, 46, 0, 0, 0, 0, - 2, 146, 116, - 3, 58, 36, - 4, 36, 16, - 4, 36, 12, - 0, 0, 0, - 2, 59, 37, - 4, 37, 17, - 4, 37, 13}, - {10, // Ver.10 - 346, 274, 216, 154, 122, - 2, 28, 50, 0, 0, 0, 0, - 2, 86, 68, - 4, 69, 43, - 6, 43, 19, - 6, 43, 15, - 2, 87, 69, - 1, 70, 44, - 2, 44, 20, - 2, 44, 16}, - {11, // Ver.11 - 404, 324, 254, 180, 140, - 2, 30, 54, 0, 0, 0, 0, - 4, 101, 81, - 1, 80, 50, - 4, 50, 22, - 3, 36, 12, - 0, 0, 0, - 4, 81, 51, - 4, 51, 23, - 8, 37, 13}, - {12, // Ver.12 - 466, 370, 290, 206, 158, - 2, 32, 58, 0, 0, 0, 0, - 2, 116, 92, - 6, 58, 36, - 4, 46, 20, - 7, 42, 14, - 2, 117, 93, - 2, 59, 37, - 6, 47, 21, - 4, 43, 15}, - {13, // Ver.13 - 532, 428, 334, 244, 180, - 2, 34, 62, 0, 0, 0, 0, - 4, 133, 107, - 8, 59, 37, - 8, 44, 20, - 12, 33, 11, - 0, 0, 0, - 1, 60, 38, - 4, 45, 21, - 4, 34, 12}, - {14, // Ver.14 - 581, 461, 365, 261, 197, - 3, 26, 46, 66, 0, 0, 0, - 3, 145, 115, - 4, 64, 40, - 11, 36, 16, - 11, 36, 12, - 1, 146, 116, - 5, 65, 41, - 5, 37, 17, - 5, 37, 13}, - {15, // Ver.15 - 655, 523, 415, 295, 223, - 3, 26, 48, 70, 0, 0, 0, - 5, 109, 87, - 5, 65, 41, - 5, 54, 24, - 11, 36, 12, - 1, 110, 88, - 5, 66, 42, - 7, 55, 25, - 7, 37, 13}, - {16, // Ver.16 - 733, 589, 453, 325, 253, - 3, 26, 50, 74, 0, 0, 0, - 5, 122, 98, - 7, 73, 45, - 15, 43, 19, - 3, 45, 15, - 1, 123, 99, - 3, 74, 46, - 2, 44, 20, - 13, 46, 16}, - {17, // Ver.17 - 815, 647, 507, 367, 283, - 3, 30, 54, 78, 0, 0, 0, - 1, 135, 107, - 10, 74, 46, - 1, 50, 22, - 2, 42, 14, - 5, 136, 108, - 1, 75, 47, - 15, 51, 23, - 17, 43, 15}, - {18, // Ver.18 - 901, 721, 563, 397, 313, - 3, 30, 56, 82, 0, 0, 0, - 5, 150, 120, - 9, 69, 43, - 17, 50, 22, - 2, 42, 14, - 1, 151, 121, - 4, 70, 44, - 1, 51, 23, - 19, 43, 15}, - {19, // Ver.19 - 991, 795, 627, 445, 341, - 3, 30, 58, 86, 0, 0, 0, - 3, 141, 113, - 3, 70, 44, - 17, 47, 21, - 9, 39, 13, - 4, 142, 114, - 11, 71, 45, - 4, 48, 22, - 16, 40, 14}, - {20, // Ver.20 - 1085, 861, 669, 485, 385, - 3, 34, 62, 90, 0, 0, 0, - 3, 135, 107, - 3, 67, 41, - 15, 54, 24, - 15, 43, 15, - 5, 136, 108, - 13, 68, 42, - 5, 55, 25, - 10, 44, 16}, - {21, // Ver.21 - 1156, 932, 714, 512, 406, - 4, 28, 50, 72, 94, 0, 0, - 4, 144, 116, - 17, 68, 42, - 17, 50, 22, - 19, 46, 16, - 4, 145, 117, - 0, 0, 0, - 6, 51, 23, - 6, 47, 17}, - {22, // Ver.22 - 1258, 1006, 782, 568, 442, - 4, 26, 50, 74, 98, 0, 0, - 2, 139, 111, - 17, 74, 46, - 7, 54, 24, - 34, 37, 13, - 7, 140, 112, - 0, 0, 0, - 16, 55, 25, - 0, 0, 0}, - {23, // Ver.23 - 1364, 1094, 860, 614, 464, - 4, 30, 54, 78, 102, 0, 0, - 4, 151, 121, - 4, 75, 47, - 11, 54, 24, - 16, 45, 15, - 5, 152, 122, - 14, 76, 48, - 14, 55, 25, - 14, 46, 16}, - {24, // Ver.24 - 1474, 1174, 914, 664, 514, - 4, 28, 54, 80, 106, 0, 0, - 6, 147, 117, - 6, 73, 45, - 11, 54, 24, - 30, 46, 16, - 4, 148, 118, - 14, 74, 46, - 16, 55, 25, - 2, 47, 17}, - {25, // Ver.25 - 1588, 1276, 1000, 718, 538, - 4, 32, 58, 84, 110, 0, 0, - 8, 132, 106, - 8, 75, 47, - 7, 54, 24, - 22, 45, 15, - 4, 133, 107, - 13, 76, 48, - 22, 55, 25, - 13, 46, 16}, - {26, // Ver.26 - 1706, 1370, 1062, 754, 596, - 4, 30, 58, 86, 114, 0, 0, - 10, 142, 114, - 19, 74, 46, - 28, 50, 22, - 33, 46, 16, - 2, 143, 115, - 4, 75, 47, - 6, 51, 23, - 4, 47, 17}, - {27, // Ver.27 - 1828, 1468, 1128, 808, 628, - 4, 34, 62, 90, 118, 0, 0, - 8, 152, 122, - 22, 73, 45, - 8, 53, 23, - 12, 45, 15, - 4, 153, 123, - 3, 74, 46, - 26, 54, 24, - 28, 46, 16}, - {28, // Ver.28 - 1921, 1531, 1193, 871, 661, - 5, 26, 50, 74, 98, 122, 0, - 3, 147, 117, - 3, 73, 45, - 4, 54, 24, - 11, 45, 15, - 10, 148, 118, - 23, 74, 46, - 31, 55, 25, - 31, 46, 16}, - {29, // Ver.29 - 2051, 1631, 1267, 911, 701, - 5, 30, 54, 78, 102, 126, 0, - 7, 146, 116, - 21, 73, 45, - 1, 53, 23, - 19, 45, 15, - 7, 147, 117, - 7, 74, 46, - 37, 54, 24, - 26, 46, 16}, - {30, // Ver.30 - 2185, 1735, 1373, 985, 745, - 5, 26, 52, 78, 104, 130, 0, - 5, 145, 115, - 19, 75, 47, - 15, 54, 24, - 23, 45, 15, - 10, 146, 116, - 10, 76, 48, - 25, 55, 25, - 25, 46, 16}, - {31, // Ver.31 - 2323, 1843, 1455, 1033, 793, - 5, 30, 56, 82, 108, 134, 0, - 13, 145, 115, - 2, 74, 46, - 42, 54, 24, - 23, 45, 15, - 3, 146, 116, - 29, 75, 47, - 1, 55, 25, - 28, 46, 16}, - {32, // Ver.32 - 2465, 1955, 1541, 1115, 845, - 5, 34, 60, 86, 112, 138, 0, - 17, 145, 115, - 10, 74, 46, - 10, 54, 24, - 19, 45, 15, - 0, 0, 0, - 23, 75, 47, - 35, 55, 25, - 35, 46, 16}, - {33, // Ver.33 - 2611, 2071, 1631, 1171, 901, - 5, 30, 58, 86, 114, 142, 0, - 17, 145, 115, - 14, 74, 46, - 29, 54, 24, - 11, 45, 15, - 1, 146, 116, - 21, 75, 47, - 19, 55, 25, - 46, 46, 16}, - {34, // Ver.34 - 2761, 2191, 1725, 1231, 961, - 5, 34, 62, 90, 118, 146, 0, - 13, 145, 115, - 14, 74, 46, - 44, 54, 24, - 59, 46, 16, - 6, 146, 116, - 23, 75, 47, - 7, 55, 25, - 1, 47, 17}, - {35, // Ver.35 - 2876, 2306, 1812, 1286, 986, - 6, 30, 54, 78, 102, 126, 150, - 12, 151, 121, - 12, 75, 47, - 39, 54, 24, - 22, 45, 15, - 7, 152, 122, - 26, 76, 48, - 14, 55, 25, - 41, 46, 16}, - {36, // Ver.36 - 3034, 2434, 1914, 1354, 1054, - 6, 24, 50, 76, 102, 128, 154, - 6, 151, 121, - 6, 75, 47, - 46, 54, 24, - 2, 45, 15, - 14, 152, 122, - 34, 76, 48, - 10, 55, 25, - 64, 46, 16}, - {37, // Ver.37 - 3196, 2566, 1992, 1426, 1096, - 6, 28, 54, 80, 106, 132, 158, - 17, 152, 122, - 29, 74, 46, - 49, 54, 24, - 24, 45, 15, - 4, 153, 123, - 14, 75, 47, - 10, 55, 25, - 46, 46, 16}, - {38, // Ver.38 - 3362, 2702, 2102, 1502, 1142, - 6, 32, 58, 84, 110, 136, 162, - 4, 152, 122, - 13, 74, 46, - 48, 54, 24, - 42, 45, 15, - 18, 153, 123, - 32, 75, 47, - 14, 55, 25, - 32, 46, 16}, - {39, // Ver.39 - 3532, 2812, 2216, 1582, 1222, - 6, 26, 54, 82, 110, 138, 166, - 20, 147, 117, - 40, 75, 47, - 43, 54, 24, - 10, 45, 15, - 4, 148, 118, - 7, 76, 48, - 22, 55, 25, - 67, 46, 16}, - {40, // Ver.40 - 3706, 2956, 2334, 1666, 1276, - 6, 30, 58, 86, 114, 142, 170, - 19, 148, 118, - 18, 75, 47, - 34, 54, 24, - 20, 45, 15, - 6, 149, 119, - 31, 76, 48, - 34, 55, 25, - 61, 46, 16} - }; - - -///////////////////////////////////////////////////////////////////////////// -static unsigned char byExpToInt[] = { 1, 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, - 76, 152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96, 192, - 157, 39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119, 238, 193, 159, 35, - 70, 140, 5, 10, 20, 40, 80, 160, 93, 186, 105, 210, 185, 111, 222, 161, - 95, 190, 97, 194, 153, 47, 94, 188, 101, 202, 137, 15, 30, 60, 120, 240, - 253, 231, 211, 187, 107, 214, 177, 127, 254, 225, 223, 163, 91, 182, 113, 226, - 217, 175, 67, 134, 17, 34, 68, 136, 13, 26, 52, 104, 208, 189, 103, 206, - 129, 31, 62, 124, 248, 237, 199, 147, 59, 118, 236, 197, 151, 51, 102, 204, - 133, 23, 46, 92, 184, 109, 218, 169, 79, 158, 33, 66, 132, 21, 42, 84, - 168, 77, 154, 41, 82, 164, 85, 170, 73, 146, 57, 114, 228, 213, 183, 115, - 230, 209, 191, 99, 198, 145, 63, 126, 252, 229, 215, 179, 123, 246, 241, 255, - 227, 219, 171, 75, 150, 49, 98, 196, 149, 55, 110, 220, 165, 87, 174, 65, - 130, 25, 50, 100, 200, 141, 7, 14, 28, 56, 112, 224, 221, 167, 83, 166, - 81, 162, 89, 178, 121, 242, 249, 239, 195, 155, 43, 86, 172, 69, 138, 9, - 18, 36, 72, 144, 61, 122, 244, 245, 247, 243, 251, 235, 203, 139, 11, 22, - 44, 88, 176, 125, 250, 233, 207, 131, 27, 54, 108, 216, 173, 71, 142, 1}; - - -///////////////////////////////////////////////////////////////////////////// -static unsigned char byIntToExp[] = { 0, 0, 1, 25, 2, 50, 26, 198, 3, 223, 51, 238, 27, 104, 199, 75, - 4, 100, 224, 14, 52, 141, 239, 129, 28, 193, 105, 248, 200, 8, 76, 113, - 5, 138, 101, 47, 225, 36, 15, 33, 53, 147, 142, 218, 240, 18, 130, 69, - 29, 181, 194, 125, 106, 39, 249, 185, 201, 154, 9, 120, 77, 228, 114, 166, - 6, 191, 139, 98, 102, 221, 48, 253, 226, 152, 37, 179, 16, 145, 34, 136, - 54, 208, 148, 206, 143, 150, 219, 189, 241, 210, 19, 92, 131, 56, 70, 64, - 30, 66, 182, 163, 195, 72, 126, 110, 107, 58, 40, 84, 250, 133, 186, 61, - 202, 94, 155, 159, 10, 21, 121, 43, 78, 212, 229, 172, 115, 243, 167, 87, - 7, 112, 192, 247, 140, 128, 99, 13, 103, 74, 222, 237, 49, 197, 254, 24, - 227, 165, 153, 119, 38, 184, 180, 124, 17, 68, 146, 217, 35, 32, 137, 46, - 55, 63, 209, 91, 149, 188, 207, 205, 144, 135, 151, 178, 220, 252, 190, 97, - 242, 86, 211, 171, 20, 42, 93, 158, 132, 60, 57, 83, 71, 109, 65, 162, - 31, 45, 67, 216, 183, 123, 164, 118, 196, 23, 73, 236, 127, 12, 111, 246, - 108, 161, 59, 82, 41, 157, 85, 170, 251, 96, 134, 177, 187, 204, 62, 90, - 203, 89, 95, 176, 156, 169, 160, 81, 11, 245, 22, 235, 122, 117, 44, 215, - 79, 174, 213, 233, 230, 231, 173, 232, 116, 214, 244, 234, 168, 80, 88, 175}; - - -///////////////////////////////////////////////////////////////////////////// -static unsigned char byRSExp7[] = {87, 229, 146, 149, 238, 102, 21}; -static unsigned char byRSExp10[] = {251, 67, 46, 61, 118, 70, 64, 94, 32, 45}; -static unsigned char byRSExp13[] = { 74, 152, 176, 100, 86, 100, 106, 104, 130, 218, 206, 140, 78}; -static unsigned char byRSExp15[] = { 8, 183, 61, 91, 202, 37, 51, 58, 58, 237, 140, 124, 5, 99, 105}; -static unsigned char byRSExp16[] = {120, 104, 107, 109, 102, 161, 76, 3, 91, 191, 147, 169, 182, 194, 225, 120}; -static unsigned char byRSExp17[] = { 43, 139, 206, 78, 43, 239, 123, 206, 214, 147, 24, 99, 150, 39, 243, 163, 136}; -static unsigned char byRSExp18[] = {215, 234, 158, 94, 184, 97, 118, 170, 79, 187, 152, 148, 252, 179, 5, 98, 96, 153}; -static unsigned char byRSExp20[] = { 17, 60, 79, 50, 61, 163, 26, 187, 202, 180, 221, 225, 83, 239, 156, 164, 212, 212, 188, 190}; -static unsigned char byRSExp22[] = {210, 171, 247, 242, 93, 230, 14, 109, 221, 53, 200, 74, 8, 172, 98, 80, 219, 134, 160, 105, - 165, 231}; -static unsigned char byRSExp24[] = {229, 121, 135, 48, 211, 117, 251, 126, 159, 180, 169, 152, 192, 226, 228, 218, 111, 0, 117, 232, - 87, 96, 227, 21}; -static unsigned char byRSExp26[] = {173, 125, 158, 2, 103, 182, 118, 17, 145, 201, 111, 28, 165, 53, 161, 21, 245, 142, 13, 102, - 48, 227, 153, 145, 218, 70}; -static unsigned char byRSExp28[] = {168, 223, 200, 104, 224, 234, 108, 180, 110, 190, 195, 147, 205, 27, 232, 201, 21, 43, 245, 87, - 42, 195, 212, 119, 242, 37, 9, 123}; -static unsigned char byRSExp30[] = { 41, 173, 145, 152, 216, 31, 179, 182, 50, 48, 110, 86, 239, 96, 222, 125, 42, 173, 226, 193, - 224, 130, 156, 37, 251, 216, 238, 40, 192, 180}; -static unsigned char byRSExp32[] = { 10, 6, 106, 190, 249, 167, 4, 67, 209, 138, 138, 32, 242, 123, 89, 27, 120, 185, 80, 156, - 38, 69, 171, 60, 28, 222, 80, 52, 254, 185, 220, 241}; -static unsigned char byRSExp34[] = {111, 77, 146, 94, 26, 21, 108, 19, 105, 94, 113, 193, 86, 140, 163, 125, 58, 158, 229, 239, - 218, 103, 56, 70, 114, 61, 183, 129, 167, 13, 98, 62, 129, 51}; -static unsigned char byRSExp36[] = {200, 183, 98, 16, 172, 31, 246, 234, 60, 152, 115, 0, 167, 152, 113, 248, 238, 107, 18, 63, - 218, 37, 87, 210, 105, 177, 120, 74, 121, 196, 117, 251, 113, 233, 30, 120}; -static unsigned char byRSExp38[] = {159, 34, 38, 228, 230, 59, 243, 95, 49, 218, 176, 164, 20, 65, 45, 111, 39, 81, 49, 118, - 113, 222, 193, 250, 242, 168, 217, 41, 164, 247, 177, 30, 238, 18, 120, 153, 60, 193}; -static unsigned char byRSExp40[] = { 59, 116, 79, 161, 252, 98, 128, 205, 128, 161, 247, 57, 163, 56, 235, 106, 53, 26, 187, 174, - 226, 104, 170, 7, 175, 35, 181, 114, 88, 41, 47, 163, 125, 134, 72, 20, 232, 53, 35, 15}; -static unsigned char byRSExp42[] = {250, 103, 221, 230, 25, 18, 137, 231, 0, 3, 58, 242, 221, 191, 110, 84, 230, 8, 188, 106, - 96, 147, 15, 131, 139, 34, 101, 223, 39, 101, 213, 199, 237, 254, 201, 123, 171, 162, 194, 117, - 50, 96}; -static unsigned char byRSExp44[] = {190, 7, 61, 121, 71, 246, 69, 55, 168, 188, 89, 243, 191, 25, 72, 123, 9, 145, 14, 247, - 1, 238, 44, 78, 143, 62, 224, 126, 118, 114, 68, 163, 52, 194, 217, 147, 204, 169, 37, 130, - 113, 102, 73, 181}; -static unsigned char byRSExp46[] = {112, 94, 88, 112, 253, 224, 202, 115, 187, 99, 89, 5, 54, 113, 129, 44, 58, 16, 135, 216, - 169, 211, 36, 1, 4, 96, 60, 241, 73, 104, 234, 8, 249, 245, 119, 174, 52, 25, 157, 224, - 43, 202, 223, 19, 82, 15}; -static unsigned char byRSExp48[] = {228, 25, 196, 130, 211, 146, 60, 24, 251, 90, 39, 102, 240, 61, 178, 63, 46, 123, 115, 18, - 221, 111, 135, 160, 182, 205, 107, 206, 95, 150, 120, 184, 91, 21, 247, 156, 140, 238, 191, 11, - 94, 227, 84, 50, 163, 39, 34, 108}; -static unsigned char byRSExp50[] = {232, 125, 157, 161, 164, 9, 118, 46, 209, 99, 203, 193, 35, 3, 209, 111, 195, 242, 203, 225, - 46, 13, 32, 160, 126, 209, 130, 160, 242, 215, 242, 75, 77, 42, 189, 32, 113, 65, 124, 69, - 228, 114, 235, 175, 124, 170, 215, 232, 133, 205}; -static unsigned char byRSExp52[] = {116, 50, 86, 186, 50, 220, 251, 89, 192, 46, 86, 127, 124, 19, 184, 233, 151, 215, 22, 14, - 59, 145, 37, 242, 203, 134, 254, 89, 190, 94, 59, 65, 124, 113, 100, 233, 235, 121, 22, 76, - 86, 97, 39, 242, 200, 220, 101, 33, 239, 254, 116, 51}; -static unsigned char byRSExp54[] = {183, 26, 201, 87, 210, 221, 113, 21, 46, 65, 45, 50, 238, 184, 249, 225, 102, 58, 209, 218, - 109, 165, 26, 95, 184, 192, 52, 245, 35, 254, 238, 175, 172, 79, 123, 25, 122, 43, 120, 108, - 215, 80, 128, 201, 235, 8, 153, 59, 101, 31, 198, 76, 31, 156}; -static unsigned char byRSExp56[] = {106, 120, 107, 157, 164, 216, 112, 116, 2, 91, 248, 163, 36, 201, 202, 229, 6, 144, 254, 155, - 135, 208, 170, 209, 12, 139, 127, 142, 182, 249, 177, 174, 190, 28, 10, 85, 239, 184, 101, 124, - 152, 206, 96, 23, 163, 61, 27, 196, 247, 151, 154, 202, 207, 20, 61, 10}; -static unsigned char byRSExp58[] = { 82, 116, 26, 247, 66, 27, 62, 107, 252, 182, 200, 185, 235, 55, 251, 242, 210, 144, 154, 237, - 176, 141, 192, 248, 152, 249, 206, 85, 253, 142, 65, 165, 125, 23, 24, 30, 122, 240, 214, 6, - 129, 218, 29, 145, 127, 134, 206, 245, 117, 29, 41, 63, 159, 142, 233, 125, 148, 123}; -static unsigned char byRSExp60[] = {107, 140, 26, 12, 9, 141, 243, 197, 226, 197, 219, 45, 211, 101, 219, 120, 28, 181, 127, 6, - 100, 247, 2, 205, 198, 57, 115, 219, 101, 109, 160, 82, 37, 38, 238, 49, 160, 209, 121, 86, - 11, 124, 30, 181, 84, 25, 194, 87, 65, 102, 190, 220, 70, 27, 209, 16, 89, 7, 33, 240}; -static unsigned char byRSExp62[] = { 65, 202, 113, 98, 71, 223, 248, 118, 214, 94, 0, 122, 37, 23, 2, 228, 58, 121, 7, 105, - 135, 78, 243, 118, 70, 76, 223, 89, 72, 50, 70, 111, 194, 17, 212, 126, 181, 35, 221, 117, - 235, 11, 229, 149, 147, 123, 213, 40, 115, 6, 200, 100, 26, 246, 182, 218, 127, 215, 36, 186, - 110, 106}; -static unsigned char byRSExp64[] = { 45, 51, 175, 9, 7, 158, 159, 49, 68, 119, 92, 123, 177, 204, 187, 254, 200, 78, 141, 149, - 119, 26, 127, 53, 160, 93, 199, 212, 29, 24, 145, 156, 208, 150, 218, 209, 4, 216, 91, 47, - 184, 146, 47, 140, 195, 195, 125, 242, 238, 63, 99, 108, 140, 230, 242, 31, 204, 11, 178, 243, - 217, 156, 213, 231}; -static unsigned char byRSExp66[] = { 5, 118, 222, 180, 136, 136, 162, 51, 46, 117, 13, 215, 81, 17, 139, 247, 197, 171, 95, 173, - 65, 137, 178, 68, 111, 95, 101, 41, 72, 214, 169, 197, 95, 7, 44, 154, 77, 111, 236, 40, - 121, 143, 63, 87, 80, 253, 240, 126, 217, 77, 34, 232, 106, 50, 168, 82, 76, 146, 67, 106, - 171, 25, 132, 93, 45, 105}; -static unsigned char byRSExp68[] = {247, 159, 223, 33, 224, 93, 77, 70, 90, 160, 32, 254, 43, 150, 84, 101, 190, 205, 133, 52, - 60, 202, 165, 220, 203, 151, 93, 84, 15, 84, 253, 173, 160, 89, 227, 52, 199, 97, 95, 231, - 52, 177, 41, 125, 137, 241, 166, 225, 118, 2, 54, 32, 82, 215, 175, 198, 43, 238, 235, 27, - 101, 184, 127, 3, 5, 8, 163, 238}; - -static unsigned char* byRSExp[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, byRSExp7, NULL, NULL, - byRSExp10, NULL, NULL, byRSExp13, NULL, byRSExp15, byRSExp16, byRSExp17, byRSExp18, NULL, - byRSExp20, NULL, byRSExp22, NULL, byRSExp24, NULL, byRSExp26, NULL, byRSExp28, NULL, - byRSExp30, NULL, byRSExp32, NULL, byRSExp34, NULL, byRSExp36, NULL, byRSExp38, NULL, - byRSExp40, NULL, byRSExp42, NULL, byRSExp44, NULL, byRSExp46, NULL, byRSExp48, NULL, - byRSExp50, NULL, byRSExp52, NULL, byRSExp54, NULL, byRSExp56, NULL, byRSExp58, NULL, - byRSExp60, NULL, byRSExp62, NULL, byRSExp64, NULL, byRSExp66, NULL, byRSExp68}; - -static int nIndicatorLenNumeral[] = {10, 12, 14}; -static int nIndicatorLenAlphabet[] = { 9, 11, 13}; -static int nIndicatorLen8Bit[] = { 8, 16, 16}; -static int nIndicatorLenKanji[] = { 8, 10, 12}; - - -///////////////////////////////////////////////////////////////////////////// - -CQR_Encode::CQR_Encode() -{ -} - -CQR_Encode::~CQR_Encode() -{ -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::EncodeData - -bool CQR_Encode::EncodeData(int nLevel, int nVersion, bool bAutoExtent, int nMaskingNo, const char* lpsSource, int ncSource) -{ - int i, j; - - m_nLevel = nLevel; - m_nMaskingNo = nMaskingNo; - - int ncLength = ncSource > 0 ? ncSource : strlen(lpsSource); - - if (ncLength == 0) - return false; - - - int nEncodeVersion = GetEncodeVersion(nVersion, lpsSource, ncLength); - - if (nEncodeVersion == 0) - return false; - - if (nVersion == 0) - { - - m_nVersion = nEncodeVersion; - } - else - { - if (nEncodeVersion <= nVersion) - { - m_nVersion = nVersion; - } - else - { - if (bAutoExtent) - m_nVersion = nEncodeVersion; - else - return false; - } - } - - int ncDataCodeWord = QR_VersonInfo[m_nVersion].ncDataCodeWord[nLevel]; - - int ncTerminater = std::min(4, (ncDataCodeWord * 8) - m_ncDataCodeWordBit); - - if (ncTerminater > 0) - m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 0, ncTerminater); - - unsigned char byPaddingCode = 0xec; - - for (i = (m_ncDataCodeWordBit + 7) / 8; i < ncDataCodeWord; ++i) - { - m_byDataCodeWord[i] = byPaddingCode; - - byPaddingCode = (unsigned char)(byPaddingCode == 0xec ? 0x11 : 0xec); - } - - - m_ncAllCodeWord = QR_VersonInfo[m_nVersion].ncAllCodeWord; - memset(m_byAllCodeWord, 0, m_ncAllCodeWord); - - int nDataCwIndex = 0; - - int ncBlock1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[nLevel].ncRSBlock; - int ncBlock2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[nLevel].ncRSBlock; - int ncBlockSum = ncBlock1 + ncBlock2; - - int nBlockNo = 0; - - int ncDataCw1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[nLevel].ncDataCodeWord; - int ncDataCw2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[nLevel].ncDataCodeWord; - - for (i = 0; i < ncBlock1; ++i) - { - for (j = 0; j < ncDataCw1; ++j) - { - m_byAllCodeWord[(ncBlockSum * j) + nBlockNo] = m_byDataCodeWord[nDataCwIndex++]; - } - - ++nBlockNo; - } - - for (i = 0; i < ncBlock2; ++i) - { - for (j = 0; j < ncDataCw2; ++j) - { - if (j < ncDataCw1) - { - m_byAllCodeWord[(ncBlockSum * j) + nBlockNo] = m_byDataCodeWord[nDataCwIndex++]; - } - else - { - m_byAllCodeWord[(ncBlockSum * ncDataCw1) + i] = m_byDataCodeWord[nDataCwIndex++]; - } - } - - ++nBlockNo; - } - - int ncRSCw1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[nLevel].ncAllCodeWord - ncDataCw1; - int ncRSCw2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[nLevel].ncAllCodeWord - ncDataCw2; - - ///////////////////////////////////////////////////////////////////////// - - nDataCwIndex = 0; - nBlockNo = 0; - - for (i = 0; i < ncBlock1; ++i) - { - memset(m_byRSWork, 0, sizeof(m_byRSWork)); - - memmove(m_byRSWork, m_byDataCodeWord + nDataCwIndex, ncDataCw1); - - GetRSCodeWord(m_byRSWork, ncDataCw1, ncRSCw1); - - for (j = 0; j < ncRSCw1; ++j) - { - m_byAllCodeWord[ncDataCodeWord + (ncBlockSum * j) + nBlockNo] = m_byRSWork[j]; - } - - nDataCwIndex += ncDataCw1; - ++nBlockNo; - } - - for (i = 0; i < ncBlock2; ++i) - { - memset(m_byRSWork, 0, sizeof(m_byRSWork)); - - memmove(m_byRSWork, m_byDataCodeWord + nDataCwIndex, ncDataCw2); - - GetRSCodeWord(m_byRSWork, ncDataCw2, ncRSCw2); - - for (j = 0; j < ncRSCw2; ++j) - { - m_byAllCodeWord[ncDataCodeWord + (ncBlockSum * j) + nBlockNo] = m_byRSWork[j]; - } - - nDataCwIndex += ncDataCw2; - ++nBlockNo; - } - - m_nSymbleSize = m_nVersion * 4 + 17; - - FormatModule(); - - return true; -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::GetEncodeVersion - -int CQR_Encode::GetEncodeVersion(int nVersion, const char* lpsSource, int ncLength) -{ - int nVerGroup = nVersion >= 27 ? QR_VRESION_L : (nVersion >= 10 ? QR_VRESION_M : QR_VRESION_S); - int i, j; - - for (i = nVerGroup; i <= QR_VRESION_L; ++i) - { - if (EncodeSourceData(lpsSource, ncLength, i)) - { - if (i == QR_VRESION_S) - { - for (j = 1; j <= 9; ++j) - { - if ((m_ncDataCodeWordBit + 7) / 8 <= QR_VersonInfo[j].ncDataCodeWord[m_nLevel]) - return j; - } - } - else if (i == QR_VRESION_M) - { - for (j = 10; j <= 26; ++j) - { - if ((m_ncDataCodeWordBit + 7) / 8 <= QR_VersonInfo[j].ncDataCodeWord[m_nLevel]) - return j; - } - } - else if (i == QR_VRESION_L) - { - for (j = 27; j <= 40; ++j) - { - if ((m_ncDataCodeWordBit + 7) / 8 <= QR_VersonInfo[j].ncDataCodeWord[m_nLevel]) - return j; - } - } - } - } - - return 0; -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::EncodeSourceData -bool CQR_Encode::EncodeSourceData(const char* lpsSource, int ncLength, int nVerGroup) -{ - memset(m_nBlockLength, 0, sizeof(m_nBlockLength)); - - int i, j; - - for (m_ncDataBlock = i = 0; i < ncLength; ++i) - { - unsigned char byMode; - - if (i < ncLength - 1 && IsKanjiData(lpsSource[i], lpsSource[i + 1])) - byMode = QR_MODE_KANJI; - else if (IsNumeralData(lpsSource[i])) - byMode = QR_MODE_NUMERAL; - else if (IsAlphabetData(lpsSource[i])) - byMode = QR_MODE_ALPHABET; - else - byMode = QR_MODE_8BIT; - - if (i == 0) - m_byBlockMode[0] = byMode; - - if (m_byBlockMode[m_ncDataBlock] != byMode) - m_byBlockMode[++m_ncDataBlock] = byMode; - - ++m_nBlockLength[m_ncDataBlock]; - - if (byMode == QR_MODE_KANJI) - { - ++m_nBlockLength[m_ncDataBlock]; - ++i; - } - } - - ++m_ncDataBlock; - - ///////////////////////////////////////////////////////////////////////// - - int ncSrcBits, ncDstBits; - - int nBlock = 0; - - while (nBlock < m_ncDataBlock - 1) - { - int ncJoinFront, ncJoinBehind; - int nJoinPosition = 0; - - if ((m_byBlockMode[nBlock] == QR_MODE_NUMERAL && m_byBlockMode[nBlock + 1] == QR_MODE_ALPHABET) || - (m_byBlockMode[nBlock] == QR_MODE_ALPHABET && m_byBlockMode[nBlock + 1] == QR_MODE_NUMERAL)) - { - ncSrcBits = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup) + - GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup); - - ncDstBits = GetBitLength(QR_MODE_ALPHABET, m_nBlockLength[nBlock] + m_nBlockLength[nBlock + 1], nVerGroup); - - if (ncSrcBits > ncDstBits) - { - if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT) - { - ncJoinFront = GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock - 1] + m_nBlockLength[nBlock], nVerGroup) + - GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup); - - if (ncJoinFront > ncDstBits + GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock - 1], nVerGroup)) - ncJoinFront = 0; - } - else - ncJoinFront = 0; - - if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT) - { - ncJoinBehind = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup) + - GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock + 1] + m_nBlockLength[nBlock + 2], nVerGroup); - - if (ncJoinBehind > ncDstBits + GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock + 2], nVerGroup)) - ncJoinBehind = 0; - } - else - ncJoinBehind = 0; - - if (ncJoinFront != 0 && ncJoinBehind != 0) - { - nJoinPosition = (ncJoinFront < ncJoinBehind) ? -1 : 1; - } - else - { - nJoinPosition = (ncJoinFront != 0) ? -1 : ((ncJoinBehind != 0) ? 1 : 0); - } - - if (nJoinPosition != 0) - { - if (nJoinPosition == -1) - { - m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock]; - - for (i = nBlock; i < m_ncDataBlock - 1; ++i) - { - m_byBlockMode[i] = m_byBlockMode[i + 1]; - m_nBlockLength[i] = m_nBlockLength[i + 1]; - } - } - else - { - m_byBlockMode[nBlock + 1] = QR_MODE_8BIT; - m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2]; - - for (i = nBlock + 2; i < m_ncDataBlock - 1; ++i) - { - m_byBlockMode[i] = m_byBlockMode[i + 1]; - m_nBlockLength[i] = m_nBlockLength[i + 1]; - } - } - - --m_ncDataBlock; - } - else - { - - if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_ALPHABET) - { - m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2]; - - for (i = nBlock + 2; i < m_ncDataBlock - 1; ++i) - { - m_byBlockMode[i] = m_byBlockMode[i + 1]; - m_nBlockLength[i] = m_nBlockLength[i + 1]; - } - - --m_ncDataBlock; - } - - m_byBlockMode[nBlock] = QR_MODE_ALPHABET; - m_nBlockLength[nBlock] += m_nBlockLength[nBlock + 1]; - - for (i = nBlock + 1; i < m_ncDataBlock - 1; ++i) - { - m_byBlockMode[i] = m_byBlockMode[i + 1]; - m_nBlockLength[i] = m_nBlockLength[i + 1]; - } - - --m_ncDataBlock; - - if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_ALPHABET) - { - m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock]; - - for (i = nBlock; i < m_ncDataBlock - 1; ++i) - { - m_byBlockMode[i] = m_byBlockMode[i + 1]; - m_nBlockLength[i] = m_nBlockLength[i + 1]; - } - - --m_ncDataBlock; - } - } - - continue; - } - } - - ++nBlock; - } - - ///////////////////////////////////////////////////////////////////////// - - nBlock = 0; - - while (nBlock < m_ncDataBlock - 1) - { - ncSrcBits = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup) - + GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup); - - ncDstBits = GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock] + m_nBlockLength[nBlock + 1], nVerGroup); - - if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT) - ncDstBits -= (4 + nIndicatorLen8Bit[nVerGroup]); - - if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT) - ncDstBits -= (4 + nIndicatorLen8Bit[nVerGroup]); - - if (ncSrcBits > ncDstBits) - { - if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT) - { - m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock]; - - for (i = nBlock; i < m_ncDataBlock - 1; ++i) - { - m_byBlockMode[i] = m_byBlockMode[i + 1]; - m_nBlockLength[i] = m_nBlockLength[i + 1]; - } - - --m_ncDataBlock; - --nBlock; - } - - if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT) - { - m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2]; - - for (i = nBlock + 2; i < m_ncDataBlock - 1; ++i) - { - m_byBlockMode[i] = m_byBlockMode[i + 1]; - m_nBlockLength[i] = m_nBlockLength[i + 1]; - } - - --m_ncDataBlock; - } - - m_byBlockMode[nBlock] = QR_MODE_8BIT; - m_nBlockLength[nBlock] += m_nBlockLength[nBlock + 1]; - - for (i = nBlock + 1; i < m_ncDataBlock - 1; ++i) - { - m_byBlockMode[i] = m_byBlockMode[i + 1]; - m_nBlockLength[i] = m_nBlockLength[i + 1]; - } - - --m_ncDataBlock; - - if (nBlock >= 1) - --nBlock; - - continue; - } - - ++nBlock; - } - - ///////////////////////////////////////////////////////////////////////// - int ncComplete = 0; - unsigned short wBinCode; - - m_ncDataCodeWordBit = 0; - - memset(m_byDataCodeWord, 0, MAX_DATACODEWORD); - - for (i = 0; i < m_ncDataBlock && m_ncDataCodeWordBit != -1; ++i) - { - if (m_byBlockMode[i] == QR_MODE_NUMERAL) - { - ///////////////////////////////////////////////////////////////// - - m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 1, 4); - - m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (unsigned short)m_nBlockLength[i], nIndicatorLenNumeral[nVerGroup]); - - for (j = 0; j < m_nBlockLength[i]; j += 3) - { - if (j < m_nBlockLength[i] - 2) - { - wBinCode = (unsigned short)(((lpsSource[ncComplete + j] - '0') * 100) + - ((lpsSource[ncComplete + j + 1] - '0') * 10) + - (lpsSource[ncComplete + j + 2] - '0')); - - m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 10); - } - else if (j == m_nBlockLength[i] - 2) - { - wBinCode = (unsigned short)(((lpsSource[ncComplete + j] - '0') * 10) + - (lpsSource[ncComplete + j + 1] - '0')); - - m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 7); - } - else if (j == m_nBlockLength[i] - 1) - { - wBinCode = (unsigned short)(lpsSource[ncComplete + j] - '0'); - - m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 4); - } - } - - ncComplete += m_nBlockLength[i]; - } - - else if (m_byBlockMode[i] == QR_MODE_ALPHABET) - { - ///////////////////////////////////////////////////////////////// - - m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 2, 4); - - m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (unsigned short)m_nBlockLength[i], nIndicatorLenAlphabet[nVerGroup]); - - for (j = 0; j < m_nBlockLength[i]; j += 2) - { - if (j < m_nBlockLength[i] - 1) - { - wBinCode = (unsigned short)((AlphabetToBinaly(lpsSource[ncComplete + j]) * 45) + - AlphabetToBinaly(lpsSource[ncComplete + j + 1])); - - m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 11); - } - else - { - wBinCode = (unsigned short)AlphabetToBinaly(lpsSource[ncComplete + j]); - - m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 6); - } - } - - ncComplete += m_nBlockLength[i]; - } - - else if (m_byBlockMode[i] == QR_MODE_8BIT) - { - ///////////////////////////////////////////////////////////////// - - m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 4, 4); - - m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (unsigned short)m_nBlockLength[i], nIndicatorLen8Bit[nVerGroup]); - - for (j = 0; j < m_nBlockLength[i]; ++j) - { - m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (unsigned short)lpsSource[ncComplete + j], 8); - } - - ncComplete += m_nBlockLength[i]; - } - else - { - ///////////////////////////////////////////////////////////////// - - m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 8, 4); - - m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (unsigned short)(m_nBlockLength[i] / 2), nIndicatorLenKanji[nVerGroup]); - - for (j = 0; j < m_nBlockLength[i] / 2; ++j) - { - unsigned short wBinCode = KanjiToBinaly((unsigned short)(((unsigned char)lpsSource[ncComplete + (j * 2)] << 8) + (unsigned char)lpsSource[ncComplete + (j * 2) + 1])); - - m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 13); - } - - ncComplete += m_nBlockLength[i]; - } - } - - return (m_ncDataCodeWordBit != -1); -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::GetBitLength - -int CQR_Encode::GetBitLength(unsigned char nMode, int ncData, int nVerGroup) -{ - int ncBits = 0; - - switch (nMode) - { - case QR_MODE_NUMERAL: - ncBits = 4 + nIndicatorLenNumeral[nVerGroup] + (10 * (ncData / 3)); - switch (ncData % 3) - { - case 1: - ncBits += 4; - break; - case 2: - ncBits += 7; - break; - default: // case 0: - break; - } - - break; - - case QR_MODE_ALPHABET: - ncBits = 4 + nIndicatorLenAlphabet[nVerGroup] + (11 * (ncData / 2)) + (6 * (ncData % 2)); - break; - - case QR_MODE_8BIT: - ncBits = 4 + nIndicatorLen8Bit[nVerGroup] + (8 * ncData); - break; - - default: // case QR_MODE_KANJI: - ncBits = 4 + nIndicatorLenKanji[nVerGroup] + (13 * (ncData / 2)); - break; - } - - return ncBits; -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::SetBitStream - -int CQR_Encode::SetBitStream(int nIndex, unsigned short wData, int ncData) -{ - int i; - - if (nIndex == -1 || nIndex + ncData > MAX_DATACODEWORD * 8) - return -1; - - for (i = 0; i < ncData; ++i) - { - if (wData & (1 << (ncData - i - 1))) - { - m_byDataCodeWord[(nIndex + i) / 8] |= 1 << (7 - ((nIndex + i) % 8)); - } - } - - return nIndex + ncData; -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::IsNumeralData - -bool CQR_Encode::IsNumeralData(unsigned char c) -{ - if (c >= '0' && c <= '9') - return true; - - return false; -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::IsAlphabetData - -bool CQR_Encode::IsAlphabetData(unsigned char c) -{ - if (c >= '0' && c <= '9') - return true; - - if (c >= 'A' && c <= 'Z') - return true; - - if (c == ' ' || c == '$' || c == '%' || c == '*' || c == '+' || c == '-' || c == '.' || c == '/' || c == ':') - return true; - - return false; -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::IsKanjiData - -bool CQR_Encode::IsKanjiData(unsigned char c1, unsigned char c2) -{ - if (((c1 >= 0x81 && c1 <= 0x9f) || (c1 >= 0xe0 && c1 <= 0xeb)) && (c2 >= 0x40)) - { - if ((c1 == 0x9f && c2 > 0xfc) || (c1 == 0xeb && c2 > 0xbf)) - return false; - - return true; - } - - return false; -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::AlphabetToBinaly - -unsigned char CQR_Encode::AlphabetToBinaly(unsigned char c) -{ - if (c >= '0' && c <= '9') return (unsigned char)(c - '0'); - - if (c >= 'A' && c <= 'Z') return (unsigned char)(c - 'A' + 10); - - if (c == ' ') return 36; - - if (c == '$') return 37; - - if (c == '%') return 38; - - if (c == '*') return 39; - - if (c == '+') return 40; - - if (c == '-') return 41; - - if (c == '.') return 42; - - if (c == '/') return 43; - - return 44; // c == ':' -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::KanjiToBinaly - -unsigned short CQR_Encode::KanjiToBinaly(unsigned short wc) -{ - if (wc >= 0x8140 && wc <= 0x9ffc) - wc -= 0x8140; - else // (wc >= 0xe040 && wc <= 0xebbf) - wc -= 0xc140; - - return (unsigned short)(((wc >> 8) * 0xc0) + (wc & 0x00ff)); -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::GetRSCodeWord -void CQR_Encode::GetRSCodeWord(unsigned char * lpbyRSWork, int ncDataCodeWord, int ncRSCodeWord) -{ - int i, j; - - for (i = 0; i < ncDataCodeWord ; ++i) - { - if (lpbyRSWork[0] != 0) - { - unsigned char nExpFirst = byIntToExp[lpbyRSWork[0]]; - - for (j = 0; j < ncRSCodeWord; ++j) - { - unsigned char nExpElement = (unsigned char)(((int)(byRSExp[ncRSCodeWord][j] + nExpFirst)) % 255); - - lpbyRSWork[j] = (unsigned char)(lpbyRSWork[j + 1] ^ byExpToInt[nExpElement]); - } - - for (j = ncRSCodeWord; j < ncDataCodeWord + ncRSCodeWord - 1; ++j) - lpbyRSWork[j] = lpbyRSWork[j + 1]; - } - else - { - for (j = 0; j < ncDataCodeWord + ncRSCodeWord - 1; ++j) - lpbyRSWork[j] = lpbyRSWork[j + 1]; - } - } -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::FormatModule - -void CQR_Encode::FormatModule() -{ - int i, j; - - memset(m_byModuleData, 0, sizeof(m_byModuleData)); - - SetFunctionModule(); - - SetCodeWordPattern(); - - if (m_nMaskingNo == -1) - { - m_nMaskingNo = 0; - - SetMaskingPattern(m_nMaskingNo); - SetFormatInfoPattern(m_nMaskingNo); - - int nMinPenalty = CountPenalty(); - - for (i = 1; i <= 7; ++i) - { - SetMaskingPattern(i); - SetFormatInfoPattern(i); - - int nPenalty = CountPenalty(); - - if (nPenalty < nMinPenalty) - { - nMinPenalty = nPenalty; - m_nMaskingNo = i; - } - } - } - - SetMaskingPattern(m_nMaskingNo); - SetFormatInfoPattern(m_nMaskingNo); - - for (i = 0; i < m_nSymbleSize; ++i) - { - for (j = 0; j < m_nSymbleSize; ++j) - { - m_byModuleData[i][j] = (unsigned char)((m_byModuleData[i][j] & 0x11) != 0); - } - } -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::SetFunctionModule - -void CQR_Encode::SetFunctionModule() -{ - int i, j; - - SetFinderPattern(0, 0); - SetFinderPattern(m_nSymbleSize - 7, 0); - SetFinderPattern(0, m_nSymbleSize - 7); - - for (i = 0; i < 8; ++i) - { - m_byModuleData[i][7] = m_byModuleData[7][i] = '\x20'; - m_byModuleData[m_nSymbleSize - 8][i] = m_byModuleData[m_nSymbleSize - 8 + i][7] = '\x20'; - m_byModuleData[i][m_nSymbleSize - 8] = m_byModuleData[7][m_nSymbleSize - 8 + i] = '\x20'; - } - - for (i = 0; i < 9; ++i) - { - m_byModuleData[i][8] = m_byModuleData[8][i] = '\x20'; - } - - for (i = 0; i < 8; ++i) - { - m_byModuleData[m_nSymbleSize - 8 + i][8] = m_byModuleData[8][m_nSymbleSize - 8 + i] = '\x20'; - } - - SetVersionPattern(); - - for (i = 0; i < QR_VersonInfo[m_nVersion].ncAlignPoint; ++i) - { - SetAlignmentPattern(QR_VersonInfo[m_nVersion].nAlignPoint[i], 6); - SetAlignmentPattern(6, QR_VersonInfo[m_nVersion].nAlignPoint[i]); - - for (j = 0; j < QR_VersonInfo[m_nVersion].ncAlignPoint; ++j) - { - SetAlignmentPattern(QR_VersonInfo[m_nVersion].nAlignPoint[i], QR_VersonInfo[m_nVersion].nAlignPoint[j]); - } - } - - for (i = 8; i <= m_nSymbleSize - 9; ++i) - { - m_byModuleData[i][6] = (i % 2) == 0 ? '\x30' : '\x20'; - m_byModuleData[6][i] = (i % 2) == 0 ? '\x30' : '\x20'; - } -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::SetFinderPattern - -void CQR_Encode::SetFinderPattern(int x, int y) -{ - static unsigned char byPattern[] = {0x7f, // 1111111b - 0x41, // 1000001b - 0x5d, // 1011101b - 0x5d, // 1011101b - 0x5d, // 1011101b - 0x41, // 1000001b - 0x7f}; // 1111111b - int i, j; - - for (i = 0; i < 7; ++i) - { - for (j = 0; j < 7; ++j) - { - m_byModuleData[x + j][y + i] = (byPattern[i] & (1 << (6 - j))) ? '\x30' : '\x20'; - } - } -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::SetAlignmentPattern - -void CQR_Encode::SetAlignmentPattern(int x, int y) -{ - static unsigned char byPattern[] = {0x1f, // 11111b - 0x11, // 10001b - 0x15, // 10101b - 0x11, // 10001b - 0x1f}; // 11111b - int i, j; - - if (m_byModuleData[x][y] & 0x20) - return; - - x -= 2; y -= 2; - - for (i = 0; i < 5; ++i) - { - for (j = 0; j < 5; ++j) - { - m_byModuleData[x + j][y + i] = (byPattern[i] & (1 << (4 - j))) ? '\x30' : '\x20'; - } - } -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::SetVersionPattern - -void CQR_Encode::SetVersionPattern() -{ - int i, j; - - if (m_nVersion <= 6) - return; - - int nVerData = m_nVersion << 12; - - for (i = 0; i < 6; ++i) - { - if (nVerData & (1 << (17 - i))) - { - nVerData ^= (0x1f25 << (5 - i)); - } - } - - nVerData += m_nVersion << 12; - - for (i = 0; i < 6; ++i) - { - for (j = 0; j < 3; ++j) - { - m_byModuleData[m_nSymbleSize - 11 + j][i] = m_byModuleData[i][m_nSymbleSize - 11 + j] = - (nVerData & (1 << (i * 3 + j))) ? '\x30' : '\x20'; - } - } -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::SetCodeWordPattern - -void CQR_Encode::SetCodeWordPattern() -{ - int x = m_nSymbleSize; - int y = m_nSymbleSize - 1; - - int nCoef_x = 1; - int nCoef_y = 1; - - int i, j; - - for (i = 0; i < m_ncAllCodeWord; ++i) - { - for (j = 0; j < 8; ++j) - { - do - { - x += nCoef_x; - nCoef_x *= -1; - - if (nCoef_x < 0) - { - y += nCoef_y; - - if (y < 0 || y == m_nSymbleSize) - { - y = (y < 0) ? 0 : m_nSymbleSize - 1; - nCoef_y *= -1; - - x -= 2; - - if (x == 6) - --x; - } - } - } - while (m_byModuleData[x][y] & 0x20); - - m_byModuleData[x][y] = (m_byAllCodeWord[i] & (1 << (7 - j))) ? '\x02' : '\x00'; - } - } -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::SetMaskingPattern - -void CQR_Encode::SetMaskingPattern(int nPatternNo) -{ - int i, j; - - for (i = 0; i < m_nSymbleSize; ++i) - { - for (j = 0; j < m_nSymbleSize; ++j) - { - if (! (m_byModuleData[j][i] & 0x20)) - { - bool bMask; - - switch (nPatternNo) - { - case 0: - bMask = ((i + j) % 2 == 0); - break; - - case 1: - bMask = (i % 2 == 0); - break; - - case 2: - bMask = (j % 3 == 0); - break; - - case 3: - bMask = ((i + j) % 3 == 0); - break; - - case 4: - bMask = (((i / 2) + (j / 3)) % 2 == 0); - break; - - case 5: - bMask = (((i * j) % 2) + ((i * j) % 3) == 0); - break; - - case 6: - bMask = ((((i * j) % 2) + ((i * j) % 3)) % 2 == 0); - break; - - default: // case 7: - bMask = ((((i * j) % 3) + ((i + j) % 2)) % 2 == 0); - break; - } - - m_byModuleData[j][i] = (unsigned char)((m_byModuleData[j][i] & 0xfe) | (((m_byModuleData[j][i] & 0x02) > 1) ^ bMask)); - } - } - } -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::SetFormatInfoPattern - -void CQR_Encode::SetFormatInfoPattern(int nPatternNo) -{ - int nFormatInfo; - int i; - - switch (m_nLevel) - { - case QR_LEVEL_M: - nFormatInfo = 0x00; // 00nnnb - break; - - case QR_LEVEL_L: - nFormatInfo = 0x08; // 01nnnb - break; - - case QR_LEVEL_Q: - nFormatInfo = 0x18; // 11nnnb - break; - - default: // case QR_LEVEL_H: - nFormatInfo = 0x10; // 10nnnb - break; - } - - nFormatInfo += nPatternNo; - - int nFormatData = nFormatInfo << 10; - - for (i = 0; i < 5; ++i) - { - if (nFormatData & (1 << (14 - i))) - { - nFormatData ^= (0x0537 << (4 - i)); // 10100110111b - } - } - - nFormatData += nFormatInfo << 10; - - nFormatData ^= 0x5412; // 101010000010010b - - for (i = 0; i <= 5; ++i) - m_byModuleData[8][i] = (nFormatData & (1 << i)) ? '\x30' : '\x20'; - - m_byModuleData[8][7] = (nFormatData & (1 << 6)) ? '\x30' : '\x20'; - m_byModuleData[8][8] = (nFormatData & (1 << 7)) ? '\x30' : '\x20'; - m_byModuleData[7][8] = (nFormatData & (1 << 8)) ? '\x30' : '\x20'; - - for (i = 9; i <= 14; ++i) - m_byModuleData[14 - i][8] = (nFormatData & (1 << i)) ? '\x30' : '\x20'; - - for (i = 0; i <= 7; ++i) - m_byModuleData[m_nSymbleSize - 1 - i][8] = (nFormatData & (1 << i)) ? '\x30' : '\x20'; - - m_byModuleData[8][m_nSymbleSize - 8] = '\x30'; - - for (i = 8; i <= 14; ++i) - m_byModuleData[8][m_nSymbleSize - 15 + i] = (nFormatData & (1 << i)) ? '\x30' : '\x20'; -} - - -///////////////////////////////////////////////////////////////////////////// -// CQR_Encode::CountPenalty - -int CQR_Encode::CountPenalty() -{ - int nPenalty = 0; - int i, j, k; - - for (i = 0; i < m_nSymbleSize; ++i) - { - for (j = 0; j < m_nSymbleSize - 4; ++j) - { - int nCount = 1; - - for (k = j + 1; k < m_nSymbleSize; k++) - { - if (((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i][k] & 0x11) == 0)) - ++nCount; - else - break; - } - - if (nCount >= 5) - { - nPenalty += 3 + (nCount - 5); - } - - j = k - 1; - } - } - - for (i = 0; i < m_nSymbleSize; ++i) - { - for (j = 0; j < m_nSymbleSize - 4; ++j) - { - int nCount = 1; - - for (k = j + 1; k < m_nSymbleSize; k++) - { - if (((m_byModuleData[j][i] & 0x11) == 0) == ((m_byModuleData[k][i] & 0x11) == 0)) - ++nCount; - else - break; - } - - if (nCount >= 5) - { - nPenalty += 3 + (nCount - 5); - } - - j = k - 1; - } - } - - for (i = 0; i < m_nSymbleSize - 1; ++i) - { - for (j = 0; j < m_nSymbleSize - 1; ++j) - { - if ((((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i + 1][j] & 0x11) == 0)) && - (((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i] [j + 1] & 0x11) == 0)) && - (((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i + 1][j + 1] & 0x11) == 0))) - { - nPenalty += 3; - } - } - } - - for (i = 0; i < m_nSymbleSize; ++i) - { - for (j = 0; j < m_nSymbleSize - 6; ++j) - { - if (((j == 0) || (! (m_byModuleData[i][j - 1] & 0x11))) && - ( m_byModuleData[i][j] & 0x11) && - (! (m_byModuleData[i][j + 1] & 0x11)) && - ( m_byModuleData[i][j + 2] & 0x11) && - ( m_byModuleData[i][j + 3] & 0x11) && - ( m_byModuleData[i][j + 4] & 0x11) && - (! (m_byModuleData[i][j + 5] & 0x11)) && - ( m_byModuleData[i][j + 6] & 0x11) && - ((j == m_nSymbleSize - 7) || (! (m_byModuleData[i][j + 7] & 0x11)))) - { - if (((j < 2 || ! (m_byModuleData[i][j - 2] & 0x11)) && - (j < 3 || ! (m_byModuleData[i][j - 3] & 0x11)) && - (j < 4 || ! (m_byModuleData[i][j - 4] & 0x11))) || - ((j >= m_nSymbleSize - 8 || ! (m_byModuleData[i][j + 8] & 0x11)) && - (j >= m_nSymbleSize - 9 || ! (m_byModuleData[i][j + 9] & 0x11)) && - (j >= m_nSymbleSize - 10 || ! (m_byModuleData[i][j + 10] & 0x11)))) - { - nPenalty += 40; - } - } - } - } - - for (i = 0; i < m_nSymbleSize; ++i) - { - for (j = 0; j < m_nSymbleSize - 6; ++j) - { - if (((j == 0) || (! (m_byModuleData[j - 1][i] & 0x11))) && - ( m_byModuleData[j] [i] & 0x11) && - (! (m_byModuleData[j + 1][i] & 0x11)) && - ( m_byModuleData[j + 2][i] & 0x11) && - ( m_byModuleData[j + 3][i] & 0x11) && - ( m_byModuleData[j + 4][i] & 0x11) && - (! (m_byModuleData[j + 5][i] & 0x11)) && - ( m_byModuleData[j + 6][i] & 0x11) && - ((j == m_nSymbleSize - 7) || (! (m_byModuleData[j + 7][i] & 0x11)))) - { - if (((j < 2 || ! (m_byModuleData[j - 2][i] & 0x11)) && - (j < 3 || ! (m_byModuleData[j - 3][i] & 0x11)) && - (j < 4 || ! (m_byModuleData[j - 4][i] & 0x11))) || - ((j >= m_nSymbleSize - 8 || ! (m_byModuleData[j + 8][i] & 0x11)) && - (j >= m_nSymbleSize - 9 || ! (m_byModuleData[j + 9][i] & 0x11)) && - (j >= m_nSymbleSize - 10 || ! (m_byModuleData[j + 10][i] & 0x11)))) - { - nPenalty += 40; - } - } - } - } - - int nCount = 0; - - for (i = 0; i < m_nSymbleSize; ++i) - { - for (j = 0; j < m_nSymbleSize; ++j) - { - if (! (m_byModuleData[i][j] & 0x11)) - { - ++nCount; - } - } - } - - nPenalty += (abs(50 - ((nCount * 100) / (m_nSymbleSize * m_nSymbleSize))) / 5) * 10; - - return nPenalty; -} diff --git a/client/3rd/QRCodeGenerator/QRCodeGenerator.h b/client/3rd/QRCodeGenerator/QRCodeGenerator.h deleted file mode 100644 index 2e8ed923..00000000 --- a/client/3rd/QRCodeGenerator/QRCodeGenerator.h +++ /dev/null @@ -1,129 +0,0 @@ - -#if !defined(AFX_QR_ENCODE_H__AC886DF7_C0AE_4C9F_AC7A_FCDA8CB1DD37__INCLUDED_) -#define AFX_QR_ENCODE_H__AC886DF7_C0AE_4C9F_AC7A_FCDA8CB1DD37__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -///////////////////////////////////////////////////////////////////////////// - -// -#define QR_LEVEL_L 0 -#define QR_LEVEL_M 1 -#define QR_LEVEL_Q 2 -#define QR_LEVEL_H 3 - -// -#define QR_MODE_NUMERAL 0 -#define QR_MODE_ALPHABET 1 -#define QR_MODE_8BIT 2 -#define QR_MODE_KANJI 3 - -// -#define QR_VRESION_S 0 -#define QR_VRESION_M 1 -#define QR_VRESION_L 2 - -#define MAX_ALLCODEWORD 3706 -#define MAX_DATACODEWORD 2956 -#define MAX_CODEBLOCK 153 -#define MAX_MODULESIZE 177 - -#define QR_MARGIN 0 - - -///////////////////////////////////////////////////////////////////////////// -typedef struct tagRS_BLOCKINFO -{ - int ncRSBlock; - int ncAllCodeWord; - int ncDataCodeWord; - -} RS_BLOCKINFO, *LPRS_BLOCKINFO; - - -///////////////////////////////////////////////////////////////////////////// - -typedef struct tagQR_VERSIONINFO -{ - int nVersionNo; - int ncAllCodeWord; - - int ncDataCodeWord[4]; - - int ncAlignPoint; - int nAlignPoint[6]; - - RS_BLOCKINFO RS_BlockInfo1[4]; - RS_BLOCKINFO RS_BlockInfo2[4]; - -} QR_VERSIONINFO, *LPQR_VERSIONINFO; - - -///////////////////////////////////////////////////////////////////////////// - -class CQR_Encode -{ -public: - CQR_Encode(); - ~CQR_Encode(); - -public: - int m_nLevel; - int m_nVersion; - bool m_bAutoExtent; - int m_nMaskingNo; - -public: - int m_nSymbleSize; - unsigned char m_byModuleData[MAX_MODULESIZE][MAX_MODULESIZE]; // [x][y] - -private: - int m_ncDataCodeWordBit; - unsigned char m_byDataCodeWord[MAX_DATACODEWORD]; - - int m_ncDataBlock; - unsigned char m_byBlockMode[MAX_DATACODEWORD]; - int m_nBlockLength[MAX_DATACODEWORD]; - - int m_ncAllCodeWord; - unsigned char m_byAllCodeWord[MAX_ALLCODEWORD]; - unsigned char m_byRSWork[MAX_CODEBLOCK]; - -public: - bool EncodeData(int nLevel, int nVersion, bool bAutoExtent, int nMaskingNo, const char* lpsSource, int ncSource = 0); - -private: - int GetEncodeVersion(int nVersion, const char* lpsSource, int ncLength); - bool EncodeSourceData(const char* lpsSource, int ncLength, int nVerGroup); - - int GetBitLength(unsigned char nMode, int ncData, int nVerGroup); - - int SetBitStream(int nIndex, unsigned short wData, int ncData); - - bool IsNumeralData(unsigned char c); - bool IsAlphabetData(unsigned char c); - bool IsKanjiData(unsigned char c1, unsigned char c2); - - unsigned char AlphabetToBinaly(unsigned char c); - unsigned short KanjiToBinaly(unsigned short wc); - - void GetRSCodeWord(unsigned char * lpbyRSWork, int ncDataCodeWord, int ncRSCodeWord); - -private: - void FormatModule(); - - void SetFunctionModule(); - void SetFinderPattern(int x, int y); - void SetAlignmentPattern(int x, int y); - void SetVersionPattern(); - void SetCodeWordPattern(); - void SetMaskingPattern(int nPatternNo); - void SetFormatInfoPattern(int nPatternNo); - int CountPenalty(); -}; - -///////////////////////////////////////////////////////////////////////////// - -#endif // !defined(AFX_QR_ENCODE_H__AC886DF7_C0AE_4C9F_AC7A_FCDA8CB1DD37__INCLUDED_) diff --git a/client/3rd/QRCodeGenerator/QRCodeGenerator.pri b/client/3rd/QRCodeGenerator/QRCodeGenerator.pri deleted file mode 100644 index 742a3d5b..00000000 --- a/client/3rd/QRCodeGenerator/QRCodeGenerator.pri +++ /dev/null @@ -1,5 +0,0 @@ -HEADERS += \ - 3rd/QRCodeGenerator/QRCodeGenerator.h \ - -SOURCES += \ - 3rd/QRCodeGenerator/QRCodeGenerator.cpp \ diff --git a/client/3rd/QtSsh/src/botan/botan.pri b/client/3rd/QtSsh/src/botan/botan.pri index 6568e154..52847ed4 100644 --- a/client/3rd/QtSsh/src/botan/botan.pri +++ b/client/3rd/QtSsh/src/botan/botan.pri @@ -11,7 +11,7 @@ win32 { -lcrypt32 \ !contains(QMAKE_TARGET.arch, x86_64) { - INCLUDEPATH += $$PWD/windows/x86_64 + INCLUDEPATH += $$PWD/windows/x86 HEADERS += $$PWD/windows/x86/botan_all.h SOURCES += $$PWD/windows/x86/botan_all.cpp } diff --git a/client/3rd/qzxing b/client/3rd/qzxing new file mode 160000 index 00000000..2fd4dd60 --- /dev/null +++ b/client/3rd/qzxing @@ -0,0 +1 @@ +Subproject commit 2fd4dd60c04a29c6d1271fdd9ae25378b8f61ec8 diff --git a/client/android/AndroidManifest.xml b/client/android/AndroidManifest.xml index 8a973542..a928c4bb 100644 --- a/client/android/AndroidManifest.xml +++ b/client/android/AndroidManifest.xml @@ -2,12 +2,13 @@ + - + diff --git a/client/android/build.gradle b/client/android/build.gradle index 92d34e56..a85742a5 100644 --- a/client/android/build.gradle +++ b/client/android/build.gradle @@ -38,13 +38,9 @@ apply plugin: 'kotlinx-serialization' dependencies { implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) implementation 'androidx.core:core-ktx:1.1.0' - implementation 'com.android.installreferrer:installreferrer:2.2' - implementation 'com.android.billingclient:billing-ktx:4.0.0' implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.0-alpha02" implementation "androidx.security:security-crypto:1.1.0-alpha03" implementation "androidx.security:security-identity-credential:1.0.0-alpha02" - implementation 'com.adjust.sdk:adjust-android:4.28.2' - implementation 'com.google.android.gms:play-services-ads-identifier:17.0.1' implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.2" coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.0.10" } @@ -106,8 +102,8 @@ android { resConfig "en" minSdkVersion = 24 targetSdkVersion = 30 - versionCode 2 // Change to a higher number - versionName "2.0.1" // Change to a higher number + versionCode 6 // Change to a higher number + versionName "2.0.6" // Change to a higher number } buildTypes { diff --git a/client/android/src/org/ftylitak/qzxing/NativeFunctions.java b/client/android/src/org/ftylitak/qzxing/NativeFunctions.java new file mode 100644 index 00000000..487fc656 --- /dev/null +++ b/client/android/src/org/ftylitak/qzxing/NativeFunctions.java @@ -0,0 +1,6 @@ +package org.ftylitak.qzxing; + +public class NativeFunctions { + public static native void onPermissionsGranted(); + public static native void onPermissionsDenied(); +} diff --git a/client/android/src/org/ftylitak/qzxing/QZXingLiveActivity.java b/client/android/src/org/ftylitak/qzxing/QZXingLiveActivity.java new file mode 100644 index 00000000..37ccb6ce --- /dev/null +++ b/client/android/src/org/ftylitak/qzxing/QZXingLiveActivity.java @@ -0,0 +1,25 @@ +package org.ftylitak.qzxing; + +import android.Manifest; +import android.content.pm.PackageManager; +import org.qtproject.qt5.android.bindings.QtActivity; +import static org.ftylitak.qzxing.Utilities.REQUEST_CAMERA; + +public class QZXingLiveActivity extends QtActivity { + @Override + public void onRequestPermissionsResult(int requestCode, + String permissions[], int[] grantResults) { + switch (requestCode) { + case REQUEST_CAMERA: { + // If request is cancelled, the result arrays are empty. + if (grantResults.length > 0 + && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + NativeFunctions.onPermissionsGranted(); + } else { + NativeFunctions.onPermissionsDenied(); + } + return; + } + } + } +} diff --git a/client/android/src/org/ftylitak/qzxing/Utilities.java b/client/android/src/org/ftylitak/qzxing/Utilities.java new file mode 100644 index 00000000..ced994b9 --- /dev/null +++ b/client/android/src/org/ftylitak/qzxing/Utilities.java @@ -0,0 +1,42 @@ +package org.ftylitak.qzxing; + +import android.Manifest; +import android.app.Activity; +import android.content.pm.PackageManager; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + +import java.util.ArrayList; + +public class Utilities { + + public static final int REQUEST_CAMERA = 0; + + public static final String[] requiredPermissionsModifyPhoneState = { + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE + }; + + public static void checkAndRequestPermissionList(Activity activity, String[] permissions) { + ArrayList permissionsToRequest = new ArrayList<>(); + for (int i = 0; i < permissions.length; i++) { + if (ContextCompat.checkSelfPermission(activity, permissions[i]) + != PackageManager.PERMISSION_GRANTED) + permissionsToRequest.add(permissions[i]); + } + + if (permissionsToRequest.size() != 0) + ActivityCompat.requestPermissions(activity, + permissionsToRequest.toArray(new String[0]), + REQUEST_CAMERA); + else + NativeFunctions.onPermissionsGranted(); + } + + public static void requestQZXingPermissions(Activity activity) { + checkAndRequestPermissionList(activity, requiredPermissionsModifyPhoneState); + } + + +} diff --git a/client/client.pro b/client/client.pro index bca96905..1371502a 100644 --- a/client/client.pro +++ b/client/client.pro @@ -5,14 +5,17 @@ TEMPLATE = app #CONFIG += console CONFIG += qtquickcompiler +CONFIG += qzxing_multimedia \ + enable_decoder_qr_code \ + enable_encoder_qr_code DEFINES += QT_DEPRECATED_WARNINGS include("3rd/QtSsh/src/ssh/qssh.pri") include("3rd/QtSsh/src/botan/botan.pri") !android:!ios:include("3rd/SingleApplication/singleapplication.pri") -include("3rd/QRCodeGenerator/QRCodeGenerator.pri") include ("3rd/SortFilterProxyModel/SortFilterProxyModel.pri") +include("3rd/QZXing/src/QZXing-components.pri") INCLUDEPATH += $$PWD/3rd/OpenSSL/include DEPENDPATH += $$PWD/3rd/OpenSSL/include @@ -48,6 +51,7 @@ HEADERS += \ ui/pages_logic/NetworkSettingsLogic.h \ ui/pages_logic/NewServerProtocolsLogic.h \ ui/pages_logic/PageLogicBase.h \ + ui/pages_logic/QrDecoderLogic.h \ ui/pages_logic/ServerConfiguringProgressLogic.h \ ui/pages_logic/ServerContainersLogic.h \ ui/pages_logic/ServerListLogic.h \ @@ -103,6 +107,7 @@ SOURCES += \ ui/pages_logic/NetworkSettingsLogic.cpp \ ui/pages_logic/NewServerProtocolsLogic.cpp \ ui/pages_logic/PageLogicBase.cpp \ + ui/pages_logic/QrDecoderLogic.cpp \ ui/pages_logic/ServerConfiguringProgressLogic.cpp \ ui/pages_logic/ServerContainersLogic.cpp \ ui/pages_logic/ServerListLogic.cpp \ @@ -141,12 +146,14 @@ win32 { RC_FILE = platform_win/vpnclient.rc HEADERS += \ - ui/framelesswindow.h \ + protocols/ikev2_vpn_protocol_windows.h \ + ui/framelesswindow.h SOURCES += \ + protocols/ikev2_vpn_protocol_windows.cpp \ ui/framelesswindow.cpp - VERSION = 1.0.0.0 + VERSION = 2.0.0.0 QMAKE_TARGET_COMPANY = "AmneziaVPN" QMAKE_TARGET_PRODUCT = "AmneziaVPN" @@ -197,7 +204,6 @@ win32|macx|linux:!android { HEADERS += \ ui/systemtray_notificationhandler.h \ protocols/openvpnprotocol.h \ - protocols/ikev2_vpn_protocol.h \ protocols/openvpnovercloakprotocol.h \ protocols/shadowsocksvpnprotocol.h \ protocols/wireguardprotocol.h \ @@ -205,7 +211,6 @@ win32|macx|linux:!android { SOURCES += \ ui/systemtray_notificationhandler.cpp \ protocols/openvpnprotocol.cpp \ - protocols/ikev2_vpn_protocol.cpp \ protocols/openvpnovercloakprotocol.cpp \ protocols/shadowsocksvpnprotocol.cpp \ protocols/wireguardprotocol.cpp \ @@ -218,11 +223,13 @@ android { INCLUDEPATH += platforms/android HEADERS += \ + platforms/android/native.h \ platforms/android/android_controller.h \ platforms/android/android_notificationhandler.h \ protocols/android_vpnprotocol.h SOURCES += \ + platforms/android/native.cpp \ platforms/android/android_controller.cpp \ platforms/android/android_notificationhandler.cpp \ protocols/android_vpnprotocol.cpp diff --git a/client/core/defs.h b/client/core/defs.h index ec04e840..37199d49 100644 --- a/client/core/defs.h +++ b/client/core/defs.h @@ -6,6 +6,8 @@ namespace amnezia { +constexpr const qint16 qrMagicCode = 1984; + struct ServerCredentials { QString hostName; diff --git a/client/defines.h b/client/defines.h index b4790d61..027ca688 100644 --- a/client/defines.h +++ b/client/defines.h @@ -4,7 +4,7 @@ #define APPLICATION_NAME "AmneziaVPN" #define SERVICE_NAME "AmneziaVPN-service" #define ORGANIZATION_NAME "AmneziaVPN.ORG" -#define APP_MAJOR_VERSION "2.0.1" -#define APP_VERSION "2.0.1.0" +#define APP_MAJOR_VERSION "2.0.6" +#define APP_VERSION "2.0.6.0" #endif // DEFINES_H diff --git a/client/images/ios/icon_1024x1024.png b/client/images/ios/icon_1024x1024.png new file mode 100644 index 00000000..695a30a5 Binary files /dev/null and b/client/images/ios/icon_1024x1024.png differ diff --git a/client/images/ios/icon_120x120.png b/client/images/ios/icon_120x120.png new file mode 100644 index 00000000..4349d194 Binary files /dev/null and b/client/images/ios/icon_120x120.png differ diff --git a/client/images/ios/icon_180x180.png b/client/images/ios/icon_180x180.png new file mode 100644 index 00000000..4bf6715a Binary files /dev/null and b/client/images/ios/icon_180x180.png differ diff --git a/client/images/ios/icon_40x40.png b/client/images/ios/icon_40x40.png new file mode 100644 index 00000000..ad3d0746 Binary files /dev/null and b/client/images/ios/icon_40x40.png differ diff --git a/client/images/ios/icon_58x58.png b/client/images/ios/icon_58x58.png new file mode 100644 index 00000000..dbacdbe7 Binary files /dev/null and b/client/images/ios/icon_58x58.png differ diff --git a/client/images/ios/icon_60x60.png b/client/images/ios/icon_60x60.png new file mode 100644 index 00000000..0778ec28 Binary files /dev/null and b/client/images/ios/icon_60x60.png differ diff --git a/client/images/ios/icon_80x80.png b/client/images/ios/icon_80x80.png new file mode 100644 index 00000000..8a1fdc1d Binary files /dev/null and b/client/images/ios/icon_80x80.png differ diff --git a/client/images/ios/icon_87x87.png b/client/images/ios/icon_87x87.png new file mode 100644 index 00000000..e57c6fbb Binary files /dev/null and b/client/images/ios/icon_87x87.png differ diff --git a/client/ios/Media.xcassets/AppIcon.appiconset/Contents.json b/client/ios/Media.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..25af9c29 --- /dev/null +++ b/client/ios/Media.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,62 @@ +{ + "images" : [ + { + "filename" : "icon_40x40.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "filename" : "icon_60x60.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "filename" : "icon_58x58.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "filename" : "icon_87x87.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "filename" : "icon_80x80.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "filename" : "icon_120x120.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "filename" : "icon_120x120-1.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "filename" : "icon_180x180.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "filename" : "icon_1024x1024.png", + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/client/ios/Media.xcassets/AppIcon.appiconset/icon_1024x1024.png b/client/ios/Media.xcassets/AppIcon.appiconset/icon_1024x1024.png new file mode 100644 index 00000000..695a30a5 Binary files /dev/null and b/client/ios/Media.xcassets/AppIcon.appiconset/icon_1024x1024.png differ diff --git a/client/ios/Media.xcassets/AppIcon.appiconset/icon_120x120-1.png b/client/ios/Media.xcassets/AppIcon.appiconset/icon_120x120-1.png new file mode 100644 index 00000000..4349d194 Binary files /dev/null and b/client/ios/Media.xcassets/AppIcon.appiconset/icon_120x120-1.png differ diff --git a/client/ios/Media.xcassets/AppIcon.appiconset/icon_120x120.png b/client/ios/Media.xcassets/AppIcon.appiconset/icon_120x120.png new file mode 100644 index 00000000..4349d194 Binary files /dev/null and b/client/ios/Media.xcassets/AppIcon.appiconset/icon_120x120.png differ diff --git a/client/ios/Media.xcassets/AppIcon.appiconset/icon_180x180.png b/client/ios/Media.xcassets/AppIcon.appiconset/icon_180x180.png new file mode 100644 index 00000000..4bf6715a Binary files /dev/null and b/client/ios/Media.xcassets/AppIcon.appiconset/icon_180x180.png differ diff --git a/client/ios/Media.xcassets/AppIcon.appiconset/icon_40x40.png b/client/ios/Media.xcassets/AppIcon.appiconset/icon_40x40.png new file mode 100644 index 00000000..ad3d0746 Binary files /dev/null and b/client/ios/Media.xcassets/AppIcon.appiconset/icon_40x40.png differ diff --git a/client/ios/Media.xcassets/AppIcon.appiconset/icon_58x58.png b/client/ios/Media.xcassets/AppIcon.appiconset/icon_58x58.png new file mode 100644 index 00000000..dbacdbe7 Binary files /dev/null and b/client/ios/Media.xcassets/AppIcon.appiconset/icon_58x58.png differ diff --git a/client/ios/Media.xcassets/AppIcon.appiconset/icon_60x60.png b/client/ios/Media.xcassets/AppIcon.appiconset/icon_60x60.png new file mode 100644 index 00000000..0778ec28 Binary files /dev/null and b/client/ios/Media.xcassets/AppIcon.appiconset/icon_60x60.png differ diff --git a/client/ios/Media.xcassets/AppIcon.appiconset/icon_80x80.png b/client/ios/Media.xcassets/AppIcon.appiconset/icon_80x80.png new file mode 100644 index 00000000..8a1fdc1d Binary files /dev/null and b/client/ios/Media.xcassets/AppIcon.appiconset/icon_80x80.png differ diff --git a/client/ios/Media.xcassets/AppIcon.appiconset/icon_87x87.png b/client/ios/Media.xcassets/AppIcon.appiconset/icon_87x87.png new file mode 100644 index 00000000..e57c6fbb Binary files /dev/null and b/client/ios/Media.xcassets/AppIcon.appiconset/icon_87x87.png differ diff --git a/client/ios/Media.xcassets/Contents.json b/client/ios/Media.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/client/ios/Media.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/client/main.cpp b/client/main.cpp index 817e885f..13b1d0ae 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -16,8 +16,9 @@ #include "ui/pages_logic/AppSettingsLogic.h" #include "ui/pages_logic/GeneralSettingsLogic.h" #include "ui/pages_logic/NetworkSettingsLogic.h" -#include "ui/pages_logic/ServerConfiguringProgressLogic.h" #include "ui/pages_logic/NewServerProtocolsLogic.h" +#include "ui/pages_logic/QrDecoderLogic.h" +#include "ui/pages_logic/ServerConfiguringProgressLogic.h" #include "ui/pages_logic/ServerContainersLogic.h" #include "ui/pages_logic/ServerListLogic.h" #include "ui/pages_logic/ServerSettingsLogic.h" @@ -34,6 +35,8 @@ #include "ui/uilogic.h" +#include "QZXing.h" + #include "debug.h" #include "defines.h" @@ -48,6 +51,10 @@ #include "Windows.h" #endif +#if defined(Q_OS_ANDROID) +#include "native.h" +#endif + static void loadTranslator() { QTranslator* translator = new QTranslator; @@ -79,6 +86,11 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); #endif +#if defined(Q_OS_ANDROID) + NativeHelpers::registerApplicationInstance(&app); +#endif + + #ifdef Q_OS_WIN AllowSetForegroundWindow(0); #endif @@ -116,6 +128,8 @@ int main(int argc, char *argv[]) app.setQuitOnLastWindowClosed(false); + QZXing::registerQMLTypes(); + qRegisterMetaType("VpnProtocol::VpnConnectionState"); qRegisterMetaType("ServerCredentials"); @@ -156,8 +170,9 @@ int main(int argc, char *argv[]) engine->rootContext()->setContextProperty("AppSettingsLogic", uiLogic->appSettingsLogic()); engine->rootContext()->setContextProperty("GeneralSettingsLogic", uiLogic->generalSettingsLogic()); engine->rootContext()->setContextProperty("NetworkSettingsLogic", uiLogic->networkSettingsLogic()); - engine->rootContext()->setContextProperty("ServerConfiguringProgressLogic", uiLogic->serverConfiguringProgressLogic()); engine->rootContext()->setContextProperty("NewServerProtocolsLogic", uiLogic->newServerProtocolsLogic()); + engine->rootContext()->setContextProperty("QrDecoderLogic", uiLogic->qrDecoderLogic()); + engine->rootContext()->setContextProperty("ServerConfiguringProgressLogic", uiLogic->serverConfiguringProgressLogic()); engine->rootContext()->setContextProperty("ServerListLogic", uiLogic->serverListLogic()); engine->rootContext()->setContextProperty("ServerSettingsLogic", uiLogic->serverSettingsLogic()); engine->rootContext()->setContextProperty("ServerContainersLogic", uiLogic->serverprotocolsLogic()); diff --git a/client/platforms/android/native.cpp b/client/platforms/android/native.cpp new file mode 100644 index 00000000..60ff2d8b --- /dev/null +++ b/client/platforms/android/native.cpp @@ -0,0 +1,54 @@ +#include "native.h" +#include +#if defined(Q_OS_ANDROID) + #include +#endif // Q_OS_ANDROID + + +QObject *NativeHelpers::application_p_ = 0; + +#if defined(Q_OS_ANDROID) + +// define our native static functions +// these are the functions that Java part will call directly from Android UI thread +static void onPermissionsGranted(JNIEnv * /*env*/, jobject /*obj*/) +{ + QMetaObject::invokeMethod(NativeHelpers::getApplicationInstance(), "onPermissionsGranted" + , Qt::QueuedConnection); +} + +static void onPermissionsDenied(JNIEnv * /*env*/, jobject /*obj*/) +{ + QMetaObject::invokeMethod(NativeHelpers::getApplicationInstance(), "onPermissionsDenied" + , Qt::QueuedConnection); +} + +//create a vector with all our JNINativeMethod(s) +static JNINativeMethod methods[] = { + {"onPermissionsGranted", "()V", (void *)onPermissionsGranted}, + {"onPermissionsDenied", "()V", (void *)onPermissionsDenied}, +}; + +// this method is called automatically by Java after the .so file is loaded +JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* /*reserved*/) +{ + JNIEnv* env; + // get the JNIEnv pointer. + if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) + return JNI_ERR; + + // search for Java class which declares the native methods + jclass javaClass = env->FindClass("org/ftylitak/qzxing/NativeFunctions"); + if (!javaClass) + return JNI_ERR; + + // register our native methods + if (env->RegisterNatives(javaClass, methods, + sizeof(methods) / sizeof(methods[0])) < 0) { + return JNI_ERR; + } + + return JNI_VERSION_1_6; +} + +#endif // Q_OS_ANDROID diff --git a/client/platforms/android/native.h b/client/platforms/android/native.h new file mode 100644 index 00000000..db187a73 --- /dev/null +++ b/client/platforms/android/native.h @@ -0,0 +1,20 @@ +#ifndef NATIVE_H +#define NATIVE_H + +#include + +class NativeHelpers { +public: + static void registerApplicationInstance(QObject *app_p) { + application_p_ = app_p; + } + + static QObject* getApplicationInstance() { + return application_p_; + } + +private: + static QObject *application_p_; +}; + +#endif // NATIVE_H diff --git a/client/protocols/ikev2_vpn_protocol.cpp b/client/protocols/ikev2_vpn_protocol_windows.cpp similarity index 57% rename from client/protocols/ikev2_vpn_protocol.cpp rename to client/protocols/ikev2_vpn_protocol_windows.cpp index 8f5d4cd3..5e4e5b14 100644 --- a/client/protocols/ikev2_vpn_protocol.cpp +++ b/client/protocols/ikev2_vpn_protocol_windows.cpp @@ -1,14 +1,13 @@ #include #include #include -//#include -//#include + #include #include #include "debug.h" -#include "ikev2_vpn_protocol.h" +#include "ikev2_vpn_protocol_windows.h" #include "utils.h" static Ikev2Protocol* self = nullptr; @@ -24,23 +23,19 @@ Ikev2Protocol::Ikev2Protocol(const QJsonObject &configuration, QObject* parent) VpnProtocol(configuration, parent) { self = this; - //m_configFile.setFileTemplate(QDir::tempPath() + QDir::separator() + serviceName() + ".conf"); readIkev2Configuration(configuration); } Ikev2Protocol::~Ikev2Protocol() { qDebug() << "IpsecProtocol::~IpsecProtocol()"; -#ifdef Q_OS_WIN disconnect_vpn(); -#endif Ikev2Protocol::stop(); } void Ikev2Protocol::stop() { setConnectionState(VpnProtocol::Disconnecting); -#ifdef Q_OS_WINDOWS { if (! disconnect_vpn() ){ qDebug()<<"We don't disconnect"; @@ -50,7 +45,6 @@ void Ikev2Protocol::stop() setConnectionState(VpnProtocol::Disconnected); } } -#endif } void Ikev2Protocol::newConnectionStateEventReceived(UINT unMsg, tagRASCONNSTATE rasconnstate, DWORD dwError) @@ -60,181 +54,117 @@ void Ikev2Protocol::newConnectionStateEventReceived(UINT unMsg, tagRASCONNSTATE switch (rasconnstate) { case RASCS_OpenPort: - qDebug()<<__FUNCTION__ << __LINE__; + //qDebug()<<__FUNCTION__ << __LINE__; setConnectionState(Preparing); - //printf ("RASCS_OpenPort = %d\n", _connection_state); - //printf ("Opening port...\n"); break; case RASCS_PortOpened: - qDebug()<<__FUNCTION__ << __LINE__; + //qDebug()<<__FUNCTION__ << __LINE__; setConnectionState(Preparing); - //printf ("RASCS_PortOpened = %d\n", _connection_state); - //printf ("Port opened.\n"); break; case RASCS_ConnectDevice: - qDebug()<<__FUNCTION__ << __LINE__; + //qDebug()<<__FUNCTION__ << __LINE__; setConnectionState(Preparing); - //printf ("RASCS_ConnectDevice = %d\n", _connection_state); - //printf ("Connecting device...\n"); break; case RASCS_DeviceConnected: - qDebug()<<__FUNCTION__ << __LINE__; + //qDebug()<<__FUNCTION__ << __LINE__; setConnectionState(Preparing); - //printf ("RASCS_DeviceConnected = %d\n", _connection_state); - //printf ("Device connected.\n"); break; case RASCS_AllDevicesConnected: - qDebug()<<__FUNCTION__ << __LINE__; + //qDebug()<<__FUNCTION__ << __LINE__; setConnectionState(Preparing); - //printf ("RASCS_AllDevicesConnected = %d\n", _connection_state); - //printf ("All devices connected.\n"); break; case RASCS_Authenticate: - qDebug()<<__FUNCTION__ << __LINE__; + //qDebug()<<__FUNCTION__ << __LINE__; setConnectionState(Preparing); - //printf ("RASCS_Authenticate = %d\n", _connection_state); - // printf ("Authenticating...\n"); break; case RASCS_AuthNotify: - qDebug()<<__FUNCTION__ << __LINE__; + //qDebug()<<__FUNCTION__ << __LINE__; if (dwError != 0) { - qDebug() << "have error" << dwError; + //qDebug() << "have error" << dwError; setConnectionState(Disconnected); } else { - qDebug() << "RASCS_AuthNotify but no error" << dwError; + //qDebug() << "RASCS_AuthNotify but no error" << dwError; } - //printf ("RASCS_AuthNotify = %d\n", _connection_state); - // printf ("Authentication notify.\n"); break; case RASCS_AuthRetry: - qDebug()<<__FUNCTION__ << __LINE__; + //qDebug()<<__FUNCTION__ << __LINE__; setConnectionState(Preparing); - //printf ("RASCS_AuthRetry = %d\n", _connection_state); - //printf ("Retrying authentication...\n"); break; case RASCS_AuthCallback: qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_AuthCallback = %d\n", _connection_state); - //printf ("Authentication callback...\n"); break; case RASCS_AuthChangePassword: qDebug()<<__FUNCTION__ << __LINE__; - // printf ("RASCS_AuthChangePassword = %d\n", _connection_state); - //printf ("Change password...\n"); break; case RASCS_AuthProject: qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_AuthProject = %d\n", _connection_state); - //printf ("Projection phase started...\n"); break; case RASCS_AuthLinkSpeed: qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_AuthLinkSpeed = %d\n", _connection_state); - //printf ("Negoting speed...\n"); break; case RASCS_AuthAck: qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_AuthAck = %d\n", _connection_state); - //printf ("Authentication acknowledge...\n"); break; case RASCS_ReAuthenticate: - qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_ReAuthenticate = %d\n", _connection_state); - //printf ("Retrying Authentication...\n"); + //qDebug()<<__FUNCTION__ << __LINE__; break; case RASCS_Authenticated: - qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_Authenticated = %d\n", _connection_state); - //printf ("Authentication complete.\n"); + //qDebug()<<__FUNCTION__ << __LINE__; break; case RASCS_PrepareForCallback: qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_PrepareForCallback = %d\n", _connection_state); - //printf ("Preparing for callback...\n"); break; case RASCS_WaitForModemReset: qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_WaitForModemReset = %d\n", _connection_state); - // printf ("Waiting for modem reset...\n"); break; case RASCS_WaitForCallback: qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_WaitForCallback = %d\n", _connection_state); - //printf ("Waiting for callback...\n"); break; case RASCS_Projected: qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_Projected = %d\n", _connection_state); - //printf ("Projection completed.\n"); break; #if (WINVER >= 0x400) case RASCS_StartAuthentication: // Windows 95 only qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_StartAuthentication = %d\n", _connection_state); - //printf ("Starting authentication...\n"); - break; case RASCS_CallbackComplete: // Windows 95 only qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_CallbackComplete = %d\n", rasconnstate); - //printf ("Callback complete.\n"); break; case RASCS_LogonNetwork: // Windows 95 only qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_LogonNetwork = %d\n", _connection_state); - //printf ("Login to the network.\n"); break; #endif case RASCS_SubEntryConnected: qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_SubEntryConnected = %d\n", _connection_state); - //printf ("Subentry connected.\n"); break; case RASCS_SubEntryDisconnected: qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_SubEntryDisconnected = %d\n", _connection_state); - //printf ("Subentry disconnected.\n"); break; //PAUSED STATES: case RASCS_Interactive: qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_Interactive = %d\n", _connection_state); - //printf ("In Paused state: Interactive mode.\n"); break; case RASCS_RetryAuthentication: qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_RetryAuthentication = %d\n", _connection_state); - //printf ("In Paused state: Retry Authentication...\n"); break; case RASCS_CallbackSetByCaller: qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_CallbackSetByCaller = %d\n", _connection_state); - //printf ("In Paused state: Callback set by Caller.\n"); break; case RASCS_PasswordExpired: setConnectionState(Error); qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_PasswordExpired = %d\n", _connection_state); - //printf ("In Paused state: Password has expired...\n"); break; case RASCS_Connected: // = RASCS_DONE: setConnectionState(Connected); - qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_Connected = %d\n", _connection_state); - //printf ("Connection completed.\n"); - //SetEvent(gEvent_handle); + //qDebug()<<__FUNCTION__ << __LINE__; break; case RASCS_Disconnected: setConnectionState(Disconnected); - qDebug()<<__FUNCTION__ << __LINE__; - //printf ("RASCS_Disconnected = %d\n", _connection_state); - //printf ("Disconnecting...\n"); + //qDebug()<<__FUNCTION__ << __LINE__; break; default: - qDebug()<<__FUNCTION__ << __LINE__; - //printf ("Unknown Status = %d\n", _connection_state); - //printf ("What are you going to do about it?\n"); + //qDebug()<<__FUNCTION__ << __LINE__; break; } } @@ -246,7 +176,6 @@ void Ikev2Protocol::readIkev2Configuration(const QJsonObject &configuration) ErrorCode Ikev2Protocol::start() { -#ifdef Q_OS_WINDOWS QByteArray cert = QByteArray::fromBase64(m_config[config_key::cert].toString().toUtf8()); setConnectionState(Connecting); @@ -277,34 +206,10 @@ ErrorCode Ikev2Protocol::start() }); certInstallProcess->setArguments(arguments); - // qDebug() << arguments.join(" "); - // connect(certInstallProcess.data(), &PrivilegedProcess::errorOccurred, [certInstallProcess](QProcess::ProcessError error) { - // qDebug() << "PrivilegedProcess errorOccurred" << error; - // }); - - // connect(certInstallProcess.data(), &PrivilegedProcess::stateChanged, [certInstallProcess](QProcess::ProcessState newState) { - // qDebug() << "PrivilegedProcess stateChanged" << newState; - // }); - - // connect(certInstallProcess.data(), &PrivilegedProcess::readyRead, [certInstallProcess]() { - // auto req = certInstallProcess->readAll(); - // req.waitForFinished(); - // qDebug() << "PrivilegedProcess readyRead" << req.returnValue(); - // }); - - certInstallProcess->start(); } // /* { - // auto adapterRemoveProcess = new QProcess; - - // adapterRemoveProcess->setProgram("powershell"); - // QString arguments = QString("-command \"Remove-VpnConnection -Name '%1' -Force\"").arg(tunnelName()); - // adapterRemoveProcess->setNativeArguments(arguments); - - // adapterRemoveProcess->start(); - // adapterRemoveProcess->waitForFinished(5000); if ( disconnect_vpn()){ qDebug()<<"VPN was disconnected"; } @@ -319,21 +224,6 @@ ErrorCode Ikev2Protocol::start() qDebug() <<"Can't create the VPN connect"; } } - // auto adapterInstallProcess = new QProcess; - - // adapterInstallProcess->setProgram("powershell"); - // QString arguments = QString("-command \"Add-VpnConnection " - // "-ServerAddress '%1' " - // "-Name '%2' " - // "-TunnelType IKEv2 " - // "-AuthenticationMethod MachineCertificate " - // "-EncryptionLevel Required " - // "-PassThru\"") - // .arg(m_config[config_key::hostName].toString()) - // .arg(tunnelName()); - // adapterInstallProcess->setNativeArguments(arguments); - // adapterInstallProcess->start(); - // adapterInstallProcess->waitForFinished(5000); } { @@ -352,10 +242,6 @@ ErrorCode Ikev2Protocol::start() .arg(tunnelName()); adapterConfigProcess->setNativeArguments(arguments); - // connect(adapterConfigProcess, &QProcess::readyRead, [adapterConfigProcess]() { - // qDebug().noquote() << "adapterConfigProcess readyRead" << adapterConfigProcess->readAll(); - // }); - adapterConfigProcess->start(); adapterConfigProcess->waitForFinished(5000); } @@ -367,13 +253,8 @@ ErrorCode Ikev2Protocol::start() } //setConnectionState(Connecting); return ErrorCode::NoError; -#else - return ErrorCode::NoError; -#endif - } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -#ifdef Q_OS_WINDOWS bool Ikev2Protocol::create_new_vpn(const QString & vpn_name, const QString & serv_addr){ @@ -442,5 +323,3 @@ void WINAPI RasDialFuncCallback(UINT unMsg, self->newConnectionStateEventReceived(unMsg, rasconnstate, dwError); } } - -#endif diff --git a/client/protocols/ikev2_vpn_protocol.h b/client/protocols/ikev2_vpn_protocol_windows.h similarity index 88% rename from client/protocols/ikev2_vpn_protocol.h rename to client/protocols/ikev2_vpn_protocol_windows.h index 05a23643..3bed1951 100644 --- a/client/protocols/ikev2_vpn_protocol.h +++ b/client/protocols/ikev2_vpn_protocol_windows.h @@ -1,5 +1,5 @@ -#ifndef IPSEC_PROTOCOL_H -#define IPSEC_PROTOCOL_H +#ifndef IKEV2_VPN_PROTOCOL_WINDOWS_H +#define IKEV2_VPN_PROTOCOL_WINDOWS_H #include #include @@ -10,7 +10,6 @@ #include "vpnprotocol.h" #include "core/ipcclient.h" -#ifdef Q_OS_WIN #include #include #include @@ -31,8 +30,6 @@ #pragma comment(lib, "rasapi32.lib") #pragma comment(lib, "Crypt32.lib") -#endif - class Ikev2Protocol : public VpnProtocol { Q_OBJECT @@ -54,14 +51,9 @@ public: private: void readIkev2Configuration(const QJsonObject &configuration); -#ifdef Q_OS_WIN - //certificates variables - -#endif private: QJsonObject m_config; -#ifdef Q_OS_WIN //RAS functions and parametrs HRASCONN hRasConn{nullptr}; bool create_new_vpn(const QString & vpn_name, @@ -70,12 +62,8 @@ private: bool connect_to_vpn(const QString & vpn_name); bool disconnect_vpn(); -#endif - }; -#ifdef Q_OS_WIN DWORD CALLBACK rasCallback(UINT msg, RASCONNSTATE rascs, DWORD err); -#endif -#endif // IPSEC_PROTOCOL_H +#endif // IKEV2_VPN_PROTOCOL_WINDOWS_H diff --git a/client/protocols/vpnprotocol.cpp b/client/protocols/vpnprotocol.cpp index 5cea3a3b..c64cff90 100644 --- a/client/protocols/vpnprotocol.cpp +++ b/client/protocols/vpnprotocol.cpp @@ -9,7 +9,10 @@ #include "shadowsocksvpnprotocol.h" #include "openvpnovercloakprotocol.h" #include "wireguardprotocol.h" -#include "ikev2_vpn_protocol.h" +#endif + +#ifdef Q_OS_WINDOWS +#include "ikev2_vpn_protocol_windows.h" #endif diff --git a/client/resources.qrc b/client/resources.qrc index 26dd1e60..b7e499fe 100644 --- a/client/resources.qrc +++ b/client/resources.qrc @@ -141,5 +141,6 @@ images/animation.gif images/connected.png images/disconnected.png + ui/qml/Pages/PageQrDecoder.qml diff --git a/client/server_scripts/wireguard/start.sh b/client/server_scripts/wireguard/start.sh index aebd283e..ab30667d 100644 --- a/client/server_scripts/wireguard/start.sh +++ b/client/server_scripts/wireguard/start.sh @@ -17,9 +17,9 @@ iptables -A FORWARD -i wg0 -j ACCEPT iptables -A OUTPUT -o wg0 -j ACCEPT # Allow forwarding traffic only from the VPN. -iptables -A FORWARD -i wg0 -o eth0 -s $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_MASK_CIDR -j ACCEPT +iptables -A FORWARD -i wg0 -o eth0 -s $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -j ACCEPT iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT -iptables -t nat -A POSTROUTING -s $WIREGUARD_SUBNET_IP/$OPENVPN_SUBNET_CIDR -o eth0 -j MASQUERADE +iptables -t nat -A POSTROUTING -s $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -o eth0 -j MASQUERADE tail -f /dev/null diff --git a/client/ui/pages.h b/client/ui/pages.h index 235b912f..69067e7f 100644 --- a/client/ui/pages.h +++ b/client/ui/pages.h @@ -24,7 +24,7 @@ enum class Page {Start = 0, NewServer, NewServerProtocols, Vpn, Wizard, WizardLow, WizardMedium, WizardHigh, WizardVpnMode, ServerConfiguringProgress, GeneralSettings, AppSettings, NetworkSettings, ServerSettings, ServerContainers, ServersList, ShareConnection, Sites, - ProtocolSettings, ProtocolShare}; + ProtocolSettings, ProtocolShare, QrDecoder}; Q_ENUM_NS(Page) static void declareQmlPageEnum() { diff --git a/client/ui/pages_logic/QrDecoderLogic.cpp b/client/ui/pages_logic/QrDecoderLogic.cpp new file mode 100644 index 00000000..64b0f98f --- /dev/null +++ b/client/ui/pages_logic/QrDecoderLogic.cpp @@ -0,0 +1,82 @@ +#include "QrDecoderLogic.h" + +#include "ui/uilogic.h" +#include "ui/pages_logic/StartPageLogic.h" + +#if defined(Q_OS_ANDROID) +#include "android_controller.h" +#endif + +using namespace amnezia; +using namespace PageEnumNS; + +QrDecoderLogic::QrDecoderLogic(UiLogic *logic, QObject *parent): + PageLogicBase(logic, parent) +{ + +} + +void QrDecoderLogic::onUpdatePage() +{ + m_chunks.clear(); + set_detectingEnabled(true); + set_totalChunksCount(0); + set_receivedChunksCount(0); + emit startDecode(); +} + +void QrDecoderLogic::onDetectedQrCode(const QString &code) +{ + //qDebug() << code; + + if (!detectingEnabled()) return; + + // check if chunk received + QByteArray ba = QByteArray::fromBase64(code.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals); + QDataStream s(&ba, QIODevice::ReadOnly); + qint16 magic; s >> magic; + + + if (magic == amnezia::qrMagicCode) { + qDebug() << "QrDecoderLogic::onDetectedQrCode magic code detected" << magic << ba.size(); + + quint8 chunksCount; s >> chunksCount; + if (totalChunksCount() != chunksCount) { + m_chunks.clear(); + } + set_totalChunksCount(chunksCount); + + quint8 chunkId; s >> chunkId; + s >> m_chunks[chunkId]; + set_receivedChunksCount(m_chunks.size()); + + qDebug() << "Received chunks:" << receivedChunksCount() << "/" << chunksCount << "cur" << chunkId << m_chunks[chunkId].size(); + qDebug() << chunkId << m_chunks[chunkId]; + + if (m_chunks.size() == totalChunksCount()) { + QByteArray data; + for (int i = 0; i < totalChunksCount(); ++i) { + data.append(m_chunks.value(i)); + } + + bool ok = uiLogic()->startPageLogic()->importConnectionFromQr(data); + if (ok) { + set_detectingEnabled(false); + emit stopDecode(); + } + else { + m_chunks.clear(); + set_totalChunksCount(0); + set_receivedChunksCount(0); + } + } + } + else { + bool ok = uiLogic()->startPageLogic()->importConnectionFromQr(ba); + if (ok) { + set_detectingEnabled(false); + emit stopDecode(); + } + } +} + diff --git a/client/ui/pages_logic/QrDecoderLogic.h b/client/ui/pages_logic/QrDecoderLogic.h new file mode 100644 index 00000000..243da95b --- /dev/null +++ b/client/ui/pages_logic/QrDecoderLogic.h @@ -0,0 +1,30 @@ +#ifndef QR_DECODER_LOGIC_H +#define QR_DECODER_LOGIC_H + +#include "PageLogicBase.h" + +class UiLogic; + +class QrDecoderLogic : public PageLogicBase +{ + Q_OBJECT + AUTO_PROPERTY(bool, detectingEnabled) + AUTO_PROPERTY(int, totalChunksCount) + AUTO_PROPERTY(int, receivedChunksCount) + +public: + Q_INVOKABLE void onUpdatePage() override; + Q_INVOKABLE void onDetectedQrCode(const QString &code); + +public: + explicit QrDecoderLogic(UiLogic *uiLogic, QObject *parent = nullptr); + ~QrDecoderLogic() = default; + +signals: + void startDecode(); + void stopDecode(); + +private: + QMap m_chunks; +}; +#endif // QR_DECODER_LOGIC_H diff --git a/client/ui/pages_logic/ShareConnectionLogic.cpp b/client/ui/pages_logic/ShareConnectionLogic.cpp index ffc71232..b53822ea 100644 --- a/client/ui/pages_logic/ShareConnectionLogic.cpp +++ b/client/ui/pages_logic/ShareConnectionLogic.cpp @@ -1,11 +1,7 @@ -#include #include -#include -#include -#include -#include -#include #include +#include +#include #include "ShareConnectionLogic.h" @@ -18,6 +14,7 @@ #include "configurators/ssh_configurator.h" #include "defines.h" +#include "core/defs.h" #include #include "../uilogic.h" @@ -35,7 +32,8 @@ ShareConnectionLogic::ShareConnectionLogic(UiLogic *logic, QObject *parent): void ShareConnectionLogic::onUpdatePage() { set_textEditShareAmneziaCodeText(tr("")); - set_shareAmneziaQrCodeText(""); + set_shareAmneziaQrCodeTextSeries({}); + set_shareAmneziaQrCodeTextSeriesLength(0); set_textEditShareOpenVpnCodeText(""); @@ -56,7 +54,8 @@ void ShareConnectionLogic::onUpdatePage() void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked() { set_textEditShareAmneziaCodeText(""); - set_shareAmneziaQrCodeText(""); + set_shareAmneziaQrCodeTextSeries({}); + set_shareAmneziaQrCodeTextSeriesLength(0); QJsonObject serverConfig; // Full access @@ -97,15 +96,15 @@ void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked() } } - QByteArray ba = QJsonDocument(serverConfig).toBinaryData(); + QByteArray ba = QJsonDocument(serverConfig).toJson(); ba = qCompress(ba, 8); QString code = QString("vpn://%1").arg(QString(ba.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals))); set_textEditShareAmneziaCodeText(code); - if (ba.size() < 2900) { - QImage qr = updateQRCodeImage(ba.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals)); - set_shareAmneziaQrCodeText(imageToBase64(qr)); - } + + QList qrChunks = genQrCodeImageSeries(ba); + set_shareAmneziaQrCodeTextSeries(qrChunks); + set_shareAmneziaQrCodeTextSeriesLength(qrChunks.size()); } void ShareConnectionLogic::onPushButtonShareOpenVpnGenerateClicked() @@ -147,7 +146,7 @@ void ShareConnectionLogic::onPushButtonShareShadowSocksGenerateClicked() ssString = "ss://" + ssString.toUtf8().toBase64(); set_lineEditShareShadowSocksStringText(ssString); - QImage qr = updateQRCodeImage(ssString.toUtf8()); + QImage qr = QZXing::encodeData(ssString.toUtf8(), QZXing::EncoderFormat_QR_CODE, QSize(512,512), QZXing::EncodeErrorCorrectionLevel_L); set_shareShadowSocksQrCodeText(imageToBase64(qr)); QString humanString = QString("Server: %3\n" @@ -200,7 +199,8 @@ void ShareConnectionLogic::onPushButtonShareWireGuardGenerateClicked() set_textEditShareWireGuardCodeText(cfg); - QImage qr = updateQRCodeImage(cfg.toUtf8()); + QImage qr = QZXing::encodeData(cfg.toUtf8(), QZXing::EncoderFormat_QR_CODE, QSize(512,512), QZXing::EncodeErrorCorrectionLevel_L); + set_shareWireGuardQrCodeText(imageToBase64(qr)); } @@ -234,30 +234,29 @@ void ShareConnectionLogic::updateSharingPage(int serverIndex, DockerContainer co uiLogic()->selectedDockerContainer = container; uiLogic()->selectedServerIndex = serverIndex; set_shareFullAccess(container == DockerContainer::None); + + m_shareAmneziaQrCodeTextSeries.clear(); + set_shareAmneziaQrCodeTextSeriesLength(0); } -QImage ShareConnectionLogic::updateQRCodeImage(const QByteArray &data) +QList ShareConnectionLogic::genQrCodeImageSeries(const QByteArray &data) { - int levelIndex = 1; - int versionIndex = 0; - bool bExtent = true; - int maskIndex = -1; + double k = 1500; - m_qrEncode.EncodeData( levelIndex, versionIndex, bExtent, maskIndex, data.data() ); + quint8 chunksCount = std::ceil(data.size() / k); + QList chunks; + for (int i = 0; i < data.size(); i = i + k) { + QByteArray chunk; + QDataStream s(&chunk, QIODevice::WriteOnly); + s << amnezia::qrMagicCode << chunksCount << (quint8)std::round(i/k) << data.mid(i, k); - int qrImageSize = m_qrEncode.m_nSymbleSize; + QByteArray ba = chunk.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals); - int encodeImageSize = qrImageSize + ( QR_MARGIN * 2 ); - QImage encodeImage( encodeImageSize, encodeImageSize, QImage::Format_Mono ); + QImage qr = QZXing::encodeData(ba, QZXing::EncoderFormat_QR_CODE, QSize(512,512), QZXing::EncodeErrorCorrectionLevel_L); + chunks.append(imageToBase64(qr)); + } - encodeImage.fill( 1 ); - - for ( int i = 0; i < qrImageSize; i++ ) - for ( int j = 0; j < qrImageSize; j++ ) - if ( m_qrEncode.m_byModuleData[i][j] ) - encodeImage.setPixel( i + QR_MARGIN, j + QR_MARGIN, 0 ); - - return encodeImage; + return chunks; } QString ShareConnectionLogic::imageToBase64(const QImage &image) diff --git a/client/ui/pages_logic/ShareConnectionLogic.h b/client/ui/pages_logic/ShareConnectionLogic.h index bc99fe1b..c3c2ad6d 100644 --- a/client/ui/pages_logic/ShareConnectionLogic.h +++ b/client/ui/pages_logic/ShareConnectionLogic.h @@ -2,7 +2,6 @@ #define SHARE_CONNECTION_LOGIC_H #include "PageLogicBase.h" -#include "3rd/QRCodeGenerator/QRCodeGenerator.h" class UiLogic; @@ -14,7 +13,8 @@ public: AUTO_PROPERTY(bool, shareFullAccess) AUTO_PROPERTY(QString, textEditShareAmneziaCodeText) - AUTO_PROPERTY(QString, shareAmneziaQrCodeText) + AUTO_PROPERTY(QStringList, shareAmneziaQrCodeTextSeries) + AUTO_PROPERTY(int, shareAmneziaQrCodeTextSeriesLength) AUTO_PROPERTY(QString, textEditShareOpenVpnCodeText) @@ -46,11 +46,10 @@ public: ~ShareConnectionLogic() = default; void updateSharingPage(int serverIndex, DockerContainer container); - QImage updateQRCodeImage(const QByteArray &data); + QList genQrCodeImageSeries(const QByteArray &data); + QString imageToBase64(const QImage &image); -private: - CQR_Encode m_qrEncode; }; #endif // SHARE_CONNECTION_LOGIC_H diff --git a/client/ui/pages_logic/StartPageLogic.cpp b/client/ui/pages_logic/StartPageLogic.cpp index 68a3d00c..0540afd1 100644 --- a/client/ui/pages_logic/StartPageLogic.cpp +++ b/client/ui/pages_logic/StartPageLogic.cpp @@ -3,6 +3,13 @@ #include "configurators/ssh_configurator.h" #include "../uilogic.h" +#include +#include + +#ifdef Q_OS_ANDROID +#include "platforms/android/android_controller.h" +#endif + StartPageLogic::StartPageLogic(UiLogic *logic, QObject *parent): PageLogicBase(logic, parent), m_pushButtonConnectEnabled{true}, @@ -119,67 +126,97 @@ void StartPageLogic::onPushButtonConnect() void StartPageLogic::onPushButtonImport() { - QString s = lineEditStartExistingCodeText(); - s.replace("vpn://", ""); - QByteArray ba = QByteArray::fromBase64(s.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals); - QByteArray ba_uncompressed = qUncompress(ba); + importConnectionFromCode(lineEditStartExistingCodeText()); +} - QJsonObject o; - if (!ba_uncompressed.isEmpty()) { - o = QJsonDocument::fromBinaryData(ba_uncompressed).object(); - } - else { - o = QJsonDocument::fromJson(ba).object(); - } +void StartPageLogic::onPushButtonImportOpenFile() +{ + QString fileName = QFileDialog::getOpenFileName(nullptr, tr("Open profile"), + QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*.vpn"); + if (fileName.isEmpty()) return; + + QFile file(fileName); + file.open(QIODevice::ReadOnly); + QByteArray data = file.readAll(); + + importConnectionFromCode(QString(data)); +} + +bool StartPageLogic::importConnection(const QJsonObject &profile) +{ ServerCredentials credentials; - credentials.hostName = o.value("h").toString(); - if (credentials.hostName.isEmpty()) credentials.hostName = o.value(config_key::hostName).toString(); + credentials.hostName = profile.value(config_key::hostName).toString(); + credentials.port = profile.value(config_key::port).toInt(); + credentials.userName = profile.value(config_key::userName).toString(); + credentials.password = profile.value(config_key::password).toString(); - credentials.port = o.value("p").toInt(); - if (credentials.port == 0) credentials.port = o.value(config_key::port).toInt(); - - credentials.userName = o.value("u").toString(); - if (credentials.userName.isEmpty()) credentials.userName = o.value(config_key::userName).toString(); - - credentials.password = o.value("w").toString(); - if (credentials.password.isEmpty()) credentials.password = o.value(config_key::password).toString(); - - if (credentials.isValid()) { - o.insert(config_key::hostName, credentials.hostName); - o.insert(config_key::port, credentials.port); - o.insert(config_key::userName, credentials.userName); - o.insert(config_key::password, credentials.password); - - o.remove("h"); - o.remove("p"); - o.remove("u"); - o.remove("w"); - } - qDebug() << QString("Added server %3@%1:%2"). - arg(credentials.hostName). - arg(credentials.port). - arg(credentials.userName); +// qDebug() << QString("Added server %3@%1:%2"). +// arg(credentials.hostName). +// arg(credentials.port). +// arg(credentials.userName); //qDebug() << QString("Password") << credentials.password; - if (credentials.isValid() || o.contains(config_key::containers)) { - m_settings.addServer(o); + if (credentials.isValid() || profile.contains(config_key::containers)) { + m_settings.addServer(profile); m_settings.setDefaultServer(m_settings.serversCount() - 1); + emit uiLogic()->goToPage(Page::Vpn); emit uiLogic()->setStartPage(Page::Vpn); } else { qDebug() << "Failed to import profile"; - qDebug().noquote() << QJsonDocument(o).toJson(); - return; + qDebug().noquote() << QJsonDocument(profile).toJson(); + return false; } - if (!o.contains(config_key::containers)) { + if (!profile.contains(config_key::containers)) { uiLogic()->selectedServerIndex = m_settings.defaultServerIndex(); uiLogic()->selectedDockerContainer = m_settings.defaultContainer(uiLogic()->selectedServerIndex); uiLogic()->onUpdateAllPages(); emit uiLogic()->goToPage(Page::ServerContainers); } + + return true; +} + +bool StartPageLogic::importConnectionFromCode(QString code) +{ + code.replace("vpn://", ""); + QByteArray ba = QByteArray::fromBase64(code.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals); + + QByteArray ba_uncompressed = qUncompress(ba); + if (!ba_uncompressed.isEmpty()) { + ba = ba_uncompressed; + } + + QJsonObject o; + o = QJsonDocument::fromJson(ba).object(); + if (!o.isEmpty()) { + return importConnection(o); + } + + o = QJsonDocument::fromBinaryData(ba).object(); + if (!o.isEmpty()) { + return importConnection(o); + } + return false; +} + +bool StartPageLogic::importConnectionFromQr(const QByteArray &data) +{ + qDebug() << "StartPageLogic::importConnectionFromQr" << data; + QJsonObject dataObj = QJsonDocument::fromJson(data).object(); + if (!dataObj.isEmpty()) { + return importConnection(dataObj); + } + + QByteArray ba_uncompressed = qUncompress(data); + if (!ba_uncompressed.isEmpty()) { + return importConnection(QJsonDocument::fromJson(ba_uncompressed).object()); + } + + return false; } diff --git a/client/ui/pages_logic/StartPageLogic.h b/client/ui/pages_logic/StartPageLogic.h index 61627727..7c33f5dc 100644 --- a/client/ui/pages_logic/StartPageLogic.h +++ b/client/ui/pages_logic/StartPageLogic.h @@ -27,6 +27,11 @@ public: Q_INVOKABLE void onPushButtonConnect(); Q_INVOKABLE void onPushButtonImport(); + Q_INVOKABLE void onPushButtonImportOpenFile(); + + bool importConnection(const QJsonObject &profile); + bool importConnectionFromCode(QString code); + bool importConnectionFromQr(const QByteArray &data); public: explicit StartPageLogic(UiLogic *uiLogic, QObject *parent = nullptr); diff --git a/client/ui/pages_logic/VpnLogic.cpp b/client/ui/pages_logic/VpnLogic.cpp index 1d66547d..65bf3fc2 100644 --- a/client/ui/pages_logic/VpnLogic.cpp +++ b/client/ui/pages_logic/VpnLogic.cpp @@ -4,6 +4,7 @@ #include "vpnconnection.h" #include #include "../uilogic.h" +#include "defines.h" VpnLogic::VpnLogic(UiLogic *logic, QObject *parent): @@ -13,7 +14,6 @@ VpnLogic::VpnLogic(UiLogic *logic, QObject *parent): m_radioButtonVpnModeAllSitesChecked{true}, m_radioButtonVpnModeForwardSitesChecked{false}, m_radioButtonVpnModeExceptSitesChecked{false}, - m_pushButtonVpnAddSiteEnabled{true}, m_labelSpeedReceivedText{tr("0 Mbps")}, m_labelSpeedSentText{tr("0 Mbps")}, @@ -42,7 +42,6 @@ void VpnLogic::onUpdatePage() set_radioButtonVpnModeAllSitesChecked(mode == Settings::VpnAllSites); set_radioButtonVpnModeForwardSitesChecked(mode == Settings::VpnOnlyForwardSites); set_radioButtonVpnModeExceptSitesChecked(mode == Settings::VpnAllExceptSites); - set_pushButtonVpnAddSiteEnabled(mode != Settings::VpnAllSites); const QJsonObject &server = uiLogic()->m_settings.defaultServer(); QString serverString = QString("%2 (%3)") @@ -53,22 +52,35 @@ void VpnLogic::onUpdatePage() DockerContainer selectedContainer = m_settings.defaultContainer(m_settings.defaultServerIndex()); QString selectedContainerName = ContainerProps::containerHumanNames().value(selectedContainer); set_labelCurrentService(selectedContainerName); + + set_isContainerWorkingOnPlatform(ContainerProps::isWorkingOnPlatform(selectedContainer)); + if (!isContainerWorkingOnPlatform()) { + set_labelErrorText(tr("AmneziaVPN not supporting selected protocol on this device. Select another protocol.")); + } + else { + set_labelErrorText(""); + } + QString ver = QString("v. %2").arg(QString(APP_MAJOR_VERSION)); + set_labelVersionText(ver); } void VpnLogic::onRadioButtonVpnModeAllSitesClicked() { m_settings.setRouteMode(Settings::VpnAllSites); + onUpdatePage(); } void VpnLogic::onRadioButtonVpnModeForwardSitesClicked() { m_settings.setRouteMode(Settings::VpnOnlyForwardSites); + onUpdatePage(); } void VpnLogic::onRadioButtonVpnModeExceptSitesClicked() { m_settings.setRouteMode(Settings::VpnAllExceptSites); + onUpdatePage(); } void VpnLogic::onBytesChanged(quint64 receivedData, quint64 sentData) diff --git a/client/ui/pages_logic/VpnLogic.h b/client/ui/pages_logic/VpnLogic.h index d077ba90..811c7f62 100644 --- a/client/ui/pages_logic/VpnLogic.h +++ b/client/ui/pages_logic/VpnLogic.h @@ -19,8 +19,10 @@ class VpnLogic : public PageLogicBase AUTO_PROPERTY(bool, pushButtonConnectEnabled) AUTO_PROPERTY(bool, pushButtonConnectVisible) AUTO_PROPERTY(bool, widgetVpnModeEnabled) + AUTO_PROPERTY(bool, isContainerWorkingOnPlatform) + AUTO_PROPERTY(QString, labelErrorText) - AUTO_PROPERTY(bool, pushButtonVpnAddSiteEnabled) + AUTO_PROPERTY(QString, labelVersionText) AUTO_PROPERTY(bool, radioButtonVpnModeAllSitesChecked) AUTO_PROPERTY(bool, radioButtonVpnModeForwardSitesChecked) diff --git a/client/ui/qml/Pages/PageBase.qml b/client/ui/qml/Pages/PageBase.qml index fef3f7e8..69d975ba 100644 --- a/client/ui/qml/Pages/PageBase.qml +++ b/client/ui/qml/Pages/PageBase.qml @@ -10,7 +10,13 @@ Item { property var page: PageEnum.Start property var logic: UiLogic + property bool pageActive: false + signal activated(bool reset) + signal deactivated() + + onActivated: pageActive = true + onDeactivated: pageActive = false // width: GC.screenWidth // height: GC.screenHeight diff --git a/client/ui/qml/Pages/PageQrDecoder.qml b/client/ui/qml/Pages/PageQrDecoder.qml new file mode 100644 index 00000000..6506b7fa --- /dev/null +++ b/client/ui/qml/Pages/PageQrDecoder.qml @@ -0,0 +1,163 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import PageEnum 1.0 +import QtMultimedia 5.5 +import QZXing 3.2 + +import "./" +import "../Controls" +import "../Config" + +PageBase { + id: root + page: PageEnum.QrDecoder + logic: QrDecoderLogic + + onDeactivated: { + console.debug("Stopping QR decoder") + loader.sourceComponent = undefined + } + + BackButton { + } + Caption { + id: caption + text: qsTr("Import configuration") + } + + Connections { + target: QrDecoderLogic + function onStartDecode() { + console.debug("Starting QR decoder") + loader.sourceComponent = component + } + function onStopDecode() { + console.debug("Stopping QR decoder") + loader.sourceComponent = undefined + } + } + + Loader { + id: loader + + anchors.top: caption.bottom + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + } + + Component { + id: component + + Item { + anchors.fill: parent + Camera + { + id:camera + focus { + focusMode: CameraFocus.FocusContinuous + focusPointMode: CameraFocus.FocusPointAuto + } + } + + VideoOutput + { + id: videoOutput + source: camera + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + autoOrientation: true + fillMode: VideoOutput.PreserveAspectFit + filters: [ zxingFilter ] + + + Rectangle { + color: "black" + opacity: 0.5 + width: videoOutput.contentRect.width *0.15 + height: videoOutput.contentRect.height + x: (videoOutput.width - videoOutput.contentRect.width)/2 + anchors.verticalCenter: videoOutput.verticalCenter + } + + Rectangle { + color: "black" + opacity: 0.5 + width: videoOutput.contentRect.width *0.15 + height: videoOutput.contentRect.height + x: videoOutput.width/2 + videoOutput.contentRect.width/2 - videoOutput.contentRect.width *0.15 + anchors.verticalCenter: videoOutput.verticalCenter + } + + Rectangle { + color: "black" + opacity: 0.5 + width: videoOutput.contentRect.width *0.7 + height: videoOutput.contentRect.height *0.15 + x: (videoOutput.width - videoOutput.contentRect.width)/2 + videoOutput.contentRect.width *0.15 + y: (videoOutput.height - videoOutput.contentRect.height)/2 + } + + Rectangle { + color: "black" + opacity: 0.5 + width: videoOutput.contentRect.width *0.7 + height: videoOutput.contentRect.height *0.15 + x: (videoOutput.width - videoOutput.contentRect.width)/2 + videoOutput.contentRect.width *0.15 + y: videoOutput.height/2 + videoOutput.contentRect.height/2 - videoOutput.contentRect.height *0.15 + } + + LabelType { + width: parent.width + text: qsTr("Decoded QR chunks " + QrDecoderLogic.receivedChunksCount + "/" + QrDecoderLogic.totalChunksCount) + horizontalAlignment: Text.AlignLeft + visible: QrDecoderLogic.totalChunksCount > 0 + anchors.horizontalCenter: videoOutput.horizontalCenter + y: videoOutput.height/2 + videoOutput.contentRect.height/2 + } + } + + QZXingFilter + { + id: zxingFilter + orientation: videoOutput.orientation + captureRect: { + // setup bindings + videoOutput.contentRect; + videoOutput.sourceRect; + return videoOutput.mapRectToSource(videoOutput.mapNormalizedRectToItem(Qt.rect( + 0.15, 0.15, 0.7, 0.7 //0, 0, 1.0, 1.0 + ))); + } + + decoder { + enabledDecoders: QZXing.DecoderFormat_QR_CODE + + onTagFound: { + QrDecoderLogic.onDetectedQrCode(tag) + } + + tryHarder: true + } + + property int framesDecoded: 0 + property real timePerFrameDecode: 0 + + onDecodingFinished: + { + timePerFrameDecode = (decodeTime + framesDecoded * timePerFrameDecode) / (framesDecoded + 1); + framesDecoded++; + if(succeeded) + console.log("frame finished: " + succeeded, decodeTime, timePerFrameDecode, framesDecoded); + } + } + + + } + + } + + +} diff --git a/client/ui/qml/Pages/PageStart.qml b/client/ui/qml/Pages/PageStart.qml index b172a15c..1f01b917 100644 --- a/client/ui/qml/Pages/PageStart.qml +++ b/client/ui/qml/Pages/PageStart.qml @@ -12,6 +12,7 @@ PageBase { BackButton { id: back_from_start + visible: pageLoader.depth > 1 } Caption { @@ -103,12 +104,43 @@ PageBase { anchors.horizontalCenter: parent.horizontalCenter y: 210 anchors.top: lineEdit_start_existing_code.bottom - anchors.topMargin: 40 + anchors.topMargin: 10 text: qsTr("Connect") onClicked: { StartPageLogic.onPushButtonImport() } } + + + BlueButtonType { + id: qr_code_import_open + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: new_sever_import.bottom + anchors.topMargin: 40 + + text: qsTr("Open file") + visible: StartPageLogic.pushButtonConnectVisible + onClicked: { + StartPageLogic.onPushButtonImportOpenFile() + } + enabled: StartPageLogic.pushButtonConnectEnabled + } + + BlueButtonType { + id: qr_code_import + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: qr_code_import_open.bottom + anchors.topMargin: 10 + + text: qsTr("Scan QR code") + visible: StartPageLogic.pushButtonConnectVisible + onClicked: { + UiLogic.goToPage(PageEnum.QrDecoder) + } + enabled: StartPageLogic.pushButtonConnectEnabled + } + + } @@ -224,8 +256,6 @@ PageBase { wrapMode: Text.Wrap } - - BlueButtonType { id: new_sever_connect anchors.horizontalCenter: parent.horizontalCenter diff --git a/client/ui/qml/Pages/PageVPN.qml b/client/ui/qml/Pages/PageVPN.qml index 7dad8e25..6312f416 100644 --- a/client/ui/qml/Pages/PageVPN.qml +++ b/client/ui/qml/Pages/PageVPN.qml @@ -20,6 +20,16 @@ PageBase { source: "qrc:/images/background_connected.png" } + LabelType { + x: 10 + y: 5 + width: 100 + height: 21 + text: VpnLogic.labelVersionText + color: "#dddddd" + font.pixelSize: 12 + } + ImageButtonType { x: parent.width - 40 y: 10 @@ -41,7 +51,7 @@ PageBase { height: width visible: !VpnLogic.pushButtonConnectVisible - paused: VpnLogic.pushButtonConnectVisible + paused: VpnLogic.pushButtonConnectVisible && !root.pageActive //VisibleBehavior on visible { } } @@ -61,7 +71,7 @@ PageBase { } contentItem: Item {} antialiasing: true - enabled: VpnLogic.pushButtonConnectEnabled + enabled: VpnLogic.pushButtonConnectEnabled && VpnLogic.isContainerWorkingOnPlatform opacity: VpnLogic.pushButtonConnectVisible ? 1 : 0 // transitions: Transition { @@ -141,11 +151,14 @@ PageBase { id: error_text anchors.top: layout2.bottom anchors.horizontalCenter: parent.horizontalCenter - width: parent.width + anchors.topMargin: 20 + width: parent.width - 20 + height: 21 horizontalAlignment: Text.AlignHCenter wrapMode: Text.Wrap text: VpnLogic.labelErrorText + color: "red" } Item { @@ -273,7 +286,7 @@ PageBase { width: parent.width - 40 height: GC.isMobile() ? 0: 40 text: qsTr("+ Add site") - enabled: VpnLogic.pushButtonVpnAddSiteEnabled + enabled: ! VpnLogic.radioButtonVpnModeAllSitesChecked background: Rectangle { anchors.fill: parent radius: 4 diff --git a/client/ui/qml/Pages/Share/PageShareProtoAmnezia.qml b/client/ui/qml/Pages/Share/PageShareProtoAmnezia.qml index aebba7fa..0fa2bf84 100644 --- a/client/ui/qml/Pages/Share/PageShareProtoAmnezia.qml +++ b/client/ui/qml/Pages/Share/PageShareProtoAmnezia.qml @@ -33,6 +33,13 @@ PageShareProtocolBase { contentHeight: content.height + 20 clip: true + Behavior on contentY{ + NumberAnimation { + duration: 300 + easing.type: Easing.InOutCubic + } + } + ColumnLayout { id: content enabled: logic.pageEnabled @@ -73,6 +80,7 @@ New encryption keys pair will be generated.") ShareConnectionLogic.onPushButtonShareAmneziaGenerateClicked() enabled = true genConfigProcess = false + fl.contentY = tfShareCode.mapToItem(fl.contentItem, 0, 0).y } } @@ -114,19 +122,32 @@ New encryption keys pair will be generated.") } Image { - id: label_share_code + id: image_share_code Layout.topMargin: 20 Layout.fillWidth: true Layout.preferredHeight: width smooth: false - source: ShareConnectionLogic.shareAmneziaQrCodeText - visible: ShareConnectionLogic.shareAmneziaQrCodeText.length > 0 + + Timer { + property int idx: 0 + interval: 1000 + running: root.pageActive && ShareConnectionLogic.shareAmneziaQrCodeTextSeriesLength > 0 + repeat: true + onTriggered: { + idx++ + if (idx >= ShareConnectionLogic.shareAmneziaQrCodeTextSeriesLength) { + idx = 0 + } + image_share_code.source = ShareConnectionLogic.shareAmneziaQrCodeTextSeries[idx] + } + } + + visible: ShareConnectionLogic.shareAmneziaQrCodeTextSeriesLength > 0 } LabelType { Layout.fillWidth: true - text: qsTr("Config too long to be displayed as QR code") - visible: ShareConnectionLogic.shareAmneziaQrCodeText.length == 0 && tfShareCode.textArea.length > 0 + text: qsTr("Scan QR code using AmneziaVPN mobile") } } } diff --git a/client/ui/qml/Pages/Share/PageShareProtoWireGuard.qml b/client/ui/qml/Pages/Share/PageShareProtoWireGuard.qml index f934ea4c..71f06dc4 100644 --- a/client/ui/qml/Pages/Share/PageShareProtoWireGuard.qml +++ b/client/ui/qml/Pages/Share/PageShareProtoWireGuard.qml @@ -36,7 +36,7 @@ PageShareProtocolBase { ColumnLayout { id: content enabled: logic.pageEnabled - anchors.top: parent.bottom + anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right diff --git a/client/ui/qml/main.qml b/client/ui/qml/main.qml index 61e7380f..9e319d76 100644 --- a/client/ui/qml/main.qml +++ b/client/ui/qml/main.qml @@ -28,7 +28,6 @@ Window { UiLogic.onCloseWindow() } - //flags: Qt.FramelessWindowHint title: "AmneziaVPN" function gotoPage(type, page, reset, slide) { @@ -41,6 +40,9 @@ Window { console.debug("QML gotoPage " + type + " " + page + " " + p_obj) + if (pageLoader.depth > 0) { + pageLoader.currentItem.deactivated() + } if (slide) { pageLoader.push(p_obj, {}, StackView.PushTransition) @@ -59,10 +61,15 @@ Window { if (pageLoader.depth <= 1) { return } + pageLoader.currentItem.deactivated() pageLoader.pop() } function set_start_page(page, slide) { + if (pageLoader.depth > 0) { + pageLoader.currentItem.deactivated() + } + pageLoader.clear() if (slide) { pageLoader.push(pages[page], {}, StackView.PushTransition) @@ -104,8 +111,6 @@ Window { color: "white" } - //PageShareProtoAmnezia {} - StackView { id: pageLoader y: GC.isDesktop() ? titleBar.height : 0 diff --git a/client/ui/uilogic.cpp b/client/ui/uilogic.cpp index f3cbed04..ee2f7c53 100644 --- a/client/ui/uilogic.cpp +++ b/client/ui/uilogic.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -16,7 +17,6 @@ #include #include #include -#include #include "configurators/cloak_configurator.h" #include "configurators/vpn_configurator.h" @@ -51,8 +51,9 @@ #include "pages_logic/AppSettingsLogic.h" #include "pages_logic/GeneralSettingsLogic.h" #include "pages_logic/NetworkSettingsLogic.h" -#include "pages_logic/ServerConfiguringProgressLogic.h" #include "pages_logic/NewServerProtocolsLogic.h" +#include "pages_logic/QrDecoderLogic.h" +#include "pages_logic/ServerConfiguringProgressLogic.h" #include "pages_logic/ServerListLogic.h" #include "pages_logic/ServerSettingsLogic.h" #include "pages_logic/ServerContainersLogic.h" @@ -84,8 +85,9 @@ UiLogic::UiLogic(QObject *parent) : m_appSettingsLogic = new AppSettingsLogic(this); m_generalSettingsLogic = new GeneralSettingsLogic(this); m_networkSettingsLogic = new NetworkSettingsLogic(this); - m_serverConfiguringProgressLogic = new ServerConfiguringProgressLogic(this); m_newServerProtocolsLogic = new NewServerProtocolsLogic(this); + m_qrDecoderLogic = new QrDecoderLogic(this); + m_serverConfiguringProgressLogic = new ServerConfiguringProgressLogic(this); m_serverListLogic = new ServerListLogic(this); m_serverSettingsLogic = new ServerSettingsLogic(this); m_serverprotocolsLogic = new ServerContainersLogic(this); @@ -121,9 +123,9 @@ UiLogic::~UiLogic() } } + m_vpnConnection->deleteLater(); m_vpnConnectionThread.quit(); m_vpnConnectionThread.wait(3000); - delete m_vpnConnection; qDebug() << "Application closed"; } @@ -263,9 +265,6 @@ void UiLogic::keyPressEvent(Qt::Key key) case Qt::Key_Q: qApp->quit(); break; - // case Qt::Key_0: - // *((char*)-1) = 'x'; - // break; case Qt::Key_H: selectedServerIndex = m_settings.defaultServerIndex(); selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex); @@ -645,38 +644,36 @@ PageEnumNS::Page UiLogic::currentPage() return static_cast(currentPageValue()); } -bool UiLogic::saveTextFile(const QString& desc, const QString& ext, const QString& data) +void UiLogic::saveTextFile(const QString& desc, const QString& ext, const QString& data) { QString fileName = QFileDialog::getSaveFileName(nullptr, desc, QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), ext); - if (fileName.isEmpty()) return false; + if (fileName.isEmpty()) return; - QSaveFile save(fileName); + QFile save(fileName); save.open(QIODevice::WriteOnly); save.write(data.toUtf8()); + save.close(); QFileInfo fi(fileName); QDesktopServices::openUrl(fi.absoluteDir().absolutePath()); - - return save.commit(); } -bool UiLogic::saveBinaryFile(const QString &desc, const QString &ext, const QString &data) +void UiLogic::saveBinaryFile(const QString &desc, const QString &ext, const QString &data) { QString fileName = QFileDialog::getSaveFileName(nullptr, desc, QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), ext); - if (fileName.isEmpty()) return false; + if (fileName.isEmpty()) return; - QSaveFile save(fileName); + QFile save(fileName); save.open(QIODevice::WriteOnly); save.write(QByteArray::fromBase64(data.toUtf8())); + save.close(); QFileInfo fi(fileName); QDesktopServices::openUrl(fi.absoluteDir().absolutePath()); - - return save.commit(); } void UiLogic::copyToClipboard(const QString &text) diff --git a/client/ui/uilogic.h b/client/ui/uilogic.h index 9eefb381..7ff699b2 100644 --- a/client/ui/uilogic.h +++ b/client/ui/uilogic.h @@ -22,6 +22,7 @@ class AppSettingsLogic; class GeneralSettingsLogic; class NetworkSettingsLogic; class NewServerProtocolsLogic; +class QrDecoderLogic; class ServerConfiguringProgressLogic; class ServerListLogic; class ServerSettingsLogic; @@ -99,8 +100,8 @@ public: Q_INVOKABLE void keyPressEvent(Qt::Key key); - Q_INVOKABLE bool saveTextFile(const QString& desc, const QString& ext, const QString& data); - Q_INVOKABLE bool saveBinaryFile(const QString& desc, const QString& ext, const QString& data); + Q_INVOKABLE void saveTextFile(const QString& desc, const QString& ext, const QString& data); + Q_INVOKABLE void saveBinaryFile(const QString& desc, const QString& ext, const QString& data); Q_INVOKABLE void copyToClipboard(const QString& text); QString getDialogConnectErrorText() const; @@ -167,8 +168,9 @@ public: AppSettingsLogic *appSettingsLogic() { return m_appSettingsLogic; } GeneralSettingsLogic *generalSettingsLogic() { return m_generalSettingsLogic; } NetworkSettingsLogic *networkSettingsLogic() { return m_networkSettingsLogic; } - ServerConfiguringProgressLogic *serverConfiguringProgressLogic() { return m_serverConfiguringProgressLogic; } NewServerProtocolsLogic *newServerProtocolsLogic() { return m_newServerProtocolsLogic; } + QrDecoderLogic *qrDecoderLogic() { return m_qrDecoderLogic; } + ServerConfiguringProgressLogic *serverConfiguringProgressLogic() { return m_serverConfiguringProgressLogic; } ServerListLogic *serverListLogic() { return m_serverListLogic; } ServerSettingsLogic *serverSettingsLogic() { return m_serverSettingsLogic; } ServerContainersLogic *serverprotocolsLogic() { return m_serverprotocolsLogic; } @@ -191,8 +193,9 @@ private: AppSettingsLogic *m_appSettingsLogic; GeneralSettingsLogic *m_generalSettingsLogic; NetworkSettingsLogic *m_networkSettingsLogic; - ServerConfiguringProgressLogic *m_serverConfiguringProgressLogic; NewServerProtocolsLogic *m_newServerProtocolsLogic; + QrDecoderLogic *m_qrDecoderLogic; + ServerConfiguringProgressLogic *m_serverConfiguringProgressLogic; ServerListLogic *m_serverListLogic; ServerSettingsLogic *m_serverSettingsLogic; ServerContainersLogic *m_serverprotocolsLogic; diff --git a/client/vpnconnection.cpp b/client/vpnconnection.cpp index 5837ce58..23767697 100644 --- a/client/vpnconnection.cpp +++ b/client/vpnconnection.cpp @@ -26,16 +26,16 @@ #include "utils.h" #include "vpnconnection.h" -VpnConnection::VpnConnection(QObject* parent) : QObject(parent) -{ +VpnConnection::VpnConnection(QObject* parent) : QObject(parent), + m_settings(this) +{ } VpnConnection::~VpnConnection() { - //qDebug() << "VpnConnection::~VpnConnection() 1"; + m_vpnProtocol->deleteLater(); m_vpnProtocol.clear(); - //qDebug() << "VpnConnection::~VpnConnection() 2"; } void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes) @@ -47,6 +47,7 @@ void VpnConnection::onConnectionStateChanged(VpnProtocol::VpnConnectionState sta { if (IpcClient::Interface()) { if (state == VpnProtocol::Connected){ + IpcClient::Interface()->resetIpStack(); IpcClient::Interface()->flushDns(); if (m_settings.routeMode() != Settings::VpnAllSites) { @@ -219,7 +220,7 @@ void VpnConnection::connectToVpn(int serverIndex, #if !defined (Q_OS_ANDROID) && !defined (Q_OS_IOS) if (!m_IpcClient) { - m_IpcClient = new IpcClient; + m_IpcClient = new IpcClient(this); } if (!m_IpcClient->isSocketConnected()) { diff --git a/ipc/ipc_interface.rep b/ipc/ipc_interface.rep index b0e89fa3..9cb99110 100644 --- a/ipc/ipc_interface.rep +++ b/ipc/ipc_interface.rep @@ -11,6 +11,7 @@ class IpcInterface SLOT( bool clearSavedRoutes() ); SLOT( bool routeDeleteList(const QString &gw, const QStringList &ip) ); SLOT( void flushDns() ); + SLOT( void resetIpStack() ); SLOT( bool checkAndInstallDriver() ); SLOT( QStringList getTapList() ); diff --git a/ipc/ipcserver.cpp b/ipc/ipcserver.cpp index 7db1ded9..c32e043a 100644 --- a/ipc/ipcserver.cpp +++ b/ipc/ipcserver.cpp @@ -83,6 +83,11 @@ void IpcServer::flushDns() return Router::flushDns(); } +void IpcServer::resetIpStack() +{ + Router::resetIpStack(); +} + bool IpcServer::checkAndInstallDriver() { #ifdef Q_OS_WIN diff --git a/ipc/ipcserver.h b/ipc/ipcserver.h index 284cda21..f0182281 100644 --- a/ipc/ipcserver.h +++ b/ipc/ipcserver.h @@ -20,6 +20,7 @@ public: virtual bool clearSavedRoutes() override; virtual bool routeDeleteList(const QString &gw, const QStringList &ips) override; virtual void flushDns() override; + virtual void resetIpStack() override; virtual bool checkAndInstallDriver() override; virtual QStringList getTapList() override; diff --git a/service/server/router.cpp b/service/server/router.cpp index 3890fcb3..6b97e795 100644 --- a/service/server/router.cpp +++ b/service/server/router.cpp @@ -53,3 +53,14 @@ void Router::flushDns() #endif } +void Router::resetIpStack() +{ +#ifdef Q_OS_WIN + RouterWin::Instance().resetIpStack(); +#elif defined (Q_OS_MAC) + // todo fixme +#elif defined Q_OS_LINUX + // todo fixme +#endif +} + diff --git a/service/server/router.h b/service/server/router.h index 59a25ede..c290f664 100644 --- a/service/server/router.h +++ b/service/server/router.h @@ -19,6 +19,7 @@ public: static bool clearSavedRoutes(); static int routeDeleteList(const QString &gw, const QStringList &ips); static void flushDns(); + static void resetIpStack(); }; #endif // ROUTER_H diff --git a/service/server/router_win.cpp b/service/server/router_win.cpp index d242821e..df431805 100644 --- a/service/server/router_win.cpp +++ b/service/server/router_win.cpp @@ -289,6 +289,27 @@ void RouterWin::flushDns() //qDebug().noquote() << "OUTPUT ipconfig /flushdns: " + p.readAll(); } +void RouterWin::resetIpStack() +{ +// { +// QProcess p; +// QString command = QString("ipconfig /release"); +// p.start(command); +// } + { + QProcess p; + QString command = QString("netsh int ip reset"); + p.start(command); + p.waitForFinished(); + } + { + QProcess p; + QString command = QString("netsh winsock reset"); + p.start(command); + p.waitForFinished(); + } +} + void RouterWin::suspendWcmSvc(bool suspend) { if (suspend == m_suspended) return; diff --git a/service/server/router_win.h b/service/server/router_win.h index 4858a766..bf23d208 100644 --- a/service/server/router_win.h +++ b/service/server/router_win.h @@ -39,6 +39,7 @@ public: bool clearSavedRoutes(); int routeDeleteList(const QString &gw, const QStringList &ips); void flushDns(); + void resetIpStack(); void suspendWcmSvc(bool suspend);