Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/neel/dhyara
Dhyara is a ESP-IDF component for Mobile Ad-Hoc Networks on the top of ESP NOW.
https://github.com/neel/dhyara
Last synced: 2 months ago
JSON representation
Dhyara is a ESP-IDF component for Mobile Ad-Hoc Networks on the top of ESP NOW.
- Host: GitHub
- URL: https://github.com/neel/dhyara
- Owner: neel
- License: bsd-2-clause
- Created: 2021-03-07T13:23:40.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2021-12-20T12:06:51.000Z (over 2 years ago)
- Last Synced: 2024-01-29T23:35:55.890Z (5 months ago)
- Language: C++
- Homepage:
- Size: 38.3 MB
- Stars: 16
- Watchers: 1
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Lists
- awesome-esp - Dhyara - A C/C++ library for making a Mobile Ad hoc Network (MANET) using ESP Now. (Libraries / Others)
README
DHYARA
======[GitHub Repository](https://github.com/neel/dhyara) | [Doxygen Documentation](http://neel.github.io/dhyara)
Dhyara is a ESP-IDF component for Mobile Ad-Hoc Networks on the top of ESP NOW (Layer 2).
Dhyara is Open Source under BSD 2 Clause License. See [LICENSE](docs/LICENSE.md)[TOC]
![Management Console](docs/images/management.png)
Basic Usage
-------------The dhyara nodes identify each other via MAC address.
Once deployed the nodes communicate with each other and each node builds a routing table based on its local view.
On the top of that, dhyara provides C and C++ APIs for send/receice/ping/traceroute functionalities.In the following example, the string "Hello World" is a variable length data which is sent to the destination identified with the mac address `4c:11:ae:9c:a6:85` over the multihop network.
If the destination is a direct neighbour of the source then the message will be delivered in one hop.
Otherwise the message sent will find its path to the destination `4c:11:ae:9c:a6:85` on its own by following the routing decisions of each intermediate nodes.~~~{.c}
uint8_t sink[] = {0x4c, 0x11, 0xae, 0x9c, 0xa6, 0x85};
dhyara_send(sink, "Hello World");
~~~C++ version of the above mentined C example.
~~~{.cpp}
dhyara::peer_address sink("4c:11:ae:9c:a6:85");
std::string data = "Hello World";
dhyara_send(sink, data.begin(), data.end());
~~~To receive the mesage sent over the network the sink node needs to register a callback where the data is received.
~~~{.c}
void data_received(const unsigned char* source, const void* data, unsigned long len){
// data received here
}
dhyara_receivef(&data_received);
~~~ESP Now limits maximum size of a frame to 250 bytes.
The variable length data is represented as a data packet (\ref dhyara::packets::data), which is broken into multiple smaller sized chunks.
On the receiving end these chunks are joined to comstruct a data packet, which is used while calling the receive callback set using \ref dhyara_receivef, \ref dhyara_receive, and \ref dhyara_receive_data.~~~{cpp}
dhyara_receive_data([](const dhyara::peer::address& source, const dhyara::packets::data& data){
std::cout << "received data " << " originating from " << data.source() << " via " << source << " of size " << data.length() << std::endl;
});
~~~In the above mentioned C++ example, source represents the immediate neighbour of the desination, and `data.source()` is the originator of the message.
[Read More](\ref dhyara)
Compilation & Integration
--------------------------Dhyara is a C++11 library that has to be used as an ESP-IDF component.
It can be cloned to the `components` directory or can be used as a `git submodule` inside your projects `components` directory.
If the application project is using an extra components directory then path to that directory has to be added in the root directory's CMakeLists.txt file as shown in the following example.```
set(EXTRA_COMPONENT_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/components)
```To configure the network parameters use `idf.py menuconfig` in the aplications directory and Go to `Component config > Dhyara ad hoc network`
To build and flash the application use `idf.py build` and `idf.py flash` as usual.![menuconfig](docs/images/menuconfig.png "idf.py menuconfig")
See [Building the examples](docs/examples.md).
C Example
----------The examples are provided in the examples directory. See [Building the examples](docs/examples.md) for instructions on building the examples.
Following is a C example demonstrating basic usage of dhyara
~~~{.c}void data_received(const unsigned char* source, const void* data, unsigned long len){
ESP_LOGI("hello-c", "data received \"%s\" (length %lu)", (const char*)data, len);
}void app_main(){
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
ESP_ERROR_CHECK(dhyara_init(WIFI_MODE_AP));
dhyara_start_default_network();
dhyara_receivef(&data_received);uint8_t self[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
dhyara_local(self);
ESP_LOGI("hello-c", "Local MAC address %x:%x:%x:%x:%x:%x", self[0], self[1], self[2], self[3], self[4], self[5]);
uint8_t source[] = {0x4c, 0x11, 0xae, 0x71, 0x0f, 0x4d}; // TODO change the source address
uint8_t sink[] = {0x4c, 0x11, 0xae, 0x9c, 0xa6, 0x85}; // TODO change the sink address
const uint8_t* other = 0x0;
if(memcmp(self, source, 6) == 0) other = sink;
if(memcmp(self, sink, 6) == 0) other = source;
while(1){
if(other){
dhyara_ping(other, .count = 1, .batch = 10);
dhyara_traceroute(other);
dhyara_send(other, "Hello World");
dhyara_send(other, "Hello World", 5);
}
vTaskDelay(pdMS_TO_TICKS(2000));
}
}
~~~C++ Example
-----------Dhyara is primarily intended to be used for C++ application.
To build a C++ application with ESP-IDF we first start from a `main.c` which calls a C++ function `mainx()`.
Following is the `main.c` from the example `hello-cxx`~~~{.c}
void app_main(){
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
ESP_ERROR_CHECK(dhyara_init(WIFI_MODE_AP));
mainx(); // Enter C++
}~~~
The `mainx()` is declared and gaurded by `extern C{}` block in the `mainx.h`, so that it can be included from c as well as C++.
Following is the definition of mainx() which can be found in the `mainx.cpp` in the `hello-cxx` example project.~~~{.cpp}
void mainx(){
dhyara::network network(dhyara_link());
dhyara_set_default_network(&network);
dhyara::peer_address sink("4c:11:ae:9c:a6:85"), source("4c:11:ae:71:0f:4d");dhyara_start_default_network();
dhyara::peer_address local = dhyara_local();
dhyara::peer_address other = (local == source) ? sink : ((local == sink) ? source : dhyara::peer_address::null());
// The anonymous function will be called once all chunks of a data packet is received
dhyara_receive_data([](const dhyara::peer::address& source, const dhyara::packets::data& data){
std::cout << "received data " << " originating from " << data.source() << " via " << source << " of size " << data.length() << std::endl;
});
while(1){
if(!other.is_null()){
dhyara_ping(other, 1, 10);
dhyara_traceroute(other);
std::string buffer = "Hello World";
dhyara_send(other, buffer.begin(), buffer.end());
}
vTaskDelay(pdMS_TO_TICKS(5000));
}
}
~~~