Openthread CLI UDP связь с main.c (NRF52840)

Мы работаем с ключами NRF52840 и хотим, чтобы они могли автоматически передавать данные через ячеистую сеть OpenThread через UDP. Мы обнаружили в OpenThread API надежную библиотеку Udp.h со всеми функциями Udp, которые нам нужны для создания кода, который запускается на ключах из main.c.

Ниже приведен наш код, который должен транслировать сообщение "Hallo" всем узлам, имеющим открытый сокет на порте 1994.

Мы прочитали, что адрес ipv6 ff03::1 зарезервирован для многоадресной широковещательной рассылки UDP и отлично работает при ручном выполнении с помощью команд CLI udp.

CLI: UDP открыт, UDP отправить ff03::1 1994 Hallo

Со всеми открытыми узлами udp udp bind:: 1994 получает сообщение Hallo от отправляющего узла.

Мы пытаемся воссоздать это в main.c наших узлов, чтобы мы могли предоставить узлам некоторый собственный интеллект.

Этот фрагмент кода запускается один раз при нажатии кнопки на ключе. Код прекрасно компилируется, и мы протестировали функции, которые возвращаются с помощью индикатора RGB (зеленый ОК, красный нет), чтобы подтвердить, что ошибок не было (к сожалению, не все функции возвращают значение no_error)

    void udpSend(){
    const char *buf = "Hallo";
    otMessageInfo messageInfo;
    otInstance *myInstance;
    myInstance = thread_ot_instance_get();
    otUdpSocket mySocket;

    memset(&messageInfo, 0, sizeof(messageInfo));

    // messageInfo.mPeerAddr = otIp6GetUnicastAddresses(myInstance)->mNext->mNext->mAddress;
    otIp6AddressFromString("ff03::1", &messageInfo.mPeerAddr);
    messageInfo.mPeerPort = 1994;
    messageInfo.mInterfaceId = OT_NETIF_INTERFACE_ID_THREAD;

    otUdpOpen(myInstance, &mySocket, NULL, NULL);

    otMessage *test_Message = otUdpNewMessage(myInstance, NULL);
    otMessageSetLength(test_Message, sizeof(buf));

    if (otMessageAppend(test_Message, &buf, sizeof(buf)) == OT_ERROR_NONE){
       nrf_gpio_pin_write(LED2_G, 0);
    }
    else{
       nrf_gpio_pin_write(LED2_R, 0);
    }

    otUdpSend(&mySocket, test_Message, &messageInfo);

    otCliUartOutputFormat("Done.\0");

   otUdpClose(&mySocket);
}

Сейчас мы не совсем эксперты, поэтому мы не уверены, почему это не работает, поскольку у нас было много проблем с выяснением, как все вызывается / инициализируется. Мы надеемся создать способ отправки и получения данных через UDP через код, чтобы они могли работать автономно.

Мы были бы очень благодарны, если бы кто-то помог нам с нашим проектом!

Спасибо!

Джонатан

1 ответ

В вашем коде есть несколько ошибок:

  1. Удалить звонок otMessageSetLength(), Длина сообщения автоматически увеличивается как часть otMessageAppend(),
  2. Призыв к otMessageAppend() должно быть: otMessageAppend(test_message, buf, (uint16_t)strlen(buf)),
    1. Удалил & до buf,
    2. Заменены sizeof() с strlen(),

Пара других вещей, которые вы должны рассмотреть:

  1. После звонка otUdpNewMessage(), если любой следующий вызов возвращает ошибку, обязательно позвоните otMessageFree() в буфере сообщений.
    • Хранение предоставляется OpenThread только после успешного вызова otUdpSend(),
  2. Не звони udpSend() из контекста прерывания.
    • Библиотека OpenThread была спроектирована так, чтобы предполагать выполнение одного потока.

Надеюсь, это поможет.

Другие вопросы по тегам