Тема 1.3 на ESP32-C6: Как асинхронно отвечать на сообщенияC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Тема 1.3 на ESP32-C6: Как асинхронно отвечать на сообщения

Сообщение Anonymous »

Я пытаюсь соединить два beetle esp32-c6 вместе в сети Thread 1.3. Они оба прошиты одним и тем же кодом. Если они обнаруживают наличие сети, они присоединяются к ней. Если сети нет, то они создают сеть и становятся ее лидером. Если они лидеры, они рассылают широковещательное сообщение («Привет, я ваш лидер»). Если они являются узлом, они отправляют сообщение только лидеру («Привет от узла»).
В коде есть ошибка компиляции. Ошибка компиляции: список выражений рассматривается как составное выражение в функциональное приведение [-fpermissive]. Я знаю, что у меня otUdpReceive(instance, onMessageReceived, &socket); неправильно, но я не могу найти документацию, чтобы это исправить. Предполагается, что эта строка устанавливает асинхронную функцию, которая вызывает onMessageReceived при получении сообщения.
Вот дополнительный контекст кода (он находится в initThreadDevice)< /p>
if (otUdpBind(instance, &socket, &bindAddr, OT_NETIF_THREAD) == OT_ERROR_NONE) {
Serial.println("UDP socket bound to port.");

// Set the UDP receive callback
otUdpReceive(instance, onMessageReceived, &socket); // Register the callback
} else {
Serial.println("Failed to bind UDP socket.");
}
}

Вот полный код.
#include
#include
#include
#include
#include
#include
#include

#define THREAD_CHANNEL 15

otInstance *instance;
otUdpSocket socket;

// Callback function to handle received messages
void onMessageReceived(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo) {

// Retrieve the Mesh-Local EID
const otIp6Address *meshLocalEid = otThreadGetMeshLocalEid(instance);
if (meshLocalEid == NULL) {
Serial.println("Failed to retrieve Mesh-Local EID.");
return;
}

// Compare the Mesh-Local EID with the source address of the incoming message
if (otIp6IsAddressEqual(meshLocalEid, &aMessageInfo->mPeerAddr)) {
Serial.println("Ignoring message from self.");
return; // Ignore the message if it's from this device
}

char messageBuffer[128];
int maxLength = sizeof(messageBuffer) - 1; // Set maximum message length (128 - 1 for null termination)

// Read the incoming message, but clip it if it's too long
int length = otMessageRead(aMessage, otMessageGetOffset(aMessage), messageBuffer, maxLength);

// Ensure the message is null-terminated
if (length > 0) {
messageBuffer[length] = '\0'; // Add null termination at the end of the message
} else {
return; // If no valid length, just return
}

// Print the received message
Serial.print("Received message: ");
Serial.println(messageBuffer);
}

// Try to join an existing Thread network
bool joinExistingNetwork(otOperationalDataset &dataset) {
if (dataset.mComponents.mIsActiveTimestampPresent) {
if (otDatasetSetActive(instance, &dataset) == OT_ERROR_NONE) {
Serial.println("Joined existing Thread network.");
return true;
} else {
Serial.println("Failed to join the network.");
}
} else {
Serial.println("No active Thread network found.");
}

return false;
}

// Form a new Thread network
bool formNewThreadNetwork(otOperationalDataset &dataset) {
Serial.println("Forming a new Thread network...");

memset(&dataset, 0, sizeof(dataset)); // Clear the dataset

// Set the network parameters (example values, you can adjust them)
dataset.mActiveTimestamp.mSeconds = 1; // Set timestamp in seconds
dataset.mActiveTimestamp.mTicks = 0; // Set ticks (usually 0)
dataset.mActiveTimestamp.mAuthoritative = true; // Mark as authoritative
dataset.mComponents.mIsActiveTimestampPresent = true;
dataset.mComponents.mIsActiveTimestampPresent = true;

dataset.mChannel = THREAD_CHANNEL; // Set the desired channel
dataset.mComponents.mIsChannelPresent = true;

dataset.mPanId = 0x1234; // Set a random PAN ID
dataset.mComponents.mIsPanIdPresent = true;

const char* networkName = "MyThreadNetwork";
strcpy(dataset.mNetworkName.m8, networkName); // Set the network name
dataset.mComponents.mIsNetworkNamePresent = true;

// Apply the new dataset to form the network
if (otDatasetSetActive(instance, &dataset) == OT_ERROR_NONE) {
Serial.println("New Thread network formed.");
return true;
} else {
Serial.println("Failed to form the new Thread network.");
}

return false;
}

