Part Number: LAUNCHXL-CC26X2R1
Other Parts Discussed in Thread: CC2652R7, CC1352P
Hello everyone, I've been struggling with this problem for quite some time now. Setting up OTBR from scratch. I connect the device to the network, and for a while everything is fine, but after some arbitrary period of time, sending post messages stops. GET will continue to process, but POST will not. I’ve already broken my head and don’t know where to dig and what to look at. I really hope for the community's help. I am attaching the otbr logs as well as the package logs from ubiqua and the code of the firmware itself. In fact, the firmware is a converted example of tempsensor
#include <assert.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <openthread/coap.h>
#include <openthread/ip6.h>
#include <openthread/link.h>
#include <openthread/thread.h>
#include <utils/uart.h>
#include <sched.h>
#include <pthread.h>
#include <mqueue.h>
#include <ti/drivers/GPIO.h>
#include <ti/drivers/apps/LED.h>
#include <ti/drivers/apps/Button.h>
#include <ti/display/Display.h>
#include <ti/drivers/Watchdog.h>
#include "otsupport/otrtosapi.h"
#include "otsupport/otinstance.h"
#include "ti_drivers_config.h"
#include "tempsensor.h"
#include "utils/code_utils.h"
#include "otstack.h"
#include "task_config.h"
#include "tiop_config.h"
#include "I2cSensor.h"
#include "disp_utils.h"
Watchdog_Handle watchdogHandle;
#define TIMEOUT_MS 30000
#define TIOP_TEMPSENSOR_REPORTING_INTERVAL 10000
#define DEFAULT_COAP_HEADER_TOKEN_LEN 2
#define TEMPSENSOR_PROC_QUEUE_MAX_MSG (11)
struct TempSensor_procQueueMsg {
TempSensor_evt evt;
};
static timer_t reportTimerID;
static otIp6Address multicastAddress;
static otIp6Address reportingAddress;
static char eui64[20] = {'\0'};
static uint16_t peerPort = OT_DEFAULT_COAP_PORT;
const char TempSensor_procQueueName[] = "ts_process";
static mqd_t TempSensor_procQueueDesc;
static char stack[TASK_CONFIG_TEMPSENSOR_TASK_STACK_SIZE];
static char data[40] = {'\0'};
static bool serverSetup;
//FROM CUI
void updateLedsWithChangeRole(otDeviceRole role);
static LED_Handle redLedHandle;
static LED_Handle greenLedHandle;
static Button_Handle rightButtonHandle;
static void *TempSensor_task(void *arg0);
static void reportingTimeoutCB(union sigval val);
static void configureReportingTimer(void) {
struct sigevent event = {
.sigev_notify_function = reportingTimeoutCB,
.sigev_notify = SIGEV_SIGNAL,
};
timer_create(CLOCK_MONOTONIC, &event, &reportTimerID);
}
static void startReportingTimer(uint32_t timeout) {
struct itimerspec newTime = {0};
struct itimerspec zeroTime = {0};
struct itimerspec currTime;
newTime.it_value.tv_sec = (timeout / 1000U);
newTime.it_value.tv_nsec = ((timeout % 1000U) * 1000000U);
timer_gettime(reportTimerID, &currTime);
if ((currTime.it_value.tv_sec != 0) || (currTime.it_value.tv_nsec != 0)) {
timer_settime(reportTimerID, 0, &zeroTime, NULL);
}
timer_settime(reportTimerID, 0, &newTime, NULL);
}
static void reportingTimeoutCB(union sigval val) {
TempSensor_postEvt(TempSensor_evtReportTemp);
(void) val;
}
void myServerIpHandler(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo, otError aResult) {
DISPUTILS_SERIALPRINTF(0, 0, "request handler called\n");
if(data[0] == '\0'){
uint16_t offset = otMessageGetOffset(aMessage);
uint16_t read = otMessageRead(aMessage, offset, data, 40 - 1);
data[read] = '\0';
DISPUTILS_SERIALPRINTF(0, 0, "server ip setted ip: %s\n", data);
}
}
static void tempSensorReport(void) {
otError error = OT_ERROR_NONE;
otMessage *requestMessage = NULL;
otMessageInfo messageInfo;
otMessageInfo putMessageInfo;
otInstance *instance = OtInstance_get();
DISPUTILS_SERIALPRINTF(0, 0, "start reporting function first symbol ip: %c\n", data[0]);
if(data[0] == '\0'){
DISPUTILS_SERIALPRINTF(0, 0, "Starting request server IP\n");
otExtAddress extAddress;
OtRtosApi_lock();
otLinkGetFactoryAssignedIeeeEui64(OtInstance_get(), &extAddress);
OtRtosApi_unlock();
sprintf(eui64, "0x%02x%02x%02x%02x%02x%02x%02x%02x",
extAddress.m8[0], extAddress.m8[1], extAddress.m8[2],
extAddress.m8[3], extAddress.m8[4], extAddress.m8[5],
extAddress.m8[6], extAddress.m8[7]);
eui64[19] = '\0';
OtRtosApi_lock();
requestMessage = otCoapNewMessage(instance, NULL);
otEXPECT_ACTION(requestMessage != NULL, error = OT_ERROR_NO_BUFS);
otCoapMessageInit(requestMessage, OT_COAP_TYPE_NON_CONFIRMABLE, OT_COAP_CODE_GET);
otCoapMessageGenerateToken(requestMessage, DEFAULT_COAP_HEADER_TOKEN_LEN);
error = otCoapMessageAppendUriPathOptions(requestMessage,
GET_SERVER_IP_URI);
OtRtosApi_unlock();
otEXPECT(OT_ERROR_NONE == error);
OtRtosApi_lock();
otCoapMessageSetPayloadMarker(requestMessage);
OtRtosApi_unlock();
OtRtosApi_lock();
error = otMessageAppend(requestMessage, eui64,
strlen(eui64));
OtRtosApi_unlock();
memset(&messageInfo, 0, sizeof(messageInfo));
OtRtosApi_lock();
otIp6AddressFromString("FF03::2", &multicastAddress);
OtRtosApi_unlock();
messageInfo.mPeerAddr = multicastAddress;
messageInfo.mPeerPort = peerPort;
OtRtosApi_lock();
error = otCoapSendRequest(instance, requestMessage, &messageInfo, &myServerIpHandler,
NULL);
DISPUTILS_SERIALPRINTF(0, 0, "IP requested\n");
OtRtosApi_unlock();
} else {
DISPUTILS_SERIALPRINTF(0, 0, "Starting sending report\n");
float temperatureValue = 0.0;
float humidityValue = 0.0;
Watchdog_clear(watchdogHandle);
DISPUTILS_SERIALPRINTF(0, 0, "watchdog restarted\n");
// getTemperature(&temperatureValue);
// getHumidity(&humidityValue);
DISPUTILS_SERIALPRINTF(0, 0, "readed values t: %2.1f, h: %2.0f\n", temperatureValue, humidityValue);
OtRtosApi_lock();
requestMessage = otCoapNewMessage(instance, NULL);
otEXPECT_ACTION(requestMessage != NULL, error = OT_ERROR_NO_BUFS);
otCoapMessageInit(requestMessage, OT_COAP_TYPE_NON_CONFIRMABLE, OT_COAP_CODE_POST);
otCoapMessageGenerateToken(requestMessage, DEFAULT_COAP_HEADER_TOKEN_LEN);
error = otCoapMessageAppendUriPathOptions(requestMessage,
PUT_SENSOR_DATA_URI);
OtRtosApi_unlock();
OtRtosApi_lock();
otIp6AddressFromString(data, &reportingAddress);
OtRtosApi_unlock();
OtRtosApi_lock();
otCoapMessageSetPayloadMarker(requestMessage);
OtRtosApi_unlock();
char str[200] = {'\0'};
sprintf(str, "{\"eui64\":\"%s\", \"params\": [{\"name\": \"TEMPERATURE\", \"value\": %2.1f}, {\"name\":\"HUMIDITY\", \"value\": %2.0f}]}",
eui64, temperatureValue, humidityValue);
OtRtosApi_lock();
error = otMessageAppend(requestMessage, str,
strlen(str));
OtRtosApi_unlock();
memset(&putMessageInfo, 0, sizeof(putMessageInfo));
putMessageInfo.mPeerAddr = reportingAddress;
putMessageInfo.mPeerPort = peerPort;
OtRtosApi_lock();
error = otCoapSendRequest(instance, requestMessage, &putMessageInfo, NULL,
NULL);
OtRtosApi_unlock();
char ip[40];
OtRtosApi_lock();
otIp6AddressToString(&reportingAddress, ip, 40);
OtRtosApi_unlock();
DISPUTILS_SERIALPRINTF(0, 0, "Data sended. data: %s, ip: %s:\n", eui64, ip);
}
startReportingTimer(TIOP_TEMPSENSOR_REPORTING_INTERVAL);
exit:
if (error != OT_ERROR_NONE && requestMessage != NULL) {
OtRtosApi_lock();
otMessageFree(requestMessage);
OtRtosApi_unlock();
}
}
static otError setupCoap(otInstance *aInstance) {
otError error = OT_ERROR_NONE;
OtRtosApi_lock();
error = otCoapStart(aInstance, OT_DEFAULT_COAP_PORT);
OtRtosApi_unlock();
otEXPECT(OT_ERROR_NONE == error);
exit:
return error;
}
static void processOtStackEvents(uint8_t event, void *aContext) {
(void) aContext;
switch (event) {
case OT_STACK_EVENT_NWK_JOINED: {
TempSensor_postEvt(TempSensor_evtNwkJoined);
break;
}
case OT_STACK_EVENT_NWK_JOINED_FAILURE: {
TempSensor_postEvt(TempSensor_evtNwkJoinFailure);
break;
}
case OT_STACK_EVENT_NWK_DATA_CHANGED: {
TempSensor_postEvt(TempSensor_evtNwkSetup);
break;
}
case OT_STACK_EVENT_DEV_ROLE_CHANGED: {
TempSensor_postEvt(TempSensor_evtDevRoleChanged);
break;
}
default: {
break;
}
}
}
static void processEvent(TempSensor_evt event) {
switch (event) {
case TempSensor_evtReportTemp: {
tempSensorReport();
break;
}
case TempSensor_evtNwkSetup: {
if (false == serverSetup) {
serverSetup = true;
(void) setupCoap(OtInstance_get());
TempSensor_postEvt(TempSensor_evtAddressValid);
}
break;
}
case TempSensor_evtKeyRight: {
if ((!otDatasetIsCommissioned(OtInstance_get())) &&
(OtStack_joinState() != OT_STACK_EVENT_NWK_JOIN_IN_PROGRESS)) {
DISPUTILS_SERIALPRINTF(0, 0, "Joining Nwk ...\n");
OtStack_joinConfiguredNetwork();
}
break;
}
case TempSensor_evtNwkJoined: {
DISPUTILS_SERIALPRINTF(0, 0, "Joinied Nwk\n");
(void) OtStack_setupNetwork();
break;
}
case TempSensor_evtNwkJoinFailure: {
DISPUTILS_SERIALPRINTF(0, 0, "Join Failure\n");
break;
}
case TempSensor_evtAddressValid: {
startReportingTimer(TIOP_TEMPSENSOR_REPORTING_INTERVAL);
break;
}
case TempSensor_evtDevRoleChanged: {
OtRtosApi_lock();
otDeviceRole role = otThreadGetDeviceRole(OtInstance_get());
OtRtosApi_unlock();
updateLedsWithChangeRole(role);
break;
}
default: {
break;
}
}
}
void otPlatUartReceived(const uint8_t *aBuf, uint16_t aBufLength) {
(void) aBuf;
(void) aBufLength;
}
void otPlatUartSendDone(void) {
}
void TempSensor_postEvt(TempSensor_evt event) {
struct TempSensor_procQueueMsg msg;
int ret;
msg.evt = event;
ret = mq_send(TempSensor_procQueueDesc, (const char *) &msg, sizeof(msg), 0);
assert(0 == ret);
(void) ret;
}
void TempSensor_taskCreate(void) {
pthread_t thread;
pthread_attr_t pAttrs;
struct sched_param priParam;
int retc;
retc = pthread_attr_init(&pAttrs);
assert(retc == 0);
retc = pthread_attr_setdetachstate(&pAttrs, PTHREAD_CREATE_DETACHED);
assert(retc == 0);
priParam.sched_priority = TASK_CONFIG_TEMPSENSOR_TASK_PRIORITY;
retc = pthread_attr_setschedparam(&pAttrs, &priParam);
assert(retc == 0);
retc = pthread_attr_setstack(&pAttrs, (void *) stack,
TASK_CONFIG_TEMPSENSOR_TASK_STACK_SIZE);
assert(retc == 0);
retc = pthread_create(&thread, &pAttrs, TempSensor_task, NULL);
assert(retc == 0);
retc = pthread_attr_destroy(&pAttrs);
assert(retc == 0);
(void) retc;
}
void processKeyChangeCB(Button_Handle _buttonHandle, Button_EventMask _buttonEvents) {
if (_buttonHandle == rightButtonHandle && _buttonEvents & Button_EV_CLICKED) {
TempSensor_postEvt(TempSensor_evtKeyRight);
}
}
void initButtonsAndLeds() {
Button_Params bparams;
LED_Params ledParams;
Button_Params_init(&bparams);
bparams.buttonEventMask = Button_EV_CLICKED;
rightButtonHandle = Button_open(CONFIG_BTN_RIGHT, &bparams);
if (!GPIO_read(((Button_HWAttrs *) rightButtonHandle->hwAttrs)->gpioIndex)) {
OtRtosApi_lock();
otInstanceFactoryReset(OtInstance_get());
OtRtosApi_unlock();
}
Button_setCallback(rightButtonHandle, processKeyChangeCB);
greenLedHandle = LED_open(CONFIG_LED_GREEN, &ledParams);
redLedHandle = LED_open(CONFIG_LED_RED, &ledParams);
}
void updateLedsWithChangeRole(otDeviceRole role) {
switch (role) {
case OT_DEVICE_ROLE_DISABLED: {
LED_setOff(greenLedHandle);
LED_setOff(redLedHandle);
break;
}
case OT_DEVICE_ROLE_DETACHED: {
LED_setOff(greenLedHandle);
LED_setOn(redLedHandle, LED_BRIGHTNESS_MAX);
break;
}
case OT_DEVICE_ROLE_CHILD: {
LED_setOn(greenLedHandle, LED_BRIGHTNESS_MAX);
LED_setOff(redLedHandle);
break;
}
case OT_DEVICE_ROLE_ROUTER: {
LED_setOn(greenLedHandle, LED_BRIGHTNESS_MAX);
LED_setOff(redLedHandle);
break;
}
case OT_DEVICE_ROLE_LEADER: {
LED_setOn(greenLedHandle, LED_BRIGHTNESS_MAX);
LED_setOn(redLedHandle, LED_BRIGHTNESS_MAX);
break;
}
}
}
void watchdogCallback(uintptr_t watchdogHandle)
{
while (1) {}
}
void *TempSensor_task(void *arg0) {
Watchdog_Params params;
uint32_t reloadValue;
Watchdog_Params_init(¶ms);
params.callbackFxn = (Watchdog_Callback)watchdogCallback;
params.debugStallMode = Watchdog_DEBUG_STALL_ON;
params.resetMode = Watchdog_RESET_ON;
watchdogHandle = Watchdog_open(CONFIG_WATCHDOG0, ¶ms);
reloadValue = Watchdog_convertMsToTicks(watchdogHandle, TIMEOUT_MS);
if (reloadValue != 0)
{
Watchdog_setReload(watchdogHandle, reloadValue);
}
struct mq_attr attr;
bool commissioned;
mqd_t procQueueLoopDesc;
attr.mq_curmsgs = 0;
attr.mq_flags = 0;
attr.mq_maxmsg = TEMPSENSOR_PROC_QUEUE_MAX_MSG;
attr.mq_msgsize = sizeof(struct TempSensor_procQueueMsg);
TempSensor_procQueueDesc = mq_open(TempSensor_procQueueName,
(O_WRONLY | O_NONBLOCK | O_CREAT),
0, &attr);
procQueueLoopDesc = mq_open(TempSensor_procQueueName, O_RDONLY, 0, NULL);
DispUtils_open();
OtStack_taskCreate();
OtStack_registerCallback(processOtStackEvents);
OtRtosApi_lock();
otLinkSetPollPeriod(OtInstance_get(), TIOP_CONFIG_POLL_PERIOD);
OtRtosApi_unlock();
initButtonsAndLeds();
OtRtosApi_lock();
commissioned = otDatasetIsCommissioned(OtInstance_get());
OtRtosApi_unlock();
if (true == commissioned) {
OtStack_setupInterfaceAndNetwork();
}
configureReportingTimer();
/* process events */
while (true) {
DISPUTILS_SERIALPRINTF(0, 0, "main while\n");
struct TempSensor_procQueueMsg msg;
ssize_t ret;
ret = mq_receive(procQueueLoopDesc, (char *) &msg, sizeof(msg), NULL);
if (ret < 0 || ret != sizeof(msg)) {
continue;
}
processEvent(msg.evt);
}
return NULL;
}