From d64031d710081641247f1512cd016c5cef5204f9 Mon Sep 17 00:00:00 2001 From: technyon Date: Thu, 25 Jul 2024 13:26:01 +0200 Subject: [PATCH] update espMqttClient --- .../.github/ISSUE_TEMPLATE/bug_report.md | 34 -- lib/espMqttClient/.github/etc/mosquitto.conf | 2 - .../.github/workflows/arduino-lint.yml | 9 - .../.github/workflows/build_arduino-ide.yml | 62 --- .../.github/workflows/build_platformio.yml | 90 ---- .../.github/workflows/cppcheck.yml | 22 - .../.github/workflows/cpplint.yml | 22 - .../.github/workflows/test_platformio.yml | 29 -- lib/espMqttClient/.gitignore | 5 - lib/espMqttClient/src/MemoryPool/README.md | 210 ++++---- lib/espMqttClient/src/MemoryPool/keywords.txt | 32 +- lib/espMqttClient/src/MemoryPool/library.json | 40 +- .../src/MemoryPool/library.properties | 18 +- lib/espMqttClient/src/MemoryPool/src/Fixed.h | 238 ++++----- .../src/MemoryPool/src/MemoryPool.h | 24 +- .../src/MemoryPool/src/Variable.h | 484 +++++++++--------- lib/espMqttClient/src/MqttClientSetup.h | 4 +- .../src/Transport/ClientPosix.cpp | 54 +- lib/espMqttClient/src/Transport/ClientPosix.h | 5 +- .../src/Transport/ClientPosixIPAddress.cpp | 8 + .../src/Transport/ClientPosixIPAddress.h | 4 +- .../test_client_native/test_client_native.cpp | 5 +- 22 files changed, 589 insertions(+), 812 deletions(-) delete mode 100644 lib/espMqttClient/.github/ISSUE_TEMPLATE/bug_report.md delete mode 100644 lib/espMqttClient/.github/etc/mosquitto.conf delete mode 100644 lib/espMqttClient/.github/workflows/arduino-lint.yml delete mode 100644 lib/espMqttClient/.github/workflows/build_arduino-ide.yml delete mode 100644 lib/espMqttClient/.github/workflows/build_platformio.yml delete mode 100644 lib/espMqttClient/.github/workflows/cppcheck.yml delete mode 100644 lib/espMqttClient/.github/workflows/cpplint.yml delete mode 100644 lib/espMqttClient/.github/workflows/test_platformio.yml delete mode 100644 lib/espMqttClient/.gitignore diff --git a/lib/espMqttClient/.github/ISSUE_TEMPLATE/bug_report.md b/lib/espMqttClient/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 4eeb3bb..0000000 --- a/lib/espMqttClient/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve espMqttClient -title: "[BUG]" -labels: '' -assignees: '' - ---- - -#### Do not use to discuss topics! - -**Describe the bug** -A clear and concise description of what the bug is. - -Which platform, esp8266 or esp32? -Do you use TLS or not? -Do you use an IDE (Arduino, Platformio...)? -Which version of the Arduino framework? - -Please include any debug output and/or decoded stack trace if applicable. - -**Expected behaviour** -A clear and concise description of what you expected to happen. - -**To Reproduce** -Steps to reproduce the behaviour: - -**Example code** -```cpp -// Put code here to reproduce the bug, if possible -``` - -**Additional context** -Add any other context about the problem here. diff --git a/lib/espMqttClient/.github/etc/mosquitto.conf b/lib/espMqttClient/.github/etc/mosquitto.conf deleted file mode 100644 index daa4137..0000000 --- a/lib/espMqttClient/.github/etc/mosquitto.conf +++ /dev/null @@ -1,2 +0,0 @@ -listener 1883 -allow_anonymous true \ No newline at end of file diff --git a/lib/espMqttClient/.github/workflows/arduino-lint.yml b/lib/espMqttClient/.github/workflows/arduino-lint.yml deleted file mode 100644 index 3c1a16d..0000000 --- a/lib/espMqttClient/.github/workflows/arduino-lint.yml +++ /dev/null @@ -1,9 +0,0 @@ -name: Arduino Lint - -on: [push, pull_request] -jobs: - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: arduino/arduino-lint-action@v1 diff --git a/lib/espMqttClient/.github/workflows/build_arduino-ide.yml b/lib/espMqttClient/.github/workflows/build_arduino-ide.yml deleted file mode 100644 index 0c06d50..0000000 --- a/lib/espMqttClient/.github/workflows/build_arduino-ide.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: Build with Arduino IDE -on: - - push - - pull_request - -jobs: - build-for-esp8266: - runs-on: ubuntu-latest - - strategy: - matrix: - fqbn: - - esp8266:esp8266:generic - - steps: - - uses: actions/checkout@v3 - - uses: arduino/compile-sketches@v1 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - fqbn: ${{ matrix.fqbn }} - enable-deltas-report: true - platforms: | - - name: esp8266:esp8266 - source-url: https://arduino.esp8266.com/stable/package_esp8266com_index.json - sketch-paths: | - - examples/largepayload-esp8266 - - examples/simple-esp8266 - - examples/simpleAsync-esp8266 - - examples/tls-esp8266 - libraries: | - - name: espMqttClient - source-path: ./ - - name: ESPAsyncTCP - source-url: https://github.com/me-no-dev/ESPAsyncTCP.git - - build-for-esp32: - runs-on: ubuntu-latest - - strategy: - matrix: - fqbn: - - esp32:esp32:esp32 - - steps: - - uses: actions/checkout@v3 - - uses: arduino/compile-sketches@v1 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - fqbn: ${{ matrix.fqbn }} - enable-deltas-report: true - platforms: | - - name: esp32:esp32 - source-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json - sketch-paths: | - - examples/simple-esp32 - - examples/simpleAsync-esp32 - - examples/tls-esp32 - libraries: | - - name: espMqttClient - source-path: ./ - - name: AsyncTCP - source-url: https://github.com/me-no-dev/AsyncTCP.git diff --git a/lib/espMqttClient/.github/workflows/build_platformio.yml b/lib/espMqttClient/.github/workflows/build_platformio.yml deleted file mode 100644 index b1a139c..0000000 --- a/lib/espMqttClient/.github/workflows/build_platformio.yml +++ /dev/null @@ -1,90 +0,0 @@ -name: Build with Platformio - -on: [push, pull_request] - -jobs: - build-for-esp8266: - runs-on: ubuntu-latest - strategy: - matrix: - example: [ - examples/largepayload-esp8266/largepayload-esp8266.ino, - examples/ota-esp8266/ota-esp8266.ino, - examples/simple-esp8266/simple-esp8266.ino, - examples/simpleAsync-esp8266/simpleAsync-esp8266.ino, - examples/tls-esp8266/tls-esp8266.ino - ] - steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 - with: - path: | - ~/.cache/pip - ~/.platformio/.cache - key: ${{ runner.os }}-pio - - uses: actions/setup-python@v4 - with: - python-version: '3.9' - - name: Install PlatformIO Core - run: pip install --upgrade platformio - - name: Download external libraries - run: pio pkg install --global --library me-no-dev/ESPAsyncTCP - - name: Build PlatformIO examples - run: pio ci --lib="." --board=d1_mini - env: - PLATFORMIO_CI_SRC: ${{ matrix.example }} - - build-for-esp32: - runs-on: ubuntu-latest - strategy: - matrix: - example: [ - examples/notask-esp32/notask-esp32.ino, - examples/simple-esp32/simple-esp32.ino, - examples/simpleAsync-esp32/simpleAsync-esp32.ino, - examples/tls-esp32/tls-esp32.ino - ] - steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 - with: - path: | - ~/.cache/pip - ~/.platformio/.cache - key: ${{ runner.os }}-pio - - uses: actions/setup-python@v4 - with: - python-version: '3.9' - - name: Install PlatformIO Core - run: pip install --upgrade platformio - - name: Download external libraries - run: pio pkg install --global --library me-no-dev/AsyncTCP - - name: Build PlatformIO examples - run: pio ci --lib="." --board=lolin32 - env: - PLATFORMIO_CI_SRC: ${{ matrix.example }} - - build-for-linux: - runs-on: ubuntu-latest - strategy: - matrix: - example: [ - examples/simple-linux/main.cpp - ] - steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 - with: - path: | - ~/.cache/pip - ~/.platformio/.cache - key: ${{ runner.os }}-pio - - uses: actions/setup-python@v4 - with: - python-version: '3.9' - - name: Install PlatformIO Core - run: pip install --upgrade platformio - - name: Build PlatformIO examples - run: pio ci --lib="." --project-conf="./examples/simple-linux/platformio.ini" - env: - PLATFORMIO_CI_SRC: ${{ matrix.example }} diff --git a/lib/espMqttClient/.github/workflows/cppcheck.yml b/lib/espMqttClient/.github/workflows/cppcheck.yml deleted file mode 100644 index cd02b46..0000000 --- a/lib/espMqttClient/.github/workflows/cppcheck.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Cppcheck - -on: [push, pull_request] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.10' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install platformio - - name: Cppcheck - run: | - pio check --fail-on-defect=medium --fail-on-defect=high --flags "--inline-suppr --enable=warning --enable=style --enable=performance --suppress=unusedFunction --suppress=preprocessorErrorDirective" --skip-packages \ No newline at end of file diff --git a/lib/espMqttClient/.github/workflows/cpplint.yml b/lib/espMqttClient/.github/workflows/cpplint.yml deleted file mode 100644 index 36f64d5..0000000 --- a/lib/espMqttClient/.github/workflows/cpplint.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: cpplint - -on: [push, pull_request] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.10' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install cpplint - - name: Linting - run: | - cpplint --repository=. --recursive --filter=-whitespace/line_length,-build/include ./src \ No newline at end of file diff --git a/lib/espMqttClient/.github/workflows/test_platformio.yml b/lib/espMqttClient/.github/workflows/test_platformio.yml deleted file mode 100644 index 6a088b0..0000000 --- a/lib/espMqttClient/.github/workflows/test_platformio.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Test with Platformio - -on: [push, pull_request] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.10' - - name: Install dependencies - run: | - sudo apt update && sudo apt install -y valgrind - python -m pip install --upgrade pip - pip install platformio - - name: Start Mosquitto - uses: namoshek/mosquitto-github-action@v1 - with: - version: '2.0' - ports: '1883:1883' - config: ${{ github.workspace }}/.github/etc/mosquitto.conf - - name: Test - run: | - pio test -e native -v \ No newline at end of file diff --git a/lib/espMqttClient/.gitignore b/lib/espMqttClient/.gitignore deleted file mode 100644 index 00649df..0000000 --- a/lib/espMqttClient/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.pio -.vscode -cov -*cov.info -.idea diff --git a/lib/espMqttClient/src/MemoryPool/README.md b/lib/espMqttClient/src/MemoryPool/README.md index 7363e77..81b6fd4 100644 --- a/lib/espMqttClient/src/MemoryPool/README.md +++ b/lib/espMqttClient/src/MemoryPool/README.md @@ -1,105 +1,105 @@ -# Memory Pool - -EARLY VERSION. USE AT OWN RISK. - -### Description - -This is a simple memory pool that doesn't solve the fragmentation problem but contains it. Inside the pool you will still suffer memory fragmentation. The upside is that you're not restricted on memory size. As long as it fits in the pool, you can request any size! - -For applications where the (maximum) size to allocate is known, a simple fixed block size memory pool is available. There is no memory fragmentation happening in this case. The downside is wastage of memory if you need less then the specified blocksize. - -#### Features - -- pool memory is statically allocated -- pool size adjusts on architecture -- no size calculation required: input number of blocks and size of block -- header-only library -- Variable size pool: no restriction on allocated size -- Variable size pool: malloc and free are O(n); The number of allocated blocks affects lookup. -- Fixed size pool: malloc and free are O(1). - -[![Test with Platformio](https://github.com/bertmelis/MemoryPool/actions/workflows/test-platformio.yml/badge.svg)](https://github.com/bertmelis/MemoryPool/actions/workflows/test-platformio.yml) -[![cpplint](https://github.com/bertmelis/MemoryPool/actions/workflows/cpplint.yml/badge.svg)](https://github.com/bertmelis/MemoryPool/actions/workflows/cpplint.yml) - - -### Usage - -#### Variable size pool - -```cpp -#include - -Struct MyStruct { - unsigned int id; - std::size_t size; - unsigned char data[256]; -}; - -// pool will be able to hold 10 blocks the size of MyStruct -MemoryPool::Variable<10, sizeof(MyStruct)> pool; - -// you can allocate the specified blocksize -// allocation is done in number of 'unsigned char' -MyStruct* s = reinterpret_cast(pool.malloc(sizeof(MyStruct))); - -// you can allocate less than the specified blocksize -int* i = reinterpret_cast(pool.malloc(sizeof(int))); - -// you can allocate more than the specified blocksize -unsigned char* m = reinterpret_cast(pool.malloc(400)); - -pool.free(s); -pool.free(i); -pool.free(m); -``` - -#### Fixed size pool - -```cpp -#include - -Struct MyStruct { - unsigned int id; - std::size_t size; - unsigned char data[256]; -}; - -// pool will be able to hold 10 blocks the size of MyStruct -MemoryPool::Fixed<10, sizeof(MyStruct)> pool; - -// there is no size argument in the malloc function! -MyStruct* s = reinterpret_cast(pool.malloc()); - -// you can allocate less than the specified blocksize -int* i = reinterpret_cast(pool.malloc()); - -pool.free(s); -pool.free(i); -``` - -#### How it works - -##### Variable size pool - -Free blocks are organized as a linked list with their header (contains pointer to next and size). An allocated block also has this header with it's pointer set to `nullptr`. Therefore, each allocation wastes memory the size of the header (`sizeof(void*) + sizeof(std::size_t)`). On creation, the pool calculations the needed space to store the number of blocks wich each their header. - -However, memory allocation isn't restricted the the specified blocksize. So in reality, you can allocate more if you allocate larger chunks because less memory blocks means less headers. After all, memory needs to be contiguous. - -If you inspect the pool you'll see that a free pool only has one big block. - -Allocation is linear: the pool is iterated until a suitable spot is found. -Freeing is also linear as the pool is traversed to insert the chunk in the linked list of free blocks - -When freeing, free blocks which are adjacent are combined into one. - -##### Fixed size pool - -The fixed size pool is implemented as an array. Free blocks are saved as a linked list in this array. - -### Bugs and feature requests - -Please use Github's facilities to get in touch. - -### License - -This library is released under the MIT Licence. A copy is included in the repo. +# Memory Pool + +EARLY VERSION. USE AT OWN RISK. + +### Description + +This is a simple memory pool that doesn't solve the fragmentation problem but contains it. Inside the pool you will still suffer memory fragmentation. The upside is that you're not restricted on memory size. As long as it fits in the pool, you can request any size! + +For applications where the (maximum) size to allocate is known, a simple fixed block size memory pool is available. There is no memory fragmentation happening in this case. The downside is wastage of memory if you need less then the specified blocksize. + +#### Features + +- pool memory is statically allocated +- pool size adjusts on architecture +- no size calculation required: input number of blocks and size of block +- header-only library +- Variable size pool: no restriction on allocated size +- Variable size pool: malloc and free are O(n); The number of allocated blocks affects lookup. +- Fixed size pool: malloc and free are O(1). + +[![Test with Platformio](https://github.com/bertmelis/MemoryPool/actions/workflows/test-platformio.yml/badge.svg)](https://github.com/bertmelis/MemoryPool/actions/workflows/test-platformio.yml) +[![cpplint](https://github.com/bertmelis/MemoryPool/actions/workflows/cpplint.yml/badge.svg)](https://github.com/bertmelis/MemoryPool/actions/workflows/cpplint.yml) + + +### Usage + +#### Variable size pool + +```cpp +#include + +Struct MyStruct { + unsigned int id; + std::size_t size; + unsigned char data[256]; +}; + +// pool will be able to hold 10 blocks the size of MyStruct +MemoryPool::Variable<10, sizeof(MyStruct)> pool; + +// you can allocate the specified blocksize +// allocation is done in number of 'unsigned char' +MyStruct* s = reinterpret_cast(pool.malloc(sizeof(MyStruct))); + +// you can allocate less than the specified blocksize +int* i = reinterpret_cast(pool.malloc(sizeof(int))); + +// you can allocate more than the specified blocksize +unsigned char* m = reinterpret_cast(pool.malloc(400)); + +pool.free(s); +pool.free(i); +pool.free(m); +``` + +#### Fixed size pool + +```cpp +#include + +Struct MyStruct { + unsigned int id; + std::size_t size; + unsigned char data[256]; +}; + +// pool will be able to hold 10 blocks the size of MyStruct +MemoryPool::Fixed<10, sizeof(MyStruct)> pool; + +// there is no size argument in the malloc function! +MyStruct* s = reinterpret_cast(pool.malloc()); + +// you can allocate less than the specified blocksize +int* i = reinterpret_cast(pool.malloc()); + +pool.free(s); +pool.free(i); +``` + +#### How it works + +##### Variable size pool + +Free blocks are organized as a linked list with their header (contains pointer to next and size). An allocated block also has this header with it's pointer set to `nullptr`. Therefore, each allocation wastes memory the size of the header (`sizeof(void*) + sizeof(std::size_t)`). On creation, the pool calculations the needed space to store the number of blocks wich each their header. + +However, memory allocation isn't restricted the the specified blocksize. So in reality, you can allocate more if you allocate larger chunks because less memory blocks means less headers. After all, memory needs to be contiguous. + +If you inspect the pool you'll see that a free pool only has one big block. + +Allocation is linear: the pool is iterated until a suitable spot is found. +Freeing is also linear as the pool is traversed to insert the chunk in the linked list of free blocks + +When freeing, free blocks which are adjacent are combined into one. + +##### Fixed size pool + +The fixed size pool is implemented as an array. Free blocks are saved as a linked list in this array. + +### Bugs and feature requests + +Please use Github's facilities to get in touch. + +### License + +This library is released under the MIT Licence. A copy is included in the repo. diff --git a/lib/espMqttClient/src/MemoryPool/keywords.txt b/lib/espMqttClient/src/MemoryPool/keywords.txt index 08db546..ef87ce2 100644 --- a/lib/espMqttClient/src/MemoryPool/keywords.txt +++ b/lib/espMqttClient/src/MemoryPool/keywords.txt @@ -1,16 +1,16 @@ -# Datatypes (KEYWORD1) -Fixed KEYWORD1 -Variable KEYWORD1 - -# Methods and Functions (KEYWORD2) -malloc KEYWORD2 -free KEYWORD2 -freeMemory KEYWORD2 -maxBlockSize KEYWORD2 -print KEYWORD2 - -# Structures (KEYWORD3) -# structure KEYWORD3 - -# Constants (LITERAL1) -MemoryPool LITERAL1 +# Datatypes (KEYWORD1) +Fixed KEYWORD1 +Variable KEYWORD1 + +# Methods and Functions (KEYWORD2) +malloc KEYWORD2 +free KEYWORD2 +freeMemory KEYWORD2 +maxBlockSize KEYWORD2 +print KEYWORD2 + +# Structures (KEYWORD3) +# structure KEYWORD3 + +# Constants (LITERAL1) +MemoryPool LITERAL1 diff --git a/lib/espMqttClient/src/MemoryPool/library.json b/lib/espMqttClient/src/MemoryPool/library.json index be2b63d..f9e6116 100644 --- a/lib/espMqttClient/src/MemoryPool/library.json +++ b/lib/espMqttClient/src/MemoryPool/library.json @@ -1,21 +1,21 @@ -{ - "name": "MemoryPool", - "keywords": "memory", - "description": "A simple memory pool for fixed and variable sizes", - "authors": - { - "name": "Bert Melis", - "url": "https://github.com/bertmelis" - }, - "license": "MIT", - "homepage": "https://github.com/bertmelis/MemoryPool", - "repository": - { - "type": "git", - "url": "https://github.com/bertmelis/MemoryPool.git" - }, - "version": "0.1.0", - "frameworks": "*", - "platforms": "*", - "headers": ["MemoryPool.h"] +{ + "name": "MemoryPool", + "keywords": "memory", + "description": "A simple memory pool for fixed and variable sizes", + "authors": + { + "name": "Bert Melis", + "url": "https://github.com/bertmelis" + }, + "license": "MIT", + "homepage": "https://github.com/bertmelis/MemoryPool", + "repository": + { + "type": "git", + "url": "https://github.com/bertmelis/MemoryPool.git" + }, + "version": "0.1.0", + "frameworks": "*", + "platforms": "*", + "headers": ["MemoryPool.h"] } \ No newline at end of file diff --git a/lib/espMqttClient/src/MemoryPool/library.properties b/lib/espMqttClient/src/MemoryPool/library.properties index 4c4a443..a46b50f 100644 --- a/lib/espMqttClient/src/MemoryPool/library.properties +++ b/lib/espMqttClient/src/MemoryPool/library.properties @@ -1,10 +1,10 @@ -name=MemoryPool -version=0.1.0 -author=Bert Melis -maintainer=Bert Melis -sentence=A simple memory pool for fixed and variable sizes -paragraph= -category=Other -url=https://github.com/bertmelis/MemoryPool -architectures=* +name=MemoryPool +version=0.1.0 +author=Bert Melis +maintainer=Bert Melis +sentence=A simple memory pool for fixed and variable sizes +paragraph= +category=Other +url=https://github.com/bertmelis/MemoryPool +architectures=* includes=MemoryPool.h \ No newline at end of file diff --git a/lib/espMqttClient/src/MemoryPool/src/Fixed.h b/lib/espMqttClient/src/MemoryPool/src/Fixed.h index d976b8f..b68dbd1 100644 --- a/lib/espMqttClient/src/MemoryPool/src/Fixed.h +++ b/lib/espMqttClient/src/MemoryPool/src/Fixed.h @@ -1,119 +1,119 @@ -/* -Copyright (c) 2024 Bert Melis. All rights reserved. - -This work is licensed under the terms of the MIT license. -For a copy, see or -the LICENSE file. -*/ - -#pragma once - -#include // std::size_t -#include // assert -#if _GLIBCXX_HAS_GTHREADS -#include // NOLINT [build/c++11] std::mutex, std::lock_guard -#else -#warning "The memory pool is not thread safe" -#endif - -#ifdef MEMPOL_DEBUG -#include -#endif - -namespace MemoryPool { - -template -class Fixed { - public: - Fixed() // cppcheck-suppress uninitMemberVar - : _buffer{0} - , _head(_buffer) { - unsigned char* b = _head; - std::size_t adjustedBlocksize = sizeof(std::size_t) > blocksize ? sizeof(std::size_t) : blocksize; - for (std::size_t i = 0; i < nrBlocks - 1; ++i) { - *reinterpret_cast(b) = b + adjustedBlocksize; - b += adjustedBlocksize; - } - *reinterpret_cast(b) = nullptr; - } - - // no copy nor move - Fixed (const Fixed&) = delete; - Fixed& operator= (const Fixed&) = delete; - - void* malloc() { - #if _GLIBCXX_HAS_GTHREADS - const std::lock_guard lockGuard(_mutex); - #endif - if (_head) { - void* retVal = _head; - _head = *reinterpret_cast(_head); - return retVal; - } - return nullptr; - } - - void free(void* ptr) { - if (!ptr) return; - #if _GLIBCXX_HAS_GTHREADS - const std::lock_guard lockGuard(_mutex); - #endif - *reinterpret_cast(ptr) = _head; - _head = reinterpret_cast(ptr); - } - - std::size_t freeMemory() { - #if _GLIBCXX_HAS_GTHREADS - const std::lock_guard lockGuard(_mutex); - #endif - unsigned char* i = _head; - std::size_t retVal = 0; - while (i) { - retVal += blocksize; - i = reinterpret_cast(i)[0]; - } - return retVal; - } - - #ifdef MEMPOL_DEBUG - void print() { - std::size_t adjustedBlocksize = sizeof(std::size_t) > blocksize ? sizeof(std::size_t) : blocksize; - std::cout << "+--------------------" << std::endl; - std::cout << "|start:" << reinterpret_cast(_buffer) << std::endl; - std::cout << "|blocks:" << nrBlocks << std::endl; - std::cout << "|blocksize:" << adjustedBlocksize << std::endl; - std::cout << "|head: " << reinterpret_cast(_head) << std::endl; - unsigned char* currentBlock = _buffer; - - for (std::size_t i = 0; i < nrBlocks; ++i) { - std::cout << "|" << i + 1 << ": " << reinterpret_cast(currentBlock) << std::endl; - if (_isFree(currentBlock)) { - std::cout << "| free" << std::endl; - std::cout << "| next: " << reinterpret_cast(*reinterpret_cast(currentBlock)) << std::endl; - } else { - std::cout << "| allocated" << std::endl; - } - currentBlock += adjustedBlocksize; - } - std::cout << "+--------------------" << std::endl; - } - - bool _isFree(const unsigned char* ptr) { - unsigned char* b = _head; - while (b) { - if (b == ptr) return true; - b = *reinterpret_cast(b); - } - return false; - } - #endif - - private: - unsigned char _buffer[nrBlocks * (sizeof(std::size_t) > blocksize ? sizeof(std::size_t) : blocksize)]; - unsigned char* _head; - #if _GLIBCXX_HAS_GTHREADS - std::mutex _mutex; - #endif -}; - -} // end namespace MemoryPool +/* +Copyright (c) 2024 Bert Melis. All rights reserved. + +This work is licensed under the terms of the MIT license. +For a copy, see or +the LICENSE file. +*/ + +#pragma once + +#include // std::size_t +#include // assert +#if _GLIBCXX_HAS_GTHREADS +#include // NOLINT [build/c++11] std::mutex, std::lock_guard +#else +#warning "The memory pool is not thread safe" +#endif + +#ifdef MEMPOL_DEBUG +#include +#endif + +namespace MemoryPool { + +template +class Fixed { + public: + Fixed() // cppcheck-suppress uninitMemberVar + : _buffer{0} + , _head(_buffer) { + unsigned char* b = _head; + std::size_t adjustedBlocksize = sizeof(std::size_t) > blocksize ? sizeof(std::size_t) : blocksize; + for (std::size_t i = 0; i < nrBlocks - 1; ++i) { + *reinterpret_cast(b) = b + adjustedBlocksize; + b += adjustedBlocksize; + } + *reinterpret_cast(b) = nullptr; + } + + // no copy nor move + Fixed (const Fixed&) = delete; + Fixed& operator= (const Fixed&) = delete; + + void* malloc() { + #if _GLIBCXX_HAS_GTHREADS + const std::lock_guard lockGuard(_mutex); + #endif + if (_head) { + void* retVal = _head; + _head = *reinterpret_cast(_head); + return retVal; + } + return nullptr; + } + + void free(void* ptr) { + if (!ptr) return; + #if _GLIBCXX_HAS_GTHREADS + const std::lock_guard lockGuard(_mutex); + #endif + *reinterpret_cast(ptr) = _head; + _head = reinterpret_cast(ptr); + } + + std::size_t freeMemory() { + #if _GLIBCXX_HAS_GTHREADS + const std::lock_guard lockGuard(_mutex); + #endif + unsigned char* i = _head; + std::size_t retVal = 0; + while (i) { + retVal += blocksize; + i = reinterpret_cast(i)[0]; + } + return retVal; + } + + #ifdef MEMPOL_DEBUG + void print() { + std::size_t adjustedBlocksize = sizeof(std::size_t) > blocksize ? sizeof(std::size_t) : blocksize; + std::cout << "+--------------------" << std::endl; + std::cout << "|start:" << reinterpret_cast(_buffer) << std::endl; + std::cout << "|blocks:" << nrBlocks << std::endl; + std::cout << "|blocksize:" << adjustedBlocksize << std::endl; + std::cout << "|head: " << reinterpret_cast(_head) << std::endl; + unsigned char* currentBlock = _buffer; + + for (std::size_t i = 0; i < nrBlocks; ++i) { + std::cout << "|" << i + 1 << ": " << reinterpret_cast(currentBlock) << std::endl; + if (_isFree(currentBlock)) { + std::cout << "| free" << std::endl; + std::cout << "| next: " << reinterpret_cast(*reinterpret_cast(currentBlock)) << std::endl; + } else { + std::cout << "| allocated" << std::endl; + } + currentBlock += adjustedBlocksize; + } + std::cout << "+--------------------" << std::endl; + } + + bool _isFree(const unsigned char* ptr) { + unsigned char* b = _head; + while (b) { + if (b == ptr) return true; + b = *reinterpret_cast(b); + } + return false; + } + #endif + + private: + unsigned char _buffer[nrBlocks * (sizeof(std::size_t) > blocksize ? sizeof(std::size_t) : blocksize)]; + unsigned char* _head; + #if _GLIBCXX_HAS_GTHREADS + std::mutex _mutex; + #endif +}; + +} // end namespace MemoryPool diff --git a/lib/espMqttClient/src/MemoryPool/src/MemoryPool.h b/lib/espMqttClient/src/MemoryPool/src/MemoryPool.h index af036fc..5b198ea 100644 --- a/lib/espMqttClient/src/MemoryPool/src/MemoryPool.h +++ b/lib/espMqttClient/src/MemoryPool/src/MemoryPool.h @@ -1,12 +1,12 @@ -/* -Copyright (c) 2024 Bert Melis. All rights reserved. - -This work is licensed under the terms of the MIT license. -For a copy, see or -the LICENSE file. -*/ - -#pragma once - -#include "Variable.h" -#include "Fixed.h" +/* +Copyright (c) 2024 Bert Melis. All rights reserved. + +This work is licensed under the terms of the MIT license. +For a copy, see or +the LICENSE file. +*/ + +#pragma once + +#include "Variable.h" +#include "Fixed.h" diff --git a/lib/espMqttClient/src/MemoryPool/src/Variable.h b/lib/espMqttClient/src/MemoryPool/src/Variable.h index 11483cc..563bf49 100644 --- a/lib/espMqttClient/src/MemoryPool/src/Variable.h +++ b/lib/espMqttClient/src/MemoryPool/src/Variable.h @@ -1,242 +1,242 @@ -/* -Copyright (c) 2024 Bert Melis. All rights reserved. - -This work is licensed under the terms of the MIT license. -For a copy, see or -the LICENSE file. -*/ - -#pragma once - -#include // std::size_t -#include // assert -#if _GLIBCXX_HAS_GTHREADS -#include // NOLINT [build/c++11] std::mutex, std::lock_guard -#else -#warning "The memory pool is not thread safe" -#endif - -#ifdef MEMPOL_DEBUG -#include -#endif - -namespace MemoryPool { - -template -class Variable { - public: - Variable() - : _buffer{0} - , _head(nullptr) - #ifdef MEMPOL_DEBUG - , _bufferSize(0) - #endif - { - std::size_t _normBlocksize = blocksize / sizeof(BlockHeader) + ((blocksize % sizeof(BlockHeader)) ? 1 : 0); - size_t nrBlocksToAlloc = nrBlocks * (_normBlocksize + 1); - BlockHeader* h = reinterpret_cast(_buffer); - h->next = nullptr; - h->size = nrBlocksToAlloc; - _head = h; - - #ifdef MEMPOL_DEBUG - _bufferSize = nrBlocksToAlloc; - #endif - } - - // no copy nor move - Variable (const Variable&) = delete; - Variable& operator= (const Variable&) = delete; - - void* malloc(size_t size) { - #if _GLIBCXX_HAS_GTHREADS - const std::lock_guard lockGuard(_mutex); - #endif - if (size == 0) return nullptr; - - size = (size / sizeof(BlockHeader) + (size % sizeof(BlockHeader) != 0)) + 1; // count by BlockHeader size, add 1 for header - - #ifdef MEMPOL_DEBUG - std::cout << "malloc (raw) " << size << std::endl; - std::cout << "malloc (adj) " << size << " - "; - #endif - - BlockHeader* currentBlock = _head; - BlockHeader* previousBlock = nullptr; - void* retVal = nullptr; - - // iterate through linked free blocks - while (currentBlock) { - // consume whole block is size equals required size - if (currentBlock->size == size) { - if (previousBlock) previousBlock->next = currentBlock->next; - break; - - // split block if size is larger and add second part to list of free blocks - } else if (currentBlock->size > size) { - BlockHeader* newBlock = currentBlock + size; - if (previousBlock) previousBlock->next = newBlock; - newBlock->next = currentBlock->next; - newBlock->size = currentBlock->size - size; - currentBlock->next = newBlock; - break; - } - previousBlock = currentBlock; - currentBlock = currentBlock->next; - } - - if (currentBlock) { - if (currentBlock == _head) { - _head = currentBlock->next; - } - currentBlock->size = size; - currentBlock->next = nullptr; // used when freeing memory - retVal = currentBlock + 1; - #ifdef MEMPOL_DEBUG - std::cout << "ok" << std::endl; - #endif - } else { - #ifdef MEMPOL_DEBUG - std::cout << "nok" << std::endl; - #endif - (void)0; - } - - return retVal; - } - - void free(void* ptr) { - if (!ptr) return; - // check if ptr points to region in _buffer - - #ifdef MEMPOL_DEBUG - std::cout << "free " << static_cast(reinterpret_cast(ptr) - 1) << std::endl; - #endif - - #if _GLIBCXX_HAS_GTHREADS - const std::lock_guard lockGuard(_mutex); - #endif - - BlockHeader* toFree = reinterpret_cast(ptr) - 1; - BlockHeader* previous = reinterpret_cast(_buffer); - BlockHeader* next = _head; - - // toFree is the only free block - if (!next) { - _head = toFree; - return; - } - - while (previous) { - if (!next || toFree < next) { - // 1. add block to linked list of free blocks - if (toFree < _head) { - toFree->next = _head; - _head = toFree; - } else { - previous->next = toFree; - toFree->next = next; - } - - // 2. merge with previous if adjacent - if (toFree > _head && toFree == previous + previous->size) { - previous->size += toFree->size; - previous->next = toFree->next; - toFree = previous; // used in next check - } - - // 3. merge with next if adjacent - if (toFree + toFree->size == next) { - toFree->size += next->size; - toFree->next = next->next; - } - - // 4. done - return; - } - previous = next; - next = next->next; - } - } - - std::size_t freeMemory() { - #if _GLIBCXX_HAS_GTHREADS - const std::lock_guard lockGuard(_mutex); - #endif - size_t retVal = 0; - BlockHeader* currentBlock = reinterpret_cast(_head); - - while (currentBlock) { - retVal += currentBlock->size - 1; - currentBlock = currentBlock->next; - } - - return retVal * sizeof(BlockHeader); - } - - std::size_t maxBlockSize() { - #if _GLIBCXX_HAS_GTHREADS - const std::lock_guard lockGuard(_mutex); - #endif - size_t retVal = 0; - BlockHeader* currentBlock = reinterpret_cast(_head); - - while (currentBlock) { - retVal = (currentBlock->size - 1 > retVal) ? currentBlock->size - 1 : retVal; - currentBlock = currentBlock->next; - } - - return retVal * sizeof(BlockHeader); - } - - #ifdef MEMPOL_DEBUG - void print() { - std::cout << "+--------------------" << std::endl; - std::cout << "|start:" << static_cast(_buffer) << std::endl; - std::cout << "|size:" << _bufferSize << std::endl; - std::cout << "|headersize:" << sizeof(BlockHeader) << std::endl; - std::cout << "|head: " << static_cast(_head) << std::endl; - BlockHeader* nextFreeBlock = _head; - BlockHeader* currentBlock = reinterpret_cast(_buffer); - size_t blockNumber = 1; - while (currentBlock < reinterpret_cast(_buffer) + _bufferSize) { - std::cout << "|" << blockNumber << ": " << static_cast(currentBlock) << std::endl; - std::cout << "| " << static_cast(currentBlock->next) << std::endl; - std::cout << "| " << currentBlock->size << std::endl; - if (currentBlock == nextFreeBlock) { - std::cout << "| free" << std::endl; - nextFreeBlock = nextFreeBlock->next; - } else { - std::cout << "| allocated" << std::endl; - } - ++blockNumber; - currentBlock += currentBlock->size; - } - std::cout << "+--------------------" << std::endl; - } - #endif - - private: - struct BlockHeader { - BlockHeader* next; - std::size_t size; - }; - /* - pool size is aligned to sizeof(BlockHeader). - requested blocksize is therefore multiple of blockheader (rounded up) - total size = nr requested blocks * multiplier * blockheadersize - - see constructor for calculation - */ - unsigned char _buffer[(nrBlocks * ((blocksize / sizeof(BlockHeader) + ((blocksize % sizeof(BlockHeader)) ? 1 : 0)) + 1)) * sizeof(BlockHeader)]; - BlockHeader* _head; - #if _GLIBCXX_HAS_GTHREADS - std::mutex _mutex; - #endif - - #ifdef MEMPOL_DEBUG - std::size_t _bufferSize; - #endif -}; - -} // end namespace MemoryPool +/* +Copyright (c) 2024 Bert Melis. All rights reserved. + +This work is licensed under the terms of the MIT license. +For a copy, see or +the LICENSE file. +*/ + +#pragma once + +#include // std::size_t +#include // assert +#if _GLIBCXX_HAS_GTHREADS +#include // NOLINT [build/c++11] std::mutex, std::lock_guard +#else +#warning "The memory pool is not thread safe" +#endif + +#ifdef MEMPOL_DEBUG +#include +#endif + +namespace MemoryPool { + +template +class Variable { + public: + Variable() + : _buffer{0} + , _head(nullptr) + #ifdef MEMPOL_DEBUG + , _bufferSize(0) + #endif + { + std::size_t _normBlocksize = blocksize / sizeof(BlockHeader) + ((blocksize % sizeof(BlockHeader)) ? 1 : 0); + size_t nrBlocksToAlloc = nrBlocks * (_normBlocksize + 1); + BlockHeader* h = reinterpret_cast(_buffer); + h->next = nullptr; + h->size = nrBlocksToAlloc; + _head = h; + + #ifdef MEMPOL_DEBUG + _bufferSize = nrBlocksToAlloc; + #endif + } + + // no copy nor move + Variable (const Variable&) = delete; + Variable& operator= (const Variable&) = delete; + + void* malloc(size_t size) { + #if _GLIBCXX_HAS_GTHREADS + const std::lock_guard lockGuard(_mutex); + #endif + if (size == 0) return nullptr; + + size = (size / sizeof(BlockHeader) + (size % sizeof(BlockHeader) != 0)) + 1; // count by BlockHeader size, add 1 for header + + #ifdef MEMPOL_DEBUG + std::cout << "malloc (raw) " << size << std::endl; + std::cout << "malloc (adj) " << size << " - "; + #endif + + BlockHeader* currentBlock = _head; + BlockHeader* previousBlock = nullptr; + void* retVal = nullptr; + + // iterate through linked free blocks + while (currentBlock) { + // consume whole block is size equals required size + if (currentBlock->size == size) { + if (previousBlock) previousBlock->next = currentBlock->next; + break; + + // split block if size is larger and add second part to list of free blocks + } else if (currentBlock->size > size) { + BlockHeader* newBlock = currentBlock + size; + if (previousBlock) previousBlock->next = newBlock; + newBlock->next = currentBlock->next; + newBlock->size = currentBlock->size - size; + currentBlock->next = newBlock; + break; + } + previousBlock = currentBlock; + currentBlock = currentBlock->next; + } + + if (currentBlock) { + if (currentBlock == _head) { + _head = currentBlock->next; + } + currentBlock->size = size; + currentBlock->next = nullptr; // used when freeing memory + retVal = currentBlock + 1; + #ifdef MEMPOL_DEBUG + std::cout << "ok" << std::endl; + #endif + } else { + #ifdef MEMPOL_DEBUG + std::cout << "nok" << std::endl; + #endif + (void)0; + } + + return retVal; + } + + void free(void* ptr) { + if (!ptr) return; + // check if ptr points to region in _buffer + + #ifdef MEMPOL_DEBUG + std::cout << "free " << static_cast(reinterpret_cast(ptr) - 1) << std::endl; + #endif + + #if _GLIBCXX_HAS_GTHREADS + const std::lock_guard lockGuard(_mutex); + #endif + + BlockHeader* toFree = reinterpret_cast(ptr) - 1; + BlockHeader* previous = reinterpret_cast(_buffer); + BlockHeader* next = _head; + + // toFree is the only free block + if (!next) { + _head = toFree; + return; + } + + while (previous) { + if (!next || toFree < next) { + // 1. add block to linked list of free blocks + if (toFree < _head) { + toFree->next = _head; + _head = toFree; + } else { + previous->next = toFree; + toFree->next = next; + } + + // 2. merge with previous if adjacent + if (toFree > _head && toFree == previous + previous->size) { + previous->size += toFree->size; + previous->next = toFree->next; + toFree = previous; // used in next check + } + + // 3. merge with next if adjacent + if (toFree + toFree->size == next) { + toFree->size += next->size; + toFree->next = next->next; + } + + // 4. done + return; + } + previous = next; + next = next->next; + } + } + + std::size_t freeMemory() { + #if _GLIBCXX_HAS_GTHREADS + const std::lock_guard lockGuard(_mutex); + #endif + size_t retVal = 0; + BlockHeader* currentBlock = reinterpret_cast(_head); + + while (currentBlock) { + retVal += currentBlock->size - 1; + currentBlock = currentBlock->next; + } + + return retVal * sizeof(BlockHeader); + } + + std::size_t maxBlockSize() { + #if _GLIBCXX_HAS_GTHREADS + const std::lock_guard lockGuard(_mutex); + #endif + size_t retVal = 0; + BlockHeader* currentBlock = reinterpret_cast(_head); + + while (currentBlock) { + retVal = (currentBlock->size - 1 > retVal) ? currentBlock->size - 1 : retVal; + currentBlock = currentBlock->next; + } + + return retVal * sizeof(BlockHeader); + } + + #ifdef MEMPOL_DEBUG + void print() { + std::cout << "+--------------------" << std::endl; + std::cout << "|start:" << static_cast(_buffer) << std::endl; + std::cout << "|size:" << _bufferSize << std::endl; + std::cout << "|headersize:" << sizeof(BlockHeader) << std::endl; + std::cout << "|head: " << static_cast(_head) << std::endl; + BlockHeader* nextFreeBlock = _head; + BlockHeader* currentBlock = reinterpret_cast(_buffer); + size_t blockNumber = 1; + while (currentBlock < reinterpret_cast(_buffer) + _bufferSize) { + std::cout << "|" << blockNumber << ": " << static_cast(currentBlock) << std::endl; + std::cout << "| " << static_cast(currentBlock->next) << std::endl; + std::cout << "| " << currentBlock->size << std::endl; + if (currentBlock == nextFreeBlock) { + std::cout << "| free" << std::endl; + nextFreeBlock = nextFreeBlock->next; + } else { + std::cout << "| allocated" << std::endl; + } + ++blockNumber; + currentBlock += currentBlock->size; + } + std::cout << "+--------------------" << std::endl; + } + #endif + + private: + struct BlockHeader { + BlockHeader* next; + std::size_t size; + }; + /* + pool size is aligned to sizeof(BlockHeader). + requested blocksize is therefore multiple of blockheader (rounded up) + total size = nr requested blocks * multiplier * blockheadersize + + see constructor for calculation + */ + unsigned char _buffer[(nrBlocks * ((blocksize / sizeof(BlockHeader) + ((blocksize % sizeof(BlockHeader)) ? 1 : 0)) + 1)) * sizeof(BlockHeader)]; + BlockHeader* _head; + #if _GLIBCXX_HAS_GTHREADS + std::mutex _mutex; + #endif + + #ifdef MEMPOL_DEBUG + std::size_t _bufferSize; + #endif +}; + +} // end namespace MemoryPool diff --git a/lib/espMqttClient/src/MqttClientSetup.h b/lib/espMqttClient/src/MqttClientSetup.h index 67f46a0..4ef7307 100644 --- a/lib/espMqttClient/src/MqttClientSetup.h +++ b/lib/espMqttClient/src/MqttClientSetup.h @@ -11,13 +11,13 @@ the LICENSE file. #pragma once +#include "MqttClient.h" + #if EMC_MULTIPLE_CALLBACKS #include #include #endif -#include "MqttClient.h" - template class MqttClientSetup : public MqttClient { public: diff --git a/lib/espMqttClient/src/Transport/ClientPosix.cpp b/lib/espMqttClient/src/Transport/ClientPosix.cpp index 1cd66e2..4b086d1 100644 --- a/lib/espMqttClient/src/Transport/ClientPosix.cpp +++ b/lib/espMqttClient/src/Transport/ClientPosix.cpp @@ -27,12 +27,12 @@ bool ClientPosix::connect(IPAddress ip, uint16_t port) { _sockfd = ::socket(AF_INET, SOCK_STREAM, 0); if (_sockfd < 0) { - emc_log_e("Error %d opening socket", errno); + emc_log_e("Error %d: \"%s\" opening socket", errno, strerror(errno)); } int flag = 1; if (setsockopt(_sockfd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int)) < 0) { - emc_log_e("Error %d disabling nagle", errno); + emc_log_e("Error %d: \"%s\" disabling nagle", errno, strerror(errno)); } memset(&_host, 0, sizeof(_host)); @@ -47,15 +47,17 @@ bool ClientPosix::connect(IPAddress ip, uint16_t port) { return false; } - emc_log_i("Connected"); + emc_log_i("Socket connected"); return true; } -bool ClientPosix::connect(const char* host, uint16_t port) { - // tbi - (void) host; - (void) port; - return false; +bool ClientPosix::connect(const char* hostname, uint16_t port) { + IPAddress ipAddress = _hostToIP(hostname); + if (ipAddress == IPAddress(0)) { + emc_log_e("No such host '%s'", hostname); + return false; + } + return connect(ipAddress, port); } size_t ClientPosix::write(const uint8_t* buf, size_t size) { @@ -87,6 +89,42 @@ bool ClientPosix::disconnected() { return _sockfd < 0; } +IPAddress ClientPosix::_hostToIP(const char* hostname) { + IPAddress returnIP(0); + struct addrinfo hints, *servinfo, *p; + struct sockaddr_in *h; + int rv; + +// Set up request addrinfo struct + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + emc_log_i("Looking for '%s'", hostname); + +// ask for host data + if ((rv = getaddrinfo(hostname, NULL, &hints, &servinfo)) != 0) { + emc_log_e("getaddrinfo: %s", gai_strerror(rv)); + return returnIP; + } + + // loop through all the results and connect to the first we can + for (p = servinfo; p != NULL; p = p->ai_next) { + h = (struct sockaddr_in *)p->ai_addr; + returnIP = ::htonl(h->sin_addr.s_addr); + if (returnIP != IPAddress(0)) break; + } + // Release allocated memory + freeaddrinfo(servinfo); + + if (returnIP != IPAddress(0)) { + emc_log_i("Host '%s' = %u", hostname, (uint32_t)returnIP); + } else { + emc_log_e("No IP for '%s' found", hostname); + } + return returnIP; +} + } // namespace espMqttClientInternals #endif diff --git a/lib/espMqttClient/src/Transport/ClientPosix.h b/lib/espMqttClient/src/Transport/ClientPosix.h index af0dd4b..adffaa1 100644 --- a/lib/espMqttClient/src/Transport/ClientPosix.h +++ b/lib/espMqttClient/src/Transport/ClientPosix.h @@ -19,6 +19,7 @@ the LICENSE file. #include #include #include +#include #include "Transport.h" // includes IPAddress #include "../Logging.h" @@ -34,7 +35,7 @@ class ClientPosix : public Transport { ClientPosix(); ~ClientPosix(); bool connect(IPAddress ip, uint16_t port) override; - bool connect(const char* host, uint16_t port) override; + bool connect(const char* hostname, uint16_t port) override; size_t write(const uint8_t* buf, size_t size) override; int read(uint8_t* buf, size_t size) override; void stop() override; @@ -44,6 +45,8 @@ class ClientPosix : public Transport { protected: int _sockfd; sockaddr_in _host; + + IPAddress _hostToIP(const char* hostname); }; } // namespace espMqttClientInternals diff --git a/lib/espMqttClient/src/Transport/ClientPosixIPAddress.cpp b/lib/espMqttClient/src/Transport/ClientPosixIPAddress.cpp index 3386dec..c6a78fc 100644 --- a/lib/espMqttClient/src/Transport/ClientPosixIPAddress.cpp +++ b/lib/espMqttClient/src/Transport/ClientPosixIPAddress.cpp @@ -29,4 +29,12 @@ IPAddress::operator uint32_t() { return _address; } +bool IPAddress::operator==(IPAddress other) { + return _address == other._address; +} + +bool IPAddress::operator!=(IPAddress other) { + return _address != other._address; +} + #endif diff --git a/lib/espMqttClient/src/Transport/ClientPosixIPAddress.h b/lib/espMqttClient/src/Transport/ClientPosixIPAddress.h index 279a195..9941ec5 100644 --- a/lib/espMqttClient/src/Transport/ClientPosixIPAddress.h +++ b/lib/espMqttClient/src/Transport/ClientPosixIPAddress.h @@ -18,8 +18,10 @@ class IPAddress { public: IPAddress(); IPAddress(uint8_t p0, uint8_t p1, uint8_t p2, uint8_t p3); - explicit IPAddress(uint32_t address); + IPAddress(uint32_t address); // NOLINT(runtime/explicit) operator uint32_t(); + bool operator==(IPAddress other); + bool operator!=(IPAddress other); protected: uint32_t _address; diff --git a/lib/espMqttClient/test/test_client_native/test_client_native.cpp b/lib/espMqttClient/test/test_client_native/test_client_native.cpp index db70a54..d2eef9d 100644 --- a/lib/espMqttClient/test/test_client_native/test_client_native.cpp +++ b/lib/espMqttClient/test/test_client_native/test_client_native.cpp @@ -16,8 +16,9 @@ uint32_t onPublishCbId = 6; std::atomic_bool exitProgram(false); std::thread t; -const IPAddress broker(127,0,0,1); -//const char* broker = "localhost"; +//const IPAddress broker(127,0,0,1); +const char* broker = "mqtt"; +//const char* broker = "test.mosquitto.org"; const uint16_t broker_port = 1883; /*