初始化提交
This commit is contained in:
13287
arduino-cli/libraries/painlessMesh-master/test/include/catch2/catch.hpp
Normal file
13287
arduino-cli/libraries/painlessMesh-master/test/include/catch2/catch.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,209 @@
|
||||
#ifndef CATCH_UTILS_H_
|
||||
#define CATCH_UTILS_H_
|
||||
|
||||
/*
|
||||
* Some helper functions to be used in catch based tests
|
||||
*/
|
||||
|
||||
#include <limits>
|
||||
#include <random>
|
||||
|
||||
#include "painlessmesh/protocol.hpp"
|
||||
|
||||
static std::random_device
|
||||
rd; // Will be used to obtain a seed for the random number engine
|
||||
static std::mt19937 gen(rd());
|
||||
|
||||
uint32_t runif(uint32_t from, uint32_t to) {
|
||||
std::uniform_int_distribution<uint32_t> distribution(from, to);
|
||||
return distribution(gen);
|
||||
}
|
||||
|
||||
uint32_t rbinom(size_t n, double p) {
|
||||
std::binomial_distribution<uint32_t> distribution(n, p);
|
||||
return distribution(gen);
|
||||
}
|
||||
|
||||
std::string randomString(uint32_t length) {
|
||||
std::string str;
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
char rnd = (char)runif(65, 90);
|
||||
str += rnd;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
void randomCString(char* str, uint32_t length) {
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
char rnd = (char)runif(65, 90);
|
||||
str[i] = rnd;
|
||||
}
|
||||
str[length] = '\0';
|
||||
}
|
||||
|
||||
painlessmesh::protocol::Single createSingle(int length = -1) {
|
||||
auto pkg = painlessmesh::protocol::Single();
|
||||
pkg.dest = runif(0, std::numeric_limits<uint32_t>::max());
|
||||
pkg.from = runif(0, std::numeric_limits<uint32_t>::max());
|
||||
|
||||
if (length < 0) length = runif(0, 4096);
|
||||
pkg.msg = randomString(length);
|
||||
return pkg;
|
||||
}
|
||||
|
||||
painlessmesh::protocol::Broadcast createBroadcast(int length = -1) {
|
||||
auto pkg = painlessmesh::protocol::Broadcast();
|
||||
pkg.dest = runif(0, std::numeric_limits<uint32_t>::max());
|
||||
pkg.from = runif(0, std::numeric_limits<uint32_t>::max());
|
||||
if (length < 0) length = runif(0, 4096);
|
||||
pkg.msg = randomString(length);
|
||||
return pkg;
|
||||
}
|
||||
|
||||
/*
|
||||
```
|
||||
{
|
||||
"dest": ...,
|
||||
"from": ...,
|
||||
"type": ...,
|
||||
"subs": [
|
||||
{
|
||||
"nodeId": ...,
|
||||
"root" : true,
|
||||
"subs": [
|
||||
{
|
||||
"nodeId": ...,
|
||||
"subs": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
*/
|
||||
painlessmesh::protocol::NodeTree createNodeTree(int nodes, int contains_root) {
|
||||
auto pkg = painlessmesh::protocol::NodeTree();
|
||||
pkg.nodeId = runif(0, std::numeric_limits<uint32_t>::max());
|
||||
if (contains_root == 0) {
|
||||
pkg.root = true;
|
||||
}
|
||||
--nodes; // The current node
|
||||
--contains_root;
|
||||
auto noSubs = runif(1, 5);
|
||||
for (uint32_t i = 0; i < noSubs; ++i) {
|
||||
if (nodes > 0) {
|
||||
if (i == noSubs - 1) {
|
||||
pkg.subs.push_back(createNodeTree(nodes, contains_root));
|
||||
} else {
|
||||
auto newNodes = 1 + rbinom(nodes - 1, 1.0 / noSubs);
|
||||
nodes -= newNodes;
|
||||
if (newNodes > 0)
|
||||
pkg.subs.push_back(createNodeTree(newNodes, contains_root));
|
||||
contains_root -= newNodes;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pkg;
|
||||
}
|
||||
|
||||
painlessmesh::protocol::NodeSyncReply createNodeSyncReply(
|
||||
int nodes = -1, bool contains_root = true) {
|
||||
auto pkg = painlessmesh::protocol::NodeSyncReply();
|
||||
pkg.dest = runif(0, std::numeric_limits<uint32_t>::max());
|
||||
pkg.from = runif(0, std::numeric_limits<uint32_t>::max());
|
||||
if (nodes < 0) nodes = runif(1, 254);
|
||||
auto rt = -1;
|
||||
if (contains_root) rt = runif(0, nodes - 1);
|
||||
auto ns = createNodeTree(nodes, rt);
|
||||
pkg.subs = ns.subs;
|
||||
pkg.nodeId = ns.nodeId;
|
||||
pkg.root = ns.root;
|
||||
return pkg;
|
||||
}
|
||||
|
||||
painlessmesh::protocol::NodeSyncRequest createNodeSyncRequest(
|
||||
int nodes = -1, bool contains_root = true) {
|
||||
auto pkg = painlessmesh::protocol::NodeSyncRequest();
|
||||
pkg.dest = runif(0, std::numeric_limits<uint32_t>::max());
|
||||
pkg.from = runif(0, std::numeric_limits<uint32_t>::max());
|
||||
if (nodes < 0) nodes = runif(1, 254);
|
||||
auto rt = -1;
|
||||
if (contains_root) rt = runif(0, nodes - 1);
|
||||
auto ns = createNodeTree(nodes, rt);
|
||||
pkg.subs = ns.subs;
|
||||
pkg.nodeId = ns.nodeId;
|
||||
pkg.root = ns.root;
|
||||
return pkg;
|
||||
}
|
||||
|
||||
/*
|
||||
```
|
||||
{
|
||||
"dest": 887034362,
|
||||
"from": 37418,
|
||||
"type":4,
|
||||
"msg":{
|
||||
"type":0
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"dest": 887034362,
|
||||
"from": 37418,
|
||||
"type":4,
|
||||
"msg":{
|
||||
"type":1,
|
||||
"t0":32990
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"dest": 37418,
|
||||
"from": 887034362,
|
||||
"type":4,
|
||||
"msg":{
|
||||
"type":2,
|
||||
"t0":32990,
|
||||
"t1":448585896,
|
||||
"t2":448596056,
|
||||
}
|
||||
}
|
||||
```
|
||||
*/
|
||||
painlessmesh::protocol::TimeSync createTimeSync(int type = -1) {
|
||||
auto pkg = painlessmesh::protocol::TimeSync();
|
||||
pkg.dest = runif(0, std::numeric_limits<uint32_t>::max());
|
||||
pkg.from = runif(0, std::numeric_limits<uint32_t>::max());
|
||||
|
||||
if (type < 0) type = runif(0, 2);
|
||||
pkg.msg.type = type;
|
||||
auto t = runif(0, std::numeric_limits<uint32_t>::max());
|
||||
if (type >= 1) pkg.msg.t0 = t;
|
||||
if (type >= 2) {
|
||||
t += runif(0, 10000);
|
||||
pkg.msg.t1 = t;
|
||||
t += runif(0, 10000);
|
||||
pkg.msg.t2 = t;
|
||||
}
|
||||
return pkg;
|
||||
}
|
||||
|
||||
painlessmesh::protocol::TimeDelay createTimeDelay(int type = -1) {
|
||||
auto pkg = painlessmesh::protocol::TimeDelay();
|
||||
pkg.dest = runif(0, std::numeric_limits<uint32_t>::max());
|
||||
pkg.from = runif(0, std::numeric_limits<uint32_t>::max());
|
||||
|
||||
if (type < 0) type = runif(0, 2);
|
||||
pkg.msg.type = type;
|
||||
auto t = runif(0, std::numeric_limits<uint32_t>::max());
|
||||
if (type == 1) pkg.msg.t0 = t;
|
||||
if (type == 2) {
|
||||
t += runif(0, 10000);
|
||||
pkg.msg.t1 = t;
|
||||
t += runif(0, 10000);
|
||||
pkg.msg.t2 = t;
|
||||
}
|
||||
return pkg;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,133 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <cstring>
|
||||
#include "Arduino.h"
|
||||
|
||||
#define ASYNC_WRITE_FLAG_COPY \
|
||||
0x01 // will allocate new buffer to hold the data while sending (else will
|
||||
// hold reference to the data given)
|
||||
#define ASYNC_WRITE_FLAG_MORE \
|
||||
0x02 // will not send PSH flag, meaning that there should be more data to be
|
||||
// sent before the application should react.
|
||||
|
||||
class AsyncClient;
|
||||
|
||||
typedef std::function<void(void*, AsyncClient*)> AcConnectHandler;
|
||||
typedef std::function<void(void*, AsyncClient*, size_t len, uint32_t time)>
|
||||
AcAckHandler;
|
||||
typedef std::function<void(void*, AsyncClient*, int8_t error)> AcErrorHandler;
|
||||
typedef std::function<void(void*, AsyncClient*, void* data, size_t len)>
|
||||
AcDataHandler;
|
||||
typedef std::function<void(void*, AsyncClient*, struct pbuf* pb)>
|
||||
AcPacketHandler;
|
||||
typedef std::function<void(void*, AsyncClient*, uint32_t time)>
|
||||
AcTimeoutHandler;
|
||||
|
||||
class AsyncServer;
|
||||
|
||||
class AsyncClient {
|
||||
public:
|
||||
AsyncClient() {}
|
||||
|
||||
AsyncClient(AsyncServer* server) : mServer(server) {}
|
||||
|
||||
void setNoDelay(bool nodelay) {}
|
||||
void setRxTimeout(uint32_t timeout) {}
|
||||
void onData(AcDataHandler cb, void* arg = 0) {_recv_cb = cb;}
|
||||
void onAck(AcAckHandler cb, void* arg = 0) { _sent_cb = cb; }
|
||||
void onError(AcErrorHandler cb, void* arg = 0) {}
|
||||
void onDisconnect(AcConnectHandler cb, void* arg = 0) {_discard_cb = cb;}
|
||||
void onConnect(AcConnectHandler cb, void* arg = 0) { _connect_cb = cb; }
|
||||
|
||||
const char* errorToString(int err) { return ""; }
|
||||
|
||||
bool connected() { return mOther; }
|
||||
|
||||
bool canSend() { return true; }
|
||||
void ack(int len) {
|
||||
if (_sent_cb)
|
||||
_sent_cb(NULL, this, len, 0);
|
||||
}
|
||||
void close(bool now = false) {
|
||||
/*if (mOther && mOther->_discard_cb) {
|
||||
mOther->_discard_cb(NULL, this);
|
||||
mOther = NULL;
|
||||
}
|
||||
mServer = NULL;*/
|
||||
}
|
||||
bool connect(IPAddress ip, uint16_t port);
|
||||
size_t space() { return 1000; }
|
||||
bool send() { return true; }
|
||||
size_t write(const char* data, size_t size,
|
||||
uint8_t apiflags = ASYNC_WRITE_FLAG_COPY) {
|
||||
char* cpy[size];
|
||||
memcpy(&cpy, data, size);
|
||||
void * arg = NULL;
|
||||
if (mOther && mOther->_recv_cb) {
|
||||
mOther->_recv_cb(arg, mOther, cpy, size);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
bool freeable() { return true; }
|
||||
int8_t abort() { return 0; }
|
||||
bool free() { return true; }
|
||||
|
||||
bool operator==(const AsyncClient &other) {
|
||||
return mOther == other.mOther;
|
||||
}
|
||||
|
||||
protected:
|
||||
AsyncServer* mServer = NULL;
|
||||
AsyncClient* mOther = NULL;
|
||||
AcConnectHandler _connect_cb = NULL;
|
||||
AcConnectHandler _discard_cb = NULL;
|
||||
AcDataHandler _recv_cb = NULL;
|
||||
AcAckHandler _sent_cb = NULL;
|
||||
};
|
||||
|
||||
class AsyncServer : public AsyncClient {
|
||||
public:
|
||||
AsyncServer() {}
|
||||
AsyncServer(uint16_t port) {}
|
||||
void onClient(AcConnectHandler cb, void* arg = 0) { _connect_cb = cb; }
|
||||
void begin() {}
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
WL_NO_SHIELD = 255, // for compatibility with WiFi Shield library
|
||||
WL_IDLE_STATUS = 0,
|
||||
WL_NO_SSID_AVAIL = 1,
|
||||
WL_SCAN_COMPLETED = 2,
|
||||
WL_CONNECTED = 3,
|
||||
WL_CONNECT_FAILED = 4,
|
||||
WL_CONNECTION_LOST = 5,
|
||||
WL_DISCONNECTED = 6
|
||||
} wl_status_t;
|
||||
|
||||
class WiFiClass {
|
||||
public:
|
||||
void disconnect() {}
|
||||
auto status() {
|
||||
return WL_CONNECTED;
|
||||
}
|
||||
};
|
||||
|
||||
class ESPClass {
|
||||
public:
|
||||
size_t getFreeHeap() { return 1e6; }
|
||||
};
|
||||
|
||||
inline bool AsyncClient::connect(IPAddress ip, uint16_t port) {
|
||||
this->mOther = new AsyncClient();
|
||||
this->mOther->mOther = this;
|
||||
void * arg = NULL;
|
||||
if (mServer->_connect_cb)
|
||||
mServer->_connect_cb(arg, this->mOther);
|
||||
if (this->_connect_cb)
|
||||
this->_connect_cb(arg, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
DSM2_tx implements the serial communication protocol used for operating
|
||||
the RF modules that can be found in many DSM2-compatible transmitters.
|
||||
Copyrigt (C) 2012 Erik Elmore <erik@ironsavior.net>
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class FakeSerial {
|
||||
public:
|
||||
void begin(unsigned long);
|
||||
void end();
|
||||
size_t write(const unsigned char*, size_t);
|
||||
void print(const char*);
|
||||
void println();
|
||||
};
|
||||
|
||||
extern FakeSerial Serial;
|
||||
Reference in New Issue
Block a user