mirror of
https://github.com/openharmony/communication_t2stack.git
synced 2026-07-22 17:25:22 -04:00
fec3d60d02
Signed-off-by: xieqiangde <xieqiangde@huawei.com>
1422 lines
44 KiB
C
1422 lines
44 KiB
C
/*
|
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "nstackx_common.h"
|
|
|
|
#include <securec.h>
|
|
#ifndef _WIN32
|
|
#include <pthread.h>
|
|
#include <semaphore.h>
|
|
#include <unistd.h>
|
|
#endif
|
|
#include "cJSON.h"
|
|
|
|
#include "coap_app.h"
|
|
#include "coap_discover.h"
|
|
#include "nstackx.h"
|
|
#include "nstackx_device.h"
|
|
#include "nstackx_epoll.h"
|
|
#include "nstackx_error.h"
|
|
#include "nstackx_event.h"
|
|
#include "nstackx_dfinder_log.h"
|
|
#include "nstackx_smartgenius.h"
|
|
#include "nstackx_timer.h"
|
|
#include "nstackx_util.h"
|
|
#include "json_payload.h"
|
|
#include "nstackx_statistics.h"
|
|
#include "nstackx_dfinder_hidump.h"
|
|
#include "nstackx_dfinder_hievent.h"
|
|
|
|
#ifdef DFINDER_USE_MINI_NSTACKX
|
|
#include "cmsis_os2.h"
|
|
#include "ohos_init.h"
|
|
#define DFINDER_THREAD_STACK_SIZE (1024 * 32)
|
|
#endif
|
|
|
|
#define TAG "nStackXDFinder"
|
|
#define DFINDER_THREAD_NAME TAG
|
|
|
|
enum {
|
|
NSTACKX_INIT_STATE_START = 0,
|
|
NSTACKX_INIT_STATE_ONGOING,
|
|
NSTACKX_INIT_STATE_DONE,
|
|
};
|
|
|
|
#ifdef DFINDER_USE_MINI_NSTACKX
|
|
static osThreadId_t g_threadId;
|
|
#else
|
|
static pthread_t g_tid;
|
|
#endif
|
|
|
|
static EpollDesc g_epollfd = INVALID_EPOLL_DESC;
|
|
static List g_eventNodeChain = {&(g_eventNodeChain), &(g_eventNodeChain)};
|
|
|
|
static uint8_t g_validTidFlag = NSTACKX_FALSE;
|
|
static uint8_t g_terminateFlag = NSTACKX_FALSE;
|
|
|
|
static NSTACKX_Parameter g_parameter;
|
|
static uint8_t g_nstackInitState;
|
|
|
|
#define EVENT_COUNT_RATE_INTERVAL 2000 /* 2 SECONDS */
|
|
#define MAX_EVENT_PROCESS_NUM_PER_INTERVAL 700
|
|
#define MAX_CONTINUOUS_BUSY_INTERVAL_NUM 20
|
|
|
|
typedef struct {
|
|
uint32_t epollWaitTimeoutCount;
|
|
uint32_t epollWaitEventCount;
|
|
struct timespec measureBefore;
|
|
} EventProcessRatePara;
|
|
static EventProcessRatePara g_processRatePara;
|
|
static uint32_t g_continuousBusyIntervals;
|
|
|
|
static int32_t CheckDiscoverySettings(const NSTACKX_DiscoverySettings *discoverySettings);
|
|
|
|
List *GetEventNodeChain(void)
|
|
{
|
|
return &g_eventNodeChain;
|
|
}
|
|
|
|
EpollDesc GetEpollFD(void)
|
|
{
|
|
return g_epollfd;
|
|
}
|
|
|
|
void NotifyDFinderMsgRecver(DFinderMsgType msgType)
|
|
{
|
|
if (g_parameter.onDFinderMsgReceived != NULL) {
|
|
g_parameter.onDFinderMsgReceived(msgType);
|
|
}
|
|
}
|
|
|
|
/* check if we need to reply a unicast based on businessType. */
|
|
int32_t CheckBusinessTypeReplyUnicast(uint8_t businessType)
|
|
{
|
|
switch (businessType) {
|
|
case NSTACKX_BUSINESS_TYPE_NULL:
|
|
return NSTACKX_EOK;
|
|
|
|
case NSTACKX_BUSINESS_TYPE_HICOM:
|
|
return NSTACKX_EOK;
|
|
|
|
case NSTACKX_BUSINESS_TYPE_SOFTBUS:
|
|
return NSTACKX_EFAILED;
|
|
|
|
case NSTACKX_BUSINESS_TYPE_NEARBY:
|
|
return NSTACKX_EOK;
|
|
|
|
default: /* Unknown businessType */
|
|
return NSTACKX_EOK;
|
|
}
|
|
}
|
|
|
|
uint32_t GetDefaultDiscoverInterval(uint32_t discoverCount)
|
|
{
|
|
if (discoverCount < COAP_FIRST_DISCOVER_COUNT_RANGE) {
|
|
return COAP_FIRST_DISCOVER_INTERVAL;
|
|
} else if (discoverCount < COAP_SECOND_DISCOVER_COUNT_RANGE) {
|
|
return COAP_SECOND_DISCOVER_INTERVAL;
|
|
} else {
|
|
return COAP_LAST_DISCOVER_INTERVAL;
|
|
}
|
|
}
|
|
|
|
int32_t GetServiceDiscoverInfo(const uint8_t *buf, size_t size, DeviceInfo *deviceInfo, char **remoteUrlPtr)
|
|
{
|
|
uint8_t *newBuf = NULL;
|
|
if (size <= 0) {
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
if (buf[size - 1] != '\0') {
|
|
newBuf = (uint8_t *)calloc(size + 1, 1U);
|
|
if (newBuf == NULL) {
|
|
DFINDER_LOGE(TAG, "data is not end with 0 and new buf calloc error");
|
|
return NSTACKX_ENOMEM;
|
|
}
|
|
if (memcpy_s(newBuf, size + 1, buf, size) != EOK) {
|
|
DFINDER_LOGE(TAG, "data is not end with 0 and memcpy data error");
|
|
goto L_COAP_ERR;
|
|
}
|
|
DFINDER_LOGI(TAG, "data is not end with 0");
|
|
buf = newBuf;
|
|
}
|
|
if (ParseServiceDiscover(buf, deviceInfo, remoteUrlPtr) != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "parse service discover error");
|
|
goto L_COAP_ERR;
|
|
}
|
|
|
|
if (newBuf != NULL) {
|
|
free(newBuf);
|
|
}
|
|
|
|
return NSTACKX_EOK;
|
|
L_COAP_ERR:
|
|
if (newBuf != NULL) {
|
|
free(newBuf);
|
|
}
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
|
|
static void ResetMainEpollTaskCount(uint8_t isBusy)
|
|
{
|
|
EpollTask *task = GetEpollTask(&g_eventNodeChain, g_epollfd);
|
|
if (task == NULL) {
|
|
return;
|
|
}
|
|
if (isBusy) {
|
|
DFINDER_LOGI(TAG, "in this busy interval: main epoll task count %llu", task->count);
|
|
}
|
|
task->count = 0;
|
|
}
|
|
|
|
static uint8_t IsBusyInterval(uint32_t eventCount, uint32_t timeMs)
|
|
{
|
|
uint8_t retFlag;
|
|
if ((uint64_t)eventCount * EVENT_COUNT_RATE_INTERVAL <
|
|
MAX_EVENT_PROCESS_NUM_PER_INTERVAL * (uint64_t)timeMs) {
|
|
retFlag = NSTACKX_FALSE;
|
|
} else {
|
|
retFlag = NSTACKX_TRUE;
|
|
}
|
|
|
|
ResetMainEpollTaskCount(retFlag);
|
|
ResetCoapSocketTaskCount(retFlag);
|
|
ResetCoapDiscoverTaskCount(retFlag);
|
|
ResetDeviceTaskCount(retFlag);
|
|
#ifndef DFINDER_USE_MINI_NSTACKX
|
|
ResetSmartGeniusTaskCount(retFlag);
|
|
#endif /* END OF DFINDER_USE_MINI_NSTACKX */
|
|
|
|
return retFlag;
|
|
}
|
|
|
|
static void CalculateEventProcessRate(void)
|
|
{
|
|
struct timespec now;
|
|
ClockGetTime(CLOCK_MONOTONIC, &now);
|
|
uint32_t measureElapse = GetTimeDiffMs(&now, &g_processRatePara.measureBefore);
|
|
if (measureElapse > EVENT_COUNT_RATE_INTERVAL) {
|
|
uint32_t totalCount = g_processRatePara.epollWaitEventCount + g_processRatePara.epollWaitTimeoutCount;
|
|
if (!IsBusyInterval(totalCount, measureElapse)) {
|
|
g_continuousBusyIntervals = 0;
|
|
} else {
|
|
DFINDER_LOGI(TAG, "main loop seems to be busy in the past interval. Timeout count %u, event count %u",
|
|
g_processRatePara.epollWaitTimeoutCount, g_processRatePara.epollWaitEventCount);
|
|
g_continuousBusyIntervals++;
|
|
if (g_continuousBusyIntervals >= MAX_CONTINUOUS_BUSY_INTERVAL_NUM) {
|
|
DFINDER_LOGE(TAG, "main loop seems to be busy in the past %u intervals. notify user to restart",
|
|
g_continuousBusyIntervals);
|
|
NotifyDFinderMsgRecver(DFINDER_ON_TOO_BUSY);
|
|
g_continuousBusyIntervals = 0;
|
|
}
|
|
}
|
|
g_processRatePara.epollWaitTimeoutCount = 0;
|
|
g_processRatePara.epollWaitEventCount = 0;
|
|
ClockGetTime(CLOCK_MONOTONIC, &g_processRatePara.measureBefore);
|
|
}
|
|
}
|
|
|
|
static void *NstackMainLoop(void *arg)
|
|
{
|
|
int32_t ret;
|
|
(void)arg;
|
|
(void)memset_s(&g_processRatePara, sizeof(g_processRatePara), 0, sizeof(g_processRatePara));
|
|
g_continuousBusyIntervals = 0;
|
|
ClockGetTime(CLOCK_MONOTONIC, &g_processRatePara.measureBefore);
|
|
#ifndef DFINDER_USE_MINI_NSTACKX
|
|
SetThreadName(DFINDER_THREAD_NAME);
|
|
#endif
|
|
while (g_terminateFlag == NSTACKX_FALSE) {
|
|
#ifndef DFINDER_USE_MINI_NSTACKX
|
|
uint32_t timeout = RegisterCoAPEpollTask(g_epollfd);
|
|
ret = EpollLoop(g_epollfd, timeout);
|
|
#else
|
|
ret = EpollLoop(g_epollfd, -1);
|
|
#endif /* END OF DFINDER_USE_MINI_NSTACKX */
|
|
if (ret == NSTACKX_EFAILED) {
|
|
IncStatistics(STATS_EPOLL_ERROR);
|
|
DFINDER_LOGE(TAG, "epoll loop failed");
|
|
#ifndef DFINDER_USE_MINI_NSTACKX
|
|
DeRegisterCoAPEpollTask();
|
|
#endif /* END OF DFINDER_USE_MINI_NSTACKX */
|
|
break;
|
|
} else if (ret == NSTACKX_ETIMEOUT) {
|
|
g_processRatePara.epollWaitTimeoutCount++;
|
|
} else if (ret > 0) {
|
|
g_processRatePara.epollWaitEventCount++;
|
|
} else {
|
|
/* do nothing */
|
|
}
|
|
CalculateEventProcessRate();
|
|
#ifndef DFINDER_USE_MINI_NSTACKX
|
|
DeRegisterCoAPEpollTask();
|
|
#endif /* END OF DFINDER_USE_MINI_NSTACKX */
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
EpollDesc GetMainLoopEpollFd(void)
|
|
{
|
|
return g_epollfd;
|
|
}
|
|
|
|
List *GetMainLoopEvendChain(void)
|
|
{
|
|
return &g_eventNodeChain;
|
|
}
|
|
|
|
static int32_t InternalInit(EpollDesc epollfd, uint32_t maxDeviceNum)
|
|
{
|
|
int32_t ret = EventModuleInit(&g_eventNodeChain, g_epollfd);
|
|
if (ret != NSTACKX_EOK) {
|
|
return ret;
|
|
}
|
|
|
|
ret = DeviceModuleInit(epollfd, maxDeviceNum);
|
|
if (ret != NSTACKX_EOK) {
|
|
return ret;
|
|
}
|
|
|
|
#if !defined(DFINDER_SUPPORT_MULTI_NIF) && !defined(DFINDER_USE_MINI_NSTACKX)
|
|
ret = P2pUsbTimerInit(epollfd);
|
|
if (ret != NSTACKX_EOK) {
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
#ifdef _WIN32
|
|
ret = CoapThreadInit();
|
|
if (ret != NSTACKX_EOK) {
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
#ifndef DFINDER_SUPPORT_MULTI_NIF
|
|
ret = CoapServerInit(NULL);
|
|
if (ret != NSTACKX_EOK) {
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
ret = CoapDiscoverInit(epollfd);
|
|
if (ret != NSTACKX_EOK) {
|
|
return ret;
|
|
}
|
|
|
|
#ifndef DFINDER_USE_MINI_NSTACKX
|
|
ret = SmartGeniusInit(epollfd);
|
|
#endif /* END OF DFINDER_USE_MINI_NSTACKX */
|
|
return ret;
|
|
}
|
|
|
|
static int32_t NstackxInitInner(uint32_t maxDeviceNum)
|
|
{
|
|
int32_t ret;
|
|
#ifdef DFINDER_USE_MINI_NSTACKX
|
|
ret = InternalInit(g_epollfd, maxDeviceNum);
|
|
if (ret != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "internal init failed");
|
|
return ret;
|
|
}
|
|
#endif
|
|
g_terminateFlag = NSTACKX_FALSE;
|
|
g_validTidFlag = NSTACKX_FALSE;
|
|
#ifndef DFINDER_USE_MINI_NSTACKX
|
|
ret = PthreadCreate(&g_tid, NULL, NstackMainLoop, NULL);
|
|
if (ret != 0) {
|
|
DFINDER_LOGE(TAG, "thread create failed");
|
|
return ret;
|
|
}
|
|
#else
|
|
osThreadAttr_t attr = {0};
|
|
attr.name = DFINDER_THREAD_NAME;
|
|
attr.stack_size = DFINDER_THREAD_STACK_SIZE;
|
|
// osPriorityNormal equals 24
|
|
attr.priority = osPriorityNormal;
|
|
g_threadId = osThreadNew((osThreadFunc_t)NstackMainLoop, NULL, &attr);
|
|
if (g_threadId == NULL) {
|
|
DFINDER_LOGE(TAG, "thread create failed with attribute settings");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
#endif
|
|
g_validTidFlag = NSTACKX_TRUE;
|
|
#ifndef DFINDER_USE_MINI_NSTACKX
|
|
ret = InternalInit(g_epollfd, maxDeviceNum);
|
|
if (ret != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "internal init failed");
|
|
return ret;
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
int32_t NSTACKX_Init(const NSTACKX_Parameter *parameter)
|
|
{
|
|
int32_t ret;
|
|
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_START) {
|
|
return NSTACKX_EOK;
|
|
}
|
|
|
|
g_nstackInitState = NSTACKX_INIT_STATE_ONGOING;
|
|
cJSON_InitHooks(NULL);
|
|
#ifdef ENABLE_USER_LOG
|
|
SetDFinderLogLevel(DFINDER_LOG_LEVEL_DEBUG);
|
|
#endif
|
|
SetLogLevel(NSTACKX_LOG_LEVEL_DEBUG);
|
|
|
|
#ifdef NSTACKX_WITH_LITEOS
|
|
EpollEventPtrInit(); /* init g_epollEventPtrMutex g_epollEventPtrArray */
|
|
#endif
|
|
|
|
g_epollfd = CreateEpollDesc();
|
|
if (!IsEpollDescValid(g_epollfd)) {
|
|
DFINDER_LOGE(TAG, "epoll creat fail! errno: %d", errno);
|
|
g_nstackInitState = NSTACKX_INIT_STATE_START;
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
|
|
DFINDER_LOGD(TAG, "nstack ctrl creat epollfd %d", REPRESENT_EPOLL_DESC(g_epollfd));
|
|
#ifdef DFINDER_SAVE_DEVICE_LIST
|
|
ret = NstackxInitInner(parameter != NULL ? parameter->maxDeviceNum : NSTACKX_DEFAULT_DEVICE_NUM);
|
|
#else
|
|
ret = NstackxInitInner(parameter != NULL ? parameter->maxDeviceNum : NSTACKX_MAX_DEVICE_NUM);
|
|
#endif
|
|
if (ret != NSTACKX_EOK) {
|
|
goto L_ERR_INIT;
|
|
}
|
|
(void)memset_s(&g_parameter, sizeof(g_parameter), 0, sizeof(g_parameter));
|
|
if (parameter != NULL) {
|
|
(void)memcpy_s(&g_parameter, sizeof(g_parameter), parameter, sizeof(NSTACKX_Parameter));
|
|
}
|
|
|
|
#ifndef DFINDER_USE_MINI_NSTACKX
|
|
CoapInitSubscribeModuleInner(); /* initialize subscribe module number */
|
|
#endif /* END OF DFINDER_USE_MINI_NSTACKX */
|
|
InitStatistics();
|
|
g_nstackInitState = NSTACKX_INIT_STATE_DONE;
|
|
DFINDER_LOGI(TAG, "DFinder init successfully");
|
|
return NSTACKX_EOK;
|
|
|
|
L_ERR_INIT:
|
|
NSTACKX_Deinit();
|
|
return ret;
|
|
}
|
|
|
|
#ifdef DFINDER_USE_MINI_NSTACKX
|
|
static void ReportMainLoopStopInner(void *argument)
|
|
{
|
|
(void)argument;
|
|
LOGI(TAG, "receive message to stop main loop");
|
|
}
|
|
|
|
static void ReportMainLoopStop(void)
|
|
{
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
|
|
LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
|
|
return;
|
|
}
|
|
if (PostEvent(&g_eventNodeChain, g_epollfd, ReportMainLoopStopInner, NULL) != NSTACKX_EOK) {
|
|
LOGE(TAG, "Failed to report mainloop stop!");
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void NSTACKX_Deinit(void)
|
|
{
|
|
if (g_nstackInitState == NSTACKX_INIT_STATE_START) {
|
|
return;
|
|
}
|
|
if (g_validTidFlag) {
|
|
g_terminateFlag = NSTACKX_TRUE;
|
|
#ifndef DFINDER_USE_MINI_NSTACKX
|
|
PthreadJoin(g_tid, NULL);
|
|
#else
|
|
ReportMainLoopStop();
|
|
if (osThreadTerminate(g_threadId) != osOK) {
|
|
LOGE(TAG, "os thread terminate failed");
|
|
}
|
|
#endif
|
|
g_validTidFlag = NSTACKX_FALSE;
|
|
}
|
|
#ifndef DFINDER_USE_MINI_NSTACKX
|
|
SmartGeniusClean();
|
|
#endif /* END OF DFINDER_USE_MINI_NSTACKX */
|
|
CoapDiscoverDeinit();
|
|
#ifdef DFINDER_SUPPORT_MULTI_NIF
|
|
for (uint32_t i = 0; i < NSTACKX_MAX_LISTENED_NIF_NUM; ++i) {
|
|
DFINDER_LOGE(TAG, "nstackx_deinit nif with idx-%u", i);
|
|
CoapServerDestroyWithIdx(i);
|
|
}
|
|
#else
|
|
#ifndef DFINDER_USE_MINI_NSTACKX
|
|
DestroyP2pUsbServerInitRetryTimer();
|
|
#endif /* END OF DFINDER_USE_MINI_NSTACKX */
|
|
CoapServerDestroy();
|
|
#ifndef DFINDER_USE_MINI_NSTACKX
|
|
CoapP2pServerDestroy();
|
|
CoapUsbServerDestroy();
|
|
#endif /* END OF DFINDER_USE_MINI_NSTACKX */
|
|
#endif /* END OF DFINDER_SUPPORT_MULTI_NIF */
|
|
#ifdef _WIN32
|
|
CoapThreadDestory();
|
|
#endif
|
|
DeviceModuleClean();
|
|
EventNodeChainClean(&g_eventNodeChain);
|
|
if (IsEpollDescValid(g_epollfd)) {
|
|
CloseEpollDesc(g_epollfd);
|
|
g_epollfd = INVALID_EPOLL_DESC;
|
|
}
|
|
|
|
g_nstackInitState = NSTACKX_INIT_STATE_START;
|
|
DFINDER_LOGI(TAG, "deinit successfully");
|
|
}
|
|
|
|
static void DeviceDiscoverInner(void *argument)
|
|
{
|
|
(void)argument;
|
|
CoapServiceDiscoverInner(INNER_DISCOVERY);
|
|
|
|
#ifdef DFINDER_SUPPORT_MULTI_NIF
|
|
if (!IsApConnected()) {
|
|
DFINDER_LOGE(TAG, "all ap not connected, notify user with empty list");
|
|
NotifyDeviceFound(NULL, 0);
|
|
}
|
|
#else
|
|
/* If both Wifi AP and BLE are disabled, we should also notify user, with empty list. */
|
|
if (!IsWifiApConnected()) {
|
|
NotifyDeviceFound(NULL, 0);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
static void DeviceDiscoverInnerAn(void *argument)
|
|
{
|
|
(void)argument;
|
|
CoapServiceDiscoverInnerAn(INNER_DISCOVERY);
|
|
}
|
|
|
|
static void DeviceDiscoverInnerConfigurable(void *argument)
|
|
{
|
|
NSTACKX_DiscoverySettings *discoverySettings = argument;
|
|
if (discoverySettings->businessType != GetLocalDeviceInfoPtr()->businessType) {
|
|
DFINDER_LOGE(TAG, "businessType is diff when check discover settings");
|
|
free(discoverySettings->businessData);
|
|
free(discoverySettings);
|
|
return;
|
|
}
|
|
ConfigureDiscoverySettings(discoverySettings);
|
|
free(discoverySettings->businessData);
|
|
free(discoverySettings);
|
|
CoapServiceDiscoverInnerConfigurable(INNER_DISCOVERY);
|
|
}
|
|
|
|
static void DeviceDiscoverStopInner(void *argument)
|
|
{
|
|
(void)argument;
|
|
CoapServiceDiscoverStopInner();
|
|
NotifyStatisticsEvent();
|
|
}
|
|
|
|
int32_t NSTACKX_StartDeviceFind(void)
|
|
{
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
|
|
DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
if (PostEvent(&g_eventNodeChain, g_epollfd, DeviceDiscoverInner, NULL) != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "Failed to start device discover!");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
return NSTACKX_EOK;
|
|
}
|
|
|
|
int32_t NSTACKX_StartDeviceFindAn(uint8_t mode)
|
|
{
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
|
|
DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
SetModeInfo(mode);
|
|
if (PostEvent(&g_eventNodeChain, g_epollfd, DeviceDiscoverInnerAn, NULL) != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "Failed to start device discover!");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
return NSTACKX_EOK;
|
|
}
|
|
|
|
int32_t NSTACKX_StopDeviceFind(void)
|
|
{
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
|
|
DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
if (PostEvent(&g_eventNodeChain, g_epollfd, DeviceDiscoverStopInner, NULL) != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "Failed to stop device discover!");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
return NSTACKX_EOK;
|
|
}
|
|
|
|
static int32_t CopyDiscoverySettings(NSTACKX_DiscoverySettings *dupDiscoverySettings,
|
|
const NSTACKX_DiscoverySettings *discoverySettings)
|
|
{
|
|
dupDiscoverySettings->businessType = discoverySettings->businessType;
|
|
dupDiscoverySettings->discoveryMode = discoverySettings->discoveryMode;
|
|
dupDiscoverySettings->length = discoverySettings->length;
|
|
if (discoverySettings->businessData != NULL) {
|
|
if (strncpy_s(dupDiscoverySettings->businessData, (dupDiscoverySettings->length + 1),
|
|
discoverySettings->businessData, discoverySettings->length) != EOK) {
|
|
DFINDER_LOGE(TAG, "businessData strncpy failed");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
}
|
|
dupDiscoverySettings->advertiseCount = discoverySettings->advertiseCount;
|
|
dupDiscoverySettings->advertiseDuration = discoverySettings->advertiseDuration;
|
|
return NSTACKX_EOK;
|
|
}
|
|
|
|
static int32_t CheckDiscoverySettings(const NSTACKX_DiscoverySettings *discoverySettings)
|
|
{
|
|
if (discoverySettings == NULL) {
|
|
DFINDER_LOGE(TAG, "Invalid discoverySettings info");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
if ((discoverySettings->businessData == NULL) && (discoverySettings->length != 0)) {
|
|
DFINDER_LOGE(TAG, "Invalid discoverySettings bData info");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
if (discoverySettings->length >= NSTACKX_MAX_BUSINESS_DATA_LEN) {
|
|
DFINDER_LOGE(TAG, "businessData length is too long");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
uint32_t advertiseCount = discoverySettings->advertiseCount;
|
|
uint32_t advertiseDuration = discoverySettings->advertiseDuration;
|
|
if ((advertiseCount == 0) && (advertiseDuration == 0)) {
|
|
return NSTACKX_EOK;
|
|
}
|
|
if ((advertiseCount < NSTACKX_MIN_ADVERTISE_COUNT) || (advertiseCount > NSTACKX_MAX_ADVERTISE_COUNT) ||
|
|
(advertiseDuration < NSTACKX_MIN_ADVERTISE_DURATION) || (advertiseDuration > NSTACKX_MAX_ADVERTISE_DURATION)) {
|
|
DFINDER_LOGE(TAG, "Invalid discoverySettings advertise info");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
return NSTACKX_EOK;
|
|
}
|
|
|
|
int32_t NSTACKX_StartDeviceDiscovery(const NSTACKX_DiscoverySettings *discoverySettings)
|
|
{
|
|
DFINDER_LOGI(TAG, "begin to NSTACKX_StartDeviceDiscovery!");
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
|
|
DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
if (CheckDiscoverySettings(discoverySettings) != NSTACKX_EOK) {
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
|
|
NSTACKX_DiscoverySettings *dupDiscoverySettings = malloc(sizeof(NSTACKX_DiscoverySettings));
|
|
if (dupDiscoverySettings == NULL) {
|
|
DFINDER_LOGE(TAG, "malloc failed");
|
|
return NSTACKX_ENOMEM;
|
|
}
|
|
dupDiscoverySettings->businessData = (char *)calloc((discoverySettings->length + 1), sizeof(char));
|
|
if (dupDiscoverySettings->businessData == NULL) {
|
|
DFINDER_LOGE(TAG, "businessData calloc fail");
|
|
free(dupDiscoverySettings);
|
|
return NSTACKX_ENOMEM;
|
|
}
|
|
if (CopyDiscoverySettings(dupDiscoverySettings, discoverySettings) != NSTACKX_EOK) {
|
|
free(dupDiscoverySettings->businessData);
|
|
free(dupDiscoverySettings);
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
|
|
if (PostEvent(&g_eventNodeChain, g_epollfd, DeviceDiscoverInnerConfigurable, dupDiscoverySettings) != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "Failed to start device discover!");
|
|
free(dupDiscoverySettings->businessData);
|
|
free(dupDiscoverySettings);
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
return NSTACKX_EOK;
|
|
}
|
|
|
|
#ifndef DFINDER_USE_MINI_NSTACKX
|
|
static void SubscribeModuleInner(void *argument)
|
|
{
|
|
(void)argument;
|
|
CoapSubscribeModuleInner(INNER_DISCOVERY);
|
|
}
|
|
|
|
int32_t NSTACKX_SubscribeModule(void)
|
|
{
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
|
|
DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
if (PostEvent(&g_eventNodeChain, g_epollfd, SubscribeModuleInner, NULL) != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "Failed to subscribe module!");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
return NSTACKX_EOK;
|
|
}
|
|
|
|
static void UnsubscribeModuleInner(void *argument)
|
|
{
|
|
(void)argument;
|
|
CoapUnsubscribeModuleInner(INNER_DISCOVERY);
|
|
}
|
|
|
|
int32_t NSTACKX_UnsubscribeModule(void)
|
|
{
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
|
|
if (PostEvent(&g_eventNodeChain, g_epollfd, UnsubscribeModuleInner, NULL) != NSTACKX_EOK) {
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
return NSTACKX_EOK;
|
|
}
|
|
#endif /* END OF DFINDER_USE_MINI_NSTACKX */
|
|
|
|
static void ConfigureLocalDeviceInfoInner(void *argument)
|
|
{
|
|
NSTACKX_LocalDeviceInfo *localDeviceInfo = argument;
|
|
|
|
ConfigureLocalDeviceInfo(localDeviceInfo);
|
|
free(localDeviceInfo);
|
|
}
|
|
|
|
int32_t NSTACKX_RegisterDevice(const NSTACKX_LocalDeviceInfo *localDeviceInfo)
|
|
{
|
|
DFINDER_LOGI(TAG, "begin to NSTACKX_RegisterDevice!");
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
|
|
DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
|
|
if (localDeviceInfo == NULL) {
|
|
DFINDER_LOGE(TAG, "Invalid local device info");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
|
|
#ifdef DFINDER_SUPPORT_MULTI_NIF
|
|
if (localDeviceInfo->ifNums > NSTACKX_MAX_LISTENED_NIF_NUM || localDeviceInfo->ifNums == 0) {
|
|
#else
|
|
if (localDeviceInfo->ifNums > NSTACKX_MAX_LISTENED_NIF_NUM) {
|
|
#endif
|
|
DFINDER_LOGE(TAG, "Invalid ifNums %hhu", localDeviceInfo->ifNums);
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
|
|
NSTACKX_LocalDeviceInfo *dupLocalDeviceInfo = malloc(sizeof(NSTACKX_LocalDeviceInfo));
|
|
if (dupLocalDeviceInfo == NULL) {
|
|
return NSTACKX_ENOMEM;
|
|
}
|
|
|
|
if (memcpy_s(dupLocalDeviceInfo, sizeof(NSTACKX_LocalDeviceInfo),
|
|
localDeviceInfo, sizeof(NSTACKX_LocalDeviceInfo)) != EOK) {
|
|
DFINDER_LOGE(TAG, "memcpy failed");
|
|
goto L_ERROR;
|
|
}
|
|
#ifndef DFINDER_SUPPORT_MULTI_NIF
|
|
if (localDeviceInfo->ifNums != 0) {
|
|
if (strcpy_s(dupLocalDeviceInfo->networkName, NSTACKX_MAX_INTERFACE_NAME_LEN,
|
|
localDeviceInfo->localIfInfo[0].networkName) != EOK) {
|
|
DFINDER_LOGE(TAG, "network name strcpy failed");
|
|
goto L_ERROR;
|
|
}
|
|
if (strcpy_s(dupLocalDeviceInfo->networkIpAddr, NSTACKX_MAX_IP_STRING_LEN,
|
|
localDeviceInfo->localIfInfo[0].networkIpAddr) != EOK) {
|
|
DFINDER_LOGE(TAG, "network ip strcpy failed");
|
|
goto L_ERROR;
|
|
}
|
|
}
|
|
#endif
|
|
if (PostEvent(&g_eventNodeChain, g_epollfd, ConfigureLocalDeviceInfoInner, dupLocalDeviceInfo) != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "Failed to configure local device info!");
|
|
goto L_ERROR;
|
|
}
|
|
return NSTACKX_EOK;
|
|
L_ERROR:
|
|
free(dupLocalDeviceInfo);
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
|
|
int32_t NSTACKX_RegisterDeviceAn(const NSTACKX_LocalDeviceInfo *localDeviceInfo, uint64_t deviceHash)
|
|
{
|
|
NSTACKX_LocalDeviceInfo *dupLocalDeviceInfo = NULL;
|
|
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
|
|
DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
|
|
if (localDeviceInfo == NULL) {
|
|
DFINDER_LOGE(TAG, "Invalid local device info");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
|
|
dupLocalDeviceInfo = malloc(sizeof(NSTACKX_LocalDeviceInfo));
|
|
if (dupLocalDeviceInfo == NULL) {
|
|
return NSTACKX_ENOMEM;
|
|
}
|
|
|
|
if (memcpy_s(dupLocalDeviceInfo, sizeof(NSTACKX_LocalDeviceInfo),
|
|
localDeviceInfo, sizeof(NSTACKX_LocalDeviceInfo)) != EOK) {
|
|
free(dupLocalDeviceInfo);
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
if (PostEvent(&g_eventNodeChain, g_epollfd, ConfigureLocalDeviceInfoInner, dupLocalDeviceInfo) != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "Failed to configure local device info!");
|
|
free(dupLocalDeviceInfo);
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
SetDeviceHash(deviceHash);
|
|
return NSTACKX_EOK;
|
|
}
|
|
|
|
typedef struct {
|
|
uint32_t capabilityBitmapNum;
|
|
uint32_t capabilityBitmap[NSTACKX_MAX_CAPABILITY_NUM];
|
|
} CapabilityProcessData;
|
|
|
|
static void RegisterCapabilityInner(void *argument)
|
|
{
|
|
LOGI(TAG, "Register Capability Inner");
|
|
CapabilityProcessData *capabilityData = argument;
|
|
|
|
RegisterCapability(capabilityData->capabilityBitmapNum, capabilityData->capabilityBitmap);
|
|
free(capabilityData);
|
|
}
|
|
|
|
static void SetFilterCapabilityInner(void *argument)
|
|
{
|
|
CapabilityProcessData *capabilityData = argument;
|
|
|
|
SetFilterCapability(capabilityData->capabilityBitmapNum, capabilityData->capabilityBitmap);
|
|
free(capabilityData);
|
|
}
|
|
|
|
static int32_t NSTACKX_CapabilityHandle(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[], EventHandle handle)
|
|
{
|
|
CapabilityProcessData *capabilityData = NULL;
|
|
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
|
|
DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
|
|
if (capabilityBitmapNum > NSTACKX_MAX_CAPABILITY_NUM) {
|
|
DFINDER_LOGE(TAG, "capabilityBitmapNum (%u) exceed max number", capabilityBitmapNum);
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
|
|
capabilityData = calloc(1U, sizeof(CapabilityProcessData));
|
|
if (capabilityData == NULL) {
|
|
return NSTACKX_ENOMEM;
|
|
}
|
|
|
|
if ((capabilityBitmapNum != 0) && memcpy_s(capabilityData->capabilityBitmap,
|
|
sizeof(capabilityData->capabilityBitmap), capabilityBitmap, capabilityBitmapNum * sizeof(uint32_t)) != EOK) {
|
|
free(capabilityData);
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
capabilityData->capabilityBitmapNum = capabilityBitmapNum;
|
|
|
|
if (PostEvent(&g_eventNodeChain, g_epollfd, handle, capabilityData) != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "Failed to register capability!");
|
|
free(capabilityData);
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
return NSTACKX_EOK;
|
|
}
|
|
|
|
int32_t NSTACKX_RegisterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[])
|
|
{
|
|
DFINDER_LOGI(TAG, "Register Capability");
|
|
return NSTACKX_CapabilityHandle(capabilityBitmapNum, capabilityBitmap, RegisterCapabilityInner);
|
|
}
|
|
|
|
int32_t NSTACKX_SetFilterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[])
|
|
{
|
|
DFINDER_LOGI(TAG, "Set Filter Capability");
|
|
return NSTACKX_CapabilityHandle(capabilityBitmapNum, capabilityBitmap, SetFilterCapabilityInner);
|
|
}
|
|
|
|
static void RegisterServiceDataInner(void *argument)
|
|
{
|
|
LOGI(TAG, "Register Service Data Inner");
|
|
char *serviceData = argument;
|
|
if (RegisterServiceData(serviceData) != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "RegisterServiceData failed");
|
|
}
|
|
free(serviceData);
|
|
}
|
|
|
|
int32_t NSTACKX_RegisterServiceData(const char *serviceData)
|
|
{
|
|
LOGI(TAG, "Register Service Data");
|
|
char *serviceDataTmp = NULL;
|
|
|
|
if (serviceData == NULL) {
|
|
DFINDER_LOGE(TAG, "serviceData is null");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
|
|
DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
if (strlen(serviceData) >= NSTACKX_MAX_SERVICE_DATA_LEN) {
|
|
DFINDER_LOGE(TAG, "serviceData (%u) exceed max number", strlen(serviceData));
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
|
|
serviceDataTmp = calloc(1U, NSTACKX_MAX_SERVICE_DATA_LEN);
|
|
if (serviceDataTmp == NULL) {
|
|
return NSTACKX_ENOMEM;
|
|
}
|
|
if (strncpy_s(serviceDataTmp, NSTACKX_MAX_SERVICE_DATA_LEN, serviceData, strlen(serviceData)) != EOK) {
|
|
DFINDER_LOGE(TAG, "Failed to copy serviceData");
|
|
free(serviceDataTmp);
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
if (PostEvent(&g_eventNodeChain, g_epollfd, RegisterServiceDataInner, serviceDataTmp) != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "Failed to register serviceData!");
|
|
free(serviceDataTmp);
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
return NSTACKX_EOK;
|
|
}
|
|
|
|
#ifndef DFINDER_USE_MINI_NSTACKX
|
|
static void RegisterExtendServiceDataInner(void *argument)
|
|
{
|
|
char *extendServiceData = argument;
|
|
if (RegisterExtendServiceData(extendServiceData) != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "RegisterExtendServiceData failed");
|
|
}
|
|
free(extendServiceData);
|
|
}
|
|
|
|
int32_t NSTACKX_RegisterExtendServiceData(const char *extendServiceData)
|
|
{
|
|
char *extendServiceDataTmp = NULL;
|
|
|
|
if (extendServiceData == NULL) {
|
|
DFINDER_LOGE(TAG, "extendServiceData is null");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
|
|
DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
if (strlen(extendServiceData) >= NSTACKX_MAX_EXTEND_SERVICE_DATA_LEN) {
|
|
DFINDER_LOGE(TAG, "extendServiceData (%u) exceed max number", strlen(extendServiceData));
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
|
|
extendServiceDataTmp = calloc(1, NSTACKX_MAX_EXTEND_SERVICE_DATA_LEN);
|
|
if (extendServiceDataTmp == NULL) {
|
|
return NSTACKX_ENOMEM;
|
|
}
|
|
if (strncpy_s(extendServiceDataTmp, NSTACKX_MAX_EXTEND_SERVICE_DATA_LEN, extendServiceData,
|
|
strlen(extendServiceData)) != EOK) {
|
|
DFINDER_LOGE(TAG, "Failed to copy extendServiceData");
|
|
free(extendServiceDataTmp);
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
if (PostEvent(&g_eventNodeChain, g_epollfd, RegisterExtendServiceDataInner, extendServiceDataTmp) != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "Failed to register extendServiceData!");
|
|
free(extendServiceDataTmp);
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
return NSTACKX_EOK;
|
|
}
|
|
|
|
#ifndef DFINDER_SUPPORT_MULTI_NIF
|
|
static void SendMsgInner(void *arg)
|
|
{
|
|
MsgCtx *msg = arg;
|
|
if (msg == NULL) {
|
|
DFINDER_LOGE(TAG, "SendMsgInner: msg is NULL");
|
|
return;
|
|
}
|
|
if (strlen(msg->p2pAddr) != 0) {
|
|
DFINDER_LOGD(TAG, "Enter WifiDirect send");
|
|
msg->err = CoapSendServiceMsgWithDefiniteTargetIp(msg, NULL);
|
|
} else {
|
|
#ifdef DFINDER_SAVE_DEVICE_LIST
|
|
DeviceInfo *deviceInfo = GetDeviceInfoById(msg->deviceId, GetDeviceDB());
|
|
if (deviceInfo == NULL) {
|
|
DFINDER_LOGW(TAG, "no device found in device list, try to find in backup");
|
|
deviceInfo = GetDeviceInfoById(msg->deviceId, GetDeviceDBBackup());
|
|
if (deviceInfo == NULL) {
|
|
DFINDER_LOGE(TAG, "no device found in device list backup yet");
|
|
}
|
|
}
|
|
msg->err = CoapSendServiceMsg(msg, deviceInfo);
|
|
#else
|
|
DFINDER_LOGE(TAG, "Invalid p2pAddr");
|
|
msg->err = NSTACKX_EINVAL;
|
|
#endif /* #ifdef DFINDER_SAVE_DEVICE_LIST */
|
|
}
|
|
SemPost(&msg->wait);
|
|
}
|
|
|
|
static int32_t NSTACKX_SendMsgParamCheck(const char *moduleName, const char *deviceId, const uint8_t *data,
|
|
uint32_t len)
|
|
{
|
|
if (moduleName == NULL || strlen(moduleName) > NSTACKX_MAX_MODULE_NAME_LEN) {
|
|
DFINDER_LOGE(TAG, "Invalid module name");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
|
|
if (deviceId == NULL || strlen(deviceId) > NSTACKX_MAX_DEVICE_ID_LEN) {
|
|
DFINDER_LOGE(TAG, "Invalid device id");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
|
|
if (data == NULL || len == 0 || len > NSTACKX_MAX_SENDMSG_DATA_LEN) {
|
|
DFINDER_LOGE(TAG, "Null data to send");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
return NSTACKX_EOK;
|
|
}
|
|
|
|
static MsgCtx *NSTACKX_GetMsgCtx(const char *moduleName, const char *deviceId, const uint8_t *data,
|
|
uint32_t len, const char *ipaddr, uint8_t type)
|
|
{
|
|
MsgCtx *msg = NULL;
|
|
|
|
msg = calloc(1U, sizeof(MsgCtx));
|
|
if (msg == NULL) {
|
|
DFINDER_LOGE(TAG, "MsgCtx malloc fail");
|
|
return NULL;
|
|
}
|
|
if ((strcpy_s(msg->deviceId, sizeof(msg->deviceId), deviceId) != EOK) ||
|
|
(strcpy_s(msg->moduleName, sizeof(msg->moduleName), moduleName) != EOK)) {
|
|
DFINDER_LOGE(TAG, "Cpy deviceId fail");
|
|
goto FAILED;
|
|
}
|
|
if (ipaddr != NULL) {
|
|
if (strcpy_s(msg->p2pAddr, sizeof(msg->p2pAddr), ipaddr) != EOK) {
|
|
DFINDER_LOGE(TAG, "Cpy p2pAddr fail.");
|
|
goto FAILED;
|
|
}
|
|
}
|
|
msg->data = malloc(len);
|
|
if (msg->data == NULL) {
|
|
DFINDER_LOGE(TAG, "Msg data malloc fail");
|
|
goto FAILED;
|
|
}
|
|
if (memcpy_s(msg->data, len, data, len) != EOK) {
|
|
DFINDER_LOGE(TAG, "Msg data memcpy error");
|
|
goto FAILED;
|
|
}
|
|
msg->len = len;
|
|
msg->type = type;
|
|
msg->err = NSTACKX_EOK;
|
|
if (SemInit(&(msg->wait), 0, 0)) {
|
|
DFINDER_LOGE(TAG, "sem init fail");
|
|
goto FAILED;
|
|
}
|
|
|
|
return msg;
|
|
FAILED:
|
|
free(msg->data);
|
|
free(msg);
|
|
return NULL;
|
|
}
|
|
#endif /* #ifndef DFINDER_SUPPORT_MULTI_NIF */
|
|
|
|
int32_t NSTACKX_SendMsgDirect(const char *moduleName, const char *deviceId, const uint8_t *data,
|
|
uint32_t len, const char *ipaddr, uint8_t type)
|
|
{
|
|
#ifdef DFINDER_SUPPORT_MULTI_NIF
|
|
(void)moduleName;
|
|
(void)deviceId;
|
|
(void)data;
|
|
(void)len;
|
|
(void)ipaddr;
|
|
(void)type;
|
|
DFINDER_LOGE(TAG, "Do not support SendMsgDirect");
|
|
return NSTACKX_EFAILED;
|
|
#else
|
|
MsgCtx *msg = NULL;
|
|
int32_t ret = NSTACKX_EOK;
|
|
DFINDER_LOGD(TAG, "NSTACKX_SendMsgDirect");
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
|
|
DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
if (ipaddr == NULL) {
|
|
DFINDER_LOGE(TAG, "ipaddr needed");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
if (NSTACKX_SendMsgParamCheck(moduleName, deviceId, data, len) != NSTACKX_EOK) {
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
msg = NSTACKX_GetMsgCtx(moduleName, deviceId, data, len, ipaddr, type);
|
|
if (msg == NULL) {
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
if (PostEvent(&g_eventNodeChain, g_epollfd, SendMsgInner, msg) != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "Failed to send msg");
|
|
ret = NSTACKX_EFAILED;
|
|
}
|
|
if (ret == NSTACKX_EOK) {
|
|
SemWait(&(msg->wait));
|
|
ret = msg->err;
|
|
}
|
|
SemDestroy(&(msg->wait));
|
|
free(msg->data);
|
|
free(msg);
|
|
return ret;
|
|
#endif /* #ifdef DFINDER_SUPPORT_MULTI_NIF */
|
|
}
|
|
|
|
int32_t NSTACKX_SendMsg(const char *moduleName, const char *deviceId, const uint8_t *data, uint32_t len)
|
|
{
|
|
#ifdef DFINDER_SUPPORT_MULTI_NIF
|
|
(void)moduleName;
|
|
(void)deviceId;
|
|
(void)data;
|
|
(void)len;
|
|
DFINDER_LOGE(TAG, "Do not support SendMsgDirect");
|
|
return NSTACKX_EFAILED;
|
|
#else
|
|
#ifdef DFINDER_SAVE_DEVICE_LIST
|
|
int32_t ret = NSTACKX_EOK;
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
|
|
DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
if (NSTACKX_SendMsgParamCheck(moduleName, deviceId, data, len) != NSTACKX_EOK) {
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
MsgCtx *msg = NSTACKX_GetMsgCtx(moduleName, deviceId, data, len, NULL, SERVER_TYPE_WLANORETH);
|
|
if (msg == NULL) {
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
if (PostEvent(&g_eventNodeChain, g_epollfd, SendMsgInner, msg) != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "failed to send msg");
|
|
ret = NSTACKX_EFAILED;
|
|
}
|
|
if (ret == NSTACKX_EOK) {
|
|
SemWait(&(msg->wait));
|
|
ret = msg->err;
|
|
}
|
|
SemDestroy(&(msg->wait));
|
|
free(msg->data);
|
|
free(msg);
|
|
return ret;
|
|
#else
|
|
(void)moduleName;
|
|
(void)deviceId;
|
|
(void)data;
|
|
(void)len;
|
|
|
|
DFINDER_LOGE(TAG, "SendMsg not supported");
|
|
|
|
return NSTACKX_EFAILED;
|
|
#endif /* END OF DFINDER_SAVE_DEVICE_LIST */
|
|
#endif /* #ifdef DFINDER_SUPPORT_MULTI_NIF */
|
|
}
|
|
#endif /* END OF DFINDER_USE_MINI_NSTACKX */
|
|
|
|
static void SendDiscoveryRspInner(void *arg)
|
|
{
|
|
NSTACKX_ResponseSettings *responseSettings = arg;
|
|
if (responseSettings->businessType != GetLocalDeviceInfoPtr()->businessType) {
|
|
DFINDER_LOGE(TAG, "businessType is diff when check response settings");
|
|
free(responseSettings->businessData);
|
|
free(responseSettings);
|
|
return;
|
|
}
|
|
SendDiscoveryRsp(responseSettings);
|
|
free(responseSettings->businessData);
|
|
free(responseSettings);
|
|
}
|
|
|
|
static int32_t CopyResponseSettings(NSTACKX_ResponseSettings *dupResponseSettings,
|
|
const NSTACKX_ResponseSettings *responseSettings)
|
|
{
|
|
dupResponseSettings->businessType = responseSettings->businessType;
|
|
dupResponseSettings->length = responseSettings->length;
|
|
if (responseSettings->businessData != NULL) {
|
|
if (strncpy_s(dupResponseSettings->businessData, (dupResponseSettings->length + 1),
|
|
responseSettings->businessData, responseSettings->length) != EOK) {
|
|
DFINDER_LOGE(TAG, "businessData strncpy failed");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
}
|
|
if (strncpy_s(dupResponseSettings->localNetworkName, NSTACKX_MAX_INTERFACE_NAME_LEN,
|
|
responseSettings->localNetworkName, strlen(responseSettings->localNetworkName)) != EOK) {
|
|
DFINDER_LOGE(TAG, "localNetworkName strncpy failed");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
if (strncpy_s(dupResponseSettings->remoteIp, NSTACKX_MAX_IP_STRING_LEN,
|
|
responseSettings->remoteIp, strlen(responseSettings->remoteIp)) != EOK) {
|
|
DFINDER_LOGE(TAG, "remoteIp strncpy failed");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
return NSTACKX_EOK;
|
|
}
|
|
|
|
static int32_t CheckResponseSettings(const NSTACKX_ResponseSettings *responseSettings)
|
|
{
|
|
if (responseSettings == NULL) {
|
|
DFINDER_LOGE(TAG, "Invalid responseSettings info");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
if ((responseSettings->businessData == NULL) && (responseSettings->length != 0)) {
|
|
DFINDER_LOGE(TAG, "Invalid responseSettings bData info");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
if (responseSettings->length >= NSTACKX_MAX_BUSINESS_DATA_LEN) {
|
|
DFINDER_LOGE(TAG, "businessData length is too long");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
return NSTACKX_EOK;
|
|
}
|
|
|
|
int32_t NSTACKX_SendDiscoveryRsp(const NSTACKX_ResponseSettings *responseSettings)
|
|
{
|
|
DFINDER_LOGI(TAG, "begin to NSTACKX_SendDiscoveryRsp!");
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
|
|
DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
if (CheckResponseSettings(responseSettings) != NSTACKX_EOK) {
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
|
|
NSTACKX_ResponseSettings *dupResponseSettings = malloc(sizeof(NSTACKX_ResponseSettings));
|
|
if (dupResponseSettings == NULL) {
|
|
DFINDER_LOGE(TAG, "malloc failed");
|
|
return NSTACKX_ENOMEM;
|
|
}
|
|
dupResponseSettings->businessData = (char *)calloc((responseSettings->length + 1), sizeof(char));
|
|
if (dupResponseSettings->businessData == NULL) {
|
|
DFINDER_LOGE(TAG, "businessData calloc failed");
|
|
free(dupResponseSettings);
|
|
return NSTACKX_ENOMEM;
|
|
}
|
|
if (CopyResponseSettings(dupResponseSettings, responseSettings) != NSTACKX_EOK) {
|
|
free(dupResponseSettings->businessData);
|
|
free(dupResponseSettings);
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
|
|
if (PostEvent(&g_eventNodeChain, g_epollfd, SendDiscoveryRspInner, dupResponseSettings) != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "Failed to send responseSettings info!");
|
|
free(dupResponseSettings->businessData);
|
|
free(dupResponseSettings);
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
return NSTACKX_EOK;
|
|
}
|
|
|
|
#ifdef DFINDER_SAVE_DEVICE_LIST
|
|
static void GetDeviceListInner(void *argument)
|
|
{
|
|
GetDeviceListMessage *message = argument;
|
|
|
|
GetDeviceListWrapper(message->deviceList, message->deviceCountPtr, true);
|
|
SemPost(&message->wait);
|
|
}
|
|
#endif
|
|
|
|
int32_t NSTACKX_GetDeviceList(NSTACKX_DeviceInfo *deviceList, uint32_t *deviceCountPtr)
|
|
{
|
|
#ifdef DFINDER_SAVE_DEVICE_LIST
|
|
GetDeviceListMessage message = {
|
|
.deviceList = deviceList,
|
|
.deviceCountPtr = deviceCountPtr,
|
|
};
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
|
|
DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
if (deviceList == NULL || deviceCountPtr == NULL) {
|
|
DFINDER_LOGE(TAG, "Device list or count pointer is NULL");
|
|
return NSTACKX_EINVAL;
|
|
}
|
|
if (SemInit(&message.wait, 0, 0)) {
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
if (PostEvent(&g_eventNodeChain, g_epollfd, GetDeviceListInner, &message) != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "Failed to get device list");
|
|
SemDestroy(&message.wait);
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
SemWait(&message.wait);
|
|
SemDestroy(&message.wait);
|
|
return NSTACKX_EOK;
|
|
#else
|
|
(void)deviceList;
|
|
(void)deviceCountPtr;
|
|
|
|
DFINDER_LOGE(TAG, "device list not supported");
|
|
|
|
return NSTACKX_EFAILED;
|
|
#endif /* END OF DFINDER_SAVE_DEVICE_LIST */
|
|
}
|
|
|
|
void NotifyDeviceListChanged(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount)
|
|
{
|
|
if (g_parameter.onDeviceListChanged != NULL) {
|
|
DFINDER_LOGI(TAG, "notify callback: device list changed");
|
|
g_parameter.onDeviceListChanged(deviceList, deviceCount);
|
|
DFINDER_LOGI(TAG, "finish to notify device list changed");
|
|
} else {
|
|
DFINDER_LOGI(TAG, "notify callback: device list changed callback is null");
|
|
}
|
|
}
|
|
|
|
void NotifyDeviceFound(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount)
|
|
{
|
|
if (g_parameter.onDeviceFound != NULL) {
|
|
DFINDER_LOGI(TAG, "notify callback: device found");
|
|
g_parameter.onDeviceFound(deviceList, deviceCount);
|
|
DFINDER_LOGI(TAG, "finish to notify device found");
|
|
} else {
|
|
DFINDER_LOGI(TAG, "notify callback: device found callback is null");
|
|
}
|
|
}
|
|
|
|
#ifndef DFINDER_USE_MINI_NSTACKX
|
|
void NotifyMsgReceived(const char *moduleName, const char *deviceId, const uint8_t *data, uint32_t len)
|
|
{
|
|
if (g_parameter.onMsgReceived != NULL) {
|
|
DFINDER_LOGI(TAG, "notify callback: message received, data length %u", len);
|
|
g_parameter.onMsgReceived(moduleName, deviceId, data, len);
|
|
DFINDER_LOGI(TAG, "finish to notify msg received");
|
|
} else {
|
|
DFINDER_LOGI(TAG, "notify callback: message received callback is null");
|
|
}
|
|
}
|
|
|
|
int32_t NSTACKX_InitRestart(const NSTACKX_Parameter *parameter)
|
|
{
|
|
#ifdef DFINDER_SUPPORT_MULTI_NIF
|
|
(void)parameter;
|
|
return NSTACKX_EOK;
|
|
#else
|
|
DFINDER_LOGI(TAG, "NSTACKX_InitRestart");
|
|
int32_t ret = NSTACKX_Init(parameter);
|
|
if (ret == NSTACKX_EOK) {
|
|
if (PostEvent(&g_eventNodeChain, g_epollfd, GetLocalNetworkInterface, NULL) != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "Failed to GetLocalNetworkInterface");
|
|
}
|
|
}
|
|
return ret;
|
|
#endif
|
|
}
|
|
|
|
static void DeviceDiscoverInnerRestart(void *argument)
|
|
{
|
|
(void)argument;
|
|
CoapServiceDiscoverInner(NSTACKX_FALSE);
|
|
}
|
|
|
|
void NSTACKX_StartDeviceFindRestart(void)
|
|
{
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
|
|
DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
|
|
return;
|
|
}
|
|
DFINDER_LOGI(TAG, "start device find for restart");
|
|
if (PostEvent(&g_eventNodeChain, g_epollfd, DeviceDiscoverInnerRestart, NULL) != NSTACKX_EOK) {
|
|
DFINDER_LOGE(TAG, "Failed to start device discover!");
|
|
return;
|
|
}
|
|
return;
|
|
}
|
|
#endif /* END OF DFINDER_USE_MINI_NSTACKX */
|
|
|
|
#ifdef ENABLE_USER_LOG
|
|
int32_t NSTACKX_DFinderRegisterLog(DFinderLogCallback userLogCallback)
|
|
{
|
|
if (userLogCallback == NULL) {
|
|
DFINDER_LOGE(TAG, "logImpl null");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
int32_t ret = SetLogCallback(userLogCallback);
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
#ifdef NSTACKX_DFINDER_HIDUMP
|
|
#define MAX_DUMP_ARGC 10
|
|
int NSTACKX_DFinderDump(const char **argv, uint32_t argc, void *softObj, DFinderDumpFunc dump)
|
|
{
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
|
|
DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
|
|
if (dump == NULL) {
|
|
DFINDER_LOGE(TAG, "dump is null");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
|
|
if (argc == 0 || argc > MAX_DUMP_ARGC) {
|
|
DFINDER_LOGE(TAG, "argc is invalid %u", argc);
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
|
|
if (argv == NULL) {
|
|
DFINDER_LOGE(TAG, "argv is null");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
|
|
uint32_t i;
|
|
for (i = 0; i < argc; i++) {
|
|
if (argv[i] == NULL) {
|
|
DFINDER_LOGE(TAG, "argv[%u] is null", i);
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
}
|
|
|
|
return DFinderDump(argv, argc, softObj, dump);
|
|
}
|
|
#else
|
|
int NSTACKX_DFinderDump(const char **argv, uint32_t argc, void *softObj, DFinderDumpFunc dump)
|
|
{
|
|
(void)argv;
|
|
(void)argc;
|
|
(void)softObj;
|
|
(void)dump;
|
|
DFINDER_LOGE(TAG, "Unsupport dfinder dump");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
#endif
|
|
|
|
int NSTACKX_DFinderSetEventFunc(void *softobj, DFinderEventFunc func)
|
|
{
|
|
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
|
|
DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
|
|
if (func == NULL) {
|
|
DFINDER_LOGE(TAG, "func is null");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
|
|
return SetEventFunc(softobj, func);
|
|
}
|