Made this lib compatible with esp-idf components system

This commit is contained in:
feedc0de committed 2021-02-04 01:57:20 +01:00
1 parent 1c7e556e7e
commit 471b524df2
16 files changed
+36 -502

No files matched your search

+33
View File
@@ -0,0 +1,33 @@
#pragma once
// espressif includes
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
#include <freertos/task.h>
// local includes
#include "cppmacros.h"
namespace espcpputils {
class binary_semaphore
{
CPP_DISABLE_COPY_MOVE(binary_semaphore)
public:
binary_semaphore() :
handle{xSemaphoreCreateBinary()}
{}
~binary_semaphore() { if (handle) vSemaphoreDelete(handle); }
TaskHandle_t getMutexHolder() const { return xSemaphoreGetMutexHolder(handle); }
UBaseType_t getCount() const { return uxSemaphoreGetCount(handle); }
bool take(TickType_t xTicksToWait) { return xSemaphoreTake(handle, xTicksToWait); }
bool give() { return xSemaphoreGive(handle); }
const SemaphoreHandle_t handle;
};
} // namespace espcpputils
+33
View File
@@ -0,0 +1,33 @@
#pragma once
// espressif includes
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
#include <freertos/task.h>
// local includes
#include "cppmacros.h"
namespace espcpputils {
class counting_semaphore
{
CPP_DISABLE_COPY_MOVE(counting_semaphore)
public:
counting_semaphore(UBaseType_t uxMaxCount, UBaseType_t uxInitialCount) :
handle{xSemaphoreCreateCounting(uxMaxCount, uxInitialCount)}
{}
~counting_semaphore() { if (handle) vSemaphoreDelete(handle); }
TaskHandle_t getMutexHolder() const { return xSemaphoreGetMutexHolder(handle); }
UBaseType_t getCount() const { return uxSemaphoreGetCount(handle); }
bool take(TickType_t xTicksToWait) { return xSemaphoreTake(handle, xTicksToWait); }
bool give() { return xSemaphoreGive(handle); }
const SemaphoreHandle_t handle;
};
} // namespace espcpputils
+43
View File
@@ -0,0 +1,43 @@
#pragma once
// system includes
#include <limits>
#include <random>
#include <iterator>
// esp-idf includes
#include <esp_system.h>
namespace espcpputils {
namespace {
class esp_random_device
{
public:
using result_type = decltype(esp_random()); // should be uint32_t
result_type operator()() const { return esp_random(); }
double entropy() const { return 1.; }
static result_type min() { return std::numeric_limits<result_type>::min(); }
static result_type max() { return std::numeric_limits<result_type>::max(); }
};
std::string randomString(std::size_t length)
{
static constexpr const char chars[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
auto rng = esp_random_device{};
auto dist = std::uniform_int_distribution{{}, std::size(chars) - 1};
auto result = std::string(length, '\0');
std::generate_n(std::begin(result), length, [&]() { return chars[dist(rng)]; });
return result;
}
} // namespace
} // namespace espcpputils
+36
View File
@@ -0,0 +1,36 @@
#pragma once
// espressif includes
#include <freertos/FreeRTOS.h>
#include <freertos/event_groups.h>
// local includes
#include "cppmacros.h"
namespace espcpputils {
class event_group
{
CPP_DISABLE_COPY_MOVE(event_group)
public:
event_group() :
handle{xEventGroupCreate()}
{}
~event_group() { if (handle) vEventGroupDelete(handle); }
EventBits_t waitBits(const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait)
{ return xEventGroupWaitBits(handle, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait); }
EventBits_t clearBits(const EventBits_t uxBitsToClear) { return xEventGroupClearBits(handle, uxBitsToClear); }
EventBits_t setBits(const EventBits_t uxBitsToSet) { return xEventGroupSetBits(handle, uxBitsToSet); }
EventBits_t groupSync(const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait)
{ return xEventGroupSync(handle, uxBitsToSet, uxBitsToWaitFor, xTicksToWait); }
EventBits_t getBits() const { return xEventGroupClearBits(handle, 0); }
const EventGroupHandle_t handle;
};
} // namespace espcpputils
+77
View File
@@ -0,0 +1,77 @@
#pragma once
// espressif includes
#include <esp_http_client.h>
// local includes
#include "cppmacros.h"
namespace espcpputils {
class http_client
{
CPP_DISABLE_COPY_MOVE(http_client)
public:
http_client(const esp_http_client_config_t *config) :
handle{esp_http_client_init(config)}
{}
~http_client() { if (handle) esp_http_client_cleanup(handle); }
esp_err_t perform() { return esp_http_client_perform(handle); }
esp_err_t set_url(const char *url) { return esp_http_client_set_url(handle, url); }
esp_err_t set_post_field(const char *data, int len) { return esp_http_client_set_post_field(handle, data, len); }
int get_post_field(char **data) { return esp_http_client_get_post_field(handle, data); }
esp_err_t set_header(const char *key, const char *value) { return esp_http_client_set_header(handle, key, value); }
esp_err_t get_header(const char *key, char **value) { return esp_http_client_get_header(handle, key, value); }
esp_err_t get_username(char **value) { return esp_http_client_get_username(handle, value); }
esp_err_t set_username(const char *username) { return esp_http_client_set_username(handle, username); }
esp_err_t get_password(char **value) { return esp_http_client_get_password(handle, value); }
esp_err_t set_password(char *password) { return esp_http_client_set_password(handle, password); }
esp_err_t set_method(esp_http_client_method_t method) { return esp_http_client_set_method(handle, method); }
esp_err_t delete_header(const char *key) { return esp_http_client_delete_header(handle, key); }
esp_err_t open(int write_len) { return esp_http_client_open(handle, write_len); }
int write(const char *buffer, int len) { return esp_http_client_write(handle, buffer, len); }
int fetch_headers() { return esp_http_client_fetch_headers(handle); }
bool is_chunked_response() const { return esp_http_client_is_chunked_response(handle); }
int read(char *buffer, int len) { return esp_http_client_read(handle, buffer, len); }
int get_status_code() const { return esp_http_client_get_status_code(handle); }
int get_content_length() const { return esp_http_client_get_content_length(handle); }
esp_err_t close() { return esp_http_client_close(handle); }
esp_http_client_transport_t get_transport_type() const { return esp_http_client_get_transport_type(handle); }
esp_err_t set_redirection() { return esp_http_client_set_redirection(handle); }
void add_auth() { return esp_http_client_add_auth(handle); }
bool is_complete_data_received() const { return esp_http_client_is_complete_data_received(handle); }
static esp_http_client_config_t zeroInitializedConfig()
{
return esp_http_client_config_t {
.url = {},
.host = {},
.port = {},
.username = {},
.password = {},
.auth_type = {},
.path = {},
.query = {},
.cert_pem = {},
.client_cert_pem = {},
.client_key_pem = {},
.method = {},
.timeout_ms = {},
.disable_auto_redirect = {},
.max_redirection_count = {},
.event_handler = {},
.transport_type = {},
.buffer_size = {},
.buffer_size_tx = {},
.user_data = {},
.is_async = {},
.use_global_ca_store = {},
.skip_cert_common_name_check = {}
};
}
const esp_http_client_handle_t handle;
};
} // namespace espcpputils
+52
View File
@@ -0,0 +1,52 @@
#pragma once
// espressif includes
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
// local includes
#include "cppmacros.h"
namespace espcpputils {
class LockHelper
{
CPP_DISABLE_COPY_MOVE(LockHelper)
public:
LockHelper(QueueHandle_t _xMutex, TickType_t xTicksToWait=portMAX_DELAY) :
xMutex{_xMutex}
{
locked = xSemaphoreTakeRecursive(xMutex, xTicksToWait);
}
~LockHelper()
{
if (locked)
xSemaphoreGiveRecursive(xMutex);
}
bool lock(TickType_t xTicksToWait=portMAX_DELAY)
{
if (locked)
return false;
locked = xSemaphoreTakeRecursive(xMutex, xTicksToWait);
return locked;
}
bool unlock()
{
if (!locked)
return false;
locked = !xSemaphoreGiveRecursive(xMutex);
return locked;
}
private:
const QueueHandle_t xMutex;
bool locked;
};
} // namespace espcpputils
+71
View File
@@ -0,0 +1,71 @@
#pragma once
// system includes
#include <optional>
#include <queue>
// espressif includes
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
// local includes
#include "delayedconstruction.h"
#include "recursive_mutex_semaphore.h"
#include "recursivelockhelper.h"
namespace espcpputils {
template<typename T>
class LockingQueue
{
public:
void push(const T &val);
void push(T &&val);
std::optional<T> tryPop();
void clear();
std::size_t size() const { return m_size; }
private:
espcpputils::recursive_mutex_semaphore m_lock;
std::queue<T> m_queue;
std::size_t m_size{}; // double-buffered to allow for reading without taking a lock
};
template<typename T>
void LockingQueue<T>::push(const T &val)
{
RecursiveLockHelper helper{m_lock.handle};
m_queue.push(val);
m_size = m_queue.size();
}
template<typename T>
void LockingQueue<T>::push(T &&val)
{
RecursiveLockHelper helper{m_lock.handle};
m_queue.emplace(std::move(val));
m_size = m_queue.size();
}
template<typename T>
std::optional<T> LockingQueue<T>::tryPop()
{
RecursiveLockHelper helper{m_lock.handle};
if (m_queue.empty())
return std::nullopt;
std::optional<T> temp = std::move(m_queue.front());
m_queue.pop();
m_size = m_queue.size();
return temp;
}
template<typename T>
void LockingQueue<T>::clear()
{
RecursiveLockHelper helper{m_lock.handle};
m_queue.clear();
}
} // namespace espcpputils
+33
View File
@@ -0,0 +1,33 @@
#pragma once
// espressif includes
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
#include <freertos/task.h>
// local includes
#include "cppmacros.h"
namespace espcpputils {
class mutex_semaphore
{
CPP_DISABLE_COPY_MOVE(mutex_semaphore)
public:
mutex_semaphore() :
handle{xSemaphoreCreateMutex()}
{}
~mutex_semaphore() { if (handle) vSemaphoreDelete(handle); }
TaskHandle_t getMutexHolder() const { return xSemaphoreGetMutexHolder(handle); }
UBaseType_t getCount() const { return uxSemaphoreGetCount(handle); }
bool take(TickType_t xTicksToWait) { return xSemaphoreTake(handle, xTicksToWait); }
bool give() { return xSemaphoreGive(handle); }
const SemaphoreHandle_t handle;
};
} // namespace espcpputils
+33
View File
@@ -0,0 +1,33 @@
#pragma once
// espressif includes
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
#include <freertos/task.h>
// local includes
#include "cppmacros.h"
namespace espcpputils {
class recursive_mutex_semaphore
{
CPP_DISABLE_COPY_MOVE(recursive_mutex_semaphore)
public:
recursive_mutex_semaphore() :
handle{xSemaphoreCreateRecursiveMutex()}
{}
~recursive_mutex_semaphore() { if (handle) vSemaphoreDelete(handle); }
TaskHandle_t getMutexHolder() const { return xSemaphoreGetMutexHolder(handle); }
UBaseType_t getCount() const { return uxSemaphoreGetCount(handle); }
bool takeRecursive(TickType_t xTicksToWait) { return xSemaphoreTakeRecursive(handle, xTicksToWait); }
bool giveRecursive() { return xSemaphoreGiveRecursive(handle); }
const SemaphoreHandle_t handle;
};
} // namespace espcpputils
+52
View File
@@ -0,0 +1,52 @@
#pragma once
// espressif includes
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
// local includes
#include "cppmacros.h"
namespace espcpputils {
class RecursiveLockHelper
{
CPP_DISABLE_COPY_MOVE(RecursiveLockHelper)
public:
RecursiveLockHelper(QueueHandle_t _xMutex, TickType_t xTicksToWait=portMAX_DELAY) :
xMutex{_xMutex}
{
locked = xSemaphoreTakeRecursive(xMutex, xTicksToWait);
}
~RecursiveLockHelper()
{
if (locked)
xSemaphoreGiveRecursive(xMutex);
}
bool lock(TickType_t xTicksToWait=portMAX_DELAY)
{
if (locked)
return false;
locked = xSemaphoreTakeRecursive(xMutex, xTicksToWait);
return locked;
}
bool unlock()
{
if (!locked)
return false;
locked = !xSemaphoreGiveRecursive(xMutex);
return locked;
}
private:
const QueueHandle_t xMutex;
bool locked;
};
} // namespace espcpputils
+36
View File
@@ -0,0 +1,36 @@
#pragma once
// espressif includes
#include <esp_websocket_client.h>
// local includes
#include "cppmacros.h"
namespace espcpputils {
class websocket_client
{
CPP_DISABLE_COPY_MOVE(websocket_client)
public:
websocket_client(const esp_websocket_client_config_t &config) :
handle{esp_websocket_client_init(&config)}
{
}
~websocket_client() { if (handle) esp_websocket_client_destroy(handle); }
esp_err_t set_uri (const char *uri) { return esp_websocket_client_set_uri (handle, uri); }
esp_err_t start () { return esp_websocket_client_start (handle); }
esp_err_t stop () { return esp_websocket_client_stop (handle); }
int send (const char *data, int len, TickType_t timeout) { return esp_websocket_client_send (handle, data, len, timeout); }
int send_bin (const char *data, int len, TickType_t timeout) { return esp_websocket_client_send_bin (handle, data, len, timeout); }
int send_text (const char *data, int len, TickType_t timeout) { return esp_websocket_client_send_text (handle, data, len, timeout); }
//esp_err_t close (TickType_t timeout) { return esp_websocket_client_close (handle, timeout); }
//esp_err_t close_with_code(int code, const char *data, int len, TickType_t timeout) { return esp_websocket_client_close_with_code(handle, code, data, len, timeout); }
bool is_connected () const { return esp_websocket_client_is_connected (handle); }
esp_err_t register_events(esp_websocket_event_id_t event, esp_event_handler_t event_handler, void *event_handler_arg)
{ return esp_websocket_register_events(handle, event, event_handler, event_handler_arg); }
const esp_websocket_client_handle_t handle;
};
} // namespace espcpputils