// Initialize Thread device and set up UDP communication
void initThreadDevice() {
Serial.println("Initializing Thread...");

Serial.println("Detecting there are any existing networks...");
otOperationalDataset dataset;

if (otDatasetGetActive(instance, &dataset) == OT_ERROR_NONE) {
Serial.println("Active Thread network found. Attempting to join...");
if (!joinExistingNetwork(dataset)) {
Serial.println("Failed to join the existing network. Exiting prematurely from initThreadDevice.");
return;
}
} else {
Serial.println("No active Thread network found. Attempting to create a new network...");
if (!formNewThreadNetwork(dataset)) {
Serial.println("Failed to create a new network. Exiting prematurely from initThreadDevice.");
return;
}
}

// Try to start the Thread protocol
if (otThreadSetEnabled(instance, true) == OT_ERROR_NONE) {
Serial.println("Thread network enabled.");
} else {
Serial.println("Failed to start Thread network.");
return;
}

// Set up UDP socket and bind it to a port
otSockAddr bindAddr;
memset(&bindAddr, 0, sizeof(bindAddr));
bindAddr.mPort = 12345; // Example port number

if (otUdpBind(instance, &socket, &bindAddr, OT_NETIF_THREAD) == OT_ERROR_NONE) {
Serial.println("UDP socket bound to port.");

// Set the UDP receive callback
otUdpReceive(instance, onMessageReceived, &socket); // Register the callback
} else {
Serial.println("Failed to bind UDP socket.");
}
}

void broadcastMessage(const char *message) {
delay(random(100, 500));
otMessageInfo messageInfo;
memset(&messageInfo, 0, sizeof(messageInfo)); // Clear the messageInfo structure

// Set the destination to the IPv6 link-local multicast address ff02::1 (all nodes)
if (otIp6AddressFromString("ff02::1", &messageInfo.mPeerAddr) != OT_ERROR_NONE) {
Serial.println("Invalid multicast address.");
return;
}
messageInfo.mPeerPort = 12345; // Specify the port to send the message

// Create a new UDP message
otMessage *udpMessage = otUdpNewMessage(instance, NULL);
if (udpMessage == NULL) {
Serial.println("Failed to create new UDP message.");
return;
}

// Append the message to the UDP message buffer
if (otMessageAppend(udpMessage, message, strlen(message)) != OT_ERROR_NONE) {
Serial.println("Failed to append message content.");
otMessageFree(udpMessage);
return;
}

// Send the message via UDP to the multicast address
otUdpSend(instance, &socket, udpMessage, &messageInfo);

Serial.println("Broadcast message sent.");
otMessageFree(udpMessage);
}

void sendMessageToLeader(const char *message) {
delay(random(100, 500));
otMessageInfo messageInfo;
memset(&messageInfo, 0, sizeof(messageInfo)); // Clear the messageInfo structure

// Get the leader's RLOC (Routing Locator)
otIp6Address leaderAddress;
if (otThreadGetLeaderRloc(instance, &leaderAddress) != OT_ERROR_NONE) {
Serial.println("Failed to get leader address.");
return;
}

// Set the destination to the leader's address
messageInfo.mPeerAddr = leaderAddress;
messageInfo.mPeerPort = 12345; // Specify the port to send the message

// Create a new UDP message
otMessage *udpMessage = otUdpNewMessage(instance, NULL);
if (udpMessage == NULL) {
Serial.println("Failed to create new UDP message.");
return;
}

// Append the message to the UDP message buffer
if (otMessageAppend(udpMessage, message, strlen(message)) != OT_ERROR_NONE) {
Serial.println("Failed to append message content.");
otMessageFree(udpMessage);
return;
}
// Send the message via UDP to the leader's address
otUdpSend(instance, &socket, udpMessage, &messageInfo);

Serial.println("Message sent to the network leader.");
otMessageFree(udpMessage);
}

bool isLeader() {
otDeviceRole role = otThreadGetDeviceRole(instance); // Get the current role of the device

if (role == OT_DEVICE_ROLE_LEADER) {
return true;
}

return false;
}

void setup() {
Serial.begin(115200);
Serial.println("Starting ESP32-C6 Thread communication...");

// Initialize the OpenThread instance
instance = otInstanceInitSingle();

// Initialize Thread device (attempt to join or form a network)
initThreadDevice();
}

void loop() {
// Send test messages periodically (for leader or node)
if (isLeader()) {
broadcastMessage("Hello from the leader.");
} else {
sendMessageToLeader("Hello from a node.");
}

// Delay between message exchanges
delay(5000);

// OpenThread processes should be called periodically
otTaskletsProcess(instance);
}


Подробнее здесь: https://stackoverflow.com/questions/791 ... o-messages
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»