@alteriom/painlessmesh 1.6.1 → 1.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +380 -143
- package/LICENSE +674 -674
- package/README.md +477 -434
- package/RELEASE_GUIDE.md +504 -418
- package/docs/DOCUMENTATION_MIGRATION_PLAN.md +175 -175
- package/docs/IMPLEMENTATION_PLAN_MESH_TOPOLOGY.md +1062 -0
- package/docs/MESH_TOPOLOGY_GUIDE.md +992 -0
- package/docs/MESH_TOPOLOGY_PROGRESS.md +422 -0
- package/docs/MQTT_BRIDGE_COMMANDS.md +894 -0
- package/docs/MQTT_BRIDGE_IMPLEMENTATION_SUMMARY.md +324 -0
- package/docs/MQTT_COMMAND_SCHEMA_PROPOSAL.md +576 -0
- package/docs/MQTT_SCHEMA_COMPLIANCE.md +285 -0
- package/docs/MQTT_SCHEMA_PROPOSALS.md +446 -0
- package/docs/MQTT_SCHEMA_REVIEW.md +690 -0
- package/docs/OTA_COMMANDS_REFERENCE.md +554 -0
- package/docs/PHASE1_GUIDE.md +349 -0
- package/docs/PHASE2_GUIDE.md +543 -0
- package/docs/README.md +77 -70
- package/docs/SCHEMA_VALIDATION_CHECKLIST.md +222 -0
- package/docs/alteriom/overview.md +507 -507
- package/docs/api/core-api.md +606 -606
- package/docs/architecture/mesh-architecture.md +378 -378
- package/docs/architecture/plugin-system.md +516 -516
- package/docs/getting-started/first-mesh.md +409 -409
- package/docs/getting-started/installation.md +274 -274
- package/docs/getting-started/quickstart.md +157 -157
- package/docs/improvements/FEATURE_PROPOSALS.md +337 -0
- package/docs/improvements/PHASE1_IMPLEMENTATION.md +325 -0
- package/docs/improvements/PHASE2_IMPLEMENTATION.md +567 -0
- package/docs/improvements/README.md +86 -68
- package/docs/improvements/ota-and-status-enhancements.md +911 -0
- package/docs/improvements/ota-status-architecture-diagrams.md +658 -0
- package/docs/improvements/ota-status-quick-reference.md +284 -0
- package/docs/platformio-publishing.md +255 -0
- package/docs/platformio-setup-summary.md +121 -0
- package/docs/troubleshooting/common-issues.md +520 -520
- package/docs/troubleshooting/faq.md +472 -472
- package/docs/tutorials/basic-examples.md +717 -717
- package/docs/wiki/API-Reference.md +245 -245
- package/docs/wiki/Complete-Documentation.md +122 -122
- package/examples/alteriom/README.md +139 -81
- package/examples/alteriom/alteriom.ino +186 -185
- package/examples/alteriom/alteriom_sensor_package.hpp +240 -127
- package/examples/alteriom/platformio.ini +24 -24
- package/examples/alteriomImproved/alteriom_sensor_package.hpp +224 -0
- package/examples/{alteriom → alteriomImproved}/improved_sensor_node.ino +245 -245
- package/examples/alteriomImproved/platformio.ini +25 -0
- package/examples/alteriomPhase1/alteriom_sensor_package.hpp +224 -0
- package/examples/alteriomPhase1/phase1_features.ino +242 -0
- package/examples/alteriomPhase1/platformio.ini +25 -0
- package/examples/alteriomPhase2/alteriom_sensor_package.hpp +224 -0
- package/examples/alteriomPhase2/phase2_features.ino +186 -0
- package/examples/alteriomPhase2/platformio.ini +25 -0
- package/examples/{alteriom → alteriomSensorNode}/alteriom_sensor_node.ino +183 -183
- package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +224 -0
- package/examples/alteriomSensorNode/platformio.ini +25 -0
- package/examples/basic/basic.ino +66 -66
- package/examples/basic/platformio.ini +25 -25
- package/examples/bridge/bridge.ino +51 -51
- package/examples/bridge/mesh_event_publisher.hpp +253 -0
- package/examples/bridge/mesh_topology_reporter.hpp +303 -0
- package/examples/bridge/mqtt_command_bridge.hpp +459 -0
- package/examples/bridge/mqtt_status_bridge.hpp +519 -0
- package/examples/bridge/platformio.ini +25 -25
- package/examples/echoNode/echoNode.ino +33 -33
- package/examples/echoNode/platformio.ini +25 -25
- package/examples/logClient/logClient.ino +109 -109
- package/examples/logClient/platformio.ini +25 -25
- package/examples/logServer/logServer.ino +81 -81
- package/examples/logServer/platformio.ini +25 -25
- package/examples/meshCommandNode/alteriom_sensor_package.hpp +235 -0
- package/examples/meshCommandNode/meshCommandNode.ino +263 -0
- package/examples/meshCommandNode/platformio.ini +25 -0
- package/examples/mqttBridge/mqttBridge.ino +118 -118
- package/examples/mqttBridge/platformio.ini +26 -26
- package/examples/mqttCommandBridge/alteriom_sensor_package.hpp +235 -0
- package/examples/mqttCommandBridge/mesh_event_publisher.hpp +253 -0
- package/examples/mqttCommandBridge/mesh_topology_reporter.hpp +303 -0
- package/examples/mqttCommandBridge/mqttCommandBridge.ino +252 -0
- package/examples/mqttCommandBridge/mqtt_command_bridge.hpp +459 -0
- package/examples/mqttCommandBridge/platformio.ini +26 -0
- package/examples/mqttStatusBridge/mqttStatusBridge.ino +216 -0
- package/examples/mqttStatusBridge/mqtt_status_bridge.hpp +522 -0
- package/examples/mqttStatusBridge/platformio.ini +26 -0
- package/examples/mqttTopologyTest/README.md +467 -0
- package/examples/mqttTopologyTest/mqttTopologyTest.ino +748 -0
- package/examples/mqttTopologyTest/platformio.ini +26 -0
- package/examples/namedMesh/namedMesh.ino +97 -97
- package/examples/namedMesh/platformio.ini +25 -25
- package/examples/otaReceiver/otaReceiver.ino +79 -79
- package/examples/otaReceiver/platformio.ini +25 -25
- package/examples/otaSender/otaSender.ino +160 -151
- package/examples/otaSender/platformio.ini +25 -25
- package/examples/startHere/platformio.ini +25 -25
- package/examples/startHere/startHere.ino +159 -159
- package/examples/webServer/platformio.ini +27 -27
- package/examples/webServer/webServer.ino +89 -89
- package/keywords.txt +48 -48
- package/library.json +55 -34
- package/library.properties +10 -10
- package/package.json +86 -78
- package/src/AlteriomPainlessMesh.h +97 -97
- package/src/arduino/wifi.hpp +365 -365
- package/src/boost/asynctcp.hpp +279 -279
- package/src/painlessMesh.h +70 -70
- package/src/painlessMeshSTA.cpp +236 -236
- package/src/painlessMeshSTA.h +58 -58
- package/src/painlessTaskOptions.h +4 -4
- package/src/painlessmesh/base64.hpp +111 -111
- package/src/painlessmesh/buffer.hpp +229 -229
- package/src/painlessmesh/callback.hpp +91 -91
- package/src/painlessmesh/configuration.hpp +77 -77
- package/src/painlessmesh/connection.hpp +192 -192
- package/src/painlessmesh/layout.hpp +188 -188
- package/src/painlessmesh/logger.hpp +158 -158
- package/src/painlessmesh/memory.hpp +119 -119
- package/src/painlessmesh/mesh.hpp +761 -560
- package/src/painlessmesh/metrics.hpp +322 -322
- package/src/painlessmesh/ntp.hpp +263 -263
- package/src/painlessmesh/ota.hpp +582 -553
- package/src/painlessmesh/plugin.hpp +188 -188
- package/src/painlessmesh/protocol.hpp +813 -813
- package/src/painlessmesh/router.hpp +322 -322
- package/src/painlessmesh/tcp.hpp +71 -71
- package/src/painlessmesh/validation.hpp +238 -238
- package/src/plugin/performance.hpp +214 -214
- package/src/plugin/remote.hpp +64 -64
- package/src/scheduler.cpp +10 -10
- package/src/wifi.cpp +2 -2
package/src/painlessMeshSTA.h
CHANGED
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
#ifndef _PAINLESS_MESH_STA_H_
|
|
2
|
-
#define _PAINLESS_MESH_STA_H_
|
|
3
|
-
|
|
4
|
-
#include "painlessmesh/configuration.hpp"
|
|
5
|
-
|
|
6
|
-
#include "painlessmesh/mesh.hpp"
|
|
7
|
-
|
|
8
|
-
#include <list>
|
|
9
|
-
|
|
10
|
-
typedef struct {
|
|
11
|
-
uint8_t bssid[6];
|
|
12
|
-
TSTRING ssid;
|
|
13
|
-
int8_t rssi;
|
|
14
|
-
} WiFi_AP_Record_t;
|
|
15
|
-
|
|
16
|
-
class StationScan {
|
|
17
|
-
public:
|
|
18
|
-
Task task; // Station scanning for connections
|
|
19
|
-
|
|
20
|
-
#ifdef ESP8266
|
|
21
|
-
Task asyncTask;
|
|
22
|
-
#endif
|
|
23
|
-
|
|
24
|
-
StationScan() {}
|
|
25
|
-
void init(painlessmesh::wifi::Mesh *pMesh, TSTRING ssid, TSTRING password,
|
|
26
|
-
uint16_t port, uint8_t channel, bool hidden);
|
|
27
|
-
void stationScan();
|
|
28
|
-
void scanComplete();
|
|
29
|
-
void filterAPs();
|
|
30
|
-
void connectToAP();
|
|
31
|
-
// This one will call the connectToAP next in the task and should be used
|
|
32
|
-
// instead of connectToAP
|
|
33
|
-
void yieldConnectToAP() {
|
|
34
|
-
task.yield([this]() { connectToAP(); });
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/// Valid APs found during the last scan
|
|
38
|
-
std::list<WiFi_AP_Record_t> lastAPs;
|
|
39
|
-
|
|
40
|
-
protected:
|
|
41
|
-
TSTRING ssid;
|
|
42
|
-
TSTRING password;
|
|
43
|
-
painlessMesh *mesh;
|
|
44
|
-
uint16_t port;
|
|
45
|
-
uint8_t channel;
|
|
46
|
-
bool hidden;
|
|
47
|
-
std::list<WiFi_AP_Record_t> aps;
|
|
48
|
-
|
|
49
|
-
void requestIP(WiFi_AP_Record_t &ap);
|
|
50
|
-
|
|
51
|
-
// Manually configure network and ip
|
|
52
|
-
bool manual = false;
|
|
53
|
-
IPAddress manualIP = IPAddress(0, 0, 0, 0);
|
|
54
|
-
|
|
55
|
-
friend painlessMesh;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
#endif
|
|
1
|
+
#ifndef _PAINLESS_MESH_STA_H_
|
|
2
|
+
#define _PAINLESS_MESH_STA_H_
|
|
3
|
+
|
|
4
|
+
#include "painlessmesh/configuration.hpp"
|
|
5
|
+
|
|
6
|
+
#include "painlessmesh/mesh.hpp"
|
|
7
|
+
|
|
8
|
+
#include <list>
|
|
9
|
+
|
|
10
|
+
typedef struct {
|
|
11
|
+
uint8_t bssid[6];
|
|
12
|
+
TSTRING ssid;
|
|
13
|
+
int8_t rssi;
|
|
14
|
+
} WiFi_AP_Record_t;
|
|
15
|
+
|
|
16
|
+
class StationScan {
|
|
17
|
+
public:
|
|
18
|
+
Task task; // Station scanning for connections
|
|
19
|
+
|
|
20
|
+
#ifdef ESP8266
|
|
21
|
+
Task asyncTask;
|
|
22
|
+
#endif
|
|
23
|
+
|
|
24
|
+
StationScan() {}
|
|
25
|
+
void init(painlessmesh::wifi::Mesh *pMesh, TSTRING ssid, TSTRING password,
|
|
26
|
+
uint16_t port, uint8_t channel, bool hidden);
|
|
27
|
+
void stationScan();
|
|
28
|
+
void scanComplete();
|
|
29
|
+
void filterAPs();
|
|
30
|
+
void connectToAP();
|
|
31
|
+
// This one will call the connectToAP next in the task and should be used
|
|
32
|
+
// instead of connectToAP
|
|
33
|
+
void yieldConnectToAP() {
|
|
34
|
+
task.yield([this]() { connectToAP(); });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/// Valid APs found during the last scan
|
|
38
|
+
std::list<WiFi_AP_Record_t> lastAPs;
|
|
39
|
+
|
|
40
|
+
protected:
|
|
41
|
+
TSTRING ssid;
|
|
42
|
+
TSTRING password;
|
|
43
|
+
painlessMesh *mesh;
|
|
44
|
+
uint16_t port;
|
|
45
|
+
uint8_t channel;
|
|
46
|
+
bool hidden;
|
|
47
|
+
std::list<WiFi_AP_Record_t> aps;
|
|
48
|
+
|
|
49
|
+
void requestIP(WiFi_AP_Record_t &ap);
|
|
50
|
+
|
|
51
|
+
// Manually configure network and ip
|
|
52
|
+
bool manual = false;
|
|
53
|
+
IPAddress manualIP = IPAddress(0, 0, 0, 0);
|
|
54
|
+
|
|
55
|
+
friend painlessMesh;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
#endif
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// The following two complie options are required for painlessMesh
|
|
2
|
-
#define _TASK_PRIORITY // Support for layered scheduling priority
|
|
3
|
-
#define _TASK_STD_FUNCTION // Support for std::function (ESP8266 and ESP32
|
|
4
|
-
// ONLY)
|
|
1
|
+
// The following two complie options are required for painlessMesh
|
|
2
|
+
#define _TASK_PRIORITY // Support for layered scheduling priority
|
|
3
|
+
#define _TASK_STD_FUNCTION // Support for std::function (ESP8266 and ESP32
|
|
4
|
+
// ONLY)
|
|
@@ -1,111 +1,111 @@
|
|
|
1
|
-
#ifndef _PAINLESS_MESH_BASE64_HPP_
|
|
2
|
-
#define _PAINLESS_MESH_BASE64_HPP_
|
|
3
|
-
|
|
4
|
-
#include <string>
|
|
5
|
-
|
|
6
|
-
#include "painlessmesh/configuration.hpp"
|
|
7
|
-
|
|
8
|
-
namespace painlessmesh {
|
|
9
|
-
namespace base64 {
|
|
10
|
-
|
|
11
|
-
static inline bool is_base64(unsigned char c) {
|
|
12
|
-
return (isalnum(c) || (c == '+') || (c == '/'));
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
static const TSTRING chars =
|
|
16
|
-
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
17
|
-
"abcdefghijklmnopqrstuvwxyz"
|
|
18
|
-
"0123456789+/";
|
|
19
|
-
|
|
20
|
-
inline TSTRING encode(unsigned char const* bytes_to_encode,
|
|
21
|
-
unsigned int in_len) {
|
|
22
|
-
TSTRING ret;
|
|
23
|
-
int i = 0;
|
|
24
|
-
int j = 0;
|
|
25
|
-
unsigned char char_array_3[3];
|
|
26
|
-
unsigned char char_array_4[4];
|
|
27
|
-
|
|
28
|
-
while (in_len--) {
|
|
29
|
-
char_array_3[i++] = *(bytes_to_encode++);
|
|
30
|
-
if (i == 3) {
|
|
31
|
-
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
|
32
|
-
char_array_4[1] =
|
|
33
|
-
((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
|
34
|
-
char_array_4[2] =
|
|
35
|
-
((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
|
36
|
-
char_array_4[3] = char_array_3[2] & 0x3f;
|
|
37
|
-
|
|
38
|
-
for (i = 0; (i < 4); i++) ret += chars[char_array_4[i]];
|
|
39
|
-
i = 0;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (i) {
|
|
44
|
-
for (j = i; j < 3; j++) char_array_3[j] = '\0';
|
|
45
|
-
|
|
46
|
-
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
|
47
|
-
char_array_4[1] =
|
|
48
|
-
((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
|
49
|
-
char_array_4[2] =
|
|
50
|
-
((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
|
51
|
-
char_array_4[3] = char_array_3[2] & 0x3f;
|
|
52
|
-
for (j = 0; (j < i + 1); j++) ret += chars[char_array_4[j]];
|
|
53
|
-
while ((i++ < 3)) ret += '=';
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return ret;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
inline TSTRING encode(const TSTRING& str64) {
|
|
60
|
-
return encode((unsigned char*)str64.c_str(), str64.length());
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
static const int B64index[256] = {
|
|
64
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
65
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
66
|
-
0, 0, 0, 0, 0, 0, 0, 62, 63, 62, 62, 63, 52, 53, 54, 55, 56, 57,
|
|
67
|
-
58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6,
|
|
68
|
-
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
|
69
|
-
25, 0, 0, 0, 0, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
|
|
70
|
-
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
|
|
71
|
-
|
|
72
|
-
inline const TSTRING decode(const void* data, const size_t& len) {
|
|
73
|
-
if (len == 0) return "";
|
|
74
|
-
|
|
75
|
-
unsigned char* p = (unsigned char*)data;
|
|
76
|
-
size_t j = 0, pad1 = len % 4 || p[len - 1] == '=',
|
|
77
|
-
pad2 = pad1 && (len % 4 > 2 || p[len - 2] != '=');
|
|
78
|
-
const size_t last = (len - pad1) / 4 << 2;
|
|
79
|
-
#ifdef PAINLESSMESH_ENABLE_STD_STRING
|
|
80
|
-
TSTRING result(last / 4 * 3 + pad1 + pad2, '\0');
|
|
81
|
-
#else
|
|
82
|
-
TSTRING result;
|
|
83
|
-
result.reserve(last / 4 * 3 + pad1 + pad2);
|
|
84
|
-
for (size_t i = 0; i < last / 4 * 3 + pad1 + pad2; ++i) result.concat('\0');
|
|
85
|
-
#endif
|
|
86
|
-
unsigned char* str = (unsigned char*)&result[0];
|
|
87
|
-
|
|
88
|
-
for (size_t i = 0; i < last; i += 4) {
|
|
89
|
-
int n = B64index[p[i]] << 18 | B64index[p[i + 1]] << 12 |
|
|
90
|
-
B64index[p[i + 2]] << 6 | B64index[p[i + 3]];
|
|
91
|
-
str[j++] = n >> 16;
|
|
92
|
-
str[j++] = n >> 8 & 0xFF;
|
|
93
|
-
str[j++] = n & 0xFF;
|
|
94
|
-
}
|
|
95
|
-
if (pad1) {
|
|
96
|
-
int n = B64index[p[last]] << 18 | B64index[p[last + 1]] << 12;
|
|
97
|
-
str[j++] = n >> 16;
|
|
98
|
-
if (pad2) {
|
|
99
|
-
n |= B64index[p[last + 2]] << 6;
|
|
100
|
-
str[j++] = n >> 8 & 0xFF;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
return result;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
inline TSTRING decode(const TSTRING& str64) {
|
|
107
|
-
return decode(str64.c_str(), str64.length());
|
|
108
|
-
}
|
|
109
|
-
} // namespace base64
|
|
110
|
-
} // namespace painlessmesh
|
|
111
|
-
#endif
|
|
1
|
+
#ifndef _PAINLESS_MESH_BASE64_HPP_
|
|
2
|
+
#define _PAINLESS_MESH_BASE64_HPP_
|
|
3
|
+
|
|
4
|
+
#include <string>
|
|
5
|
+
|
|
6
|
+
#include "painlessmesh/configuration.hpp"
|
|
7
|
+
|
|
8
|
+
namespace painlessmesh {
|
|
9
|
+
namespace base64 {
|
|
10
|
+
|
|
11
|
+
static inline bool is_base64(unsigned char c) {
|
|
12
|
+
return (isalnum(c) || (c == '+') || (c == '/'));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
static const TSTRING chars =
|
|
16
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
17
|
+
"abcdefghijklmnopqrstuvwxyz"
|
|
18
|
+
"0123456789+/";
|
|
19
|
+
|
|
20
|
+
inline TSTRING encode(unsigned char const* bytes_to_encode,
|
|
21
|
+
unsigned int in_len) {
|
|
22
|
+
TSTRING ret;
|
|
23
|
+
int i = 0;
|
|
24
|
+
int j = 0;
|
|
25
|
+
unsigned char char_array_3[3];
|
|
26
|
+
unsigned char char_array_4[4];
|
|
27
|
+
|
|
28
|
+
while (in_len--) {
|
|
29
|
+
char_array_3[i++] = *(bytes_to_encode++);
|
|
30
|
+
if (i == 3) {
|
|
31
|
+
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
|
32
|
+
char_array_4[1] =
|
|
33
|
+
((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
|
34
|
+
char_array_4[2] =
|
|
35
|
+
((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
|
36
|
+
char_array_4[3] = char_array_3[2] & 0x3f;
|
|
37
|
+
|
|
38
|
+
for (i = 0; (i < 4); i++) ret += chars[char_array_4[i]];
|
|
39
|
+
i = 0;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (i) {
|
|
44
|
+
for (j = i; j < 3; j++) char_array_3[j] = '\0';
|
|
45
|
+
|
|
46
|
+
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
|
47
|
+
char_array_4[1] =
|
|
48
|
+
((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
|
49
|
+
char_array_4[2] =
|
|
50
|
+
((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
|
51
|
+
char_array_4[3] = char_array_3[2] & 0x3f;
|
|
52
|
+
for (j = 0; (j < i + 1); j++) ret += chars[char_array_4[j]];
|
|
53
|
+
while ((i++ < 3)) ret += '=';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return ret;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
inline TSTRING encode(const TSTRING& str64) {
|
|
60
|
+
return encode((unsigned char*)str64.c_str(), str64.length());
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static const int B64index[256] = {
|
|
64
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
65
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
66
|
+
0, 0, 0, 0, 0, 0, 0, 62, 63, 62, 62, 63, 52, 53, 54, 55, 56, 57,
|
|
67
|
+
58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6,
|
|
68
|
+
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
|
69
|
+
25, 0, 0, 0, 0, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
|
|
70
|
+
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
|
|
71
|
+
|
|
72
|
+
inline const TSTRING decode(const void* data, const size_t& len) {
|
|
73
|
+
if (len == 0) return "";
|
|
74
|
+
|
|
75
|
+
unsigned char* p = (unsigned char*)data;
|
|
76
|
+
size_t j = 0, pad1 = len % 4 || p[len - 1] == '=',
|
|
77
|
+
pad2 = pad1 && (len % 4 > 2 || p[len - 2] != '=');
|
|
78
|
+
const size_t last = (len - pad1) / 4 << 2;
|
|
79
|
+
#ifdef PAINLESSMESH_ENABLE_STD_STRING
|
|
80
|
+
TSTRING result(last / 4 * 3 + pad1 + pad2, '\0');
|
|
81
|
+
#else
|
|
82
|
+
TSTRING result;
|
|
83
|
+
result.reserve(last / 4 * 3 + pad1 + pad2);
|
|
84
|
+
for (size_t i = 0; i < last / 4 * 3 + pad1 + pad2; ++i) result.concat('\0');
|
|
85
|
+
#endif
|
|
86
|
+
unsigned char* str = (unsigned char*)&result[0];
|
|
87
|
+
|
|
88
|
+
for (size_t i = 0; i < last; i += 4) {
|
|
89
|
+
int n = B64index[p[i]] << 18 | B64index[p[i + 1]] << 12 |
|
|
90
|
+
B64index[p[i + 2]] << 6 | B64index[p[i + 3]];
|
|
91
|
+
str[j++] = n >> 16;
|
|
92
|
+
str[j++] = n >> 8 & 0xFF;
|
|
93
|
+
str[j++] = n & 0xFF;
|
|
94
|
+
}
|
|
95
|
+
if (pad1) {
|
|
96
|
+
int n = B64index[p[last]] << 18 | B64index[p[last + 1]] << 12;
|
|
97
|
+
str[j++] = n >> 16;
|
|
98
|
+
if (pad2) {
|
|
99
|
+
n |= B64index[p[last + 2]] << 6;
|
|
100
|
+
str[j++] = n >> 8 & 0xFF;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
inline TSTRING decode(const TSTRING& str64) {
|
|
107
|
+
return decode(str64.c_str(), str64.length());
|
|
108
|
+
}
|
|
109
|
+
} // namespace base64
|
|
110
|
+
} // namespace painlessmesh
|
|
111
|
+
#endif
|