已合并
feat:添加专用热点网关模块,支持专用热点设备配网--dedap集成模块 #225
移动-吴昊创建于 8月22日
feat:添加专用热点网关模块,支持专用热点设备配网--dedap集成模块 #225
已合并
共 13 个文件变更+1924-9
| @@ -21,16 +21,21 @@ set_property(CACHE TARGET_PLATFORM PROPERTY STRINGS linux android) | |||
| 21 | option(ENABLE_ETH "Enable ETH Module support" OFF) | 21 | option(ENABLE_ETH "Enable ETH Module support" OFF) |
| 22 | option(ENABLE_WIFI "Enable WIFI Module support" ON) | 22 | option(ENABLE_WIFI "Enable WIFI Module support" ON) |
| 23 | option(ENABLE_BLE "Enable BLE Module support" ON) | 23 | option(ENABLE_BLE "Enable BLE Module support" ON) |
| 24 | -option(ENABLE_SLE "Enable SLE Module support" OFF) | 24 | +option(ENABLE_SLE "Enable SLE Module support" ON) |
| 25 | option(ENABLE_SLE_ADP "Enable SLE Adapter" ON) | 25 | option(ENABLE_SLE_ADP "Enable SLE Adapter" ON) |
| 26 | +option(ENABLE_DEDAP "Enable DEDAP Module support" ON) | ||
| 26 | 27 | ||
| 27 | -# BLE/SLE role, default is server. | 28 | +# BLE/SLE/DEDAP role, default is server. |
| 28 | option(BLE_ROLE_SERVER "BLE role, server or client" ON) | 29 | option(BLE_ROLE_SERVER "BLE role, server or client" ON) |
| 29 | -option(SLE_ROLE_SERVER "SLE role, server or client" ON) | 30 | +option(SLE_ROLE_SERVER "SLE role, server or client" OFF) |
| 31 | +option(DEDAP_ROLE_SERVER "DEDAP role, server or client" ON) | ||
| 30 | 32 | ||
| 31 | -# Bridge is enabled automatically when an enabled BLE or SLE link uses the client role. | 33 | +# Bridge is enabled automatically for a BLE/SLE client or a DEDAP server. |
| 32 | set(ENABLE_BRIDGE OFF) | 34 | set(ENABLE_BRIDGE OFF) |
| 33 | -if ((ENABLE_BLE AND NOT BLE_ROLE_SERVER) OR (ENABLE_SLE AND NOT SLE_ROLE_SERVER)) | 35 | +set(BRIDGE_TCP_MODE_ENABLE OFF) |
| 36 | +if ((ENABLE_BLE AND NOT BLE_ROLE_SERVER) OR | ||
| 37 | + (ENABLE_SLE AND NOT SLE_ROLE_SERVER) OR | ||
| 38 | + (ENABLE_DEDAP AND DEDAP_ROLE_SERVER)) | ||
| 34 | set(ENABLE_BRIDGE ON) | 39 | set(ENABLE_BRIDGE ON) |
| 35 | endif() | 40 | endif() |
| 36 | 41 | ||
| @@ -47,7 +52,7 @@ set(ONECONNECT_VERSION_CODE 2 CACHE INTEGER "OneConnect version code") | |||
| 47 | 52 | ||
| 48 | # SPEKE PBKDF2 iterations configuration | 53 | # SPEKE PBKDF2 iterations configuration |
| 49 | set(SPEKE_PBKDF2_ITERATIONS 10000 CACHE INTEGER "SPEKE PBKDF2 iterations (1000-100000)") | 54 | set(SPEKE_PBKDF2_ITERATIONS 10000 CACHE INTEGER "SPEKE PBKDF2 iterations (1000-100000)") |
| 50 | -# 暂时只支持一个管理员级别的terminal PSK | 55 | +# 锟斤拷时只支锟斤拷一锟斤拷锟斤拷锟斤拷员锟斤拷锟斤拷锟絫erminal PSK |
| 51 | set(SEC_TERMINAL_PSK_MAX_NUM 1 CACHE INTEGER "Terminal PSK max num") | 56 | set(SEC_TERMINAL_PSK_MAX_NUM 1 CACHE INTEGER "Terminal PSK max num") |
| 52 | if(NOT SEC_TERMINAL_PSK_MAX_NUM EQUAL 1) | 57 | if(NOT SEC_TERMINAL_PSK_MAX_NUM EQUAL 1) |
| 53 | message(FATAL_ERROR "SEC_TERMINAL_PSK_MAX_NUM must be 1") | 58 | message(FATAL_ERROR "SEC_TERMINAL_PSK_MAX_NUM must be 1") |
| @@ -30,6 +30,7 @@ | |||
| 30 | "iot_connect_sle_support", | 30 | "iot_connect_sle_support", |
| 31 | "iot_connect_wifi_support", | 31 | "iot_connect_wifi_support", |
| 32 | "iot_connect_eth_support", | 32 | "iot_connect_eth_support", |
| 33 | + "iot_connect_dedap_support", | ||
| 33 | "iot_connect_ailife_support", | 34 | "iot_connect_ailife_support", |
| 34 | "iot_connect_mbedtls_v2_support", | 35 | "iot_connect_mbedtls_v2_support", |
| 35 | "iot_connect_mbedtls_psk_support", | 36 | "iot_connect_mbedtls_psk_support", |
| @@ -24,13 +24,17 @@ endif() | |||
| 24 | 24 | ||
| 25 | if (ENABLE_ETH) | 25 | if (ENABLE_ETH) |
| 26 | add_subdirectory(eth) | 26 | add_subdirectory(eth) |
| 27 | -elseif (ENABLE_WIFI) | 27 | +endif() |
| 28 | + | ||
| 29 | +if (ENABLE_WIFI) | ||
| 28 | add_subdirectory(wifi) | 30 | add_subdirectory(wifi) |
| 29 | endif() | 31 | endif() |
| 30 | 32 | ||
| 31 | if (ENABLE_BRIDGE) | 33 | if (ENABLE_BRIDGE) |
| 32 | add_subdirectory(bridge) | 34 | add_subdirectory(bridge) |
| 33 | -else() | 35 | +endif() |
| 36 | + | ||
| 37 | +if (ENABLE_SLE AND NOT SLE_ROLE_SERVER) | ||
| 34 | add_subdirectory(gateway) | 38 | add_subdirectory(gateway) |
| 35 | endif() | 39 | endif() |
| 36 | 40 | ||
| @@ -14,6 +14,10 @@ | |||
| 14 | 14 | ||
| 15 | add_subdirectory(connect) | 15 | add_subdirectory(connect) |
| 16 | add_subdirectory(softap) | 16 | add_subdirectory(softap) |
| 17 | +add_subdirectory(local_control) | ||
| 18 | +if (ENABLE_DEDAP AND DEDAP_ROLE_SERVER) | ||
| 19 | + add_subdirectory(dedap) | ||
| 20 | +endif() | ||
| 17 | 21 | ||
| 18 | # 2.0 keeps the legacy Wi-Fi LAN Search and cloud services. 3.0 Wi-Fi Combo | 22 | # 2.0 keeps the legacy Wi-Fi LAN Search and cloud services. 3.0 Wi-Fi Combo |
| 19 | # uses core/network/lan_search and does not build these legacy services. | 23 | # uses core/network/lan_search and does not build these legacy services. |
| @@ -0,0 +1,37 @@ | |||
| 1 | +# | ||
| 2 | +# Copyright (c) 2024 China Mobile (Hangzhou) Information Technology Co., Ltd. | ||
| 3 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | +# you may not use this file except in compliance with the License. | ||
| 5 | +# You may obtain a copy of the License at | ||
| 6 | +# | ||
| 7 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | +# | ||
| 9 | +# Unless required by applicable law or agreed to in writing, software | ||
| 10 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | +# See the License for the specific language governing permissions and | ||
| 13 | +# limitations under the License. | ||
| 14 | + | ||
| 15 | +set(IOTC_SRC_LIST | ||
| 16 | + ${IOTC_SRC_LIST} | ||
| 17 | + ${CMAKE_CURRENT_SOURCE_DIR}/dedap_ctx.c | ||
| 18 | + ${CMAKE_CURRENT_SOURCE_DIR}/dedap_service.c | ||
| 19 | + ${CMAKE_CURRENT_SOURCE_DIR}/dedap_event_handler.c | ||
| 20 | + ${CMAKE_CURRENT_SOURCE_DIR}/dedap_hotspot.c | ||
| 21 | + ${CMAKE_CURRENT_SOURCE_DIR}/dedap_device_session.c | ||
| 22 | + ${CMAKE_CURRENT_SOURCE_DIR}/dedap_coap_client.c | ||
| 23 | + ${CMAKE_CURRENT_SOURCE_DIR}/dedap_connrequest.c | ||
| 24 | + ${CMAKE_CURRENT_SOURCE_DIR}/dedap_coap_server.c | ||
| 25 | + ${CMAKE_CURRENT_SOURCE_DIR}/dedap_provision.c | ||
| 26 | + ${CMAKE_CURRENT_SOURCE_DIR}/dedap_coap_enc.c | ||
| 27 | + ${CMAKE_CURRENT_SOURCE_DIR}/dedap_coap_apiserver.c | ||
| 28 | + PARENT_SCOPE | ||
| 29 | +) | ||
| 30 | + | ||
| 31 | +set(IOTC_INC_LIST | ||
| 32 | + ${IOTC_INC_LIST} | ||
| 33 | + ${CMAKE_CURRENT_SOURCE_DIR}/include | ||
| 34 | + PARENT_SCOPE | ||
| 35 | +) | ||
| 36 | + | ||
| 37 | +set(IOTC_TEST_INC_LIST ${IOTC_TEST_INC_LIST} PARENT_SCOPE) | ||
| @@ -0,0 +1,333 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2024-2026 China Mobile (Hangzhou) Information Technology Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#include <string.h> | ||
| 17 | +#include "iotc_errcode.h" | ||
| 18 | +#include "iotc_log.h" | ||
| 19 | +#include "iotc_network.h" | ||
| 20 | +#include "iotc_os.h" | ||
| 21 | +#include "securec.h" | ||
| 22 | +#include "utils_assert.h" | ||
| 23 | +#include "utils_list.h" | ||
| 24 | +#include "coap_codec_udp.h" | ||
| 25 | +#include "coap_endpoint.h" | ||
| 26 | +#include "coap_endpoint_event_source.h" | ||
| 27 | +#include "coap_endpoint_client.h" | ||
| 28 | +#include "coap_net_stack.h" | ||
| 29 | +#include "trans_sess.h" | ||
| 30 | +#include "trans_buffer_inner.h" | ||
| 31 | +#include "sched_event_loop.h" | ||
| 32 | +#include "dedap_coap_enc.h" | ||
| 33 | +#include "dedap_device_session.h" | ||
| 34 | +#include "dedap_coap_server.h" | ||
| 35 | +#include "dedap_ctx.h" | ||
| 36 | + | ||
| 37 | +#define DEDAP_COAP_CLIENT_NAME "DEDAP_COAP" | ||
| 38 | +#define DEDAP_COAP_RESP_TIMEOUT_MS (10 * 1000) | ||
| 39 | +#define DEDAP_COAP_TOKEN_LEN 4 | ||
| 40 | + | ||
| 41 | +// coap错误类别 | ||
| 42 | +#define COAP_CODE_CLASS_CLIENT_ERROR 4U | ||
| 43 | +#define COAP_CODE_CLASS_SERVER_ERROR 5U | ||
| 44 | + | ||
| 45 | +static void DedapCoapServerDeinit(void); | ||
| 46 | + | ||
| 47 | +/** | ||
| 48 | + * @brief 获取dedap上下文(使用static局部变量实现单例)。 | ||
| 49 | + * @return 上下文指针 | ||
| 50 | + */ | ||
| 51 | +DedapCtx *GetDedapCtx(void) | ||
| 52 | +{ | ||
| 53 | + static DedapCtx ctx; | ||
| 54 | + return &ctx; | ||
| 55 | +} | ||
| 56 | + | ||
| 57 | +/** | ||
| 58 | + * @brief 初始化dedap上下文 | ||
| 59 | + * @details 清零结构体,初始化会话链表,设置initialized标志 | ||
| 60 | + * @return 0成功,非0失败 | ||
| 61 | + */ | ||
| 62 | +int32_t DedapCtxInit(void) | ||
| 63 | +{ | ||
| 64 | + DedapCtx *ctx = GetDedapCtx(); | ||
| 65 | + | ||
| 66 | + IOTC_LOGI("dedap ctx init starting..."); | ||
| 67 | + | ||
| 68 | + /* 清零上下文 */ | ||
| 69 | + (void)memset_s(ctx, sizeof(DedapCtx), 0, sizeof(DedapCtx)); | ||
| 70 | + | ||
| 71 | + /* 初始化会话链表 */ | ||
| 72 | + LIST_INIT(&ctx->sessionList); | ||
| 73 | + | ||
| 74 | + ctx->initialized = true; | ||
| 75 | + | ||
| 76 | + IOTC_LOGI("dedap ctx init success"); | ||
| 77 | + return IOTC_OK; | ||
| 78 | +} | ||
| 79 | + | ||
| 80 | +/** | ||
| 81 | + * @brief 创建Dedap CoAP网络栈。 | ||
| 82 | + * @param ctx Dedap上下文。 | ||
| 83 | + * @param port UDP端口号。 | ||
| 84 | + * @return 0成功,非0失败。 | ||
| 85 | + */ | ||
| 86 | +static int32_t DedapCreateCoapStack(DedapCtx *ctx, uint16_t port) | ||
| 87 | +{ | ||
| 88 | + char localIp[IOTC_IP_STR_MAX_LEN + 1] = {0}; | ||
| 89 | + int32_t ret = IotcGetLocalIp(localIp, IOTC_IP_STR_MAX_LEN); | ||
| 90 | + if (ret != IOTC_OK) { | ||
| 91 | + return ret; | ||
| 92 | + } | ||
| 93 | + TransSocket *socket = TransSocketUdpNew(&(SocketUdpInitParam) { | ||
| 94 | + .port = port, | ||
| 95 | + .localAddr = localIp, | ||
| 96 | + .multicastAddr = NULL, | ||
| 97 | + .broadcastAddr = NULL, | ||
| 98 | + }); | ||
| 99 | + if (socket == NULL) { | ||
| 100 | + return IOTC_CORE_WIFI_TRANS_ERR_SOCKET_UDP_CREATE; | ||
| 101 | + } | ||
| 102 | + CoapNetStackParam param = { | ||
| 103 | + .name = DEDAP_COAP_CLIENT_NAME, | ||
| 104 | + .socket = socket, | ||
| 105 | + .sessMsgSize = sizeof(CoapPacket), | ||
| 106 | + .sessUserData = ctx, | ||
| 107 | + .encoder = CoapUdpEncode, | ||
| 108 | + .decoder = CoapUdpDecode, | ||
| 109 | + .endpointUserData = ctx, | ||
| 110 | + }; | ||
| 111 | + ret = CoapNetStackCreate(&ctx->coapStack, ¶m); | ||
| 112 | + if (ret != IOTC_OK) { | ||
| 113 | + TransSocketFree(socket); | ||
| 114 | + return ret; | ||
| 115 | + } | ||
| 116 | + TransSessAddRecvTailHandler(ctx->coapStack.sess, DedapCoapMsgRecvDecryptProcess, "decrypt", NULL); | ||
| 117 | + TransSessAddSendTailHandler(ctx->coapStack.sess, DedapCoapMsgSendEncryptProcess, "encrypt", NULL); | ||
| 118 | + CoapEndpointSessSetup(ctx->coapStack.endpoint); | ||
| 119 | + return IOTC_OK; | ||
| 120 | +} | ||
| 121 | + | ||
| 122 | +/** | ||
| 123 | + * @brief 配置Dedap CoAP端点参数。 | ||
| 124 | + * @param ctx Dedap上下文。 | ||
| 125 | + * @return 0成功,非0失败。 | ||
| 126 | + */ | ||
| 127 | +static int32_t DedapConfigureCoapEndpoint(DedapCtx *ctx) | ||
| 128 | +{ | ||
| 129 | + int32_t ret = CoapClientSetRespTimeout(ctx->coapStack.endpoint, DEDAP_COAP_RESP_TIMEOUT_MS); | ||
| 130 | + if (ret != IOTC_OK) { | ||
| 131 | + return ret; | ||
| 132 | + } | ||
| 133 | + return CoapClientSetTokenLen(ctx->coapStack.endpoint, DEDAP_COAP_TOKEN_LEN); | ||
| 134 | +} | ||
| 135 | + | ||
| 136 | +/** | ||
| 137 | + * @brief 创建并注册Dedap CoAP事件源。 | ||
| 138 | + * @param ctx Dedap上下文。 | ||
| 139 | + * @return 0成功,非0失败。 | ||
| 140 | + */ | ||
| 141 | +static int32_t DedapRegisterCoapEventSource(DedapCtx *ctx) | ||
| 142 | +{ | ||
| 143 | + ctx->coapSource = CoapEndpointEventSourceNew(ctx->coapStack.endpoint); | ||
| 144 | + if (ctx->coapSource == NULL) { | ||
| 145 | + return IOTC_ERROR; | ||
| 146 | + } | ||
| 147 | + int32_t ret = EventLoopAddSource(GetSchedEventLoop(), ctx->coapSource); | ||
| 148 | + if (ret != IOTC_OK) { | ||
| 149 | + EventSourceFree(ctx->coapSource); | ||
| 150 | + ctx->coapSource = NULL; | ||
| 151 | + } | ||
| 152 | + return ret; | ||
| 153 | +} | ||
| 154 | + | ||
| 155 | +/** | ||
| 156 | + * @brief 初始化CoAP服务器。 | ||
| 157 | + * @param port UDP端口号(0表示自动分配)。 | ||
| 158 | + * @return 0成功,非0失败。 | ||
| 159 | + */ | ||
| 160 | +static int32_t DedapCoapServerInit(uint16_t port) | ||
| 161 | +{ | ||
| 162 | + DedapCtx *ctx = GetDedapCtx(); | ||
| 163 | + int32_t ret = DedapCreateCoapStack(ctx, port); | ||
| 164 | + if (ret == IOTC_OK) { | ||
| 165 | + ret = DedapConfigureCoapEndpoint(ctx); | ||
| 166 | + } | ||
| 167 | + if (ret == IOTC_OK) { | ||
| 168 | + ret = DedapRegisterCoapEventSource(ctx); | ||
| 169 | + } | ||
| 170 | + if (ret != IOTC_OK) { | ||
| 171 | + DedapCoapServerDeinit(); | ||
| 172 | + } | ||
| 173 | + return ret; | ||
| 174 | +} | ||
| 175 | + | ||
| 176 | +/** | ||
| 177 | + * @brief 反初始化CoAP服务器 | ||
| 178 | + * @details 停止CoAP网络栈,移除事件源,销毁网络栈 | ||
| 179 | + * @return 无返回值;尚未创建的资源会被跳过。 | ||
| 180 | + */ | ||
| 181 | +static void DedapCoapServerDeinit(void) | ||
| 182 | +{ | ||
| 183 | + DedapCtx *ctx = GetDedapCtx(); | ||
| 184 | + | ||
| 185 | + /* 停止CoAP网络栈 */ | ||
| 186 | + if (ctx->coapStarted) { | ||
| 187 | + CoapNetStackStop(&ctx->coapStack); | ||
| 188 | + ctx->coapStarted = false; | ||
| 189 | + } | ||
| 190 | + | ||
| 191 | + /* 移除事件源 */ | ||
| 192 | + if (ctx->coapSource != NULL) { | ||
| 193 | + EventLoopDelSource(GetSchedEventLoop(), ctx->coapSource); | ||
| 194 | + EventSourceFree(ctx->coapSource); | ||
| 195 | + ctx->coapSource = NULL; | ||
| 196 | + } | ||
| 197 | + | ||
| 198 | + /* 销毁CoAP网络栈 */ | ||
| 199 | + if (ctx->coapStack.endpoint != NULL) { | ||
| 200 | + CoapNetStackDestroy(&ctx->coapStack); | ||
| 201 | + } | ||
| 202 | +} | ||
| 203 | + | ||
| 204 | +/** | ||
| 205 | + * @brief 启动CoAP网络栈 | ||
| 206 | + * @details 启动已初始化的CoAP网络栈,开始监听请求 | ||
| 207 | + * @return 0成功,非0失败 | ||
| 208 | + */ | ||
| 209 | +static int32_t DedapCoapServerStart(void) | ||
| 210 | +{ | ||
| 211 | + DedapCtx *ctx = GetDedapCtx(); | ||
| 212 | + int32_t ret = CoapNetStackStart(&ctx->coapStack); | ||
| 213 | + if (ret != IOTC_OK) { | ||
| 214 | + IOTC_LOGE("dedap:start coap stack failed %d", ret); | ||
| 215 | + return ret; | ||
| 216 | + } | ||
| 217 | + ctx->coapStarted = true; | ||
| 218 | + return IOTC_OK; | ||
| 219 | +} | ||
| 220 | + | ||
| 221 | +/** | ||
| 222 | + * @brief 初始化dedap UDP传输层 | ||
| 223 | + * @details 按顺序执行:初始化CoAP服务器、注册处理器、启动网络栈 | ||
| 224 | + * @param port UDP端口号(0表示自动分配) | ||
| 225 | + * @return 0成功,非0失败 | ||
| 226 | + */ | ||
| 227 | +int32_t DedapTransportUdpInit(uint16_t port) | ||
| 228 | +{ | ||
| 229 | + int32_t ret; | ||
| 230 | + | ||
| 231 | + /* 初始化CoAP服务器基础设施 */ | ||
| 232 | + ret = DedapCoapServerInit(port); | ||
| 233 | + if (ret != IOTC_OK) { | ||
| 234 | + IOTC_LOGE("dedap:coap server init failed %d", ret); | ||
| 235 | + return ret; | ||
| 236 | + } | ||
| 237 | + | ||
| 238 | + /* 注册CoAP接收处理器 */ | ||
| 239 | + ret = DedapCoapHandlerRegister(); | ||
| 240 | + if (ret != IOTC_OK) { | ||
| 241 | + IOTC_LOGE("dedap:handler register failed, cleanup"); | ||
| 242 | + DedapCoapServerDeinit(); | ||
| 243 | + return ret; | ||
| 244 | + } | ||
| 245 | + | ||
| 246 | + /* 启动CoAP网络栈(handler注册完成后再开始监听) */ | ||
| 247 | + ret = DedapCoapServerStart(); | ||
| 248 | + if (ret != IOTC_OK) { | ||
| 249 | + IOTC_LOGE("dedap:server start failed, cleanup"); | ||
| 250 | + DedapCoapHandlerUnregister(); | ||
| 251 | + DedapCoapServerDeinit(); | ||
| 252 | + return ret; | ||
| 253 | + } | ||
| 254 | + | ||
| 255 | + IOTC_LOGI("dedap transport mode: UDP, port=%u", port); | ||
| 256 | + return IOTC_OK; | ||
| 257 | +} | ||
| 258 | + | ||
| 259 | +/** | ||
| 260 | + * @brief 反初始化dedap UDP传输层 | ||
| 261 | + * @details 注销CoAP接收处理器,清理CoAP服务器 | ||
| 262 | + * @return 无返回值。 | ||
| 263 | + */ | ||
| 264 | +void DedapTransportUdpDeinit(void) | ||
| 265 | +{ | ||
| 266 | + /* 注销CoAP接收处理器 */ | ||
| 267 | + DedapCoapHandlerUnregister(); | ||
| 268 | + | ||
| 269 | + /* 清理CoAP服务器 */ | ||
| 270 | + DedapCoapServerDeinit(); | ||
| 271 | +} | ||
| 272 | + | ||
| 273 | +/** | ||
| 274 | + * @brief 反初始化dedap上下文 | ||
| 275 | + * @details 按以下顺序清理资源: | ||
| 276 | + * 1. 清理传输层(调用DedapTransportUdpDeinit,包含CoAP处理器注销和CoAP服务器清理) | ||
| 277 | + * 2. 释放所有活跃的设备会话 | ||
| 278 | + * 3. 清零上下文结构体,重置initialized标志 | ||
| 279 | + * @note 调用此函数后,dedap模块完全重置,需重新调用DedapCtxInit才能使用 | ||
| 280 | + * @return 无返回值;上下文未初始化时直接返回。 | ||
| 281 | + */ | ||
| 282 | +void DedapCtxDeinit(void) | ||
| 283 | +{ | ||
| 284 | + DedapCtx *ctx = GetDedapCtx(); | ||
| 285 | + if (!ctx->initialized) { | ||
| 286 | + return; | ||
| 287 | + } | ||
| 288 | + | ||
| 289 | + IOTC_LOGI("dedap ctx deinit starting..."); | ||
| 290 | + | ||
| 291 | + /* 清理传输层 */ | ||
| 292 | + DedapTransportUdpDeinit(); | ||
| 293 | + | ||
| 294 | + /* 释放所有活跃的设备会话 */ | ||
| 295 | + ListEntry *pos = NULL; | ||
| 296 | + ListEntry *tmp = NULL; | ||
| 297 | + LIST_FOR_EACH_ITEM_SAFE(pos, tmp, &ctx->sessionList) { | ||
| 298 | + DedapDeviceSession *sess = CONTAINER_OF(pos, DedapDeviceSession, node); | ||
| 299 | + DedapFreeSession(sess); | ||
| 300 | + } | ||
| 301 | + | ||
| 302 | + (void)memset_s(ctx, sizeof(DedapCtx), 0, sizeof(DedapCtx)); | ||
| 303 | + ctx->initialized = false; | ||
| 304 | + | ||
| 305 | + IOTC_LOGI("dedap ctx deinit done"); | ||
| 306 | +} | ||
| 307 | + | ||
| 308 | +/** | ||
| 309 | + * @brief 将 CoAP 响应码映射为 Dedap 业务错误码 | ||
| 310 | + * @param coapCode CoAP 响应码 | ||
| 311 | + * @return Dedap 业务错误码 | ||
| 312 | + */ | ||
| 313 | +int32_t DedapMapCoapCodeToBusinessError(uint8_t coapCode) | ||
| 314 | +{ | ||
| 315 | + /* 2.xx 成功响应 */ | ||
| 316 | + if (COAP_CODE_CLASS(coapCode) == COAP_CODE_CLASS_SUCC_RESP) { | ||
| 317 | + return IOTC_OK; | ||
| 318 | + } | ||
| 319 | + | ||
| 320 | + /* 4.xx 客户端错误 - 映射为 Dedap 客户端错误 */ | ||
| 321 | + uint8_t codeClass = COAP_CODE_CLASS(coapCode); | ||
| 322 | + if (codeClass == COAP_CODE_CLASS_CLIENT_ERROR) { | ||
| 323 | + return IOTC_CORE_DEDAP_ERR_COAP_CLIENT_ERROR; | ||
| 324 | + } | ||
| 325 | + | ||
| 326 | + /* 5.xx 服务器错误 - 映射为 Dedap 服务器错误 */ | ||
| 327 | + if (codeClass == COAP_CODE_CLASS_SERVER_ERROR) { | ||
| 328 | + return IOTC_CORE_DEDAP_ERR_COAP_SERVER_ERROR; | ||
| 329 | + } | ||
| 330 | + | ||
| 331 | + /* 其他未知错误 */ | ||
| 332 | + return IOTC_CORE_DEDAP_ERR_COAP_CLIENT_ERROR; | ||
| 333 | +} | ||
| @@ -0,0 +1,203 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2024-2026 China Mobile (Hangzhou) Information Technology Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#include "iotc_event.h" | ||
| 17 | +#include "iotc_event_params.h" | ||
| 18 | +#include "iotc_log.h" | ||
| 19 | +#include "iotc_errcode.h" | ||
| 20 | +#include "utils_assert.h" | ||
| 21 | +#include "utils_common.h" | ||
| 22 | +#include "event_bus.h" | ||
| 23 | +#include "securec.h" | ||
| 24 | +#include "dedap_hotspot.h" | ||
| 25 | +#include "dedap_device_session.h" | ||
| 26 | +#include "dedap_event_handler.h" | ||
| 27 | + | ||
| 28 | +/** | ||
| 29 | + * @brief 处理START_DISCOVERY事件回调(bridge下行→dedap)。 | ||
| 30 | + * @details enable=1时启动专用热点,enable=2时停止专用热点。 | ||
| 31 | + * @param event 事件ID。 | ||
| 32 | + * @param param 事件参数,包含enable/timeout/scanType。 | ||
| 33 | + * @param len 参数长度。 | ||
| 34 | + * @return 无返回值;参数非法或热点操作失败时记录日志后返回。 | ||
| 35 | + */ | ||
| 36 | +static void DedapStartDiscoveryCallback(uint32_t event, IotcStartDiscoveryParam *param, uint32_t len) | ||
| 37 | +{ | ||
| 38 | + NOT_USED(event); | ||
| 39 | + if (param == NULL || len < sizeof(IotcStartDiscoveryParam)) { | ||
| 40 | + IOTC_LOGE("dedap:start discovery param invalid"); | ||
| 41 | + return; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + IotcStartDiscoveryParam *p = param; | ||
| 45 | + IOTC_LOGI("dedap:[enter]%s,enable=%d,timeout=%d,scanType=0x%X", | ||
| 46 | + __FUNCTION__, p->enable, p->timeout, p->scanType); | ||
| 47 | + | ||
| 48 | + int32_t ret; | ||
| 49 | + if (p->enable == IOTC_SCAN_CMD_STOP) { | ||
| 50 | + ret = DedapHotspotStop(); | ||
| 51 | + if (ret != IOTC_OK) { | ||
| 52 | + IOTC_LOGE("dedap:stop hotspot failed %d", ret); | ||
| 53 | + } | ||
| 54 | + } else { | ||
| 55 | + ret = DedapHotspotStart(); | ||
| 56 | + if (ret != IOTC_OK) { | ||
| 57 | + IOTC_LOGE("dedap:start hotspot failed %d", ret); | ||
| 58 | + } | ||
| 59 | + } | ||
| 60 | +} | ||
| 61 | + | ||
| 62 | +/** | ||
| 63 | + * @brief 处理ADD_SUBDEV事件回调(bridge下行→dedap)。 | ||
| 64 | + * @details 解析prodId/sn/mac/pin/timeout,启动指定WiFi设备的配网流程。 | ||
| 65 | + * @param event 事件ID。 | ||
| 66 | + * @param param 事件参数,包含添加子设备的信息。 | ||
| 67 | + * @param len 参数长度。 | ||
| 68 | + * @return 无返回值;参数非法、链路类型不匹配或配网启动失败时提前返回。 | ||
| 69 | + */ | ||
| 70 | +static void DedapAddSubDevCallback(uint32_t event, IotcAddSubDevParam *param, uint32_t len) | ||
| 71 | +{ | ||
| 72 | + NOT_USED(event); | ||
| 73 | + if (param == NULL || len < sizeof(IotcAddSubDevParam)) { | ||
| 74 | + IOTC_LOGE("dedap:add subdev param invalid"); | ||
| 75 | + return; | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + IotcAddSubDevParam *p = param; | ||
| 79 | + | ||
| 80 | + /* 链路类型过滤:仅处理WiFi链路的事件 */ | ||
| 81 | + if (p->linkType != IOTC_LINK_WIFI && p->linkType != IOTC_LINK_NONE) { | ||
| 82 | + IOTC_LOGD("dedap:add subdev event filtered out, linkType=%d", p->linkType); | ||
| 83 | + return; | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + IOTC_LOGI("dedap:[enter]%s,prodId=%s,mac=%s,timeout=%u", | ||
| 87 | + __FUNCTION__, p->prodId, p->mac, p->timeout); | ||
| 88 | + | ||
| 89 | + int32_t ret = DedapDeviceProvisionStart(p->mac, p->prodId, p->pin); | ||
| 90 | + if (ret != IOTC_OK) { | ||
| 91 | + IOTC_LOGE("dedap:start provisioning failed %d", ret); | ||
| 92 | + } | ||
| 93 | +} | ||
| 94 | + | ||
| 95 | +/** | ||
| 96 | + * @brief 处理HUB_SETUP事件回调(bridge下行→dedap)。 | ||
| 97 | + * @details 将管理域和配网信息(WiFi凭证、认证信息)下发到目标WiFi设备。 | ||
| 98 | + * 采用链式触发机制:先下发 provisionPSK,成功后由响应处理器触发 hubCfg。 | ||
| 99 | + * @param event 事件ID。 | ||
| 100 | + * @param param 事件参数,包含配网通知的结构化字段。 | ||
| 101 | + * @param len 参数长度。 | ||
| 102 | + * @return 无返回值;参数非法、链路类型不匹配或配置下发失败时提前返回。 | ||
| 103 | + */ | ||
| 104 | +static void DedapHubSetupCallback(uint32_t event, IotcHubSetupParam *param, uint32_t len) | ||
| 105 | +{ | ||
| 106 | + NOT_USED(event); | ||
| 107 | + if (param == NULL || len < sizeof(IotcHubSetupParam)) { | ||
| 108 | + IOTC_LOGE("dedap:hub setup param invalid"); | ||
| 109 | + return; | ||
| 110 | + } | ||
| 111 | + | ||
| 112 | + IotcHubSetupParam *p = param; | ||
| 113 | + | ||
| 114 | + /* 链路类型过滤:仅处理WiFi链路的事件 */ | ||
| 115 | + if (p->linkType != IOTC_LINK_WIFI && p->linkType != IOTC_LINK_NONE) { | ||
| 116 | + IOTC_LOGD("dedap:hub setup event filtered out, linkType=%d", p->linkType); | ||
| 117 | + return; | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + IOTC_LOGI("dedap:[enter]%s,prodId=%s,devId=%s,authType=%d,mac=%s", | ||
| 121 | + __FUNCTION__, p->prodId, p->devId, p->authType, p->mac); | ||
| 122 | + | ||
| 123 | + int32_t ret = DedapDeviceHubSetup(p); | ||
| 124 | + if (ret != IOTC_OK) { | ||
| 125 | + IOTC_LOGE("dedap:hub setup failed %d", ret); | ||
| 126 | + /* 上报失败事件到 bridge */ | ||
| 127 | + DedapPublishAddFail(p->mac, p->prodId, p->snSuffix, ret); | ||
| 128 | + } | ||
| 129 | +} | ||
| 130 | + | ||
| 131 | +/** | ||
| 132 | + * @brief 处理SUBDEV_CLEANUP事件回调(bridge下行→dedap)。 | ||
| 133 | + * @details 配网超时后bridge发布此事件,dedap按mac清理对应的设备会话。 | ||
| 134 | + * @param event 事件ID。 | ||
| 135 | + * @param param 事件参数,包含mac。 | ||
| 136 | + * @param len 参数长度。 | ||
| 137 | + * @return 无返回值;参数非法或链路类型不匹配时提前返回。 | ||
| 138 | + */ | ||
| 139 | +static void DedapSubDevCleanupCallback(uint32_t event, IotcSubDevCleanupParam *param, uint32_t len) | ||
| 140 | +{ | ||
| 141 | + NOT_USED(event); | ||
| 142 | + if (param == NULL || len < sizeof(IotcSubDevCleanupParam)) { | ||
| 143 | + IOTC_LOGE("dedap:subdev cleanup param invalid"); | ||
| 144 | + return; | ||
| 145 | + } | ||
| 146 | + | ||
| 147 | + IotcSubDevCleanupParam *p = param; | ||
| 148 | + | ||
| 149 | + /* 链路类型过滤:仅处理WiFi链路的事件 */ | ||
| 150 | + if (p->linkType != IOTC_LINK_WIFI && p->linkType != IOTC_LINK_NONE) { | ||
| 151 | + IOTC_LOGD("dedap:subdev cleanup event filtered out, linkType=%d", p->linkType); | ||
| 152 | + return; | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + IOTC_LOGI("dedap:[enter]%s,mac=%s", __FUNCTION__, p->mac); | ||
| 156 | + | ||
| 157 | + /* 按mac清理指定设备会话 */ | ||
| 158 | + DedapDeviceSession *sess = DedapFindSessionByMac(p->mac); | ||
| 159 | + if (sess != NULL) { | ||
| 160 | + IOTC_LOGI("dedap:cleanup session mac=%s", p->mac); | ||
| 161 | + DedapFreeSession(sess); | ||
| 162 | + } | ||
| 163 | +} | ||
| 164 | + | ||
| 165 | +/** | ||
| 166 | + * @brief 初始化dedap事件订阅。 | ||
| 167 | + * @details 订阅bridge下行事件(START_DISCOVERY/ADD_SUBDEV/HUB_SETUP/SUBDEV_CLEANUP)。 | ||
| 168 | + * @return 0成功,非0失败。 | ||
| 169 | + */ | ||
| 170 | +int32_t DedapEventHandlerInit(void) | ||
| 171 | +{ | ||
| 172 | + int32_t ret; | ||
| 173 | + | ||
| 174 | + ret = EventBusSubscribe((EventBusCallback)DedapStartDiscoveryCallback, IOTC_BRIDGE_EVENT_START_DISCOVERY); | ||
| 175 | + CHECK_RETURN_LOGE(ret == IOTC_OK, ret, "dedap:subscribe start discovery err:%d", ret); | ||
| 176 | + | ||
| 177 | + ret = EventBusSubscribe((EventBusCallback)DedapAddSubDevCallback, IOTC_BRIDGE_EVENT_ADD_SUBDEV); | ||
| 178 | + CHECK_RETURN_LOGE(ret == IOTC_OK, ret, "dedap:subscribe add subdev err:%d", ret); | ||
| 179 | + | ||
| 180 | + ret = EventBusSubscribe((EventBusCallback)DedapHubSetupCallback, IOTC_BRIDGE_EVENT_HUB_SETUP); | ||
| 181 | + CHECK_RETURN_LOGE(ret == IOTC_OK, ret, "dedap:subscribe hub setup err:%d", ret); | ||
| 182 | + | ||
| 183 | + ret = EventBusSubscribe((EventBusCallback)DedapSubDevCleanupCallback, IOTC_BRIDGE_EVENT_SUBDEV_CLEANUP); | ||
| 184 | + CHECK_RETURN_LOGE(ret == IOTC_OK, ret, "dedap:subscribe subdev cleanup err:%d", ret); | ||
| 185 | + | ||
| 186 | + IOTC_LOGI("dedap:event handlers registered"); | ||
| 187 | + return IOTC_OK; | ||
| 188 | +} | ||
| 189 | + | ||
| 190 | +/** | ||
| 191 | + * @brief 反初始化dedap事件订阅。 | ||
| 192 | + * @details 退订所有已订阅的bridge事件。 | ||
| 193 | + * @return 无返回值。 | ||
| 194 | + */ | ||
| 195 | +void DedapEventHandlerDeinit(void) | ||
| 196 | +{ | ||
| 197 | + EventBusUnsubscribe((EventBusCallback)DedapSubDevCleanupCallback); | ||
| 198 | + EventBusUnsubscribe((EventBusCallback)DedapHubSetupCallback); | ||
| 199 | + EventBusUnsubscribe((EventBusCallback)DedapAddSubDevCallback); | ||
| 200 | + EventBusUnsubscribe((EventBusCallback)DedapStartDiscoveryCallback); | ||
| 201 | + | ||
| 202 | + IOTC_LOGI("dedap:event handlers unregistered"); | ||
| 203 | +} | ||
| @@ -0,0 +1,120 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2024-2026 China Mobile (Hangzhou) Information Technology Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#include <stdio.h> | ||
| 17 | +#include "iotc_log.h" | ||
| 18 | +#include "iotc_wifi.h" | ||
| 19 | +#include "iotc_errcode.h" | ||
| 20 | +#include "utils_assert.h" | ||
| 21 | +#include "securec.h" | ||
| 22 | +#include "dedap_ctx.h" | ||
| 23 | +#include "dedap_hotspot.h" | ||
| 24 | + | ||
| 25 | +#define DEDAP_HOTSPOT_SSID_MAX_LEN (IOTC_WIFI_SSID_MAX_LEN + 1) | ||
| 26 | +#define DEDAP_HOTSPOT_PWD_MAX_LEN (64) | ||
| 27 | +#define DEDAP_HOTSPOT_SSID "ONECONNECT-QOC-LINK" // CMCC-GUIDE-LINK | ||
| 28 | + | ||
| 29 | +/** | ||
| 30 | + * @brief 生成dedap代理配网专用热点的SSID。 | ||
| 31 | + * @param ssid 输出缓冲区,用于存放生成的SSID。 | ||
| 32 | + * @param len 输入/输出:输入时为缓冲区最大长度,输出时为实际长度。 | ||
| 33 | + * @return 0成功,非0失败。 | ||
| 34 | + */ | ||
| 35 | +static int32_t BuildDedapSoftapSsid(uint8_t *ssid, uint32_t *len) | ||
| 36 | +{ | ||
| 37 | + CHECK_RETURN_LOGW(ssid != NULL && len != NULL && *len > 0, | ||
| 38 | + IOTC_ERR_PARAM_INVALID, "param invalid"); | ||
| 39 | + | ||
| 40 | + uint32_t requiredLen = (uint32_t)sizeof(DEDAP_HOTSPOT_SSID); | ||
| 41 | + if (*len < requiredLen) { | ||
| 42 | + IOTC_LOGE("dedap:ssid buffer too small"); | ||
| 43 | + return IOTC_ERR_PARAM_INVALID; | ||
| 44 | + } | ||
| 45 | + if (strcpy_s((char *)ssid, *len, DEDAP_HOTSPOT_SSID) != EOK) { | ||
| 46 | + IOTC_LOGE("dedap:copy ssid failed"); | ||
| 47 | + return IOTC_ERR_SECUREC_STRCPY; | ||
| 48 | + } | ||
| 49 | + *len = requiredLen - 1; | ||
| 50 | + return IOTC_OK; | ||
| 51 | +} | ||
| 52 | + | ||
| 53 | +/** | ||
| 54 | + * @brief 启动专用热点(SoftAP)。 | ||
| 55 | + * @details 生成SSID并调用底层WiFi适配器启动SoftAP, | ||
| 56 | + * 等待WiFi设备连接进行代理配网。 | ||
| 57 | + * @return 0成功,非0失败。 | ||
| 58 | + */ | ||
| 59 | +int32_t DedapHotspotStart(void) | ||
| 60 | +{ | ||
| 61 | + DedapCtx *ctx = GetDedapCtx(); | ||
| 62 | + if (ctx->hotspotRunning) { | ||
| 63 | + IOTC_LOGW("dedap:hotspot already running"); | ||
| 64 | + return IOTC_OK; | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + uint8_t ssid[DEDAP_HOTSPOT_SSID_MAX_LEN] = {0}; | ||
| 68 | + uint32_t ssidLen = sizeof(ssid); | ||
| 69 | + | ||
| 70 | + int32_t ret = BuildDedapSoftapSsid(ssid, &ssidLen); | ||
| 71 | + if (ret != IOTC_OK) { | ||
| 72 | + IOTC_LOGE("dedap:build ssid failed %d", ret); | ||
| 73 | + return ret; | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + IOTC_LOGI("dedap:starting hotspot with ssid='%.*s' len=%u", ssidLen, ssid, ssidLen); | ||
| 77 | + | ||
| 78 | + ret = IotcStartSoftAp(ssid, ssidLen, NULL, 0); | ||
| 79 | + if (ret != IOTC_OK) { | ||
| 80 | + IOTC_LOGE("dedap:start softap failed %d", ret); | ||
| 81 | + return ret; | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + ctx->hotspotRunning = true; | ||
| 85 | + IOTC_LOGI("dedap:hotspot started"); | ||
| 86 | + return IOTC_OK; | ||
| 87 | +} | ||
| 88 | + | ||
| 89 | +/** | ||
| 90 | + * @brief 停止专用热点。 | ||
| 91 | + * @details 调用底层WiFi适配器关闭SoftAP。 | ||
| 92 | + * @return 0成功,非0失败。 | ||
| 93 | + */ | ||
| 94 | +int32_t DedapHotspotStop(void) | ||
| 95 | +{ | ||
| 96 | + DedapCtx *ctx = GetDedapCtx(); | ||
| 97 | + if (!ctx->hotspotRunning) { | ||
| 98 | + IOTC_LOGW("dedap:hotspot not running"); | ||
| 99 | + return IOTC_OK; | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + int32_t ret = IotcStopSoftAp(); | ||
| 103 | + if (ret != IOTC_OK) { | ||
| 104 | + IOTC_LOGE("dedap:stop softap failed %d", ret); | ||
| 105 | + return ret; | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + ctx->hotspotRunning = false; | ||
| 109 | + IOTC_LOGI("dedap:hotspot stopped"); | ||
| 110 | + return IOTC_OK; | ||
| 111 | +} | ||
| 112 | + | ||
| 113 | +/** | ||
| 114 | + * @brief 检查热点是否正在运行。 | ||
| 115 | + * @return true表示热点处于活动状态,false表示未运行。 | ||
| 116 | + */ | ||
| 117 | +bool DedapHotspotIsRunning(void) | ||
| 118 | +{ | ||
| 119 | + return GetDedapCtx()->hotspotRunning; | ||
| 120 | +} | ||
| @@ -0,0 +1,97 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2024-2026 China Mobile (Hangzhou) Information Technology Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#include "iotc_log.h" | ||
| 17 | +#include "iotc_errcode.h" | ||
| 18 | +#include "utils_assert.h" | ||
| 19 | +#include "dedap_ctx.h" | ||
| 20 | +#include "dedap_coap_server.h" | ||
| 21 | +#include "dedap_event_handler.h" | ||
| 22 | +#include "dedap_hotspot.h" | ||
| 23 | +#include "dedap_device_session.h" | ||
| 24 | +#include "dedap_service.h" | ||
| 25 | + | ||
| 26 | +/** | ||
| 27 | + * @brief 初始化dedap服务 | ||
| 28 | + * @details 按顺序初始化:上下文 → 传输层 → 事件订阅 | ||
| 29 | + * @return 0成功,非0失败 | ||
| 30 | + */ | ||
| 31 | +int32_t DedapServiceInit(void) | ||
| 32 | +{ | ||
| 33 | + DedapCtx *ctx = GetDedapCtx(); | ||
| 34 | + if (ctx->initialized) { | ||
| 35 | + IOTC_LOGW("dedap:already initialized"); | ||
| 36 | + return IOTC_OK; | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + IOTC_LOGI("dedap:service init starting..."); | ||
| 40 | + | ||
| 41 | + /* 1. 初始化上下文 */ | ||
| 42 | + int32_t ret = DedapCtxInit(); | ||
| 43 | + if (ret != IOTC_OK) { | ||
| 44 | + IOTC_LOGE("dedap:ctx init failed %d", ret); | ||
| 45 | + return ret; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + /* 2. 初始化传输层(UDP模式) */ | ||
| 49 | + ret = DedapTransportUdpInit(DEDAP_DEFAULT_PORT); | ||
| 50 | + if (ret != IOTC_OK) { | ||
| 51 | + IOTC_LOGE("dedap:transport init failed %d", ret); | ||
| 52 | + DedapCtxDeinit(); | ||
| 53 | + return ret; | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + /* 3. 初始化事件订阅(订阅bridge事件) */ | ||
| 57 | + ret = DedapEventHandlerInit(); | ||
| 58 | + if (ret != IOTC_OK) { | ||
| 59 | + IOTC_LOGE("dedap:event handler init failed %d", ret); | ||
| 60 | + DedapTransportUdpDeinit(); | ||
| 61 | + DedapCtxDeinit(); | ||
| 62 | + return ret; | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + IOTC_LOGI("dedap:service init success"); | ||
| 66 | + return IOTC_OK; | ||
| 67 | +} | ||
| 68 | + | ||
| 69 | +/** | ||
| 70 | + * @brief 反初始化dedap服务 | ||
| 71 | + * @details 按逆序释放资源: | ||
| 72 | + * 1. 停止热点(如果正在运行) | ||
| 73 | + * 2. 退订EventBus事件(取消对bridge事件的订阅) | ||
| 74 | + * 3. 清理上下文(DedapCtxDeinit内部会清理传输层和所有设备会话) | ||
| 75 | + * @note DedapCtxDeinit已包含传输层清理,无需单独调用DedapTransportUdpDeinit | ||
| 76 | + * @return 无返回值;服务未初始化时直接返回。 | ||
| 77 | + */ | ||
| 78 | +void DedapServiceDeinit(void) | ||
| 79 | +{ | ||
| 80 | + DedapCtx *ctx = GetDedapCtx(); | ||
| 81 | + if (!ctx->initialized) { | ||
| 82 | + return; | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + IOTC_LOGI("dedap:service deinit starting..."); | ||
| 86 | + | ||
| 87 | + /* 1. 停止热点(如果正在运行) */ | ||
| 88 | + (void)DedapHotspotStop(); | ||
| 89 | + | ||
| 90 | + /* 2. 退订事件订阅 */ | ||
| 91 | + DedapEventHandlerDeinit(); | ||
| 92 | + | ||
| 93 | + /* 3. 清理上下文(内部会调用DedapTransportUdpDeinit清理传输层,并释放所有设备会话) */ | ||
| 94 | + DedapCtxDeinit(); | ||
| 95 | + | ||
| 96 | + IOTC_LOGI("dedap:service deinit done"); | ||
| 97 | +} | ||
| @@ -138,3 +138,22 @@ if (iotc_one_connect_version_code < 2) { | |||
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | iotc_core_wifi_def = [] | 140 | iotc_core_wifi_def = [] |
| 141 | + | ||
| 142 | +if (iot_connect_wifi_support && iot_connect_dedap_support && | ||
| 143 | + iot_connect_dedap_role_server) { | ||
| 144 | + iotc_core_wifi_inc += [ "$wifi_core_path/application/dedap/include" ] | ||
| 145 | + iotc_core_wifi_src += [ | ||
| 146 | + "$wifi_core_path/application/dedap/dedap_ctx.c", | ||
| 147 | + "$wifi_core_path/application/dedap/dedap_service.c", | ||
| 148 | + "$wifi_core_path/application/dedap/dedap_event_handler.c", | ||
| 149 | + "$wifi_core_path/application/dedap/dedap_hotspot.c", | ||
| 150 | + "$wifi_core_path/application/dedap/dedap_device_session.c", | ||
| 151 | + "$wifi_core_path/application/dedap/dedap_coap_client.c", | ||
| 152 | + "$wifi_core_path/application/dedap/dedap_connrequest.c", | ||
| 153 | + "$wifi_core_path/application/dedap/dedap_coap_server.c", | ||
| 154 | + "$wifi_core_path/application/dedap/dedap_provision.c", | ||
| 155 | + "$wifi_core_path/application/dedap/dedap_coap_enc.c", | ||
| 156 | + "$wifi_core_path/application/dedap/dedap_coap_apiserver.c", | ||
| 157 | + ] | ||
| 158 | + iotc_core_wifi_def += [ "ENABLE_DEDAP_GATEWAY" ] | ||
| 159 | +} | ||
| @@ -26,6 +26,13 @@ | |||
| 26 | #if IOTC_ONECONNECT_VERSION_CODE >= 2 | 26 | #if IOTC_ONECONNECT_VERSION_CODE >= 2 |
| 27 | #include "sched_fd_watch.h" | 27 | #include "sched_fd_watch.h" |
| 28 | #include "net_trans_buffer_inner.h" | 28 | #include "net_trans_buffer_inner.h" |
| 29 | +#include "iotc_event.h" | ||
| 30 | +#include "comm_def.h" | ||
| 31 | +#include "net_lan_search.h" | ||
| 32 | +#include "wifi_net_info.h" | ||
| 33 | +#ifdef ENABLE_DEDAP_GATEWAY | ||
| 34 | +#include "dedap_service.h" | ||
| 35 | +#endif | ||
| 29 | #else | 36 | #else |
| 30 | #include "m2m_cloud_svc.h" | 37 | #include "m2m_cloud_svc.h" |
| 31 | #endif | 38 | #endif |
| @@ -40,6 +47,9 @@ static const FwkInitUnit CORE_WIFI_V3[] = { | |||
| 40 | {FWK_INIT_LVL_BIZ, "wifi_connect", WifiServiceConnectInit, WifiServiceConnectDeinit}, | 47 | {FWK_INIT_LVL_BIZ, "wifi_connect", WifiServiceConnectInit, WifiServiceConnectDeinit}, |
| 41 | {FWK_INIT_LVL_BIZ, "lan_search", LanSearchServiceInit, LanSearchServiceDeinit}, | 48 | {FWK_INIT_LVL_BIZ, "lan_search", LanSearchServiceInit, LanSearchServiceDeinit}, |
| 42 | {FWK_INIT_LVL_BIZ, "local_control", LocalControlServiceInit, LocalControlServiceDeinit}, | 49 | {FWK_INIT_LVL_BIZ, "local_control", LocalControlServiceInit, LocalControlServiceDeinit}, |
| 50 | +#ifdef ENABLE_DEDAP_GATEWAY | ||
| 51 | + {FWK_INIT_LVL_BIZ, "dedap_gw", DedapServiceInit, DedapServiceDeinit}, | ||
| 52 | +#endif | ||
| 43 | }; | 53 | }; |
| 44 | #else | 54 | #else |
| 45 | static const FwkInitUnit CORE_WIFI[] = { | 55 | static const FwkInitUnit CORE_WIFI[] = { |
| @@ -25,6 +25,8 @@ declare_args() { | |||
| 25 | iot_connect_wifi_support = true | 25 | iot_connect_wifi_support = true |
| 26 | iot_connect_eth_support = false | 26 | iot_connect_eth_support = false |
| 27 | iot_connect_bridge_support = false | 27 | iot_connect_bridge_support = false |
| 28 | + iot_connect_dedap_support = false | ||
| 29 | + iot_connect_dedap_role_server = false | ||
| 28 | iot_connect_ailife_support = false | 30 | iot_connect_ailife_support = false |
| 29 | iot_connect_mbedtls_v2_support = false | 31 | iot_connect_mbedtls_v2_support = false |
| 30 | iot_connect_mbedtls_psk_support = false | 32 | iot_connect_mbedtls_psk_support = false |
| @@ -46,7 +48,7 @@ declare_args() { | |||
| 46 | iot_connect_ble_adv_update_support = false | 48 | iot_connect_ble_adv_update_support = false |
| 47 | #是否支持iotc数据保存 | 49 | #是否支持iotc数据保存 |
| 48 | iot_connect_kv_support = true | 50 | iot_connect_kv_support = true |
| 49 | - #控制发OH靠近发现广播的发出 | 51 | + #控制发OH靠近发现广播的发出 |
| 50 | iot_connect_oh_nearlink_support = false | 52 | iot_connect_oh_nearlink_support = false |
| 51 | iot_connect_ssl_backend = "mbedtls" | 53 | iot_connect_ssl_backend = "mbedtls" |
| 52 | iot_connect_openhitls_include_dirs = [] | 54 | iot_connect_openhitls_include_dirs = [] |
| @@ -78,6 +80,10 @@ if (iotc_one_connect_version_code >= 2) { | |||
| 78 | iot_connect_network_support = iot_connect_eth_support || | 80 | iot_connect_network_support = iot_connect_eth_support || |
| 79 | (iot_connect_wifi_support && iotc_one_connect_version_code >= 2) | 81 | (iot_connect_wifi_support && iotc_one_connect_version_code >= 2) |
| 80 | 82 | ||
| 83 | +if (iot_connect_dedap_support && iot_connect_dedap_role_server) { | ||
| 84 | + iot_connect_bridge_support = true | ||
| 85 | +} | ||
| 86 | + | ||
| 81 | if (defined(ohos_lite)) { | 87 | if (defined(ohos_lite)) { |
| 82 | if (ohos_kernel_type == "liteos_m") { | 88 | if (ohos_kernel_type == "liteos_m") { |
| 83 | declare_args() { | 89 | declare_args() { |