主题中讨论的其他器件:CC2652R7、 CC1352P
大家好、我在这个问题上花了很长时间。 从头开始设置 OTBR。 我将设备连接到网络,有一段时间一切正常,但经过一段时间后,发送 POST 消息停止。 GET 将继续处理、但 POST 不会。 我已经晕头转向、不知道该深入研究什么以及看什么。 我非常希望社区的帮助。 我将随附 oubr 日志以及来自 ubiqua 的软件包日志和固件本身的代码。 事实上、固件是一个转换型温度传感器示例、
#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;
}