Skip to content

Commit ef995b6

Browse files
feat(openthread): adds native api (#11474)
* feat(openthread): adds native api * feat(openthread): adds source code to CMakeLists.txt * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
1 parent 2283937 commit ef995b6

File tree

31 files changed

+833
-205
lines changed

31 files changed

+833
-205
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ set(ARDUINO_LIBRARY_LittleFS_SRCS libraries/LittleFS/src/LittleFS.cpp)
165165
set(ARDUINO_LIBRARY_NetBIOS_SRCS libraries/NetBIOS/src/NetBIOS.cpp)
166166

167167
set(ARDUINO_LIBRARY_OpenThread_SRCS
168+
libraries/OpenThread/src/OThread.cpp
168169
libraries/OpenThread/src/OThreadCLI.cpp
169170
libraries/OpenThread/src/OThreadCLI_Util.cpp)
170171

libraries/OpenThread/README.md

Lines changed: 195 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,177 @@
11
| Supported Targets | ESP32-C6 | ESP32-H2 |
22
| ----------------- | -------- | -------- |
33

4-
# ESP32 Arduino OpenThreadCLI
4+
# General View
55

6-
The `OpenThreadCLI` class is an Arduino API for interacting with the OpenThread Command Line Interface (CLI). It allows you to manage and configure the Thread stack using a command-line interface.
6+
This Arduino OpenThread Library allows using ESP OpenThread implementation using CLI and/or Native OpenThread API.
7+
8+
The Library implements 3 C++ Classes:
9+
- `OThread` Class for Native OpenThread API
10+
- `OThreadCLI` Class for CLI OpenThread API
11+
- `DataSet` Class for OpenThread dataset manipulation using Native `OThread` Class
12+
13+
# ESP32 Arduino OpenThread Native
14+
15+
The `OThread` class provides methods for managing the OpenThread instance and controlling the Thread network. It allows you to initialize, start, stop, and manage the Thread network using native OpenThread APIs.
16+
17+
## Class Definition
18+
19+
```cpp
20+
class OpenThread {
21+
public:
22+
static bool otStarted; // Indicates whether the OpenThread stack is running.
23+
24+
// Get the current Thread device role (e.g., Leader, Router, Child, etc.).
25+
static ot_device_role_t otGetDeviceRole();
26+
27+
// Get the current Thread device role as a string.
28+
static const char *otGetStringDeviceRole();
29+
30+
// Print network information (e.g., network name, channel, PAN ID) to the specified stream.
31+
static void otPrintNetworkInformation(Stream &output);
32+
33+
OpenThread();
34+
~OpenThread();
35+
36+
// Returns true if the OpenThread stack is running.
37+
operator bool() const;
38+
39+
// Initialize the OpenThread stack.
40+
static void begin(bool OThreadAutoStart = true);
41+
42+
// Deinitialize the OpenThread stack.
43+
static void end();
44+
45+
// Start the Thread network.
46+
void start();
47+
48+
// Stop the Thread network.
49+
void stop();
50+
51+
// Bring up the Thread network interface (equivalent to "ifconfig up").
52+
void networkInterfaceUp();
53+
54+
// Bring down the Thread network interface (equivalent to "ifconfig down").
55+
void networkInterfaceDown();
56+
57+
// Commit a dataset to the OpenThread instance.
58+
void commitDataSet(const DataSet &dataset);
59+
60+
private:
61+
static otInstance *mInstance; // Pointer to the OpenThread instance.
62+
DataSet mCurrentDataSet; // Current dataset being used by the OpenThread instance.
63+
};
64+
65+
extern OpenThread OThread;
66+
```
67+
## Class Overview
68+
69+
The `OThread` class provides a simple and intuitive interface for managing the OpenThread stack and Thread network. It abstracts the complexity of the OpenThread APIs and provides Arduino-style methods for common operations.
70+
71+
## Public Methods
72+
### Initialization and Deinitialization
73+
- `begin(bool OThreadAutoStart = true)`: Initializes the OpenThread stack. If `OThreadAutoStart` is `true`, the Thread network will start automatically using NVS data.
74+
- `end()`: Deinitializes the OpenThread stack and releases resources.
75+
### Thread Network Control
76+
- `start()`: Starts the Thread network. This is equivalent to the CLI command "thread start".
77+
- `stop()`: Stops the Thread network. This is equivalent to the CLI command "thread stop".
78+
### Network Interface Control
79+
- `networkInterfaceUp()`: Brings up the Thread network interface. This is equivalent to the CLI command "ifconfig up".
80+
- `networkInterfaceDown()`: Brings down the Thread network interface. This is equivalent to the CLI command "ifconfig down".
81+
### Dataset Management
82+
- `commitDataSet(const DataSet &dataset)`: Commits a dataset to the OpenThread instance. This is used to configure the Thread network with specific parameters (e.g., network name, channel, PAN ID).
83+
### Network Information
84+
- `otGetDeviceRole()`: Returns the current Thread device role as an `ot_device_role_t` enum (e.g., `OT_ROLE_LEADER`, `OT_ROLE_ROUTER`).
85+
- `otGetStringDeviceRole()`: Returns the current Thread device role as a string (e.g., "Leader", "Router").
86+
- `otPrintNetworkInformation(Stream &output)`: Prints the current network information (e.g., network name, channel, PAN ID) to the specified stream.
87+
88+
## Key Features
89+
- **Initialization and Cleanup**: Easily initialize and deinitialize the OpenThread stack.
90+
- **Network Control**: Start and stop the Thread network with simple method calls.
91+
- **Dataset Management**: Configure the Thread network using the `DataSet` class and commit it to the OpenThread instance.
92+
- **Network Information**: Retrieve and print the current network information and device role.
93+
94+
## Notes
95+
- The `OThread` class is designed to simplify the use of OpenThread APIs in Arduino sketches.
96+
- It works seamlessly with the DataSet class for managing Thread network configurations.
97+
- Ensure that the OpenThread stack is initialized (`OThread.begin()`) before calling other methods.
98+
99+
This documentation provides a comprehensive overview of the `OThread` class, its methods, and example usage. It is designed to help developers quickly integrate OpenThread functionality into their Arduino projects.
100+
101+
# DataSet Class
102+
103+
The `DataSet` class provides a structured way to manage and configure Thread network datasets using native OpenThread APIs. It allows you to set and retrieve network parameters such as the network name, channel, PAN ID, and more. The `DataSet` class works seamlessly with the `OThread` class to apply these configurations to the OpenThread instance.
104+
105+
## Class Definition
106+
107+
```cpp
108+
class DataSet {
109+
public:
110+
DataSet();
111+
void clear();
112+
void initNew();
113+
const otOperationalDataset &getDataset() const;
114+
115+
// Setters
116+
void setNetworkName(const char *name);
117+
void setExtendedPanId(const uint8_t *extPanId);
118+
void setNetworkKey(const uint8_t *key);
119+
void setChannel(uint8_t channel);
120+
void setPanId(uint16_t panId);
121+
122+
// Getters
123+
const char *getNetworkName() const;
124+
const uint8_t *getExtendedPanId() const;
125+
const uint8_t *getNetworkKey() const;
126+
uint8_t getChannel() const;
127+
uint16_t getPanId() const;
128+
129+
// Apply the dataset to the OpenThread instance
130+
void apply(otInstance *instance);
131+
132+
private:
133+
otOperationalDataset mDataset; // Internal representation of the dataset
134+
};
135+
```
136+
137+
## Class Overview
138+
The DataSet` class simplifies the management of Thread network datasets by providing intuitive methods for setting, retrieving, and applying network parameters. It abstracts the complexity of the OpenThread dataset APIs and provides Arduino-style methods for common operations.
139+
140+
## Public Methods
141+
### Initialization
142+
- `DataSet()`: Constructor that initializes an empty dataset.
143+
- `void clear()`: Clears the dataset, resetting all fields to their default values.
144+
- `void initNew()`: Initializes a new dataset with default values (equivalent to the CLI command dataset init new).
145+
### Setters
146+
- `void setNetworkName(const char *name)`: Sets the network name.
147+
- `void setExtendedPanId(const uint8_t *extPanId)`: Sets the extended PAN ID.
148+
- `void setNetworkKey(const uint8_t *key)`: Sets the network key.
149+
- `void setChannel(uint8_t channel)`: Sets the channel.
150+
- `void setPanId(uint16_t panId)`: Sets the PAN ID.
151+
### Getters
152+
- `const char *getNetworkName() const`: Retrieves the network name.
153+
- `const uint8_t *getExtendedPanId() const`: Retrieves the extended PAN ID.
154+
- `const uint8_t *getNetworkKey() const`: Retrieves the network key.
155+
- `uint8_t getChannel() const`: Retrieves the channel.
156+
- `uint16_t getPanId() const`: Retrieves the PAN ID.
157+
### Dataset Application
158+
- `void apply(otInstance *instance)`: Applies the dataset to the specified OpenThread instance.
159+
160+
## Key Features
161+
- **Dataset Initialization**: Easily initialize a new dataset with default values using initNew().
162+
- **Custom Configuration**: Set custom network parameters such as the network name, channel, and PAN ID using setter methods.
163+
- **Dataset Application**: Apply the configured dataset to the OpenThread instance using apply().
164+
165+
** Notes
166+
- The `DataSet` class is designed to work seamlessly with the `OThread` class for managing Thread network configurations.
167+
- Ensure that the OpenThread stack is initialized (`OThread.begin()`) before applying a dataset.
168+
- The initNew()`` method provides default values for the dataset, which can be customized using the setter methods.
169+
170+
This documentation provides a comprehensive overview of the `DataSet` class, its methods, and example usage. It is designed to help developers easily manage Thread network configurations in their Arduino projects.
171+
172+
# OpenThreadCLI Class
173+
174+
The `OpenThreadCLI` class is an Arduino API for interacting with the OpenThread Command Line Interface (CLI). It allows you to send commands to the OpenThread stack and receive responses. This class is designed to simplify the use of OpenThread CLI commands in Arduino sketches.
7175

8176
There is one main class called `OpenThreadCLI` and a global object used to operate OpenThread CLI, called `OThreadCLI`.\
9177
Some [helper functions](helper_functions.md) were made available for working with the OpenThread CLI environment.
@@ -20,7 +188,7 @@ Below are the details of the class:
20188
class OpenThreadCLI : public Stream {
21189
private:
22190
static size_t setBuffer(QueueHandle_t &queue, size_t len);
23-
bool otStarted = false;
191+
static bool otCLIStarted = false;
24192

25193
public:
26194
OpenThreadCLI();
@@ -59,14 +227,35 @@ extern OpenThreadCLI OThreadCLI;
59227
- You can customize the console behavior by adjusting parameters such as echoback and buffer sizes.
60228
61229
## Public Methods
230+
### Initialization and Deinitialization
231+
- `begin()`: Initializes the OpenThread stack (optional auto-start).
232+
- `end()`: Deinitializes the OpenThread stack and releases resources.
233+
### Console Management
62234
- `startConsole(Stream& otStream, bool echoback = true, const char* prompt = "ot> ")`: Starts the OpenThread console with the specified stream, echoback option, and prompt.
63235
- `stopConsole()`: Stops the OpenThread console.
64236
- `setPrompt(char* prompt)`: Changes the console prompt (set to NULL for an empty prompt).
65237
- `setEchoBack(bool echoback)`: Changes the console echoback option.
66238
- `setStream(Stream& otStream)`: Changes the console Stream object.
67239
- `onReceive(OnReceiveCb_t func)`: Sets a callback function to handle complete lines of output from the OT CLI.
68-
- `begin(bool OThreadAutoStart = true)`: Initializes the OpenThread stack (optional auto-start).
69-
- `end()`: Deinitializes the OpenThread stack.
240+
### Buffer Management
70241
- `setTxBufferSize(size_t tx_queue_len)`: Sets the transmit buffer size (default is 256 bytes).
71242
- `setRxBufferSize(size_t rx_queue_len)`: Sets the receive buffer size (default is 1024 bytes).
72-
- `write(uint8_t)`, `available()`, `read()`, `peek()`, `flush()`: Standard Stream methods implementation for OpenThread CLI object.
243+
### Stream Methods
244+
- `write(uint8_t)`: Writes a byte to the CLI.
245+
- `available()`: Returns the number of bytes available to read.
246+
- `read()`: Reads a byte from the CLI.
247+
- `peek()`: Returns the next byte without removing it from the buffer.
248+
- `flush()`: Flushes the CLI buffer.
249+
250+
## Key Features
251+
- **Arduino Stream Compatibility**: Inherits from the Stream class, making it compatible with Arduino's standard I/O functions.
252+
- **Customizable Console**: Allows customization of the CLI prompt, echoback behavior, and buffer sizes.
253+
- **Callback Support**: Provides a callback mechanism to handle CLI responses asynchronously.
254+
- **Seamless Integration**: Designed to work seamlessly with the OThread and DataSet classes
255+
256+
## Notes
257+
- The `OThreadCLI` class is designed to simplify the use of OpenThread CLI commands in Arduino sketches.
258+
- It works seamlessly with the `OThread` and `DataSet` classes for managing Thread networks.
259+
- Ensure that the OpenThread stack is initialized (`OThreadCLI.begin()`) before starting the CLI console.
260+
261+
This documentation provides a comprehensive overview of the `OThreadCLI` class, its methods, and example usage. It is designed to help developers easily integrate OpenThread CLI functionality into their Arduino projects.

libraries/OpenThread/examples/COAP/coap_lamp/coap_lamp.ino renamed to libraries/OpenThread/examples/CLI/COAP/coap_lamp/coap_lamp.ino

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,18 +75,18 @@ bool otDeviceSetup(const char **otSetupCmds, uint8_t nCmds1, const char **otCoap
7575
Serial.println("OpenThread started.\r\nWaiting for activating correct Device Role.");
7676
// wait for the expected Device Role to start
7777
uint8_t tries = 24; // 24 x 2.5 sec = 1 min
78-
while (tries && otGetDeviceRole() != expectedRole) {
78+
while (tries && OThread.otGetDeviceRole() != expectedRole) {
7979
Serial.print(".");
8080
delay(2500);
8181
tries--;
8282
}
8383
Serial.println();
8484
if (!tries) {
85-
log_e("Sorry, Device Role failed by timeout! Current Role: %s.", otGetStringDeviceRole());
85+
log_e("Sorry, Device Role failed by timeout! Current Role: %s.", OThread.otGetStringDeviceRole());
8686
rgbLedWrite(RGB_BUILTIN, 255, 0, 0); // RED ... failed!
8787
return false;
8888
}
89-
Serial.printf("Device is %s.\r\n", otGetStringDeviceRole());
89+
Serial.printf("Device is %s.\r\n", OThread.otGetStringDeviceRole());
9090
for (i = 0; i < nCmds2; i++) {
9191
if (!otExecCommand(otCoapCmds[i * 2], otCoapCmds[i * 2 + 1])) {
9292
break;
@@ -151,7 +151,8 @@ void setup() {
151151
Serial.begin(115200);
152152
// LED starts RED, indicating not connected to Thread network.
153153
rgbLedWrite(RGB_BUILTIN, 64, 0, 0);
154-
OThreadCLI.begin(false); // No AutoStart is necessary
154+
OThread.begin(false); // No AutoStart is necessary
155+
OThreadCLI.begin();
155156
OThreadCLI.setTimeout(250); // waits 250ms for the OpenThread CLI response
156157
setupNode();
157158
// LED goes Green when all is ready and Red when failed.

libraries/OpenThread/examples/COAP/coap_switch/coap_switch.ino renamed to libraries/OpenThread/examples/CLI/COAP/coap_switch/coap_switch.ino

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,18 @@ bool otDeviceSetup(
6969
Serial.println("OpenThread started.\r\nWaiting for activating correct Device Role.");
7070
// wait for the expected Device Role to start
7171
uint8_t tries = 24; // 24 x 2.5 sec = 1 min
72-
while (tries && otGetDeviceRole() != expectedRole1 && otGetDeviceRole() != expectedRole2) {
72+
while (tries && OThread.otGetDeviceRole() != expectedRole1 && OThread.otGetDeviceRole() != expectedRole2) {
7373
Serial.print(".");
7474
delay(2500);
7575
tries--;
7676
}
7777
Serial.println();
7878
if (!tries) {
79-
log_e("Sorry, Device Role failed by timeout! Current Role: %s.", otGetStringDeviceRole());
79+
log_e("Sorry, Device Role failed by timeout! Current Role: %s.", OThread.otGetStringDeviceRole());
8080
rgbLedWrite(RGB_BUILTIN, 255, 0, 0); // RED ... failed!
8181
return false;
8282
}
83-
Serial.printf("Device is %s.\r\n", otGetStringDeviceRole());
83+
Serial.printf("Device is %s.\r\n", OThread.otGetStringDeviceRole());
8484
for (i = 0; i < nCmds2; i++) {
8585
if (!otExecCommand(otCoapCmds[i * 2], otCoapCmds[i * 2 + 1])) {
8686
break;
@@ -176,7 +176,8 @@ void setup() {
176176
Serial.begin(115200);
177177
// LED starts RED, indicating not connected to Thread network.
178178
rgbLedWrite(RGB_BUILTIN, 64, 0, 0);
179-
OThreadCLI.begin(false); // No AutoStart is necessary
179+
OThread.begin(false); // No AutoStart is necessary
180+
OThreadCLI.begin();
180181
OThreadCLI.setTimeout(250); // waits 250ms for the OpenThread CLI response
181182
setupNode();
182183
// LED goes and keeps Blue when all is ready and Red when failed.

libraries/OpenThread/examples/SimpleCLI/SimpleCLI.ino renamed to libraries/OpenThread/examples/CLI/SimpleCLI/SimpleCLI.ino

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2024 Espressif Systems (Shanghai) PTE LTD
1+
// Copyright 2025 Espressif Systems (Shanghai) PTE LTD
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -26,7 +26,8 @@
2626

2727
void setup() {
2828
Serial.begin(115200);
29-
OThreadCLI.begin(false); // No AutoStart - fresh start
29+
OThread.begin(false); // No AutoStart - fresh start
30+
OThreadCLI.begin();
3031
Serial.println("OpenThread CLI started - type 'help' for a list of commands.");
3132
OThreadCLI.startConsole(Serial);
3233
}

libraries/OpenThread/examples/SimpleNode/SimpleNode.ino renamed to libraries/OpenThread/examples/CLI/SimpleNode/SimpleNode.ino

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2024 Espressif Systems (Shanghai) PTE LTD
1+
// Copyright 2025 Espressif Systems (Shanghai) PTE LTD
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -35,12 +35,13 @@
3535

3636
void setup() {
3737
Serial.begin(115200);
38-
OThreadCLI.begin(); // AutoStart using Thread default settings
39-
otPrintNetworkInformation(Serial); // Print Current Thread Network Information
38+
OThread.begin(); // AutoStart using Thread default settings
39+
OThreadCLI.begin();
40+
OThread.otPrintNetworkInformation(Serial); // Print Current Thread Network Information
4041
}
4142

4243
void loop() {
4344
Serial.print("Thread Node State: ");
44-
Serial.println(otGetStringDeviceRole());
45+
Serial.println(OThread.otGetStringDeviceRole());
4546
delay(5000);
4647
}

libraries/OpenThread/examples/SimpleThreadNetwork/ExtendedRouterNode/ExtendedRouterNode.ino renamed to libraries/OpenThread/examples/CLI/SimpleThreadNetwork/ExtendedRouterNode/ExtendedRouterNode.ino

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2024 Espressif Systems (Shanghai) PTE LTD
1+
// Copyright 2025 Espressif Systems (Shanghai) PTE LTD
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -22,7 +22,8 @@ bool otStatus = true;
2222

2323
void setup() {
2424
Serial.begin(115200);
25-
OThreadCLI.begin(false); // No AutoStart - fresh start
25+
OThread.begin(false); // No AutoStart - fresh start
26+
OThreadCLI.begin();
2627
Serial.println("Setting up OpenThread Node as Router/Child");
2728
Serial.println("Make sure the Leader Node is already running");
2829

@@ -39,7 +40,7 @@ void setup() {
3940
}
4041
// wait for the node to enter in the router state
4142
uint32_t timeout = millis() + 90000; // waits 90 seconds to
42-
while (otGetDeviceRole() != OT_ROLE_CHILD && otGetDeviceRole() != OT_ROLE_ROUTER) {
43+
while (OThread.otGetDeviceRole() != OT_ROLE_CHILD && OThread.otGetDeviceRole() != OT_ROLE_ROUTER) {
4344
Serial.print(".");
4445
if (millis() > timeout) {
4546
Serial.println("\r\n\t===> Timeout! Failed.");
@@ -70,7 +71,7 @@ void loop() {
7071
if (otStatus) {
7172
Serial.println("Thread NetworkInformation: ");
7273
Serial.println("---------------------------");
73-
otPrintNetworkInformation(Serial);
74+
OThread.otPrintNetworkInformation(Serial);
7475
Serial.println("---------------------------");
7576
} else {
7677
Serial.println("Some OpenThread operation has failed...");

0 commit comments

Comments
 (0)