add_subdirectory_with_alias_if_exist(third_party/qrcodegen ${PROJECT_BINARY_DIR}/qrcodegen)
add_subdirectory_with_alias_if_exist(third_party/icu ${PROJECT_BINARY_DIR}/icu)
add_subdirectory_with_alias_if_exist(third_party/harfbuzz ${PROJECT_BINARY_DIR}/harfbuzz)
-endif()
-
-if (DEFINES MATCHES "XTS_SUPPORT")
add_subdirectory_with_alias_if_exist(third_party/libjpeg ${PROJECT_BINARY_DIR}/libjpeg)
add_subdirectory_with_alias_if_exist(third_party/zlib ${PROJECT_BINARY_DIR}/zlib)
add_subdirectory_with_alias_if_exist(third_party/libpng ${PROJECT_BINARY_DIR}/libpng)
add_subdirectory_with_alias_if_exist(base/sensors/location ${PROJECT_BINARY_DIR}/ohos/location)
add_subdirectory_with_alias_if_exist(drivers/peripheral/location ${PROJECT_BINARY_DIR}/ohos/location_hdi)
add_subdirectory_with_alias_if_exist(base/sensors ${PROJECT_BINARY_DIR}/ohos/sensors)
-add_subdirectory_with_alias_if_exist(drivers/peripheral/sensor/hal ${PROJECT_BINARY_DIR}/ohos/sensor_hdi)
+add_subdirectory_with_alias_if_exist(drivers/peripheral/sensor/ ${PROJECT_BINARY_DIR}/ohos/sensor_hdi)
add_subdirectory_with_alias_if_exist(utils/native/lite/file ${PROJECT_BINARY_DIR}/ohos/file)
add_subdirectory_with_alias_if_exist(utils/native/lite/kv_store ${PROJECT_BINARY_DIR}/ohos/kv_store)
add_subdirectory_with_alias_if_exist(utils/native/lite/js/builtin ${PROJECT_BINARY_DIR}/ohos/storage_jsi)
#include <unistd.h>\r
\r
#define MAX_ID_ITEM_NUM 0x7F\r
-#define MAX_RES_CONFIG_NUM 0x10\r
+#define MAX_RES_CONFIG_NUM 0x46\r
#define MAX_ITEM_LENGTH 0xFF\r
\r
enum LocaleIndex {\r
* 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
+ * 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,
#include "mbedtls_pkcs7.h"
#include <ctype.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
+#include <stdbool.h>
#include <dirent.h>
#include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
#include <stdlib.h>
+#include <string.h>
#include "app_common.h"
#include "securec.h"
#include "mbedtls/platform.h"
#include <mbedtls/rsa.h>
#include <mbedtls/sha256.h>
#include <mbedtls/pk.h>
+#include "mbedtls/x509_crt.h"
+#include "mbedtls/oid.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include <mbedtls/ecdh.h>
#include "log.h"
#include "nv.h"
-/*
- * below pkcs-7 and pkcs-9 oid definition is not defined in mbedtls now
- * pkcs-7 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 7 }
- */
+#define VERIFY_BUF_LEN 512
+
#ifndef MBEDTLS_OID_PKCS7
-#define MBEDTLS_OID_PKCS7 MBEDTLS_OID_PKCS "\x07"
+#define MBEDTLS_OID_PKCS7 MBEDTLS_OID_PKCS "\x07"
#endif
#ifndef MBEDTLS_OID_PKCS7_DATA
#define PEM_FORMAT_SINGED_DATA 1
#define DER_FORMAT_SINGED_DATA 2
-#define PKCS7_ERR_GOTO_OUT(rc) \
+#define PKCS7_ERR_RETURN_WITH_LOG(rc) \
do { \
if ((rc) != PKCS7_SUCC) \
{ \
} \
} while (0)
+#define OEM_CERT_PATH "/user/app/user/certcfg/"
+
+/* hardcoded public key */
+static const char ROOT_CA_OEM_PUBKEY_IN_PEM[] =
+ "-----BEGIN PUBLIC KEY-----\r\n"
+ "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAvnjlpcsSvEOhMfYwrW/Y\r\n"
+ "ExDmXL47SkbomiorGtdF63J2Vkgs2/HTxhUKBkIvSPbGRTR+io8rAo2J3oz1U48m\r\n"
+ "+M/+yIszIYC2s+tW64v8NuxLwMFFeg7+cud07/FwfJYYIRvyDQVduwV0VwvkTQy+\r\n"
+ "4/n5m+zJEHNheCakEEmFXn7vXUzxlSVSji5cHbGZ2ZzdmettLMc88tv/Kq8X3rgM\r\n"
+ "KQkngVylO4p93UvzY9hIAh9heL5VWMVOj241p3RojavIofODIeF7Vti2DjJjvbPW\r\n"
+ "igV0M9C0wLlZzMTQwoZbZT8mKsHkXW3XdTgc8ccD7RioeQa9MOlLKFbnJQLYNKr+\r\n"
+ "WsGDTFO2iHQmRAIGGuvWnxZIGS5Ho+ZUntdIYAvH8ww+36eFOwNp5cb1/ZjZmQ4c\r\n"
+ "p0zTw3zF8mSEieToMgIgz19wc9hvYgMPLlZpzFZklg8tJenJvcNpk5/3saEmpV6R\r\n"
+ "gGZ0IrmT/5h3Z/49W86Dv3b2ro4zb/sqtLufDqGoF3IDAgMBAAE=\r\n"
+ "-----END PUBLIC KEY-----\r\n";
+
static mbedtls_x509_crt g_rootCaG2Cert;
static bool g_rootCertLoaded;
-static const unsigned char g_rootCaG2CertInPem[] =
+static const unsigned char ROOT_CA_G2_CERT_IN_PEM[] =
"-----BEGIN CERTIFICATE-----\r\n"
"MIICGjCCAaGgAwIBAgIIShhpn519jNAwCgYIKoZIzj0EAwMwUzELMAkGA1UEBhMC\r\n"
"Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEeMBwGA1UE\r\n"
static mbedtls_x509_crt g_debugModeRootCert;
static bool g_debugModeEnabled;
-static const unsigned char g_debugModeRootCertInPem[] =
+static const unsigned char DEBUG_MODE_ROOT_CERT_IN_PEM[] =
"-----BEGIN CERTIFICATE-----\r\n"
"MIICJTCCAaugAwIBAgIIb/9KnVieVTgwCgYIKoZIzj0EAwMwWDELMAkGA1UEBhMC\r\n"
"Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEjMCEGA1UE\r\n"
"1CumzkcYhgU=\r\n"
"-----END CERTIFICATE-----\r\n";
-#define VERIFY_BUF_LEN 512
-#define MAX_CERTPATH_LEN 256
-#define OEM_CERT_PATH "/user/app/user/certcfg/"
+static CertVerifyCache g_certCache = {0};
+static bool g_cacheValid = false;
static void *Pkcs7Calloc(size_t nmemb, size_t size)
{
-#if (RUNNING_BOARD == LITE_WEARABLE)
- void *ptr = PSRAM_Malloc(nmemb * size);
- if (ptr == NULL) {
- return NULL;
- }
- (void)memset_s(ptr, nmemb * size, 0, nmemb * size);
- return ptr;
+#ifdef LITEWEARABLE_SUPPORT_ENABLED
+ return APPV_CALLOC(nmemb, size);
#else
return calloc(nmemb, size);
#endif
static void Pkcs7Free(void *ptr)
{
-#if (RUNNING_BOARD == LITE_WEARABLE)
- PSRAM_Free(ptr);
+#ifdef LITEWEARABLE_SUPPORT_ENABLED
+ APPV_FREE(ptr);
#else
free(ptr);
#endif
}
-
-#ifdef MARKET_ENABLE
+#ifdef OH_MARKET_ENABLE
#define DIALMARKET_PUBKEY_PATH "/user/dialpubkey"
-/* hardcoded public key */
-static const char ROOT_CA_OEM_PUBKEY_IN_PEM[] =
- "-----BEGIN PUBLIC KEY-----\r\n"
- "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAvnjlpcsSvEOhMfYwrW/Y\r\n"
- "ExDmXL47SkbomiorGtdF63J2Vkgs2/HTxhUKBkIvSPbGRTR+io8rAo2J3oz1U48m\r\n"
- "+M/+yIszIYC2s+tW64v8NuxLwMFFeg7+cud07/FwfJYYIRvyDQVduwV0VwvkTQy+\r\n"
- "4/n5m+zJEHNheCakEEmFXn7vXUzxlSVSji5cHbGZ2ZzdmettLMc88tv/Kq8X3rgM\r\n"
- "KQkngVylO4p93UvzY9hIAh9heL5VWMVOj241p3RojavIofODIeF7Vti2DjJjvbPW\r\n"
- "igV0M9C0wLlZzMTQwoZbZT8mKsHkXW3XdTgc8ccD7RioeQa9MOlLKFbnJQLYNKr+\r\n"
- "WsGDTFO2iHQmRAIGGuvWnxZIGS5Ho+ZUntdIYAvH8ww+36eFOwNp5cb1/ZjZmQ4c\r\n"
- "p0zTw3zF8mSEieToMgIgz19wc9hvYgMPLlZpzFZklg8tJenJvcNpk5/3saEmpV6R\r\n"
- "gGZ0IrmT/5h3Z/49W86Dv3b2ro4zb/sqtLufDqGoF3IDAgMBAAE=\r\n"
- "-----END PUBLIC KEY-----\r\n";
-
static const unsigned char g_dialRootCertInPem[] =
"-----BEGIN CERTIFICATE-----\r\n"
"MIIEsTCCAxmgAwIBAgIUdJ4u/0ct0XJHZphCzmBQQddboC4wDQYJKoZIhvcNAQEL\r\n"
return ret;
}
-int32_t PKCS7_GenerateECCKeypair()
+int32_t PKCS7_GenerateECCKeypair(void)
{
unsigned char clientPubKey[ECC_PEN_KEY_LEN];
EcdhEntity client = {0};
HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to GetClientECCPubKey!\n");
goto cleanup;
}
- if (CreateCubdirAndFile(DIALMARKET_PUBKEY_PATH, pubKeyFileName, clientPubKey, strlen(clientPubKey)) != 0) {
+ if (CreateCubdirAndFile(DIALMARKET_PUBKEY_PATH, (const char*)pubKeyFileName,
+ clientPubKey, strlen((const char*)clientPubKey)) != 0) {
HILOG_ERROR(HILOG_MODULE_AAFWK, "Public key write failed!");
ret = MBEDTLS_ERR_PK_FILE_IO_ERROR;
goto cleanup;
memset_s(eccWorkKey, AES_KEY_LEN, 0, AES_KEY_LEN);
return ret;
}
+#endif
-static int32_t VerifyHashList()
+static void FreeCertVerifyCache(CertVerifyCache *cache)
{
- int32_t rc = 0;
- const char *hashListFile = OEM_CERT_PATH"root_cert_hash_list.bin";
- const char *signatureFile = OEM_CERT_PATH"hash_list_sign.bin";
- unsigned char hash[SHA256_HASH_SIZE];
- mbedtls_pk_context pk;
- FILE *file = fopen(hashListFile, "rb");
+ if (cache == NULL) return;
+
+ if (cache->hashListData != NULL) {
+ Pkcs7Free(cache->hashListData);
+ cache->hashListData = NULL;
+ }
+ cache->hashListSize = 0;
+ cache->verifyTime = 0;
+ g_cacheValid = false;
+}
+
+/**
+ * 计算文件的SHA256哈希值(与openssl dgst -sha256兼容)
+ * @param filePath 文件路径
+ * @param hash 输出二进制哈希值(32字节)
+ * @param hexHash 输出十六进制哈希字符串(65字节,包含终止符)
+ * @return 成功返回PKCS7_SUCC,失败返回错误码
+ */
+static int32_t CalculateFileSha256(const char *filePath, unsigned char *hash, char *hexHash)
+{
+ if (filePath == NULL || hash == NULL || hexHash == NULL) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Invalid parameters to CalculateFileSha256");
+ return PKCS7_INVALID_PARAM;
+ }
+
+ FILE *file = NULL;
+ mbedtls_sha256_context sha256Ctx;
+ unsigned char *buffer = NULL;
+ size_t bufferSize = 4096; // 4KB缓冲区
+ size_t bytesRead;
+ int32_t rc = PKCS7_SUCC;
+ const char *hexChars = "0123456789abcdef";
+
+ // 分配堆内存缓冲区
+ buffer = Pkcs7Calloc(bufferSize, sizeof(unsigned char));
+ if (buffer == NULL) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to allocate buffer for file reading");
+ return PKCS7_MEMORY_EXHAUST;
+ }
+
+ file = fopen(filePath, "rb");
if (!file) {
- HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to open file to verify.");
- return PKCS7_VERIFY_FAIL;
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to open file: %s", filePath);
+ rc = PKCS7_FILE_OPERATION_FAIL;
+ goto cleanup;
}
- rc = fseek(file, 0, SEEK_END);
- if (rc != 0) {
- rc = PKCS7_HAS_NO_SIGNER_CRT;
- goto exit;
+
+ mbedtls_sha256_init(&sha256Ctx);
+
+ // 初始化SHA256上下文(0表示SHA-256,1表示SHA-224)
+ if (mbedtls_sha256_starts(&sha256Ctx, 0) != 0) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to initialize SHA256 context");
+ rc = PKCS7_INVALID_VALUE;
+ goto cleanup;
}
- long fileSize = ftell(file);
- rc = fseek(file, 0, SEEK_SET);
- if (rc != 0 || fileSize > INT_MAX) {
- rc = PKCS7_HAS_NO_SIGNER_CRT;
- goto exit;
+
+ // 读取文件并更新哈希
+ while ((bytesRead = fread(buffer, 1, bufferSize, file)) > 0) {
+ if (mbedtls_sha256_update(&sha256Ctx, buffer, bytesRead) != 0) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to update SHA256 hash");
+ rc = PKCS7_INVALID_VALUE;
+ goto cleanup;
+ }
}
- unsigned char *fileData = Pkcs7Calloc(fileSize, sizeof(char));
- if (!fileData) {
- rc = PKCS7_HAS_NO_SIGNER_CRT;
- goto exit;
+
+ // 检查文件读取错误
+ if (ferror(file)) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Error reading file: %s", filePath);
+ rc = PKCS7_FILE_OPERATION_FAIL;
+ goto cleanup;
}
- int32_t fileLen = fread(fileData, 1, fileSize, file);
- if (fileLen != fileSize) {
- rc = PKCS7_HAS_NO_SIGNER_CRT;
- goto exit;
+
+ // 完成哈希计算
+ if (mbedtls_sha256_finish(&sha256Ctx, hash) != 0) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to finalize SHA256 hash");
+ rc = PKCS7_INVALID_VALUE;
+ goto cleanup;
}
- mbedtls_pk_init(&pk);
- if ((rc = mbedtls_pk_parse_public_key(&pk, (const unsigned char *)ROOT_CA_OEM_PUBKEY_IN_PEM,
- strlen(ROOT_CA_OEM_PUBKEY_IN_PEM) + 1)) != 0) {
- rc = PKCS7_HAS_NO_SIGNER_CRT;
- goto exit;
+
+ // 转换为十六进制字符串(与openssl输出格式一致)
+ for (int i = 0; i < SHA256_HASH_SIZE; i++) {
+ hexHash[i * 2] = hexChars[(hash[i] >> 4) & 0x0F];
+ hexHash[i * 2 + 1] = hexChars[hash[i] & 0x0F];
}
- mbedtls_rsa_context *rsa = mbedtls_pk_rsa(pk);
- mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
- FILE *sigFile = fopen(signatureFile, "rb");
- if (!sigFile) {
- rc = PKCS7_HAS_NO_SIGNER_CRT;
- goto exit;
+ hexHash[64] = '\0';
+
+cleanup:
+ if (file) fclose(file);
+ if (buffer) Pkcs7Free(buffer);
+ mbedtls_sha256_free(&sha256Ctx);
+ return rc;
+}
+
+// 十六进制哈希转换为二进制(使用安全函数)
+static int32_t HexHashToBinary(const char *hexHash, unsigned char *binaryHash)
+{
+ if (hexHash == NULL || binaryHash == NULL) {
+ return PKCS7_INVALID_PARAM;
}
- unsigned char *signature = Pkcs7Calloc(RSA3072_SIG_SIZE, sizeof(char));
- if (!signature) {
- rc = PKCS7_HAS_NO_SIGNER_CRT;
- goto exit;
+
+ for (size_t i = 0; i < SHA256_HASH_SIZE; i++) {
+ unsigned int byte = 0;
+ if (sscanf_s(hexHash + i * 2, "%2x", &byte) != 1) {
+ return PKCS7_INVALID_VALUE;
+ }
+ binaryHash[i] = (unsigned char)byte;
}
- if (fread(signature, 1, RSA3072_SIG_SIZE, sigFile) != RSA3072_SIG_SIZE) {
- rc = PKCS7_VERIFY_FAIL;
- goto exit;
+ return PKCS7_SUCC;
+}
+
+// 解析单行哈希条目
+static int32_t ParseHashLine(const char *line, size_t lineLen, CertHashEntry *entry)
+{
+ if (line == NULL || entry == NULL) {
+ return PKCS7_INVALID_PARAM;
}
- mbedtls_sha256(fileData, fileSize, hash, 0);
- rc = mbedtls_pk_verify(&pk, MBEDTLS_MD_SHA256, hash, SHA256_HASH_SIZE, signature, RSA3072_SIG_SIZE);
- if (rc != 0) {
- HILOG_ERROR(HILOG_MODULE_AAFWK, "mbedtls_pk_verify failed! return %d\n", rc);
- goto exit;
+
+ const char *colon = memchr(line, ':', lineLen);
+ if (colon == NULL || colon <= line || colon >= line + lineLen - 1) {
+ return PKCS7_INVALID_VALUE;
}
-exit:
- if (file) {
+
+ size_t nameLen = colon - line;
+ size_t hashHexLen = line + lineLen - colon - 1;
+
+ // 跳过可能的回车符
+ if (hashHexLen > 0 && *(colon + hashHexLen) == '\r') {
+ hashHexLen--;
+ }
+
+ if (hashHexLen != 64) {
+ return PKCS7_INVALID_VALUE;
+ }
+
+ // 分配证书名内存
+ entry->certName = Pkcs7Calloc(nameLen + 1, 1);
+ if (entry->certName == NULL) {
+ return PKCS7_MEMORY_EXHAUST;
+ }
+
+ // 复制证书名
+ if (memcpy_s(entry->certName, nameLen + 1, line, nameLen) != EOK) {
+ Pkcs7Free(entry->certName);
+ entry->certName = NULL;
+ return PKCS7_INVALID_VALUE;
+ }
+ entry->certName[nameLen] = '\0';
+
+ // 复制哈希十六进制字符串
+ if (memcpy_s(entry->hashHex, sizeof(entry->hashHex), colon + 1, hashHexLen) != EOK) {
+ Pkcs7Free(entry->certName);
+ entry->certName = NULL;
+ return PKCS7_INVALID_VALUE;
+ }
+ entry->hashHex[hashHexLen] = '\0';
+ entry->hashHexLen = hashHexLen;
+
+ // 转换为二进制哈希
+ return HexHashToBinary(entry->hashHex, entry->hash);
+}
+
+// 十六进制哈希转换为二进制
+/**
+ * 解析哈希列表文本格式(证书文件名:哈希值)
+ * 格式示例:cert.pem:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ */
+int32_t ParseHashListTextFormat(const unsigned char *data, size_t dataLen, CertHashList *hashList)
+{
+ if (data == NULL || dataLen == 0 || hashList == NULL) {
+ return PKCS7_INVALID_PARAM;
+ }
+
+ const char *start = (const char *)data;
+ const char *end = start + dataLen;
+ const char *ptr = start;
+ size_t lineCount = 0;
+
+ // 计算行数
+ while (ptr < end) {
+ const char *lineEnd = memchr(ptr, '\n', end - ptr);
+ if (lineEnd == NULL) {
+ if (ptr < end) lineCount++;
+ break;
+ }
+ if (lineEnd > ptr) lineCount++;
+ ptr = lineEnd + 1;
+ }
+
+ if (lineCount == 0) {
+ return PKCS7_INVALID_VALUE;
+ }
+
+ // 分配内存
+ hashList->entries = Pkcs7Calloc(lineCount, sizeof(CertHashEntry));
+ if (hashList->entries == NULL) {
+ return PKCS7_MEMORY_EXHAUST;
+ }
+
+ hashList->count = 0;
+ hashList->capacity = lineCount;
+
+ // 解析每行
+ ptr = start;
+ size_t index = 0;
+
+ while (ptr < end && index < lineCount) {
+ const char *lineEnd = memchr(ptr, '\n', end - ptr);
+ if (lineEnd == NULL) lineEnd = end;
+
+ size_t lineLen = lineEnd - ptr;
+ if (lineLen > 0) {
+ int32_t rc = ParseHashLine(ptr, lineLen, &hashList->entries[index]);
+ if (rc == PKCS7_SUCC) {
+ hashList->count++;
+ index++;
+ }
+ }
+ ptr = lineEnd + 1;
+ }
+
+ return (hashList->count > 0) ? PKCS7_SUCC : PKCS7_INVALID_VALUE;
+}
+
+static void FreeCertHashList(CertHashList *hashList)
+{
+ if (hashList == NULL) return;
+
+ if (hashList->entries != NULL) {
+ for (size_t i = 0; i < hashList->count; i++) {
+ if (hashList->entries[i].certName != NULL) {
+ Pkcs7Free(hashList->entries[i].certName);
+ hashList->entries[i].certName = NULL;
+ }
+ }
+ Pkcs7Free(hashList->entries);
+ hashList->entries = NULL;
+ }
+ hashList->count = 0;
+ hashList->capacity = 0;
+}
+
+// 解析hash列表文件内容
+static int32_t ParseHashListContent(const unsigned char *data, size_t dataLen,
+ char ***certNames, unsigned char **certHashes,
+ size_t *certCount)
+{
+ if (data == NULL || dataLen == 0 || certNames == NULL ||
+ certHashes == NULL || certCount == NULL) {
+ return PKCS7_INVALID_PARAM;
+ }
+ HILOG_INFO(HILOG_MODULE_AAFWK, "ParseHashListContent: dataLen=%zu", dataLen);
+ // 简单的行解析逻辑,实际应根据具体格式调整
+ size_t count = 0;
+ const char *start = (const char *)data;
+ const char *end = start + dataLen;
+
+ // 第一遍:计算行数
+ const char *ptr = start;
+ while (ptr < end) {
+ const char *lineEnd = memchr(ptr, '\n', end - ptr);
+ if (lineEnd == NULL) break;
+ if (lineEnd > ptr) count++;
+ ptr = lineEnd + 1;
+ }
+ HILOG_INFO(HILOG_MODULE_AAFWK, "Found %zu lines in hash list", count);
+ if (count == 0) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "No valid lines found in hash list");
+ return PKCS7_INVALID_VALUE;
+ }
+
+ *certNames = Pkcs7Calloc(count, sizeof(char *));
+ *certHashes = Pkcs7Calloc(count, SHA256_HASH_SIZE);
+ if (*certNames == NULL || *certHashes == NULL) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Memory allocation failed for certNames or certHashes");
+ if (*certNames) Pkcs7Free(*certNames);
+ if (*certHashes) Pkcs7Free(*certHashes);
+ return PKCS7_MEMORY_EXHAUST;
+ }
+
+ // 第二遍:解析每行
+ ptr = start;
+ size_t index = 0;
+ while (ptr < end && index < count) {
+ const char *lineEnd = memchr(ptr, '\n', end - ptr);
+ if (lineEnd == NULL) lineEnd = end;
+
+ const char *colon = memchr(ptr, ':', lineEnd - ptr);
+ if (colon != NULL && colon > ptr && (lineEnd - colon - 1) >= SHA256_HASH_SIZE) {
+ // 解析证书文件名
+ size_t nameLen = colon - ptr;
+ (*certNames)[index] = Pkcs7Calloc(nameLen + 1, 1);
+ if ((*certNames)[index] == NULL) {
+ // 清理已分配的内存
+ for (size_t i = 0; i < index; i++) {
+ Pkcs7Free((*certNames)[i]);
+ }
+ Pkcs7Free(*certNames);
+ Pkcs7Free(*certHashes);
+ return PKCS7_MEMORY_EXHAUST;
+ }
+ int ret = memcpy_s((*certNames)[index], nameLen + 1, ptr, nameLen);
+ if (ret != 0) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to copy certificate name, error: %d", ret);
+ // 清理已分配的内存
+ Pkcs7Free((*certNames)[index]);
+ for (size_t i = 0; i < index; i++) {
+ Pkcs7Free((*certNames)[i]);
+ }
+ Pkcs7Free(*certNames);
+ Pkcs7Free(*certHashes);
+ return PKCS7_FILE_OPERATION_FAIL;
+ }
+ (*certNames)[index][nameLen] = '\0';
+
+ // 解析哈希值
+ ret = memcpy_s(&(*certHashes)[index * SHA256_HASH_SIZE], SHA256_HASH_SIZE, colon + 1, SHA256_HASH_SIZE);
+ if (ret != 0) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to copy certificate hash, error: %d", ret);
+ // 清理已分配的内存
+ Pkcs7Free((*certNames)[index]);
+ for (size_t i = 0; i < index; i++) {
+ Pkcs7Free((*certNames)[i]);
+ }
+ Pkcs7Free(*certNames);
+ Pkcs7Free(*certHashes);
+ return PKCS7_FILE_OPERATION_FAIL;
+ }
+ index++;
+ }
+
+ ptr = lineEnd + 1;
+ }
+
+ *certCount = index;
+ return PKCS7_SUCC;
+}
+
+// 读取哈希列表文件
+static int32_t ReadHashListFile(const char *hashListFile, unsigned char **fileData, long *fileSize)
+{
+ FILE *file = NULL;
+ int32_t rc = PKCS7_SUCC;
+
+ if (hashListFile == NULL || fileData == NULL || fileSize == NULL) {
+ return PKCS7_INVALID_PARAM;
+ }
+
+ file = fopen(hashListFile, "rb");
+ if (!file) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to open hash list file: %s", hashListFile);
+ return PKCS7_FILE_OPERATION_FAIL;
+ }
+
+ if (fseek(file, 0, SEEK_END) != 0) {
+ fclose(file);
+ return PKCS7_FILE_OPERATION_FAIL;
+ }
+
+ *fileSize = ftell(file);
+ if (fseek(file, 0, SEEK_SET) != 0 || *fileSize <= 0) {
+ fclose(file);
+ return PKCS7_FILE_OPERATION_FAIL;
+ }
+
+ *fileData = Pkcs7Calloc(*fileSize + 1, sizeof(char));
+ if (*fileData == NULL) {
fclose(file);
- file = NULL;
+ return PKCS7_MEMORY_EXHAUST;
+ }
+
+ size_t bytesRead = fread(*fileData, 1, *fileSize, file);
+ fclose(file);
+
+ if (bytesRead != (size_t)*fileSize) {
+ Pkcs7Free(*fileData);
+ *fileData = NULL;
+ return PKCS7_FILE_OPERATION_FAIL;
}
- if (sigFile) {
+
+ (*fileData)[*fileSize] = '\0';
+ return PKCS7_SUCC;
+}
+
+// 读取签名文件
+static int32_t ReadSignatureFile(const char *signatureFile, unsigned char **signature)
+{
+ FILE *sigFile = NULL;
+
+ if (signatureFile == NULL || signature == NULL) {
+ return PKCS7_INVALID_PARAM;
+ }
+
+ sigFile = fopen(signatureFile, "rb");
+ if (!sigFile) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to open signature file: %s", signatureFile);
+ return PKCS7_FILE_OPERATION_FAIL;
+ }
+
+ *signature = Pkcs7Calloc(RSA3072_SIG_SIZE, sizeof(char));
+ if (*signature == NULL) {
fclose(sigFile);
- sigFile = NULL;
+ return PKCS7_MEMORY_EXHAUST;
+ }
+
+ size_t sigLen = fread(*signature, 1, RSA3072_SIG_SIZE, sigFile);
+ fclose(sigFile);
+
+ if (sigLen != RSA3072_SIG_SIZE) {
+ Pkcs7Free(*signature);
+ *signature = NULL;
+ return PKCS7_FILE_OPERATION_FAIL;
+ }
+
+ return PKCS7_SUCC;
+}
+
+// 验证哈希列表签名
+static int32_t VerifyHashListSignature(const unsigned char *fileData, long fileSize,
+ const unsigned char *signature)
+{
+ mbedtls_pk_context pk;
+ unsigned char hash[SHA256_HASH_SIZE];
+ int32_t rc;
+
+ if (fileData == NULL || fileSize <= 0 || signature == NULL) {
+ return PKCS7_INVALID_PARAM;
}
+
+ mbedtls_pk_init(&pk);
+
+ rc = mbedtls_pk_parse_public_key(&pk, (const unsigned char *)ROOT_CA_OEM_PUBKEY_IN_PEM,
+ strlen(ROOT_CA_OEM_PUBKEY_IN_PEM) + 1);
+ if (rc != 0) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Public key parsing failed: -0x%04X", -rc);
+ mbedtls_pk_free(&pk);
+ return PKCS7_INVALID_PARAM;
+ }
+
+ // 设置RSA填充模式
+ if (mbedtls_pk_get_type(&pk) == MBEDTLS_PK_RSA) {
+ mbedtls_rsa_context *rsa = mbedtls_pk_rsa(pk);
+ mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
+ }
+
+ rc = mbedtls_sha256(fileData, fileSize, hash, 0);
+ if (rc != 0) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "SHA256 calculation failed: -0x%04X", -rc);
+ mbedtls_pk_free(&pk);
+ return rc;
+ }
+
+ rc = mbedtls_pk_verify(&pk, MBEDTLS_MD_SHA256, hash, SHA256_HASH_SIZE,
+ signature, RSA3072_SIG_SIZE);
+ if (rc != 0) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Signature verification failed: -0x%04X", -rc);
+ }
+
+ mbedtls_pk_free(&pk);
+ return (rc == 0) ? PKCS7_SUCC : rc;
+}
+
+static int32_t VerifyAndCacheHashList(CertVerifyCache *cache)
+{
+ int32_t rc = 0;
+ const char *hashListFile = OEM_CERT_PATH"root_cert_hash_list.bin";
+ const char *signatureFile = OEM_CERT_PATH"hash_list_sign.bin";
+ unsigned char *fileData = NULL;
+ unsigned char *signature = NULL;
+ unsigned char *cachedData = NULL;
+ long fileSize = 0;
+
+ if (cache == NULL) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Invalid cache parameter");
+ return PKCS7_INVALID_PARAM;
+ }
+
+ // 检查缓存是否仍然有效
+ if (g_cacheValid && cache->hashListData != NULL) {
+ struct stat st;
+ if (stat(hashListFile, &st) == 0 && st.st_mtime <= cache->verifyTime) {
+ HILOG_INFO(HILOG_MODULE_AAFWK, "Using cached hash list verification");
+ return PKCS7_SUCC;
+ }
+ }
+
+ // 清除旧缓存
+ FreeCertVerifyCache(cache);
+
+ // 读取哈希列表文件
+ rc = ReadHashListFile(hashListFile, &fileData, &fileSize);
+ if (rc != PKCS7_SUCC) {
+ goto cleanup;
+ }
+
+ // 读取签名文件
+ rc = ReadSignatureFile(signatureFile, &signature);
+ if (rc != PKCS7_SUCC) {
+ goto cleanup;
+ }
+
+ // 验证签名
+ rc = VerifyHashListSignature(fileData, fileSize, signature);
+ if (rc != PKCS7_SUCC) {
+ goto cleanup;
+ }
+
+ // 创建缓存数据的副本
+ cachedData = Pkcs7Calloc(fileSize + 1, sizeof(char));
+ if (cachedData == NULL) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Memory allocation failed for cache data");
+ rc = PKCS7_MEMORY_EXHAUST;
+ goto cleanup;
+ }
+
+ if (memcpy_s(cachedData, fileSize + 1, fileData, fileSize) != EOK) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to copy cache data");
+ rc = PKCS7_INVALID_VALUE;
+ goto cleanup;
+ }
+ cachedData[fileSize] = '\0';
+
+ // 设置缓存
+ cache->hashListData = cachedData;
+ cache->hashListSize = fileSize;
+ cache->verifyTime = time(NULL);
+
+ if (strcpy_s(cache->certDirPath, sizeof(cache->certDirPath), OEM_CERT_PATH) != EOK) {
+ HILOG_WARN(HILOG_MODULE_AAFWK, "Failed to copy certificate directory path");
+ }
+
+ g_cacheValid = true;
+ cachedData = NULL; // 所有权转移给cache,避免重复释放
+
+ HILOG_INFO(HILOG_MODULE_AAFWK, "Hash list verification successful");
+
+cleanup:
if (fileData) {
Pkcs7Free(fileData);
fileData = NULL;
Pkcs7Free(signature);
signature = NULL;
}
- mbedtls_pk_free(&pk);
+ if (cachedData) {
+ Pkcs7Free(cachedData);
+ cachedData = NULL;
+ }
return rc;
}
-#endif
/* valid digest alg now: sha256 sha384 sha512 */
static bool InvalidDigestAlg(const mbedtls_asn1_buf *alg)
MBEDTLS_OID_CMP(MBEDTLS_OID_DIGEST_ALG_SHA512, alg);
}
-static int32_t GetContentInfoType(unsigned char **p, const unsigned char *end, mbedtls_asn1_buf *contentType,
- bool *hasContent)
+static int32_t GetContentInfoType(unsigned char **p, const unsigned char *end,
+ mbedtls_asn1_buf *contentType, bool *hasContent)
{
size_t seqLen = 0;
size_t len = 0;
unsigned char *oneSignerEnd = NULL;
/* parse one signer info */
rc = mbedtls_asn1_get_tag(p, end, &oneSignerLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
- PKCS7_ERR_GOTO_OUT(rc);
+ PKCS7_ERR_RETURN_WITH_LOG(rc);
oneSignerEnd = *p + oneSignerLen;
/* parse version */
rc = ParseSignerVersion(p, oneSignerEnd, signers);
- PKCS7_ERR_GOTO_OUT(rc);
+ PKCS7_ERR_RETURN_WITH_LOG(rc);
/* parse issuerAndSerialNum */
rc = ParseSignerIssuerAndSerialNum(p, oneSignerEnd, signers);
- PKCS7_ERR_GOTO_OUT(rc);
+ PKCS7_ERR_RETURN_WITH_LOG(rc);
/* parse digestAlgorithm */
rc = ParseSignerDigestAlg(p, oneSignerEnd, signers);
- PKCS7_ERR_GOTO_OUT(rc);
+ PKCS7_ERR_RETURN_WITH_LOG(rc);
/* parse authenticatedAttributes */
rc = ParseSignerAuthAttr(p, oneSignerEnd, signers);
- PKCS7_ERR_GOTO_OUT(rc);
+ PKCS7_ERR_RETURN_WITH_LOG(rc);
/* parse digestEncryptionAlgorithm */
rc = ParseSignerEncAlg(p, oneSignerEnd, signers);
- PKCS7_ERR_GOTO_OUT(rc);
+ PKCS7_ERR_RETURN_WITH_LOG(rc);
/* parse encryptedDigest */
rc = ParseSignerSignature(p, oneSignerEnd, signers);
- PKCS7_ERR_GOTO_OUT(rc);
+ PKCS7_ERR_RETURN_WITH_LOG(rc);
/* parse unauthenticatedAttributes */
rc = ParseSignerUnAuthAttr(p, oneSignerEnd, signers);
- PKCS7_ERR_GOTO_OUT(rc);
+ PKCS7_ERR_RETURN_WITH_LOG(rc);
if (*p < end) {
signers->next = Pkcs7Calloc(1, sizeof(*signers));
return certsList;
}
-static int32_t LoadSelfSignedCert(void)
+// 验证单个证书文件
+static int32_t VerifyCertificateFile(const char *certPath, const unsigned char *expectedHash,
+ mbedtls_x509_crt *topCert)
{
- mbedtls_x509_crt_init(&g_ohosRootCert);
- int32_t rc = mbedtls_x509_crt_parse(&g_ohosRootCert, OHOS_ROOT_CERT_IN_PEM, sizeof(OHOS_ROOT_CERT_IN_PEM));
- if (rc) {
- HILOG_ERROR(HILOG_MODULE_AAFWK,"load oh signed ca failed %d", rc);
+ unsigned char actualHash[SHA256_HASH_SIZE];
+ char actualHashHex[65];
+ int32_t rc;
+
+ if (certPath == NULL || expectedHash == NULL || topCert == NULL) {
+ return PKCS7_INVALID_PARAM;
+ }
+
+ // 计算文件哈希
+ rc = CalculateFileSha256(certPath, actualHash, actualHashHex);
+ if (rc != PKCS7_SUCC) {
return rc;
- } else {
- HILOG_INFO(HILOG_MODULE_AAFWK,"load oh signed root ca success");
}
- return rc;
+
+ // 比较哈希值
+ if (memcmp(actualHash, expectedHash, SHA256_HASH_SIZE) != 0) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Certificate hash verification failed for: %s", certPath);
+ return PKCS7_INVALID_VALUE;
+ }
+
+ // 解析证书
+ mbedtls_x509_crt tmpCert;
+ mbedtls_x509_crt_init(&tmpCert);
+
+ rc = mbedtls_x509_crt_parse_file(&tmpCert, certPath);
+ if (rc != 0) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to parse certificate: %s, error: -0x%04X", certPath, -rc);
+ mbedtls_x509_crt_free(&tmpCert);
+ return rc;
+ }
+
+ // 检查证书匹配
+ int32_t match = CompareX509NameList(&tmpCert.subject, &topCert->issuer);
+ mbedtls_x509_crt_free(&tmpCert);
+
+ return (match == 0) ? PKCS7_SUCC : PKCS7_INVALID_VALUE;
}
-static int32_t FindAndStoreRootCert(mbedtls_x509_crt *topCert)
+// 加载根证书
+static int32_t LoadRootCertificate(const char *certPath)
{
- int32_t rc = PKCS7_PARSING_ERROR;
- DIR *dir = NULL;
- struct dirent *entry = NULL;
- char certPath[MAX_CERTPATH_LEN];
- if (access(OEM_CERT_PATH, F_OK) != 0) {
- HILOG_DEBUG(HILOG_MODULE_AAFWK, "Please upload the application root certificate.");
- return LoadSelfSignedCert();
+ if (certPath == NULL) {
+ return PKCS7_INVALID_PARAM;
}
- dir = opendir(OEM_CERT_PATH);
- if (dir == NULL) {
- HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to open certificate directory.");
- return PKCS7_BUILD_CERT_PATH_FAIL;
+
+ mbedtls_x509_crt_free(&g_ohosRootCert);
+ mbedtls_x509_crt_init(&g_ohosRootCert);
+
+ int32_t rc = mbedtls_x509_crt_parse_file(&g_ohosRootCert, certPath);
+ if (rc != 0) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to load root certificate: %s, error: -0x%04X", certPath, -rc);
+ return PKCS7_HAS_NO_SIGNER_CRT;
+ }
+
+ return PKCS7_SUCC;
+}
+
+// 辅助函数
+static bool ShouldSkipFile(const struct dirent *entry)
+{
+ if (entry == NULL) {
+ return true;
+ }
+
+ return (strcmp(entry->d_name, ".") == 0 ||
+ strcmp(entry->d_name, "..") == 0 ||
+ strstr(entry->d_name, ".pem") == NULL);
+}
+
+static const CertHashEntry *FindHashEntry(const CertHashList *hashList, const char *fileName)
+{
+ if (hashList == NULL || fileName == NULL) {
+ return NULL;
+ }
+
+ for (size_t i = 0; i < hashList->count; i++) {
+ if (hashList->entries[i].certName != NULL &&
+ strcmp(fileName, hashList->entries[i].certName) == 0) {
+ return &hashList->entries[i];
+ }
+ }
+ return NULL;
+}
+
+// 扫描证书目录
+static int32_t ScanCertificateDirectory(DIR *dir, const CertHashList *hashList,
+ mbedtls_x509_crt *topCert)
+{
+ struct dirent *entry;
+ char certPath[MAX_CERTPATH_LEN];
+ int32_t rc = PKCS7_PARSING_ERROR;
+
+ if (dir == NULL || hashList == NULL || topCert == NULL) {
+ return PKCS7_INVALID_PARAM;
}
+
while ((entry = readdir(dir)) != NULL) {
- const char *ext = strrchr(entry->d_name, '.');
- if (ext == NULL || strcmp(ext, ".pem") != 0) {
+ if (ShouldSkipFile(entry)) {
continue;
}
- rc = snprintf_s(certPath, sizeof(certPath), sizeof(certPath) - 1, OEM_CERT_PATH"%s", entry->d_name);
- if (rc < 0) {
- HILOG_ERROR(HILOG_MODULE_AAFWK, "Get cert path failed, return %d!", rc);
+
+ // 构建证书路径
+ if (snprintf_s(certPath, sizeof(certPath), sizeof(certPath) - 1,
+ "%s%s", OEM_CERT_PATH, entry->d_name) < 0) {
continue;
}
- mbedtls_x509_crt tmpRootCert;
- mbedtls_x509_crt_init(&tmpRootCert);
- rc = mbedtls_x509_crt_parse_file(&tmpRootCert, certPath);
- if (rc != 0) {
- HILOG_ERROR(HILOG_MODULE_AAFWK, "Parse %s failed: %d.", certPath, rc);
- mbedtls_x509_crt_free(&tmpRootCert);
+
+ // 查找匹配的哈希条目
+ const CertHashEntry *hashEntry = FindHashEntry(hashList, entry->d_name);
+ if (hashEntry == NULL) {
continue;
}
- /* Compare the subject of the device root certificate and the issuer of the uppermost certificate. */
- if (CompareX509NameList(&tmpRootCert.subject, &topCert->issuer) == 0) {
- HILOG_INFO(HILOG_MODULE_AAFWK, "Found matching root cert: %s.", entry->d_name);
- /* Reparse the root certificate to g_ohosRootCert. */
- rc = mbedtls_x509_crt_parse_file(&g_ohosRootCert, certPath);
- if (rc != 0) {
- HILOG_ERROR(HILOG_MODULE_AAFWK, "Re-parsing root cert failed: %d!", rc);
- mbedtls_x509_crt_free(&tmpRootCert);
- closedir(dir);
- return PKCS7_HAS_NO_SIGNER_CRT;
+
+ // 验证证书文件
+ rc = VerifyCertificateFile(certPath, hashEntry->hash, topCert);
+ if (rc == PKCS7_SUCC) {
+ // 加载根证书
+ rc = LoadRootCertificate(certPath);
+ if (rc == PKCS7_SUCC) {
+ break;
}
- rc = PKCS7_SUCC;
- mbedtls_x509_crt_free(&tmpRootCert);
- break;
}
- mbedtls_x509_crt_free(&tmpRootCert);
}
+ return rc;
+}
+
+// 检查证书路径是否可用
+bool IsCertPathAvailable(void)
+{
+ struct stat st;
+ if (stat(OEM_CERT_PATH, &st) != 0) {
+ HILOG_INFO(HILOG_MODULE_AAFWK, "Certificate path does not exist: %s", OEM_CERT_PATH);
+ return false;
+ }
+
+ if (!S_ISDIR(st.st_mode)) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Certificate path is not a directory: %s", OEM_CERT_PATH);
+ return false;
+ }
+
+ // 检查目录是否可读
+ if (access(OEM_CERT_PATH, 0) != 0) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Certificate directory is not readable: %s", OEM_CERT_PATH);
+ return false;
+ }
+
+ return true;
+}
+
+// 加载内置证书
+static int32_t LoadSelfSignedCert(void)
+{
+ mbedtls_x509_crt_free(&g_ohosRootCert);
+ mbedtls_x509_crt_init(&g_ohosRootCert);
+
+ HILOG_INFO(HILOG_MODULE_AAFWK, "Loading built-in OpenHarmony root certificate");
+
+ // 规范化证书格式:将\r\n转换为\n
+ size_t certLen = strlen((const char*)OHOS_ROOT_CERT_IN_PEM);
+ char *normalizedCert = Pkcs7Calloc(certLen + 1, 1);
+ if (normalizedCert == NULL) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Memory allocation failed for certificate normalization");
+ return PKCS7_MEMORY_EXHAUST;
+ }
+
+ // 复制并替换换行符
+ const char *src = (const char*)OHOS_ROOT_CERT_IN_PEM;
+ char *dst = normalizedCert;
+ while (*src) {
+ if (src[0] == '\r' && src[1] == '\n') {
+ *dst++ = '\n';
+ src += 2; // 跳过\r\n
+ } else {
+ *dst++ = *src++;
+ }
+ }
+ *dst = '\0';
+
+ int32_t rc = mbedtls_x509_crt_parse(&g_ohosRootCert, (const unsigned char*)normalizedCert,
+ strlen(normalizedCert) + 1);
+
+ Pkcs7Free(normalizedCert);
+
+ if (rc != 0) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to parse built-in certificate: -0x%04X", -rc);
+ return PKCS7_HAS_NO_SIGNER_CRT;
+ }
+
+ HILOG_INFO(HILOG_MODULE_AAFWK, "Built-in certificate loaded successfully with normalized line endings");
+ return PKCS7_SUCC;
+}
+
+static int32_t FindAndStoreRootCertWithCache(mbedtls_x509_crt *topCert, CertVerifyCache *cache)
+{
+ if (topCert == NULL) {
+ return PKCS7_INVALID_PARAM;
+ }
+
+ // 如果缓存无效,先验证哈希列表
+ if (cache == NULL || cache->hashListData == NULL) {
+ HILOG_INFO(HILOG_MODULE_AAFWK, "Cache invalid, verifying hash list");
+ int32_t rc = VerifyAndCacheHashList(cache);
+ if (rc != PKCS7_SUCC) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Hash list verification failed: %d", rc);
+ return rc;
+ }
+ }
+
+ CertHashList hashList = {0};
+ DIR *dir = NULL;
+ int32_t rc = PKCS7_PARSING_ERROR;
+
+ // 解析哈希列表
+ rc = ParseHashListTextFormat(cache->hashListData, cache->hashListSize, &hashList);
+ if (rc != PKCS7_SUCC || hashList.count == 0) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to parse hash list or no entries found");
+ FreeCertHashList(&hashList);
+ return PKCS7_INVALID_VALUE;
+ }
+
+ // 打开证书目录
+ dir = opendir(OEM_CERT_PATH);
+ if (dir == NULL) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to open certificate directory: %s", OEM_CERT_PATH);
+ FreeCertHashList(&hashList);
+ return PKCS7_BUILD_CERT_PATH_FAIL;
+ }
+
+ // 扫描证书文件
+ rc = ScanCertificateDirectory(dir, &hashList, topCert);
+
closedir(dir);
+ FreeCertHashList(&hashList);
+
+ if (rc != PKCS7_SUCC) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to find matching root certificate");
+ }
+
return rc;
}
int32_t rc = 0;
if (!g_rootCertLoaded) {
mbedtls_x509_crt_init(&g_rootCaG2Cert);
- rc = mbedtls_x509_crt_parse(&g_rootCaG2Cert, g_rootCaG2CertInPem, sizeof(g_rootCaG2CertInPem));
+ rc = mbedtls_x509_crt_parse(&g_rootCaG2Cert, ROOT_CA_G2_CERT_IN_PEM, sizeof(ROOT_CA_G2_CERT_IN_PEM));
if (rc) {
HILOG_ERROR(HILOG_MODULE_AAFWK, "load root ca failed!");
return rc;
static int32_t LoadDebugModeRootCert(void)
{
mbedtls_x509_crt_init(&g_debugModeRootCert);
- int32_t rc = mbedtls_x509_crt_parse(&g_debugModeRootCert, g_debugModeRootCertInPem,
- sizeof(g_debugModeRootCertInPem));
+ int32_t rc = mbedtls_x509_crt_parse(&g_debugModeRootCert, DEBUG_MODE_ROOT_CERT_IN_PEM,
+ sizeof(DEBUG_MODE_ROOT_CERT_IN_PEM));
if (rc) {
HILOG_ERROR(HILOG_MODULE_AAFWK, "load debug mode root ca failed %d", rc);
return rc;
mbedtls_x509_buf *signerSerial = &signer->serial;
mbedtls_x509_name *signerIssuer = &signer->issuer;
mbedtls_x509_crt *cert = signedData->certs;
- HILOG_INFO(HILOG_MODULE_AAFWK, "To filter one signer's cert");
while (cert != NULL) {
if (SerialCmp(signerSerial, &cert->serial) == 0 &&
CompareX509NameList(signerIssuer, &cert->issuer) == 0) {
signer->certPath.depth++;
}
-static int32_t BuildSignerCertPath(SignerInfo *signer, mbedtls_x509_crt *lowerCrt, SignedData *signeData)
+static int32_t BuildSignerCertPath(SignerInfo *signer, mbedtls_x509_crt *lowerCrt, SignedData *signedData)
{
+ if (signer == NULL || lowerCrt == NULL || signedData == NULL) {
+ return PKCS7_INVALID_PARAM;
+ }
+
+ HILOG_INFO(HILOG_MODULE_AAFWK, "Building certificate path");
+
int32_t scanCnt = 0;
int32_t rc = PKCS7_SUCC;
+
+ // 确保根证书已加载
if (!g_rootCertLoaded) {
- return PKCS7_ROOT_CA_NOT_VALID;
+ rc = LoadRootCert();
+ if (rc != PKCS7_SUCC) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Root certificate not loaded: %d", rc);
+ return PKCS7_ROOT_CA_NOT_VALID;
+ }
}
+
+ // 设置默认根证书
signer->rootCert = &g_rootCaG2Cert;
- mbedtls_x509_crt *certs = signeData->certs;
- /* From the root ca cert, to found the signer secondary ca , and use secondary cert to
- * find the next level ca cert */
+ mbedtls_x509_crt *certs = signedData->certs;
+ if (certs == NULL) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "No certificates in signed data");
+ return PKCS7_INVALID_VALUE;
+ }
+
mbedtls_x509_crt *cur = lowerCrt;
mbedtls_x509_crt *next = NULL;
int32_t certsCnt = GetCertsNumOfSignedData(certs);
- DelCertOfSignedData(signeData, cur);
+
+ HILOG_INFO(HILOG_MODULE_AAFWK, "Certificate chain has %d certificates", certsCnt);
+
+ DelCertOfSignedData(signedData, cur);
AddCertToSignerCertPath(signer, cur);
+
while (true) {
- next = FindSuperCert(cur, signeData->certs);
+ next = FindSuperCert(cur, signedData->certs);
if (next == NULL) {
- mbedtls_x509_crt_init(&g_ohosRootCert);
- rc = FindAndStoreRootCert(cur);
- if (rc == 0) {
- HILOG_INFO(HILOG_MODULE_AAFWK, "load self signed root ca success");
+ HILOG_INFO(HILOG_MODULE_AAFWK, "Reached top of certificate chain");
+
+ // 根据路径可用性选择证书源
+ if (IsCertPathAvailable()) {
+ HILOG_INFO(HILOG_MODULE_AAFWK, "Using local certificate path for root certificate");
+ rc = FindAndStoreRootCertWithCache(cur, &g_certCache);
} else {
- HILOG_ERROR(HILOG_MODULE_AAFWK, "load self signed ca failed %d", rc);
+ HILOG_INFO(HILOG_MODULE_AAFWK, "Using built-in OpenHarmony root certificate");
+ rc = LoadSelfSignedCert();
+ if (rc == PKCS7_SUCC) {
+ // 设置签名者的根证书为内置证书
+ signer->rootCert = &g_ohosRootCert;
+ }
+ }
+
+ if (rc != PKCS7_SUCC) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to load root certificate: %d", rc);
}
break;
} else {
- DelCertOfSignedData(signeData, next);
+ DelCertOfSignedData(signedData, next);
AddCertToSignerCertPath(signer, next);
}
+
scanCnt++;
if (scanCnt > certsCnt) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Certificate chain scanning exceeded limit");
rc = PKCS7_BUILD_CERT_PATH_FAIL;
break;
}
cur = next;
}
+
+ HILOG_INFO(HILOG_MODULE_AAFWK, "Certificate path building completed: %d", rc);
return rc;
}
static int32_t ConstructSignerCerts(SignedData *signedData)
{
- /* scan all of the signers , and filter the signer's certs by serial and name */
+ if (signedData == NULL) {
+ return PKCS7_INVALID_PARAM;
+ }
+
SignerInfo *signer = &signedData->signers;
while (signer != NULL) {
mbedtls_x509_crt *cert = GetLowLevelCerts(signedData);
HILOG_ERROR(HILOG_MODULE_AAFWK, "Could not found signer's lowest cert");
return PKCS7_INVALID_VALUE;
}
+
+ // 根据路径可用性构建证书路径
int32_t rc = BuildSignerCertPath(signer, cert, signedData);
- if (rc != 0) {
+ if (rc != PKCS7_SUCC) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Build signer certificate path failed: %d", rc);
return rc;
}
signer = signer->next;
}
- return 0;
+ return PKCS7_SUCC;
}
/* get signer digest alg */
static int32_t VerifyClicert(mbedtls_x509_crt *clicert, mbedtls_x509_crt *rootCert, const Pkcs7 *pkcs7)
{
- uint32_t flags;
+ uint32_t flags = 0;
int32_t rc = mbedtls_x509_crt_verify(clicert, rootCert,
(mbedtls_x509_crl *)&pkcs7->signedData.crl, NULL, &flags, NULL, NULL);
if (rc) {
if (pkcs7 == NULL) {
return PKCS7_INVALID_PARAM;
}
+
int32_t cnt = 0;
const SignerInfo *signer = &pkcs7->signedData.signers;
+
while (signer != NULL) {
mbedtls_x509_crt *clicert = signer->certPath.crt;
if (clicert == NULL) {
- HILOG_ERROR(HILOG_MODULE_AAFWK, "Signer has no certs");
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Signer has no certificates");
return PKCS7_HAS_NO_SIGNER_CRT;
}
+
int32_t rc;
cnt++;
- HILOG_INFO(HILOG_MODULE_AAFWK, "signer : %d", cnt);
+
if (g_debugModeEnabled) {
rc = VerifyClicert(clicert, &g_debugModeRootCert, pkcs7);
- HILOG_DEBUG(HILOG_MODULE_AAFWK, "Verify inner: %d", rc);
if (rc == PKCS7_SUCC) {
signer = signer->next;
continue;
}
- if (rc == PKCS7_IS_REVOKED) {
- return PKCS7_IS_REVOKED;
- }
+ HILOG_WARN(HILOG_MODULE_AAFWK, "Debug mode verification failed");
}
- rc = VerifyClicert(clicert, signer->rootCert, pkcs7);
- HILOG_DEBUG(HILOG_MODULE_AAFWK, "Verify : %d", rc);
+#ifndef OHOS_SIGN_HAPS_BY_SERVER
+ // 首先尝试使用内置OpenHarmony根证书
+ rc = VerifyClicert(clicert, &g_ohosRootCert, pkcs7);
if (rc == PKCS7_SUCC) {
signer = signer->next;
continue;
}
- if (rc == PKCS7_IS_REVOKED) {
- return PKCS7_IS_REVOKED;
- }
-#ifndef OHOS_SIGN_HAPS_BY_SERVER
- rc = VerifyClicert(clicert, &g_ohosRootCert, pkcs7);
- HILOG_DEBUG(HILOG_MODULE_AAFWK, "Verify self : %d", rc);
+#endif
+ // 如果内置证书验证失败,尝试系统根证书
+ HILOG_WARN(HILOG_MODULE_AAFWK, "Built-in certificate failed, trying system root certificate");
+ rc = VerifyClicert(clicert, &g_rootCaG2Cert, pkcs7);
if (rc == PKCS7_SUCC) {
+ HILOG_INFO(HILOG_MODULE_AAFWK, "System root certificate verification successful");
signer = signer->next;
continue;
}
-#endif
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "All certificate verification attempts failed: %d", rc);
return rc;
}
+
+ HILOG_INFO(HILOG_MODULE_AAFWK, "All certificate chains verified successfully");
return PKCS7_SUCC;
}
}
#endif
+// 统一的证书加载入口
+static int32_t CheckAndLoadCertificates(void)
+{
+ static bool certificatesLoaded = false;
+ static int32_t lastLoadResult = PKCS7_SUCC;
+
+ // 如果已经加载过且成功,直接返回缓存结果
+ if (certificatesLoaded) {
+ return lastLoadResult;
+ }
+
+ int32_t rc = PKCS7_SUCC;
+
+ if (IsCertPathAvailable()) {
+ HILOG_INFO(HILOG_MODULE_AAFWK, "Certificate path available, verifying hash list");
+ rc = VerifyAndCacheHashList(&g_certCache);
+ if (rc != PKCS7_SUCC) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Hash list verification failed, falling back to built-in certificate");
+ // 验证失败时回退到内置证书
+ rc = LoadSelfSignedCert();
+ }
+ } else {
+ HILOG_INFO(HILOG_MODULE_AAFWK, "Certificate path not available, using built-in certificate");
+ // 清理可能存在的旧缓存
+ FreeCertVerifyCache(&g_certCache);
+ rc = LoadSelfSignedCert();
+ }
+
+ certificatesLoaded = true;
+ lastLoadResult = rc;
+ return rc;
+}
+
int32_t PKCS7_ParseSignedData(const unsigned char *buf, size_t bufLen, Pkcs7 *pkcs7)
{
int32_t rc;
bool hasContent = false;
unsigned char *start = NULL;
unsigned char *end = NULL;
+
if (buf == NULL || bufLen == 0 || pkcs7 == NULL) {
return PKCS7_INVALID_PARAM;
}
+
(void)memset_s(pkcs7, sizeof(*pkcs7), 0, sizeof(*pkcs7));
+
+ HILOG_INFO(HILOG_MODULE_AAFWK, "Starting PKCS7 parsing, bufLen=%zu", bufLen);
+
start = (unsigned char *)buf;
-#ifdef PARSE_PEM_FORMAT_SIGNED_DATA
- char format = 0;
- rc = ParsePemFormatSignedData(buf, bufLen, &pkcs7->pem, &format);
- if (rc) {
- goto EXIT;
- }
- if (format == PEM_FORMAT_SINGED_DATA) {
- start = pkcs7->pem.MBEDTLS_PRIVATE(buf);
- bufLen = pkcs7->pem.MBEDTLS_PRIVATE(buflen);
- }
-#endif
-#ifdef MARKET_ENABLE
- if (access(OEM_CERT_PATH, F_OK) == 0) {
- rc = VerifyHashList();
- P_ERR_GOTO_WTTH_LOG(rc);
- }
-#endif
- /* loaded the c2 root ca cert */
- rc = LoadRootCert();
- P_ERR_GOTO_WTTH_LOG(rc);
- HILOG_INFO(HILOG_MODULE_AAFWK, "Begin to parse pkcs#7 signed data");
end = start + bufLen;
- /* parse the ContentInfo total head */
+
+ // 先解析PKCS7数据,再处理证书
+ HILOG_INFO(HILOG_MODULE_AAFWK, "Begin to parse pkcs#7 signed data");
+
+ // 解析ContentInfo头部
rc = GetContentInfoType(&start, end, &(pkcs7->contentTypeOid), &hasContent);
- P_ERR_GOTO_WTTH_LOG(rc);
+ if (rc != PKCS7_SUCC) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Get content info type failed: %d", rc);
+ goto exit;
+ }
+
if (!IsSigedDataOid(pkcs7) || !hasContent) {
rc = PKCS7_INVALID_CONTENT_TYPE_OR_NO_CONTENT;
HILOG_ERROR(HILOG_MODULE_AAFWK, "Input data is not pkcs#7 signed data format or has no content info");
- goto EXIT;
+ goto exit;
}
+
rc = GetContentLenOfContentInfo(&start, end, &len);
- P_ERR_GOTO_WTTH_LOG(rc);
+ if (rc != PKCS7_SUCC) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Get content length failed: %d", rc);
+ goto exit;
+ }
+
if (start + len > end) {
rc = PKCS7_INVALID_CONTENT_TYPE_OR_NO_CONTENT;
HILOG_ERROR(HILOG_MODULE_AAFWK, "The length of input data is invalid");
- goto EXIT;
+ goto exit;
}
+
rc = ParseSignedData(start, len, &(pkcs7->signedData));
- P_ERR_GOTO_WTTH_LOG(rc);
+ if (rc != PKCS7_SUCC) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Parse signed data failed: %d", rc);
+ goto exit;
+ }
+
HILOG_INFO(HILOG_MODULE_AAFWK, "Parse pkcs#7 signed data success");
+
+ // 现在构建证书路径(这里会根据路径可用性选择证书)
rc = ConstructSignerCerts(&pkcs7->signedData);
- P_ERR_GOTO_WTTH_LOG(rc);
+ if (rc != PKCS7_SUCC) {
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "Construct signer certificates failed: %d", rc);
+ goto exit;
+ }
+
+ HILOG_INFO(HILOG_MODULE_AAFWK, "PKCS7 parsing completed successfully");
return rc;
-EXIT:
+
+exit:
+ HILOG_ERROR(HILOG_MODULE_AAFWK, "PKCS7 parsing failed: %d", rc);
+ PKCS7_FreeRes(pkcs7);
return rc;
}
#ifndef OHOS_SIGN_HAPS_BY_SERVER
UnLoadSelfSignedCert();
#endif
+ FreeCertVerifyCache(&g_certCache);
}
\ No newline at end of file
int len;
} AppSignPk;
-#ifdef MARKET_ENABLE
+#ifdef OH_MARKET_ENABLE
#define NOISE_SIZE 32
#define SALT_INFO_POOL_ROWS 3
#define PUBLIC_KEY_FILE_LEN (SALT_INFO_POOL_ROWS * NOISE_SIZE * 2 + 4 + 1)
/* get unsigned file len without verify, return V_ERR if not OK */
int APPVERI_GetUnsignedFileLength(const char *filePath);
-#ifdef MARKET_ENABLE
+#ifdef OH_MARKET_ENABLE
/*******************************************************************************
* Function : PKCS7_GenerateECCKeypair
* Description : Generate ECC brainpool256R1 key pair and write to PEM files
*
* Return : int 0 on success, non-zero error code on failure
*******************************************************************************/
-int32_t PKCS7_GenerateECCKeypair();
+int32_t PKCS7_GenerateECCKeypair(void);
/*******************************************************************************
* Function : PKCS7_VerifyAndDecrypt
* #define PARSE_PEM_FORMAT_SIGNED_DATA 1
*/
#define MAX_SIGNER_NAME_LEN 512
+#define MAX_CERTPATH_LEN 256
+#define SHA256_HASH_SIZE 32
+#define RSA3072_SIG_SIZE 384
/* Parse error definition */
typedef enum {
PKCS7_SUCC = 0,
#endif
} Pkcs7;
+typedef struct {
+ unsigned char *hashListData;
+ size_t hashListSize;
+ char certDirPath[MAX_CERTPATH_LEN];
+ time_t verifyTime;
+} CertVerifyCache;
+
+typedef struct {
+ char *certName;
+ unsigned char hash[SHA256_HASH_SIZE];
+ size_t hashHexLen;
+ char hashHex[65]; // 十六进制表示的哈希值
+} CertHashEntry;
+
+typedef struct {
+ CertHashEntry *entries;
+ size_t count;
+ size_t capacity;
+} CertHashList;
+
/*******************************************************************************
* Function : PKCS7_ParseSignedData
* Description : parse the pkcs7 signed data, store the resolved data to pkcs7
${CMAKE_CURRENT_SOURCE_DIR}/include
${ROOT_DIR}/open_source/mbedtls/mbedtls_v3.6.0/include
${OHOS_DIR}/commonlibrary/utils_lite/include
+ ${ROOT_DIR}/open_source/openharmony/base/security/appverify/include
)
set(SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/cipher_sha256.c
${CMAKE_CURRENT_SOURCE_DIR}/src/cipher_aes.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/cipher_base64.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/cipher_hmac_sha256.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/cipher_md5.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/cipher_nv_store.c
)
set(COMPONENT_PUBLIC_CCFLAGS
#ifdef __cplusplus\r
#include <cstdint>\r
#include <cstdio>\r
+#include <cstdbool>\r
#else\r
#include <stdint.h>\r
#include <stdio.h>\r
+#include <stdbool.h>\r
#endif\r
+#include "nv.h"\r
\r
#ifdef __cplusplus\r
#if __cplusplus\r
#define ERROR_CODE_GENERAL (-1)\r
#define ERROR_SUCCESS 0\r
\r
+#define UT_NV_MAX_LENGTH 4060\r
+#define KEY_ID_START NV_ID_ACE_CIPHER\r
+#define KEY_ID_END 0x2900\r
+#define KEY_ID_COUNT (KEY_ID_END - KEY_ID_START)\r
+\r
typedef struct Sha256Context Sha256Context;\r
\r
typedef enum {\r
void Sha256Starts(Sha256Context *ctx);\r
int32_t Sha256Update(Sha256Context *ctx, const unsigned char *input, size_t ilen);\r
void Sha256Finish(Sha256Context *ctx, unsigned char output[32]);\r
+\r
+int Base64EncodeInternal(const unsigned char *input, size_t inputLen, char *output, size_t outputLen);\r
+int Base64DecodeInternal(const char *input, size_t inputLen, unsigned char *output, size_t outputLen);\r
+int HmacSha256Compute(const unsigned char *key,\r
+ size_t keyLen, const unsigned char *input, size_t inputLen, unsigned char *output);\r
+int Md5Compute(const unsigned char *input, size_t inputLen, unsigned char *output);\r
+uint16_t InnerGetUsedKeyIds(uint16_t *used_ids, uint16_t max_count);\r
+uint16_t InnerGetAvailableKeyIds(uint16_t *available_ids, uint16_t max_count);\r
+int32_t InnerDeleteKeyFromNv(uint16_t keyId);\r
+int32_t InnerGetKeyFromNv(uint16_t keyId, uint8_t *data, uint16_t *actualKeyLen);\r
+int32_t InnerSaveKeyToNv(unsigned char *keyBuff, uint32_t keyBuffLen, uint16_t keyId, bool overwrite);\r
+\r
+\r
// ohos end\r
int32_t InitAesCryptData(const char *action, const char *text, const char *key,\r
const AesIvMode *iv, AesCryptContext *aesCryptCxt);\r
\r
enum CipherLogLevel {\r
CIPHER_LOG_LEVEL_E,\r
+ CIPHER_LOG_LEVEL_D,\r
+ CIPHER_LOG_LEVEL_I,\r
};\r
\r
#ifdef __cplusplus\r
\r
#ifndef __LITEOS__\r
#define CIPHER_LOG_E(...) CipherLog(CIPHER_LOG_LEVEL_E, __func__, __LINE__, __VA_ARGS__)\r
+#define CIPHER_LOG_D(...) CipherLog(CIPHER_LOG_LEVEL_D, __func__, __LINE__, __VA_ARGS__)\r
+#define CIPHER_LOG_I(...) CipherLog(CIPHER_LOG_LEVEL_I, __func__, __LINE__, __VA_ARGS__)\r
#else\r
#define CIPHER_LOG_E printf\r
+#define CIPHER_LOG_D printf\r
+#define CIPHER_LOG_I printf\r
#endif\r
#ifdef __cplusplus\r
}\r
return ERROR_SUCCESS;
}
+static void GetPaddingLen(char *data, int32_t *paddingLen)
+{
+ uint8_t pad_len = data[*paddingLen - 1];
+ for (int i = 0; i < *paddingLen; i++) {
+ uint8_t temp = data[i];
+ if (temp > 0 && temp <= AES_BLOCK_SIZE && temp == pad_len) {
+ *paddingLen = i;
+ break;
+ }
+ }
+}
+
static int32_t InitAesCryptContext(const char *key, const AesIvMode *iv, AesCryptContext *ctx)
{
int32_t ret;
CIPHER_LOG_E("remove padding failed.\n");
return ERROR_CODE_GENERAL;
}
+ if (ctx->paddingMode == PADDING_NONE) {
+ GetPaddingLen(ctx->data.text, &unpaddedLen);
+ }
ctx->data.textLen = unpaddedLen;
// 添加字符串终止符
CIPHER_LOG_E("remove padding failed.\n");
return ERROR_CODE_GENERAL;
}
+ if (ctx->paddingMode == PADDING_NONE) {
+ GetPaddingLen(ctx->data.text, &unpaddedLen);
+ }
ctx->data.textLen = unpaddedLen;
// 添加字符串终止符
--- /dev/null
+/*
+ * Copyright (c) 2025-2030 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.
+ */
+
+// ohos begin
+// Add software base64
+#include "cipher.h"
+#include "mbedtls/base64.h"
+
+// Base64编码底层实现
+int Base64EncodeInternal(const unsigned char *input, size_t inputLen, char *output, size_t outputLen)
+{
+ size_t actualOutputLen = 0;
+ return mbedtls_base64_encode((unsigned char *)(output), outputLen, &actualOutputLen, input, inputLen);
+}
+
+// Base64解码底层实现
+int Base64DecodeInternal(const char *input, size_t inputLen, unsigned char *output, size_t outputLen)
+{
+ size_t actualOutputLen = 0;
+ return mbedtls_base64_decode(
+ output, outputLen, &actualOutputLen, (const unsigned char *)(input), inputLen);
+}
+// ohos end
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2025-2030 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.
+ */
+
+// ohos begin
+// Add software hmac-sha256
+#include "cipher.h"
+#include "cipher_log.h"
+#include "mbedtls/md.h"
+#include "mbedtls/error.h"
+#include <string.h>
+
+// HMAC-SHA256底层计算
+int HmacSha256Compute(
+ const unsigned char *key, size_t keyLen, const unsigned char *input, size_t inputLen, unsigned char *output)
+{
+ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
+ if (md_info == NULL) {
+ return -1;
+ }
+
+ return mbedtls_md_hmac(md_info, key, keyLen, input, inputLen, output);
+}
+// ohos end
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2025-2030 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.
+ */
+
+// ohos begin
+// Add software md5
+#include "cipher.h"
+#include "mbedtls/md5.h"
+
+// MD5底层计算
+int Md5Compute(const unsigned char *input, size_t inputLen, unsigned char *output)
+{
+ mbedtls_md5_context ctx;
+ mbedtls_md5_init(&ctx);
+
+ int ret = mbedtls_md5_starts(&ctx);
+ if (ret != 0) {
+ goto cleanup;
+ }
+
+ ret = mbedtls_md5_update(&ctx, input, inputLen);
+ if (ret != 0) {
+ goto cleanup;
+ }
+
+ ret = mbedtls_md5_finish(&ctx, output);
+
+cleanup:
+ mbedtls_md5_free(&ctx);
+ return ret;
+}
+// ohos end
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2025-2030 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.
+ */
+
+// ohos begin
+// Add NV store
+#include "cipher.h"
+#include "cipher_log.h"
+#include "app_common.h"
+#include <stdint.h>
+#include <string.h>
+
+// 位图大小计算(每个bit表示一个keyId)
+#define BITMAP_SIZE ((KEY_ID_COUNT + 7) / 8)
+
+// 使用一个特殊的keyId来存储位图(在密钥区间之前)
+#define BITMAP_KEY_ID 0x26FF
+
+// 全局位图变量
+static uint8_t keyIdBitmap[BITMAP_SIZE] = {0};
+static int bitmapInitialized = 0;
+
+// 属性配置
+static nv_key_attr_t nvAttr = {0, 1, 0, 0};
+
+/**
+ * @brief 初始化密钥ID位图
+ * @return 0-成功,其他-失败
+ */
+static int32_t InitKeyIdBitmap(void)
+{
+ int32_t ret = 0;
+ uint16_t readLen = 0;
+
+ if (bitmapInitialized) {
+ return 0;
+ }
+
+ // 尝试从NV读取位图
+ ret = uapi_nv_read_with_attr(BITMAP_KEY_ID, BITMAP_SIZE, &readLen, keyIdBitmap, &nvAttr);
+ if (ret != 0 || readLen != BITMAP_SIZE) {
+ // 读取失败或长度不匹配,初始化位图为全0
+ CIPHER_LOG_D("Initialize key_id bitmap for first use\n");
+ memset_s(keyIdBitmap, BITMAP_SIZE, 0, BITMAP_SIZE);
+
+ // 将初始化的位图保存到NV
+ ret = uapi_nv_write_with_attr(BITMAP_KEY_ID, keyIdBitmap, BITMAP_SIZE, &nvAttr, NULL);
+ if (ret != 0) {
+ CIPHER_LOG_E("Failed to initialize key_id bitmap to NV\n");
+ return ret;
+ }
+ }
+
+ bitmapInitialized = 1;
+ CIPHER_LOG_I("Key_id bitmap initialized successfully\n");
+ return 0;
+}
+
+/**
+ * @brief 保存位图到NV
+ * @return 0-成功,其他-失败
+ */
+static int32_t SaveKeyIdBitmap(void)
+{
+ if (!bitmapInitialized) {
+ CIPHER_LOG_E("Bitmap not initialized\n");
+ return -1;
+ }
+
+ int32_t ret = uapi_nv_write_with_attr(BITMAP_KEY_ID, keyIdBitmap, BITMAP_SIZE, &nvAttr, NULL);
+ if (ret != 0) {
+ CIPHER_LOG_E("Failed to save key_id bitmap to NV\n");
+ }
+ return ret;
+}
+
+/**
+ * @brief 检查keyId是否有效且在范围内
+ * @param keyId 密钥ID
+ * @return 1-有效,0-无效
+ */
+static int IsValidKeyId(uint16_t keyId)
+{
+ return (keyId >= KEY_ID_START && keyId < KEY_ID_END);
+}
+
+/**
+ * @brief 设置keyId为已使用
+ * @param keyId 密钥ID
+ */
+static void SetKeyIdUsed(uint16_t keyId)
+{
+ if (IsValidKeyId(keyId)) {
+ uint16_t index = keyId - KEY_ID_START;
+ keyIdBitmap[index / 8] |= (1 << (index % 8));
+ }
+}
+
+/**
+ * @brief 检查keyId是否已被使用
+ * @param keyId 密钥ID
+ * @return 1-已使用,0-未使用
+ */
+static int IsKeyIdUsed(uint16_t keyId)
+{
+ if (!IsValidKeyId(keyId)) {
+ return 0;
+ }
+ uint16_t index = keyId - KEY_ID_START;
+ return (keyIdBitmap[index / 8] >> (index % 8)) & 1;
+}
+
+/**
+ * @brief 清除keyId的使用标记
+ * @param keyId 密钥ID
+ */
+static void ClearKeyIdUsed(uint16_t keyId)
+{
+ if (IsValidKeyId(keyId)) {
+ uint16_t index = keyId - KEY_ID_START;
+ keyIdBitmap[index / 8] &= ~(1 << (index % 8));
+ }
+}
+
+/**
+ * @brief 保存密钥到NV存储
+ * @param keyBuff 密钥数据缓冲区
+ * @param keyBuffLen 密钥数据长度
+ * @param keyId 密钥ID
+ * @param overwrite 是否覆盖已存在的密钥
+ * @return 0-成功,其他-失败
+ */
+int32_t InnerSaveKeyToNv(unsigned char *keyBuff, uint32_t keyBuffLen, uint16_t keyId, bool overwrite)
+{
+ int32_t ret = 0;
+
+ // 初始化位图(如果未初始化)
+ if (!bitmapInitialized) {
+ ret = InitKeyIdBitmap();
+ if (ret != 0) {
+ CIPHER_LOG_E("Failed to initialize key_id bitmap\n");
+ return ret;
+ }
+ }
+
+ // 检查keyId是否有效
+ if (!IsValidKeyId(keyId)) {
+ CIPHER_LOG_E("Invalid keyId: 0x%04X, valid range: [0x%04X, 0x%04X)\n",
+ keyId, KEY_ID_START, KEY_ID_END);
+ return -1;
+ }
+
+ // 检查参数有效性
+ if (keyBuff == NULL || keyBuffLen == 0) {
+ CIPHER_LOG_E("Invalid key buffer or length\n");
+ return -1;
+ }
+
+ // 检查keyId是否已被使用
+ bool keyUsed = IsKeyIdUsed(keyId);
+ if (keyUsed && !overwrite) {
+ CIPHER_LOG_E("KeyId 0x%04X already used and overwrite not allowed\n", keyId);
+ return -1;
+ }
+
+ // 保存密钥到NV
+ ret = uapi_nv_write_with_attr(keyId, keyBuff, keyBuffLen, &nvAttr, NULL);
+ if (ret != 0) {
+ CIPHER_LOG_E("Failed to write key 0x%04X to nv, ret=%d\n", keyId, ret);
+ return ret;
+ }
+
+ // 如果之前未使用,标记为已使用并保存位图
+ if (!keyUsed) {
+ SetKeyIdUsed(keyId);
+ ret = SaveKeyIdBitmap();
+ if (ret != 0) {
+ CIPHER_LOG_E("Failed to save key_id bitmap after writing key 0x%04X\n", keyId);
+ } else {
+ CIPHER_LOG_D("Key 0x%04X saved successfully (new)\n", keyId);
+ }
+ } else {
+ CIPHER_LOG_I("Key 0x%04X saved successfully (overwritten)\n", keyId);
+ }
+
+ return ret;
+}
+
+/**
+ * @brief 从NV读取密钥
+ * @param keyId 密钥ID
+ * @param data 输出缓冲区
+ * @return 0-成功,其他-失败
+ */
+int32_t InnerGetKeyFromNv(uint16_t keyId, uint8_t *data, uint16_t *actualKeyLen)
+{
+ int32_t ret = 0;
+ uint16_t keyLen = 0;
+
+ // 初始化位图(如果未初始化)
+ if (!bitmapInitialized) {
+ ret = InitKeyIdBitmap();
+ if (ret != 0) {
+ CIPHER_LOG_E("Failed to initialize key_id bitmap\n");
+ return ret;
+ }
+ }
+
+ // 检查keyId是否有效
+ if (!IsValidKeyId(keyId)) {
+ CIPHER_LOG_E("Invalid keyId: 0x%04X\n", keyId);
+ return -1;
+ }
+
+ // 检查keyId是否已被使用
+ if (!IsKeyIdUsed(keyId)) {
+ CIPHER_LOG_E("KeyId 0x%04X not exists\n", keyId);
+ return -1;
+ }
+
+ // 检查输出缓冲区
+ if (data == NULL || actualKeyLen == NULL) {
+ CIPHER_LOG_E("Invalid output buffer\n");
+ return -1;
+ }
+
+ // 从NV读取密钥
+ ret = uapi_nv_read_with_attr(keyId, UT_NV_MAX_LENGTH, &keyLen, data, &nvAttr);
+ if (ret != 0) {
+ CIPHER_LOG_E("Failed to read key 0x%04X from nv, ret=%d\n", keyId, ret);
+
+ // 如果读取失败,可能密钥数据已损坏,清除使用标记
+ ClearKeyIdUsed(keyId);
+ SaveKeyIdBitmap(); // 尝试保存更新后的位图
+ } else {
+ CIPHER_LOG_I("Key 0x%04X read successfully, length=%d\n", keyId, keyLen);
+ *actualKeyLen = keyLen; // 设置实际长度
+ }
+
+ return ret;
+}
+
+/**
+ * @brief 从NV删除密钥
+ * @param keyId 密钥ID
+ * @return 0-成功,其他-失败
+ */
+int32_t InnerDeleteKeyFromNv(uint16_t keyId)
+{
+ int32_t ret = 0;
+ uint16_t keyLen = 0;
+ // 初始化位图(如果未初始化)
+ if (!bitmapInitialized) {
+ ret = InitKeyIdBitmap();
+ if (ret != 0) {
+ CIPHER_LOG_E("Failed to initialize key_id bitmap\n");
+ return ret;
+ }
+ }
+
+ // 检查keyId是否有效
+ if (!IsValidKeyId(keyId)) {
+ CIPHER_LOG_E("Invalid keyId: 0x%04X\n", keyId);
+ return -1;
+ }
+
+ // 检查keyId是否已被使用
+ if (!IsKeyIdUsed(keyId)) {
+ CIPHER_LOG_E("KeyId 0x%04X not exists\n", keyId);
+ return -1;
+ }
+ uint8_t *tempBuffer = (uint8_t*)APPV_MALLOC(UT_NV_MAX_LENGTH);
+ if (tempBuffer == NULL) {
+ CIPHER_LOG_E("Failed to allocate memory for temp deletion data\n");
+ return -1;
+ }
+ ret = uapi_nv_read_with_attr(keyId, UT_NV_MAX_LENGTH, &keyLen, tempBuffer, &nvAttr);
+ if (ret != 0) {
+ APPV_FREE(tempBuffer);
+ tempBuffer = NULL;
+ CIPHER_LOG_E("Failed to read key length for deletion 0x%04X, ret=%X\n", keyId, ret);
+ return -1;
+ }
+ APPV_FREE(tempBuffer);
+ tempBuffer = NULL;
+ uint8_t *zeroData = (uint8_t*)APPV_MALLOC(keyLen);
+ if (zeroData == NULL) {
+ CIPHER_LOG_E("Failed to allocate memory for deletion data\n");
+ return -1;
+ }
+
+ // 用0xf填充数据
+ memset_s(zeroData, keyLen, 0xFF, keyLen);
+ // 删除密钥:覆盖原始数据
+ ret = uapi_nv_write_with_attr(keyId, zeroData, keyLen, &nvAttr, NULL);
+ if (ret != 0) {
+ APPV_FREE(zeroData);
+ zeroData = NULL;
+ CIPHER_LOG_E("Failed to delete key 0x%04X from nv, ret=%d\n", keyId, ret);
+ return ret;
+ }
+ APPV_FREE(zeroData);
+ zeroData = NULL;
+ // 清除使用标记并保存位图
+ ClearKeyIdUsed(keyId);
+ ret = SaveKeyIdBitmap();
+ if (ret != 0) {
+ CIPHER_LOG_E("Failed to save key_id bitmap after deleting key 0x%04X\n", keyId);
+ } else {
+ CIPHER_LOG_I("Key 0x%04X deleted successfully\n", keyId);
+ }
+
+ return ret;
+}
+
+/**
+ * @brief 获取可用的密钥ID列表
+ * @param availableIds 输出可用ID数组
+ * @param maxCount 数组最大容量
+ * @return 可用ID数量
+ */
+uint16_t InnerGetAvailableKeyIds(uint16_t *availableIds, uint16_t maxCount)
+{
+ // 初始化密钥ID位图
+ uint16_t count = 0;
+
+ // 检查位图是否已初始化,若未初始化则进行初始化
+ if (!bitmapInitialized) {
+ if (InitKeyIdBitmap() != 0) {
+ return 0;
+ }
+ }
+
+ // 检查输入参数是否有效
+ if (availableIds == NULL || maxCount == 0) {
+ return 0;
+ }
+
+ // 遍历所有密钥ID,查找可用的密钥ID
+ for (uint16_t i = 0; i < KEY_ID_COUNT && count < maxCount; i++) {
+ // 检查当前密钥ID是否可用,8:一个字节8位
+ if (!(keyIdBitmap[i / 8] & (1 << (i % 8)))) {
+ // 将可用的密钥ID存入数组,并增加计数
+ availableIds[count++] = KEY_ID_START + i;
+ }
+ }
+
+ // 返回实际获取的可用密钥ID的数量
+ return count;
+}
+
+/**
+ * @brief 获取已使用的密钥ID列表
+ * @param usedIds 输出已使用ID数组
+ * @param maxCount 数组最大容量
+ * @return 已使用ID数量
+ */
+uint16_t InnerGetUsedKeyIds(uint16_t *usedIds, uint16_t maxCount)
+{
+ // 初始化计数器
+ uint16_t count = 0;
+
+ // 如果位图未初始化,则尝试初始化
+ if (!bitmapInitialized) {
+ if (InitKeyIdBitmap() != 0) {
+ return 0;
+ }
+ }
+
+ // 检查参数有效性
+ if (usedIds == NULL || maxCount == 0) {
+ return 0;
+ }
+
+ // 遍历所有密钥ID,查找已使用的密钥ID
+ for (uint16_t i = 0; i < KEY_ID_COUNT && count < maxCount; i++) {
+ // 检查当前密钥ID是否已使用,8:一个字节8位
+ if (keyIdBitmap[i / 8] & (1 << (i % 8))) {
+ // 将已使用的密钥ID存入数组,并递增计数器
+ usedIds[count++] = KEY_ID_START + i;
+ }
+ }
+
+ // 返回实际获取的已使用密钥ID数量
+ return count;
+}
+// ohos end
\ No newline at end of file
${ROOT_DIR}/foundation/arkui/ace_engine_lite/interfaces/jsi
${ROOT_DIR}/foundation/arkui/ace_engine_lite/interfaces/base
${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/interfaces/base
+ ${ROOT_DIR}/open_source/openharmony/base/security/appverify/include
)
set(SOURCES
static JSIValue Sha256SubStarts(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
static JSIValue Sha256SubUpdate(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
static JSIValue Sha256SubFinish(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+
+ static JSIValue HmacSha256(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue HmacSha256Bytes(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue Md5FromString(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue Md5FromBytes(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue Base64Encode(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue Base64Decode(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue GetAvailableKeyIds(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue GetUsedKeyIds(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue DeleteKeyFromNv(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue GetKeyFromNv(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue SaveKeyToNv(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+
static void OnDestroy();
#endif
private:
- static constexpr uint8_t ERR_CODE = 200;
+ static const int HMAC_SHA256_LEN = 32; // SHA1²»°²È«£¬·ñÔò³¤¶ÈΪ20
+ static const int HMAC_SHA256_RESULT_LEN = 64;
+ static const int MD5_LEN = 16;
+ static const int MD5_RESULT_LEN = 32;
+
static void ResetStrBuf(char *strBuf);
static CipherAesMode GetMode(char *strTransformation);
static PaddingMode GetPaddingMode(char *strTransformation);
+ static constexpr uint8_t ERR_CODE = 200;
};
void InitCipherModule(JSIValue exports);
// OHOS BEGIN
#include <string>
#ifdef HUKS_LITEWEARABLE_SUPPORT_ENABLED
+#include "app_common.h"
#include "mbedtls/sha256.h"
+#include "mbedtls/base64.h"
#include "js_async_work.h"
#endif
const int8_t SHA256_LEN = 32;
const int8_t SHA256_RESULT_LEN = SHA256_LEN * 2;
const int32_t MAX_LEN = 16384;
+const int32_t MAX_TXT_LEN = 4096;
+const int32_t MAX_KEY_LEN = 64;
struct CipherMsgParams {
char *msgBody;
// OHOS END
namespace OHOS {
namespace ACELite {
+void CipherModule::ResetStrBuf(char *strBuf)
+{
+ if (strBuf == nullptr) {
+ return;
+ }
+
+ int ret = memset_s(strBuf, strlen(strBuf), 0, strlen(strBuf));
+ if (ret != EOK) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "memset failed.");
+ }
+}
+
+static int32_t CheckTxtLen(char *text)
+{
+ uint32_t textLen = strlen(text);
+ if (textLen == 0 || textLen > MAX_TXT_LEN) {
+ return ERROR_CODE_GENERAL;
+ }
+ return ERROR_SUCCESS;
+}
+
+static int32_t CheckKeyLen(char *key)
+{
+ uint32_t keyLen = strlen(key);
+ if (keyLen == 0 || keyLen > MAX_KEY_LEN * 2) {
+ return ERROR_CODE_GENERAL;
+ }
+ return ERROR_SUCCESS;
+}
+
JSIValue CipherModule::Rsa(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
{
JSIValue undefValue = JSI::CreateUndefined();
}
RELEASE:
+ JSI::ReleaseValueList(success, fail, context, ARGS_END);
JSI::ReleaseString(strText);
return undefValue;
}
HILOG_ERROR(HILOG_MODULE_ACE, "Sha256SubFinish send message error.");
CipherMsgToJS("Sha256SubFinish error", context, fail);
}
+ JSI::ReleaseValueList(success, fail, context, ARGS_END);
DestroySha256Context(&g_sha256Context);
return undefValue;
}
HILOG_ERROR(HILOG_MODULE_ACE, "args error , text is nullptr");
goto RELEASE;
}
+ if (strlen(strText) > MAX_LEN) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "args error , text size more than 16KB");
+ goto RELEASE;
+ }
if (!strcmp(strAction, "encrypt") && paddingMode == PADDING_NONE && strlen(strText) % AES_BLOCK_SIZE != 0) {
HILOG_ERROR(HILOG_MODULE_ACE, "args error , text is not valid");
goto RELEASE;
JSI::ReleaseString(strKey);
JSI::ReleaseString(strIv);
JSI::ReleaseString(strTransformation);
+#ifdef HUKS_LITEWEARABLE_SUPPORT_ENABLED
+ JSI::ReleaseValue(context);
+#endif
+ JSI::ReleaseValueList(success, fail, jsIvLen, code, data, result, ARGS_END);
DeinitAesCryptData(&aes);
return undefValue;
}
}
#endif
// OHOS END
-void CipherModule::ResetStrBuf(char *strBuf)
-{
- if (strBuf == nullptr) {
- return;
- }
-
- int ret = memset_s(strBuf, strlen(strBuf), 0, strlen(strBuf));
- if (ret != EOK) {
- HILOG_ERROR(HILOG_MODULE_ACE, "memset failed.");
- }
-}
CipherAesMode CipherModule::GetMode(char *strTransformation)
{
HILOG_ERROR(HILOG_MODULE_ACE, "More than Max Memory");
return -1;
}
- *destStr = static_cast<char *>(ace_malloc(length));
+ *destStr = static_cast<char *>(APPV_MALLOC(length));
if (*destStr == nullptr) {
HILOG_ERROR(HILOG_MODULE_ACE, "Failed to allocate memory for destination string");
return -1;
if (memset_s(*destStr, length, 0, length) != EOK) {
HILOG_ERROR(HILOG_MODULE_ACE, "Failed to set memory for destination string");
- ace_free(*destStr);
+ APPV_FREE(*destStr);
return -1;
}
if (memcpy_s(*destStr, length, srcStr, length) != EOK) {
HILOG_ERROR(HILOG_MODULE_ACE, "Failed to copy source string to destination string");
- ace_free(*destStr);
+ APPV_FREE(*destStr);
return -1;
}
return 0;
}
-static void ExecuteSendMsgToJS(void *data)
+// HMAC-SHA256实现
+JSIValue CipherModule::HmacSha256(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
{
- if (data == nullptr) {
- return;
+ int32_t ret = 0;
+ JSIValue undefValue = JSI::CreateUndefined();
+ if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256 args error.");
+ return undefValue;
}
- CipherMsgParams *params = static_cast<CipherMsgParams *>(data);
- char *msgBody = params->msgBody;
- OHOS::ACELite::JSIValue callback = params->callback;
- OHOS::ACELite::JSIValue context = params->context;
- delete params;
- params = nullptr;
+ JSIValue context = JSI::AcquireValue(thisVal);
+ JSIValue success = JSI::GetNamedProperty(args[0], "success");
+ JSIValue fail = JSI::GetNamedProperty(args[0], "fail");
- OHOS::ACELite::JSIValue dataInfo = OHOS::ACELite::JSI::CreateString(msgBody);
- OHOS::ACELite::JSIValue callbackArgv[OHOS::ACELite::ARGC_ONE] = {dataInfo};
- OHOS::ACELite::JSI::CallFunction(callback, context, callbackArgv, OHOS::ACELite::ARGC_ONE);
- OHOS::ACELite::JSI::ReleaseValue(dataInfo);
- ace_free(msgBody);
- return;
+ char *text = JSI::GetStringProperty(args[0], "text");
+ char *key = JSI::GetStringProperty(args[0], "key");
+ unsigned char hmacResult[HMAC_SHA256_LEN];
+ char result[HMAC_SHA256_RESULT_LEN + 1];
+ if (text == nullptr || key == nullptr) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256: text or key is null");
+ CipherMsgToJS("HmacSha256: text or key is null", context, fail);
+ goto RELEASE;
+ }
+ if (CheckTxtLen(text) != ERROR_SUCCESS || CheckKeyLen(key) != ERROR_SUCCESS) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256: the length of text or key is out of range.");
+ goto RELEASE;
+ }
+
+ ret = HmacSha256Compute(
+ reinterpret_cast<unsigned char*>(key), strlen(key),
+ reinterpret_cast<unsigned char*>(text), strlen(text),
+ hmacResult
+ );
+ if (ret != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256 compute error: %d", ret);
+ CipherMsgToJS("HmacSha256 compute error", context, fail);
+ goto RELEASE;
+ }
+ // 转换为十六进制字符串
+ for (int i = 0; i < HMAC_SHA256_LEN; i++) {
+ ret = sprintf_s(&result[i * 2], 3, "%02x", hmacResult[i]);
+ if (ret < 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256 sprintf_s error.");
+ CipherMsgToJS("HmacSha256 format error", context, fail);
+ goto RELEASE;
+ }
+ }
+ result[HMAC_SHA256_RESULT_LEN] = '\0';
+
+ ret = CipherMsgToJS(result, context, success);
+ if (ret != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256 send message error.");
+ CipherMsgToJS("HmacSha256 send message error", context, fail);
+ }
+
+RELEASE:
+ JSI::ReleaseValueList(success, fail, context, ARGS_END);
+ if (text != nullptr) {
+ JSI::ReleaseString(text);
+ }
+ if (key != nullptr) {
+ JSI::ReleaseString(key);
+ }
+ return undefValue;
+}
+
+JSIValue CipherModule::HmacSha256Bytes(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ int32_t ret = 0;
+ JSIValue result[1];
+ JSIValue undefValue = JSI::CreateUndefined();
+ if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256Bytes args error.");
+ return undefValue;
+ }
+
+ JSIValue context = JSI::AcquireValue(thisVal);
+ JSIValue success = JSI::GetNamedProperty(args[0], "success");
+ JSIValue fail = JSI::GetNamedProperty(args[0], "fail");
+ uint8_t *bufferPtr = nullptr;
+ JSIValue arrayBuffer = JSI::CreateUndefined();
+
+ char *text = JSI::GetStringProperty(args[0], "text");
+ char *key = JSI::GetStringProperty(args[0], "key");
+ unsigned char hmacResult[HMAC_SHA256_LEN];
+
+ if (text == nullptr || key == nullptr) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256Bytes: text or key is null");
+ CipherMsgToJS("HmacSha256Bytes: text or key is null", context, fail);
+ goto RELEASE;
+ }
+ if (CheckTxtLen(text) != ERROR_SUCCESS || CheckKeyLen(key) != ERROR_SUCCESS) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256Bytes: the length of text or key is out of range.");
+ goto RELEASE;
+ }
+
+ ret = HmacSha256Compute(
+ reinterpret_cast<unsigned char*>(key), strlen(key),
+ reinterpret_cast<unsigned char*>(text), strlen(text),
+ hmacResult
+ );
+ if (ret != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256Bytes compute error: %d", ret);
+ CipherMsgToJS("HmacSha256Bytes compute error", context, fail);
+ goto RELEASE;
+ }
+
+ // 创建 ArrayBuffer 并直接返回字节数组
+ arrayBuffer = JSI::CreateArrayBuffer(HMAC_SHA256_LEN, bufferPtr);
+ if (bufferPtr == nullptr) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256Bytes: CreateArrayBuffer failed");
+ CipherMsgToJS("HmacSha256Bytes: CreateArrayBuffer failed", context, fail);
+ JSI::ReleaseValue(arrayBuffer);
+ goto RELEASE;
+ }
+
+ // 拷贝数据到 ArrayBuffer
+ if (memcpy_s(bufferPtr, HMAC_SHA256_LEN, hmacResult, HMAC_SHA256_LEN) != EOK) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256Bytes: memcpy_s failed");
+ CipherMsgToJS("HmacSha256Bytes: memcpy_s failed", context, fail);
+ JSI::ReleaseValue(arrayBuffer);
+ goto RELEASE;
+ }
+
+ // 返回 ArrayBuffer
+ result[0] = arrayBuffer;
+ JSI::CallFunction(success, context, result, 1);
+ JSI::ReleaseValueList(arrayBuffer, ARGS_END);
+
+RELEASE:
+ JSI::ReleaseValueList(success, fail, context, ARGS_END);
+ if (text != nullptr) {
+ JSI::ReleaseString(text);
+ }
+ if (key != nullptr) {
+ JSI::ReleaseString(key);
+ }
+ return undefValue;
+}
+
+// Base64编码实现
+JSIValue CipherModule::Base64Encode(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ int32_t ret = 0;
+ JSIValue undefValue = JSI::CreateUndefined();
+ if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Base64Encode args error.");
+ return undefValue;
+ }
+
+ JSIValue context = JSI::AcquireValue(thisVal);
+ JSIValue success = JSI::GetNamedProperty(args[0], "success");
+ JSIValue fail = JSI::GetNamedProperty(args[0], "fail");
+ size_t inputLen = 0;
+ size_t outputLen = 0;
+ char *base64Result = nullptr;
+
+ char *text = JSI::GetStringProperty(args[0], "text");
+ if (text == nullptr) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Base64Encode: text is null");
+ CipherMsgToJS("Base64Encode: text is null", context, fail);
+ goto RELEASE;
+ }
+ if (CheckTxtLen(text) != ERROR_SUCCESS) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Base64Encode: the length of text is out of range.");
+ goto RELEASE;
+ }
+
+ inputLen = strlen(text);
+ mbedtls_base64_encode(nullptr, 0, &outputLen,
+ reinterpret_cast<const unsigned char*>(text), inputLen);
+
+ base64Result = static_cast<char*>(APPV_MALLOC(outputLen + 1));
+ if (base64Result == nullptr) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Base64Encode: malloc failed");
+ CipherMsgToJS("Base64Encode: memory allocation failed", context, fail);
+ goto RELEASE;
+ }
+
+ ret = Base64EncodeInternal(
+ reinterpret_cast<const unsigned char*>(text), inputLen,
+ base64Result, outputLen
+ );
+
+ if (ret != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Base64Encode error: %d", ret);
+ CipherMsgToJS("Base64Encode error", context, fail);
+ APPV_FREE(base64Result);
+ goto RELEASE;
+ }
+
+ base64Result[outputLen] = '\0';
+ ret = CipherMsgToJS(base64Result, context, success);
+ APPV_FREE(base64Result);
+
+ if (ret != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Base64Encode send message error.");
+ CipherMsgToJS("Base64Encode send message error", context, fail);
+ }
+
+RELEASE:
+ JSI::ReleaseValueList(success, fail, context, ARGS_END);
+ if (text != nullptr) {
+ JSI::ReleaseString(text);
+ }
+ return undefValue;
+}
+
+// Base64解码实现
+JSIValue CipherModule::Base64Decode(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ int32_t ret = 0;
+ JSIValue undefValue = JSI::CreateUndefined();
+ if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Base64Decode args error.");
+ return undefValue;
+ }
+
+ JSIValue context = JSI::AcquireValue(thisVal);
+ JSIValue success = JSI::GetNamedProperty(args[0], "success");
+ JSIValue fail = JSI::GetNamedProperty(args[0], "fail");
+ size_t inputLen = 0;
+ size_t outputLen = 0;
+ unsigned char *decodedResult = nullptr;
+ char *resultStr = nullptr;
+
+ char *base64Text = JSI::GetStringProperty(args[0], "text");
+ if (base64Text == nullptr) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Base64Decode: text is null");
+ CipherMsgToJS("Base64Decode: text is null", context, fail);
+ goto RELEASE;
+ }
+ if (CheckTxtLen(base64Text) != ERROR_SUCCESS) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Base64Decode: the length of text is out of range.");
+ goto RELEASE;
+ }
+
+ inputLen = strlen(base64Text);
+ mbedtls_base64_decode(nullptr, 0, &outputLen,
+ reinterpret_cast<const unsigned char*>(base64Text), inputLen);
+
+ decodedResult = static_cast<unsigned char*>(APPV_MALLOC(outputLen + 1));
+ if (decodedResult == nullptr) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Base64Decode: malloc failed");
+ CipherMsgToJS("Base64Decode: memory allocation failed", context, fail);
+ goto RELEASE;
+ }
+
+ ret = Base64DecodeInternal(base64Text, inputLen, decodedResult, outputLen);
+ if (ret != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Base64Decode error: %d", ret);
+ CipherMsgToJS("Base64Decode error", context, fail);
+ APPV_FREE(decodedResult);
+ goto RELEASE;
+ }
+
+ decodedResult[outputLen] = '\0';
+ resultStr = reinterpret_cast<char*>(decodedResult);
+ ret = CipherMsgToJS(resultStr, context, success);
+ APPV_FREE(decodedResult);
+ if (ret != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Base64Decode send message error.");
+ CipherMsgToJS("Base64Decode send message error", context, fail);
+ }
+
+RELEASE:
+ JSI::ReleaseValueList(success, fail, context, ARGS_END);
+ if (base64Text != nullptr) {
+ JSI::ReleaseString(base64Text);
+ }
+ return undefValue;
+}
+
+// MD5实现
+JSIValue CipherModule::Md5FromString(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ int32_t ret = 0;
+ JSIValue undefValue = JSI::CreateUndefined();
+ if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Md5 args error.");
+ return undefValue;
+ }
+
+ JSIValue context = JSI::AcquireValue(thisVal);
+ JSIValue success = JSI::GetNamedProperty(args[0], "success");
+ JSIValue fail = JSI::GetNamedProperty(args[0], "fail");
+ unsigned char md5Result[MD5_LEN];
+ char result[MD5_RESULT_LEN + 1];
+
+ char *text = JSI::GetStringProperty(args[0], "text");
+ if (text == nullptr) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Md5: text is null");
+ CipherMsgToJS("Md5: text is null", context, fail);
+ goto RELEASE;
+ }
+ if (CheckTxtLen(text) != ERROR_SUCCESS) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Md5: the length of text is out of range.");
+ goto RELEASE;
+ }
+
+ ret = Md5Compute(reinterpret_cast<unsigned char*>(text), strlen(text), md5Result);
+ if (ret != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Md5 compute error: %d", ret);
+ CipherMsgToJS("Md5 compute error", context, fail);
+ goto RELEASE;
+ }
+
+ // 转换为十六进制字符串
+ for (int i = 0; i < MD5_LEN; i++) {
+ ret = sprintf_s(&result[i * 2], 3, "%02x", md5Result[i]);
+ if (ret < 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Md5 sprintf_s error.");
+ CipherMsgToJS("Md5 format error", context, fail);
+ goto RELEASE;
+ }
+ }
+ result[MD5_RESULT_LEN] = '\0';
+
+ ret = CipherMsgToJS(result, context, success);
+ if (ret != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Md5 send message error.");
+ CipherMsgToJS("Md5 send message error", context, fail);
+ }
+
+RELEASE:
+ JSI::ReleaseValueList(success, fail, context, ARGS_END);
+ if (text != nullptr) {
+ JSI::ReleaseString(text);
+ }
+ return undefValue;
+}
+
+JSIValue CipherModule::Md5FromBytes(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ int32_t ret = 0;
+ JSIValue undefValue = JSI::CreateUndefined();
+ JSIValue context = JSI::CreateUndefined();
+ JSIValue success = JSI::CreateUndefined();
+ JSIValue fail = JSI::CreateUndefined();
+ JSIValue dataBuffer = JSI::CreateUndefined();
+ size_t dataLen = 0;
+ unsigned char md5Result[MD5_LEN];
+ uint8_t* byteData = nullptr;
+ char result[MD5_LEN * 2 + 1];
+ bool conversionSuccess = true;
+
+ if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Md5FromBytes args error.");
+ goto RELEASE;
+ }
+
+ context = JSI::AcquireValue(thisVal);
+ success = JSI::GetNamedProperty(args[0], "success");
+ fail = JSI::GetNamedProperty(args[0], "fail");
+
+ // 获取 ArrayBuffer 参数
+ dataBuffer = JSI::GetNamedProperty(args[0], "data");
+ if (JSI::ValueIsUndefined(dataBuffer)) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Md5FromBytes: data is undefined");
+ CipherMsgToJS("Md5FromBytes: data is undefined", context, fail);
+ goto RELEASE;
+ }
+
+ // 从 ArrayBuffer 获取数据指针和长度
+ byteData = JSI::GetArrayBufferInfo(dataBuffer, dataLen);
+ if (byteData == nullptr || dataLen == 0 || dataLen > MAX_KEY_LEN) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Md5FromBytes: invalid array buffer");
+ CipherMsgToJS("Md5FromBytes: invalid array buffer", context, fail);
+ goto RELEASE;
+ }
+
+ ret = Md5Compute(byteData, dataLen, md5Result);
+ if (ret != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Md5FromBytes compute error: %d", ret);
+ CipherMsgToJS("Md5FromBytes compute error", context, fail);
+ goto RELEASE;
+ }
+
+ // 转换为十六进制字符串 - 添加安全检查
+ for (int i = 0; i < MD5_LEN; i++) {
+ // 检查缓冲区边界
+ if (i * 2 + 2 > MD5_LEN * 2) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Md5FromBytes: buffer overflow detected");
+ conversionSuccess = false;
+ break;
+ }
+
+ // 使用 sprintf_s 并检查返回值
+ int written = sprintf_s(&result[i * 2], 3, "%02x", md5Result[i]);
+ if (written != 2) { // 期望写入2个字符
+ HILOG_ERROR(HILOG_MODULE_ACE, "Md5FromBytes: sprintf_s failed at position %d, written=%d", i, written);
+ conversionSuccess = false;
+ break;
+ }
+ }
+
+ if (!conversionSuccess) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Md5FromBytes: hex conversion failed");
+ CipherMsgToJS("Md5FromBytes: hex conversion failed", context, fail);
+ goto RELEASE;
+ }
+
+ result[MD5_LEN * 2] = '\0';
+
+ ret = CipherMsgToJS(result, context, success);
+ if (ret != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Md5FromBytes send message error.");
+ CipherMsgToJS("Md5FromBytes send message error", context, fail);
+ }
+
+RELEASE:
+ JSI::ReleaseValueList(success, fail, context, dataBuffer, ARGS_END);
+ return undefValue;
+}
+
+// 最大密钥ID数量
+#define MAX_KEY_IDS_COUNT 100
+
+// 将密钥内容字节数组转换为十六进制字符串
+static char* BytesToHexString(const uint8_t *bytes, uint32_t len)
+{
+ if (bytes == NULL || len == 0) {
+ return NULL;
+ }
+
+ char *hexStr = (char*)APPV_MALLOC(len * 2 + 1);
+ if (hexStr == NULL) {
+ return NULL;
+ }
+
+ for (uint32_t i = 0; i < len; i++) {
+ int written = snprintf_s(&hexStr[i * 2], 3, 2, "%02x", bytes[i]);
+ if (written < 0 || written >= 3) {
+ APPV_FREE(hexStr);
+ return NULL;
+ }
+ }
+ hexStr[len * 2] = '\0';
+
+ return hexStr;
+}
+
+// 将密钥ID数组转换为十六进制字符串
+static char* KeyIdsToHexString(uint16_t *keyIds, uint16_t count)
+{
+ if (keyIds == NULL || count == 0) {
+ return NULL;
+ }
+
+ // 每个keyId占4个十六进制字符,加上分隔符和结束符
+ char *hexStr = (char*)APPV_MALLOC(count * 5); // 5: 4字符 + 1分隔符
+ if (hexStr == NULL) {
+ return NULL;
+ }
+
+ int offset = 0;
+ for (uint16_t i = 0; i < count; i++) {
+ // 5: 4字符 + 1分隔符
+ int written = snprintf_s(hexStr + offset, 5, 4, "%04X", keyIds[i]);
+ if (written < 0 || written >= 5) {
+ APPV_FREE(hexStr);
+ return NULL;
+ }
+ offset += written;
+
+ // 添加分隔符(最后一个不添加)
+ if (i < count - 1) {
+ hexStr[offset] = ',';
+ offset++;
+ }
+ }
+ hexStr[offset] = '\0';
+
+ return hexStr;
+}
+
+// 将十六进制字符串转换为字节数组
+static int HexStringToBytes(const char *hexStr, uint8_t *bytes, uint32_t maxLen)
+{
+ if (hexStr == NULL || bytes == NULL) {
+ return -1;
+ }
+
+ size_t hexLen = strlen(hexStr);
+ if (hexLen % 2 != 0 || hexLen / 2 > maxLen) {
+ return -1;
+ }
+
+ for (size_t i = 0; i < hexLen; i += 2) {
+ char hexByte[3] = {hexStr[i], hexStr[i + 1], '\0'};
+ bytes[i / 2] = (uint8_t)strtol(hexByte, NULL, 16);
+ }
+
+ return hexLen / 2;
+}
+
+/**
+ * @brief 获取已使用的密钥ID列表
+ */
+JSIValue CipherModule::GetUsedKeyIds(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ // 提前声明所有变量
+ JSIValue undefValue = JSI::CreateUndefined();
+ JSIValue context = JSI::CreateUndefined();
+ JSIValue success = JSI::CreateUndefined();
+ JSIValue fail = JSI::CreateUndefined();
+ JSIValue countValue = JSI::CreateUndefined();
+ uint16_t maxCount = MAX_KEY_IDS_COUNT;
+ uint16_t *usedIds = NULL;
+ uint16_t actualCount = 0;
+ char *hexString = NULL;
+
+ if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "GetUsedKeyIdsJSI args error.");
+ goto release;
+ }
+
+ context = JSI::AcquireValue(thisVal);
+ success = JSI::GetNamedProperty(args[0], "success");
+ fail = JSI::GetNamedProperty(args[0], "fail");
+
+ // 获取count参数,默认为MAX_KEY_IDS_COUNT
+ countValue = JSI::GetNamedProperty(args[0], "count");
+ if (!JSI::ValueIsUndefined(countValue)) {
+ maxCount = (uint16_t)JSI::ValueToNumber(countValue);
+ if (maxCount > MAX_KEY_IDS_COUNT) {
+ maxCount = MAX_KEY_IDS_COUNT;
+ }
+ }
+
+ usedIds = (uint16_t*)APPV_MALLOC(maxCount * sizeof(uint16_t));
+ if (usedIds == NULL) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "GetUsedKeyIds: memory allocation failed");
+ CipherMsgToJS("Memory allocation failed", context, fail);
+ goto release;
+ }
+
+ actualCount = InnerGetUsedKeyIds(usedIds, maxCount);
+
+ if (actualCount == 0) {
+ HILOG_INFO(HILOG_MODULE_ACE, "No used key IDs found");
+ CipherMsgToJS("", context, success);
+ goto release;
+ }
+
+ // 将密钥ID数组转换为十六进制字符串
+ hexString = KeyIdsToHexString(usedIds, actualCount);
+ if (hexString != NULL) {
+ CipherMsgToJS(hexString, context, success);
+ } else {
+ HILOG_ERROR(HILOG_MODULE_ACE, "GetUsedKeyIds: hex string conversion failed");
+ CipherMsgToJS("Data conversion failed", context, fail);
+ }
+
+release:
+ // 释放所有分配的内存
+ APPV_FREE(usedIds);
+ APPV_FREE(hexString);
+ JSI::ReleaseValueList(countValue, success, fail, context, ARGS_END);
+ return undefValue;
+}
+
+/**
+ * @brief 获取可用的密钥ID列表
+ */
+JSIValue CipherModule::GetAvailableKeyIds(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ // 提前声明所有变量
+ JSIValue undefValue = JSI::CreateUndefined();
+ JSIValue context = JSI::CreateUndefined();
+ JSIValue success = JSI::CreateUndefined();
+ JSIValue fail = JSI::CreateUndefined();
+ JSIValue countValue = JSI::CreateUndefined();
+ uint16_t maxCount = MAX_KEY_IDS_COUNT;
+ uint16_t *availableIds = NULL;
+ uint16_t actualCount = 0;
+ char *hexString = NULL;
+
+ if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "GetAvailableKeyIdsJSI args error.");
+ goto release;
+ }
+
+ context = JSI::AcquireValue(thisVal);
+ success = JSI::GetNamedProperty(args[0], "success");
+ fail = JSI::GetNamedProperty(args[0], "fail");
+
+ // 获取count参数,默认为MAX_KEY_IDS_COUNT
+ countValue = JSI::GetNamedProperty(args[0], "count");
+ if (!JSI::ValueIsUndefined(countValue)) {
+ maxCount = (uint16_t)JSI::ValueToNumber(countValue);
+ if (maxCount > MAX_KEY_IDS_COUNT) {
+ maxCount = MAX_KEY_IDS_COUNT;
+ }
+ }
+
+ availableIds = (uint16_t*)APPV_MALLOC(maxCount * sizeof(uint16_t));
+ if (availableIds == NULL) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "GetAvailableKeyIds: memory allocation failed");
+ CipherMsgToJS("Memory allocation failed", context, fail);
+ goto release;
+ }
+
+ actualCount = InnerGetAvailableKeyIds(availableIds, maxCount);
+ if (actualCount == 0) {
+ HILOG_INFO(HILOG_MODULE_ACE, "No available key IDs found");
+ CipherMsgToJS("", context, success);
+ goto release;
+ }
+
+ // 将密钥ID数组转换为十六进制字符串
+ hexString = KeyIdsToHexString(availableIds, actualCount);
+ if (hexString != NULL) {
+ CipherMsgToJS(hexString, context, success);
+ } else {
+ HILOG_ERROR(HILOG_MODULE_ACE, "GetAvailableKeyIds: hex string conversion failed");
+ CipherMsgToJS("Data conversion failed", context, fail);
+ }
+
+release:
+ // 释放所有分配的内存
+ APPV_FREE(availableIds);
+ APPV_FREE(hexString);
+ JSI::ReleaseValueList(countValue, success, fail, context, ARGS_END);
+ return undefValue;
+}
+
+/**
+ * @brief 删除密钥
+ */
+JSIValue CipherModule::DeleteKeyFromNv(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ // 提前声明所有变量
+ JSIValue undefValue = JSI::CreateUndefined();
+ JSIValue context = JSI::CreateUndefined();
+ JSIValue success = JSI::CreateUndefined();
+ JSIValue fail = JSI::CreateUndefined();
+ JSIValue keyIdValue = JSI::CreateUndefined();
+ uint16_t keyId = 0;
+ int32_t ret = 0;
+
+ if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "DeleteKeyFromNvJSI args error.");
+ goto release;
+ }
+
+ context = JSI::AcquireValue(thisVal);
+ success = JSI::GetNamedProperty(args[0], "success");
+ fail = JSI::GetNamedProperty(args[0], "fail");
+
+ // 获取keyId参数
+ keyIdValue = JSI::GetNamedProperty(args[0], "keyId");
+ if (JSI::ValueIsUndefined(keyIdValue)) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "DeleteKeyFromNvJSI: keyId is required");
+ CipherMsgToJS("keyId is required", context, fail);
+ goto release;
+ }
+
+ keyId = (uint16_t)JSI::ValueToNumber(keyIdValue);
+
+ ret = InnerDeleteKeyFromNv(keyId);
+ if (ret != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "DeleteKeyFromNv failed: %d", ret);
+ CipherMsgToJS("Key deleted failed", context, fail);
+ } else {
+ CipherMsgToJS("Key deleted successfully", context, success);
+ }
+
+release:
+ JSI::ReleaseValueList(keyIdValue, success, fail, context, ARGS_END);
+ return undefValue;
+}
+
+/**
+ * @brief 读取密钥
+ */
+JSIValue CipherModule::GetKeyFromNv(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum) {
+ // 提前声明所有变量
+ JSIValue undefValue = JSI::CreateUndefined();
+ JSIValue context = JSI::CreateUndefined();
+ JSIValue success = JSI::CreateUndefined();
+ JSIValue fail = JSI::CreateUndefined();
+ JSIValue keyIdValue = JSI::CreateUndefined();
+ uint16_t keyId = 0;
+ uint8_t *keyData = NULL;
+ int32_t ret = 0;
+ char *hexKey = NULL;
+ uint16_t actualKeyLen = 0; // 新增:实际密钥长度
+
+ if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "GetKeyFromNvJSI args error.");
+ goto release;
+ }
+
+ context = JSI::AcquireValue(thisVal);
+ success = JSI::GetNamedProperty(args[0], "success");
+ fail = JSI::GetNamedProperty(args[0], "fail");
+
+ // 获取keyId参数
+ keyIdValue = JSI::GetNamedProperty(args[0], "keyId");
+ if (JSI::ValueIsUndefined(keyIdValue)) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "GetKeyFromNvJSI: keyId is required");
+ CipherMsgToJS("keyId is required", context, fail);
+ goto release;
+ }
+
+ keyId = (uint16_t)JSI::ValueToNumber(keyIdValue);
+
+ keyData = (uint8_t*)APPV_MALLOC(UT_NV_MAX_LENGTH);
+ if (keyData == NULL) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "GetKeyFromNv: memory allocation failed");
+ CipherMsgToJS("Memory allocation failed", context, fail);
+ goto release;
+ }
+
+ // 修改:调用支持实际长度的InnerGetKeyFromNv
+ ret = InnerGetKeyFromNv(keyId, keyData, &actualKeyLen);
+ if (ret != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "GetKeyFromNv failed: %d", ret);
+ CipherMsgToJS("Get key failed!", context, fail);
+ } else {
+ // 修改:使用实际长度转换十六进制字符串
+ hexKey = BytesToHexString(keyData, actualKeyLen);
+ if (hexKey != NULL) {
+ CipherMsgToJS(hexKey, context, success);
+ } else {
+ CipherMsgToJS("Key data format conversion failed", context, fail);
+ }
+ }
+
+release:
+ // 释放所有分配的内存
+ APPV_FREE(keyData);
+ APPV_FREE(hexKey);
+ JSI::ReleaseValueList(keyIdValue, success, fail, context, ARGS_END);
+ return undefValue;
+}
+
+/**
+ * @brief 保存密钥
+ */
+/**
+ * @brief 保存密钥 - 优化内存使用
+ */
+JSIValue CipherModule::SaveKeyToNv(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum) {
+ // 提前声明所有变量
+ int32_t ret = 0;
+ uint8_t *keyData = NULL;
+ uint16_t keyId = 0;
+ bool overwrite = false;
+ int keyLen = 0;
+ char *keyDataHex = NULL;
+ size_t hexLen = 0;
+ size_t actualDataLen = 0;
+
+ JSIValue undefValue = JSI::CreateUndefined();
+ JSIValue context = JSI::CreateUndefined();
+ JSIValue success = JSI::CreateUndefined();
+ JSIValue fail = JSI::CreateUndefined();
+ JSIValue keyIdValue = JSI::CreateUndefined();
+ JSIValue keyDataValue = JSI::CreateUndefined();
+ JSIValue overwriteValue = JSI::CreateUndefined();
+
+ if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "SaveKeyToNvJSI args error.");
+ goto release;
+ }
+
+ context = JSI::AcquireValue(thisVal);
+ success = JSI::GetNamedProperty(args[0], "success");
+ fail = JSI::GetNamedProperty(args[0], "fail");
+
+ // 获取必需参数
+ keyIdValue = JSI::GetNamedProperty(args[0], "keyId");
+ keyDataValue = JSI::GetNamedProperty(args[0], "keyData");
+ overwriteValue = JSI::GetNamedProperty(args[0], "overwrite");
+
+ if (JSI::ValueIsUndefined(keyIdValue) || JSI::ValueIsUndefined(keyDataValue)) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "SaveKeyToNvJSI: keyId and keyData are required");
+ CipherMsgToJS("keyId and keyData are required", context, fail);
+ goto release;
+ }
+
+ keyId = (uint16_t)JSI::ValueToNumber(keyIdValue);
+ overwrite = JSI::ValueToBoolean(overwriteValue);
+
+ // 获取密钥数据字符串
+ keyDataHex = JSI::GetStringProperty(args[0], "keyData");
+ if (keyDataHex == NULL) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "SaveKeyToNvJSI: keyData is null");
+ CipherMsgToJS("keyData is null", context, fail);
+ goto release;
+ }
+
+ // 计算实际需要的缓冲区大小
+ hexLen = strlen(keyDataHex);
+ if (hexLen % 2 != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "SaveKeyToNvJSI: keyData format error (odd length)");
+ CipherMsgToJS("keyData format error (must be even length hex string)", context, fail);
+ JSI::ReleaseString(keyDataHex);
+ goto release;
+ }
+
+ actualDataLen = hexLen / 2;
+ if (actualDataLen > UT_NV_MAX_LENGTH) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "SaveKeyToNvJSI: keyData too long");
+ CipherMsgToJS("keyData too long", context, fail);
+ JSI::ReleaseString(keyDataHex);
+ goto release;
+ }
+
+ // 修改:按实际长度分配内存
+ keyData = (uint8_t*)APPV_MALLOC(actualDataLen);
+ if (keyData == NULL) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "SaveKeyToNv: memory allocation failed");
+ CipherMsgToJS("Memory allocation failed", context, fail);
+ JSI::ReleaseString(keyDataHex);
+ goto release;
+ }
+
+ // 将十六进制字符串转换为字节数组
+ keyLen = HexStringToBytes(keyDataHex, keyData, actualDataLen);
+ if (keyLen <= 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "SaveKeyToNvJSI: keyData format error");
+ CipherMsgToJS("keyData format error (must be hex string)", context, fail);
+ JSI::ReleaseString(keyDataHex);
+ goto release;
+ }
+
+ ret = InnerSaveKeyToNv(keyData, keyLen, keyId, overwrite);
+ if (ret != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "SaveKeyToNv failed: %d", ret);
+ CipherMsgToJS("Save key failed!", context, fail);
+ } else {
+ CipherMsgToJS("Key saved successfully", context, success);
+ }
+
+ JSI::ReleaseString(keyDataHex);
+
+release:
+ // 释放所有分配的内存
+ APPV_FREE(keyData);
+ JSI::ReleaseValueList(keyIdValue, keyDataValue, overwriteValue, success, fail, context, ARGS_END);
+ return undefValue;
}
#endif
// OHOS END
JSI::SetModuleAPI(exports, "shaInit", CipherModule::Sha256SubStarts);
JSI::SetModuleAPI(exports, "shaUpdate", CipherModule::Sha256SubUpdate);
JSI::SetModuleAPI(exports, "shaFinal", CipherModule::Sha256SubFinish);
+
+ JSI::SetModuleAPI(exports, "hmacSha256", CipherModule::HmacSha256);
+ JSI::SetModuleAPI(exports, "hmacSha256Bytes", CipherModule::HmacSha256Bytes);
+ JSI::SetModuleAPI(exports, "md5FromBytes", CipherModule::Md5FromBytes);
+ JSI::SetModuleAPI(exports, "md5FromString", CipherModule::Md5FromString);
+ JSI::SetModuleAPI(exports, "base64Encode", CipherModule::Base64Encode);
+ JSI::SetModuleAPI(exports, "base64Decode", CipherModule::Base64Decode);
+ JSI::SetModuleAPI(exports, "getUsedKeyIds", CipherModule::GetUsedKeyIds);
+ JSI::SetModuleAPI(exports, "getAvailableKeyIds", CipherModule::GetAvailableKeyIds);
+ JSI::SetModuleAPI(exports, "deleteKeyFromNv", CipherModule::DeleteKeyFromNv);
+ JSI::SetModuleAPI(exports, "getKeyFromNv", CipherModule::GetKeyFromNv);
+ JSI::SetModuleAPI(exports, "saveKeyToNv", CipherModule::SaveKeyToNv);
+
JSI::SetOnDestroy(exports, CipherModule::OnDestroy);
#endif
}
} // namespace OHOS
// OHOS START
#ifdef HUKS_LITEWEARABLE_SUPPORT_ENABLED
+static void ExecuteSendMsgToJS(void *data)
+{
+ if (data == nullptr) {
+ return;
+ }
+ CipherMsgParams *params = static_cast<CipherMsgParams *>(data);
+
+ char *msgBody = params->msgBody;
+ OHOS::ACELite::JSIValue callback = params->callback;
+ OHOS::ACELite::JSIValue context = params->context;
+ params->msgBody = nullptr;
+ delete params;
+ params = nullptr;
+
+ OHOS::ACELite::JSIValue dataInfo = OHOS::ACELite::JSI::CreateString(msgBody);
+ OHOS::ACELite::JSIValue callbackArgv[OHOS::ACELite::ARGC_ONE] = {dataInfo};
+ OHOS::ACELite::JSI::CallFunction(callback, context, callbackArgv, OHOS::ACELite::ARGC_ONE);
+ OHOS::ACELite::JSI::ReleaseValue(dataInfo);
+ OHOS::ACELite::JSI::ReleaseValue(callback);
+ OHOS::ACELite::JSI::ReleaseValue(context);
+ OHOS::ACELite::ace_free(msgBody);
+ return;
+}
+
int32_t CipherMsgToJS(const char *msgBody, OHOS::ACELite::JSIValue context, OHOS::ACELite::JSIValue callback)
{
CipherMsgParams *params = new CipherMsgParams();
HILOG_ERROR(HILOG_MODULE_ACE, "Failed to allocate memory for params");
return -1;
}
- params->context = context;
- params->callback = callback;
+ params->context = OHOS::ACELite::JSI::AcquireValue(context);
+ params->callback = OHOS::ACELite::JSI::AcquireValue(callback);
int32_t copyRet = OHOS::ACELite::CopyStr(¶ms->msgBody, msgBody);
if (copyRet != 0) {
HILOG_ERROR(HILOG_MODULE_ACE, "Failed to copy msgBody");
+ OHOS::ACELite::JSI::ReleaseValue(params->callback);
+ OHOS::ACELite::JSI::ReleaseValue(params->context);
OHOS::ACELite::ace_free(params->msgBody);
params->msgBody = nullptr;
delete params;
return copyRet;
}
bool ret =
- OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(OHOS::ACELite::ExecuteSendMsgToJS, static_cast<void *>(params));
+ OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(ExecuteSendMsgToJS, static_cast<void *>(params));
if (!ret) {
HILOG_ERROR(HILOG_MODULE_ACE, "Failed to dispatch async work");
+ OHOS::ACELite::JSI::ReleaseValue(params->callback);
+ OHOS::ACELite::JSI::ReleaseValue(params->context);
OHOS::ACELite::ace_free(params->msgBody);
params->msgBody = nullptr;
delete params;
g_proxy = GetServiceProxy();\r
}\r
return SetOptionByProxy(g_proxy, sensorTypeId, user, option);\r
-}
\ No newline at end of file
+}\r
+// ohos-hisi begin\r
+int32_t GetSensorData(int32_t sensorTypeId, SensorUser *user, void *sensorData)\r
+{\r
+ if (g_proxy == NULL) {\r
+ g_proxy = GetServiceProxy();\r
+ }\r
+ return GetSensorDataByProxy(g_proxy, sensorTypeId, user, sensorData);\r
+}\r
+// ohos-hisi end
\ No newline at end of file
SensorFeatureApi *sensor = (SensorFeatureApi *)proxy;\r
return sensor->SetOption(sensorId, user, option);\r
}\r
+\r
+// ohos-hisi begin\r
+int32_t GetSensorDataByProxy(const void *proxy, int32_t sensorId, const SensorUser *user, void *sensorData)\r
+{\r
+ HILOG_DEBUG(HILOG_MODULE_APP, "%s begin", __func__);\r
+ if ((proxy == NULL) || (user == NULL)) {\r
+ HILOG_ERROR(HILOG_MODULE_APP, "%s proxy or user is NULL", __func__);\r
+ return SENSOR_ERROR_INVALID_PARAM;\r
+ }\r
+ SensorFeatureApi *sensor = (SensorFeatureApi *)proxy;\r
+ return sensor->GetData(sensorId, user, sensorData);\r
+}\r
+// ohos-hisi end
\ No newline at end of file
* @since 5\r
*/\r
int32_t SetMode(int32_t sensorTypeId, SensorUser *user, int32_t mode);\r
-\r
+// ohos-hisi begin\r
+/**\r
+* @brief Get the data of the specified sensor stored.\r
+*\r
+* @param sensorTypeId Indicates the ID of a sensor type. For details, see {@link SensorTypeId}.\r
+* @param user Indicates the pointer to the sensor subscriber that requests sensor data.\r
+* For details, see {@link SensorUser}. A subscriber can obtain data from only one sensor.\r
+* @param sensorData Indicates the data of sensor stored For details, see {@link SensorData}.\r
+* @return Returns <b>0</b> if get sensor data successfully; returns a non-zero value otherwise.\r
+*\r
+* @since 5\r
+*/\r
+int32_t GetSensorData(int32_t sensorTypeId, SensorUser *user, void *sensorData);\r
+// ohos-hisi end\r
#ifdef __cplusplus\r
#if __cplusplus\r
}\r
#define SENSOR_OK 0\r
#ifndef SENSOR_NAME_MAX_LEN\r
/** Maximum length of the sensor name */\r
-#define SENSOR_NAME_MAX_LEN 16\r
+#define SENSOR_NAME_MAX_LEN 32\r
#endif /* SENSOR_NAME_MAX_LEN */\r
\r
#ifndef SENSOR_USER_DATA_SIZE\r
SENSOR_TYPE_ID_DEVICE_ORIENTATION = 279, /**< Device orientation sensor */\r
SENSOR_TYPE_ID_WEAR_DETECTION = 280, /**< Wear detection sensor */\r
SENSOR_TYPE_ID_ACCELEROMETER_UNCALIBRATED = 281, /**< Uncalibrated acceleration sensor */\r
- SENSOR_TYPE_ID_MAX = 0xFFF, /**< Maximum number of sensor type IDs*/\r
+ // ohos-hisi begin\r
+ SENSOR_TYPE_ID_VSENSOR_EXPAND_START = 0x1000, /* 4096 */\r
+ SENSOR_TYPE_ID_VSENSOR_ACCELEROMETER_ALG_SIMU, /**< ACCELEROMETER ALG sensor */\r
+ SENSOR_TYPE_ID_MAX, /**< Maximum number of sensor types */\r
+ // ohos-hisi end\r
} SensorTypeId;\r
\r
/**\r
int32_t sensorTypeId; /**< Sensor type ID */\r
int32_t sensorId; /**< Sensor ID */\r
float maxRange; /**< Maximum measurement range of the sensor */\r
- float precision; /**< Sensor accuracy */\r
+ float accuracy; /**< Sensor accuracy */\r
float power; /**< Sensor power */\r
+ int64_t minDelay; /**< Minimum sample period allowed in microseconds */\r
+ int64_t maxDelay; /**< Maxmum sample period allowed in microseconds */\r
+ uint32_t fifoMaxEventCount; /**< Maxmum number of events of this sensor that could be batched */\r
+ uint32_t reserved; /**< Reserved fields */\r
} SensorInfo;\r
\r
/**\r
uint32_t dataValid;\r
} PressureData;\r
\r
+/**\r
+ * @brief Defines the sensor data.\r
+ *\r
+ * @since 5\r
+ */\r
+typedef struct SensorData {\r
+ int64_t timestamp; /**< Time when sensor data was reported */\r
+ uint32_t batchCnt; /**< Sensor batch cnt */\r
+ uint8_t *data; /**< Sensor data */\r
+ uint32_t dataLen; /**< Sensor data length */\r
+} SensorData;\r
+\r
#ifdef __cplusplus\r
#if __cplusplus\r
}\r
{
directionAccuracy_ = directionAccuracy;
}
+
+ inline double GetNorthVelocity() const
+ {
+ return velocityNorth_;
+ }
+
+ inline void SetNorthVelocity(double velocityNorth)
+ {
+ velocityNorth_ = velocityNorth;
+ }
+
+ inline double GetEastVelocity() const
+ {
+ return velocityEast_;
+ }
+
+ inline void SetEastVelocity(double velocityEast)
+ {
+ velocityEast_ = velocityEast;
+ }
+
+ inline double GetDescendVelocity() const
+ {
+ return velocityDescend_;
+ }
+
+ inline void SetDescendVelocity(double velocityDescend)
+ {
+ velocityDescend_ = velocityDescend;
+ }
inline int32_t GetLocationSourceType() const
{
locationSourceType_ = locationSourceType;
}
+ inline int32_t GetStatusNumber() const
+ {
+ return statusNumber_;
+ }
+
+ inline void SetStatusNumber(int32_t statusNumber)
+ {
+ statusNumber_ = statusNumber;
+ }
+
inline std::string GetUuid() const
{
return uuid_;
double altitudeAccuracy_;
double speedAccuracy_;
double directionAccuracy_;
+ float velocityNorth_;
+ float velocityEast_;
+ float velocityDescend_;
int64_t uncertaintyOfTimeSinceBoot_;
int32_t locationSourceType_;
+ int32_t statusNumber_;
std::string uuid_;
};
} // namespace Location
void OnLocationReport(const std::shared_ptr<Location> &location) override
{
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "OnLocationReport Lat:%.3f Long:%.3f Alt:%.3f Speed:%.3f dir:%.3f\n",
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "OnLocationReport Lat:%.3f Long:%.3f Alt:%.3f Speed:%.3f dir:%.3f"
+ " AltitudeAccuracy:%.3f SpeedAccuracy:%.3f DirectionAccuracy:%.3f Nvelocity:%.3f Evelocity:%.3f DVelocity:%.3f statusNumber:%d\n",
location->GetLatitude(), location->GetLongitude(), location->GetAltitude(),
- location->GetSpeed(), location->GetDirection());
+ location->GetSpeed(), location->GetDirection(), location->GetAltitudeAccuracy(), location->GetSpeedAccuracy(), location->GetDirectionAccuracy(),
+ location->GetNorthVelocity(), location->GetEastVelocity(), location->GetDescendVelocity(), location->GetStatusNumber());
}
void OnErrorReport(const int errorCode) override
locationNew->SetAltitudeAccuracy(location.verticalAccuracy);
locationNew->SetSpeedAccuracy(location.speedAccuracy);
locationNew->SetDirectionAccuracy(location.bearingAccuracy);
+ locationNew->SetNorthVelocity(location.velocityNorth);
+ locationNew->SetEastVelocity(location.velocityEast);
+ locationNew->SetDescendVelocity(location.velocityDescend);
locationNew->SetTimeStamp(location.timeForFix);
locationNew->SetTimeSinceBoot(location.timeSinceBoot);
locationNew->SetUncertaintyOfTimeSinceBoot(location.timeUncertainty);
+ locationNew->SetStatusNumber(location.signal);
locationNew->SetLocationSourceType(LocationSourceType::GNSS_TYPE);
// add dummy sv if needed
altitudeAccuracy_ = 0.0;
speedAccuracy_ = 0.0;
directionAccuracy_ = 0.0;
+ velocityNorth_ = 0.0;
+ velocityEast_ = 0.0;
+ velocityDescend_ = 0.0;
uncertaintyOfTimeSinceBoot_ = 0;
locationSourceType_ = 0;
+ statusNumber_ = 0;
uuid_ = "";
}
altitudeAccuracy_ = location.GetAltitudeAccuracy();
speedAccuracy_ = location.GetSpeedAccuracy();
directionAccuracy_ = location.GetDirectionAccuracy();
+ velocityNorth_ = location.GetNorthVelocity();
+ velocityEast_ = location.GetEastVelocity();
+ velocityDescend_ = location.GetDescendVelocity();
uncertaintyOfTimeSinceBoot_ = location.GetUncertaintyOfTimeSinceBoot();
locationSourceType_ = location.GetLocationSourceType();
+ statusNumber_ = location.GetStatusNumber();
uuid_ = location.GetUuid();
}
", altitudeAccuracy : " + std::to_string(altitudeAccuracy_) +
", speedAccuracy : " + std::to_string(speedAccuracy_) +
", directionAccuracy : " + std::to_string(directionAccuracy_) +
+ ", velocityEast : " + std::to_string(velocityEast_) +
+ ", velocityNorth_ : " + std::to_string(velocityNorth_) +
+ ", velocityDescend_ : " + std::to_string(velocityDescend_) +
", uncertaintyOfTimeSinceBoot : " + std::to_string(uncertaintyOfTimeSinceBoot_) +
", locationSourceType : " + std::to_string(locationSourceType_) +
+ ", statusNumber : " + std::to_string(statusNumber_) +
", uuid : " + uuid_;
return str;
}
static int32_t SensorActivate(SensorTypeId sensorTypeId);
static int32_t SensorUnsubscribe(SensorTypeId sensorTypeId);
static int32_t SensorDeactivate(SensorTypeId sensorTypeId);
+static int32_t SensorGetData(SensorTypeId sensorTypeId);
typedef struct {
char cmd[SENSOR_CMD_LEN_MAX];
{"activate", SensorActivate},
{"unsubscribe", SensorUnsubscribe},
{"deactivate", SensorDeactivate},
+ {"getdata", SensorGetData},
};
typedef struct {
return SENSOR_OK;
}
+static int32_t SensorGetData(SensorTypeId sensorTypeId)
+{
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "getData :%d\n", sensorTypeId);
+ SensorDev *sensorDev = GetSensorIdBySensorDevIndex(sensorTypeId);
+ if (sensorDev == NULL) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetSensorIdBySensorDevIndex failed\n");
+ return SENSOR_ERROR_UNKNOWN;
+ }
+ SensorData *sensorData = (SensorData *)malloc(sizeof(SensorData));
+ if (sensorData == NULL) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "malloc failed\n");
+ return SENSOR_ERROR_UNKNOWN;
+ }
+ int32_t errCode = GetSensorData(sensorTypeId, &sensorDev->user, sensorData);
+ if (errCode != SENSOR_OK) {
+ free(sensorData);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetSensorData failed:%d\n", errCode);
+ return errCode;
+ }
+ AccelData *accData = (AccelData *)sensorData->data;
+ for (uint32_t i = 0; i < sensorData->batchCnt; i++) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+ "SensorData dataX:%x, datY:%x, dataZ:%x\n",
+ accData[i].axisX,
+ accData[i].axisY,
+ accData[i].axisZ);
+ }
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SensorData batchCnt:%u timestamp:%lld\n",
+ sensorData->batchCnt, sensorData->timestamp);
+ free(sensorData);
+ return SENSOR_OK;
+}
+
static SensorTypeId GetSensorIdByParam(const char *argv)
{
if (argv == NULL) {
int32_t (*UnsubscribeSensor)(int32_t sensorTypeId, const SensorUser *user);\r
int32_t (*SetMode)(int32_t sensorTypeId, const SensorUser *user, int32_t mode);\r
int32_t (*SetOption)(int32_t sensorTypeId, const SensorUser *user, int32_t option);\r
+// ohos-hisi begin\r
+ int32_t (*GetData)(int32_t sensorTypeId, const SensorUser *user, void *sensorData);\r
+// ohos-hisi end\r
} SensorFeatureApi;\r
\r
typedef struct SensorService {\r
int32_t SetModeInvoke(SensorFeatureApi *defaultApi, IpcIo *req, IpcIo *reply);\r
int32_t SetOptionInvoke(SensorFeatureApi *defaultApi, IpcIo *req, IpcIo *reply);\r
void SetSvcIdentity(IpcIo *req, const IpcIo *reply);\r
+// ohos-hisi begin\r
+int32_t GetSensorDataImpl(int32_t sensorId, const SensorUser *user, void *sensorData);\r
+// ohos-hisi end\r
#ifdef __cplusplus\r
#if __cplusplus\r
}\r
.UnsubscribeSensor = UnsubscribeSensorImpl,\r
.SetMode = SetModeImpl,\r
.SetOption = SetOptionImpl,\r
+// ohos-hisi begin\r
+ .GetData = GetSensorDataImpl,\r
+// ohos-hisi end\r
IPROXY_END,\r
};\r
\r
}\r
return SENSOR_OK;\r
}\r
+\r
+// ohos-hisi begin\r
+int32_t GetSensorDataImpl(int32_t sensorId, const SensorUser *user, void *sensorData)\r
+{\r
+ HILOG_DEBUG(HILOG_MODULE_APP, "[SERVICE:%s]: %s begin",\r
+ SENSOR_SERVICE, __func__);\r
+ if (!CheckSensorTypeId(sensorId)) {\r
+ return SENSOR_ERROR_INVALID_ID;\r
+ }\r
+ return g_sensorDevice->GetSensorData(sensorId, (SensorData *)sensorData);\r
+}\r
+// ohos-hisi end
\ No newline at end of file
static const char OHOS_HARDWARE_MODEL[] = {"FD230V10"};\r
static const char OHOS_HARDWARE_PROFILE[] = {"aout:true,display:true"};\r
static const char OHOS_BOOTLOADER_VERSION[] = {"bootloader"};\r
-static const char OHOS_SECURITY_PATCH_TAG[] = {"2024/12/01"};\r
+static const char OHOS_SECURITY_PATCH_TAG[] = {"2025/06/17"};\r
static const char OHOS_ABI_LIST[] = {"riscv-liteos"};\r
static const char OHOS_SERIAL[] = {"****"}; // provided by OEM.\r
const char g_roBuildOs[] = {"OpenHarmony"};\r
-const char g_roBuildVerShow[] = {"OpenHarmony 5.0.1.115"};\r
+const char g_roBuildVerShow[] = {"OpenHarmony 5.1.1.115"};\r
const int g_roFirstApiLevel = 1;\r
const char INCREMENTAL_VERSION[] = {"version"};\r
const char BUILD_TYPE[] = {"BUILD_TYPE"};\r
#define FILE_RO "ro."\r
#define VERSION_ID_LEN 256\r
#define PROPERTY_MAX_LENGTH 2048\r
-#define INCREMENTAL_VERSION "version"\r
+#define INCREMENTAL_VERSION "OpenHarmony 5.1 Release"\r
#define BUILD_TYPE "release"\r
#define BUILD_USER "luozheng"\r
#define BUILD_HOST "linux"\r
#define BT_MAC_BUFF_SIZE 6\r
#define BT_MAC_BUFF_LEN 17\r
\r
-static char g_roBuildOs[] = {"OpenHarmony-5.0.1.115"};\r
+static char g_roBuildOs[] = {"OpenHarmony-5.1.1.115"};\r
static char g_roBuildVerShow[] = {"1.0.0"};\r
static char g_roSdkApiLevel[] = {"13"};\r
static char g_roFirstApiLevel[] = {"1"};\r
static const char OHOS_OS_NAME[] = { "OpenHarmony" };\r
static const int OHOS_SDK_API_VERSION = 13;\r
-static const char OHOS_SECURITY_PATCH_TAG[] = {"2024/12/01"};\r
+static const char OHOS_SECURITY_PATCH_TAG[] = {"2025/06/17"};\r
static const char OHOS_RELEASE_TYPE[] = { "Release" };\r
static const char OHOS_DEFAULT_VALUE[] = { "Default" };\r
\r
static const int MAJOR_VERSION = 5;\r
-static const int SENIOR_VERSION = 0;\r
-static const int FEATURE_VERSION = 0;\r
-static const int BUILD_VERSION = 0;\r
+static const int SENIOR_VERSION = 1;\r
+static const int FEATURE_VERSION = 1;\r
+static const int BUILD_VERSION = 115;\r
\r
static const char EMPTY_STR[] = { "" };\r
\r
--- /dev/null
+文件夹1201patch合并提交
\ No newline at end of file
SOURCE_TYPE_BUT /**< Undefined source */
} SourceType;
-#define URL_LEN 4096 /**< Indicates the URL length. */
+#define URL_LEN 256 /**< Indicates the URL length. */
/**
* @brief Defines the demuxer data source.
OUTPUT_FORMAT_HEIF = 3, /**< HEIF */
OUTPUT_FORMAT_OGG = 4, /**< Ogg */
OUTPUT_FORMAT_WAV = 5, /**< WAV */
+ OUTPUT_FORMAT_MP3 = 6, /**< mp3 */
+ OUTPUT_FORMAT_SILK = 7, /* Silk */
OUTPUT_FORMAT_INVALID /**< Invalid format */
} OutputFormat;
#include "gnss_nmea_parse.h"
#include "pm_definition.h"
#include "pm.h"
+#include "osal_task.h"
namespace OHOS {
namespace HDI {
#define MSG_TYPE_BINRY 0
#define MSG_TYPE_ASCII 1
#define LISTEN_DATA_MAX_LINES 1000
-#define REPORT_MAX_BYTES 10000
#define LISTEN_TIME_THR 1000
+#define GNSS_TASK_CREATE_OK_WAIT_TIMEOUT 1000 // ms
+#define GNSS_TASK_CREATE_TICK_TIME 50 // ms
std::string g_gnssNmeaFile = "/user/gnss_nmea.log";
typedef struct {
bool gnssEnabled;
bool gnssStarted;
+ bool gnssRunning;
GnssCallbackStruct *gnssCallback;
GnssInfo gnssInfo;
GnssLocation location;
GnssSatelliteStatus satStatus;
ThreadId listenGnssDataThreadId;
+#ifdef SUPPORT_FILE
std::ifstream gnssNmeaFp;
+#endif
} GnssServiceContext;
static GnssServiceContext g_gnssServiceCtx = {
.gnssEnabled = false,
.gnssStarted = false,
+ .gnssRunning = false,
.gnssCallback = nullptr,
.gnssInfo = {0},
.location = {0},
}
}
+#ifdef SUPPORT_FILE
static void ListenGnssData(void *argv)
{
LBSLOGI(HDI_GNSS, "enter ListenGnssData");
LBSLOGE(HDI_GNSS, "ListenGnssData argv invalid");
return;
}
+ GnssNmeaInit();
+ gnssServiceCtx->gnssRunning = true;
while (gnssServiceCtx->gnssStarted && g_gnssServiceCtx.gnssNmeaFp.good()) {
std::string nmeaLine;
while (getline(gnssServiceCtx->gnssNmeaFp, nmeaLine)) {
gnssServiceCtx->gnssNmeaFp.clear();
gnssServiceCtx->gnssNmeaFp.seekg(0, std::ios::beg);
}
+ gnssServiceCtx->gnssRunning = false;
LBSLOGI(HDI_GNSS, "exit ListenGnssData");
}
+#else
+constexpr uint32_t REPORT_MAX_CNT = 27;
+constexpr uint32_t REPORT_MAX_BYTES = 512;
+static char g_nmeaData[REPORT_MAX_CNT][REPORT_MAX_BYTES] = {
+ "$GNGGA,021707.00,3045.804990,N,10353.991346,E,1,37,1.2,597.4,M,,M,,*6D",
+ "$GNGLL,3045.804990,N,10353.991346,E,021707.00,A,A*7E",
+ "$GNGSA,A,3,10,12,15,18,23,25,32,,,,,,2.4,1.2,2.1,1*3F",
+ "$GNGSA,A,3,67,68,69,77,78,79,82,83,84,,,,2.4,1.2,2.1,2*38",
+ "$GNGSA,A,3,3,5,15,24,25,34,36,,,,,,2.4,1.2,2.1,3*34",
+ "$GNGSA,A,3,9,11,13,14,16,24,25,26,28,33,38,39,2.4,1.2,2.1,4*05",
+ "$GNGSA,A,3,2,3,,,,,,,,,,,2.4,1.2,2.1,5*32",
+ "$GPGSV,2,1,07,10,51,332,29,12,18,104,26,15,08,071,22,18,32,179,22,1*6A",
+ "$GPGSV,2,2,07,23,68,068,15,25,17,145,35,32,41,285,44,1*5A",
+ "$GLGSV,3,1,09,67,29,054,27,68,44,350,43,69,19,298,45,77,24,044,21,1*72",
+ "$GLGSV,3,2,09,78,43,117,22,79,15,168,19,82,18,200,27,83,41,242,18,1*75",
+ "$GLGSV,3,3,09,84,22,318,18,1*4E",
+ "$GBGSV,6,1,22,01,34,119,,02,51,217,,03,55,166,,04,20,108,,1*71",
+ "$GBGSV,6,2,22,05,31,245,,09,59,202,18,11,10,191,30,13,75,039,21,1*78",
+ "$GBGSV,6,3,22,14,58,018,30,16,79,185,23,21,05,092,,24,50,130,27,1*7C",
+ "$GBGSV,6,4,22,25,19,186,35,26,33,059,16,27,05,316,,28,24,276,28,1*7C",
+ "$GBGSV,6,5,22,33,50,329,40,38,61,107,28,39,85,183,17,41,11,293,,1*7A",
+ "$GBGSV,6,6,22,42,45,061,19,43,19,211,23,1*72",
+ "$GQGSV,1,1,03,02,16,127,30,03,20,157,19,04,56,083,,1*52",
+ "$GAGSV,2,1,08,03,53,293,29,05,50,030,31,08,10,259,,15,42,304,42,7*7B",
+ "$GAGSV,2,2,08,24,18,089,24,25,15,141,36,34,59,213,27,36,18,167,18,7*7A",
+ "$GNRMC,021707.00,A,3045.804990,N,10353.991346,E,000.9,159.3,071124,,E,A,V*70",
+ "$GNVTG,159.3,T,159.3,M,000.9,N,001.7,K,A*32",
+ "$GNZDA,021707.00,07,11,2024,00,00*78",
+ "$PNTH000,6,,-91,0,,,,,1,1*11",
+ "$PNTH001,1.226969,2.06,1.61,15.72,0,39,108*2E",
+ "$PNTH002,021707.00,N,243.524682,3,200,0.166667,12,0.270406*44",
+};
+
+static void ListenGnssData(void *argv)
+{
+ LBSLOGI(HDI_GNSS, "enter ListenGnssData");
+ GnssServiceContext *gnssServiceCtx = (GnssServiceContext *)argv;
+ if (gnssServiceCtx == nullptr || gnssServiceCtx->gnssCallback == nullptr) {
+ LBSLOGE(HDI_GNSS, "ListenGnssData argv invalid");
+ return;
+ }
+ GnssNmeaInit();
+ gnssServiceCtx->gnssRunning = true;
+ while (gnssServiceCtx->gnssStarted) {
+ for (uint32_t i = 0; i < REPORT_MAX_CNT; i++) {
+ const char *nmeaStr = g_nmeaData[i];
+ int32_t nmeaLen = strlen(g_nmeaData[i]);
+ GnssNmeaFrameType nmeaType = GnssNmeaGetFrameType(nmeaStr, nmeaLen);
+ LBSLOGD(HDI_GNSS, "nmeaType:%d nmeaStr:%s nmeaLen:%d", nmeaType, nmeaStr, nmeaLen);
+ if (nmeaType >= GNSS_NMEA_FRAME_MAX) {
+ LBSLOGW(HDI_GNSS, "invalid nmeaStr:%s", nmeaStr);
+ continue;
+ }
+ if (nmeaType == GNSS_NMEA_FRAME_GGA) {
+ ResetGnssInfo(gnssServiceCtx);
+ }
+ gnssServiceCtx->gnssCallback->gnssCallback.nmeaUpdate(LocationGnssUtilsGetTimestampMS(), nmeaStr, nmeaLen);
+ int32_t ret =
+ GnssNmeaDecodeFrame(nmeaStr, nmeaLen, &gnssServiceCtx->gnssInfo);
+ if (ret != GNSS_SUCCESS) {
+ LBSLOGW(HDI_GNSS, "GnssNmeaDecodeFrame failed:%d", ret);
+ }
+ if (nmeaType == GNSS_NMEA_FRAME_TH002) {
+ ResetLocationSatelliteStatus(gnssServiceCtx);
+
+ ret = LocationGnssUtilsFillGnssLocation(&gnssServiceCtx->gnssInfo, &gnssServiceCtx->location);
+ if (ret == GNSS_SUCCESS) {
+ gnssServiceCtx->gnssCallback->gnssCallback.locationUpdate(&gnssServiceCtx->location);
+ }
+ ret = LocationGnssUtilsFillAllSatelliteStatus(&gnssServiceCtx->gnssInfo, &gnssServiceCtx->satStatus);
+ if (ret == GNSS_SUCCESS) {
+ gnssServiceCtx->gnssCallback->gnssCallback.satelliteStatusUpdate(&gnssServiceCtx->satStatus);
+ }
+ osDelay(LISTEN_TIME_THR);
+ }
+ }
+ }
+ gnssServiceCtx->gnssRunning = false;
+ LBSLOGI(HDI_GNSS, "exit ListenGnssData");
+}
+#endif
static int LocationStopGnss(uint32_t category)
{
return GNSS_FAILURE;
}
g_gnssServiceCtx.gnssStarted = false;
+#ifdef SUPPORT_FILE
if (g_gnssServiceCtx.gnssNmeaFp) {
g_gnssServiceCtx.gnssNmeaFp.close();
}
+#endif
+ uint16_t taskReadyWait = 0;
+ while ((taskReadyWait < GNSS_TASK_CREATE_OK_WAIT_TIMEOUT) && g_gnssServiceCtx.gnssRunning) {
+ osal_msleep(GNSS_TASK_CREATE_TICK_TIME);
+ taskReadyWait += GNSS_TASK_CREATE_TICK_TIME;
+ }
g_gnssServiceCtx.listenGnssDataThreadId = nullptr;
return GNSS_SUCCESS;
}
LBSLOGI(HDI_GNSS, "Gnss has Started");
return GNSS_SUCCESS;
}
+#ifdef SUPPORT_FILE
g_gnssServiceCtx.gnssNmeaFp.open(g_gnssNmeaFile, std::ifstream::in);
if (!g_gnssServiceCtx.gnssNmeaFp.good() ||
LBSLOGI(HDI_GNSS, "Gnss open :%s failed", g_gnssNmeaFile.c_str());
return GNSS_FAILURE;
}
+#endif
g_gnssServiceCtx.gnssStarted = true;
ThreadAttr attr = {"ListenGnssDataTask", 0x2000, (uint8_t)osPriorityNormal, 0, 0};
ThreadId threadId = (ThreadId)ThreadCreate(ListenGnssData, &g_gnssServiceCtx, &attr);
/* Bearing accuracy in degrees. */
float bearingAccuracy;
+ /* Northward Velocity in m/s. */
+ float velocityNorth;
+
+ /* Eastward Velocity in m/s. */
+ float velocityEast;
+
+ /* Descent Velocity in m/s. */
+ float velocityDescend;
+
/* Timestamp for the location fix. Number of milliseconds since January 1, 1970. */
int64_t timeForFix;
/* Time uncertainty in nanosecond. */
uint64_t timeUncertainty;
+
+ /* Signal status */
+ int32_t signal;
} GnssLocation;
/*
locationNew.altitude = location->altitude;
locationNew.horizontalAccuracy = location->horizontalAccuracy;
locationNew.speed = location->speed;
+ locationNew.velocityNorth = location->velocityNorth;
+ locationNew.velocityEast = location->velocityEast;
+ locationNew.velocityDescend = location->velocityDescend;
locationNew.bearing = location->bearing;
locationNew.verticalAccuracy = location->verticalAccuracy;
locationNew.speedAccuracy = location->speedAccuracy;
locationNew.timeForFix = location->timeForFix;
locationNew.timeSinceBoot = location->timeSinceBoot;
locationNew.timeUncertainty = location->timeUncertainty;
+ locationNew.signal = location->signal;
if (g_gnssCallback != nullptr) {
g_gnssCallback->ReportLocation(locationNew);
}
#define GNSS_SAT_IN_MSG 4
#define GNSS_NSAT_MSGS (GNSS_SAT_NUM_MAX / GNSS_SAT_IN_MSG)
-#define GNSS_KNOTS (1.852)
+#define GNSS_KNOTS (0.514444 * 100) // knots to m/s
+#define GNSS_STRAIGHT_ANGLE (180.0)
#define NMEA_SENTENCE_START_BIT (3) // $-- 正式语句从第四位开始
#define NMEA_SENTENCE_TYPE_BIT (3) // 语句类型标识长度
#define NMEA_HEX 16
#define NMEA_ONE_SENTENCE_FOUR_SAT 4
#define NMEA_GSV_OTHER_BIT 3
+#define NMEA_ERROR (4.0) // 估算误差
typedef enum {
GNSS_SYSTEM_INVALID = 0,
GNSS_NMEA_FIELD_TYPE_SATUSEDNUM = 0x8000,
GNSS_NMEA_FIELD_TYPE_SATINUSE = 0x10000,
GNSS_NMEA_FIELD_TYPE_SATINVIEW = 0x20000,
+ GNSS_NMEA_FIELD_TYPE_HORIZONTAL_ACCURACY = 0x40000,
+ GNSS_NMEA_FIELD_TYPE_VERTICAL_ACCURACY = 0x80000,
+ GNSS_NMEA_FIELD_TYPE_SPEED_ACCURACY = 0x100000,
+ GNSS_NMEA_FIELD_TYPE_NORTH_VELOCITY = 0x200000,
+ GNSS_NMEA_FIELD_TYPE_EAST_VELOCITY = 0x400000,
+ GNSS_NMEA_FIELD_TYPE_DESCEND_VELOCITY = 0x800000,
} GnssNmeaFieldType;
typedef struct {
double lat; // 纬度
double lon; // 经度
double altitude; // 天线海拔高度
- double speed; // 速度 千米/小时
+ float speed; // 速度 千米/小时
double pdop; // 三维位置精度因子:为纬度、经度和高程等误差平方和的开根号值
double hdop; // 水平分量精度因子:为纬度和经度等误差平方和的开根号值
double vdop; // 垂直分量精度因子
double trackAng; // 跟踪角
double magneticTrackAng; // 磁轨角
double magVariation; // 磁场变化度
+ // Calculated Velocity Components
+ // 计算后的速度分量
+ float velocityNorth; // Northward Velocity (m/s)
+ // 向北速度 (米/秒)
+ float velocityEast; // Eastward Velocity (m/s)
+ // 向东速度 (米/秒)
+ float velocityDescend; // Descent Velocity (m/s)
+ // 下降速度 (米/秒)
+
+ float verticalAccuracy; // Vertical accuracy estimate in mm
+ // 垂直精度估计 单位:mm
+ float horizontalAccuracy; // Horizontal accuracy estimate in mm
+ // 水平精度估计 单位:mm
+ float speedAccuracy; // Speed accuracy estimate in cm/s
+ // 速度精度估计 单位:cm/s
GnssTime utc; // 世界标准时间
GnssSatelliteList satelist; // 卫星信息
char nmeaBuf[GNSS_NMEA_FRAME_MAX_SIZE];
} GnssNmeaFrameProcess;
+void GnssNmeaInit();
+
GnssNmeaFrameType GnssNmeaGetFrameType(const char* nmeaBuf, unsigned int length);
int GnssNmeaDecodeFrame(const char* nmea, unsigned int nmeaLen, GnssInfo* gnssInfo);
\r
#pragma pack()\r
\r
-int32_t LocationGnssUtilsUtc2UnixTime(const GnssUtcTime *utcTime, uint32_t *unixTime);\r
+int32_t LocationGnssUtilsUtc2UnixTime(const GnssUtcTime *utcTime, int64_t *unixTime);\r
\r
int64_t LocationGnssUtilsGetTimestampMS(void);\r
\r
if (nmeaGSA->fieldType & GNSS_NMEA_FIELD_TYPE_HDOP) {
gnssInfo->hdop = nmeaGSA->hdop;
+ gnssInfo->horizontalAccuracy = gnssInfo->hdop * NMEA_ERROR; // 估算水平误差
+ gnssInfo->field |= GNSS_NMEA_FIELD_TYPE_HORIZONTAL_ACCURACY;
}
if (nmeaGSA->fieldType & GNSS_NMEA_FIELD_TYPE_VDOP) {
gnssInfo->vdop = nmeaGSA->vdop;
+ gnssInfo->verticalAccuracy = gnssInfo->vdop * NMEA_ERROR; // 估算垂直误差
+ gnssInfo->field |= GNSS_NMEA_FIELD_TYPE_VERTICAL_ACCURACY;
}
return GNSS_OK;
}
gnssInfo->field |= nmeaVTG->fieldType;
gnssInfo->sentence |= GNSS_NMEA_FRAME_VTG;
- if (nmeaVTG->fieldType & GNSS_NMEA_FIELD_TYPE_SPEED) {
- gnssInfo->speed = nmeaVTG->speed;
- }
if (nmeaVTG->fieldType & GNSS_NMEA_FIELD_TYPE_TRACK) {
gnssInfo->trackAng = nmeaVTG->trackAng;
}
return;
}
+#define NMEA_SPEEDS_SAMPLE_CNT (100)
+float g_speeds[NMEA_SPEEDS_SAMPLE_CNT]; // 存储速度样本
+int32_t g_sampleCnt = 0;
+bool g_isWriteinPlace = false;
+
+// 计算 RMSE
+static float NmeaComputeRmse(int32_t sampleCnt)
+{
+ if (sampleCnt == 0) {
+ return 0.0f;
+ }
+
+ float sum = 0.0, mean = 0.0, errorSum = 0.0;
+ for (int32_t i = 0; i < sampleCnt; i++) {
+ sum += g_speeds[i];
+ }
+ mean = sum / sampleCnt;
+
+ for (int32_t i = 0; i < sampleCnt; i++) {
+ float error = g_speeds[i] - mean;
+ errorSum += error * error;
+ }
+
+ return sqrtf(errorSum / sampleCnt);
+}
+
static int NmeaRMC2GnssInfo(GnssNmeaRMC *nmeaRMC, GnssInfo *gnssInfo)
{
if (nmeaRMC == NULL || gnssInfo == NULL) {
}
if (nmeaRMC->fieldType & GNSS_NMEA_FIELD_TYPE_SPEED) {
+ // knots to cm/s
gnssInfo->speed = nmeaRMC->speedN * GNSS_KNOTS;
+ if (g_sampleCnt == NMEA_SPEEDS_SAMPLE_CNT) {
+ g_sampleCnt = 0;
+ g_isWriteinPlace = true;
+ }
+ g_speeds[g_sampleCnt++] = gnssInfo->speed;
+ gnssInfo->speedAccuracy = NmeaComputeRmse(g_isWriteinPlace ? NMEA_SPEEDS_SAMPLE_CNT : g_sampleCnt);
+ gnssInfo->field |= GNSS_NMEA_FIELD_TYPE_SPEED_ACCURACY;
+
}
if (nmeaRMC->fieldType & GNSS_NMEA_FIELD_TYPE_TRACK) {
gnssInfo->trackAng = nmeaRMC->trackAng;
+ if (nmeaRMC->fieldType & GNSS_NMEA_FIELD_TYPE_SPEED) {
+ gnssInfo->velocityNorth = gnssInfo->speed * cos(gnssInfo->trackAng * M_PI / GNSS_STRAIGHT_ANGLE);
+ gnssInfo->field |= GNSS_NMEA_FIELD_TYPE_NORTH_VELOCITY;
+ gnssInfo->velocityEast = gnssInfo->speed * sin(gnssInfo->trackAng * M_PI / GNSS_STRAIGHT_ANGLE);
+ gnssInfo->field |= GNSS_NMEA_FIELD_TYPE_EAST_VELOCITY;
+ }
}
if (nmeaRMC->fieldType & GNSS_NMEA_FIELD_TYPE_MAGVAR) {
return GNSS_OK;
}
+#define NMEA_HOUR_TO_SEC (3600)
+#define NMEA_MIN_TO_SEC (60)
+#define NMEA_12_HOUR_TO_SEC (43200)
+#define NMEA_24_HOUR_TO_SEC (86400)
+// Store previous altitude and time for velocity calculation
+// 用于存储前一时刻的高度和时间,用于计算速度
+static double g_previousAltitude = 0.0;
+static double g_previousTime = 0.0;
+
+static void CalculateVelocityDescend(const GnssNmeaGGA *nmeaGGA, GnssInfo *gnssInfo)
+{
+ // 计算下降速度 (需要上一高度和时间)
+ // Calculate descent velocity (needs previous altitude and time)
+ if (g_previousTime > 0.0) {
+ double currentTime =
+ gnssInfo->utc.hour * NMEA_HOUR_TO_SEC + gnssInfo->utc.min * NMEA_MIN_TO_SEC + gnssInfo->utc.sec;
+ double deltaTime = currentTime - g_previousTime;
+
+ // 处理跨天情况
+ // Handle day crossover
+ if (deltaTime < -NMEA_12_HOUR_TO_SEC) { // 如果时间差小于-12小时,说明跨天了
+ // If time difference is less than -12 hours, day has changed
+ deltaTime += NMEA_24_HOUR_TO_SEC; // 加上24小时
+ // Add 24 hours
+ } else if (deltaTime > NMEA_12_HOUR_TO_SEC) { // 如果时间差大于12小时,说明是前一天的数据
+ // If time difference is more than 12 hours, it's previous day's data
+ deltaTime -= NMEA_24_HOUR_TO_SEC;
+ }
+
+ if (deltaTime > 0 && deltaTime < NMEA_TEN) { // 只处理合理的时间差(比如小于10秒)
+ // Only process reasonable time differences (e.g., less than 10 seconds)
+ double deltaAltitude = gnssInfo->altitude - g_previousAltitude;
+ // 过滤异常值(比如高度差太大)
+ // Filter abnormal values (e.g., too large altitude differences)
+ if (fabs(deltaAltitude) < NMEA_NUM_100) { // 假设最大垂直速度不超过100m/s
+ // Assume maximum vertical speed doesn't exceed 100m/s
+ gnssInfo->velocityDescend =
+ -deltaAltitude / deltaTime; // 注意符号:上升为负,下降为正
+ // Note: negative for ascent, positive for descent
+ gnssInfo->field |= GNSS_NMEA_FIELD_TYPE_DESCEND_VELOCITY;
+ }
+ }
+ }
+ g_previousAltitude = gnssInfo->altitude;
+ g_previousTime = gnssInfo->utc.hour * NMEA_HOUR_TO_SEC + gnssInfo->utc.min * NMEA_MIN_TO_SEC + gnssInfo->utc.sec;
+}
+
static int NmeaGGA2GnssInfo(const GnssNmeaGGA *nmeaGGA, GnssInfo *gnssInfo)
{
if (nmeaGGA == NULL || gnssInfo == NULL) {
if (nmeaGGA->fieldType & GNSS_NMEA_FIELD_TYPE_ANTALT) {
gnssInfo->altitude = nmeaGGA->antAltitude;
+ CalculateVelocityDescend(nmeaGGA, gnssInfo);
}
return GNSS_OK;
}
nmeaFrameType = GnssNmeaGetFrameType((const char *)&nmeaFrameProcess.nmeaBuf, nmeaFrameProcess.length);
return NmeaFrameProc(nmeaFrameType, &nmeaFrameProcess, gnssInfo);
}
+
+void GnssNmeaInit()
+{
+ (void)memset_s(g_speeds, sizeof(g_speeds), 0, sizeof(g_speeds));
+ g_isWriteinPlace = false;
+ g_sampleCnt = 0;
+ g_previousAltitude = 0.0;
+ g_previousTime = 0.0;
+}
}\r
\r
/* 将日历时(年月日时分秒) 转换为 unix时间(1970年1月1日起的时间秒数) */\r
-int32_t LocationGnssUtilsUtc2UnixTime(const GnssUtcTime *utcTime, uint32_t *unixTime)\r
+int32_t LocationGnssUtilsUtc2UnixTime(const GnssUtcTime *utcTime, int64_t *unixTime)\r
{\r
if (utcTime == NULL || unixTime == NULL) {\r
LBSLOGE(HDI_GNSS, "error: [Utc2UnixTime] null pointer!");\r
int32_t *monthDays = (CheckIfLeapYear(utcTime->year) == 1) ? g_leapMonthDays : g_normMonthDays;\r
\r
// 计算从1970.01.01开始的unix 秒数\r
- uint32_t timestamp = 0;\r
- timestamp += (uint32_t)(utcTime->year - UNIX_TIME_START_YEAR) * SECONDS_PER_NORMAL_YEAR;\r
- timestamp += (uint32_t)GetLeapYearNum(UNIX_TIME_START_YEAR, utcTime->year) * SECONDS_PER_DAY;\r
+ int64_t timestamp = 0;\r
+ timestamp += (int64_t)(utcTime->year - UNIX_TIME_START_YEAR) * SECONDS_PER_NORMAL_YEAR;\r
+ timestamp += (int64_t)GetLeapYearNum(UNIX_TIME_START_YEAR, utcTime->year) * SECONDS_PER_DAY;\r
\r
for (int32_t i = 1; i < utcTime->month; i++) {\r
- timestamp += (uint32_t)monthDays[i - 1] * SECONDS_PER_DAY;\r
+ timestamp += (int64_t)monthDays[i - 1] * SECONDS_PER_DAY;\r
}\r
\r
- timestamp += (uint32_t)(utcTime->day - 1) * SECONDS_PER_DAY;\r
- timestamp += (uint32_t)utcTime->hour * SECONDS_PER_HOUR;\r
- timestamp += (uint32_t)utcTime->minute * SECONDS_PER_MIN;\r
- uint32_t timestampSec = (uint32_t)(utcTime->second + utcTime->ms / TIME_UNIT);\r
+ timestamp += (int64_t)(utcTime->day - 1) * SECONDS_PER_DAY;\r
+ timestamp += (int64_t)utcTime->hour * SECONDS_PER_HOUR;\r
+ timestamp += (int64_t)utcTime->minute * SECONDS_PER_MIN;\r
+ int64_t timestampSec = (int64_t)(utcTime->second * TIME_UNIT + utcTime->ms);\r
\r
*unixTime = timestamp + timestampSec;\r
return GNSS_SUCCESS;\r
location->fieldValidity |= GNSS_LOCATION_TIME_VALID;\r
GnssUtcTime utcTime = {gnssInfo->utc.year, gnssInfo->utc.month, gnssInfo->utc.day, gnssInfo->utc.hour,\r
gnssInfo->utc.min, gnssInfo->utc.sec, gnssInfo->utc.centisec, 1};\r
- uint32_t unixTime = 0;\r
+ int64_t unixTime = 0;\r
LocationGnssUtilsUtc2UnixTime(&utcTime, &unixTime);\r
location->timeForFix = unixTime;\r
location->size++;\r
return GNSS_FAILURE;\r
}\r
location->fieldValidity = GNSS_NMEA_FIELD_TYPE_SMASK;\r
+ if (gnssInfo->field & GNSS_NMEA_FIELD_TYPE_SIGNAL) {\r
+ location->signal = (int32_t)gnssInfo->signal;\r
+ location->fieldValidity |= GNSS_LOCATION_SIGNAL_VALID;\r
+ location->size++;\r
+ }\r
if (gnssInfo->field & GNSS_NMEA_FIELD_TYPE_LAT) {\r
location->latitude = gnssInfo->lat;\r
location->fieldValidity |= GNSS_LOCATION_LAT_VALID;\r
location->fieldValidity |= GNSS_LOCATION_BEARING_VALID;\r
location->size++;\r
}\r
+ if (gnssInfo->field & GNSS_NMEA_FIELD_TYPE_HORIZONTAL_ACCURACY) {\r
+ location->horizontalAccuracy = gnssInfo->horizontalAccuracy;\r
+ location->fieldValidity |= GNSS_LOCATION_HORIZONTAL_ACCURACY_VALID;\r
+ location->size++;\r
+ }\r
+ if (gnssInfo->field & GNSS_NMEA_FIELD_TYPE_VERTICAL_ACCURACY) {\r
+ location->verticalAccuracy = gnssInfo->verticalAccuracy;\r
+ location->fieldValidity |= GNSS_LOCATION_VERTICAL_ACCURACY_VALID;\r
+ location->size++;\r
+ }\r
+ if (gnssInfo->field & GNSS_NMEA_FIELD_TYPE_SPEED_ACCURACY) {\r
+ location->speedAccuracy = gnssInfo->speedAccuracy;\r
+ location->fieldValidity |= GNSS_LOCATION_SPEED_ACCURACY_VALID;\r
+ location->size++;\r
+ }\r
+ if (gnssInfo->field & GNSS_NMEA_FIELD_TYPE_NORTH_VELOCITY) {\r
+ location->velocityNorth = gnssInfo->velocityNorth;\r
+ location->fieldValidity |= GNSS_LOCATION_NORTH_VELOCITY_VALID;\r
+ location->size++;\r
+ }\r
+ if (gnssInfo->field & GNSS_NMEA_FIELD_TYPE_EAST_VELOCITY) {\r
+ location->velocityEast = gnssInfo->velocityEast;\r
+ location->fieldValidity |= GNSS_LOCATION_EAST_VELOCITY_VALID;\r
+ location->size++;\r
+ }\r
+ if (gnssInfo->field & GNSS_NMEA_FIELD_TYPE_DESCEND_VELOCITY) {\r
+ location->velocityDescend = gnssInfo->velocityDescend;\r
+ location->fieldValidity |= GNSS_LOCATION_DESCEND_VELOCITY_VALID;\r
+ location->size++;\r
+ }\r
\r
FillGnssLocationTimeInfo(gnssInfo, location);\r
\r
LBSLOGD(HDI_GNSS,\r
"location size :%lu field:0x%x lat%.3f lon:%.3f alti:%.3f speed:%.3f bearing:%.3f "\r
- "hAcc:%.3f vAcc:%.3f sAcc:%.3f bearingAcc:%.3f timeFix:%lld tSB:%llu",\r
+ "hAcc:%.3f vAcc:%.3f sAcc:%.3f bearingAcc:%.3f timeFix:%lld tSB:%llu velocityNorth:%.3f"\r
+ "velocityEast:%.3f velocityDescend:%.3f",\r
location->size, location->fieldValidity, location->latitude, location->longitude, location->altitude,\r
location->speed, location->bearing, location->horizontalAccuracy, location->verticalAccuracy,\r
- location->speedAccuracy, location->bearingAccuracy, location->timeForFix, location->timeSinceBoot);\r
+ location->speedAccuracy, location->bearingAccuracy, location->timeForFix, location->timeSinceBoot, location->velocityNorth,\r
+ location->velocityEast, location->velocityDescend);\r
return GNSS_SUCCESS;\r
}\r
\r
GNSS_LOCATION_TIME_VALID = 512,
GNSS_LOCATION_TIME_SINCE_BOOT_VALID = 1024,
GNSS_LOCATION_TIME_UNCERTAINTY_VALID = 2048,
+ GNSS_LOCATION_NORTH_VELOCITY_VALID = 4096,
+ GNSS_LOCATION_EAST_VELOCITY_VALID = 8192,
+ GNSS_LOCATION_DESCEND_VELOCITY_VALID = 16384,
+ GNSS_LOCATION_SIGNAL_VALID = 32768,
};
enum GnssWorkingMode : int32_t {
float verticalAccuracy;
float speedAccuracy;
float bearingAccuracy;
+ float velocityNorth;
+ float velocityEast;
+ float velocityDescend;
int64_t timeForFix;
int64_t timeSinceBoot;
int64_t timeUncertainty;
+ int32_t signal;
} __attribute__ ((aligned(8)));
struct GnssRefInfo {
--- /dev/null
+#===============================================================================
+# @brief cmake file
+# Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved.
+#===============================================================================
+
+add_subdirectory_with_alias_if_exist(hal_lite/sensor_mgr ${PROJECT_BINARY_DIR}/ohos/sensor_hdi_lite/sensor_mgr)
+add_subdirectory_with_alias_if_exist(hal_lite/sensors/hsensor/acc_simulator ${PROJECT_BINARY_DIR}/ohos/sensor_hdi_lite/hsensors/acc_simulator)
+add_subdirectory_with_alias_if_exist(hal_lite/sensors/hsensor/barometer ${PROJECT_BINARY_DIR}/ohos/sensor_hdi_lite/hsensors/barometer)
+add_subdirectory_with_alias_if_exist(hal_lite/sensors/hsensor/gyroscope ${PROJECT_BINARY_DIR}/ohos/sensor_hdi_lite/hsensors/gyroscope)
+add_subdirectory_with_alias_if_exist(hal_lite/sensors/hsensor/heart_rate_counter ${PROJECT_BINARY_DIR}/ohos/sensor_hdi_lite/hsensors/heart_rate_counter)
+add_subdirectory_with_alias_if_exist(hal_lite/sensors/hsensor/pedometer ${PROJECT_BINARY_DIR}/ohos/sensor_hdi_lite/hsensors/pedometer)
+add_subdirectory_with_alias_if_exist(hal_lite/sensors/hsensor/wear_detection ${PROJECT_BINARY_DIR}/ohos/sensor_hdi_lite/hsensors/wear_detection)
+add_subdirectory_with_alias_if_exist(hal_lite/sensors/vsensor/acc_alg_simulator ${PROJECT_BINARY_DIR}/ohos/sensor_hdi_lite/vsensors)
\ No newline at end of file
--- /dev/null
+set(COMPONENT_NAME "sensor_hdi")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+)
+
+set(PRIVATE_HEADER
+ ${ROOT_DIR}/application/wearable/ohos_deps
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../interfaces/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/hsensormgr_service/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/hsensor_data_service/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/vsensormgr_service/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/vsensormgr_service/src/vsensor_task_common/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/task/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/include
+)
+
+set(SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/sensor_interface_impl.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/sensor_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/hsensormgr_service/src/hsensormgr_service.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/hsensor_data_service/src/hsensor_data_service.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/vsensormgr_service/src/vsensormgr_service.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/vsensormgr_service/src/vsensor_task_mgr.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/vsensormgr_service/src/vsensor_task_common/src/vsensor_task_class.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/vsensormgr_service/src/vsensor_task_common/src/vsensor_task_comm.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/src/sensor_thread.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/src/sensor_log.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/src/sensor_utils.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/src/sensor_memory.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/src/sensor_msgqueue.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/task/src/sensor_task.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/task/src/sensor_tmsg.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/src/sensor_para_decision.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/src/sensor_state.c
+)
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+ -Wno-error
+ -Wno-unused-parameter
+ -fno-exceptions
+ -fno-unwind-tables
+ -fno-asynchronous-unwind-tables
+ -Wno-undef
+ -Wno-bitwise-op-parentheses
+ -Wno-shift-op-parentheses
+ -nostdlibinc
+ -nostdinc
+ -nostdlib
+ -Wno-error=unused-function
+)
+
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+set(AUTO_ADD_PATH
+ false
+)
+
+set(PUBLIC_DEFINES
+)
+
+set(CDEFINES ${CDEFINES} "CMSIS_SUPPORT" "ENABLE_INFO_LEVEL_LOG")
+set(PRIVATE_DEFINES
+ ${CDEFINES}
+)
+
+build_component()
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor common
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+
+#ifndef HDI_SENSOR_COMMON_H
+#define HDI_SENSOR_COMMON_H
+
+#include <stdio.h>
+#include "sensor_log.h"
+#include "securec.h"
+
+/* err number 管理,约定mudule id为30 */
+#define SENSOR_ERRNO_MODULE_ID 30 /* 0x1e */
+
+/* start:0x801e0000 end:0x801effff 返回错误信息均为负数 */
+#define SENSOR_ERR_NUMBER(type, code) \
+ (int32_t)((((((0x80 << 8) | (SENSOR_ERRNO_MODULE_ID)) << 8) | (type)) << 8) | (code))
+
+typedef enum {
+ SENSOR_ETYPE_ALG = 0x00,
+ SENSOR_ETYPE_VSENSOR_MGR = 0x01,
+ SENSOR_ETYPE_DATA_SERVICE = 0x02,
+ SENSOR_ETYPE_FRAME = 0x03,
+ SENSOR_ETYPE_ENTRY_PARA = 0x04,
+
+ SENSOR_ETYPE_MAX
+} SensorErrType;
+
+/* all return values of SENSOR Engine, partition by module */
+enum {
+ SENSOR_ERROR = -1,
+ SENSOR_OK = 0,
+
+ /* 算法错误码 SENSOR_ETYPE_ALG */
+ SENSOR_ALG_ERRNO = SENSOR_ERR_NUMBER(SENSOR_ETYPE_ALG, 0), /* 0x801e0000 */
+
+ /* 虚拟算法Sensor管理错误码 SENSOR_ETYPE_VSENSOR_MGR */
+ SENSOR_ALG_SERVICE_ERRNO = SENSOR_ERR_NUMBER(SENSOR_ETYPE_VSENSOR_MGR, 0), /* 0x801e0100 */
+ SENSOR_CHECK_RELY_SENSORS_NULL, /* 0x801e0101 */
+ SENSOR_CHECK_RELY_SENSORS_SENSORIL, /* 0x801e0102 */
+ SENSOR_CHECK_PROCESS_DATA_NULL, /* 0x801e0103 */
+ SENSOR_CHECK_PROCESS_DATA_TS_ERR, /* 0x801e0104 */
+ SENSOR_GET_RELY_SENSOR_INF_SENSORIL, /* 0x801e0105 */
+ SENSOR_OPEN_RELY_SENSORS_CHECK_NULL, /* 0x801e0106 */
+ SENSOR_VSENSOR_NOT_SUPPORT, /* 0x801e01A1 */
+ SENSOR_PERSON_INFO_NULL, /* 0x801e01A2 */
+ SENSOR_VSENSOR_TASK_REG_VENSOR_NULL, /* 0x801e01A5 */
+ SENSOR_TASK_SENSOR_DATA_UPDATE_NULL, /* 0x801e01A6 */
+ SENSOR_TASK_CHECK_COMM_COMPONENT_NULL, /* 0x801e01A7 */
+ SENSOR_TASK_LISTENER_FIND_NULL, /* 0x801e01A8 */
+ SENSOR_TASK_SENSOR_NULL, /* 0x801e01A9 */
+ SENSOR_TASK_HSDATA_UPDATE_DATA_NULL, /* 0x801e01AA */
+ SENSOR_TASK_VSENSOR_INFO_FIND_NULL, /* 0x801e01AB */
+ SENSOR_UTIL_CANNOT_GET_ALG_TASK, /* 0x801e01AC */
+ SENSOR_VSENSOR_NOT_REGISTER, /* 0x801e01AD */
+ SENSOR_HSENSOR_REG_NULL, /* 0x801e01AF */
+ SENSOR_TASK_HLISTENER_REG_TYPE_ERR, /* 0x801e01B1 */
+ SENSOR_TASK_RELY_SENSOR_NOT_REGISTERED, /* 0x801e01B2 */
+ SENSOR_TASK_SENSOR_DECISION_PARA_ERROR, /* 0x801e01B3 */
+ SENSOR_TASK_VSENSOR_OPEN_FAIL, /* 0x801e01B4 */
+ SENSOR_TASK_VSENSOR_CLOSE_FAIL, /* 0x801e01B5 */
+ SENSOR_TASK_VSENSOR_OPEN_NULL, /* 0x801e01B6 */
+ SENSOR_TASK_VSENSOR_CLOSE_NULL, /* 0x801e01B7 */
+ SENSOR_TASK_VSENSOR_PROCESS_NULL, /* 0x801e01B8 */
+
+ /* 数据管理错误码 SENSOR_ETYPE_DATA_SERVICE */
+ SENSOR_DATA_SERVICE_ERRNO = SENSOR_ERR_NUMBER(SENSOR_ETYPE_DATA_SERVICE, 0), /* 0x801e0200 */
+ SENSOR_SENSOR_DECISION_PARA_NULL, /* 0x801e0201 */
+ SENSOR_HSENSOR_CALIBRATE_INF_NULL, /* 0x801e0202 */
+ SENSOR_HSENSOR_SELFTEST_INF_NULL, /* 0x801e0203 */
+ SENSOR_HSENSOR_DRV_CALIBRATE_ERR, /* 0x801e0204 */
+ SENSOR_HSENSOR_DRV_SELFTEST_ERR, /* 0x801e0205 */
+
+ SENSOR_HSENSOR_PERIOD_BATCH_ERR,
+ SENSOR_HSENSOR_MODE_ERR,
+ SENSOR_HSENSOR_LISTENER_INFO_NULL,
+ SENSOR_HSENSOR_LISTENER_NULL,
+ SENSOR_HSENSOR_GET_SCB_SENSORIL,
+ SENSOR_HSENSOR_SCB_NULL,
+ SENSOR_HSENSOR_SCB_HSENSOR_NULL,
+ SENSOR_HSENSOR_SCB_LISTENER_EXIST,
+ SENSOR_HSENSOR_SCB_LISTENER_NOT_EXIST,
+ SENSOR_HSENSOR_SCB_REPORT_PERIOD_ZERO,
+ SENSOR_HSENSOR_NULL,
+ SENSOR_HSENSOR_NAME_NULL,
+ SENSOR_HSENSOR_INTERSENSORCE_NULL,
+ SENSOR_HSENSOR_READ_ERR,
+ SENSOR_HSENSOR_REGISTER_TYPE_DUPLICATE,
+
+ /* SENSOR基础框架,线程,消息队列等模块 错误码 SENSOR_ETYPE_FRAME */
+ SENSOR_FRAME_ERRNO = SENSOR_ERR_NUMBER(SENSOR_ETYPE_FRAME, 0), /* 0x801e0600 */
+ SENSOR_MEMSET_ERR, /* 0x801e0601 */
+ SENSOR_SEND_TMSG_NULL, /* 0x801e0602 */
+ SENSOR_SEND_TMSG_MSG_QUEUE_NULL, /* 0x801e0603 */
+ SENSOR_RECV_TMSG_NULL, /* 0x801e0604 */
+ SENSOR_RECV_TMSG_MSG_QUEUE_NULL, /* 0x801e0605 */
+ SENSOR_RECV_TMSG_ERR, /* 0x801e0606 */
+ SENSOR_FREE_TMSG_NULL, /* 0x801e0607 */
+ SENSOR_MSG_QUEUE_CREATE_FAIL, /* 0x801e0608 */
+ SENSOR_TASK_CREATE_FAIL, /* 0x801e0609 */
+ SENSOR_SEND_TMSG_DEST_NOT_RUNNING, /* 0x801e060A */
+ SENSOR_SENSOR_NOT_INIT, /* 0x801e060B */
+ SENSOR_SENSOR_SECUREC_FUNC_ERR, /* 0x801e060C */
+ SENSOR_VSENSOR_TASK_CLASS_NULL, /* 0x801e060D */
+ SENSOR_TASK_CREATE_ID_WRONG, /* 0x801e060F */
+
+ /* SENSOR MGR 所有入参检验 */
+ SENSOR_ENTRY_PARA_ERROR = SENSOR_ERR_NUMBER(SENSOR_ETYPE_ENTRY_PARA, 0), /* 0x801e0900 */
+ SENSOR_ENTRY_HSENSOR_NULL, /* 0x801e0901 */
+ SENSOR_ENTRY_HSENSOR_NAME_NULL, /* 0x801e0902 */
+ SENSOR_ENTRY_HSENSOR_FUNC_NULL, /* 0x801e0903 */
+ SENSOR_ENTRY_HSENSOR_TYPE_NULL, /* 0x801e0904 */
+ SENSOR_ENTRY_VSENSOR_NULL, /* 0x801e0905 */
+ SENSOR_ENTRY_VSENSOR_NAME_NULL, /* 0x801e0906 */
+ SENSOR_ENTRY_VSENSOR_FUNC_NULL, /* 0x801e0907 */
+ SENSOR_ENTRY_VSENSOR_TYPE_NULL, /* 0x801e0908 */
+ SENSOR_ENTRY_VSENSOR_RELY_NULL, /* 0x801e0909 */
+ SENSOR_ENTRY_VSENSOR_RELY_PARA_ERR, /* 0x801e090A */
+ SENSOR_ENTRY_CALIBRATE_PARA_NULL, /* 0x801e090B */
+ SENSOR_ENTRY_SELFTEST_PARA_NULL, /* 0x801e090C */
+ SENSOR_ENTRY_SENSOR_TYPE_ILLEGAL, /* 0x801e090D */
+
+ SENSOR_MAX
+};
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+#endif
+
+#ifndef SENSOR_MIN
+#define SENSOR_MIN(a, b) (((a) > (b)) ? (b) : (a))
+#endif
+#ifndef SENSOR_MAX
+#define SENSOR_MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#define CHECK_NULL_PTR_RETURN_VALUE(ptr, ret) \
+ do { \
+ if ((ptr) == NULL) { \
+ HILOG_ERROR(HILOG_MODULE_SEN, "pointer is null and return ret:%d", ret); \
+ return (ret); \
+ } \
+ } while (0)
+
+#define CHECK_NULL_PTR_RETURN(ptr) \
+ do { \
+ if ((ptr) == NULL) { \
+ HILOG_ERROR(HILOG_MODULE_SEN, "pointer is null and return"); \
+ return; \
+ } \
+ } while (0)
+
+#define CHECK_SENSOR_TYPE_ILLEGAL_RETURN_RET(type, ret) \
+ do { \
+ if ((type == SENSOR_TYPE_NONE) || (type >= SENSOR_TYPE_MAX)) { \
+ HILOG_ERROR(HILOG_MODULE_SEN, "type :%d illegal\n", type); \
+ return ret; \
+ } \
+ } while (0)
+
+#define CHECK_SENSOR_TYPE_ILLEGAL_RETURN(type) \
+ do { \
+ if ((type == SENSOR_TYPE_NONE) || (type >= SENSOR_TYPE_MAX)) { \
+ HILOG_ERROR(HILOG_MODULE_SEN, "type :%d illegal\n", type); \
+ return; \
+ } \
+ } while (0)
+
+#define SENSOR_CHECK_OK(x) \
+ do { \
+ if ((int32_t)(x) != SENSOR_OK) { \
+ HILOG_ERROR(HILOG_MODULE_SEN, "ret err ret:%d!\n", x); \
+ return x; \
+ } \
+ } while (0)
+#endif /* HDI_SENSOR_COMMON_H */
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor mgr
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+
+#ifndef HDI_SENSOR_MANAGER_H
+#define HDI_SENSOR_MANAGER_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sensor_typedef.h"
+
+int32_t SensorMgrInit(void);
+int32_t SensorMgrDeInit(void);
+
+int32_t SensorMgrRegistHsensor(const Hsensor *sensor);
+int32_t SensorMgrRegistVsensor(const Vsensor *sensor);
+
+int32_t SensorMgrGetAllSensors(struct SensorInformation **sensorInfo, int32_t *count);
+
+int32_t SensorMgrEnable(int32_t sensorTypeId);
+
+int32_t SensorMgrDisable(int32_t sensorTypeId);
+
+int32_t SensorMgrSetBatch(int32_t sensorTypeId, int64_t samplingInterval, int64_t reportInterval);
+
+int32_t SensorMgrSetMode(int32_t sensorTypeId, int32_t mode);
+
+int32_t SensorMgrSetOption(int32_t sensorTypeId, uint32_t option);
+
+int32_t SensorMgrRegistDataCallback(int32_t sensorTypeId, RecordDataCallback cb);
+
+int32_t SensorMgrUnregistDataCallback(int32_t sensorTypeId, RecordDataCallback cb);
+
+#endif /* HDI_SENSOR_MANAGER_H */
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor type def
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef HDI_SENSOR_TYPEDEF_H
+#define HDI_SENSOR_TYPEDEF_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sensor_type.h"
+
+/* person info */
+#define MIN_USER_WEIGHT 10 /* 单位:公斤 */
+#define DEFAULT_USER_WEIGHT 60 /* 单位:公斤 */
+#define MAX_USER_WEIGHT 250 /* 单位:公斤 */
+#define MIN_USER_HEIGHT 50 /* 单位:厘米 */
+#define DEFAULT_USER_HEIGHT 170 /* 单位:厘米 */
+#define MAX_USER_HEIGHT 250 /* 单位:厘米 */
+#define DEFAULT_USER_AGE 30 /* 单位:年 */
+#define MAX_USER_AGE 150 /* 单位:年 */
+#define ALG_USER_SEX_WOMEN 0 /* 女 */
+#define ALG_USER_SEX_MAN 1 /* 男 */
+#define ALG_USER_SEX_UNKNOWN 2 /* UNKNOWN */
+#define MAX_USER_GENDER 2
+
+typedef struct {
+ uint8_t weight; /* kg */
+ uint8_t height; /* cm */
+ uint8_t age; /* YEAR */
+ uint8_t gender; /* MALE为 1, FEMALE为 0, UNKNOWN 为2 */
+} SensorPersonInfo;
+
+typedef enum {
+ SENSOR_IOCTL_SET_PARA = 0,
+ SENSOR_IOCTL_GET_PARA,
+ SENSOR_IOCTL_GET_INTERVAL,
+ SENSOR_IOCTL_GET_INFO,
+ SENSOR_IOCTL_CURRENT_ADJUST,
+ SENSOR_IOCTL_GET_CHIP_TYPE,
+ SENSOR_IOCTL_GET_MAX_BATCHCOUNT,
+ SENSOR_IOCTL_GET_FW_VERSION,
+ SENSOR_IOCTL_GET_MAX_RANGE,
+ SENSOR_IOCTL_GET_PRECISION,
+ SENSOR_IOCTL_GET_SENSOR_DATA,
+ SENSOR_IOCTL_MAX
+} SensorIoctlCmd;
+
+typedef enum {
+ SENSOR_STATE_IDLE = 0,
+ SENSOR_STATE_OPEN,
+ SENSOR_STATE_CLOSE,
+
+ SENSOR_STATE_MAX
+} SensorState;
+
+typedef struct {
+ uint32_t period; /* 采样间隔单位 ms */
+ uint32_t batch; /* 一次上报的数据组数 */
+ uint32_t option;
+ enum SensorModeType mode; /* fifo mode OR realtime mode */
+} SensorPara;
+
+typedef struct {
+ enum SensorTypeTag type;
+ SensorPara param;
+} RelySensorInfo;
+
+typedef struct {
+ RelySensorInfo *relySensorArray;
+ uint32_t relySensorCnt;
+ uint8_t reserve[3]; /* 4字节对齐,3个字节保留 */
+} RelySensorsInfo;
+
+/* sensor信息 */
+typedef struct {
+ enum SensorTypeTag type; /* sensor 类型 */
+ const char *name; /* sensor 信息 “ACCEL” 、“HR v2.0” 等 */
+ const void *privateData; /* sensor 的私有信息,私有接口 */
+ uint32_t privateDataLen; /* sensor 的私有信息长度 */
+ SensorState state; /* 当前传感器运行状态,开、关、使能、去使能、暂停等 */
+ SensorPara openPara; /* 当前传感器运行参数 */
+} SensorInfo;
+
+/* sensor操作句柄结构 */
+typedef struct Sensor Sensor;
+struct Sensor {
+ SensorInfo sensorInfo;
+ /* 方法 */
+ int32_t (*open)(const Sensor *sensor, const SensorPara *openPara); /* 传感器开,设置传感器 */
+ int32_t (*close)(const Sensor *sensor); /* 传感器关 */
+ int32_t (*setBatch)(Sensor *sensor, int64_t samplingInterval, int64_t reportInterval);
+ int32_t (*setMode)(Sensor *sensor, int32_t mode);
+ int32_t (*setOption)(Sensor *sensor, uint32_t option);
+ int32_t (*registerResultCallback)(const Sensor *sensor, RecordDataCallback cb);
+ int32_t (*unregisterResultCallback)(const Sensor *sensor, RecordDataCallback cb);
+ int32_t (*calibrate)(const Sensor *sensor, void *para, uint32_t len); /* 物理传感器专用校准接口,暂不支持 */
+ int32_t (*selfTest)(
+ const Sensor *sensor, void *para, uint32_t len); /* 厂测模式下使用,物理传感器专用自检接口,暂不支持 */
+ int32_t (*ioctl)(const Sensor *sensor, SensorIoctlCmd cmd, void *data, uint32_t len); /* 其他io操作 */
+};
+
+typedef struct {
+ float maxRange; /**< Maximum measurement range of the sensor, not support now */
+ float accuracy; /**< Sensor accuracy, not support now */
+ int64_t minDelay; /**< Minimum sample period allowed in microseconds, not support now */
+ int64_t maxDelay; /**< Maxmum sample period allowed in microseconds, not support now */
+ uint32_t sampleElementlen; /**< one sample len */
+ uint32_t maxBatchCount; /**< Maxmum number of data of this sensor that could be batched */
+ uint32_t reserved; /**< Reserved fields */
+} SensorCapability;
+
+/* 物理传感器数据结构定义,注册时需要实现 */
+typedef struct {
+ enum SensorTypeTag type; /* 传感器类型 */
+ const char *name; /* sensor 信息 “ACCEL” “GYRO”等 */
+ SensorCapability caps;
+ const void *privateData; /* sensor 的私有信息,私有接口 */
+ uint32_t privateDataLen; /* sensor 的私有信息长度 */
+ /* 方法 */
+ int32_t (*init)(void); /* 上电,sensor初始化 */
+ int32_t (*deinit)(void); /* 下电,去初始化 */
+ int32_t (*open)(SensorPara *para); /* 传感器开 */
+ int32_t (*close)(void); /* 传感器关 */
+ int32_t (*read)(uint8_t *data, uint32_t len); /* 从传感器读数据 */
+ /* 其他io操作 */
+ int32_t (*ioctl)(SensorIoctlCmd cmd, void *data, uint32_t len);
+} Hsensor;
+
+/* 虚拟传感器(算法)数据结构定义,注册时需要实现 */
+typedef struct {
+ enum SensorTypeTag type; /* 虚拟传感器类型,注册时写明 */
+ const char *name; /* 虚拟传感器信息,注册时写明 */
+ const void *privateData; /* 虚拟传感器的私有信息 */
+ uint32_t privateDataLen; /* 虚拟传感器的私有信息长度 */
+ RelySensorsInfo *relySensors; /* 注册时写明,写清依赖的传感器 */
+
+ int32_t (*registDataCb)(RecordDataCallback cb); /* 注册结果回调函数 */
+ int32_t (*unRegistDataCb)(RecordDataCallback cb); /* 取消注册结果回调函数 */
+ /* 方法 */
+ int32_t (*open)(SensorPara *para); /* 算法开,模式设置 */
+ int32_t (*close)(void); /* 算法关 */
+ /* 算法接收传感器(包括依赖的算法)数据的接口 ts 微秒 */
+ int32_t (*process)(enum SensorTypeTag type, uint8_t *data, uint64_t ts, uint32_t len);
+ int32_t (*ioctl)(SensorIoctlCmd cmd, void *data, uint32_t len);
+} Vsensor;
+
+#endif /* HDI_SENSOR_TYPEDEF_H */
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor data service
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef HSENSOR_DATA_SERVICE_H
+#define HSENSOR_DATA_SERVICE_H
+
+#include "sensor_typedef.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int32_t HsensorDataServiceInit(enum SensorTypeTag type);
+uint32_t HsensorDataServiceProcess(enum SensorTypeTag type);
+int32_t HsensorDataServiceDeInit(enum SensorTypeTag type);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* HSENSOR_DATA_SERVICE_H */
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor data service impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "hsensor_data_service.h"
+#include "sensor_common.h"
+#include "sensor_utils.h"
+#include "sensor_log.h"
+#include "hsensormgr_service.h"
+
+struct SensorEvents g_sensorEvent = {};
+
+int32_t HsensorDataServiceInit(enum SensorTypeTag type)
+{
+ return SENSOR_OK;
+}
+
+/* ******************************************************************************
+ 函 数 名 : HsensorDataServiceNotifyResultData
+ 功能描述 : 数据分发,目前尚未做降采样,直接将所有数据上报,
+ 目前将所有数据的batch和采样率设置为一样,等待缓冲区和降采样完成
+ 输入参数 : None
+ 输出参数 : None
+ 返 回 值 : None
+****************************************************************************** */
+static void HsensorDataServiceNotifyResultData(HsensorScb *hsensorScb, HsensorListener *listener)
+{
+ if (listener->resultDataCb == NULL) {
+ return;
+ }
+ g_sensorEvent.sensorId = hsensorScb->type;
+ g_sensorEvent.version = 0;
+ g_sensorEvent.timestamp = hsensorScb->sysTick;
+ g_sensorEvent.option = hsensorScb->decisionPara.option;
+ g_sensorEvent.mode = hsensorScb->decisionPara.mode;
+ g_sensorEvent.data = hsensorScb->dataBuf;
+ g_sensorEvent.dataLen = hsensorScb->dataPackSize;
+ HILOG_DEBUG(HILOG_MODULE_SEN, "hsensorScb->type:%d data:%x", hsensorScb->type, hsensorScb->dataBuf);
+
+ listener->resultDataCb(&g_sensorEvent);
+}
+
+static void HsensorDataServiceNotifyData(HsensorScb *hsensorScb, HsensorListener *listener)
+{
+ if (listener->notifyCallback == NULL) {
+ return;
+ }
+ SensorNotifyInfo notifyInfo = {
+ .type = hsensorScb->type,
+ .data = hsensorScb->dataBuf,
+ .dataLen = hsensorScb->dataPackSize,
+ .option = hsensorScb->decisionPara.option,
+ .timestamp = hsensorScb->sysTick,
+ };
+ listener->notifyCallback(¬ifyInfo, listener->notifyArg);
+}
+
+static void HsensorDataServiceNotifyAll(HsensorScb *hsensorScb)
+{
+ HsensorListener *listenerIndex = NULL;
+ osal_list_for_each_entry(listenerIndex, &hsensorScb->listenerList, list)
+ {
+ if (listenerIndex->status != SENSOR_LISTENER_WORKING) {
+ continue;
+ }
+ HsensorDataServiceNotifyResultData(hsensorScb, listenerIndex);
+ HsensorDataServiceNotifyData(hsensorScb, listenerIndex);
+ }
+}
+
+uint32_t HsensorDataServiceProcess(enum SensorTypeTag type)
+{
+ HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(type);
+ uint32_t samplingInterval = hsensorScb->decisionPara.period;
+ CHECK_NULL_PTR_RETURN_VALUE(hsensorScb, samplingInterval);
+ CHECK_NULL_PTR_RETURN_VALUE(hsensorScb->batchDataBuf, samplingInterval);
+ HILOG_DEBUG(HILOG_MODULE_SEN,
+ "hsensor type:%d period:%u batch:%u option:%u mode:%d reportPeriod:%u",
+ type,
+ hsensorScb->decisionPara.period,
+ hsensorScb->decisionPara.batch,
+ hsensorScb->decisionPara.option,
+ hsensorScb->decisionPara.mode,
+ hsensorScb->reportPeriod);
+ int32_t dataLen = hsensorScb->hsensor->read(hsensorScb->batchDataBuf, hsensorScb->batchDataBufSize);
+ if (dataLen <= 0) {
+ HILOG_WARN(HILOG_MODULE_SEN, "type: %d read data fail.", type);
+ return samplingInterval;
+ }
+ hsensorScb->batchCount++;
+ hsensorScb->dataPackSize += dataLen;
+ hsensorScb->batchDataBuf += dataLen;
+ hsensorScb->batchDataBufSize -= dataLen;
+ HILOG_DEBUG(HILOG_MODULE_SEN, "batchCount: %d dataLen: %d", hsensorScb->batchCount, dataLen);
+ if (hsensorScb->batchCount < hsensorScb->decisionPara.batch) {
+ return samplingInterval;
+ }
+ hsensorScb->sysTick = SensorUtilsGetRtcTimeMs();
+ HsensorDataServiceNotifyAll(hsensorScb);
+ hsensorScb->batchDataBuf = hsensorScb->dataBuf;
+ hsensorScb->batchDataBufSize = hsensorScb->dataBufSize;
+ hsensorScb->dataPackSize = 0;
+ hsensorScb->batchCount = 0;
+ return samplingInterval;
+}
+
+int32_t HsensorDataServiceDeInit(enum SensorTypeTag type)
+{
+ return SENSOR_OK;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: hsensor mgr
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef HSENSOR_MGR_SERVICE_H
+#define HSENSOR_MGR_SERVICE_H
+#include "sensor_typedef.h"
+#include "soc_osal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define HSENSOR_LISTENER_NAME_MAX_LEN 64
+
+typedef enum {
+ SENSOR_LISTENER_REGISTER,
+ SENSOR_LISTENER_UNREGISTER,
+ SENSOR_LISTENER_ENABLE,
+ SENSOR_LISTENER_DISABLE,
+ SENSOR_LISTENER_WORKING,
+} HsensorListenerStatus;
+
+typedef struct {
+ enum SensorTypeTag type;
+ uint8_t *data;
+ uint32_t dataLen;
+ uint32_t option;
+ uint64_t timestamp;
+} SensorNotifyInfo;
+
+typedef void (*NotifyCallback)(const SensorNotifyInfo *info, void *notifyArg);
+
+typedef struct {
+ struct osal_list_head list;
+ char name[HSENSOR_LISTENER_NAME_MAX_LEN];
+ enum SensorTypeTag type;
+ uint16_t bufIndex; /* listener的缓存索引 */
+ uint16_t sampleCnt; /* 传感器的采样次数 */
+ uint16_t dispatchCnt; /* 数据分发间隔次数 */
+ uint32_t notifyPeriod; /* listener数据需求周期 ms */
+ SensorPara openParam;
+ NotifyCallback notifyCallback;
+ void *notifyArg;
+ RecordDataCallback resultDataCb;
+ HsensorListenerStatus status;
+} HsensorListener;
+
+typedef enum {
+ HSENSOR_SCB_UNINITED,
+ HSENSOR_SCB_INITED,
+} HsensorScbStatus;
+
+typedef struct HsensorScb {
+ struct osal_list_head list; /* scb link point */
+ struct osal_list_head listenerList; /* scb listener head */
+ uint16_t listenerNum;
+ enum SensorTypeTag type; /* scb sensor type */
+ HsensorScbStatus status;
+ uint8_t *dataBuf; /* scb buffer */
+ uint8_t *batchDataBuf; /* scb batch buffer */
+ uint32_t batchDataBufSize; /* scb batch buffer length */
+ uint32_t dataBufSize; /* scb buffer length */
+ uint32_t dataPackSize; /* scb data len for every batch */
+ uint32_t dataBufIndex; /* scb buffer current index */
+ uint32_t reportPeriod; /* 传感器采样的上报周期 */
+ uint32_t batchCount; /* scb buffer current index */
+ uint64_t sysTick;
+ SensorPara decisionPara; /* scb decision param */
+ Hsensor *hsensor;
+} HsensorScb;
+
+typedef struct {
+ struct osal_list_head hsensorScbHead;
+ uint32_t hsensorScbNum;
+ uint8_t *dataBuf;
+ uint8_t *dataDispatchBuf;
+ bool inited;
+} HsensorMgr;
+
+int32_t HsensorMgrInit(void);
+int32_t HsensorMgrRegister(const Hsensor *hsensor);
+int32_t HsensorMgrRegisterListener(HsensorListener *listener);
+int32_t HsensorMgrUnRegisterListener(HsensorListener *listener);
+int32_t HsensorMgrOpenListener(HsensorListener *listener);
+int32_t HsensorMgrCloseListener(HsensorListener *listener);
+HsensorScb *HsensorMgrHsensorScbFind(const enum SensorTypeTag type);
+
+int32_t HsensorMgrIoctl(enum SensorTypeTag type, SensorIoctlCmd cmd, void *data, uint32_t len);
+int32_t HsensorMgrReadData(const enum SensorTypeTag type, const uint64_t *ts);
+void HsensorMgrPrintListener(enum SensorTypeTag type);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: hsensor mgr impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "hsensormgr_service.h"
+#include <string.h>
+#include <stdbool.h>
+#include "securec.h"
+#include "sensor_log.h"
+#include "sensor_common.h"
+#include "sensor_memory.h"
+#include "sensor_tmsg.h"
+#include "sensor_utils.h"
+#include "sensor_para_decision.h"
+
+#define HSENSOR_SCB_MAX_NUM 10
+#define HSENSORMGR_MAX_DATA_LEN (1024 * 1024)
+static HsensorMgr g_hsensormgr = {0};
+static HsensorScb g_hsensorScb[HSENSOR_SCB_MAX_NUM] = {0};
+
+static HsensorMgr *HsensorMgrGetInstance(void)
+{
+ return &g_hsensormgr;
+}
+
+static int32_t HsensorScbMallocDataBuffer(HsensorScb *hsensorScb)
+{
+ if (hsensorScb == NULL) {
+ return SENSOR_ERROR;
+ }
+ uint32_t dataBufSize = hsensorScb->hsensor->caps.sampleElementlen * hsensorScb->decisionPara.batch;
+ if (dataBufSize >= HSENSORMGR_MAX_DATA_LEN) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "hsensorScb dataBufSize :%u is invalid.", dataBufSize);
+ return SENSOR_ERROR;
+ }
+ hsensorScb->dataBuf = SensorMalloc(dataBufSize);
+ if (hsensorScb->dataBuf == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "hsensorScb MallocDataBuffer NULL.");
+ return SENSOR_ERROR;
+ }
+ hsensorScb->batchDataBuf = hsensorScb->dataBuf;
+ hsensorScb->batchDataBufSize = dataBufSize;
+ hsensorScb->dataBufSize = dataBufSize;
+ return SENSOR_OK;
+}
+
+static int32_t HsensorScbFreeDataBuffer(HsensorScb *hsensorScb)
+{
+ if (hsensorScb == NULL) {
+ return SENSOR_ERROR;
+ }
+ if (hsensorScb->dataBuf == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "hsensorScb cDataBuffer NULL.");
+ return SENSOR_ERROR;
+ }
+ SensorFree(hsensorScb->dataBuf);
+ hsensorScb->dataBuf = NULL;
+ hsensorScb->batchDataBuf = NULL;
+ hsensorScb->batchDataBufSize = 0;
+ hsensorScb->dataBufSize = 0;
+ hsensorScb->dataPackSize = 0;
+ return SENSOR_OK;
+}
+
+static void HsensorScbInit(HsensorScb *hsensorScb)
+{
+ if (hsensorScb == NULL) {
+ return;
+ }
+ OSAL_INIT_LIST_HEAD(&(hsensorScb->list));
+ OSAL_INIT_LIST_HEAD(&(hsensorScb->listenerList));
+ hsensorScb->listenerNum = 0;
+ hsensorScb->type = SENSOR_TYPE_NONE;
+ hsensorScb->status = HSENSOR_SCB_UNINITED;
+ hsensorScb->dataBuf = NULL;
+ hsensorScb->dataBufSize = 0;
+ hsensorScb->dataBufIndex = 0;
+ hsensorScb->dataPackSize = 0;
+ hsensorScb->batchCount = 0;
+ SensorPara initDecisionPara = {0};
+ hsensorScb->decisionPara = initDecisionPara;
+ hsensorScb->hsensor = NULL;
+}
+
+static HsensorScb *HsensorScbRequest(uint16_t scbNum)
+{
+ return (scbNum >= HSENSOR_SCB_MAX_NUM) ? NULL : (&g_hsensorScb[scbNum]);
+}
+
+HsensorScb *HsensorMgrHsensorScbFind(const enum SensorTypeTag type)
+{
+ HsensorMgr *hsensorMgr = HsensorMgrGetInstance();
+ HsensorScb *hsensorScbIndex = NULL;
+ osal_list_for_each_entry(hsensorScbIndex, &hsensorMgr->hsensorScbHead, list)
+ {
+ if (type == hsensorScbIndex->type) {
+ return hsensorScbIndex;
+ }
+ }
+ return NULL;
+}
+
+int32_t HsensorMgrInit(void)
+{
+ HILOG_DEBUG(HILOG_MODULE_SEN, "in.");
+ HsensorMgr *hsensorMgr = HsensorMgrGetInstance();
+ if (hsensorMgr->inited) {
+ return SENSOR_OK;
+ }
+ OSAL_INIT_LIST_HEAD(&(hsensorMgr->hsensorScbHead));
+ hsensorMgr->hsensorScbNum = 0;
+ hsensorMgr->dataBuf = NULL;
+ hsensorMgr->dataDispatchBuf = NULL;
+ for (uint16_t i = 0; i < HSENSOR_SCB_MAX_NUM; i++) {
+ HsensorScb *hsensorScb = HsensorScbRequest(i);
+ HsensorScbInit(hsensorScb);
+ }
+ hsensorMgr->inited = true;
+ HILOG_DEBUG(HILOG_MODULE_SEN, "out.");
+ return SENSOR_OK;
+}
+
+/* ******************************************************************************
+ 函 数 名 : HsensormgrCheckListener
+ 功能描述 : 检查listener是否存在于该scb中
+ 输入参数 : None
+ 输出参数 : None
+ 返 回 值 : None
+****************************************************************************** */
+static int32_t HsensormgrCheckListener(const HsensorScb *hsensorScb, const HsensorListener *listener)
+{
+ HsensorListener *listenerIndex = NULL;
+ osal_list_for_each_entry(listenerIndex, &hsensorScb->listenerList, list)
+ {
+ if (memcmp(listenerIndex->name, listener->name, (uint32_t)HSENSOR_LISTENER_NAME_MAX_LEN) == 0) {
+ return SENSOR_OK;
+ }
+ }
+ return SENSOR_ERROR;
+}
+
+int32_t HsensorMgrRegisterListener(HsensorListener *listener)
+{
+ HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(listener->type);
+ if (hsensorScb == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", listener->type);
+ return SENSOR_HSENSOR_SCB_NULL;
+ }
+ if (HsensormgrCheckListener(hsensorScb, listener) == SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "hsensorListener name %s already exits.", listener->name);
+ return SENSOR_HSENSOR_SCB_LISTENER_EXIST;
+ }
+
+ osal_list_add(&listener->list, &hsensorScb->listenerList);
+ hsensorScb->listenerNum++;
+ listener->status = SENSOR_LISTENER_REGISTER;
+ HILOG_DEBUG(HILOG_MODULE_SEN,
+ "hsensorListener name: %s type:%d listenerNum:%u",
+ listener->name,
+ listener->type,
+ hsensorScb->listenerNum);
+ return SENSOR_OK;
+}
+
+int32_t HsensorMgrUnRegisterListener(HsensorListener *listener)
+{
+ HILOG_DEBUG(HILOG_MODULE_SEN, "UnRegister hsensor type %d listener name:%s.",
+ listener->type, listener->name);
+ /* 表示vsensor 注册的 Listener 不需要 UnRegister */
+ if (listener->notifyCallback != NULL) {
+ return SENSOR_OK;
+ }
+ HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(listener->type);
+ if (hsensorScb == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", listener->type);
+ return SENSOR_HSENSOR_SCB_NULL;
+ }
+ if (HsensormgrCheckListener(hsensorScb, listener) != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "hsensorListener name %s not exits.", listener->name);
+ return SENSOR_HSENSOR_SCB_LISTENER_NOT_EXIST;
+ }
+
+ osal_list_del(&listener->list);
+ hsensorScb->listenerNum--;
+ listener->status = SENSOR_LISTENER_UNREGISTER;
+ SensorUtilsFreeListener(listener);
+ HILOG_DEBUG(HILOG_MODULE_SEN, "UnRegister listenerNum: :%u", hsensorScb->listenerNum);
+ return SENSOR_OK;
+}
+
+static void HsensormgrCheckOpenParam(SensorPara *openParam)
+{
+ if (openParam->period == 0) {
+ openParam->period = SENSOR_PARA_REALTIME_PERIOD_MIN;
+ }
+ if (openParam->batch == 1 || openParam->batch == 0) {
+ openParam->batch = 1;
+ openParam->mode = SENSOR_MODE_REALTIME;
+ }
+ if (openParam->mode == SENSOR_MODE_REALTIME && (openParam->period < SENSOR_PARA_REALTIME_PERIOD_MIN)) {
+ openParam->period = SENSOR_PARA_REALTIME_PERIOD_MIN;
+ }
+}
+
+static void HsensormgrOpenCheckOpenParam(HsensorListener *listener, SensorPara *openParam, uint32_t *reportPeriod)
+{
+ HsensormgrCheckOpenParam(openParam);
+ listener->notifyPeriod = openParam->period * openParam->batch;
+ *reportPeriod = listener->notifyPeriod;
+}
+
+/* ******************************************************************************
+ 函 数 名 : HsensormgrCalculateGCD
+ 功能描述 : 计算最大公约数
+ 输入参数 : None
+ 输出参数 : None
+ 返 回 值 : None
+****************************************************************************** */
+static uint32_t HsensormgrCalculateGCD(uint32_t a, uint32_t b)
+{
+ uint32_t c;
+ while (b) {
+ c = b;
+ b = a % b;
+ a = c;
+ }
+ return a;
+}
+
+/* ******************************************************************************
+ 函 数 名 : HsensormgrUpdateOpenParam
+ 功能描述 : 更新 scb的 openParam ,遍历所有enable的listener
+ 输入参数 : None
+ 输出参数 : None
+ 返 回 值 : None
+****************************************************************************** */
+static bool HsensormgrUpdateOpenParam(HsensorScb *hsensorScb, SensorPara *openParam, uint32_t reportPeriod)
+{
+ uint8_t openMode = 0;
+ uint32_t reportPeriodGcd = reportPeriod;
+ uint32_t notifyPeriodTemp = 0;
+ bool needOpen = false;
+ uint32_t periodMin = openParam->period;
+ uint32_t notifyPeriodMin = reportPeriod;
+ HsensorListener *listenerIndex = NULL;
+ osal_list_for_each_entry(listenerIndex, &hsensorScb->listenerList, list)
+ {
+ HsensorMgrPrintListener(listenerIndex->type);
+ if (listenerIndex->status == SENSOR_LISTENER_WORKING || listenerIndex->status == SENSOR_LISTENER_ENABLE) {
+ openMode |= (1 << listenerIndex->openParam.mode);
+ periodMin = (periodMin > listenerIndex->openParam.period) ? listenerIndex->openParam.period : periodMin;
+ notifyPeriodMin =
+ (notifyPeriodMin > listenerIndex->notifyPeriod) ? listenerIndex->notifyPeriod : notifyPeriodMin;
+ if (needOpen == false) {
+ reportPeriodGcd = listenerIndex->notifyPeriod;
+ }
+ reportPeriodGcd = HsensormgrCalculateGCD(reportPeriodGcd, notifyPeriodTemp);
+ notifyPeriodTemp = notifyPeriodMin;
+ needOpen = true;
+ }
+ }
+ if (openMode & (1 << SENSOR_MODE_REALTIME)) {
+ openParam->mode = SENSOR_MODE_REALTIME;
+ } else {
+ openParam->mode = SENSOR_MODE_FIFO_MODE;
+ }
+ openParam->period = periodMin;
+ if (periodMin != 0) {
+ openParam->batch = reportPeriodGcd / periodMin;
+ } else {
+ openParam->batch = 0;
+ }
+ HILOG_DEBUG(HILOG_MODULE_SEN, "needOpen: %d", needOpen);
+ return needOpen;
+}
+
+/* ******************************************************************************
+ 函 数 名 : HsensormgrUpdateListener
+ 功能描述 : 更新 listener ,并决定是否重新打开 sensor
+ 1. 如果不重启sensor,只需要更新该listener的相关参数即可
+ 2. 如果需要重启sensor,则需要更新所有listener的相关参数
+ 参考6.22未合入的提交
+ 输入参数 : None
+ 输出参数 : None
+ 返 回 值 : None
+****************************************************************************** */
+int32_t HsensormgrUpdateListener(HsensorScb *hsensorScb, HsensorListener *listener, const SensorPara *openParam)
+{
+ if (memcmp(&(hsensorScb->decisionPara), openParam, sizeof(SensorPara)) == 0) {
+ /* 说明不需要重启,更新此次listener的相关参数 */
+ if (hsensorScb->reportPeriod != 0) {
+ listener->sampleCnt = 0;
+ listener->dispatchCnt = listener->notifyPeriod / hsensorScb->reportPeriod;
+ return SENSOR_OK;
+ } else {
+ HILOG_ERROR(HILOG_MODULE_SEN,
+ "hsensorListener name %s type %d open error, batch %d period %d.",
+ listener->name,
+ listener->type,
+ openParam->batch,
+ openParam->period);
+ return SENSOR_HSENSOR_SCB_REPORT_PERIOD_ZERO;
+ }
+ }
+ /* 需要重启hensor */
+ (void)memcpy_s(&hsensorScb->decisionPara, sizeof(SensorPara), openParam, sizeof(SensorPara));
+ hsensorScb->reportPeriod = openParam->batch * openParam->period;
+ if (hsensorScb->reportPeriod == 0) {
+ HILOG_ERROR(HILOG_MODULE_SEN,
+ "hsensorListener name %s type %d open error, batch %d period %d.",
+ listener->name,
+ listener->type,
+ openParam->batch,
+ openParam->period);
+ return SENSOR_HSENSOR_SCB_REPORT_PERIOD_ZERO;
+ }
+
+ int32_t ret = hsensorScb->hsensor->open(&hsensorScb->decisionPara);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN,
+ "hsensorListener name %s type %d open error, batch %u period %u.",
+ listener->name,
+ listener->type,
+ openParam->batch,
+ openParam->period);
+ return ret;
+ }
+ HILOG_INFO(HILOG_MODULE_SEN,
+ "hsensor name %s type %d open batch %u period %u.",
+ hsensorScb->hsensor->name,
+ hsensorScb->type,
+ hsensorScb->decisionPara.batch,
+ hsensorScb->decisionPara.period);
+ return SENSOR_OK;
+}
+
+/* ******************************************************************************
+ 函 数 名 : HsensorMgrOpenListener
+ 功能描述 : 1.检查open 参数 2.更新所有listener 3.打开对应的hsensor
+
+ 输入参数 : None
+ 输出参数 : None
+ 返 回 值 : None
+****************************************************************************** */
+int32_t HsensorMgrOpenListener(HsensorListener *listener)
+{
+ if (listener == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "listener is null.", listener->type);
+ return SENSOR_HSENSOR_LISTENER_NULL;
+ }
+ HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(listener->type);
+ if (hsensorScb == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", listener->type);
+ return SENSOR_HSENSOR_SCB_NULL;
+ }
+ // 检查该 listener 是否 存在于scb中
+ if (HsensormgrCheckListener(hsensorScb, listener) != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "hsensorListener name %s type %d not exits.", listener->name, listener->type);
+ return SENSOR_HSENSOR_SCB_LISTENER_NOT_EXIST;
+ }
+ listener->status = SENSOR_LISTENER_ENABLE;
+ SensorPara openParam = listener->openParam;
+ uint32_t reportPeriod = 0;
+ /* 计算此次listener的reportPeriod等 */
+ HILOG_DEBUG(HILOG_MODULE_SEN,
+ "open listener para period: %u batch: %u mode: %d option: %u ",
+ openParam.period,
+ openParam.batch,
+ openParam.mode,
+ openParam.option);
+ HsensormgrOpenCheckOpenParam(listener, &openParam, &reportPeriod);
+ /* 遍历所有使能的listener,更新全局的openParam */
+ if (HsensormgrUpdateOpenParam(hsensorScb, &openParam, reportPeriod) == false) {
+ HILOG_INFO(
+ HILOG_MODULE_SEN, "hsensor not need open, listener open type %d name %s ", listener->type, listener->name);
+ return SENSOR_OK;
+ }
+ if (HsensormgrUpdateListener(hsensorScb, listener, &openParam) != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "hsensorListener name %s type %d open error.", listener->name, listener->type);
+ return SENSOR_ERROR;
+ }
+ listener->status = SENSOR_LISTENER_WORKING;
+ uint32_t taskId = SensorUtilsGetRegisteredTaskId(listener->type);
+ if (taskId != SENSOR_FAILURE) { // 已经创建线程
+ return SENSOR_OK;
+ }
+ int32_t ret = HsensorScbMallocDataBuffer(hsensorScb);
+ if (ret != SENSOR_OK) {
+ return ret;
+ }
+ ret = SensorTaskCreateHsensorTask(hsensorScb->hsensor);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "hsensor type %d CreateHsensorTask failed.", listener->type);
+ return ret;
+ }
+ HILOG_INFO(HILOG_MODULE_SEN, "hsensor listener open type %d name %s ", listener->type, listener->name);
+ return SENSOR_OK;
+}
+
+/* ******************************************************************************
+ 函 数 名 : HsensormgrCloseCheckOpenParam
+ 功能描述 : 遍历剩余的使能的listener,找到一个开启的openParam
+ 输入参数 : None
+ 输出参数 : None
+ 返 回 值 : None
+****************************************************************************** */
+static void HsensormgrCloseCheckOpenParam(HsensorScb *hsensorScb, SensorPara *openParam, uint32_t *reportPeriod)
+{
+ HsensorListener *listenerIndex = NULL;
+ osal_list_for_each_entry(listenerIndex, &hsensorScb->listenerList, list)
+ {
+ if (listenerIndex->status == SENSOR_LISTENER_WORKING || listenerIndex->status == SENSOR_LISTENER_ENABLE) {
+ (void)memcpy_s(openParam, sizeof(SensorPara), &listenerIndex->openParam, sizeof(SensorPara));
+ HsensormgrCheckOpenParam(openParam);
+ *reportPeriod = openParam->period * openParam->batch;
+ break;
+ }
+ }
+}
+
+int32_t HsensorMgrCloseListener(HsensorListener *listener)
+{
+ if (listener == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "close listener is null.");
+ return SENSOR_HSENSOR_LISTENER_NULL;
+ }
+ HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(listener->type);
+ if (hsensorScb == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", listener->type);
+ return SENSOR_HSENSOR_SCB_NULL;
+ }
+ if (HsensormgrCheckListener(hsensorScb, listener) != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "hsensorListener name %s not exits.", listener->name);
+ return SENSOR_ERROR;
+ }
+ uint32_t reportPeriod = 0;
+ SensorPara openParam = {.period = 0, .batch = 0, .mode = SENSOR_MODE_REALTIME, .option = 0};
+ listener->status = SENSOR_LISTENER_DISABLE;
+
+ HsensormgrCloseCheckOpenParam(hsensorScb, &openParam, &reportPeriod);
+ /* 遍历所有使能的listener,更新全局的openParam */
+ if (HsensormgrUpdateOpenParam(hsensorScb, &openParam, reportPeriod) == false) {
+ /* 不存在打开的listener,关闭hsensor */
+ int32_t ret = SensorTaskDestroyHsensorTask(hsensorScb->type);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "hsensor type %d Destroy failed.", hsensorScb->type);
+ }
+ ret = HsensorScbFreeDataBuffer(hsensorScb);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "hsensor type %d FreeData failed.", hsensorScb->type);
+ return ret;
+ }
+ memset_s(&hsensorScb->decisionPara, sizeof(SensorPara), 0, sizeof(SensorPara));
+ hsensorScb->hsensor->close();
+ HILOG_INFO(HILOG_MODULE_SEN, "hsensor name %s type %d close.", hsensorScb->hsensor->name, hsensorScb->type);
+ return SENSOR_OK;
+ } else {
+ /* 还存在使能的listener, */
+ if (HsensormgrUpdateListener(hsensorScb, listener, &openParam) != SENSOR_OK) {
+ HILOG_ERROR(
+ HILOG_MODULE_SEN, "hsensorListener name %s type %d open error.", listener->name, listener->type);
+ return SENSOR_ERROR;
+ }
+ }
+ HILOG_INFO(HILOG_MODULE_SEN, "hsensor listener close type %d name %s ", listener->type, listener->name);
+ return SENSOR_OK;
+}
+
+static int32_t HsensorMgrSensorOpen(const Sensor *sensor, const SensorPara *openPara)
+{
+ HILOG_INFO(HILOG_MODULE_SEN,
+ "SensorOpen hsensor type:%d name:%s period:%u batch:%u option:%u mode:%d",
+ sensor->sensorInfo.type,
+ sensor->sensorInfo.name,
+ openPara->period,
+ openPara->batch,
+ openPara->option,
+ openPara->mode);
+ int32_t ret = SENSOR_OK;
+ HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(sensor->sensorInfo.type);
+ if (hsensorScb == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", sensor->sensorInfo.type);
+ return SENSOR_HSENSOR_SCB_NULL;
+ }
+ HsensorMgrPrintListener(sensor->sensorInfo.type);
+ HsensorListener *listenerIndex = NULL;
+ osal_list_for_each_entry(listenerIndex, &hsensorScb->listenerList, list)
+ {
+ HILOG_DEBUG(HILOG_MODULE_SEN,
+ "hsensor type: %d openParam:%d name:%s",
+ sensor->sensorInfo.type,
+ SensorParaIsClear(&listenerIndex->openParam),
+ listenerIndex->name);
+ /* 表示vsensor 注册的 Listener 不需要 APP open */
+ if (listenerIndex->notifyCallback != NULL) {
+ continue;
+ }
+ if (SensorParaIsClear(&listenerIndex->openParam)) {
+ SensorParaCopy(&listenerIndex->openParam, openPara);
+ }
+ ret = HsensorMgrOpenListener(listenerIndex);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "hsensor type %d OpenListener failed.", sensor->sensorInfo.type);
+ }
+ }
+ return SENSOR_OK;
+}
+
+static int32_t HsensorMgrSensorClose(const Sensor *sensor)
+{
+ int32_t ret = SENSOR_OK;
+ HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(sensor->sensorInfo.type);
+ if (hsensorScb == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", sensor->sensorInfo.type);
+ return SENSOR_HSENSOR_SCB_NULL;
+ }
+ HsensorMgrPrintListener(sensor->sensorInfo.type);
+ HsensorListener *listenerIndex = NULL;
+ HsensorListener *listenerIndexTemp = NULL;
+ osal_list_for_each_entry_safe(listenerIndex, listenerIndexTemp, &hsensorScb->listenerList, list)
+ {
+ ret = HsensorMgrCloseListener(listenerIndex);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "hsensor type %d CloseListener failed.", sensor->sensorInfo.type);
+ }
+
+ ret = HsensorMgrUnRegisterListener(listenerIndex);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "UnRegisterListener fail.");
+ }
+ }
+ HILOG_DEBUG(HILOG_MODULE_SEN, "close sensorInfo type : %d", sensor->sensorInfo.type);
+ return SENSOR_OK;
+}
+
+/* samplingInterval Indicates the sensor data sampling interval to set, in millisecond. 数据采样间隔 */
+/* reportInterval Indicates the sensor data reporting interval, in millisecond.数据上报间隔 */
+static int32_t HsensorMgrSensorSetBatch(Sensor *sensor, int64_t samplingInterval, int64_t reportInterval)
+{
+ HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(sensor->sensorInfo.type);
+ if (hsensorScb == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", sensor->sensorInfo.type);
+ return SENSOR_HSENSOR_SCB_NULL;
+ }
+ if (samplingInterval < SENSOR_PARA_REALTIME_PERIOD_MIN || samplingInterval > SENSOR_PARA_REALTIME_PERIOD_MAX) {
+ HILOG_ERROR(HILOG_MODULE_SEN,
+ "samplingInterval is max: %d to min: %d, samplingInterval: %d ",
+ SENSOR_PARA_REALTIME_PERIOD_MAX,
+ SENSOR_PARA_REALTIME_PERIOD_MIN,
+ samplingInterval,
+ reportInterval);
+ return SENSOR_HSENSOR_PERIOD_BATCH_ERR;
+ }
+ uint32_t batch = reportInterval / samplingInterval;
+ uint32_t maxBatchCount = hsensorScb->hsensor->caps.maxBatchCount;
+ if (batch < SENSOR_PARA_BATCH_MIN || batch > maxBatchCount) {
+ HILOG_ERROR(
+ HILOG_MODULE_SEN, "batch is max: %d to min: %d, batch: %u ", maxBatchCount, SENSOR_PARA_BATCH_MIN, batch);
+ return SENSOR_HSENSOR_PERIOD_BATCH_ERR;
+ }
+ sensor->sensorInfo.openPara.period = samplingInterval;
+ sensor->sensorInfo.openPara.batch = batch;
+ HILOG_INFO(HILOG_MODULE_SEN,
+ "samplingInterval: %lld reportInterval: %lld batch: %u",
+ samplingInterval,
+ reportInterval,
+ batch);
+ return SENSOR_OK;
+}
+
+static int32_t HsensorMgrSensorSetMode(Sensor *sensor, int32_t mode)
+{
+ HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(sensor->sensorInfo.type);
+ if (hsensorScb == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", sensor->sensorInfo.type);
+ return SENSOR_HSENSOR_SCB_NULL;
+ }
+ if (mode < 0 || mode >= SENSOR_MODE_MAX) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "type %d set mode error %d", hsensorScb->type, mode);
+ return SENSOR_HSENSOR_MODE_ERR;
+ }
+ sensor->sensorInfo.openPara.mode = mode;
+ HILOG_INFO(HILOG_MODULE_SEN, "mode: %d ", mode);
+ return SENSOR_OK;
+}
+
+static int32_t HsensorMgrSensorSetOption(Sensor *sensor, uint32_t option)
+{
+ HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(sensor->sensorInfo.type);
+ if (hsensorScb == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", sensor->sensorInfo.type);
+ return SENSOR_HSENSOR_SCB_NULL;
+ }
+ hsensorScb->decisionPara.option = option;
+ return SENSOR_OK;
+}
+
+static HsensorListener *HsensorMgrHlistenerInit(const Sensor *sensor, RecordDataCallback cb)
+{
+ HsensorListener *listener = SensorUtilsRequestListener();
+ if (listener == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "type %d listener get fail.", sensor->sensorInfo.type);
+ return NULL;
+ }
+ errno_t err = memset_s(listener, sizeof(HsensorListener), 0, sizeof(HsensorListener));
+ if (err != EOK) {
+ SensorUtilsFreeListener(listener);
+ HILOG_ERROR(HILOG_MODULE_SEN, "ResultCallback memset failed! type:%d", sensor->sensorInfo.type);
+ return NULL;
+ }
+ err = strcat_s(listener->name, sizeof(listener->name), "APP");
+ if (err != EOK) {
+ SensorUtilsFreeListener(listener);
+ HILOG_ERROR(HILOG_MODULE_SEN, "ResultCallback init name strcat full! type:%d", sensor->sensorInfo.type);
+ return NULL;
+ }
+ err = strcat_s(listener->name, sizeof(listener->name), sensor->sensorInfo.name);
+ if (err != EOK) {
+ SensorUtilsFreeListener(listener);
+ HILOG_ERROR(HILOG_MODULE_SEN, "ResultCallback init name strcat full! type:%d", sensor->sensorInfo.type);
+ return NULL;
+ }
+ listener->type = sensor->sensorInfo.type;
+ listener->resultDataCb = cb;
+ HILOG_INFO(HILOG_MODULE_SEN,
+ "HlistenerInit hsensor type:%d name:%s period:%u batch:%u option:%u mode:%u",
+ sensor->sensorInfo.type,
+ sensor->sensorInfo.name,
+ sensor->sensorInfo.openPara.period,
+ sensor->sensorInfo.openPara.batch,
+ sensor->sensorInfo.openPara.option,
+ sensor->sensorInfo.openPara.mode);
+ return listener;
+}
+
+static int32_t HsensorMgrSensorRegisterResultCallback(const Sensor *sensor, RecordDataCallback cb)
+{
+ HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(sensor->sensorInfo.type);
+ if (hsensorScb == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb or simpleName get fail.", sensor->sensorInfo.type);
+ return SENSOR_HSENSOR_SCB_NULL;
+ }
+ HsensorListener *listener = HsensorMgrHlistenerInit(sensor, cb);
+ if (listener == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "RegisterListener failed! type:%d", sensor->sensorInfo.type);
+ return SENSOR_HSENSOR_LISTENER_NULL;
+ }
+ int32_t ret = HsensorMgrRegisterListener(listener);
+ if (ret != SENSOR_OK) {
+ SensorUtilsFreeListener(listener);
+ HILOG_ERROR(HILOG_MODULE_SEN, "RegisterListener failed! type:%d", sensor->sensorInfo.type);
+ return ret;
+ }
+ return SENSOR_OK;
+}
+
+static int32_t HsensorMgrSensorUnregisterResultCallback(const Sensor *sensor, RecordDataCallback cb)
+{
+ HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(sensor->sensorInfo.type);
+ if (hsensorScb == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", sensor->sensorInfo.type);
+ return SENSOR_HSENSOR_SCB_NULL;
+ }
+ HsensorListener *listenerIndex = NULL;
+ HsensorListener *listener = NULL;
+ osal_list_for_each_entry(listenerIndex, &hsensorScb->listenerList, list)
+ {
+ if (listenerIndex->resultDataCb == cb) {
+ listener = listenerIndex;
+ HILOG_INFO(HILOG_MODULE_SEN, "hsensor type %d RecordDataCallback exits.", sensor->sensorInfo.type);
+ break;
+ }
+ }
+ if (listener == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "HsensorListener get fail.");
+ return SENSOR_HSENSOR_LISTENER_NULL;
+ }
+ int32_t ret = HsensorMgrCloseListener(listener);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "hsensor type %d CloseListener failed.", sensor->sensorInfo.type);
+ }
+ ret = HsensorMgrUnRegisterListener(listener);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "UnRegisterListener fail.");
+ }
+ HILOG_INFO(HILOG_MODULE_SEN, "hsensor type: %d Unregister Success", sensor->sensorInfo.type);
+ return SENSOR_OK;
+}
+
+static int32_t HsensorMgrSensorCalibrate(const Sensor *sensor, void *para, uint32_t len)
+{
+ HILOG_WARN(HILOG_MODULE_SEN, "unsupport");
+ return SENSOR_OK;
+}
+
+static int32_t HsensorMgrSensorSelfTest(const Sensor *sensor, void *para, uint32_t len)
+{
+ HILOG_WARN(HILOG_MODULE_SEN, "unsupport");
+ return SENSOR_OK;
+}
+
+static int32_t HsensorMgrSensorIoctl(const Sensor *sensor, SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+ if (cmd >= SENSOR_IOCTL_MAX || cmd < SENSOR_IOCTL_SET_PARA) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "invalid command!");
+ return SENSOR_ERROR;
+ }
+ HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(sensor->sensorInfo.type);
+ if (hsensorScb->hsensor->ioctl == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "invalid ioctl function!");
+ return SENSOR_ERROR;
+ }
+ return hsensorScb->hsensor->ioctl(cmd, data, len);
+}
+
+static int32_t HsensorMgrSensorRegisterProc(const Hsensor *hsensor)
+{
+ Sensor *sensor = SensorUtilsRequestSensor(hsensor->type);
+ if (sensor == NULL || sensor->sensorInfo.state != SENSOR_STATE_IDLE) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "sensor type %d name %s request fail.", hsensor->type, hsensor->name);
+ return SENSOR_ERROR;
+ }
+ sensor->sensorInfo.type = hsensor->type;
+ sensor->sensorInfo.name = hsensor->name;
+ SensorParaDefaultInit(&sensor->sensorInfo.openPara);
+ sensor->open = HsensorMgrSensorOpen;
+ sensor->close = HsensorMgrSensorClose;
+ sensor->setBatch = HsensorMgrSensorSetBatch;
+ sensor->setMode = HsensorMgrSensorSetMode;
+ sensor->setOption = HsensorMgrSensorSetOption;
+ sensor->registerResultCallback = HsensorMgrSensorRegisterResultCallback;
+ sensor->unregisterResultCallback = HsensorMgrSensorUnregisterResultCallback;
+ sensor->calibrate = HsensorMgrSensorCalibrate;
+ sensor->selfTest = HsensorMgrSensorSelfTest;
+ sensor->ioctl = HsensorMgrSensorIoctl;
+ HILOG_INFO(HILOG_MODULE_SEN,
+ "hsensor type:%d name:%s period:%u batch:%u option:%u mode:%d",
+ hsensor->type,
+ hsensor->name,
+ sensor->sensorInfo.openPara.period,
+ sensor->sensorInfo.openPara.batch,
+ sensor->sensorInfo.openPara.option,
+ sensor->sensorInfo.openPara.mode);
+ return SENSOR_OK;
+}
+
+int32_t HsensorMgrRegister(const Hsensor *hsensor)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "register hsensor type:%d name:%s ", hsensor->type, hsensor->name);
+ HsensorMgr *hsensorMgr = HsensorMgrGetInstance();
+ if (!hsensorMgr->inited && (HsensorMgrInit() != SENSOR_OK)) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "hsensorMgr inited failed.");
+ return SENSOR_ERROR;
+ }
+ HsensorScb *hsensorScbIndex = NULL;
+ osal_list_for_each_entry(hsensorScbIndex, &hsensorMgr->hsensorScbHead, list)
+ {
+ if (hsensorScbIndex->type == hsensor->type) {
+ HILOG_WARN(HILOG_MODULE_SEN, "hsensor type %d already exits.", hsensorScbIndex->type);
+ return SENSOR_HSENSOR_REGISTER_TYPE_DUPLICATE;
+ }
+ }
+ HsensorScb *hsensorScb = HsensorScbRequest(hsensorMgr->hsensorScbNum);
+ if (hsensorScb == NULL || hsensorScb->status != HSENSOR_SCB_UNINITED) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "hsensorScb type %d name %s request fail.", hsensor->type, hsensor->name);
+ return SENSOR_ERROR;
+ }
+ if (hsensor->init() != SENSOR_OK) {
+ hsensor->deinit();
+ HILOG_ERROR(HILOG_MODULE_SEN, "hsensor type %d name %s init fail.", hsensor->type, hsensor->name);
+ return SENSOR_ERROR;
+ }
+ hsensorScb->hsensor = (Hsensor *)hsensor;
+ hsensorScb->type = hsensor->type;
+ int32_t ret = SensorUtilsAddHsensorList(hsensorScb);
+ if (ret != SENSOR_OK) {
+ hsensorScb->type = SENSOR_TYPE_NONE;
+ hsensor->deinit();
+ HILOG_ERROR(
+ HILOG_MODULE_SEN, "hsensor type %d name %s SensorUtilsAddSensorList fail", hsensor->type, hsensor->name);
+ return SENSOR_ERROR;
+ }
+ ret = HsensorMgrSensorRegisterProc(hsensor);
+ if (ret != SENSOR_OK) {
+ hsensorScb->type = SENSOR_TYPE_NONE;
+ hsensor->deinit();
+ HILOG_ERROR(HILOG_MODULE_SEN, "hsensor type %d name %s SensorRegisterProc fail", hsensor->type, hsensor->name);
+ return SENSOR_ERROR;
+ }
+ hsensorScb->status = HSENSOR_SCB_INITED;
+ osal_list_add(&hsensorScb->list, &hsensorMgr->hsensorScbHead);
+ hsensorMgr->hsensorScbNum++;
+ HILOG_INFO(HILOG_MODULE_SEN, "register hsensor type %d name %s success.", hsensor->type, hsensor->name);
+ return SENSOR_OK;
+}
+
+int32_t HsensorMgrIoctl(enum SensorTypeTag type, SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+ HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(type);
+ if (hsensorScb == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", type);
+ return SENSOR_ERROR;
+ }
+ if (hsensorScb->hsensor != NULL && hsensorScb->hsensor->ioctl != NULL) {
+ return hsensorScb->hsensor->ioctl(cmd, data, len);
+ }
+ return SENSOR_ERROR;
+}
+
+void HsensorMgrPrintListener(enum SensorTypeTag type)
+{
+ HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(type);
+ if (hsensorScb == NULL) {
+ return;
+ }
+ HILOG_INFO(HILOG_MODULE_SEN, "type: %d listenerNum:%u", type, hsensorScb->listenerNum);
+ HsensorListener *listenerIndex = NULL;
+ osal_list_for_each_entry(listenerIndex, &hsensorScb->listenerList, list)
+ {
+ HILOG_INFO(HILOG_MODULE_SEN,
+ "type %d name %s period %u batch %u mode %d option %u status %d",
+ listenerIndex->type,
+ listenerIndex->name,
+ listenerIndex->openParam.period,
+ listenerIndex->openParam.batch,
+ listenerIndex->openParam.mode,
+ listenerIndex->openParam.option,
+ listenerIndex->status);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor interface impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include "securec.h"
+#include "sensor_thread.h"
+#include "sensor_common.h"
+#include "sensor_if.h"
+#include "sensor_manager.h"
+
+struct SensorInterfaceContext {
+ bool inited;
+ MutexId mutex;
+};
+
+struct SensorInterfaceContext g_sensorInterfaceCtx = {
+ .inited = false,
+ .mutex = NULL,
+};
+
+static void GetSensorDeviceMethods(struct SensorInterface *device);
+
+const struct SensorInterface *NewSensorInterfaceInstance(void)
+{
+ HILOG_ERROR(HILOG_MODULE_SEN, "in");
+ g_sensorInterfaceCtx.mutex = SensorMutexCreate(NULL);
+ CHECK_NULL_PTR_RETURN_VALUE(g_sensorInterfaceCtx.mutex, NULL);
+ SensorMutexLock(g_sensorInterfaceCtx.mutex);
+ static struct SensorInterface sensorDevInstance;
+ if (g_sensorInterfaceCtx.inited) {
+ SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+ return &sensorDevInstance;
+ }
+ int32_t ret = SensorMgrInit();
+ if (ret != SENSOR_OK) {
+ SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+ HILOG_ERROR(HILOG_MODULE_SEN, "SensorMgrInit failed");
+ return NULL;
+ }
+
+ // Construct device interface instance
+ GetSensorDeviceMethods(&sensorDevInstance);
+
+ g_sensorInterfaceCtx.inited = true;
+ SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+ HILOG_DEBUG(HILOG_MODULE_APP, "Get sensor instance success");
+ return &sensorDevInstance;
+}
+
+int32_t FreeSensorInterfaceInstance(void)
+{
+ SensorMutexLock(g_sensorInterfaceCtx.mutex);
+ if (!g_sensorInterfaceCtx.inited) {
+ SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+ return SENSOR_OK;
+ }
+ SensorMgrDeInit();
+ g_sensorInterfaceCtx.inited = false;
+ SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+ SensorMutexDestroy(&g_sensorInterfaceCtx.mutex);
+ return SENSOR_OK;
+}
+
+static int32_t GetSensorInfo(struct SensorInformation **sensorInfo, int32_t *count)
+{
+ HILOG_DEBUG(HILOG_MODULE_SEN, "enter");
+ SensorMutexLock(g_sensorInterfaceCtx.mutex);
+ int32_t ret = SensorMgrGetAllSensors(sensorInfo, count);
+ SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+ return ret;
+}
+
+static int32_t EnableSensor(int32_t sensorTypeId)
+{
+ HILOG_DEBUG(HILOG_MODULE_SEN, "enter");
+ SensorMutexLock(g_sensorInterfaceCtx.mutex);
+ int32_t ret = SensorMgrEnable(sensorTypeId);
+ SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+ return ret;
+}
+
+static int32_t DisableSensor(int32_t sensorTypeId)
+{
+ HILOG_DEBUG(HILOG_MODULE_SEN, "enter");
+ SensorMutexLock(g_sensorInterfaceCtx.mutex);
+ int32_t ret = SensorMgrDisable(sensorTypeId);
+ SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+ return ret;
+}
+
+static int32_t RegisterSensorDataCb(int32_t sensorTypeId, RecordDataCallback cb)
+{
+ HILOG_DEBUG(HILOG_MODULE_SEN, "enter sensorId:%d", sensorTypeId);
+ SensorMutexLock(g_sensorInterfaceCtx.mutex);
+ int32_t ret = SensorMgrRegistDataCallback(sensorTypeId, cb);
+ SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+ return ret;
+}
+
+static int32_t UnregisterSensorDataCb(int32_t sensorTypeId, RecordDataCallback cb)
+{
+ HILOG_DEBUG(HILOG_MODULE_SEN, "enter sensorId:%d", sensorTypeId);
+ SensorMutexLock(g_sensorInterfaceCtx.mutex);
+ int32_t ret = SensorMgrUnregistDataCallback(sensorTypeId, cb);
+ SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+ return ret;
+}
+
+static int32_t SetSensorBatch(int32_t sensorTypeId, int64_t samplingInterval, int64_t interval)
+{
+ HILOG_DEBUG(HILOG_MODULE_SEN, "enter");
+ SensorMutexLock(g_sensorInterfaceCtx.mutex);
+ int32_t ret = SensorMgrSetBatch(sensorTypeId, samplingInterval, interval);
+ SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+ return ret;
+}
+
+static int32_t SetSensorMode(int32_t sensorTypeId, int32_t mode)
+{
+ HILOG_DEBUG(HILOG_MODULE_SEN, "enter");
+ SensorMutexLock(g_sensorInterfaceCtx.mutex);
+ int32_t ret = SensorMgrSetMode(sensorTypeId, mode);
+ SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+ return ret;
+}
+
+static int32_t SetSensorOption(int32_t sensorTypeId, uint32_t option)
+{
+ HILOG_DEBUG(HILOG_MODULE_SEN, "enter");
+ SensorMutexLock(g_sensorInterfaceCtx.mutex);
+ int32_t ret = SensorMgrSetOption(sensorTypeId, option);
+ SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+ return ret;
+}
+
+static int32_t SensorIfGetData(int32_t sensorTypeId, SensorData *sensorData)
+{
+ HILOG_DEBUG(HILOG_MODULE_SEN, "enter");
+ return SensorMgrGetData(sensorTypeId, sensorData);
+}
+
+void GetSensorDeviceMethods(struct SensorInterface *device)
+{
+ CHECK_NULL_PTR_RETURN(device);
+ device->GetAllSensors = GetSensorInfo;
+ device->Enable = EnableSensor;
+ device->Disable = DisableSensor;
+ device->SetBatch = SetSensorBatch;
+ device->SetMode = SetSensorMode;
+ device->SetOption = SetSensorOption;
+ device->Register = RegisterSensorDataCb;
+ device->Unregister = UnregisterSensorDataCb;
+ device->GetSensorData = SensorIfGetData;
+}
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor mgr
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "sensor_manager.h"
+#include "sensor_common.h"
+#include "sensor_utils.h"
+#include "sensor_if.h"
+#include "hsensormgr_service.h"
+#include "vsensormgr_service.h"
+
+int32_t SensorMgrInit(void)
+{
+ int32_t ret = HsensorMgrInit();
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "HsensorMgrInit err!", ret);
+ return ret;
+ }
+ ret = VsensorMgrInit();
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "VsensorMgrInit err!", ret);
+ return ret;
+ }
+ SensorUtilsInit();
+ return SENSOR_OK;
+}
+
+int32_t SensorMgrDeInit(void)
+{
+ return SENSOR_OK;
+}
+
+int32_t SensorMgrRegistHsensor(const Hsensor *sensor)
+{
+ int32_t ret = SensorUtilsHsensorCheck(sensor);
+ if (ret != SENSOR_OK) {
+ HILOG_INFO(HILOG_MODULE_SEN, "hsensor:%d entry check err!", sensor->type);
+ return ret;
+ }
+ return HsensorMgrRegister(sensor);
+}
+
+int32_t SensorMgrRegistVsensor(const Vsensor *sensor)
+{
+ int32_t ret = SensorUtilsVsensorCheck(sensor);
+ if (ret != SENSOR_OK) {
+ HILOG_INFO(HILOG_MODULE_SEN, "vsensor:%d entry check err!", sensor->type);
+ return ret;
+ }
+ return VsensorMgrRegister(sensor);
+}
+
+int32_t SensorMgrGetAllSensors(struct SensorInformation **sensorInfo, int32_t *count)
+{
+ return SensorUtilsGetAllSensors(sensorInfo, count);
+}
+
+int32_t SensorMgrEnable(int32_t sensorTypeId)
+{
+ Sensor *sensor = SensorUtilsFindSensor(sensorTypeId);
+ if (sensor == NULL || sensor->open == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[INF] sensor NULL!\n");
+ return SENSOR_ENTRY_PARA_ERROR;
+ }
+ return sensor->open(sensor, &sensor->sensorInfo.openPara);
+}
+
+int32_t SensorMgrDisable(int32_t sensorTypeId)
+{
+ Sensor *sensor = SensorUtilsFindSensor(sensorTypeId);
+ if (sensor == NULL || sensor->close == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[INF] sensor NULL!\n");
+ return SENSOR_ENTRY_PARA_ERROR;
+ }
+ return sensor->close(sensor);
+}
+
+int32_t SensorMgrSetBatch(int32_t sensorTypeId, int64_t samplingInterval, int64_t reportInterval)
+{
+ Sensor *sensor = SensorUtilsFindSensor(sensorTypeId);
+ if (sensor == NULL || sensor->setBatch == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[INF] sensor NULL!\n");
+ return SENSOR_ENTRY_PARA_ERROR;
+ }
+ return sensor->setBatch(sensor, samplingInterval, reportInterval);
+}
+
+int32_t SensorMgrSetMode(int32_t sensorTypeId, int32_t mode)
+{
+ Sensor *sensor = SensorUtilsFindSensor(sensorTypeId);
+ if (sensor == NULL || sensor->setMode == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[INF] sensor NULL!\n");
+ return SENSOR_ENTRY_PARA_ERROR;
+ }
+ return sensor->setMode(sensor, mode);
+}
+
+int32_t SensorMgrSetOption(int32_t sensorTypeId, uint32_t option)
+{
+ Sensor *sensor = SensorUtilsFindSensor(sensorTypeId);
+ if (sensor == NULL || sensor->setOption == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[INF] sensor NULL!\n");
+ return SENSOR_ENTRY_PARA_ERROR;
+ }
+ return sensor->setOption(sensor, option);
+}
+
+int32_t SensorMgrRegistDataCallback(int32_t sensorTypeId, RecordDataCallback cb)
+{
+ Sensor *sensor = SensorUtilsFindSensor(sensorTypeId);
+ CHECK_NULL_PTR_RETURN_VALUE(sensor, SENSOR_ENTRY_PARA_ERROR);
+ CHECK_NULL_PTR_RETURN_VALUE(sensor->registerResultCallback, SENSOR_ENTRY_PARA_ERROR);
+ return sensor->registerResultCallback(sensor, cb);
+}
+
+int32_t SensorMgrUnregistDataCallback(int32_t sensorTypeId, RecordDataCallback cb)
+{
+ Sensor *sensor = SensorUtilsFindSensor(sensorTypeId);
+ CHECK_NULL_PTR_RETURN_VALUE(sensor, SENSOR_ENTRY_PARA_ERROR);
+ CHECK_NULL_PTR_RETURN_VALUE(sensor->unregisterResultCallback, SENSOR_ENTRY_PARA_ERROR);
+ return sensor->unregisterResultCallback(sensor, cb);
+}
+
+int32_t SensorMgrGetData(int32_t sensorTypeId, SensorData *sensorData)
+{
+ Sensor *sensor = SensorUtilsFindSensor(sensorTypeId);
+ CHECK_NULL_PTR_RETURN_VALUE(sensor, SENSOR_ENTRY_PARA_ERROR);
+ CHECK_NULL_PTR_RETURN_VALUE(sensor->ioctl, SENSOR_ENTRY_PARA_ERROR);
+ return sensor->ioctl(sensor, SENSOR_IOCTL_GET_SENSOR_DATA, sensorData, sizeof(SensorData));
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor task
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef SENSOR_TASK_H
+#define SENSOR_TASK_H
+
+#include <stdbool.h>
+#include "sensor_typedef.h"
+#include "sensor_thread.h"
+#include "sensor_msgqueue.h"
+#include "soc_osal.h"
+
+typedef struct {
+ struct osal_list_head list; /* SensorTaskCfg link point */
+ uint32_t taskId;
+ SensorThreadCfg threadCfg;
+ SensorMsgQueueCfg msgQueueCfg;
+ bool runningFlag;
+ ThreadId *task;
+ bool taskExited;
+} SensorTaskCfg;
+
+typedef enum {
+ SENSOR_TASK_PRIORITY_HIGH = osPriorityHigh,
+ SENSOR_TASK_PRIORITY_MIDDLE = osPriorityNormal,
+ SENSOR_TASK_PRIORITY_LOW = osPriorityLow6
+} SensorTaskPriority;
+
+#define SENSORMGR_TASK_MSG_QUEUE_LENGTH 32
+#define TASK_MSG_QUEUE_LENGTH_DEFAULT 32
+#ifdef JS_ENABLE
+#define HSENSOR_TASK_STACK_SIZE 8192
+#define VSENSOR_TASK_STACK_SIZE 8192
+#else
+#define HSENSOR_TASK_STACK_SIZE 2048
+#define VSENSOR_TASK_STACK_SIZE 4096
+#endif
+
+#define SENSOR_TASK_CREATE_OK_WAIT_TIMEOUT 1000 // ms
+#define SENSOR_TASK_CREATE_TICK_TIME 50 // ms
+
+#define SENSOR_TASK_MAX_CNT 10
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int32_t SensorTaskInit(void);
+
+/* 创建vsensor任务 */
+int32_t SensorTaskCreateVsensorTask(const Vsensor *vsensor);
+
+/* 创建hsensor任务 */
+int32_t SensorTaskCreateHsensorTask(const Hsensor *hsensor);
+
+/* 销毁vsensor任务 */
+int32_t SensorTaskDestroyVsensorTask(enum SensorTypeTag type);
+
+/* 销毁hsensor任务 */
+int32_t SensorTaskDestroyHsensorTask(enum SensorTypeTag type);
+
+/* 获取任务消息队列句柄 */
+SensorMsgQueueCfg *SensorTaskGetTaskMsgqueueHandle(uint32_t taskId);
+
+/* 判断任务运行状态(true和false) */
+bool SensorTaskGetRunningFlag(uint32_t taskId);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor msg
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef SENSOR_TMSG_H
+#define SENSOR_TMSG_H
+
+#include "sensor_typedef.h"
+#include "sensor_task.h"
+
+/* FA线程间消息定义 */
+typedef enum {
+ SENSOR_TMSG_INVALID = 0,
+
+ /* 虚拟vsensor管理消息 */
+ SENSOR_TMSG_HSENSOR_DATA_UPDATE,
+ SENSOR_TMSG_VSENSOR_DATA_UPDATE,
+ SENSOR_TMSG_VSENSOR_REG_EVENT,
+ SENSOR_TMSG_VSENSOR_OPEN_EVENT,
+ SENSOR_TMSG_VSENSOR_CLOSE_EVENT,
+ SENSOR_TMSG_VSENSOR_RELY_OPEN_EVENT,
+ SENSOR_TMSG_VSENSOR_RELY_CLOSE_EVENT,
+
+ SENSOR_TMSG_MAX_ID
+} SensorTmsgId;
+
+typedef struct {
+ SensorTmsgId id;
+ uintptr_t value;
+ uint64_t ts;
+ void *info;
+ uint32_t infoSize;
+} SensorTmsg;
+
+typedef struct {
+ SensorTmsgId tmsgId;
+ int32_t (*tmsgProc)(const SensorTmsg* tmsg);
+} SensorTmsgProcMap;
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int32_t SensorTmsgSend(uint32_t taskId, SensorTmsg* tmsg);
+int32_t SensorTmsgRecv(uint32_t taskId, SensorTmsg* tmsg);
+int32_t SensorTmsgFree(SensorTmsg* tmsg);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor task impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "sensor_task.h"
+#include "sensor_tmsg.h"
+#include "vsensor_task_mgr.h"
+#include "securec.h"
+#include "sensor_log.h"
+#include "sensor_utils.h"
+#include "sensor_common.h"
+#include "sensor_memory.h"
+#include "hsensor_data_service.h"
+
+static void VsensorTaskFunc(void* param);
+static void HsensorTaskFunc(void* param);
+
+typedef struct {
+ struct osal_list_head sensorTaskHead; // SensorTaskCfg
+ uint32_t sensorTaskNum;
+ bool sensorTaskId[SENSOR_TASK_MAX_CNT];
+} SensorTaskContext;
+
+static SensorTaskContext g_sensorTaskCxt = {
+ .sensorTaskNum = 0,
+ .sensorTaskId = {0}
+};
+
+static SensorTaskContext *SensorTaskGetInstance(void)
+{
+ return &g_sensorTaskCxt;
+}
+
+int32_t SensorTaskInit(void)
+{
+ SensorTaskContext *ctx = SensorTaskGetInstance();
+ OSAL_INIT_LIST_HEAD(&(ctx->sensorTaskHead));
+ ctx->sensorTaskNum = 0;
+ return SENSOR_OK;
+}
+
+SensorMsgQueueCfg *SensorTaskGetTaskMsgqueueHandle(uint32_t taskId)
+{
+ SensorTaskContext *ctx = SensorTaskGetInstance();
+ SensorTaskCfg *sensorTaskIndex = NULL;
+ osal_list_for_each_entry(sensorTaskIndex, &ctx->sensorTaskHead, list)
+ {
+ if (taskId == sensorTaskIndex->taskId) {
+ return &(sensorTaskIndex->msgQueueCfg);
+ }
+ }
+ return NULL;
+}
+
+static void SensorTaskAddTaskCfg(SensorTaskCfg *sensorTask)
+{
+ SensorTaskContext *ctx = SensorTaskGetInstance();
+ osal_list_add(&sensorTask->list, &ctx->sensorTaskHead);
+ ctx->sensorTaskNum++;
+ HILOG_INFO(HILOG_MODULE_SEN, "[task] add task:%u!", sensorTask->taskId);
+}
+
+static SensorTaskCfg *SensorTaskFindTaskCfg(enum SensorTypeTag type)
+{
+ SensorTaskContext *ctx = SensorTaskGetInstance();
+ uint32_t taskId = SensorUtilsGetRegisteredTaskId(type);
+ if (taskId == SENSOR_FAILURE) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] TaskSync not found taskId type:%d", type);
+ return NULL;
+ }
+ SensorTaskCfg *sensorTaskIndex = NULL;
+ SensorTaskCfg *sensorTask = NULL;
+ osal_list_for_each_entry(sensorTaskIndex, &ctx->sensorTaskHead, list)
+ {
+ if (sensorTaskIndex->taskId != taskId) {
+ continue;
+ }
+ sensorTask = sensorTaskIndex;
+ break;
+ }
+ return sensorTask;
+}
+
+static void SensorTaskRemoveTaskCfg(SensorTaskCfg *sensorTask)
+{
+ CHECK_NULL_PTR_RETURN(sensorTask);
+ SensorTaskContext *ctx = SensorTaskGetInstance();
+ SensorTaskCfg *sensorTaskIndex = NULL;
+ bool found = false;
+ osal_list_for_each_entry(sensorTaskIndex, &ctx->sensorTaskHead, list)
+ {
+ if (sensorTask->taskId == sensorTaskIndex->taskId) {
+ found = true;
+ }
+ }
+ if (found) {
+ g_sensorTaskCxt.sensorTaskId[sensorTask->taskId] = false;
+ osal_list_del(&sensorTask->list);
+ ctx->sensorTaskNum--;
+ }
+ SensorFree(sensorTask);
+}
+
+bool SensorTaskGetRunningFlag(uint32_t taskId)
+{
+ SensorTaskContext *ctx = SensorTaskGetInstance();
+ SensorTaskCfg *sensorTaskIndex = NULL;
+ osal_list_for_each_entry(sensorTaskIndex, &ctx->sensorTaskHead, list)
+ {
+ if (taskId == sensorTaskIndex->taskId) {
+ return sensorTaskIndex->runningFlag;
+ }
+ }
+ HILOG_INFO(HILOG_MODULE_SEN, "[task] run_flag cannot find task:%d!", taskId);
+ return false;
+}
+
+static void VsensorTaskFunc(void* param)
+{
+ HILOG_DEBUG(HILOG_MODULE_SEN, "[task] in");
+ SensorTmsg tmsg = {0};
+ SensorTaskCfg *taskCfg = (SensorTaskCfg *)param;
+ CHECK_NULL_PTR_RETURN(taskCfg);
+ int32_t ret = VsensorTaskMgrInit(taskCfg->taskId);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[task] VsensorTaskMgrInit FAIL! ret:0x%X, taskId:%d", ret, taskCfg->taskId);
+ return;
+ }
+ taskCfg->runningFlag = true;
+ while (taskCfg->runningFlag) {
+ int32_t ret = SensorTmsgRecv(taskCfg->taskId, &tmsg);
+ if ((ret != SENSOR_OK) || (tmsg.id == SENSOR_TMSG_INVALID)) {
+ SensorTmsgFree(&tmsg);
+ continue;
+ }
+ (void)VsensorTaskMgrMsgProcess(taskCfg->taskId, &tmsg);
+
+ SensorTmsgFree(&tmsg);
+ }
+ (void)VsensorTaskMgrDeInit(taskCfg->taskId);
+ taskCfg->taskExited = true;
+ HILOG_DEBUG(HILOG_MODULE_SEN, "[task] out");
+}
+
+static void HsensorTaskFunc(void* param)
+{
+ SensorTaskCfg *taskCfg = (SensorTaskCfg *)param;
+ CHECK_NULL_PTR_RETURN(taskCfg);
+ enum SensorTypeTag type = SensorUtilsGetRegisteredType(taskCfg->taskId);
+ CHECK_SENSOR_TYPE_ILLEGAL_RETURN(type);
+ int32_t ret = HsensorDataServiceInit(type);
+ if (ret != SENSOR_OK) {
+ return;
+ }
+ taskCfg->runningFlag = true;
+
+ while (taskCfg->runningFlag) {
+ uint32_t delayTime = HsensorDataServiceProcess(type);
+ osDelay(delayTime);
+ }
+ (void)HsensorDataServiceDeInit(type);
+ taskCfg->taskExited = true;
+}
+
+/* 创建任务接口(异步接口) */
+static int32_t SensorCreateTaskAsync(SensorTaskCfg *taskCfg, enum SensorTypeTag type)
+{
+ /* 创建消息队列 */
+ int32_t ret = SensorMsgQueueCreate(&(taskCfg->msgQueueCfg), (uint32_t)(taskCfg->taskId));
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] msg queue create FAIL! ret:0x%X, taskId:%d", ret, taskCfg->taskId);
+ return SENSOR_MSG_QUEUE_CREATE_FAIL;
+ }
+ SensorUtilsRegisterTaskTable(type, taskCfg->taskId);
+ /* 创建工作线程 */
+ ThreadId *task = SensorThreadCreate((const SensorThreadCfg*)(&(taskCfg->threadCfg)));
+ if (task == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] task create FAIL! task:%d", taskCfg->taskId);
+ SensorUtilsUnRegisterTaskTable(type, taskCfg->taskId);
+ return SENSOR_TASK_CREATE_FAIL;
+ }
+ taskCfg->task = task;
+ taskCfg->taskExited = false;
+
+ HILOG_INFO(HILOG_MODULE_SEN, "[SYS] task:%d prio:%d.", taskCfg->taskId, taskCfg->threadCfg.priority);
+ return SENSOR_OK;
+}
+
+/* 销毁任务接口(同步接口,阻塞等待任务销毁完成) */
+static void SensorTaskDestoryTaskSync(SensorTaskCfg *taskCfg)
+{
+ if (taskCfg->taskExited) {
+ return;
+ }
+
+ taskCfg->runningFlag = false;
+
+ uint16_t taskReadyWait = 0;
+ while ((taskReadyWait < SENSOR_TASK_CREATE_OK_WAIT_TIMEOUT) && (!taskCfg->taskExited)) {
+ osal_msleep(SENSOR_TASK_CREATE_TICK_TIME);
+ taskReadyWait += SENSOR_TASK_CREATE_TICK_TIME;
+ }
+ SensorMsgQueueDelete((uint32_t)(taskCfg->msgQueueCfg.queueId));
+}
+
+static int32_t GetSensorTaskId(SensorTaskCfg *taskCfg)
+{
+ SensorTaskContext *ctx = SensorTaskGetInstance();
+ for (int32_t index = 0; index < SENSOR_TASK_MAX_CNT; ++index) {
+ if (!ctx->sensorTaskId[index]) {
+ taskCfg->taskId = index;
+ ctx->sensorTaskId[index] = true;
+ return index;
+ }
+ }
+ return SENSOR_FAILURE;
+}
+
+static SensorTaskCfg *SensorTaskCreateVsensorTaskCfg(const Vsensor *vsensor)
+{
+ SensorTaskCfg *taskCfg = (SensorTaskCfg *)SensorMalloc(sizeof(SensorTaskCfg));
+ CHECK_NULL_PTR_RETURN_VALUE(taskCfg, NULL);
+ SensorTaskContext *ctx = SensorTaskGetInstance();
+ OSAL_INIT_LIST_HEAD(&(taskCfg->list));
+ SensorThreadCfg threadCfg = {
+ vsensor->name,
+ VSENSOR_TASK_STACK_SIZE,
+ SENSOR_TASK_PRIORITY_HIGH,
+ VsensorTaskFunc,
+ taskCfg
+ };
+ taskCfg->threadCfg = threadCfg;
+ SensorMsgQueueCfg msgQueueCfg = {
+ vsensor->name,
+ SENSORMGR_TASK_MSG_QUEUE_LENGTH,
+ sizeof(SensorTmsg),
+ 0,
+ 0
+ };
+ taskCfg->msgQueueCfg = msgQueueCfg;
+ taskCfg->runningFlag = false;
+ taskCfg->task = NULL;
+ taskCfg->taskId = GetSensorTaskId(taskCfg);
+ if (taskCfg->taskId < 0) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "no free taskID!");
+ return NULL;
+ }
+ SensorTaskAddTaskCfg(taskCfg);
+ HILOG_INFO(HILOG_MODULE_SEN, "TaskSync create type:%d name:%s", vsensor->type, threadCfg.name);
+ return taskCfg;
+}
+
+static SensorTaskCfg *SensorTaskCreateHsensorTaskCfg(const Hsensor *hsensor)
+{
+ SensorTaskCfg *taskCfg = (SensorTaskCfg *)SensorMalloc(sizeof(SensorTaskCfg));
+ CHECK_NULL_PTR_RETURN_VALUE(taskCfg, NULL);
+ SensorTaskContext *ctx = SensorTaskGetInstance();
+ OSAL_INIT_LIST_HEAD(&(taskCfg->list));
+ SensorThreadCfg threadCfg = {
+ hsensor->name,
+ HSENSOR_TASK_STACK_SIZE,
+ SENSOR_TASK_PRIORITY_HIGH,
+ HsensorTaskFunc,
+ taskCfg
+ };
+ taskCfg->threadCfg = threadCfg;
+ SensorMsgQueueCfg msgQueueCfg = {
+ hsensor->name,
+ SENSORMGR_TASK_MSG_QUEUE_LENGTH,
+ sizeof(SensorTmsg),
+ 0,
+ 0
+ };
+ taskCfg->msgQueueCfg = msgQueueCfg;
+ taskCfg->runningFlag = false;
+ taskCfg->task = NULL;
+ taskCfg->taskId = GetSensorTaskId(taskCfg);
+ if (taskCfg->taskId < 0) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "no free taskID!");
+ return NULL;
+ }
+ SensorTaskAddTaskCfg(taskCfg);
+ return taskCfg;
+}
+
+/* 创建Vsensor算法任务(同步接口,阻塞等待任务创建完成) */
+int32_t SensorTaskCreateVsensorTask(const Vsensor *vsensor)
+{
+ SensorTaskContext *ctx = SensorTaskGetInstance();
+ SensorTaskCfg *taskCfg = SensorTaskCreateVsensorTaskCfg(vsensor);
+ CHECK_NULL_PTR_RETURN_VALUE(taskCfg, SENSOR_ERROR);
+ int32_t ret = SensorCreateTaskAsync(taskCfg, vsensor->type);
+ if (ret != SENSOR_OK) {
+ SensorTaskRemoveTaskCfg(taskCfg);
+ HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] TaskSync create FAIL! ret:0x%X, type:%d", ret, vsensor->type);
+ return SENSOR_TASK_CREATE_FAIL;
+ }
+ SensorUtilsRegisterTaskTable(vsensor->type, taskCfg->taskId);
+ return SENSOR_OK;
+}
+
+/* 销毁vsensor任务 */
+int32_t SensorTaskDestroyVsensorTask(enum SensorTypeTag type)
+{
+ SensorTaskCfg *sensorTask = SensorTaskFindTaskCfg(type);
+ if (sensorTask == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] vsensorTask not found type:%d", type);
+ return SENSOR_ERROR;
+ }
+ SensorTaskDestoryTaskSync(sensorTask);
+ SensorUtilsUnRegisterTaskTable(type, sensorTask->taskId);
+ SensorTaskRemoveTaskCfg(sensorTask);
+ return SENSOR_OK;
+}
+
+int32_t SensorTaskCreateHsensorTask(const Hsensor *hsensor)
+{
+ SensorTaskContext *ctx = SensorTaskGetInstance();
+ SensorTaskCfg *taskCfg = SensorTaskCreateHsensorTaskCfg(hsensor);
+ CHECK_NULL_PTR_RETURN_VALUE(taskCfg, SENSOR_ERROR);
+ int32_t ret = SensorCreateTaskAsync(taskCfg, hsensor->type);
+ if (ret != SENSOR_OK) {
+ SensorTaskRemoveTaskCfg(taskCfg);
+ HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] TaskSync create FAIL! ret:0x%X, type:%d", ret, hsensor->type);
+ return SENSOR_TASK_CREATE_FAIL;
+ }
+ HILOG_INFO(HILOG_MODULE_SEN, "[SYS] TaskSync create sensorTaskNum:%u, type:%d", ctx->sensorTaskNum, hsensor->type);
+ return SENSOR_OK;
+}
+
+/* 销毁hsensor任务 */
+int32_t SensorTaskDestroyHsensorTask(enum SensorTypeTag type)
+{
+ SensorTaskCfg *sensorTask = SensorTaskFindTaskCfg(type);
+ if (sensorTask == NULL) {
+ HILOG_DEBUG(HILOG_MODULE_SEN, "[SYS] hsensorTask not found type:%d", type);
+ return SENSOR_ERROR;
+ }
+ SensorTaskDestoryTaskSync(sensorTask);
+ SensorUtilsUnRegisterTaskTable(type, sensorTask->taskId);
+ SensorTaskRemoveTaskCfg(sensorTask);
+ return SENSOR_OK;
+}
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor tmsg impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "sensor_tmsg.h"
+#include "sensor_typedef.h"
+#include "sensor_msgqueue.h"
+#include "sensor_task.h"
+#include "securec.h"
+#include "sensor_memory.h"
+#include "sensor_common.h"
+#include "sensor_log.h"
+
+#define FTMSG_WAIT_FOREVER 0xFFFFFFFF /* 接收消息永久等待 */
+
+int32_t SensorTmsgSend(uint32_t taskId, SensorTmsg *tmsg)
+{
+ uint32_t tmsgSize = (uint32_t)sizeof(SensorTmsg);
+
+ if (tmsg == NULL) {
+ return SENSOR_SEND_TMSG_NULL;
+ }
+
+ if (SensorTaskGetRunningFlag(taskId) == false) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "taskId :%u NOT RUNNING", taskId);
+ return SENSOR_SEND_TMSG_DEST_NOT_RUNNING;
+ }
+
+ SensorMsgQueueCfg *msgqueueHandle = SensorTaskGetTaskMsgqueueHandle(taskId);
+ if (msgqueueHandle == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "msgqueueHandle null");
+ return SENSOR_SEND_TMSG_MSG_QUEUE_NULL;
+ }
+
+ int32_t ret = SensorMsgQueueWriteCopy(msgqueueHandle->queueId, tmsg, tmsgSize, 0);
+ if (ret != 0) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "SensorMsgQueueWriteCopy error ret:0x%X\n", ret);
+ return ret;
+ }
+
+ return SENSOR_OK;
+}
+
+int32_t SensorTmsgRecv(uint32_t taskId, SensorTmsg *tmsg)
+{
+ uint32_t tmsgSize = (uint32_t)sizeof(SensorTmsg);
+
+ if (tmsg == NULL) {
+ return SENSOR_RECV_TMSG_NULL;
+ }
+ SensorMsgQueueCfg *msgqueueHandle = SensorTaskGetTaskMsgqueueHandle(taskId);
+ if (msgqueueHandle == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "SensorTmsgRecv msgqueueHandle NULL");
+ return SENSOR_RECV_TMSG_MSG_QUEUE_NULL;
+ }
+ int32_t ret = SensorMsgQueueReadCopy(msgqueueHandle->queueId, tmsg, &tmsgSize, FTMSG_WAIT_FOREVER);
+ if (ret != 0) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "SensorTmsgRecv error ret:0x%X\n", ret);
+ return SENSOR_RECV_TMSG_ERR;
+ }
+ return SENSOR_OK;
+}
+
+int32_t SensorTmsgFree(SensorTmsg *tmsg)
+{
+ if (tmsg == NULL) {
+ return SENSOR_FREE_TMSG_NULL;
+ }
+
+ if (tmsg->info != NULL) {
+ SensorFree(tmsg->info);
+ }
+
+ memset_s(tmsg, sizeof(SensorTmsg), 0, sizeof(SensorTmsg));
+
+ return SENSOR_OK;
+}
--- /dev/null
+/*\r
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.\r
+ * Description: sensor memory\r
+ * Author: Media Software Group\r
+ * Create: 2025-06-06\r
+ */\r
+\r
+#ifndef SENSOR_MEMORY_H\r
+#define SENSOR_MEMORY_H\r
+\r
+#include <stdlib.h>\r
+\r
+#define MEM_ALLOC_MIN_SIZE 1\r
+#define MEM_ALLOC_MAX_SIZE 10000 // ????10k\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif /* __cplusplus */\r
+\r
+void *SensorMalloc(unsigned long size);\r
+void SensorFree(void *addr);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+\r
+ \r
+#endif /* SENSOR_MEMORY_H */\r
--- /dev/null
+/*\r
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.\r
+ * Description: sensor msgqueue\r
+ * Author: Media Software Group\r
+ * Create: 2025-06-06\r
+ */\r
+\r
+#ifndef SENSOR_MSGQUEUE_H\r
+#define SENSOR_MSGQUEUE_H\r
+\r
+#include <stdint.h>\r
+#include "soc_osal.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif /* __cplusplus */\r
+\r
+typedef struct {\r
+ const char *name;\r
+ uint16_t queueLen;\r
+ uint16_t maxMsgSize;\r
+ unsigned long queueId;\r
+ uint32_t flags;\r
+} SensorMsgQueueCfg;\r
+\r
+int32_t SensorMsgQueueCreate(SensorMsgQueueCfg *cfg, uint32_t taskId);\r
+int32_t SensorMsgQueueWriteCopy(unsigned int queueId, void *bufferAddr, unsigned int bufferSize, unsigned int timeout);\r
+int32_t SensorMsgQueueReadCopy(unsigned int queueId, void *bufferAddr, unsigned int *bufferSize, unsigned int timeout);\r
+void SensorMsgQueueDelete(unsigned int queueId);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+\r
+#endif /* SENSOR_MSGQUEUE_H */\r
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor para
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+#ifndef SENSOR_PARA_DECISION_H
+#define SENSOR_PARA_DECISION_H
+
+#include "sensor_typedef.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define SENSOR_PARA_REALTIME_PERIOD_MIN 1
+#define SENSOR_PARA_REALTIME_PERIOD_MAX 1000000
+#define SENSOR_PARA_BATCH_MIN 1
+#define SENSOR_PARA_BATCH_MAX 100
+
+void SensorParaDefaultInit(SensorPara *sensorPara);
+void SensorParaClear(SensorPara *para);
+void SensorParaCopy(SensorPara *dest, const SensorPara *src);
+int32_t SensorOpenParaDecision(
+ enum SensorTypeTag type, const SensorPara *cur, const SensorPara *require, SensorPara *result);
+int32_t SensorOptionDecision(enum SensorTypeTag type, int32_t cur, int32_t require);
+bool SensorParaIsClear(const SensorPara *para);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SENSOR_PARA_DECISION_H */
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor state
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef SENSOR_STATE_H
+#define SENSOR_STATE_H
+
+#include "sensor_typedef.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+void SensorSetState(enum SensorTypeTag type, SensorState state);
+void SensorSetPara(enum SensorTypeTag type, const SensorPara *para);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SENSOR_STATE_H */
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor thread
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef SENSOR_THREAD_H
+#define SENSOR_THREAD_H
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <cmsis_os.h>
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif
+
+typedef struct {
+ bool isRecursive;
+} MutexAttr;
+
+typedef void *MutexId;
+
+MutexId SensorMutexCreate(MutexAttr *attr);
+
+void SensorMutexDestroy(MutexId *mutex);
+
+void SensorMutexLock(MutexId mutex);
+
+void SensorMutexUnLock(MutexId mutex);
+
+void SensorMutexGlobalLock(void);
+
+void SensorMutexGlobalUnLock(void);
+
+void SensorInitStaticMutexLock(MutexId *mutex);
+
+typedef void *ThreadId;
+typedef void (*ThreadFunc)(void *argv);
+
+typedef struct {
+ const char *name; // name of the thread
+ uint32_t stackSize; // size of stack
+ uint8_t priority; // initial thread priority
+ ThreadFunc func;
+ void *argv;
+} SensorThreadCfg;
+
+ThreadId SensorThreadCreate(const SensorThreadCfg *cfg);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif
+#endif // SENSOR_THREAD_H
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor utils
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef SENSOR_HAL_UTILS_H
+#define SENSOR_HAL_UTILS_H
+
+#include "sensor_typedef.h"
+#include "hsensormgr_service.h"
+#include "vsensormgr_service.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define RELY_SENSOR_CNT_MAX 10
+#define SENSOR_MAX_NUM 10 /* 支持的最大的传感器数量 */
+#define VSENSOR_MAX_NUM 10 /* 虚拟传感器的最大数目 */
+
+/* 初始化util模块 */
+void SensorUtilsInit(void);
+Sensor *SensorUtilsFindSensor(enum SensorTypeTag type);
+Sensor *SensorUtilsRequestSensor(enum SensorTypeTag type);
+char *SensorUtilsGetSimpleName(enum SensorTypeTag type);
+HsensorListener *SensorUtilsRequestListener(void);
+void SensorUtilsFreeListener(HsensorListener *listener);
+int32_t SensorUtilsAddHsensorList(HsensorScb *hsensorScb);
+int32_t SensorUtilsAddVsensorList(enum SensorTypeTag type);
+int32_t SensorUtilsHsensorCheck(const Hsensor *hsensor);
+int32_t SensorUtilsVsensorCheck(const Vsensor *vsensor);
+bool SensorUtilsCheckHSensorType(enum SensorTypeTag type);
+void SensorUtilsRegisterVsensorType(enum SensorTypeTag type);
+bool SensorUtilsCheckVSensorType(enum SensorTypeTag type);
+bool SensorUtilsIsVSensor(enum SensorTypeTag type);
+int32_t SensorUtilsUserInfoCheck(SensorPersonInfo *info);
+/* 获取全部sensor */
+int32_t SensorUtilsGetAllSensors(struct SensorInformation **sensorInfo, int32_t *count);
+
+void SensorUtilsRegisterTaskTable(enum SensorTypeTag type, uint32_t taskId);
+void SensorUtilsUnRegisterTaskTable(enum SensorTypeTag type, uint32_t taskId);
+uint32_t SensorUtilsGetRegisteredTaskId(enum SensorTypeTag type);
+enum SensorTypeTag SensorUtilsGetRegisteredType(uint32_t taskId);
+/* 判断sensor有没有被注册 */
+bool SensorUtilsSensorIsRegistered(enum SensorTypeTag type);
+uint64_t SensorUtilsGetRtcTimeMs(void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor log
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "sensor_log.h"
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include "sensor_type.h"
+#ifdef SUPPORT_AT_UART_PRINT
+#include "app_at_uart.h"
+#endif
+
+#ifdef ENABLE_INFO_LEVEL_LOG
+static SENSOR_LOG_LEVEL g_enabledLevel = SENSOR_LOG_DEBUG;
+#else
+static SENSOR_LOG_LEVEL g_enabledLevel = SENSOR_LOG_ERR;
+#endif
+
+#define MAX_BUFFER_SZ 256
+
+static void LogTime(void)
+{
+ struct timeval tv = {0};
+ gettimeofday(&tv, NULL);
+ struct tm tm = {};
+ localtime_r(&tv.tv_sec, &tm);
+ const int64_t usecToMsec = 1000;
+ printf("[%02d:%02d:%02d:%03lld]", tm.tm_hour, tm.tm_min, tm.tm_sec, tv.tv_usec / usecToMsec);
+}
+
+int32_t SensorLogPrintf(SENSOR_LOG_LEVEL level, const char *fmt, ...)
+{
+ if (level < g_enabledLevel) {
+ return SENSOR_SUCCESS;
+ }
+ if (fmt == NULL) {
+ return SENSOR_INVALID_PARAM;
+ }
+ const char *levelStr = NULL;
+ char out[MAX_BUFFER_SZ] = {0};
+ switch (level) {
+ case SENSOR_LOG_DEBUG:
+ levelStr = "D";
+ break;
+ case SENSOR_LOG_INFO:
+ levelStr = "I";
+ break;
+ case SENSOR_LOG_WARN:
+ levelStr = "W";
+ break;
+ case SENSOR_LOG_ERR:
+ levelStr = "E";
+ break;
+ default:
+ levelStr = "E";
+ break;
+ }
+ LogTime();
+ va_list args;
+#ifdef SUPPORT_AT_UART_PRINT
+ at_uart_printf("[%s]", levelStr);
+#else
+ printf("[%s]", levelStr);
+#endif
+ va_start(args, fmt);
+ int result = vsnprintf_s(out, MAX_BUFFER_SZ, MAX_BUFFER_SZ - 1, fmt, args);
+ if (result == -1) {
+ printf("vsnprintf_s failed!\n");
+ va_end(args);
+ return SENSOR_INVALID_PARAM;
+ }
+ va_end(args);
+#ifdef SUPPORT_AT_UART_PRINT
+ at_uart_printf("%s \n", out);
+#else
+ printf("%s \n", out);
+#endif
+ return SENSOR_SUCCESS;
+}
+
+int32_t SetSensorLogEnabledLevel(SENSOR_LOG_LEVEL level)
+{
+ if (level < SENSOR_LOG_DEBUG ||
+ level > SENSOR_LOG_ERR) {
+ return SENSOR_INVALID_PARAM;
+ }
+ g_enabledLevel = level;
+ return SENSOR_SUCCESS;
+}
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.\r
+ * Description: Sensor Malloc impl\r
+ * Create: 2025-6-6\r
+ */\r
+\r
+#include "sensor_memory.h"\r
+#include "sensor_log.h"\r
+\r
+void *SensorMalloc(unsigned long size)\r
+{\r
+ return malloc(size);\r
+}\r
+\r
+void SensorFree(void *addr)\r
+{\r
+ free(addr);\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.\r
+ * Description: sensor msgqueue impl\r
+ * Author: Media Software Group\r
+ * Create: 2025-06-06\r
+ */\r
+\r
+#include "sensor_msgqueue.h"\r
+#include "sensor_log.h"\r
+\r
+int32_t SensorMsgQueueCreate(SensorMsgQueueCfg* cfg, uint32_t taskId)\r
+{\r
+ if (cfg == NULL) {\r
+ return 0;\r
+ }\r
+ HILOG_INFO(HILOG_MODULE_SEN, "task:%u create msgqueue.\n", taskId);\r
+ return osal_msg_queue_create(cfg->name, cfg->queueLen, &(cfg->queueId), cfg->flags, cfg->maxMsgSize);\r
+}\r
+\r
+int32_t SensorMsgQueueWriteCopy(unsigned int queueId, void *bufferAddr, unsigned int bufferSize, unsigned int timeout)\r
+{\r
+ return osal_msg_queue_write_copy(queueId, bufferAddr, bufferSize, timeout);\r
+}\r
+\r
+int32_t SensorMsgQueueReadCopy(unsigned int queueId, void *bufferAddr, unsigned int *bufferSize, unsigned int timeout)\r
+{\r
+ return osal_msg_queue_read_copy(queueId, bufferAddr, bufferSize, timeout);\r
+}\r
+\r
+void SensorMsgQueueDelete(unsigned int queueId)\r
+{\r
+ osal_msg_queue_delete(queueId);\r
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor para impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+
+#include "sensor_para_decision.h"
+#include "sensor_log.h"
+#include "sensor_utils.h"
+#include "sensor_common.h"
+
+#define OPTION_DEFAULT_VAL 0 /* OPTION初始值 0 */
+#define DEFAULT_REALTIME_PERIOD (SENSOR_PARA_REALTIME_PERIOD_MIN * 1000)
+
+void SensorParaDefaultInit(SensorPara *sensorPara)
+{
+ sensorPara->period = DEFAULT_REALTIME_PERIOD;
+ sensorPara->batch = SENSOR_PARA_BATCH_MIN;
+ sensorPara->mode = SENSOR_MODE_REALTIME; /* fifo mode OR realtime mode */
+ sensorPara->option = 0;
+}
+
+
+void SensorParaClear(SensorPara *para)
+{
+ if (para == NULL) {
+ return;
+ }
+
+ para->period = 0;
+ para->batch = 0;
+ para->mode = SENSOR_MODE_MAX;
+ para->option = OPTION_DEFAULT_VAL;
+}
+
+void SensorParaCopy(SensorPara *dest, const SensorPara *src)
+{
+ if (dest == NULL || src == NULL) {
+ return;
+ }
+
+ dest->period = src->period;
+ dest->batch = src->batch;
+ dest->mode = src->mode;
+ dest->option = src->option;
+}
+
+bool SensorParaIsClear(const SensorPara *para)
+{
+ if (para == NULL) {
+ return true;
+ }
+
+ if (para->period == 0) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+int32_t SensorOptionDecision(enum SensorTypeTag type, int32_t cur, int32_t require)
+{
+ return OPTION_DEFAULT_VAL;
+}
+
+int32_t SensorOpenParaDecision(
+ enum SensorTypeTag type, const SensorPara *cur, const SensorPara *require, SensorPara *result)
+{
+ if (cur == NULL || require == NULL || result == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "type %d para null", type);
+ return SENSOR_SENSOR_DECISION_PARA_NULL;
+ }
+
+ if (SensorParaIsClear(cur)) {
+ SensorParaCopy(result, require);
+ return SENSOR_OK;
+ }
+
+ result->period = SENSOR_MIN(cur->period, require->period);
+ if (result->period == 0) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "type %d period == 0", type);
+ return SENSOR_ERROR;
+ }
+ result->batch = SENSOR_MIN(cur->batch * cur->period, require->batch * require->period) / result->period;
+ result->mode = SENSOR_MIN(cur->mode, require->mode);
+ result->option = SensorOptionDecision(type, cur->option, require->option);
+
+ return SENSOR_OK;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor state impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "sensor_state.h"
+#include "sensor_log.h"
+#include "sensor_utils.h"
+#include "sensor_common.h"
+
+void SensorSetState(enum SensorTypeTag type, SensorState state)
+{
+ Sensor *sensor = NULL;
+
+ sensor = SensorUtilsFindSensor(type);
+ if (sensor == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[STATE] cannot get sensor:%d, sensor may be not registered\n", type);
+ return;
+ }
+
+ sensor->sensorInfo.state = state;
+}
+
+void SensorSetPara(enum SensorTypeTag type, const SensorPara *para)
+{
+ Sensor *sensor = NULL;
+ sensor = SensorUtilsFindSensor(type);
+ if (sensor == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[STATE] cannot get sensor:%d, sensor may be not registered\n", type);
+ return;
+ }
+
+ if (para == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[ATASK] sensor open para NULL!");
+ return;
+ }
+ sensor->sensorInfo.openPara.period = para->period;
+ sensor->sensorInfo.openPara.batch = para->batch;
+ sensor->sensorInfo.openPara.mode = para->mode;
+ sensor->sensorInfo.openPara.option = para->option;
+
+ HILOG_INFO(HILOG_MODULE_SEN,
+ "[UTIL][storge msg] period:%d batch:%d mode:%d option:%d\n",
+ sensor->sensorInfo.openPara.period,
+ sensor->sensorInfo.openPara.batch,
+ sensor->sensorInfo.openPara.mode,
+ sensor->sensorInfo.openPara.option);
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor thread impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "sensor_thread.h"
+#include <unistd.h>
+#include <sys/time.h>
+#include "securec.h"
+
+#ifndef CMSIS_SUPPORT
+pthread_mutex_t g_globalMutexLock = PTHREAD_MUTEX_INITIALIZER;
+static void *ThreadMallocZ(uint32_t len)
+{
+ if (len == 0) {
+ return NULL;
+ }
+
+ void *value = malloc(len);
+ if (value == NULL) {
+ return NULL;
+ }
+
+ if (memset_s(value, len, 0, len) != EOK) {
+ free(value);
+ value = NULL;
+ }
+
+ return value;
+}
+#endif
+
+MutexId SensorMutexCreate(MutexAttr *attr)
+{
+#ifdef CMSIS_SUPPORT
+ osMutexAttr_t mutexAttr = { NULL, 0, NULL, 0 };
+ osMutexAttr_t *pAttr = NULL;
+ if (attr != NULL && attr->isRecursive) {
+ mutexAttr.attr_bits |= osMutexRecursive;
+ pAttr = &mutexAttr;
+ }
+ osMutexId_t mutex = osMutexNew(pAttr);
+ return mutex;
+#else
+ pthread_mutex_t *mutexId = (pthread_mutex_t *)ThreadMallocZ(sizeof(pthread_mutex_t));
+ if (mutexId == NULL) {
+ return NULL;
+ }
+ pthread_mutexattr_t mutexAttr = {0};
+ pthread_mutexattr_t *pAttr = NULL;
+ bool needSetAttr = (attr != NULL && attr->isRecursive && pthread_mutexattr_init(&mutexAttr) == 0);
+ if (needSetAttr) {
+ if (pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE) == 0) {
+ pAttr = &mutexAttr;
+ }
+ }
+ (void)pthread_mutex_init(mutexId, pAttr);
+ if (needSetAttr) {
+ pthread_mutexattr_destroy(&mutexAttr);
+ }
+ return mutexId;
+#endif
+}
+
+void SensorMutexDestroy(MutexId *mutex)
+{
+ if (mutex == NULL || *mutex == NULL) {
+ return;
+ }
+#ifdef CMSIS_SUPPORT
+ (void)osMutexDelete(*mutex);
+#else
+ if (*mutex == NULL) {
+ return;
+ }
+
+ (void)pthread_mutex_destroy((pthread_mutex_t *)*mutex);
+ free(*mutex);
+#endif
+ *mutex = NULL;
+}
+
+void SensorMutexLock(MutexId mutex)
+{
+ if (mutex == NULL) {
+ return;
+ }
+
+#ifdef CMSIS_SUPPORT
+ (void)osMutexAcquire(mutex, osWaitForever);
+#else
+ (void)pthread_mutex_lock((pthread_mutex_t *)mutex);
+#endif
+}
+
+void SensorMutexUnLock(MutexId mutex)
+{
+ if (mutex == NULL) {
+ return;
+ }
+
+#ifdef CMSIS_SUPPORT
+ (void)osMutexRelease(mutex);
+#else
+ (void)pthread_mutex_unlock((pthread_mutex_t *)mutex);
+#endif
+}
+
+void SensorMutexGlobalLock(void)
+{
+#ifdef CMSIS_SUPPORT
+ osKernelLock();
+#else
+ pthread_mutex_lock(&g_globalMutexLock);
+#endif
+}
+
+void SensorMutexGlobalUnLock(void)
+{
+#ifdef CMSIS_SUPPORT
+ osKernelUnlock();
+#else
+ pthread_mutex_unlock(&g_globalMutexLock);
+#endif
+}
+
+void SensorInitStaticMutexLock(MutexId *mutex)
+{
+ if (mutex == NULL || *mutex != NULL) {
+ return;
+ }
+
+ SensorMutexGlobalLock();
+ if (*mutex == NULL) {
+ MutexAttr attr = { false };
+ *mutex = SensorMutexCreate(&attr);
+ }
+ SensorMutexGlobalUnLock();
+}
+
+ThreadId SensorThreadCreate(const SensorThreadCfg *cfg)
+{
+ osThreadAttr_t taskAttr = {cfg->name, 0, NULL, 0, NULL, cfg->stackSize, (osPriority_t)(cfg->priority), 0, 0};
+ return (ThreadId)osThreadNew((osThreadFunc_t)cfg->func, cfg->argv, &taskAttr);
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor utils impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "sensor_utils.h"
+#include <sys/time.h>
+#include "sensor_log.h"
+#include "sensor_task.h"
+#include "sensor_memory.h"
+#include "sensor_common.h"
+
+#define MS_TO_US 1000
+
+typedef struct {
+ enum SensorTypeTag type;
+ const char* simpleName;
+} SensorSimpleNameInfo;
+
+typedef struct {
+ enum SensorTypeTag type;
+ uint32_t taskId;
+} SensorTaskTable;
+
+static SensorTaskTable g_registeredSensorTaskTable[SENSOR_MAX_NUM] = {0};
+
+static struct SensorInformation g_sensorList[SENSOR_MAX_NUM] = {0};
+static Sensor g_sensorPool[SENSOR_MAX_NUM] = {0};
+static enum SensorTypeTag g_registeredVSensorTable[VSENSOR_MAX_NUM] = {0};
+
+const SensorSimpleNameInfo g_sensorSimpleNameInfoDefines[] = {
+ {SENSOR_TYPE_NONE, "none"},
+ {SENSOR_TYPE_ACCELEROMETER, "acc"},
+ {SENSOR_TYPE_GYROSCOPE, "gyro"},
+ {SENSOR_TYPE_PHOTOPLETHYSMOGRAPH, "ppg"},
+ {SENSOR_TYPE_ELECTROCARDIOGRAPH, "ecg"},
+ {SENSOR_TYPE_AMBIENT_LIGHT, "amblitght"},
+ {SENSOR_TYPE_MAGNETIC_FIELD, "magn"},
+ {SENSOR_TYPE_CAPACITIVE, "cap"},
+ {SENSOR_TYPE_BAROMETER, "bar"},
+ {SENSOR_TYPE_TEMPERATURE, "temp"},
+ {SENSOR_TYPE_HALL, "hall"},
+ {SENSOR_TYPE_GESTURE, "gest"},
+ {SENSOR_TYPE_PROXIMITY, "prox"},
+ {SENSOR_TYPE_HUMIDITY, "humi"},
+ {SENSOR_TYPE_PHYSICAL_MAX, "phymax"},
+ {SENSOR_TYPE_ORIENTATION, "ori"},
+ {SENSOR_TYPE_GRAVITY, "grav"},
+ {SENSOR_TYPE_LINEAR_ACCELERATION, "lacc"},
+ {SENSOR_TYPE_ROTATION_VECTOR, "rvec"},
+ {SENSOR_TYPE_AMBIENT_TEMPERATURE, "atemp"},
+ {SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED, "magnu"},
+ {SENSOR_TYPE_GAME_ROTATION_VECTOR, "grvec"},
+ {SENSOR_TYPE_GYROSCOPE_UNCALIBRATED, "gyrou"},
+ {SENSOR_TYPE_SIGNIFICANT_MOTION, "smo"},
+ {SENSOR_TYPE_PEDOMETER_DETECTION, "pedde"},
+ {SENSOR_TYPE_PEDOMETER, "ped"},
+ {SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR, "grvec"},
+ {SENSOR_TYPE_HEART_RATE, "hr"},
+ {SENSOR_TYPE_DEVICE_ORIENTATION, "devor"},
+ {SENSOR_TYPE_WEAR_DETECTION, "wd"},
+ {SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED, "accu"},
+ {SENSOR_TYPE_VSENSOR_ACCELEROMETER_ALG_SIMU, "accalgsimu"},
+
+ {SENSOR_TYPE_MAX, "max"}
+};
+
+void SensorUtilsInit(void)
+{
+}
+
+char *SensorUtilsGetSimpleName(enum SensorTypeTag type)
+{
+ char* ret = NULL;
+ for (uint32_t i = 0; i < (sizeof(g_sensorSimpleNameInfoDefines) / sizeof(SensorSimpleNameInfo)); i++) {
+ if (g_sensorSimpleNameInfoDefines[i].type == type) {
+ ret = (char*)(g_sensorSimpleNameInfoDefines[i].simpleName);
+ break;
+ }
+ }
+ return ret;
+}
+
+Sensor *SensorUtilsFindSensor(enum SensorTypeTag type)
+{
+ CHECK_SENSOR_TYPE_ILLEGAL_RETURN_RET(type, NULL);
+
+ for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+ Sensor *sensor = &(g_sensorPool[i]);
+ if (type == sensor->sensorInfo.type) {
+ return sensor;
+ }
+ }
+
+ return NULL;
+}
+
+Sensor *SensorUtilsRequestSensor(enum SensorTypeTag type)
+{
+ Sensor *sensor = SensorUtilsFindSensor(type);
+ if (sensor != NULL) {
+ /* sensor已存在,不允许重复注册 */
+ HILOG_ERROR(HILOG_MODULE_SEN, "[util] find sensor:%d exit!", sensor->sensorInfo.type);
+ return NULL;
+ }
+
+ for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+ sensor = &(g_sensorPool[i]);
+ if (sensor->sensorInfo.type == SENSOR_TYPE_NONE) {
+ return sensor;
+ }
+ }
+ HILOG_WARN(HILOG_MODULE_SEN, "[util] find sensor:%d Exceed max!", sensor->sensorInfo.type);
+ return NULL;
+}
+
+/* 获取全部sensor */
+int32_t SensorUtilsGetAllSensors(struct SensorInformation **sensorInfo, int32_t *count)
+{
+ HILOG_DEBUG(HILOG_MODULE_SEN, "in!");
+ if (sensorInfo == NULL || count == NULL) {
+ return SENSOR_ENTRY_PARA_ERROR;
+ }
+ *count = 0;
+ for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+ HILOG_DEBUG(HILOG_MODULE_SEN, "index:%d sensorID:%d sensorTypeId:%d", i, g_sensorList[i].sensorId, g_sensorList[i].sensorTypeId);
+ if (g_sensorList[i].sensorTypeId == (int32_t)SENSOR_TYPE_NONE) {
+ break;
+ }
+ (*count)++;
+ }
+ *sensorInfo = g_sensorList;
+ HILOG_DEBUG(HILOG_MODULE_SEN, "find sensorlist:%d! list addr:%x", *count, g_sensorList);
+ return SENSOR_OK;
+}
+
+static struct SensorInformation *SensorUtilsFindSensorsList(enum SensorTypeTag type)
+{
+ CHECK_SENSOR_TYPE_ILLEGAL_RETURN_RET(type, NULL);
+
+ for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+ struct SensorInformation *sensorList = &(g_sensorList[i]);
+ if (type == (enum SensorTypeTag)sensorList->sensorTypeId) {
+ return sensorList;
+ }
+ }
+
+ return NULL;
+}
+
+static struct SensorInformation *SensorUtilsRequestSensorList(enum SensorTypeTag type)
+{
+ struct SensorInformation *sensorList = SensorUtilsFindSensorsList(type);
+ if (sensorList != NULL) {
+ /* sensor已存在,不允许重复注册 */
+ HILOG_ERROR(HILOG_MODULE_SEN, "[util] find sensorlist:%d exit!", sensorList->sensorTypeId);
+ return NULL;
+ }
+
+ for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+ sensorList = &(g_sensorList[i]);
+ if (sensorList->sensorTypeId == (int32_t)SENSOR_TYPE_NONE) {
+ return sensorList;
+ }
+ }
+ return NULL;
+}
+
+int32_t SensorUtilsAddHsensorList(HsensorScb *hsensorScb)
+{
+ struct SensorInformation *sensorList = SensorUtilsRequestSensorList(hsensorScb->type);
+ if (sensorList == NULL) {
+ return SENSOR_ERROR;
+ }
+
+ sensorList->sensorTypeId = hsensorScb->type;
+ // sensorList->sensorName = hsensorScb->hsensor->name;
+ return SENSOR_OK;
+}
+
+int32_t SensorUtilsAddVsensorList(enum SensorTypeTag type)
+{
+ struct SensorInformation *sensorList = SensorUtilsRequestSensorList(type);
+ if (sensorList == NULL) {
+ return SENSOR_ERROR;
+ }
+
+ sensorList->sensorTypeId = type;
+ return SENSOR_OK;
+}
+
+HsensorListener *SensorUtilsRequestListener(void)
+{
+ return (HsensorListener *)SensorMalloc(sizeof(HsensorListener));
+}
+
+void SensorUtilsFreeListener(HsensorListener *listener)
+{
+ if (listener) {
+ SensorFree(listener);
+ }
+}
+
+/* 用户信息有效性检查 */
+int32_t SensorUtilsUserInfoCheck(SensorPersonInfo *info)
+{
+ /* 参数检查 */
+ if ((info->weight > MAX_USER_WEIGHT) || (info->weight < MIN_USER_WEIGHT)) {
+ HILOG_INFO(HILOG_MODULE_SEN, "user weight out range!");
+ info->weight = DEFAULT_USER_WEIGHT;
+ }
+
+ if ((info->height > MAX_USER_HEIGHT) || (info->height < MIN_USER_HEIGHT)) {
+ HILOG_INFO(HILOG_MODULE_SEN, "user height out range!");
+ info->height = DEFAULT_USER_HEIGHT;
+ }
+
+ if ((info->age > MAX_USER_AGE) || (info->age == 0)) {
+ HILOG_INFO(HILOG_MODULE_SEN, "user age out range!");
+ info->age = DEFAULT_USER_AGE;
+ }
+
+ if (info->gender > ALG_USER_SEX_UNKNOWN) {
+ HILOG_INFO(HILOG_MODULE_SEN, "user gender out range!");
+ info->gender = ALG_USER_SEX_MAN;
+ }
+
+ return SENSOR_OK;
+}
+
+static int32_t SensorUtilsVsensorRelyCheck(const RelySensorsInfo *relySensors)
+{
+ if (relySensors->relySensorCnt == 0) {
+ return SENSOR_ENTRY_VSENSOR_RELY_NULL;
+ }
+ return SENSOR_OK;
+}
+
+bool SensorUtilsCheckHSensorType(enum SensorTypeTag type)
+{
+ if ((type == SENSOR_TYPE_NONE) || (type >= SENSOR_TYPE_VSENSOR_EXPAND_START)) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "type :%d illegal", type);
+ return false;
+ }
+ return true;
+}
+
+bool SensorUtilsCheckVSensorType(enum SensorTypeTag type)
+{
+ if ((type <= SENSOR_TYPE_VSENSOR_EXPAND_START) || (type >= SENSOR_TYPE_MAX)) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "type :%d illegal", type);
+ return false;
+ }
+ return true;
+}
+
+void SensorUtilsRegisterVsensorType(enum SensorTypeTag type)
+{
+ CHECK_SENSOR_TYPE_ILLEGAL_RETURN(type);
+
+ for (uint8_t i = 0; i < VSENSOR_MAX_NUM; i++) {
+ if (type == g_registeredVSensorTable[i]) {
+ return;
+ }
+ if (g_registeredVSensorTable[i] == SENSOR_TYPE_NONE) {
+ g_registeredVSensorTable[i] = type;
+ return;
+ }
+ }
+}
+
+bool SensorUtilsIsVSensor(enum SensorTypeTag type)
+{
+ for (uint8_t i = 0; i < VSENSOR_MAX_NUM; i++) {
+ if (type == g_registeredVSensorTable[i]) {
+ return true;
+ }
+ }
+ return false;
+}
+
+int32_t SensorUtilsHsensorCheck(const Hsensor *hsensor)
+{
+ CHECK_NULL_PTR_RETURN_VALUE(hsensor, SENSOR_ENTRY_HSENSOR_NULL);
+ CHECK_NULL_PTR_RETURN_VALUE(hsensor->name, SENSOR_ENTRY_HSENSOR_NAME_NULL);
+ CHECK_NULL_PTR_RETURN_VALUE(hsensor->init, SENSOR_ENTRY_HSENSOR_FUNC_NULL);
+ CHECK_NULL_PTR_RETURN_VALUE(hsensor->deinit, SENSOR_ENTRY_HSENSOR_FUNC_NULL);
+ CHECK_NULL_PTR_RETURN_VALUE(hsensor->close, SENSOR_ENTRY_HSENSOR_FUNC_NULL);
+ CHECK_NULL_PTR_RETURN_VALUE(hsensor->read, SENSOR_ENTRY_HSENSOR_FUNC_NULL);
+ CHECK_NULL_PTR_RETURN_VALUE(hsensor->ioctl, SENSOR_ENTRY_HSENSOR_FUNC_NULL);
+ if (hsensor->caps.maxBatchCount == 0 || hsensor->caps.sampleElementlen == 0) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "maxBatchCount :%u sampleElementlen :%u illegal",
+ hsensor->caps.maxBatchCount, hsensor->caps.sampleElementlen);
+ return SENSOR_HSENSOR_PERIOD_BATCH_ERR;
+ }
+
+ if (!SensorUtilsCheckHSensorType(hsensor->type)) {
+ return SENSOR_ENTRY_SENSOR_TYPE_ILLEGAL;
+ }
+
+ return SENSOR_OK;
+}
+
+int32_t SensorUtilsVsensorCheck(const Vsensor *vsensor)
+{
+ CHECK_NULL_PTR_RETURN_VALUE(vsensor, SENSOR_ENTRY_VSENSOR_NULL);
+ CHECK_NULL_PTR_RETURN_VALUE(vsensor->name, SENSOR_ENTRY_VSENSOR_NAME_NULL);
+ CHECK_NULL_PTR_RETURN_VALUE(vsensor->relySensors, SENSOR_ENTRY_VSENSOR_RELY_NULL);
+
+ CHECK_NULL_PTR_RETURN_VALUE(vsensor->registDataCb, SENSOR_ENTRY_VSENSOR_FUNC_NULL);
+ CHECK_NULL_PTR_RETURN_VALUE(vsensor->unRegistDataCb, SENSOR_ENTRY_VSENSOR_FUNC_NULL);
+ CHECK_NULL_PTR_RETURN_VALUE(vsensor->open, SENSOR_ENTRY_VSENSOR_FUNC_NULL);
+ CHECK_NULL_PTR_RETURN_VALUE(vsensor->close, SENSOR_ENTRY_VSENSOR_FUNC_NULL);
+ CHECK_NULL_PTR_RETURN_VALUE(vsensor->process, SENSOR_ENTRY_VSENSOR_FUNC_NULL);
+
+ if (!SensorUtilsCheckVSensorType(vsensor->type)) {
+ return SENSOR_ENTRY_SENSOR_TYPE_ILLEGAL;
+ }
+
+ int32_t ret = SensorUtilsVsensorRelyCheck(vsensor->relySensors);
+ if (ret != SENSOR_OK) {
+ return ret;
+ }
+
+ return SENSOR_OK;
+}
+
+void SensorUtilsRegisterTaskTable(enum SensorTypeTag type, uint32_t taskId)
+{
+ CHECK_SENSOR_TYPE_ILLEGAL_RETURN(type);
+ for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+ if (type == g_registeredSensorTaskTable[i].type) {
+ g_registeredSensorTaskTable[i].taskId = taskId;
+ return;
+ }
+ }
+
+ for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+ if (g_registeredSensorTaskTable[i].type == SENSOR_TYPE_NONE) {
+ g_registeredSensorTaskTable[i].type = type;
+ g_registeredSensorTaskTable[i].taskId = taskId;
+ return;
+ }
+ }
+}
+
+void SensorUtilsUnRegisterTaskTable(enum SensorTypeTag type, uint32_t taskId)
+{
+ CHECK_SENSOR_TYPE_ILLEGAL_RETURN(type);
+ for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+ if (type == g_registeredSensorTaskTable[i].type && taskId == g_registeredSensorTaskTable[i].taskId) {
+ g_registeredSensorTaskTable[i].taskId = 0;
+ g_registeredSensorTaskTable[i].type = SENSOR_TYPE_NONE;
+ return;
+ }
+ }
+}
+
+uint32_t SensorUtilsGetRegisteredTaskId(enum SensorTypeTag type)
+{
+ for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+ if (type == g_registeredSensorTaskTable[i].type) {
+ return g_registeredSensorTaskTable[i].taskId;
+ }
+ }
+ return SENSOR_FAILURE;
+}
+
+enum SensorTypeTag SensorUtilsGetRegisteredType(uint32_t taskId)
+{
+ for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+ if (taskId == g_registeredSensorTaskTable[i].taskId) {
+ return g_registeredSensorTaskTable[i].type;
+ }
+ }
+ return SENSOR_TYPE_MAX;
+}
+
+bool SensorUtilsSensorIsRegistered(enum SensorTypeTag type)
+{
+ for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+ Sensor *sensor = &(g_sensorPool[i]);
+ if (sensor->sensorInfo.type == type) {
+ return true;
+ }
+ }
+ return false;
+}
+
+uint64_t SensorUtilsGetRtcTimeMs(void)
+{
+ struct timeval tv;
+ (void)gettimeofday(&tv, NULL);
+ return (tv.tv_sec * MS_TO_US + tv.tv_usec / MS_TO_US);
+}
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: vsensor task mgr
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef VENSOR_TASK_MGR_H
+#define VENSOR_TASK_MGR_H
+
+#include <stdbool.h>
+#include "sensor_typedef.h"
+#include "sensor_tmsg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int32_t VsensorTaskMgrInit(uint32_t taskId);
+void VsensorTaskMgrDeInit(uint32_t taskId);
+int32_t VsensorTaskMgrMsgProcess(uint32_t taskId, const SensorTmsg *tmsg);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: vsensor task mgr service
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef VSENSOR_MGR_SEVICE_H
+#define VSENSOR_MGR_SEVICE_H
+
+#include "sensor_typedef.h"
+#include "soc_osal.h"
+#include "hsensormgr_service.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int32_t VsensorMgrInit(void);
+int32_t VsensorMgrRegister(const Vsensor *vsensor);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: vsensor task class
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef VSENSOR_TASK_CLASS_H
+#define VSENSOR_TASK_CLASS_H
+
+#include "vsensor_task_comm.h"
+
+typedef struct {
+ VsensorTaskComm component;
+ SensorTmsgProcMap *tmsgProcMap;
+ uint16_t tmsgProcMapLen;
+} VsensorTaskClass;
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* aclass对象创建 */
+VsensorTaskClass *VsensorTaskClassInit(uint32_t taskId, const char *taskPrefix, NotifyCallback hdataCb,
+ const SensorTmsgProcMap *tmsgProcMap, uint16_t tmsgProcMapLen);
+
+/* aclass对象销毁 */
+void VsensorTaskClassDestruct(VsensorTaskClass *vSensorClass);
+
+/* 通过 taskid 查找 aclass 对象 */
+VsensorTaskClass *VsensorTaskClassGetByTaskid(uint32_t taskId);
+
+/* aclass类公用的消息处理函数 */
+int32_t VsensorTaskClassMsgProcess(VsensorTaskClass *vSensorClass, const SensorTmsg *tmsg);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: vsensor task common
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef SENSOR_TASK_COMM_H
+#define SENSOR_TASK_COMM_H
+
+#include <stdbool.h>
+#include "sensor_typedef.h"
+#include "hsensormgr_service.h"
+#include "sensor_task.h"
+#include "sensor_tmsg.h"
+#include "sensor_utils.h"
+
+#define VSENSOR_TASK_HLISTENER_MAX_NUM 10 /* FA算法线程支持的物理传感器listener的最大数量设置 */
+#define FA_VSENSOR_BE_RELYED_NUM 10 /* 虚拟sensor被依赖的任务最大个数 */
+#define VSENSOR_RESULT_TS_OFFSET 1000 /* 虚拟传感器上报的时间戳与获取的时间戳的矫正间隔值 */
+
+enum {
+ APP_CTRL = 0,
+ RELY_CTRL,
+};
+
+typedef struct {
+ bool appOpenFlag;
+ uint32_t relyedCnt; /* 被其他算法依赖的次数 */
+} VsensorTaskRelyedInfo;
+
+typedef struct {
+ enum SensorTypeTag type;
+ SensorState state;
+ Vsensor *vsensor;
+ VsensorTaskRelyedInfo relyedInfo;
+} VsensorTaskInfo;
+
+typedef struct {
+ enum SensorTypeTag type;
+ HsensorListener hlistener;
+} VsensorTaskHlistener;
+
+typedef struct {
+ enum SensorTypeTag sensor;
+ uint32_t dataLen;
+ uint64_t timestamp;
+ uint8_t sensordata[];
+} VsensorProcessData;
+
+typedef struct {
+ uint32_t taskId;
+ char *taskPrefix;
+ NotifyCallback hdataCb; /* hlistener中的数据回调函数,若为NULL,将直接使用atask类默认的数据回调函数 */
+ VsensorTaskHlistener hlistenersList[VSENSOR_TASK_HLISTENER_MAX_NUM];
+ VsensorTaskInfo vsensorInfo[VSENSOR_MAX_NUM];
+} VsensorTaskComm;
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int32_t VsensorTaskCheckCommComponents(const VsensorTaskComm *component);
+bool VsensorTaskVsensorIsRunning(const VsensorTaskInfo *vsensorInfo);
+void VsensorTaskCommInit(VsensorTaskComm *component);
+int32_t VsensorTaskVsensorRegEvent(VsensorTaskComm *component, Vsensor *vsensor);
+int32_t VsensorTaskSensorDataUpdateEvent(VsensorTaskComm *component, VsensorProcessData *data);
+
+int32_t VsensorTaskVsensorOpenEvent(
+ VsensorTaskComm *component, enum SensorTypeTag type, SensorPara *para, uint32_t openType);
+int32_t VsensorTaskVsensorCloseEvent(VsensorTaskComm *component, enum SensorTypeTag type, uint32_t closeType);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* VSENSOR_TASK_COMM_H */
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: vsensor task class impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "vsensor_task_class.h"
+#include "securec.h"
+#include "sensor_log.h"
+#include "sensor_common.h"
+#include "sensor_utils.h"
+#include "sensor_memory.h"
+#include "sensor_tmsg.h"
+
+/* 存储 taskid 和 aclass 对象的对应表 */
+static VsensorTaskClass *g_vsensorTaskObjArray[SENSOR_TASK_MAX_CNT] = {NULL};
+
+/* aclass对象创建 */
+VsensorTaskClass *VsensorTaskClassInit(uint32_t taskId, const char *taskPrefix, NotifyCallback hdataCb,
+ const SensorTmsgProcMap *tmsgProcMap, uint16_t tmsgProcMapLen)
+{
+ if (taskPrefix == NULL) {
+ return NULL;
+ }
+
+ VsensorTaskClass *vsensorTaskObj = (VsensorTaskClass *)SensorMalloc(sizeof(VsensorTaskClass));
+ if (vsensorTaskObj == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "aclass:%d malloc fail!\n", taskId);
+ return NULL;
+ }
+
+ memset_s(vsensorTaskObj, sizeof(VsensorTaskClass), 0, sizeof(VsensorTaskClass));
+
+ vsensorTaskObj->component.taskId = taskId;
+ vsensorTaskObj->component.taskPrefix = (char *)taskPrefix;
+ vsensorTaskObj->component.hdataCb = hdataCb;
+ vsensorTaskObj->tmsgProcMap = (SensorTmsgProcMap *)tmsgProcMap;
+ vsensorTaskObj->tmsgProcMapLen = tmsgProcMapLen;
+ VsensorTaskCommInit(&(vsensorTaskObj->component));
+ g_vsensorTaskObjArray[taskId] = vsensorTaskObj;
+
+ return vsensorTaskObj;
+}
+
+/* aclass对象销毁 */
+void VsensorTaskClassDestruct(VsensorTaskClass *vSensorClass)
+{
+ if (vSensorClass == NULL) {
+ return;
+ }
+ g_vsensorTaskObjArray[vSensorClass->component.taskId] = NULL;
+ SensorFree(vSensorClass);
+}
+
+/* 通过 taskid 查找 aclass 对象 */
+VsensorTaskClass *VsensorTaskClassGetByTaskid(uint32_t taskId)
+{
+ if (taskId < SENSOR_TASK_MAX_CNT) {
+ return g_vsensorTaskObjArray[taskId];
+ } else {
+ return NULL;
+ }
+}
+
+/* aclass类公用的消息处理函数,当aclass对象没有指定消息处理函数时,会使用此函数的消息处理流程 */
+static int32_t VsensorTaskGenericMsgProcess(VsensorTaskComm *component, const SensorTmsg *tmsg)
+{
+ HILOG_DEBUG(HILOG_MODULE_SEN, "msg:%d task:%d proc", tmsg->id, component->taskId);
+ /* 无需多重校验入参指针,在函数上下文中,已经判断了,提升代码运行效率 */
+ int32_t ret = SENSOR_OK;
+ switch (tmsg->id) {
+ case SENSOR_TMSG_VSENSOR_REG_EVENT: {
+ Vsensor *vsensor = (Vsensor *)(tmsg->value);
+ CHECK_NULL_PTR_RETURN_VALUE(vsensor, SENSOR_VSENSOR_TASK_REG_VENSOR_NULL);
+ ret = VsensorTaskVsensorRegEvent(component, (Vsensor *)(tmsg->value));
+ break;
+ }
+ case SENSOR_TMSG_HSENSOR_DATA_UPDATE:
+ case SENSOR_TMSG_VSENSOR_DATA_UPDATE: {
+ ret = VsensorTaskSensorDataUpdateEvent(component, (VsensorProcessData *)(tmsg->info));
+ break;
+ }
+ case SENSOR_TMSG_VSENSOR_OPEN_EVENT: {
+ ret = VsensorTaskVsensorOpenEvent(
+ component, (enum SensorTypeTag)(tmsg->value), (SensorPara *)(tmsg->info), APP_CTRL);
+ break;
+ }
+ case SENSOR_TMSG_VSENSOR_CLOSE_EVENT: {
+ ret = VsensorTaskVsensorCloseEvent(component, (enum SensorTypeTag)(tmsg->value), APP_CTRL);
+ break;
+ }
+ case SENSOR_TMSG_VSENSOR_RELY_OPEN_EVENT: {
+ ret = VsensorTaskVsensorOpenEvent(
+ component, (enum SensorTypeTag)(tmsg->value), (SensorPara *)(tmsg->info), RELY_CTRL);
+ break;
+ }
+ case SENSOR_TMSG_VSENSOR_RELY_CLOSE_EVENT: {
+ ret = VsensorTaskVsensorCloseEvent(component, (enum SensorTypeTag)(tmsg->value), RELY_CTRL);
+ break;
+ }
+ default:
+ HILOG_INFO(HILOG_MODULE_SEN, "cannot get msg:%d task:%d proc.\n", tmsg->id, component->taskId);
+ }
+ HILOG_DEBUG(HILOG_MODULE_SEN, "msg:%d task:%d proc ret:%d", tmsg->id, component->taskId, ret);
+ return ret;
+}
+
+/* aclass类公用的消息处理函数 */
+int32_t VsensorTaskClassMsgProcess(VsensorTaskClass *vSensorClass, const SensorTmsg *tmsg)
+{
+ VsensorTaskComm *component = &(vSensorClass->component);
+
+ CHECK_NULL_PTR_RETURN_VALUE(vSensorClass, SENSOR_VSENSOR_TASK_CLASS_NULL);
+ int32_t ret = VsensorTaskCheckCommComponents(component);
+ SENSOR_CHECK_OK(ret);
+
+ if (tmsg == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "VsensorTaskClassMsgProcess tmsg NULL\r\n");
+ return SENSOR_RECV_TMSG_NULL;
+ }
+
+ if (vSensorClass->tmsgProcMap == NULL || vSensorClass->tmsgProcMapLen == 0) {
+ return VsensorTaskGenericMsgProcess(component, tmsg);
+ }
+
+ for (uint32_t i = 0; i < vSensorClass->tmsgProcMapLen; i++) {
+ if (vSensorClass->tmsgProcMap[i].tmsgId == tmsg->id && vSensorClass->tmsgProcMap[i].tmsgProc != NULL) {
+ return vSensorClass->tmsgProcMap[i].tmsgProc(tmsg);
+ }
+ }
+ return VsensorTaskGenericMsgProcess(component, tmsg);
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: vsensor task common impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "vsensor_task_comm.h"
+#include "sensor_log.h"
+#include "sensor_memory.h"
+#include "sensor_common.h"
+#include "securec.h"
+#include "sensor_tmsg.h"
+#include "sensor_para_decision.h"
+#include "sensor_state.h"
+
+int32_t VsensorTaskCheckCommComponents(const VsensorTaskComm *component)
+{
+ if (component == NULL || component->taskPrefix == NULL) {
+ return SENSOR_TASK_CHECK_COMM_COMPONENT_NULL;
+ }
+ return SENSOR_OK;
+}
+
+static VsensorTaskHlistener *VsensorTaskFindHlistener(
+ const VsensorTaskHlistener *hlistenerPool, uint16_t hlistenerPoolLen, enum SensorTypeTag type)
+{
+ CHECK_SENSOR_TYPE_ILLEGAL_RETURN_RET(type, NULL);
+
+ for (uint32_t i = 0; i < VSENSOR_TASK_HLISTENER_MAX_NUM; i++) {
+ VsensorTaskHlistener *hlistener = (VsensorTaskHlistener *)(&(hlistenerPool[i]));
+ if (hlistener->type == type) {
+ return hlistener;
+ }
+ }
+
+ return NULL;
+}
+
+static VsensorTaskHlistener *VsensorTaskRequestHlistener(
+ const VsensorTaskHlistener *hlistenerPool, uint16_t hlistenerPoolLen, enum SensorTypeTag type)
+{
+ VsensorTaskHlistener *hlistener = VsensorTaskFindHlistener(hlistenerPool, hlistenerPoolLen, type);
+ if (hlistener != NULL) {
+ return hlistener;
+ }
+
+ for (uint32_t i = 0; i < VSENSOR_TASK_HLISTENER_MAX_NUM; i++) {
+ hlistener = (VsensorTaskHlistener *)(&(hlistenerPool[i]));
+ if (hlistener->type == SENSOR_TYPE_NONE) {
+ return hlistener;
+ }
+ }
+
+ return NULL;
+}
+
+static int32_t VsensorTaskDataUpdateCheck(const SensorNotifyInfo *events, const void *notifyArg)
+{
+ if ((events == NULL) || (events->data == NULL) || (notifyArg == NULL)) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]dataupdate para null %d\r\n", (int32_t)events->dataLen);
+ return SENSOR_TASK_HSDATA_UPDATE_DATA_NULL;
+ }
+
+ if (events->type >= SENSOR_TYPE_MAX) {
+ HILOG_ERROR(HILOG_MODULE_SEN,
+ "[VTASK]dataupdate sensor type or len err,type:%d, len:%u\r\n",
+ events->type,
+ events->dataLen);
+ return SENSOR_TASK_HSDATA_UPDATE_DATA_NULL;
+ }
+
+ return SENSOR_OK;
+}
+
+static void VsensorTaskSensorDataUpdate(const SensorNotifyInfo *events, void *notifyArg)
+{
+ int32_t ret;
+ ret = VsensorTaskDataUpdateCheck(events, notifyArg);
+ if (ret != SENSOR_OK) {
+ return;
+ }
+
+ VsensorTaskComm *component = (VsensorTaskComm *)notifyArg;
+
+ /* 计算实际需要的存储空间 */
+ uint32_t dataSize = (uint32_t)(sizeof(VsensorProcessData)) + events->dataLen;
+ VsensorProcessData *processData = (VsensorProcessData *)SensorMalloc(dataSize);
+ if (processData == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN,
+ "[VTASK]cannot malloc for hsensor:%d data!, taskId:%d\n",
+ events->type,
+ component->taskId);
+ return;
+ }
+ int32_t err = memset_s(processData, dataSize, 0, dataSize);
+ if (err != EOK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]dataupdate: memset fail\r\n");
+ }
+
+ processData->timestamp = events->timestamp;
+ processData->sensor = events->type;
+ processData->dataLen = events->dataLen;
+
+ uint32_t i = 0;
+ while (i < events->dataLen) {
+ processData->sensordata[i] = events->data[i];
+ i++;
+ }
+ SensorTmsg tmsgSend = {
+ .id = SENSOR_TMSG_HSENSOR_DATA_UPDATE, .value = 0, .ts = 0, .info = processData, .infoSize = dataSize};
+
+ ret = SensorTmsgSend(component->taskId, &tmsgSend);
+ if (ret != SENSOR_OK) {
+ SensorFree((void *)processData);
+ processData = NULL;
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]dataupdate send msg error 0x%x\r\n", ret);
+ }
+
+ return;
+}
+
+static int32_t VsensorTaskHlistenerInit(
+ VsensorTaskComm *component, VsensorTaskHlistener *hlistener, enum SensorTypeTag type)
+{
+ HsensorListener *listener = &(hlistener->hlistener);
+ Sensor *sensor = SensorUtilsFindSensor(type);
+ if (sensor == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]init sensor NULL! type:%d", type);
+ return SENSOR_TASK_SENSOR_NULL;
+ }
+
+ errno_t err = memset_s(listener->name, HSENSOR_LISTENER_NAME_MAX_LEN, 0, HSENSOR_LISTENER_NAME_MAX_LEN);
+ if (err != EOK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]hlistener init name memset full! type:%d", type);
+ return SENSOR_SENSOR_SECUREC_FUNC_ERR;
+ }
+ err = strcat_s(listener->name, sizeof(listener->name), component->taskPrefix);
+ if (err != EOK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]hlistener init name strcat full! type:%d", type);
+ return SENSOR_SENSOR_SECUREC_FUNC_ERR;
+ }
+ err = strcat_s(listener->name, sizeof(listener->name), sensor->sensorInfo.name);
+ if (err != EOK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]hlistener init name strcat full! type:%d", type);
+ return SENSOR_SENSOR_SECUREC_FUNC_ERR;
+ }
+
+ listener->type = type;
+ hlistener->type = type;
+
+ /* 如果没有指定物理传感器数据更新函数,默认直接采用 标准通道函数 */
+ if (component->hdataCb == NULL) {
+ listener->notifyCallback = VsensorTaskSensorDataUpdate;
+ } else {
+ listener->notifyCallback = component->hdataCb;
+ }
+ listener->notifyArg = (void *)component;
+ HILOG_DEBUG(HILOG_MODULE_SEN, "[VTASK]Hlistener init type :%d", type);
+ return SENSOR_OK;
+}
+
+static int32_t VsensorTaskHlistenerRegister(HsensorListener *listener)
+{
+ int32_t ret = HsensorMgrRegisterListener(listener);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]hsensormgr reg listener:%d return FAIL!\n", listener->type);
+ return ret;
+ }
+
+ return SENSOR_OK;
+}
+
+static VsensorTaskInfo *VsensorTaskFindVsensorInfo(
+ const VsensorTaskInfo *vsensorPool, uint16_t vsensorPoolLen, enum SensorTypeTag type)
+{
+ CHECK_SENSOR_TYPE_ILLEGAL_RETURN_RET(type, NULL);
+
+ for (uint32_t i = 0; i < VSENSOR_MAX_NUM; i++) {
+ VsensorTaskInfo *vsensorInfo = (VsensorTaskInfo *)(&(vsensorPool[i]));
+ if (vsensorInfo->type == type) {
+ if (vsensorInfo->vsensor == NULL) {
+ vsensorInfo->type = (enum SensorTypeTag)0;
+ vsensorInfo->state = SENSOR_STATE_IDLE;
+ continue;
+ }
+ return vsensorInfo;
+ }
+ }
+
+ return NULL;
+}
+
+static VsensorTaskInfo *VsensorTaskRequestVsensorInfo(
+ const VsensorTaskInfo *vsensorPool, uint16_t vsensorPoolLen, enum SensorTypeTag type)
+{
+ VsensorTaskInfo *vsensorInfo = VsensorTaskFindVsensorInfo(vsensorPool, vsensorPoolLen, type);
+ if (vsensorInfo != NULL) {
+ return vsensorInfo;
+ }
+
+ for (uint32_t i = 0; i < VSENSOR_MAX_NUM; i++) {
+ vsensorInfo = (VsensorTaskInfo *)(&(vsensorPool[i]));
+ if (vsensorInfo->type == (enum SensorTypeTag)0) {
+ return vsensorInfo;
+ }
+ }
+
+ return NULL;
+}
+
+static int32_t VsensorTaskVsensorReg(const VsensorTaskComm *component, Vsensor *vsensor)
+{
+ VsensorTaskInfo *vsensorInfo =
+ VsensorTaskRequestVsensorInfo(component->vsensorInfo, VSENSOR_MAX_NUM, vsensor->type);
+ if (vsensorInfo == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]init find vsensorInfo NULL! type:%d", vsensor->type);
+ return SENSOR_TASK_VSENSOR_INFO_FIND_NULL;
+ }
+
+ vsensorInfo->type = vsensor->type;
+ vsensorInfo->vsensor = vsensor;
+ HILOG_DEBUG(HILOG_MODULE_SEN, "[VTASK]Reg type:%d", vsensor->type);
+ return SENSOR_OK;
+}
+
+static int32_t VsensorTaskOpenRelyHSensor(VsensorTaskComm *component, enum SensorTypeTag type, const SensorPara *para)
+{
+ VsensorTaskHlistener *hlistenerPool = component->hlistenersList;
+ HILOG_DEBUG(HILOG_MODULE_SEN, "[VTASK]Open Rely hsensor:%d ", type);
+ VsensorTaskHlistener *var = VsensorTaskFindHlistener(hlistenerPool, VSENSOR_TASK_HLISTENER_MAX_NUM, type);
+ if ((var == NULL) || (var->type == SENSOR_TYPE_NONE)) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]rely hlistener NULL! type:%d", type);
+ return SENSOR_TASK_LISTENER_FIND_NULL;
+ }
+
+ SensorPara curDecisionPara = var->hlistener.openParam;
+ int32_t ret = SensorOpenParaDecision(type, &curDecisionPara, para, &(var->hlistener.openParam));
+ if (ret != SENSOR_OK) {
+ return ret;
+ }
+
+ if (SensorParaIsClear(&(var->hlistener.openParam))) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]sensor decision para err! type:%d", type);
+ return SENSOR_TASK_SENSOR_DECISION_PARA_ERROR;
+ }
+
+ ret = HsensorMgrOpenListener(&(var->hlistener));
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]hsensor:%d enable err 0x%04x!\n", type, ret);
+ return ret;
+ }
+ HILOG_DEBUG(HILOG_MODULE_SEN, "[VTASK]Open Rely hsensor:%d sucess", type);
+ return SENSOR_OK;
+}
+
+int32_t VsensorTaskOpenRelySensors(VsensorTaskComm *component, const RelySensorInfo *relySensors, uint8_t relyCnt)
+{
+ int32_t ret = SENSOR_OK;
+ if ((relySensors == NULL) || (relyCnt <= 0)) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[RELY] rely sensor is NULL!\n");
+ return SENSOR_OPEN_RELY_SENSORS_CHECK_NULL;
+ }
+
+ for (uint8_t i = 0; i < relyCnt; i++) {
+ enum SensorTypeTag type = relySensors[i].type;
+
+ if (!SensorUtilsSensorIsRegistered(type)) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[RELY] rely sensor:%d not registed!\n", type);
+ return SENSOR_TASK_RELY_SENSOR_NOT_REGISTERED;
+ }
+
+ uint32_t taskId = SensorUtilsGetRegisteredTaskId(type);
+ bool isVsensor = SensorUtilsIsVSensor(type);
+ if (isVsensor == true) {
+ // 打开虚拟sensor
+ SensorTmsg tmsgSend = {.id = SENSOR_TMSG_VSENSOR_RELY_OPEN_EVENT,
+ .value = (uintptr_t)type,
+ .ts = 0,
+ .info = NULL,
+ .infoSize = 0};
+
+ ret = SensorTmsgSend(taskId, &tmsgSend);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "vsensor:%d send open msg FAIL!\r\n", type);
+ return ret;
+ }
+ } else {
+ /* 打开物理sensor, type 为物理sensor的类型 */
+ ret = VsensorTaskOpenRelyHSensor(component, type, (SensorPara *)&(relySensors[i].param));
+ if (ret != SENSOR_OK) {
+ return ret;
+ }
+ }
+ }
+ HILOG_DEBUG(HILOG_MODULE_SEN, "Open Rely Sensors sucess");
+ return SENSOR_OK;
+}
+
+static int32_t SensorCloseParaDecision(enum SensorTypeTag type, VsensorTaskComm *component, SensorPara *result)
+{
+ SensorPara *temp = NULL;
+ VsensorTaskInfo *vsensorInfo = NULL;
+ Vsensor *vsensor = NULL;
+
+ if (component == NULL || result == NULL) {
+ return SENSOR_TASK_CHECK_COMM_COMPONENT_NULL;
+ }
+
+ SensorParaClear(result);
+
+ for (uint32_t i = 0; i < VSENSOR_MAX_NUM; i++) {
+ vsensorInfo = (VsensorTaskInfo *)(&(component->vsensorInfo[i]));
+ if (vsensorInfo->type == (enum SensorTypeTag)0 || vsensorInfo->vsensor == NULL) {
+ continue;
+ }
+
+ vsensor = vsensorInfo->vsensor;
+ temp = NULL;
+ for (uint32_t cnt = 0; cnt < vsensor->relySensors->relySensorCnt; cnt++) {
+ if (type == vsensor->relySensors->relySensorArray[cnt].type && vsensorInfo->state == SENSOR_STATE_OPEN) {
+ temp = &(vsensor->relySensors->relySensorArray[cnt].param);
+ HILOG_INFO(
+ HILOG_MODULE_SEN, "close sensor:%d decision, vsensor:%d still running\n", type, vsensor->type);
+ }
+ }
+
+ if (temp == NULL) {
+ continue;
+ }
+
+ if (SensorParaIsClear(result)) {
+ SensorParaCopy(result, temp);
+ } else {
+ SensorPara cur = *result;
+ result->period = SENSOR_MIN(cur.period, temp->period);
+ if (result->period == 0) {
+ return SENSOR_ERROR;
+ }
+ result->batch = SENSOR_MIN(cur.batch * cur.period, temp->batch * temp->period) / result->period;
+ result->mode = SENSOR_MIN(cur.mode, temp->mode);
+ result->option = SensorOptionDecision(type, cur.option, temp->option);
+ }
+ }
+
+ return SENSOR_OK;
+}
+
+static int32_t VsensorTaskCloseRelyHsensor(VsensorTaskComm *component, enum SensorTypeTag type)
+{
+ VsensorTaskHlistener *hlistenerPool = component->hlistenersList;
+
+ VsensorTaskHlistener *var = VsensorTaskFindHlistener(hlistenerPool, VSENSOR_TASK_HLISTENER_MAX_NUM, type);
+ if ((var == NULL) || (var->type == (enum SensorTypeTag)0)) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]rely hlistenerInfo NULL! type:%d", type);
+ return SENSOR_TASK_LISTENER_FIND_NULL;
+ }
+
+ int32_t ret = SensorCloseParaDecision(type, component, &(var->hlistener.openParam));
+ if (ret != SENSOR_OK) {
+ return ret;
+ }
+
+ if (!SensorParaIsClear(&(var->hlistener.openParam))) {
+ HILOG_INFO(HILOG_MODULE_SEN,
+ "[VTASK]do not close rely sensor:%d, decision para,period:%d, batch:%d, mode:%d, option:%d\n",
+ type,
+ var->hlistener.openParam.period,
+ var->hlistener.openParam.batch,
+ var->hlistener.openParam.mode,
+ var->hlistener.openParam.option);
+ ret = HsensorMgrOpenListener(&(var->hlistener));
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]hsensor:%d enable err %d!\n", type, ret);
+ return ret;
+ }
+ return SENSOR_OK;
+ }
+
+ ret = HsensorMgrCloseListener(&(var->hlistener));
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]hsensor:%d close err!\n", type);
+ return ret;
+ }
+
+ return SENSOR_OK;
+}
+
+static int32_t VsensorTaskCloseRelySensors(
+ VsensorTaskComm *component, const RelySensorInfo *relySensors, uint8_t relyCnt)
+{
+ int32_t ret = SENSOR_OK;
+
+ if ((relySensors == NULL) || (relyCnt <= 0)) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[RELY] rely sensor is NULL!\n");
+ return SENSOR_OPEN_RELY_SENSORS_CHECK_NULL;
+ }
+
+ for (uint8_t i = 0; i < relyCnt; i++) {
+ enum SensorTypeTag type = relySensors[i].type;
+
+ if (!SensorUtilsSensorIsRegistered(type)) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[RELY] rely sensor:%d not registed!\n", type);
+ return SENSOR_TASK_RELY_SENSOR_NOT_REGISTERED;
+ }
+
+ uint32_t taskId = SensorUtilsGetRegisteredTaskId(type);
+ bool isVsensor = SensorUtilsIsVSensor(type);
+ if (isVsensor == true) {
+ // 关闭虚拟sensor
+ SensorTmsg tmsgSend = {.id = SENSOR_TMSG_VSENSOR_RELY_CLOSE_EVENT,
+ .value = (uintptr_t)type,
+ .ts = 0,
+ .info = NULL,
+ .infoSize = 0};
+
+ ret = SensorTmsgSend(taskId, &tmsgSend);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[UTIL] fa vsensor:%d send open msg FAIL!\r\n", type);
+ return ret;
+ }
+ } else {
+ /* 关闭物理sensor */
+ ret = VsensorTaskCloseRelyHsensor(component, type);
+ if (ret != SENSOR_OK) {
+ return ret;
+ }
+ }
+ }
+
+ return SENSOR_OK;
+}
+
+static bool VsensorTaskSensorBeRelied(enum SensorTypeTag type, const RelySensorInfo *relySensors, uint8_t relyCnt)
+{
+ if ((relySensors == NULL) || (relyCnt <= 0)) {
+ return false;
+ }
+
+ for (uint8_t i = 0; i < relyCnt; i++) {
+ if (relySensors[i].type == type) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static int32_t VsensorTaskHlistenerRegEvent(VsensorTaskComm *component, enum SensorTypeTag type)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "[VTASK]type:%d Hlistener RegEvent ", type);
+
+ VsensorTaskHlistener *var =
+ VsensorTaskRequestHlistener(component->hlistenersList, VSENSOR_TASK_HLISTENER_MAX_NUM, type);
+ if (var == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]VsensorTaskHlistenerRegEvent find hlistener NULL! type:%d", type);
+ return SENSOR_TASK_LISTENER_FIND_NULL;
+ }
+ int32_t ret = VsensorTaskHlistenerInit(component, var, type);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]hlistener:%d init FAIL!\n", type);
+ return ret;
+ }
+
+ ret = VsensorTaskHlistenerRegister(&(var->hlistener));
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]hlistener:%d reg FAIL!\n", type);
+ return ret;
+ }
+ return SENSOR_OK;
+}
+
+static int32_t VsensorTaskVsensorRelyReg(VsensorTaskComm *component, enum SensorTypeTag type)
+{
+ CHECK_SENSOR_TYPE_ILLEGAL_RETURN_RET(type, SENSOR_TASK_HLISTENER_REG_TYPE_ERR);
+ if (SensorUtilsIsVSensor(type)) {
+ /* 依赖虚拟传感器,do nothing */
+ HILOG_INFO(HILOG_MODULE_SEN, "[VTASK]type:%d IsVSensor do nothing", type);
+ return SENSOR_OK;
+ }
+ /* 依赖物理传感器 */
+ int32_t ret = VsensorTaskHlistenerRegEvent(component, type);
+ if (ret != SENSOR_OK) {
+ return ret;
+ }
+ return SENSOR_OK;
+}
+
+bool VsensorTaskVsensorIsRunning(const VsensorTaskInfo *vsensorInfo)
+{
+ if (vsensorInfo == NULL || vsensorInfo->vsensor == NULL) {
+ return false;
+ }
+ if (vsensorInfo->type == SENSOR_TYPE_NONE) {
+ return false;
+ }
+ if (vsensorInfo->state == SENSOR_STATE_OPEN) {
+ return true;
+ }
+ return false;
+}
+
+void VsensorTaskCommInit(VsensorTaskComm *component)
+{
+ int32_t ret = VsensorTaskCheckCommComponents(component);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]init :component is NULL!\n");
+ return;
+ }
+
+ for (uint32_t i = 0; i < VSENSOR_TASK_HLISTENER_MAX_NUM; i++) {
+ ret = memset_s(&component->hlistenersList[i].hlistener, sizeof(HsensorListener), 0, sizeof(HsensorListener));
+ if (ret != EOK) {
+ HILOG_WARN(HILOG_MODULE_SEN, "init :component memset_s hlistener failed!\n");
+ }
+ SensorPara *openParam = &(component->hlistenersList[i].hlistener.openParam);
+ SensorParaClear(openParam);
+ }
+ return;
+}
+
+int32_t VsensorTaskVsensorRegEvent(VsensorTaskComm *component, Vsensor *vsensor)
+{
+ int32_t ret = VsensorTaskCheckCommComponents(component);
+ SENSOR_CHECK_OK(ret);
+ CHECK_NULL_PTR_RETURN_VALUE(vsensor, SENSOR_VSENSOR_TASK_REG_VENSOR_NULL);
+
+ HILOG_DEBUG(HILOG_MODULE_SEN, "[VTASK]vsensor:%d reg task:%d start", vsensor->type, component->taskId);
+
+ ret = VsensorTaskVsensorReg(component, vsensor);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN,
+ "[VTASK]vsensor:%d reg task:%d FAIL!, ret:0x%04x",
+ vsensor->type,
+ component->taskId,
+ ret);
+ return ret;
+ }
+
+ RelySensorsInfo *relySensors = vsensor->relySensors;
+ CHECK_NULL_PTR_RETURN_VALUE(relySensors, SENSOR_OPEN_RELY_SENSORS_CHECK_NULL);
+ HILOG_DEBUG(
+ HILOG_MODULE_SEN, "[VTASK]vsensor:%d relySensorCnt:%u", vsensor->type, relySensors->relySensorCnt);
+ for (uint8_t i = 0; i < relySensors->relySensorCnt; i++) {
+ enum SensorTypeTag type = relySensors->relySensorArray[i].type;
+ HILOG_DEBUG(HILOG_MODULE_SEN, "[VTASK]vsensor:%d relySensor :%u", vsensor->type, type);
+ ret = VsensorTaskVsensorRelyReg(component, type);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN,
+ "[VTASK]vsensor:%d rely sensor:%d FAIL!, ret:0x%04x\n",
+ vsensor->type,
+ type,
+ ret);
+ return ret;
+ }
+ }
+ HILOG_DEBUG(HILOG_MODULE_SEN, "[VTASK]vsensor:%d reg task:%d SUCCESS", vsensor->type, component->taskId);
+ return SENSOR_OK;
+}
+
+int32_t VsensorTaskSensorDataUpdateEvent(VsensorTaskComm *component, VsensorProcessData *data)
+{
+ int32_t ret;
+ enum SensorTypeTag type;
+ Vsensor *vsensor = NULL;
+ VsensorTaskInfo *vsensorInfo = NULL;
+
+ ret = VsensorTaskCheckCommComponents(component);
+ SENSOR_CHECK_OK(ret);
+ CHECK_NULL_PTR_RETURN_VALUE(data, SENSOR_TASK_HSDATA_UPDATE_DATA_NULL);
+
+ type = data->sensor;
+
+ for (uint32_t i = 0; i < VSENSOR_MAX_NUM; i++) {
+ vsensorInfo = &(component->vsensorInfo[i]);
+ vsensor = vsensorInfo->vsensor;
+
+ /* 判断算法是否在运行 */
+ if (!VsensorTaskVsensorIsRunning(vsensorInfo)) {
+ continue;
+ }
+
+ /* 检查数据依赖 */
+ if (!VsensorTaskSensorBeRelied(type, vsensor->relySensors->relySensorArray,
+ vsensor->relySensors->relySensorCnt)) {
+ continue;
+ }
+
+ if (vsensor->process == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]vsensor_process NULL! type:%d", vsensor->type);
+ return SENSOR_TASK_VSENSOR_PROCESS_NULL;
+ }
+ ret = vsensor->process(type, data->sensordata, data->timestamp, data->dataLen);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]alg:%d process err:%x\n", vsensorInfo->type, ret);
+ continue;
+ }
+ }
+
+ return SENSOR_OK;
+}
+
+static int32_t VsensorTaskVsensorOpenRely(
+ VsensorTaskComm *component, VsensorTaskInfo *vsensorInfo, SensorPara *para, uint32_t openType)
+{
+ /* 在前面的处理中,不可能出现空指针现象 */
+ Vsensor *vsensor = vsensorInfo->vsensor;
+ if (vsensor == NULL) {
+ return SENSOR_TASK_VSENSOR_INFO_FIND_NULL;
+ }
+
+ if (vsensor->open == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]vsensor_open NULL! type:%d", vsensorInfo->type);
+ return SENSOR_TASK_VSENSOR_OPEN_NULL;
+ }
+ int32_t ret = vsensor->open(para);
+ if (ret != SENSOR_OK) {
+ return SENSOR_TASK_VSENSOR_OPEN_FAIL;
+ }
+ vsensorInfo->state = SENSOR_STATE_OPEN;
+ if (openType == APP_CTRL) {
+ SensorSetState(vsensor->type, SENSOR_STATE_OPEN);
+ if (para != NULL) {
+ SensorSetPara(vsensor->type, para);
+ }
+ }
+
+ RelySensorsInfo *relySensors = vsensor->relySensors;
+ ret = VsensorTaskOpenRelySensors(component, relySensors->relySensorArray, relySensors->relySensorCnt);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(
+ HILOG_MODULE_SEN, "[VTASK]vsensor:%d open rely sensor FAIL 0x%04x!\n", vsensorInfo->type, ret);
+ return ret;
+ }
+ HILOG_DEBUG(
+ HILOG_MODULE_SEN, "[VTASK]VsensorOpenRely type:%d openType:%u SUCESS", vsensorInfo->type, openType);
+ return SENSOR_OK;
+}
+
+int32_t VsensorTaskVsensorOpenEvent(
+ VsensorTaskComm *component, enum SensorTypeTag type, SensorPara *para, uint32_t openType)
+{
+ HILOG_DEBUG(HILOG_MODULE_SEN, "[VTASK]OpenEvent type:%d openType:%u", type, openType);
+ int32_t ret = VsensorTaskCheckCommComponents(component);
+ SENSOR_CHECK_OK(ret);
+
+ VsensorTaskInfo *vsensorInfo = VsensorTaskFindVsensorInfo(component->vsensorInfo, VSENSOR_MAX_NUM, type);
+ if (vsensorInfo == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]open find vsensorInfo NULL! type:%d", type);
+ return SENSOR_TASK_VSENSOR_INFO_FIND_NULL;
+ }
+
+ if (openType == APP_CTRL) {
+ vsensorInfo->relyedInfo.appOpenFlag = true;
+ } else { /* VSENSOR_CTRL */
+ vsensorInfo->relyedInfo.relyedCnt++;
+ }
+
+ if (vsensorInfo->state == SENSOR_STATE_OPEN) {
+ /* 已经开启vsensor,不再重复打开 */
+ if (openType == APP_CTRL) {
+ /* APP_CTRL 将状态刷新为OPEN */
+ Vsensor *vsensor = vsensorInfo->vsensor;
+ if (vsensor == NULL) {
+ return SENSOR_TASK_VSENSOR_INFO_FIND_NULL;
+ }
+ SensorSetState(vsensor->type, SENSOR_STATE_OPEN);
+ }
+ return SENSOR_OK;
+ }
+
+ return VsensorTaskVsensorOpenRely(component, vsensorInfo, para, openType);
+}
+
+int32_t VsensorTaskVsensorCloseEvent(VsensorTaskComm *component, enum SensorTypeTag type, uint32_t closeType)
+{
+ int32_t ret = VsensorTaskCheckCommComponents(component);
+ SENSOR_CHECK_OK(ret);
+
+ VsensorTaskInfo *vsensorInfo = VsensorTaskFindVsensorInfo(component->vsensorInfo, VSENSOR_MAX_NUM, type);
+ if (vsensorInfo == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]close find vsensorInfo NULL! type:%d", type);
+ return SENSOR_TASK_VSENSOR_INFO_FIND_NULL;
+ }
+
+ if (closeType == APP_CTRL) {
+ vsensorInfo->relyedInfo.appOpenFlag = false;
+ } else {
+ vsensorInfo->relyedInfo.relyedCnt--;
+ }
+
+ if (vsensorInfo->relyedInfo.relyedCnt > 0 || vsensorInfo->relyedInfo.appOpenFlag ||
+ (vsensorInfo->state == SENSOR_STATE_CLOSE)) {
+ /* (1)用户控制开和其他算法依赖开,都不能关闭虚拟传感器;(2)已经关闭的情况下无需再关闭一次 */
+ if (closeType == APP_CTRL) { // 关闭vsensor,但还存在依赖不能关闭,需将状态更新为close
+ SensorSetState(type, SENSOR_STATE_CLOSE);
+ }
+ return SENSOR_OK;
+ }
+
+ /* 在前面的处理中,不可能出现空指针现象 */
+ Vsensor *vsensor = vsensorInfo->vsensor;
+ if (vsensor == NULL) {
+ return SENSOR_TASK_VSENSOR_INFO_FIND_NULL;
+ }
+
+ if (vsensor->close == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]vsensor_close NULL! type:%d", type);
+ return SENSOR_TASK_VSENSOR_CLOSE_NULL;
+ }
+ ret = vsensor->close();
+ if (ret != SENSOR_OK) {
+ return SENSOR_TASK_VSENSOR_CLOSE_FAIL;
+ }
+ vsensorInfo->state = SENSOR_STATE_CLOSE;
+ if (closeType == APP_CTRL) {
+ SensorSetState(vsensor->type, SENSOR_STATE_CLOSE);
+ }
+
+ RelySensorsInfo *relySensors = vsensor->relySensors;
+ ret = VsensorTaskCloseRelySensors(component, relySensors->relySensorArray, relySensors->relySensorCnt);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]vsensor:%d close rely sensor FAIL!, ret:0x%04x\n", type, ret);
+ return ret;
+ }
+
+ return SENSOR_OK;
+}
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: vsensor task mgr impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "vsensor_task_mgr.h"
+#include "vsensor_task_class.h"
+#include "sensor_common.h"
+#include "sensor_log.h"
+#include "sensor_tmsg.h"
+
+/* 任务初始化 */
+int32_t VsensorTaskMgrInit(uint32_t taskId)
+{
+ VsensorTaskClass* aclassMotion = VsensorTaskClassInit(taskId, "VSENSOR_", NULL, NULL, 0);
+ if (aclassMotion == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "extern alg task create ERR!\n");
+ return SENSOR_ERROR;
+ }
+
+ return SENSOR_OK;
+}
+
+/* 任务销毁 */
+void VsensorTaskMgrDeInit(uint32_t taskId)
+{
+ VsensorTaskClass* vSensorClass = VsensorTaskClassGetByTaskid(taskId);
+ VsensorTaskClassDestruct(vSensorClass);
+}
+
+/* 任务消息处理函数入口 */
+int32_t VsensorTaskMgrMsgProcess(uint32_t taskId, const SensorTmsg *tmsg)
+{
+ VsensorTaskClass* vSensorClass = VsensorTaskClassGetByTaskid(taskId);
+ if (vSensorClass == NULL) {
+ return SENSOR_VSENSOR_TASK_CLASS_NULL;
+ }
+
+ return VsensorTaskClassMsgProcess(vSensorClass, tmsg);
+}
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: vsensor mgr service
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "vsensormgr_service.h"
+#include "securec.h"
+#include "sensor_log.h"
+#include "sensor_utils.h"
+#include "sensor_memory.h"
+#include "sensor_common.h"
+#include "sensor_task.h"
+#include "sensor_tmsg.h"
+#include "sensor_para_decision.h"
+
+typedef struct {
+ struct osal_list_head list;
+ const Vsensor *vsensor;
+} VsensorInfo;
+
+typedef struct {
+ struct osal_list_head vsensorHead;
+ uint32_t vsensorNum;
+ bool inited;
+} VsensorMgr;
+
+static VsensorMgr g_vsensormgr = {0};
+
+VsensorMgr *VsensorMgrGetInstance(void)
+{
+ return &g_vsensormgr;
+}
+
+int32_t VsensorMgrInit(void)
+{
+ VsensorMgr *vsensorMgr = VsensorMgrGetInstance();
+ if (vsensorMgr->inited) {
+ return SENSOR_OK;
+ }
+ OSAL_INIT_LIST_HEAD(&(vsensorMgr->vsensorHead));
+ vsensorMgr->vsensorNum = 0;
+
+ int32_t ret = SensorTaskInit();
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "SensorTask fail.\n");
+ return SENSOR_ERROR;
+ }
+ vsensorMgr->inited = true;
+ HILOG_INFO(HILOG_MODULE_SEN, "VsensorMgrInit OK.");
+ return SENSOR_OK;
+}
+
+static int32_t NotifyVsensorTaskRegVsensor(const Vsensor *vsensor, int32_t taskId)
+{
+ SensorTmsg tmsgSend = {
+ .id = SENSOR_TMSG_VSENSOR_REG_EVENT, .value = (uintptr_t)vsensor, .ts = 0, .info = NULL, .infoSize = 0};
+ return SensorTmsgSend(taskId, &tmsgSend);
+}
+
+static const Vsensor *VsensorMgrFindVsensor(enum SensorTypeTag type)
+{
+ VsensorMgr *vsensorMgr = VsensorMgrGetInstance();
+
+ HILOG_DEBUG(HILOG_MODULE_SEN, "vsensorNum:%u", vsensorMgr->vsensorNum);
+ VsensorInfo *vsensorIndex = NULL;
+ osal_list_for_each_entry(vsensorIndex, &vsensorMgr->vsensorHead, list)
+ {
+ HILOG_DEBUG(HILOG_MODULE_SEN, "vsensor type:%d", vsensorIndex->vsensor->type);
+ if (vsensorIndex->vsensor->type == type) {
+ return vsensorIndex->vsensor;
+ }
+ }
+ return NULL;
+}
+
+static int32_t VsensorMgrSensorOpen(const Sensor *sensor, const SensorPara *openPara)
+{
+ const Vsensor *vsensor = VsensorMgrFindVsensor(sensor->sensorInfo.type);
+ CHECK_NULL_PTR_RETURN_VALUE(vsensor, SENSOR_ERROR);
+ uint32_t taskId = SensorUtilsGetRegisteredTaskId(sensor->sensorInfo.type);
+ if (taskId == SENSOR_TASK_MAX_CNT) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] not found taskId type:%d", vsensor->type);
+ return SENSOR_ERROR;
+ }
+ /* 传递para 计算实际需要的存储空间 */
+ uint32_t dataSize = (uint32_t)(sizeof(SensorPara));
+ SensorPara *paraTemp = (SensorPara *)SensorMalloc(dataSize);
+ if (paraTemp == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "cannot malloc for sensor:%d data!, taskId:%d", sensor->sensorInfo.type, taskId);
+ return SENSOR_ERROR;
+ }
+
+ SensorParaCopy(paraTemp, openPara);
+
+ SensorTmsg tmsgSend = {.id = SENSOR_TMSG_VSENSOR_OPEN_EVENT,
+ .value = (uintptr_t)sensor->sensorInfo.type,
+ .ts = 0,
+ .info = paraTemp,
+ .infoSize = dataSize};
+ HILOG_INFO(HILOG_MODULE_SEN, "Open vsensor type: %d name: %s taskId:%u ", vsensor->type, vsensor->name, taskId);
+ return SensorTmsgSend(taskId, &tmsgSend);
+}
+
+static int32_t VsensorMgrSensorClose(const Sensor *sensor)
+{
+ const Vsensor *vsensor = VsensorMgrFindVsensor(sensor->sensorInfo.type);
+ CHECK_NULL_PTR_RETURN_VALUE(vsensor, SENSOR_ERROR);
+ uint32_t taskId = SensorUtilsGetRegisteredTaskId(sensor->sensorInfo.type);
+ if (taskId == SENSOR_TASK_MAX_CNT) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] not found taskId type:%d", vsensor->type);
+ return SENSOR_ERROR;
+ }
+ SensorTmsg tmsgSend = {
+ .id = SENSOR_TMSG_VSENSOR_CLOSE_EVENT, .value = (uintptr_t)vsensor->type, .ts = 0, .info = NULL, .infoSize = 0};
+ HILOG_INFO(HILOG_MODULE_SEN, "close vsensor type: %d name: %s taskId:%u ", vsensor->type, vsensor->name, taskId);
+ return SensorTmsgSend(taskId, &tmsgSend);
+}
+
+static int32_t VsensorMgrSensorSetBatch(Sensor *sensor, int64_t samplingInterval, int64_t reportInterval)
+{
+ HILOG_WARN(HILOG_MODULE_SEN, "unsupport");
+ return SENSOR_VSENSOR_NOT_SUPPORT;
+}
+
+static int32_t VsensorMgrSensorSetMode(Sensor *sensor, int32_t mode)
+{
+ HILOG_WARN(HILOG_MODULE_SEN, "unsupport");
+ return SENSOR_VSENSOR_NOT_SUPPORT;
+}
+
+static int32_t VsensorMgrSensorSetOption(Sensor *sensor, uint32_t option)
+{
+ HILOG_WARN(HILOG_MODULE_SEN, "unsupport");
+ return SENSOR_VSENSOR_NOT_SUPPORT;
+}
+
+static int32_t VsensorMgrSensorRegisterResultCallback(const Sensor *sensor, RecordDataCallback cb)
+{
+ const Vsensor *vsensor = VsensorMgrFindVsensor(sensor->sensorInfo.type);
+ CHECK_NULL_PTR_RETURN_VALUE(vsensor, SENSOR_ERROR);
+ return vsensor->registDataCb(cb);
+}
+
+static int32_t VsensorMgrSensorUnregisterResultCallback(const Sensor *sensor, RecordDataCallback cb)
+{
+ const Vsensor *vsensor = VsensorMgrFindVsensor(sensor->sensorInfo.type);
+ CHECK_NULL_PTR_RETURN_VALUE(vsensor, SENSOR_ERROR);
+ return vsensor->unRegistDataCb(cb);
+}
+
+static int32_t VsensorMgrSensorCalibrate(const Sensor *sensor, void *para, uint32_t len)
+{
+ HILOG_WARN(HILOG_MODULE_SEN, "unsupport");
+ return SENSOR_VSENSOR_NOT_SUPPORT;
+}
+
+static int32_t VsensorMgrSensorSelfTest(const Sensor *sensor, void *para, uint32_t len)
+{
+ HILOG_WARN(HILOG_MODULE_SEN, "unsupport");
+ return SENSOR_VSENSOR_NOT_SUPPORT;
+}
+
+static int32_t VsensorMgrSensorIoctl(const Sensor *sensor, SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+ if (cmd >= SENSOR_IOCTL_MAX || cmd < SENSOR_IOCTL_SET_PARA) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "invalid command!");
+ return SENSOR_ERROR;
+ }
+ const Vsensor *vsensor = VsensorMgrFindVsensor(sensor->sensorInfo.type);
+ if (vsensor->ioctl == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "invalid ioctl function!");
+ return SENSOR_ERROR;
+ }
+ return vsensor->ioctl(cmd, data, len);
+}
+
+static int32_t VsensorTaskRegister(const Vsensor *vsensor)
+{
+ int32_t ret = SensorTaskCreateVsensorTask(vsensor);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "vsensor type %d name %s CreateVsensorTask fail", vsensor->type, vsensor->name);
+ return SENSOR_ERROR;
+ }
+ uint32_t taskId = SensorUtilsGetRegisteredTaskId(vsensor->type);
+ if (taskId == SENSOR_TASK_MAX_CNT) {
+ SensorTaskDestroyVsensorTask(vsensor->type);
+ HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] not found taskId type:%d", vsensor->type);
+ return SENSOR_ERROR;
+ }
+ SensorUtilsRegisterVsensorType(vsensor->type);
+
+ HILOG_DEBUG(HILOG_MODULE_SEN, "vsensor type:%d taskId:%u", vsensor->type, taskId);
+ ret = NotifyVsensorTaskRegVsensor(vsensor, taskId);
+ if (ret != SENSOR_OK) {
+ SensorTaskDestroyVsensorTask(vsensor->type);
+ HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] NotifyVsensorTaskRegVsensor failed type:%d ret:%d", vsensor->type, ret);
+ return SENSOR_ERROR;
+ }
+ return SENSOR_OK;
+}
+
+static int32_t VsensorMgrSensorRegisterProc(const Vsensor *vsensor)
+{
+ Sensor *sensor = SensorUtilsRequestSensor(vsensor->type);
+ if (sensor == NULL || sensor->sensorInfo.state != SENSOR_STATE_IDLE) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "sensor type %d name %s request fail.", vsensor->type, vsensor->name);
+ return SENSOR_ERROR;
+ }
+ sensor->sensorInfo.type = vsensor->type;
+ sensor->sensorInfo.name = vsensor->name;
+ SensorParaDefaultInit(&sensor->sensorInfo.openPara);
+ sensor->open = VsensorMgrSensorOpen;
+ sensor->close = VsensorMgrSensorClose;
+ sensor->setBatch = VsensorMgrSensorSetBatch;
+ sensor->setMode = VsensorMgrSensorSetMode;
+ sensor->setOption = VsensorMgrSensorSetOption;
+ sensor->registerResultCallback = VsensorMgrSensorRegisterResultCallback;
+ sensor->unregisterResultCallback = VsensorMgrSensorUnregisterResultCallback;
+ sensor->calibrate = VsensorMgrSensorCalibrate;
+ sensor->selfTest = VsensorMgrSensorSelfTest;
+ sensor->ioctl = VsensorMgrSensorIoctl;
+ HILOG_INFO(HILOG_MODULE_SEN, "register vsensor type:%d name:%s ", sensor->sensorInfo.type, sensor->sensorInfo.name);
+ return SENSOR_OK;
+}
+
+int32_t VsensorMgrRegister(const Vsensor *vsensor)
+{
+ VsensorMgr *vsensorMgr = VsensorMgrGetInstance();
+ if (!vsensorMgr->inited && (VsensorMgrInit() != SENSOR_OK)) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "vsensorMgr inited failed.");
+ return SENSOR_ERROR;
+ }
+ int32_t ret = VsensorTaskRegister(vsensor);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] VsensorPostRegist failed type:%d", vsensor->type);
+ return SENSOR_ERROR;
+ }
+ ret = SensorUtilsAddVsensorList(vsensor->type);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(
+ HILOG_MODULE_SEN, "vsensor type %d name %s SensorUtilsAddSensorList fail", vsensor->type, vsensor->name);
+ return SENSOR_ERROR;
+ }
+ ret = VsensorMgrSensorRegisterProc(vsensor);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN,
+ "vsensor type %d name %s VsensorMgrSensorRegisterProc fail",
+ vsensor->type,
+ vsensor->name);
+ return SENSOR_ERROR;
+ }
+ VsensorInfo *vsensorInfo = SensorMalloc(sizeof(VsensorInfo));
+ CHECK_NULL_PTR_RETURN_VALUE(vsensorInfo, SENSOR_ERROR);
+ OSAL_INIT_LIST_HEAD(&(vsensorInfo->list));
+ vsensorInfo->vsensor = vsensor;
+ osal_list_add(&vsensorInfo->list, &vsensorMgr->vsensorHead);
+ vsensorMgr->vsensorNum++;
+ HILOG_INFO(HILOG_MODULE_SEN, "register vsensor type %d name %s success.", vsensor->type, vsensor->name);
+ return SENSOR_OK;
+}
\ No newline at end of file
--- /dev/null
+set(COMPONENT_NAME "sensor_hdi_acc_simulator")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+)
+
+set(PRIVATE_HEADER
+ ${ROOT_DIR}/application/wearable/ohos_deps
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../interfaces/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../sensor_mgr/include
+)
+
+set(SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/acc_simulator.c
+)
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+ -Wno-error
+ -Wno-unused-parameter
+ -fno-exceptions
+ -fno-unwind-tables
+ -fno-asynchronous-unwind-tables
+ -Wno-undef
+ -Wno-bitwise-op-parentheses
+ -Wno-shift-op-parentheses
+ -nostdlibinc
+ -nostdinc
+ -nostdlib
+ -Wno-error=unused-function
+)
+
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+set(AUTO_ADD_PATH
+ false
+)
+
+set(PUBLIC_DEFINES
+)
+
+set(CDEFINES ${CDEFINES} "CMSIS_SUPPORT")
+set(PRIVATE_DEFINES
+ ${CDEFINES}
+)
+
+build_component()
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: accel simu
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "sensor_typedef.h"
+#include "sensor_log.h"
+#include "sensor_common.h"
+#include "securec.h"
+#include "sensor_manager.h"
+#include "ohos_init.h"
+
+#define ACCEL_MAX_BATCH_COUNT 10
+
+static int32_t AccSimuInit(void);
+static int32_t AccSimuDeinit(void);
+static int32_t AccSimuOpen(SensorPara *para);
+static int32_t AccSimuClose(void);
+static int32_t AccSimuRead(uint8_t *data, uint32_t len);
+static int32_t AccSimuIoctl(SensorIoctlCmd cmd, void *data, uint32_t len);
+
+const static Hsensor g_accSimuHsensor = {
+ .type = SENSOR_TYPE_ACCELEROMETER,
+ .name = "ACCEL_SIMU",
+ .caps.sampleElementlen = sizeof(struct AccelData),
+ .caps.maxBatchCount = ACCEL_MAX_BATCH_COUNT,
+ .privateData = NULL,
+ .privateDataLen = 0,
+ .init = AccSimuInit,
+ .deinit = AccSimuDeinit,
+ .open = AccSimuOpen,
+ .close = AccSimuClose,
+ .read = AccSimuRead,
+ .ioctl = AccSimuIoctl
+};
+
+static struct AccelData g_accSimuData = {
+ .axisX = 8,
+ .axisY = 9,
+ .axisZ = 10
+};
+
+static struct AccelData g_accSimuStoreData[ACCEL_MAX_BATCH_COUNT] = {0};
+static uint32_t g_accSimuBacthCnt = 1;
+static uint32_t g_accSimuTimeStamp = 0;
+
+static void AccSimuAddStoreData()
+{
+ uint32_t top = g_accSimuBacthCnt == ACCEL_MAX_BATCH_COUNT ? ACCEL_MAX_BATCH_COUNT - 1 : g_accSimuBacthCnt;
+ if (g_accSimuBacthCnt != ACCEL_MAX_BATCH_COUNT) {
+ g_accSimuBacthCnt++;
+ }
+ for (uint32_t i = top; i > 0; i--) {
+ g_accSimuStoreData[i].axisX = g_accSimuStoreData[i - 1].axisX;
+ g_accSimuStoreData[i].axisY = g_accSimuStoreData[i - 1].axisY;
+ g_accSimuStoreData[i].axisZ = g_accSimuStoreData[i - 1].axisZ;
+ }
+ g_accSimuStoreData[0].axisX = g_accSimuData.axisX++;
+ g_accSimuStoreData[0].axisY = g_accSimuData.axisY++;
+ g_accSimuStoreData[0].axisZ = g_accSimuData.axisZ++;
+ HILOG_INFO(HILOG_MODULE_SEN,
+ "AccSimuRead dataX:%d, dataY:%d, dataZ:%d",
+ g_accSimuData.axisX,
+ g_accSimuData.axisY,
+ g_accSimuData.axisZ);
+}
+
+static int32_t AccSimuInit(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "AccSimuInit!");
+ return SENSOR_OK;
+}
+
+static int32_t AccSimuDeinit(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "AccSimuDeinit!");
+ return SENSOR_OK;
+}
+
+static int32_t AccSimuOpen(SensorPara *para)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "AccSimuOpen!");
+ return SENSOR_OK;
+}
+
+static int32_t AccSimuClose(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "AccSimuClose!");
+ g_accSimuData.axisX = 0;
+ g_accSimuData.axisY = 0;
+ g_accSimuData.axisZ = 0;
+ return SENSOR_OK;
+}
+
+static int32_t AccSimuRead(uint8_t *data, uint32_t len)
+{
+ AccSimuAddStoreData();
+ g_accSimuTimeStamp += 1;
+ CHECK_NULL_PTR_RETURN_VALUE(data, SENSOR_ERROR);
+ int32_t readLen = sizeof(struct AccelData);
+ int32_t ret = memcpy_s(data, len, &g_accSimuData, readLen);
+ if (ret != EOK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "memcpy_s err");
+ return -1;
+ }
+ g_accSimuData.axisX++;
+ g_accSimuData.axisY++;
+ g_accSimuData.axisZ++;
+ return readLen;
+}
+
+static int32_t AccSimuGetData(SensorData *sensorData)
+{
+ sensorData->data = g_accSimuStoreData;
+ size_t len = sizeof(struct AccelData);
+ sensorData->dataLen = (uint32_t)len;
+ sensorData->batchCnt = g_accSimuBacthCnt;
+ sensorData->timestamp = g_accSimuTimeStamp;
+ return SENSOR_OK;
+}
+
+static int32_t AccSimuIoctl(SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "AccSimuIoctl!");
+ switch (cmd) {
+ case SENSOR_IOCTL_GET_SENSOR_DATA:
+ AccSimuGetData((SensorData *)data);
+ break;
+ default:
+ return SENSOR_ERROR;
+ }
+ return SENSOR_OK;
+}
+
+static void AccSimuHsensorRigister(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d !", g_accSimuHsensor.type);
+ int32_t ret = SensorMgrRegistHsensor(&g_accSimuHsensor);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "RegistHsensor type:%d ERR!", g_accSimuHsensor.type);
+ return;
+ }
+ HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d SUCCESS!", g_accSimuHsensor.type);
+}
+
+APP_FEATURE_INIT_PRI(AccSimuHsensorRigister, 3);
--- /dev/null
+set(COMPONENT_NAME "sensor_hdi_barometer")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+)
+
+set(PRIVATE_HEADER
+ ${ROOT_DIR}/application/wearable/ohos_deps
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../interfaces/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../sensor_mgr/include
+)
+
+set(SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/barometer.c
+)
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+ -Wno-error
+ -Wno-unused-parameter
+ -fno-exceptions
+ -fno-unwind-tables
+ -fno-asynchronous-unwind-tables
+ -Wno-undef
+ -Wno-bitwise-op-parentheses
+ -Wno-shift-op-parentheses
+ -nostdlibinc
+ -nostdinc
+ -nostdlib
+ -Wno-error=unused-function
+)
+
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+set(AUTO_ADD_PATH
+ false
+)
+
+set(PUBLIC_DEFINES
+)
+
+set(CDEFINES ${CDEFINES} "CMSIS_SUPPORT")
+set(PRIVATE_DEFINES
+ ${CDEFINES}
+)
+
+build_component()
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: baroMeter simu
+ * Author: Media Software Group
+ * Create: 2025-09-25
+ */
+
+#include "sensor_typedef.h"
+#include "sensor_log.h"
+#include "sensor_common.h"
+#include "securec.h"
+#include "sensor_manager.h"
+#include "ohos_init.h"
+
+#define MAX_BATCH_COUNT 10
+
+static int32_t BaroMeterInit(void);
+static int32_t BaroMeterDeInit(void);
+static int32_t BaroMeterOpen(SensorPara *para);
+static int32_t BaroMeterClose(void);
+static int32_t BaroMeterRead(uint8_t *data, uint32_t len);
+static int32_t BaroMeterIoctl(SensorIoctlCmd cmd, void *data, uint32_t len);
+
+const static Hsensor g_baroMeterHsensor = {
+ .type = SENSOR_TYPE_BAROMETER,
+ .name = "BARO_METER",
+ .caps.sampleElementlen = sizeof(struct PressureData),
+ .caps.maxBatchCount = MAX_BATCH_COUNT,
+ .privateData = NULL,
+ .privateDataLen = 0,
+ .init = BaroMeterInit,
+ .deinit = BaroMeterDeInit,
+ .open = BaroMeterOpen,
+ .close = BaroMeterClose,
+ .read = BaroMeterRead,
+ .ioctl = BaroMeterIoctl
+};
+
+static struct PressureData g_baroMeterData = {
+ .pressure = 8,
+ .temperature = 9,
+ .dataValid = 0
+};
+
+static int32_t BaroMeterInit(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "BaroMeterInit!");
+ g_baroMeterData.dataValid = 1;
+ return SENSOR_OK;
+}
+
+static int32_t BaroMeterDeInit(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "BaroMeterDeInit!");
+ return SENSOR_OK;
+}
+
+static int32_t BaroMeterOpen(SensorPara *para)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "BaroMeterOpen!");
+ return SENSOR_OK;
+}
+
+static int32_t BaroMeterClose(void)
+{
+ g_baroMeterData.pressure = 0;
+ g_baroMeterData.temperature = 0;
+ g_baroMeterData.dataValid = 0;
+ HILOG_INFO(HILOG_MODULE_SEN, "BaroMeterClose!");
+ return SENSOR_OK;
+}
+
+static int32_t BaroMeterRead(uint8_t *data, uint32_t len)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "BaroMeterRead");
+ CHECK_NULL_PTR_RETURN_VALUE(data, SENSOR_ERROR);
+ int32_t readLen = sizeof(struct PressureData);
+ int32_t ret = memcpy_s(data, len, &g_baroMeterData, readLen);
+ if (ret != EOK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "memcpy_s err");
+ return -1;
+ }
+ g_baroMeterData.pressure++;
+ g_baroMeterData.temperature++;
+ return readLen;
+}
+
+static int32_t BaroMeterIoctl(SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "BaroMeterIoctl!");
+ return SENSOR_OK;
+}
+
+static void BaroMeterHsensorRigister(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d !", g_baroMeterHsensor.type);
+ int32_t ret = SensorMgrRegistHsensor(&g_baroMeterHsensor);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "RegistHsensor type:%d ERR!", g_baroMeterHsensor.type);
+ return;
+ }
+ HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d SUCCESS!", g_baroMeterHsensor.type);
+}
+
+APP_FEATURE_INIT_PRI(BaroMeterHsensorRigister, 3);
--- /dev/null
+set(COMPONENT_NAME "sensor_hdi_gyroscope")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+)
+
+set(PRIVATE_HEADER
+ ${ROOT_DIR}/application/wearable/ohos_deps
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../interfaces/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../sensor_mgr/include
+)
+
+set(SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/gyroscope.c
+)
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+ -Wno-error
+ -Wno-unused-parameter
+ -fno-exceptions
+ -fno-unwind-tables
+ -fno-asynchronous-unwind-tables
+ -Wno-undef
+ -Wno-bitwise-op-parentheses
+ -Wno-shift-op-parentheses
+ -nostdlibinc
+ -nostdinc
+ -nostdlib
+ -Wno-error=unused-function
+)
+
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+set(AUTO_ADD_PATH
+ false
+)
+
+set(PUBLIC_DEFINES
+)
+
+set(CDEFINES ${CDEFINES} "CMSIS_SUPPORT")
+set(PRIVATE_DEFINES
+ ${CDEFINES}
+)
+
+build_component()
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: gyroScope simu
+ * Author: Media Software Group
+ * Create: 2025-09-25
+ */
+
+#include "sensor_typedef.h"
+#include "sensor_log.h"
+#include "sensor_common.h"
+#include "securec.h"
+#include "sensor_manager.h"
+#include "ohos_init.h"
+
+#define ACCEL_MAX_BATCH_COUNT 10
+
+static int32_t GyroScopeInit(void);
+static int32_t GyroScopeDeinit(void);
+static int32_t GyroScopeOpen(SensorPara *para);
+static int32_t GyroScopeClose(void);
+static int32_t GyroScopeRead(uint8_t *data, uint32_t len);
+static int32_t GyroScopeIoctl(SensorIoctlCmd cmd, void *data, uint32_t len);
+
+const static Hsensor g_gyroScopeHsensor = {
+ .type = SENSOR_TYPE_GYROSCOPE,
+ .name = "GYRO_SCOPE",
+ .caps.sampleElementlen = sizeof(struct GyroData),
+ .caps.maxBatchCount = ACCEL_MAX_BATCH_COUNT,
+ .privateData = NULL,
+ .privateDataLen = 0,
+ .init = GyroScopeInit,
+ .deinit = GyroScopeDeinit,
+ .open = GyroScopeOpen,
+ .close = GyroScopeClose,
+ .read = GyroScopeRead,
+ .ioctl = GyroScopeIoctl
+};
+
+static struct GyroData g_gyroScopeData = {
+ .axisX = 8,
+ .axisY = 9,
+ .axisZ = 10
+};
+
+static int32_t GyroScopeInit(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "GyroScopeInit!");
+ return SENSOR_OK;
+}
+
+static int32_t GyroScopeDeinit(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "GyroScopeDeinit!");
+ return SENSOR_OK;
+}
+
+static int32_t GyroScopeOpen(SensorPara *para)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "GyroScopeOpen!");
+ return SENSOR_OK;
+}
+
+static int32_t GyroScopeClose(void)
+{
+ g_gyroScopeData.axisX = 0;
+ g_gyroScopeData.axisY = 0;
+ g_gyroScopeData.axisZ = 0;
+ HILOG_INFO(HILOG_MODULE_SEN, "GyroScopeClose!");
+ return SENSOR_OK;
+}
+
+static int32_t GyroScopeRead(uint8_t *data, uint32_t len)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "GyroScopeRead");
+ CHECK_NULL_PTR_RETURN_VALUE(data, SENSOR_ERROR);
+ int32_t readLen = sizeof(struct GyroData);
+ int32_t ret = memcpy_s(data, len, &g_gyroScopeData, readLen);
+ if (ret != EOK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "memcpy_s err");
+ return -1;
+ }
+ g_gyroScopeData.axisX++;
+ g_gyroScopeData.axisY++;
+ g_gyroScopeData.axisZ++;
+ return readLen;
+}
+
+static int32_t GyroScopeIoctl(SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "GyroScopeIoctl!");
+ return SENSOR_OK;
+}
+
+static void GyroScopeHsensorRigister(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d !", g_gyroScopeHsensor.type);
+ int32_t ret = SensorMgrRegistHsensor(&g_gyroScopeHsensor);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "RegistHsensor type:%d ERR!", g_gyroScopeHsensor.type);
+ return;
+ }
+ HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d SUCCESS!", g_gyroScopeHsensor.type);
+}
+
+APP_FEATURE_INIT_PRI(GyroScopeHsensorRigister, 3);
--- /dev/null
+set(COMPONENT_NAME "sensor_hdi_hr_counter")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+)
+
+set(PRIVATE_HEADER
+ ${ROOT_DIR}/application/wearable/ohos_deps
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../interfaces/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../sensor_mgr/include
+)
+
+set(SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/heart_rate_counter.c
+)
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+ -Wno-error
+ -Wno-unused-parameter
+ -fno-exceptions
+ -fno-unwind-tables
+ -fno-asynchronous-unwind-tables
+ -Wno-undef
+ -Wno-bitwise-op-parentheses
+ -Wno-shift-op-parentheses
+ -nostdlibinc
+ -nostdinc
+ -nostdlib
+ -Wno-error=unused-function
+)
+
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+set(AUTO_ADD_PATH
+ false
+)
+
+set(PUBLIC_DEFINES
+)
+
+set(CDEFINES ${CDEFINES} "CMSIS_SUPPORT")
+set(PRIVATE_DEFINES
+ ${CDEFINES}
+)
+
+build_component()
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: heart rate simu
+ * Author: Media Software Group
+ * Create: 2025-09-25
+ */
+
+#include "sensor_typedef.h"
+#include "sensor_log.h"
+#include "sensor_common.h"
+#include "securec.h"
+#include "sensor_manager.h"
+#include "ohos_init.h"
+
+#define MAX_BATCH_COUNT 10
+#define DEFAULT_HEART_RATE 80
+
+static int32_t HeartRateInit(void);
+static int32_t HeartRateDeinit(void);
+static int32_t HeartRateOpen(SensorPara *para);
+static int32_t HeartRateClose(void);
+static int32_t HeartRateRead(uint8_t *data, uint32_t len);
+static int32_t HeartRateIoctl(SensorIoctlCmd cmd, void *data, uint32_t len);
+
+const static Hsensor g_heartRateHsensor = {
+ .type = SENSOR_TYPE_HEART_RATE,
+ .name = "HEART_RATE",
+ .caps.sampleElementlen = sizeof(int32_t),
+ .caps.maxBatchCount = MAX_BATCH_COUNT,
+ .privateData = NULL,
+ .privateDataLen = 0,
+ .init = HeartRateInit,
+ .deinit = HeartRateDeinit,
+ .open = HeartRateOpen,
+ .close = HeartRateClose,
+ .read = HeartRateRead,
+ .ioctl = HeartRateIoctl
+};
+
+static int32_t g_heartRate = 0;
+
+static int32_t HeartRateInit(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "HeartRateInit!");
+ return SENSOR_OK;
+}
+
+static int32_t HeartRateDeinit(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "HeartRateDeinit!");
+ return SENSOR_OK;
+}
+
+static int32_t HeartRateOpen(SensorPara *para)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "HeartRateOpen!");
+ g_heartRate = DEFAULT_HEART_RATE;
+ return SENSOR_OK;
+}
+
+static int32_t HeartRateClose(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "HeartRateClose!");
+ g_heartRate = 0;
+ return SENSOR_OK;
+}
+
+static int32_t HeartRateRead(uint8_t *data, uint32_t len)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "HeartRateRead");
+ CHECK_NULL_PTR_RETURN_VALUE(data, SENSOR_ERROR);
+ int32_t readLen = sizeof(int32_t);
+ int32_t ret = memcpy_s(data, len, &g_heartRate, readLen);
+ if (ret != EOK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "memcpy_s err");
+ return -1;
+ }
+ g_heartRate++;
+ return readLen;
+}
+
+static int32_t HeartRateIoctl(SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "HeartRateIoctl!");
+ return SENSOR_OK;
+}
+
+static void HeartRateHsensorRigister(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d !", g_heartRateHsensor.type);
+ int32_t ret = SensorMgrRegistHsensor(&g_heartRateHsensor);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "RegistHsensor type:%d ERR!", g_heartRateHsensor.type);
+ return;
+ }
+ HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d SUCCESS!", g_heartRateHsensor.type);
+}
+
+APP_FEATURE_INIT_PRI(HeartRateHsensorRigister, 3);
--- /dev/null
+set(COMPONENT_NAME "sensor_hdi_pedometer")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+)
+
+set(PRIVATE_HEADER
+ ${ROOT_DIR}/application/wearable/ohos_deps
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../interfaces/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../sensor_mgr/include
+)
+
+set(SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/pedometer.c
+)
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+ -Wno-error
+ -Wno-unused-parameter
+ -fno-exceptions
+ -fno-unwind-tables
+ -fno-asynchronous-unwind-tables
+ -Wno-undef
+ -Wno-bitwise-op-parentheses
+ -Wno-shift-op-parentheses
+ -nostdlibinc
+ -nostdinc
+ -nostdlib
+ -Wno-error=unused-function
+)
+
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+set(AUTO_ADD_PATH
+ false
+)
+
+set(PUBLIC_DEFINES
+)
+
+set(CDEFINES ${CDEFINES} "CMSIS_SUPPORT")
+set(PRIVATE_DEFINES
+ ${CDEFINES}
+)
+
+build_component()
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: pedometer simu
+ * Author: Media Software Group
+ * Create: 2025-09-25
+ */
+
+#include "sensor_typedef.h"
+#include "sensor_log.h"
+#include "sensor_common.h"
+#include "securec.h"
+#include "sensor_manager.h"
+#include "ohos_init.h"
+
+#define ACCEL_MAX_BATCH_COUNT 10
+
+static int32_t PedoMeterInit(void);
+static int32_t PedoMeterDeinit(void);
+static int32_t PedoMeterOpen(SensorPara *para);
+static int32_t PedoMeterClose(void);
+static int32_t PedoMeterRead(uint8_t *data, uint32_t len);
+static int32_t PedoMeterIoctl(SensorIoctlCmd cmd, void *data, uint32_t len);
+
+const static Hsensor g_pedoMeterHsensor = {
+ .type = SENSOR_TYPE_PEDOMETER,
+ .name = "PEDO_METER",
+ .caps.sampleElementlen = sizeof(int32_t),
+ .caps.maxBatchCount = ACCEL_MAX_BATCH_COUNT,
+ .privateData = NULL,
+ .privateDataLen = 0,
+ .init = PedoMeterInit,
+ .deinit = PedoMeterDeinit,
+ .open = PedoMeterOpen,
+ .close = PedoMeterClose,
+ .read = PedoMeterRead,
+ .ioctl = PedoMeterIoctl
+};
+
+static int32_t g_pedoMeterData = 0;
+
+static int32_t PedoMeterInit(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "PedoMeterInit!");
+ return SENSOR_OK;
+}
+
+static int32_t PedoMeterDeinit(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "PedoMeterDeinit!");
+ return SENSOR_OK;
+}
+
+static int32_t PedoMeterOpen(SensorPara *para)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "PedoMeterOpen!");
+ return SENSOR_OK;
+}
+
+static int32_t PedoMeterClose(void)
+{
+ g_pedoMeterData = 0;
+ HILOG_INFO(HILOG_MODULE_SEN, "PedoMeterClose!");
+ return SENSOR_OK;
+}
+
+static int32_t PedoMeterRead(uint8_t *data, uint32_t len)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "PedoMeterRead");
+ CHECK_NULL_PTR_RETURN_VALUE(data, SENSOR_ERROR);
+ int32_t readLen = sizeof(int32_t);
+ int32_t ret = memcpy_s(data, len, &g_pedoMeterData, readLen);
+ if (ret != EOK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "memcpy_s err");
+ return -1;
+ }
+ g_pedoMeterData++;
+ return readLen;
+}
+
+static int32_t PedoMeterIoctl(SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "PedoMeterIoctl!");
+ return SENSOR_OK;
+}
+
+static void PedoMeterHsensorRigister(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d !", g_pedoMeterHsensor.type);
+ int32_t ret = SensorMgrRegistHsensor(&g_pedoMeterHsensor);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "RegistHsensor type:%d ERR!", g_pedoMeterHsensor.type);
+ return;
+ }
+ HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d SUCCESS!", g_pedoMeterHsensor.type);
+}
+
+APP_FEATURE_INIT_PRI(PedoMeterHsensorRigister, 3);
--- /dev/null
+set(COMPONENT_NAME "sensor_hdi_wear_detection")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+)
+
+set(PRIVATE_HEADER
+ ${ROOT_DIR}/application/wearable/ohos_deps
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../interfaces/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../sensor_mgr/include
+)
+
+set(SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/wear_detection.c
+)
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+ -Wno-error
+ -Wno-unused-parameter
+ -fno-exceptions
+ -fno-unwind-tables
+ -fno-asynchronous-unwind-tables
+ -Wno-undef
+ -Wno-bitwise-op-parentheses
+ -Wno-shift-op-parentheses
+ -nostdlibinc
+ -nostdinc
+ -nostdlib
+ -Wno-error=unused-function
+)
+
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+set(AUTO_ADD_PATH
+ false
+)
+
+set(PUBLIC_DEFINES
+)
+
+set(CDEFINES ${CDEFINES} "CMSIS_SUPPORT")
+set(PRIVATE_DEFINES
+ ${CDEFINES}
+)
+
+build_component()
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: wear detection simu
+ * Author: Media Software Group
+ * Create: 2025-09-25
+ */
+
+#include "sensor_typedef.h"
+#include "sensor_log.h"
+#include "sensor_common.h"
+#include "securec.h"
+#include "sensor_manager.h"
+#include "ohos_init.h"
+
+#define ACCEL_MAX_BATCH_COUNT 10
+
+static int32_t WearDetectionInit(void);
+static int32_t WearDetectionDeinit(void);
+static int32_t WearDetectionOpen(SensorPara *para);
+static int32_t WearDetectionClose(void);
+static int32_t WearDetectionRead(uint8_t *data, uint32_t len);
+static int32_t WearDetectionIoctl(SensorIoctlCmd cmd, void *data, uint32_t len);
+
+const static Hsensor g_wearDetectionHsensor = {
+ .type = SENSOR_TYPE_WEAR_DETECTION,
+ .name = "WEAR_DETECTION",
+ .caps.sampleElementlen = sizeof(bool),
+ .caps.maxBatchCount = ACCEL_MAX_BATCH_COUNT,
+ .privateData = NULL,
+ .privateDataLen = 0,
+ .init = WearDetectionInit,
+ .deinit = WearDetectionDeinit,
+ .open = WearDetectionOpen,
+ .close = WearDetectionClose,
+ .read = WearDetectionRead,
+ .ioctl = WearDetectionIoctl
+};
+
+static bool g_wearStatus = false;
+
+static int32_t WearDetectionInit(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "WearDetectionInit!");
+ return SENSOR_OK;
+}
+
+static int32_t WearDetectionDeinit(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "WearDetectionDeinit!");
+ return SENSOR_OK;
+}
+
+static int32_t WearDetectionOpen(SensorPara *para)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "WearDetectionOpen!");
+ g_wearStatus = true;
+ return SENSOR_OK;
+}
+
+static int32_t WearDetectionClose(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "WearDetectionClose!");
+ g_wearStatus = false;
+ return SENSOR_OK;
+}
+
+static int32_t WearDetectionRead(uint8_t *data, uint32_t len)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "WearDetectionRead");
+ CHECK_NULL_PTR_RETURN_VALUE(data, SENSOR_ERROR);
+ int32_t readLen = sizeof(bool);
+ int32_t ret = memcpy_s(data, len, &g_wearStatus, readLen);
+ if (ret != EOK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "memcpy_s err");
+ return -1;
+ }
+ return readLen;
+}
+
+static int32_t WearDetectionIoctl(SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "WearDetectionIoctl!");
+ return SENSOR_OK;
+}
+
+static void WearDetectionHsensorRigister(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d !", g_wearDetectionHsensor.type);
+ int32_t ret = SensorMgrRegistHsensor(&g_wearDetectionHsensor);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "RegistHsensor type:%d ERR!", g_wearDetectionHsensor.type);
+ return;
+ }
+ HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d SUCCESS!", g_wearDetectionHsensor.type);
+}
+
+APP_FEATURE_INIT_PRI(WearDetectionHsensorRigister, 3);
--- /dev/null
+set(COMPONENT_NAME "sensor_hdi_acc_alg_simulator")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+)
+
+set(PRIVATE_HEADER
+ ${ROOT_DIR}/application/wearable/ohos_deps
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../interfaces/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../sensor_mgr/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../common/include
+)
+
+set(SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/acc_alg_simulator.c
+)
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+ -Wno-error
+ -Wno-unused-parameter
+ -fno-exceptions
+ -fno-unwind-tables
+ -fno-asynchronous-unwind-tables
+ -Wno-undef
+ -Wno-bitwise-op-parentheses
+ -Wno-shift-op-parentheses
+ -nostdlibinc
+ -nostdinc
+ -nostdlib
+ -Wno-error=unused-function
+)
+
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+set(AUTO_ADD_PATH
+ false
+)
+
+set(PUBLIC_DEFINES
+)
+
+set(CDEFINES ${CDEFINES} "CMSIS_SUPPORT")
+set(PRIVATE_DEFINES
+ ${CDEFINES}
+)
+
+build_component()
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: accel vsensor simu
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "sensor_common.h"
+#include "vsensor_common.h"
+#include "securec.h"
+#include "sensor_manager.h"
+#include "sensor_log.h"
+#include "ohos_init.h"
+
+#define ACC_ALG_PERIOD_MS 100 // ms
+#define ACC_ALG_BATCH_COUNT 5
+
+#define ACC_ALG_OFFSET 10
+
+static int32_t AccAlgSimuDataCbRegister(RecordDataCallback cb);
+static int32_t AccAlgSimuDataCbUnRegister(RecordDataCallback cb);
+static int32_t AccAlgSimuOpen(SensorPara *para);
+static int32_t AccAlgSimuClose(void);
+static int32_t AccAlgSimuProcess(enum SensorTypeTag type, uint8_t *data, uint64_t ts, uint32_t len);
+static int32_t AccAlgSimuIoctl(SensorIoctlCmd cmd, void *data, uint32_t len);
+static int32_t AccAlgSimuGetData(SensorData *sensorData);
+
+typedef struct {
+ struct osal_list_head dataCbListHead; /* DataCallbackInfo head */
+ uint32_t dataCbNum;
+ uint32_t batchCount;
+ uint32_t timeStamp;
+ struct AccelData accAlgSimuData[ACC_ALG_BATCH_COUNT];
+} AccAlgSimuContext;
+
+const RelySensorInfo g_accAlgSimuRelySensor[] = {
+ {
+ .type = SENSOR_TYPE_ACCELEROMETER,
+ .param = {
+ .period = ACC_ALG_PERIOD_MS,
+ .batch = ACC_ALG_BATCH_COUNT,
+ .mode = SENSOR_MODE_REALTIME,
+ .option = 0
+ }
+ }
+};
+
+const RelySensorsInfo g_accAlgSimuRelySensors = {
+ .relySensorArray = (RelySensorInfo*)g_accAlgSimuRelySensor,
+ .relySensorCnt = sizeof(g_accAlgSimuRelySensor) / sizeof(RelySensorInfo)
+};
+
+const static Vsensor g_accAlgSimuVsensor = {
+ .type = SENSOR_TYPE_VSENSOR_ACCELEROMETER_ALG_SIMU,
+ .name = "ACCEL_ALG_SIMU",
+ .privateData = NULL,
+ .privateDataLen = 0,
+ .relySensors = (RelySensorsInfo*)&g_accAlgSimuRelySensors,
+ .registDataCb = AccAlgSimuDataCbRegister,
+ .unRegistDataCb = AccAlgSimuDataCbUnRegister,
+ .open = AccAlgSimuOpen,
+ .close = AccAlgSimuClose,
+ .process = AccAlgSimuProcess,
+ .ioctl = AccAlgSimuIoctl,
+};
+
+AccAlgSimuContext g_accAlgSimuCtx = {
+ .dataCbNum = 0,
+ .batchCount = 0,
+ .timeStamp = 0,
+ .accAlgSimuData = {0},
+};
+
+struct AccelData g_storeAccData[ACC_ALG_BATCH_COUNT] = {0};
+static uint32_t g_storeBatchCnt = 1;
+static uint32_t g_storeTimeStamp = 0;
+static int32_t AccAlgSimuDataCbRegister(RecordDataCallback cb)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "IN");
+ if (g_accAlgSimuCtx.dataCbNum == 0) {
+ OSAL_INIT_LIST_HEAD(&(g_accAlgSimuCtx.dataCbListHead));
+ }
+ DataCallbackInfo *dataCallbackInfoIndex = NULL;
+ osal_list_for_each_entry(dataCallbackInfoIndex, &g_accAlgSimuCtx.dataCbListHead, list)
+ {
+ if (cb == dataCallbackInfoIndex->dataCb) {
+ HILOG_INFO(HILOG_MODULE_SEN, "cb :%p is Registed");
+ return SENSOR_OK;
+ }
+ }
+ DataCallbackInfo *dataCallbackInfo = (DataCallbackInfo *)malloc(sizeof(DataCallbackInfo));
+ if (dataCallbackInfo == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "malloc DataCallbackInfo failed!");
+ return SENSOR_ERROR;
+ }
+ OSAL_INIT_LIST_HEAD(&(dataCallbackInfo->list));
+ dataCallbackInfo->dataCb = cb;
+ osal_list_add(&dataCallbackInfo->list, &g_accAlgSimuCtx.dataCbListHead);
+ g_accAlgSimuCtx.dataCbNum++;
+ return SENSOR_OK;
+}
+
+static int32_t AccAlgSimuDataCbUnRegister(RecordDataCallback cb)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "IN");
+ DataCallbackInfo *dataCallbackInfoIndex = NULL;
+ DataCallbackInfo *dataCallbackInfo = NULL;
+ osal_list_for_each_entry(dataCallbackInfoIndex, &g_accAlgSimuCtx.dataCbListHead, list)
+ {
+ if (cb == dataCallbackInfoIndex->dataCb) {
+ dataCallbackInfo = dataCallbackInfoIndex;
+ HILOG_INFO(HILOG_MODULE_SEN, "cb is Registed");
+ break;
+ }
+ }
+ if (dataCallbackInfo == NULL) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "DataCallback not Registed!");
+ return SENSOR_ERROR;
+ }
+ osal_list_del(&dataCallbackInfo->list);
+ free(dataCallbackInfo);
+ g_accAlgSimuCtx.dataCbNum--;
+ return SENSOR_OK;
+}
+
+
+static int32_t AccAlgSimuOpen(SensorPara *para)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "IN");
+ return SENSOR_OK;
+}
+
+static int32_t AccAlgSimuClose(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "IN");
+ for (uint32_t i = 0; i < ACC_ALG_BATCH_COUNT; i++) {
+ g_accAlgSimuCtx.accAlgSimuData[i].axisX = 0;
+ g_accAlgSimuCtx.accAlgSimuData[i].axisY = 0;
+ g_accAlgSimuCtx.accAlgSimuData[i].axisZ = 0;
+ }
+ return SENSOR_OK;
+}
+
+static int32_t AccAlgSimuProcess(enum SensorTypeTag type, uint8_t *data, uint64_t ts, uint32_t len)
+{
+ HILOG_DEBUG(HILOG_MODULE_SEN, "Acc ALG Process ts :%llu len:%u!", ts, len);
+ uint32_t accelDataLen = sizeof(struct AccelData);
+ struct AccelData *orgAccelData = (struct AccelData*)data;
+ if (orgAccelData == NULL || (len % sizeof(struct AccelData)) != 0) {
+ HILOG_INFO(HILOG_MODULE_SEN, "Acc ALG Process :%llu invalid data!", ts);
+ return -1;
+ }
+ uint32_t batchCount = len / accelDataLen;
+ if (batchCount > ACC_ALG_BATCH_COUNT) {
+ HILOG_INFO(HILOG_MODULE_SEN, "Acc ALG Process :%llu invalid batchCount:%u!", ts, batchCount);
+ return -1;
+ }
+ for (uint32_t i = 0; i < batchCount; i++) {
+ g_accAlgSimuCtx.accAlgSimuData[i].axisX = orgAccelData[i].axisX + ACC_ALG_OFFSET;
+ g_accAlgSimuCtx.accAlgSimuData[i].axisY = orgAccelData[i].axisY + ACC_ALG_OFFSET;
+ g_accAlgSimuCtx.accAlgSimuData[i].axisZ = orgAccelData[i].axisZ + ACC_ALG_OFFSET;
+ g_storeAccData[i].axisX = orgAccelData[i].axisX + ACC_ALG_OFFSET;
+ g_storeAccData[i].axisY = orgAccelData[i].axisY + ACC_ALG_OFFSET;
+ g_storeAccData[i].axisZ = orgAccelData[i].axisZ + ACC_ALG_OFFSET;
+ }
+ g_accAlgSimuCtx.batchCount = batchCount;
+ g_accAlgSimuCtx.timeStamp = ts;
+ g_storeTimeStamp = g_accAlgSimuCtx.timeStamp;
+ g_storeBatchCnt = g_accAlgSimuCtx.batchCount;
+ DataCallbackInfo *dataCallbackInfoIndex = NULL;
+ osal_list_for_each_entry(dataCallbackInfoIndex, &g_accAlgSimuCtx.dataCbListHead, list)
+ {
+ struct SensorEvents sensorEvent = {
+ .sensorId = type,
+ .version = 0,
+ .timestamp = ts,
+ .option = 0,
+ .mode = 0,
+ .data = (uint8_t *)g_accAlgSimuCtx.accAlgSimuData,
+ .dataLen = len,
+ };
+ dataCallbackInfoIndex->dataCb(&sensorEvent);
+ }
+ return SENSOR_OK;
+}
+
+static int32_t AccAlgSimuIoctl(SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "AccAlgSimuIoctl!");
+ switch (cmd) {
+ case SENSOR_IOCTL_GET_SENSOR_DATA:
+ AccAlgSimuGetData((SensorData *)data);
+ break;
+ default:
+ return SENSOR_ERROR;
+ }
+ return SENSOR_OK;
+}
+
+static int32_t AccAlgSimuGetData(SensorData *sensorData)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "AccAlgSimuGetData!");
+ sensorData->data = (uint8_t *)(g_storeAccData);
+ size_t len = sizeof(struct AccelData);
+ sensorData->dataLen = (uint32_t)len;
+ sensorData->batchCnt = g_storeBatchCnt;
+ sensorData->timestamp = g_storeTimeStamp;
+ HILOG_INFO(HILOG_MODULE_SEN,
+ "SensorData datalen:%u batchcnt:%u timestamp:%lld",
+ sensorData->dataLen,
+ sensorData->batchCnt,
+ sensorData->timestamp);
+ return SENSOR_OK;
+}
+
+static void AccAlgSimuVsensorRegister(void)
+{
+ HILOG_INFO(HILOG_MODULE_SEN, "RegistVsensor type:%d in !", g_accAlgSimuVsensor.type);
+ int32_t ret = SensorMgrRegistVsensor(&g_accAlgSimuVsensor);
+ if (ret != SENSOR_OK) {
+ HILOG_ERROR(HILOG_MODULE_SEN, "RegistHsensor type:%d ERR!", g_accAlgSimuVsensor.type);
+ return;
+ }
+ HILOG_INFO(HILOG_MODULE_SEN, "RegistVsensor type:%d SUCCESS!", g_accAlgSimuVsensor.type);
+}
+
+APP_FEATURE_INIT_PRI(AccAlgSimuVsensorRegister, 4);
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: vsensor common
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef HDI_V_SENSOR_COMMON_H
+#define HDI_V_SENSOR_COMMON_H
+
+#include <stdio.h>
+#include "sensor_typedef.h"
+#include "sensor_log.h"
+#include "soc_osal.h"
+
+typedef struct {
+ struct osal_list_head list; /* link point */
+ RecordDataCallback dataCb;
+} DataCallbackInfo;
+
+#endif /* HDI_V_SENSOR_COMMON_H */
* @since 2.2
* @version 1.0
*/
- int32_t (*Enable)(int32_t sensorTypeId);
+ int32_t (*Enable)(int32_t sensorId);
/**
* @brief Disables an enabled sensor.
* @since 2.2
* @version 1.0
*/
- int32_t (*Disable)(int32_t sensorTypeId);
+ int32_t (*Disable)(int32_t sensorId);
/**
* @brief Sets the data sampling interval and data reporting interval for the specified sensor.
* @since 2.2
* @version 1.0
*/
- int32_t (*SetBatch)(int32_t sensorTypeId, int64_t samplingInterval, int64_t reportInterval);
+ int32_t (*SetBatch)(int32_t sensorId, int64_t samplingInterval, int64_t reportInterval);
/**
* @brief Sets the data reporting mode for the specified sensor.
* @since 2.2
* @version 1.0
*/
- int32_t (*SetMode)(int32_t sensorTypeId, int32_t mode);
+ int32_t (*SetMode)(int32_t sensorId, int32_t mode);
/**
* @brief Sets options for the specified sensor, including its measurement range and accuracy.
* @since 2.2
* @version 1.0
*/
- int32_t (*SetOption)(int32_t sensorTypeId, uint32_t option);
+ int32_t (*SetOption)(int32_t sensorId, uint32_t option);
/**
* @brief Registers the callback for reporting sensor data to the subscriber.
*
+ * @param sensorTypeId Indicates the sensor group ID.
+ * The sensorId enumeration value range is 128-160, which means that the medical sensor service is subscribed.
+ * It only needs to be subscribed once successfully, and there is no need to subscribe repeatedly.
+ * The sensorId enumeration value range is not within 128-160, which means that the traditional sensor
+ * is subscribed, and the subscription is successful once.
* @param cb Indicates the callback to register. For details, see {@link RecordDataCallback}.
* @return Returns <b>0</b> if the callback is successfully registered; returns a negative value otherwise.
*
/**
* @brief Deregisters the callback for reporting sensor data.
*
+ * @param sensorTypeId Indicates the sensor group ID.
+ * The sensorId enumeration value range is 128-160, which means that the medical sensor service is subscribed.
+ * It only needs to cancel the subscription once successfully, and there is no need to
+ * cancel the subscription repeatedly. The sensorId enumeration value range is not within 128-160,
+ * which means that the traditional sensor is subscribed. You can cancel the subscription once successfully.
+ * @param cb Indicates the callback to register. For details, see {@link RecordDataCallback}.
* @return Returns <b>0</b> if the callback is successfully deregistered; returns a negative value otherwise.
*
* @since 2.2
* @version 1.0
*/
int32_t (*Unregister)(int32_t sensorTypeId, RecordDataCallback cb);
+
+ /**
+ * @brief Obtain the sensor event data in the small system.
+ *
+ * @param sensorId Indicates the sensor ID. For details, see {@link SensorTypeTag}.
+ * @param event Indicates the vector of the sensor event data in the system.
+ * The sensor event data includes the sensor ID, sensor algorithm version, data generation time,
+ * data options (such as the measurement range and accuracy), data reporting mode, data address, and data length.
+ * For details, see {@link HdfSensorEvents}.
+ * @return Returns <b>0</b> if the event data is obtained; returns a negative value otherwise.
+ *
+ * @since 2.2
+ * @version 1.0
+ */
+ int32_t (*ReadData)(int32_t sensorId, struct SensorEvents *event);
+
+ /**
+ * @brief Obtain sensor information for SDC
+ *
+ * @param sdcSensorInfo Indicates the data of the SDC type.
+ * @return Returns <b>0</b> if the event data is obtained; returns a negative value otherwise.
+ *
+ * @since 4.1
+ * @version 2.0
+ */
+ int32_t (*GetSdcSensorInfo)(struct SdcSensorInfo sdcSensorInfo[]);
+ // ohos-hisi begin
+ /**
+ * @brief Get the data of the specified sensor stored.
+ *
+ * @param sensorTypeId Indicates the ID of a sensor type. For details, see {@link SensorTypeId}.
+ * @param sensorData Indicates the data of sensor stored For details, see {@link SensorData}.
+ * @return Returns <b>0</b> if get sensor data successfully; returns a non-zero value otherwise.
+ *
+ * @since 5
+ */
+ int32_t (*GetSensorData)(int32_t sensorTypeId, SensorData *sensorData);
+ // ohos-hisi end
};
/**
#endif
#endif /* __cplusplus */
-#define SENSOR_NAME_MAX_LEN 16 /**< Maximum length of the sensor name */
+// ohos-hisi begin
+// avoid redefined for SENSOR_NAME_MAX_LEN by liteos_m
+#ifndef SENSOR_NAME_MAX_LEN
+#define SENSOR_NAME_MAX_LEN 32 /**< Maximum length of the sensor name */
+#endif /* SENSOR_NAME_MAX_LEN */
+// ohos-hisi end
#define SENSOR_VERSION_MAX_LEN 16 /**< Maximum length of the sensor version */
/**
SENSOR_TYPE_GESTURE = 11, /**< Gesture sensor */
SENSOR_TYPE_PROXIMITY = 12, /**< Proximity sensor */
SENSOR_TYPE_HUMIDITY = 13, /**< Humidity sensor */
+ SENSOR_TYPE_COLOR = 14, /**< Color sensor */
+ SENSOR_TYPE_SAR = 15, /**< SAR sensor */
+ SENSOR_TYPE_AMBIENT_LIGHT1 = 16, /**< Secondary ambient light sensor*/
+ SENSOR_TYPE_HALL1 = 17, /**< Secondary hall effect sensor */
+ SENSOR_TYPE_PROXIMITY1 = 18, /**< Secondary proximity sensor */
+ SENSOR_TYPE_MEDICAL_BEGIN = 128, /**< The begin of medical sensorId enumeration value range */
+ SENSOR_TYPE_MEDICAL_END = 160, /**< The end of medical sensorId enumeration value range */
SENSOR_TYPE_PHYSICAL_MAX = 255, /**< Maximum type of a physical sensor */
SENSOR_TYPE_ORIENTATION = 256, /**< Orientation sensor */
SENSOR_TYPE_GRAVITY = 257, /**< Gravity sensor */
SENSOR_TYPE_SIGNIFICANT_MOTION = 264, /**< Significant motion sensor */
SENSOR_TYPE_PEDOMETER_DETECTION = 265, /**< Pedometer detection sensor */
SENSOR_TYPE_PEDOMETER = 266, /**< Pedometer sensor */
+ SENSOR_TYPE_POSTURE = 267, /**< Posture sensor */
+ SENSOR_TYPE_HEADPOSTURE = 268, /**< Headposture sensor */
+ SENSOR_TYPE_DROP_DETECT = 269, /**< Drop detection sensor */
SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR = 277, /**< Geomagnetic rotation vector sensor */
SENSOR_TYPE_HEART_RATE = 278, /**< Heart rate sensor */
SENSOR_TYPE_DEVICE_ORIENTATION = 279, /**< Device orientation sensor */
SENSOR_TYPE_WEAR_DETECTION = 280, /**< Wear detection sensor */
SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED = 281, /**< Uncalibrated acceleration sensor */
- SENSOR_TYPE_MAX = 0xFFF, /**< Maximum number of sensor types */
+ SENSOR_TYPE_RPC = 282, /**< Radio Power Control */
+ // ohos-hisi begin
+ SENSOR_TYPE_VSENSOR_EXPAND_START = 0x1000, /* 4096 */
+ SENSOR_TYPE_VSENSOR_ACCELEROMETER_ALG_SIMU, /**< ACCELEROMETER ALG sensor */
+ SENSOR_TYPE_VSENSOR_WEAR_ALG, /**< WEAR ALG sensor */
+ SENSOR_TYPE_VSENSOR_PRESS_ALG, /**< PRESS ALG sensor */
+ // ohos-hisi end
+ SENSOR_TYPE_MAX, /**< Maximum number of sensor types */
};
/**
};
/**
- * @brief 加速度传感器的数据结构
- */
-struct AccelData {
- /** 加速度X轴 */
- int16_t axisX;
- /** 加速度Y轴 */
- int16_t axisY;
- /** 加速度Z轴 */
- int16_t axisZ;
-};
-
-/**
- * @brief 角速度传感器的数据结构
- */
-struct GyroData {
- /** 加速度X轴 */
- int16_t axisX;
- /** 加速度Y轴 */
- int16_t axisY;
- /** 加速度Z轴 */
- int16_t axisZ;
-};
-
-/**
- * @brief 气压传感器的数据结构
+ * @brief Enumerates hardware service group for sensors
+ *
+ * @since 2.2
*/
-struct PressureData {
- /** 气压计气压值 */
- uint32_t pressure;
- /** 气压计温度值 */
- uint32_t temperature;
- /** 气压计数据有效性 */
- uint32_t dataValid;
+enum SensorGroupType {
+ TRADITIONAL_SENSOR_TYPE = 0, /**< traditional sensor type, the sensorId enumeration value range is 128-160 */
+ MEDICAL_SENSOR_TYPE = 1, /**< medical sensor type, the sensorId enumeration value range is not within 128-160 */
+ SENSOR_GROUP_TYPE_MAX, /**< Maximum sensor type*/
};
/**
float maxRange; /**< Maximum measurement range of the sensor */
float accuracy; /**< Sensor accuracy */
float power; /**< Sensor power */
+ int64_t minDelay; /**< Minimum sample period allowed in microseconds */
+ int64_t maxDelay; /**< Maxmum sample period allowed in microseconds */
+ uint32_t fifoMaxEventCount; /**< Maxmum number of events of this sensor that could be batched */
+ uint32_t reserved; /**< Reserved fields */
};
/**
uint32_t dataLen; /**< Sensor data length */
};
+/**
+ * @brief Defines SDC reports data object operations to the node.
+ *
+ * The reported sensor data includes the offset, type, ddrSize, minRateLevel, maxRateLevel, reserved, memAddr.
+ *
+ * @since 4.1
+ */
+struct SdcSensorInfo {
+ uint64_t offset;
+ int32_t sensorId;
+ int32_t ddrSize;
+ int32_t minRateLevel;
+ int32_t maxRateLevel;
+ uint64_t memAddr;
+ int32_t reserved;
+};
+
+// ohos-hisi begin
+/**
+ * @brief Accelerometer sensor data structure
+ */
+struct AccelData {
+ /** Accelerometer data X-axis */
+ int16_t axisX;
+ /** Accelerometer data Y-axis */
+ int16_t axisY;
+ /** Accelerometer data Z-axis */
+ int16_t axisZ;
+};
+
+/**
+ * @brief Gyro sensor data structure
+ */
+struct GyroData {
+ /** Gyro data X-axis */
+ int16_t axisX;
+ /** Gyro data Y-axis */
+ int16_t axisY;
+ /** Gyro data Z-axis */
+ int16_t axisZ;
+};
+
+/**
+ * @brief Pressure sensor data structure
+ */
+struct PressureData {
+ /** pressure value */
+ uint32_t pressure;
+ /** temperature value */
+ uint32_t temperature;
+ /** Data Validity */
+ uint32_t dataValid;
+};
+
+/**
+ * @brief Defines the sensor data.
+ *
+ * @since 5
+ */
+typedef struct SensorData {
+ int64_t timestamp; /**< Time when sensor data was reported */
+ uint32_t batchCnt; /**< Sensor batch cnt */
+ uint8_t *data; /**< Sensor data */
+ uint32_t dataLen; /**< Sensor data length */
+} SensorData;
+// ohos-hisi end
+
/**
* @brief Defines the callback for reporting sensor data. This callback needs to be registered when
* a sensor user subscribes to sensor data. Only after the sensor is enabled, the sensor data subscriber can receive
${ROOT_DIR}/middleware/services/gui/uikit/proprietary/src/utils/innerkits
${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include
${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include/service
+ ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include/components
${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits
${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/components
${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/animator
${ROOT_DIR}/application/wearable/ohos_deps
${ROOT_DIR}/application/wearable/nativeabilityfwk/include
${ROOT_DIR}/application/wearable/nativeapp/nativelauncher/include
+ ${ROOT_DIR}/application/wearable/nativeapp/nativeui/include
${ROOT_DIR}/application/wearable/service/xiaodu_navi_vector/libs
${ROOT_DIR}/open_source/openharmony/third_party/cJSON
${ROOT_DIR}/open_source/openharmony/third_party/qrcodegen/cpp
)
set(PRIVATE_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}/ace_ext
${CMAKE_CURRENT_SOURCE_DIR}/interfaces/base
${CMAKE_CURRENT_SOURCE_DIR}/animation
${CMAKE_CURRENT_SOURCE_DIR}/base
${ROOT_DIR}/middleware/services/gui/uikit/proprietary/src/utils/innerkits
${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include
${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include/service
+ ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include/components
${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits
-
+ ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network/connection_manage
+ ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/src/ui/innerkits
${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/components
${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/animator
${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/innerkits
${ROOT_DIR}/application/wearable/ohos_deps
${ROOT_DIR}/application/wearable/nativeabilityfwk/include
${ROOT_DIR}/application/wearable/nativeapp/nativelauncher/include
+ ${ROOT_DIR}/application/wearable/nativeapp/nativeui/include
${ROOT_DIR}/application/wearable/service/xiaodu_navi_vector/libs
${ROOT_DIR}/open_source/openharmony/third_party/cJSON
${ROOT_DIR}/open_source/openharmony/third_party/qrcodegen/cpp
${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network
${ROOT_DIR}/open_source/openharmony/base/sensors/location/interfaces/kits/include
${ROOT_DIR}/open_source/openharmony/base/sensors/interfaces/kits/native/include
+ ${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_adapter/lwip_driver_adapter
)
if("JS_ENABLE" IN_LIST DEFINES)
${CMAKE_CURRENT_SOURCE_DIR}/modules/device_module.cpp
${CMAKE_CURRENT_SOURCE_DIR}/modules/nativeapi_ohos_deviceinfo.cpp
${CMAKE_CURRENT_SOURCE_DIR}/modules/network/network_module.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/network/network_listener.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/network/connection_manage/connection_manage.cpp
${CMAKE_CURRENT_SOURCE_DIR}/modules/nfc_module.cpp
${CMAKE_CURRENT_SOURCE_DIR}/modules/vibrator_module.cpp
${CMAKE_CURRENT_SOURCE_DIR}/modules/battery_module.cpp
)
set(PUBLIC_DEFINES
+ FEATURE_COMPONENT_LISTEXT
+ FEATURE_COMPONENT_SCROLL
+)
+
+set(PRIVATE_DEFINES
+ ENABLE_LOCATION
+)
+
+install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/interfaces" "*")
+install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/include" "*")
+
+build_component()
+
+set(COMPONENT_NAME "ace_ext")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}/interfaces
+ ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/async
+ ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/base
+ ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/jsi
+ ${CMAKE_CURRENT_SOURCE_DIR}/
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/base
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/context
+)
+
+set(PRIVATE_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/base
+ ${CMAKE_CURRENT_SOURCE_DIR}/animation
+ ${CMAKE_CURRENT_SOURCE_DIR}/base
+ ${CMAKE_CURRENT_SOURCE_DIR}/base/cache
+ ${CMAKE_CURRENT_SOURCE_DIR}/components
+ ${CMAKE_CURRENT_SOURCE_DIR}/context
+ ${CMAKE_CURRENT_SOURCE_DIR}/directive
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/base
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/context
+ ${CMAKE_CURRENT_SOURCE_DIR}/jsi
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/presets
+ ${CMAKE_CURRENT_SOURCE_DIR}/router
+ ${CMAKE_CURRENT_SOURCE_DIR}/stylemgr
+ ${CMAKE_CURRENT_SOURCE_DIR}/targets
+ ${ROOT_DIR}/application/wearable/service/msg_center/include/vendor_app
+ ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/src/utils/innerkits
+ ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include
+ ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include/service
+ ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include/components
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits
+
+ ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/src/ui/innerkits
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/components
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/animator
+ ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/innerkits
+ ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/kits
+ ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/kits/gfx_utils
+ ${ROOT_DIR}/middleware/services/gui/uikit/surface/interfaces/kits
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/layout
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits/common
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/font
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/dfx
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/common
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/frameworks
+ ${ROOT_DIR}/open_source/openharmony/drivers/peripheral/display/interfaces/include
+ ${ROOT_DIR}/application/wearable/ohos_deps
+ ${ROOT_DIR}/application/wearable/nativeabilityfwk/include
+ ${ROOT_DIR}/application/wearable/nativeapp/nativelauncher/include
+ ${ROOT_DIR}/application/wearable/nativeapp/nativeui/include
+ ${ROOT_DIR}/application/wearable/service/xiaodu_navi_vector/libs
+ ${ROOT_DIR}/open_source/openharmony/third_party/cJSON
+ ${ROOT_DIR}/open_source/openharmony/third_party/qrcodegen/cpp
+ ${ROOT_DIR}/open_source/openharmony/base/global/i18n_lite/frameworks/i18n/include
+ ${ROOT_DIR}/open_source/openharmony/base/global/i18n_lite/interfaces/kits/i18n/include
+ ${ROOT_DIR}/open_source/openharmony/base/global/resmgr_lite/frameworks/resmgr_lite/include
+ ${ROOT_DIR}/open_source/openharmony/base/global/resmgr_lite/interfaces/innerkits/include
+ ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/keyinput
+ ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network
+ ${ROOT_DIR}/open_source/openharmony/base/sensors/location/interfaces/kits/include
+ ${ROOT_DIR}/open_source/openharmony/base/sensors/interfaces/kits/native/include
+ ${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_adapter/lwip_driver_adapter
+)
+
+if("JS_ENABLE" IN_LIST DEFINES)
+set(SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/ace_ext/menu_item_component.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/ace_ext/list_ext_component.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/ace_ext/scroll_component.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/ace_ext/list_adapter_ext.cpp
+)
+
+endif()
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+ -std=c++11
+ -Wno-error
+ -Wno-unused-parameter
+ -fno-exceptions
+ -fno-unwind-tables
+ -fno-asynchronous-unwind-tables
+ -Wno-undef
+ -Wno-bitwise-op-parentheses
+ -Wno-shift-op-parentheses
+ -nostdlibinc
+ -nostdinc
+ -nostdlib
+ -Wno-c++11-narrowing
+ -Wno-error=unused-function
+)
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+set(PUBLIC_DEFINES
+ FEATURE_COMPONENT_LISTEXT
+ FEATURE_COMPONENT_SCROLL
)
set(PRIVATE_DEFINES
+ ENABLE_LOCATION
)
install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/interfaces" "*")
build_component()
+set(COMPONENT_NAME "ace_ble")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+)
+
+set(PRIVATE_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/base
+ ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/bluetooth
+ ${ROOT_DIR}/application/wearable/nativeapp/nativeui/include/bluetooth
+ ${ROOT_DIR}/middleware/services/bts/ble
+ ${ROOT_DIR}/middleware/services/bts/br
+)
+
+set(SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/bluetooth/ble_module_common.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/bluetooth/ble_module_gattc_callback.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/bluetooth/ble_module_discover.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/bluetooth/ble_module_advertise.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/bluetooth/ble_module_scan.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/bluetooth/ble_module.cpp
+)
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+ -std=c++11
+ -Wno-error
+ -Wno-unused-parameter
+ -fno-exceptions
+ -fno-unwind-tables
+ -fno-asynchronous-unwind-tables
+ -Wno-undef
+ -Wno-bitwise-op-parentheses
+ -Wno-shift-op-parentheses
+ -nostdlibinc
+ -nostdinc
+ -nostdlib
+ -Wno-c++11-narrowing
+ -Wno-error=unused-function
+)
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+set(PRIVATE_DEFINES
+)
+
+set(PUBLIC_DEFINES
+ FEATURE_MODULE_BLE
+)
+
+build_component()
+
set(COMPONENT_NAME "netstack_http")
set(MODULE_NAME "ohos")
set(AUTO_DEF_FILE_ID TRUE)
${CMAKE_CURRENT_SOURCE_DIR}/modules/netstack/http/src/http_api.c
${CMAKE_CURRENT_SOURCE_DIR}/modules/netstack/http/src/http_client.c
${CMAKE_CURRENT_SOURCE_DIR}/modules/netstack/http/src/http_wrapper.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/netstack/http/src/http_form_data.c
)
set(COMPONENT_PUBLIC_CCFLAGS
)
set(PRIVATE_DEFINES
+ CONFIG_HTTP_FORM_DATA
+ CONFIG_HTTP_FILE_OPERATE
)
install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/interfaces" "*")
set(PRIVATE_HEADER
${CMAKE_CURRENT_SOURCE_DIR}/interfaces/base
- ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/net
+ ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/http
${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/http/include
${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/include
${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_adapter/liteos/src/include
${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_adapter/lwip_driver_adapter
+ ${ROOT_DIR}/open_source/openharmony/utils/native/lite/js/builtin/filekit/include
+ ${ROOT_DIR}/open_source/openharmony/utils/native/lite/js/builtin/common/include
)
set(SOURCES
- ${CMAKE_CURRENT_SOURCE_DIR}/modules/net/http_module.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/http/http_module.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/http/http_module_client.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/http/http_module_callback.cpp
)
set(COMPONENT_PUBLIC_CCFLAGS
set(PRIVATE_HEADER
${CMAKE_CURRENT_SOURCE_DIR}/interfaces/base
- ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/net
+ ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/http
${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/include
${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/include
${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_adapter/liteos/src/include
set(SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/modules/websocket/websocket_module.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/websocket/websocket_module_client.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/websocket/websocket_module_callback.cpp
)
set(COMPONENT_PUBLIC_CCFLAGS
set(PRIVATE_HEADER
${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/include
+ ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal
${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/include
${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_adapter/liteos/src/include
${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_adapter/lwip_driver_adapter
install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/interfaces" "*")
install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/include" "*")
+build_component()
+
+set(COMPONENT_NAME "ace_watchface")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+)
+
+set(PRIVATE_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/base
+ ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/watchface
+ ${ROOT_DIR}/open_source/openharmony/utils/native/lite/js/builtin/filekit/include
+ ${ROOT_DIR}/open_source/openharmony/utils/native/lite/js/builtin/common/include
+ ${ROOT_DIR}/application/wearable/nativeapp/nativeui/include/main/dial/
+ ${ROOT_DIR}/open_source/openharmony/drivers/peripheral/format/interfaces/include/
+)
+
+set(SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/watchface/watchface_module.cpp
+)
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+ -std=c++11
+ -Wno-error
+ -Wno-unused-parameter
+ -fno-exceptions
+ -fno-unwind-tables
+ -fno-asynchronous-unwind-tables
+ -Wno-undef
+ -Wno-bitwise-op-parentheses
+ -Wno-shift-op-parentheses
+ -nostdlibinc
+ -nostdinc
+ -nostdlib
+ -Wno-c++11-narrowing
+ -Wno-error=unused-function
+)
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+set(PUBLIC_DEFINES
+ FEATURE_MODULE_WATCHFACE
+)
+
+set(PRIVATE_DEFINES
+)
+
+install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/interfaces" "*")
+install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/include" "*")
+
+build_component()
+
+set(COMPONENT_NAME "ace_calendar")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}/interfaces
+ ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/async
+ ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/base
+ ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/jsi
+ ${CMAKE_CURRENT_SOURCE_DIR}/
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/base
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/context
+)
+
+set(PRIVATE_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/base
+ ${CMAKE_CURRENT_SOURCE_DIR}/animation
+ ${CMAKE_CURRENT_SOURCE_DIR}/base
+ ${CMAKE_CURRENT_SOURCE_DIR}/base/cache
+ ${CMAKE_CURRENT_SOURCE_DIR}/components
+ ${CMAKE_CURRENT_SOURCE_DIR}/context
+ ${CMAKE_CURRENT_SOURCE_DIR}/directive
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/base
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/context
+ ${CMAKE_CURRENT_SOURCE_DIR}/jsi
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/presets
+ ${CMAKE_CURRENT_SOURCE_DIR}/router
+ ${CMAKE_CURRENT_SOURCE_DIR}/stylemgr
+ ${CMAKE_CURRENT_SOURCE_DIR}/targets
+ ${ROOT_DIR}/application/wearable/service/msg_center/include/vendor_app
+ ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/src/utils/innerkits
+ ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include
+ ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include/service
+ ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include/components
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits
+
+ ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/src/ui/innerkits
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/components
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/animator
+ ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/innerkits
+ ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/kits
+ ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/kits/gfx_utils
+ ${ROOT_DIR}/middleware/services/gui/uikit/surface/interfaces/kits
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/layout
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits/common
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/font
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/dfx
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/common
+ ${ROOT_DIR}/middleware/services/gui/uikit/ui/frameworks
+ ${ROOT_DIR}/open_source/openharmony/drivers/peripheral/display/interfaces/include
+ ${ROOT_DIR}/application/wearable/ohos_deps
+ ${ROOT_DIR}/application/wearable/nativeabilityfwk/include
+ ${ROOT_DIR}/application/wearable/nativeapp/nativelauncher/include
+ ${ROOT_DIR}/application/wearable/nativeapp/nativeui/include
+ ${ROOT_DIR}/application/wearable/service/xiaodu_navi_vector/libs
+ ${ROOT_DIR}/open_source/openharmony/third_party/cJSON
+ ${ROOT_DIR}/open_source/openharmony/third_party/qrcodegen/cpp
+ ${ROOT_DIR}/open_source/openharmony/base/global/i18n_lite/frameworks/i18n/include
+ ${ROOT_DIR}/open_source/openharmony/base/global/i18n_lite/interfaces/kits/i18n/include
+ ${ROOT_DIR}/open_source/openharmony/base/global/resmgr_lite/frameworks/resmgr_lite/include
+ ${ROOT_DIR}/open_source/openharmony/base/global/resmgr_lite/interfaces/innerkits/include
+ ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/keyinput
+ ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network
+ ${ROOT_DIR}/open_source/openharmony/base/sensors/location/interfaces/kits/include
+ ${ROOT_DIR}/open_source/openharmony/base/sensors/interfaces/kits/native/include
+ ${ROOT_DIR}/application/wearable/service/msg_center/include/client
+)
+
+if("JS_ENABLE" IN_LIST DEFINES)
+set(SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/calendarManager/calendar_manager.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/calendarManager/calendar_timer.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/calendarManager/calendar_module.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/modules/calendarManager/event_id_manager.cpp
+)
+
+endif()
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+ -std=c++11
+ -Wno-error
+ -Wno-unused-parameter
+ -fno-exceptions
+ -fno-unwind-tables
+ -fno-asynchronous-unwind-tables
+ -Wno-undef
+ -Wno-bitwise-op-parentheses
+ -Wno-shift-op-parentheses
+ -nostdlibinc
+ -nostdinc
+ -nostdlib
+ -Wno-c++11-narrowing
+ -Wno-error=unused-function
+)
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+set(PUBLIC_DEFINES
+ ENABLE_MODULE_CALENDAR
+)
+
+set(PRIVATE_DEFINES
+)
+
+install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/interfaces" "*")
+install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/include" "*")
+
build_component()
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2024-2025. All rights reserved.
+ * Description: ace_ext listadapter
+ * Author: SoftwarePlatform Group
+ * Create: 2024-08-10
+ */
+
+#ifndef OHOS_ACELITE_LIST_ADAPTER_EXT_H
+#define OHOS_ACELITE_LIST_ADAPTER_EXT_H
+
+#include <string>
+#include <vector>
+#include "text_component.h"
+
+namespace OHOS {
+namespace ACELite {
+
+class ListAdapterExt {
+public:
+ ListAdapterExt();
+
+ ~ListAdapterExt();
+
+ static void SetItemAdaptive(bool isItemAdaptive);
+
+ static bool GetItemAdaptive();
+
+ static void SetListValue(char *text);
+
+ static void SetItemIndex(int16_t index);
+
+ static int16_t GetItemIndex();
+
+ static int16_t BuildItemAdaptive(Component *component, int16_t index);
+
+ static void CleanVector();
+
+ static void CleanString();
+
+ static void CleanAll();
+
+private:
+ static int16_t CalculateItems(UILabel *uiLable, int16_t index);
+ static bool isItemAdaptive_;
+ static int16_t itemIndex_;
+ static std::vector<std::string> strings_;
+ static std::string all_;
+};
+} // namespace ACELite
+} // namespace OHOS
+#endif // OHOS_ACELITE_LIST_ADAPTER_EXT_H
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: ace scale-list
+ * Author: SoftwarePlatform Group
+ * Create: 2025-08-8
+ */
+
+#ifndef OHOS_ACELITE_LIST_EXT_COMPONENT_H
+#define OHOS_ACELITE_LIST_EXT_COMPONENT_H
+
+#include "component.h"
+#include "list_adapter.h"
+#include "ui_transform_list.h"
+
+namespace OHOS {
+namespace ACELite {
+class ListExtComponent final : public Component {
+public:
+ ACE_DISALLOW_COPY_AND_MOVE(ListExtComponent);
+ ListExtComponent() = delete;
+ ListExtComponent(JSValue options, JSValue children, AppStyleManager *styleManager);
+ ~ListExtComponent() override {}
+
+protected:
+ bool CreateNativeViews() override;
+ void ReleaseNativeViews() override;
+ UIView *GetComponentRootView() const override;
+ bool ApplyPrivateStyle(const AppStyleItem* style) override;
+ bool RegisterPrivateEventListener(uint16_t eventTypeId, JSValue funcValue, bool isStopPropagation) override;
+ bool SetPrivateAttribute(uint16_t attrKeyId, jerry_value_t attrValue) override;
+ bool ProcessChildren() override;
+ void OnViewAttached() override;
+ bool UpdateForView() override;
+
+private:
+ UITransformList list_;
+ ListAdapter adapter_;
+ ListEventListener listEventListener_;
+ static const char * const FUNC_SCROLLTO;
+ static const char * const INDEX_SCROLLTO;
+
+ int16_t scaleFactor_;
+ UIView::ViewExtraMsg scaleMsg_;
+ static bool ScaleListItem(UITransformList* list, UIView* item);
+
+ static const char * const FUNC_SCROLLTO_END;
+ static JSValue ListScrollTo(const JSValue func, const JSValue dom, const JSValue args[], const jerry_length_t size);
+ static JSValue ListScrollToEnd(const JSValue func, const JSValue dom, const JSValue args[], const jerry_length_t size);
+ void ComputeListLength();
+ static JSValue ListScroll(const JSValue func, const JSValue dom, const JSValue args[], const jerry_length_t size);
+};
+} // namespace ACELite
+} // namespace OHOS
+
+#endif // OHOS_ACELITE_LIST_EXT_COMPONENT_H
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: ace scale-list
+ * Author: SoftwarePlatform Group item
+ * Create: 2025-08-8
+ */
+
+#ifndef OHOS_ACELITE_MENU_ITEM_COMPONENT_H
+#define OHOS_ACELITE_MENU_ITEM_COMPONENT_H
+#include "component.h"
+#include "ui_transform_group.h"
+#include "non_copyable.h"
+
+namespace OHOS {
+namespace ACELite {
+class MenuItemComponent final : public Component {
+public:
+
+ ACE_DISALLOW_COPY_AND_MOVE(MenuItemComponent);
+ MenuItemComponent() = delete;
+ MenuItemComponent(jerry_value_t options, jerry_value_t children, AppStyleManager* styleManager);
+ ~MenuItemComponent() override {}
+
+protected:
+ UIView *GetComponentRootView() const override;
+ bool ProcessChildren() override;
+ void AttachView(const Component *child) override;
+
+private:
+ UITransformGroup item_;
+};
+} // namespace ACELite
+} // namespace OHOS
+
+#endif // OHOS_ACELITE_MENU_ITEM_COMPONENT_H
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: ace scroll view
+ * Author: SoftwarePlatform Group item
+ * Create: 2025-08-12
+ */
+
+#ifndef OHOS_ACELITE_SCROLL_COMPONENT_H
+#define OHOS_ACELITE_SCROLL_COMPONENT_H
+#include "component.h"
+#include "ui_scroll_view.h"
+#include "non_copyable.h"
+
+namespace OHOS {
+namespace ACELite {
+class ScrollComponent final : public Component {
+public:
+
+ ACE_DISALLOW_COPY_AND_MOVE(ScrollComponent);
+ ScrollComponent() = delete;
+ ScrollComponent(jerry_value_t options, jerry_value_t children, AppStyleManager* styleManager);
+ ~ScrollComponent() override {}
+
+protected:
+ UIView *GetComponentRootView() const override;
+ bool SetPrivateAttribute(uint16_t attrKeyId, jerry_value_t attrValue) override;
+ bool ProcessChildren() override;
+ void AttachView(const Component *child) override;
+
+private:
+ UIScrollView scrolliew_;
+};
+} // namespace ACELite
+} // namespace OHOS
+
+#endif // OHOS_ACELITE_SCROLL_COMPONENT_H
KEYWORD(ITEM_SELECTED, itemselected) // scroll item selected event listener
KEYWORD(ITERATION, iteration) // image-animator attribute
KEYWORD(JUSTIFY_CONTENT, justifyContent) // layout style
+ // ohos begin
+ // list-item adaptive
+ KEYWORD(LONG_TEXT, longText) // common attributes
+ // ohos end
#ifdef JS_TOUCH_EVENT_SUPPORT
KEYWORD(KEY, key) // onkey event
#endif
KEYWORD(LINE_HEIGHT, lineHeight) // text style type
KEYWORD(LIST, list) // list tag name
KEYWORD(LIST_ITEM, list-item) // list-item tag name
+#ifdef FEATURE_COMPONENT_LISTEXT
+ KEYWORD(MENU_ITEM, arclist-item) // arclist-item tag name
+ KEYWORD(LIST_EXT, arclist) // arclist tag name
+#endif // FEATURE_COMPONENT_LISTEXT
+#ifdef FEATURE_COMPONENT_SCROLL
+ KEYWORD(SCROLL, scroll) // scroll tag name
+#endif // FEATURE_COMPONENT_SCROLL
#ifdef FEATURE_DATE_FORMAT
KEYWORD(LONG, long)
#endif
#endif // FEATURE_COMPONENT_BAIDUMAP
#include "text_component.h"
#include "video_component.h"
+#if FEATURE_COMPONENT_LISTEXT
+#include "menu_item_component.h"
+#include "list_ext_component.h"
+#endif // FEATURE_COMPONENT_LISTEXT
+#if FEATURE_COMPONENT_SCROLL
+#include "scroll_component.h"
+#endif // FEATURE_COMPONENT_SCROLL
namespace OHOS {
namespace ACELite {
case K_LIST_ITEM:
component = new DivComponent(options, children, styleManager);
break;
+#if FEATURE_COMPONENT_LISTEXT
+ case K_MENU_ITEM:
+ component = new MenuItemComponent(options, children, styleManager);
+ break;
+ case K_LIST_EXT:
+ component = new ListExtComponent(options, children, styleManager);
+ break;
+#endif // FEATURE_COMPONENT_LISTEXT
+#if FEATURE_COMPONENT_SCROLL
+ case K_SCROLL:
+ component = new ScrollComponent(options, children, styleManager);
+ break;
+#endif // FEATURE_COMPONENT_SCROLL
#ifdef FEATURE_COMPONENT_ANALOG_CLOCK
case K_CLOCK_HAND:
component = new ClockHandComponent(options, children, styleManager);
if (rootComponent == nullptr) {
return;
}
+#if FEATURE_COMPONENT_LISTEXT
+ if (rootComponent->GetComponentName() != K_LIST && rootComponent->GetComponentName() != K_LIST_EXT) {
+#else
// for list component, release all the list items first
if (rootComponent->GetComponentName() != K_LIST) {
+#endif // FEATURE_COMPONENT_LISTEXT
JSValue descriptors = rootComponent->GetDescriptors();
if (!JSUndefined::Is(descriptors)) {
DescriptorUtils::ReleaseDescriptorOrElements(descriptors);
#include "key_parser.h"
#include "keys.h"
#include "product_adapter.h"
+#include "input_method/ui_input_method.h"
namespace OHOS {
namespace ACELite {
+InputEditTextComponent::~InputEditTextComponent()
+{
+ UIInputMethod::GetInstance()->Input(UI_KEYCODE::UI_KEY_ENTER);
+}
+
bool InputEditTextComponent::CreateNativeViews()
{
fontSize_ = ProductAdapter::GetDefaultFontSize();
{
SetComponentName(K_INPUT);
}
- ~InputEditTextComponent() override {};
+ ~InputEditTextComponent() override;
bool CreateNativeViews() override;
void ReleaseNativeViews() override;
bool SetPrivateAttribute(uint16_t attrKeyId, jerry_value_t attrValue) override;
#include "securec.h"
#include "text_component.h"
+// ohos begin
+// list-item adaptive
+#include "list_adapter_ext.h"
+// ohos end
namespace OHOS {
namespace ACELite {
ListAdapter::ListAdapter()
itemsCount_ = 0;
listItemsCount_ = 0;
+ // ohos begin
+ // list-item adaptive
+ ListAdapterExt::CleanAll();
+ // ohos end
}
bool ListAdapter::Initialize(const JSValue descriptors)
if (listItems_ == nullptr) {
return FAILED;
}
-
+ // ohos begin
+ // list-item adaptive
+ if (ListAdapterExt::GetItemAdaptive()) {
+ return 0;
+ }
+ // ohos end
for (int16_t listItemsIndex = 0; listItemsIndex < listItemsCount_; listItemsIndex++) {
if (itemIndex >= listItems_[listItemsIndex].startIndex &&
itemIndex <= (listItems_[listItemsIndex].startIndex + listItems_[listItemsIndex].itemsCount - 1) &&
if (index < 0) {
return nullptr;
}
+ // ohos begin
+ // list-item adaptive
+ if (ListAdapterExt::GetItemAdaptive() && index >= itemsCount_) {
+ return nullptr;
+ }
+ // ohos end
// 1. get UIView according to index which will show in list.
int16_t listItemsIndex = CalculateItemIndex(index);
if (listItemsIndex < 0) {
return newView;
}
-JSValue ListAdapter::GetElement(int16_t listItemsIndex, int16_t index, bool &isFor) const
+JSValue ListAdapter::GetElement(int16_t listItemsIndex, int16_t index, bool &isFor)
{
JSValue element = UNDEFINED;
JSValue descriptorOrElement = listItems_[listItemsIndex].descriptorOrElement;
// if it is a for or for+if type list-item, we need create view dynamically.
if (isFor) {
// get render argument
- JSValue item = jerry_get_property_by_index(getterRetList, index - startIndex);
+ // ohos begin
+ // list-item adaptive
+ JSValue item =
+ jerry_get_property_by_index(getterRetList, (ListAdapterExt::GetItemAdaptive() ? 0 : index) - startIndex);
+ // ohos end
if (jerry_value_is_undefined(item)) {
HILOG_ERROR(HILOG_MODULE_ACE, "List adapter: Get item from getterRetList failed.");
return UNDEFINED;
}
- JSValue itemIdx = jerry_create_number(index - startIndex);
+ // ohos begin
+ // list-item adaptive
+ JSValue itemIdx = jerry_create_number((ListAdapterExt::GetItemAdaptive() ? 0 : index) - startIndex);
+ // ohos end
const int8_t argsLen = 2;
JSValue args[argsLen] = {item, itemIdx};
// get render function
} else { // if it is a common list-item
element = descriptorOrElement;
}
+ // ohos begin
+ // list-item adaptive
+ ListAdapterExt::SetItemIndex(index);
+ // ohos end
BuildItemViewTree(element);
return element;
}
-void ListAdapter::BuildItemViewTree(const JSValue element) const
+void ListAdapter::BuildItemViewTree(const JSValue element)
{
Component *component = ComponentUtils::GetComponentFromBindingObject(element);
if (component == nullptr) {
Component::BuildViewTree(component, nullptr, parentParam);
}
}
+ // begin end
+ // ohos begin
+ // list-item adaptive
+ if (ListAdapterExt::GetItemAdaptive()) {
+ int16_t itemsCount = ListAdapterExt::BuildItemAdaptive(component, ListAdapterExt::GetItemIndex());
+ itemsCount_ = itemsCount > 0 ? itemsCount : itemsCount_;
+ }
+ // ohos end
component->OnViewAttached();
}
itemsCount_ = 0;
listItemsCount_ = 0;
+ // ohos begin
+ // list-item adaptive
+ ListAdapterExt::CleanVector();
+ // ohos end
+
if (listItems_ != nullptr) {
delete[] listItems_;
listItems_ = nullptr;
private:
bool GenerateListItems(const JSValue descriptors, int16_t size);
int16_t CalculateItemIndex(int16_t itemIndex) const;
- JSValue GetElement(int16_t listItemsIndex, int16_t index, bool &isFor) const;
+ // ohos begin
+ // list-item adaptive
+ JSValue GetElement(int16_t listItemsIndex, int16_t index, bool &isFor);
+ // ohos end
bool AddForDescriptorToList(JSValue descriptorOrElement, int16_t listItemsIndex) const;
void InsertItem(JSValue nativeElement, UIView *uiView);
- void BuildItemViewTree(const JSValue element) const;
+ // ohos begin
+ // list-item adaptive
+ void BuildItemViewTree(const JSValue element);
+ // ohos end
ListItemValue *listItems_;
ViewNativePair *headNode_;
ViewNativePair *tailNode_;
#include "fatal_handler.h"
#include "key_parser.h"
#include "keys.h"
+// ohos begin
+// list-item adaptive
+#include "list_adapter_ext.h"
+// ohos end
namespace OHOS {
namespace ACELite {
list_.SetYScrollBarVisible(false);
}
return true;
+ // ohos begin
+ // list-item adaptive
+ } else if (attrKeyId == K_LONG_TEXT) {
+ if (jerry_value_is_boolean(attrValue)) {
+ ListAdapterExt::SetItemAdaptive(BoolOf(attrValue));
+ }
+ return true;
+ } else if (attrKeyId == K_VALUE) {
+ if (jerry_value_is_string(attrValue)) {
+ char *value = MallocStringOf(attrValue);
+ if (value == nullptr) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "value is nullptr");
+ return false;
+ }
+ ListAdapterExt::SetListValue(value);
+ ace_free(value);
+ }
+ return true;
}
+ // ohos end
return false;
}
namespace OHOS {
namespace ACELite {
+int8_t GetJsPageState();
+
class JSAbilityImpl final : public MemoryHeap {
public:
ACE_DISALLOW_COPY_AND_MOVE(JSAbilityImpl);
namespace OHOS {
namespace ACELite {
+int8_t GetJsPageStateInfo();
+
class JSAbility final : public MemoryHeap {
public:
JSAbility(const JSAbility &) = delete;
#ifdef CUSTOM_ZHIHUI
#include "themestyle/include/ThemeStyleModel.h"
#else
-#include "settings/SetDesktopModel.h"
+#include "settings/model/SettingDesktopModel.h"
#endif
namespace OHOS {
(void)forceStop;
uint16_t preSliceId = NativeAbility::GetInstance().GetPreSliceId();
if (preSliceId == VIEW_APPLIST) {
- if (SetDesktopModel::GetInstance().GetDesktopStyle() == HEXAGONS_STYLE) {
+ if (SettingDesktopModel::GetInstance().GetDesktopStyle() == HEXAGONS_STYLE) {
AbilityMsClient::GetInstance().TerminateAbility(token, TransitionType::TRANSITION_BACK_TO_HEXAGONS);
return;
- } else if (SetDesktopModel::GetInstance().GetDesktopStyle() == WATERFALL_STYLE) {
+ } else if (SettingDesktopModel::GetInstance().GetDesktopStyle() == WATERFALL_STYLE) {
AbilityMsClient::GetInstance().TerminateAbility(token, TransitionType::TRANSITION_BACK_TO_WATERFALL);
return;
}
if (!ret) {
HILOG_ERROR(HILOG_MODULE_ACE, "Failed to dispatch async work");
AdapterFree(params->msgBody);
+ params->msgBody = nullptr;
delete params;
params = nullptr;
return -1;
if (!ret) {
HILOG_ERROR(HILOG_MODULE_ACE, "Failed to dispatch async work");
AdapterFree(params->msgBody);
+ params->msgBody = nullptr;
delete params;
params = nullptr;
return -1;
--- /dev/null
+/*\r
+ * Copyright (c) CompanyNameMagicTag. 2025. All rights reserved.\r
+ * Description: http control interfaces\r
+ * Author: Software Group\r
+ * Create: 2025-08-06\r
+ */\r
+\r
+#ifndef BLE_CLIENT_MODULE_H\r
+#define BLE_CLIENT_MODULE_H\r
+\r
+#include "ble_module_common.h"\r
+#include "los_task.h" \r
+#include "bts_le_gap.h"\r
+#include "cmsis_os2.h"\r
+#include "ohos_init.h"\r
+#include <queue>\r
+#include <mutex>\r
+#include <condition_variable>\r
+\r
+namespace OHOS {\r
+namespace ACELite {\r
+class BleModule final : public MemoryHeap {\r
+public:\r
+ BleModule() = default;\r
+ ~BleModule() = default;\r
+ static JSIValue JSGetMtu(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue Connect(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue DisConnect(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue GetServices(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue ReadCharacteristicValue(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue WriteCharacteristicValue(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue ReadDescriptorValue(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue WriteDescriptorValue(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue SetNotifyCharacteristicChanged(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue GetDeviceName(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue GetRssiValue(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue Close(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue CreateGattClientDevice(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue StartBLEScan(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue StopBLEScan(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue StartAdvertising(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue StopAdvertising(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue SetCharacteristicChangeIndication(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue SetCharacteristicChangeNotification(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue On(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue Off(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue ClientOff(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue ClientOn(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static void CheckSubscription(const char *type, const JSIValue err, const JSIValue value);\r
+ static void Destroy();\r
+ static void GetAdvertiseData(AdvertisingParams &advertisingParams, JSIValue jsiAdvertisingParams, const char *type,\r
+ bool *hasResponse);\r
+ static void GetAdvertiseWithCallback(const JSIValue *args, uint8_t argsSize, AdvertisingParams &advertisingParams,\r
+ bool *hasResponse);\r
+ static void GetAdvertiseWithParame(const JSIValue *args, uint8_t argsSize, AdvertiseSetting &setting,\r
+ AdvertiseData &advData, AdvertiseData &advResponse, bool *hasResponse);\r
+ static void DiscoverCharacteristicsForService(uint8_t client_id, uint16_t conn_id);\r
+ static void CompleteDiscovery(uint16_t conn_id, errcode_t status);\r
+ static void StartDescriptorDiscovery(uint8_t client_id, uint16_t conn_id);\r
+ static DiscoveryContext* GetValidDiscoveryContext(uint16_t connId);\r
+ static void ProcessNextDescriptorDiscovery(uint8_t client_id, uint16_t conn_id);\r
+ // 辅助函数:根据UUID查找特征值\r
+ static bool FindCharacteristic(const uint16_t charHandle, const std::string& serviceUuid,\r
+ const std::string& charUuid, BLECharacteristic& outChar, uint16_t connId);\r
+ static void CleanupConnectionResources(uint16_t conn_id);\r
+ // 辅助函数:根据UUID查找描述符\r
+ static bool FindDescriptor(const uint16_t descHandle, const std::string& serviceUuid, const std::string& charUuid,\r
+ const std::string& descUuid, BLEDescriptor& outDesc, uint16_t connId);\r
+ static void DsicoverExecute(void *data);\r
+ static void OnTerminate();\r
+\r
+ static std::map<std::string, EventCallback *> eventCallbacks;\r
+ static std::mutex scanResultMutex;\r
+ static std::vector<ScanResult> scanResult;\r
+ static uint32_t bleMtu;\r
+ static uint8_t clientId;\r
+ static std::mutex addrMapMutex;\r
+ static std::map<std::string, uint8_t> addrMap;\r
+ static BLEConnectionChangeState connectState;\r
+ static std::vector<GattService> gattServices; // -----发现服务的回调里捞取服务、特征值、描述\r
+ static std::vector<BLECharacteristic> gattCharacteristics;\r
+ static std::vector<BLEDescriptor> gattDescriptors; \r
+ static std::map<std::string, uint16_t> connectMap;\r
+ static std::map<uint8_t, uint8_t> advertisingMap;\r
+ static uint8_t advId;\r
+ static std::string deviceId;\r
+ static bool hasOn;\r
+ // 上下文管理相关静态成员\r
+ static std::map<uint16_t, DiscoveryContext> discoveryContexts;\r
+ static std::mutex contextMutex;\r
+ // 操作上下文管理\r
+ static std::vector<GattOperationContext> operationContexts;\r
+ static std::mutex operationMutex;\r
+ static std::vector<BleScanFilter> bleScanFilters;\r
+ static std::map<uint16_t, std::vector<GattService>> discoveredServicesMap;\r
+\r
+ static std::queue<gap_scan_result_data_t> scanDataQueue;\r
+ static std::mutex queueMutex;\r
+ static std::condition_variable queueCond;\r
+ static bool workerThreadRunning;\r
+ static osThreadId_t workerThreadId;\r
+\r
+ static std::queue<std::shared_ptr<DiscoveryData>> discoveryQueue;\r
+ static std::mutex discoveryQueueMutex;\r
+ static std::condition_variable discoveryQueueCond;\r
+ static bool discoveryWorkerRunning;\r
+ static osThreadId_t discoveryWorkerThreadId;\r
+ static ScanOptions scanOptions;\r
+private:\r
+ static errcode_t ProcessAdvertisingParameters(const JSIValue *args, uint8_t argsSize,\r
+ gap_ble_adv_params_t &adv_param, gap_ble_config_adv_data_t &cfg_adv_data, bool &hasResponse);\r
+ static errcode_t HandleAdvertiseSetting(const JSIValue *args, uint8_t argsSize,\r
+ gap_ble_config_adv_data_t &cfg_adv_data, bool &hasResponse);\r
+ static errcode_t HandleAdvertisingParams(const JSIValue *args, uint8_t argsSize,\r
+ gap_ble_adv_params_t &adv_param, gap_ble_config_adv_data_t &cfg_adv_data, bool &hasResponse);\r
+ static errcode_t ConfigureAndStartAdvertising(gap_ble_adv_params_t &adv_param,\r
+ gap_ble_config_adv_data_t &cfg_adv_data);\r
+ static JSIValue HandleExit(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize, errcode_t ret,\r
+ const gap_ble_config_adv_data_t &cfg_adv_data);\r
+ static bool CheckResponseData(const char *type, JSIValue jsiAdvertisingData, bool *hasResponse);\r
+ static void ProcessServiceUuids(AdvertisingParams &advertisingParams, JSIValue jsiAdvertisingData,\r
+ const char *type);\r
+ static void ProcessManufactureData(AdvertisingParams &advertisingParams, JSIValue jsiAdvertisingData,\r
+ const char *type);\r
+ static void ProcessManufactureValue(JSIValue jsiManufactureDataItem, ManufactureData &manufactureData);\r
+ static void ProcessServiceData(AdvertisingParams &advertisingParams, JSIValue jsiAdvertisingData,\r
+ const char *type);\r
+ static void ProcessServiceValue(JSIValue jsiServiceDataItem, ServiceData &serviceData);\r
+ static void ProcessIncludeDeviceName(AdvertisingParams &advertisingParams, JSIValue jsiAdvertisingData,\r
+ const char *type);\r
+ \r
+ static errcode_t ReleaseConnect();\r
+ static void ReleaseClose();\r
+ static void DestroyStopScanAndAdv();\r
+ static JSIValue gattClient;\r
+};\r
+void InitBleModule(JSIValue exports);\r
+\r
+} // namespace ACELite\r
+} // namespace OHOS\r
+#endif // BLE_CLIENT_MODULE_H
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright (c) CompanyNameMagicTag. 2025. All rights reserved.\r
+ * Description: http control interfaces\r
+ * Author: Software Group\r
+ * Create: 2025-08-06\r
+ */\r
+\r
+#ifndef BLE_CLIENT_MODULE_COMMON_H\r
+#define BLE_CLIENT_MODULE_COMMON_H\r
+\r
+#include <stdint.h>\r
+#include "jsi.h"\r
+#include "errcode.h"\r
+#include "bts_gatt_client.h"\r
+#include "non_copyable.h"\r
+#include "js_async_work.h"\r
+#include "bts_le_gap.h"\r
+#include <map>\r
+#include <vector>\r
+#include <string> \r
+\r
+namespace OHOS {\r
+namespace ACELite {\r
+\r
+#define MAX_CHARACTERISTICVALUE_LEN 128\r
+#define MAX_BLE_NAME_LEN 10\r
+#define MIN_BLE_INTERVEL_LEN 48\r
+#define MAX_BLE_INTERVEL_LEN 96\r
+#define MAX_ADV_DATA_LEN 31\r
+#define NOMAL_MTU_VALUE 512\r
+#define NOMAL_ADV_ID 3\r
+\r
+#define BLE_ADDR_LEN 6\r
+#define BLE_INVALID_CHARACTERISTIC_HANDLE 65530\r
+#define BLE_INVALID_DESCRIPTOR_HANDLE 65531\r
+\r
+// 蓝牙广播数据类型定义\r
+#define BLE_AD_TYPE_FLAGS 0x01\r
+#define BLE_AD_TYPE_16BIT_SERVICE_UUID 0x03\r
+#define BLE_AD_TYPE_32BIT_SERVICE_UUID 0x05\r
+#define BLE_AD_TYPE_128BIT_SERVICE_UUID 0x07\r
+#define BLE_AD_TYPE_COMPLETE_LOCAL_NAME 0x09\r
+#define BLE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF\r
+#define BLE_AD_TYPE_SERVICE_DATA_16BIT 0x16\r
+#define BLE_AD_TYPE_SERVICE_DATA_32BIT 0x20\r
+#define BLE_AD_TYPE_SERVICE_DATA_128BIT 0x21\r
+// 广播数据类型常量定义\r
+constexpr const char* ADVERTISING_DATA = "advertisingData";\r
+constexpr const char* ADVERTISING_RESPONSE = "advertisingResponse";\r
+constexpr const char* SERVICE_UUIDS = "serviceUuids";\r
+constexpr const char* MANUFACTURE_DATA = "manufactureData";\r
+constexpr const char* SERVICE_DATA = "serviceData";\r
+constexpr const char* MANUFACTURE_ID = "manufactureId";\r
+constexpr const char* MANUFACTURE_VALUE = "manufactureValue";\r
+constexpr const char* SERVICE_UUID = "serviceUuid";\r
+constexpr const char* SERVICE_VALUE = "serviceValue";\r
+constexpr const char* INCLUDE_DEVICE_NAME = "includeDeviceName";\r
+\r
+\r
+struct EventCallback {\r
+ JSIValue callback;\r
+ JSIValue context;\r
+};\r
+\r
+enum ErrNum {\r
+ BLE_SUCCESS = 0,\r
+ BLE_PERMISSION_DENIED = 201,\r
+ BLE_INVALID_PARAMETER = 401,\r
+ BLE_UNSUPPORT = 801,\r
+ BLE_SERVICE_STOP = 2900001,\r
+ BLE_READ_FORBID = 2901000,\r
+ BLE_OPRATION_FAILED = 2900099,\r
+};\r
+\r
+enum class MatchType {\r
+ NONE,\r
+ CHARACTERISTIC,\r
+ DESCRIPTOR\r
+};\r
+\r
+enum ChannelMap {\r
+ BLE_ONE_CHANEL = 0x1,\r
+ BLE_THREE_CHANEL = 0x7,\r
+};\r
+\r
+enum ScanDuty {\r
+ SCAN_MODE_LOW_POWER = 0,\r
+ SCAN_MODE_BALANCED = 1,\r
+ SCAN_MODE_LOW_LATENCY = 2,\r
+ SCAN_MODE_NONE,\r
+};\r
+\r
+enum MatchMode {\r
+ MATCH_MODE_AGGRESSIVE = 1,\r
+ MATCH_MODE_STICKY = 2,\r
+ MATCH_MODE_NONE,\r
+};\r
+\r
+enum PhyType {\r
+ PHY_LE_1M = 1,\r
+ PHY_LE_ALL_SUPPORTED = 255,\r
+ PHY_LE_NONE,\r
+};\r
+\r
+enum ScanReportMode {\r
+ SCAN_REPORT_MODE_NORMAL = 1,\r
+ SCAN_REPORT_MODE_NONE,\r
+};\r
+\r
+struct BLEDescriptor {\r
+ std::string serviceUuid;\r
+ std::string characteristicUuid;\r
+ std::string descriptorUuid;\r
+ std::vector<uint8_t> descriptorValue;\r
+ gattc_discovery_descriptor_result_t descriptor;\r
+};\r
+\r
+struct GattProperties {\r
+ bool write;\r
+ bool writeNoResponse;\r
+ bool read;\r
+ bool notify;\r
+ bool indicate;\r
+};\r
+\r
+struct BLECharacteristic {\r
+ std::string serviceUuid;\r
+ std::string characteristicUuid;\r
+ std::vector<uint8_t> characteristicValue;\r
+ std::vector<BLEDescriptor> descriptors;\r
+ GattProperties properties;\r
+ gattc_discovery_character_result_t character;\r
+ uint16_t service_start_hdl;\r
+ uint16_t service_end_hdl;\r
+};\r
+\r
+struct CallFuncAsyncParams : public MemoryHeap {\r
+ ACE_DISALLOW_COPY_AND_MOVE(CallFuncAsyncParams);\r
+ CallFuncAsyncParams() : err(nullptr), result(nullptr), callback(nullptr), context(nullptr),\r
+ type(nullptr), connId(0), characteristicArgs(nullptr){}\r
+\r
+ JSIValue err;\r
+ JSIValue result;\r
+ JSIValue callback;\r
+ JSIValue context;\r
+ char* type;\r
+ uint16_t connId;\r
+ BLECharacteristic *characteristicArgs;\r
+};\r
+\r
+struct BleScanFilter {\r
+ std::string deviceId;\r
+ std::string name;\r
+ std::string serviceUuid;\r
+ std::string serviceUuidMask;\r
+ std::string serviceSolicitationUuid;\r
+ std::string serviceSolicitationUuidMask;\r
+ std::vector<uint8_t> serviceData;\r
+ std::vector<uint8_t> serviceDataMask;\r
+ uint16_t manufactureId = 0;\r
+ std::vector<uint8_t> manufactureData;\r
+ std::vector<uint8_t> manufactureDataMask;\r
+};\r
+\r
+struct ScanOptions {\r
+ double interval;\r
+ ScanDuty dutyMode;\r
+ MatchMode matchMode;\r
+ PhyType phyType;\r
+ ScanReportMode reportMode;\r
+};\r
+\r
+struct ScanResult {\r
+ std::string deviceId;\r
+ int8_t rssi;\r
+ std::vector<uint8_t> data;\r
+ std::string deviceName;\r
+ bool connectable;\r
+};\r
+\r
+// AD结构定义\r
+struct AdStruct {\r
+ uint8_t length; // 类型+数据的总长度\r
+ uint8_t type; // 类型标志\r
+ std::vector<uint8_t> data; // 数据内容\r
+};\r
+\r
+struct BleParsedResult {\r
+ std::vector<std::string> serviceUuids; // 服务UUID\r
+ std::vector<std::string> serviceSolicitationUuids; // 服务请求UUID\r
+ std::vector<std::pair<std::string, std::vector<uint8_t>>> serviceDatas; // 服务数据\r
+ uint16_t manufactureId = 0; // 厂商ID\r
+ std::vector<uint8_t> manufactureData; // 厂商数据\r
+};\r
+\r
+struct ServiceData {\r
+ std::string serviceUuid;\r
+ std::vector<uint8_t> serviceValue;\r
+};\r
+\r
+struct ManufactureData {\r
+ uint16_t manufactureId;\r
+ std::vector<uint8_t> manufactureValue;\r
+};\r
+\r
+struct AdvertiseSetting {\r
+ double interval;\r
+ double txPower;\r
+ bool connectable;\r
+};\r
+\r
+struct AdvertiseData {\r
+ std::vector<std::string> serviceUuids;\r
+ std::vector<ManufactureData> manufactureData;\r
+ std::vector<ServiceData> serviceData;\r
+ bool includeDeviceName;\r
+};\r
+\r
+\r
+struct AdvertisingParams {\r
+ AdvertiseSetting advertisingSettings;\r
+ AdvertiseData advertisingData;\r
+ AdvertiseData advertisingResponse;\r
+ uint32_t duration;\r
+};\r
+\r
+enum ProfileConnectionState {\r
+ STATE_DISCONNECTED = 0,\r
+ STATE_CONNECTING = 1,\r
+ STATE_CONNECTED = 2,\r
+ STATE_DISCONNECTING = 3,\r
+};\r
+\r
+enum GattWriteType {\r
+ WRITE = 1,\r
+ WRITE_NO_RESPONSE = 2,\r
+};\r
+\r
+enum AdvertisingState {\r
+ STARTED = 1, // advertising started.\r
+ ENABLED = 2, // advertising temporarily enabled.\r
+ DISABLED = 3, // advertising temporarily disabled.\r
+ STOPPED = 4, // advertising stopped.\r
+};\r
+\r
+struct AdvertisingStateChangeInfo {\r
+ uint32_t advertisingId;\r
+ AdvertisingState state;\r
+};\r
+\r
+struct BLEConnectionChangeState {\r
+ std::string deviceId;\r
+ ProfileConnectionState state;\r
+};\r
+\r
+struct GattService {\r
+ std::string serviceUuid;\r
+ bool isPrimary;\r
+ std::vector<BLECharacteristic> characteristics;\r
+ std::vector<GattService> includeServices;\r
+ gattc_discovery_service_result_t service;\r
+ GattService() : isPrimary(true) {}\r
+};\r
+\r
+// 发现过程上下文,管理单个连接的服务发现状态\r
+struct DiscoveryContext {\r
+ uint16_t connId;\r
+ bool isInProgress;\r
+ JSIValue callback;\r
+ JSIValue thisVal;\r
+ uint16_t currentStartHandle;\r
+ std::vector<uint16_t> pendingCharHandles;\r
+ uint32_t currentServiceIndex;\r
+ uint16_t currentDescHandle;\r
+ uint16_t expectedDescCount; // 预期描述符总数\r
+ uint16_t receivedDescCount; // 已接收描述符计数\r
+ std::vector<GattService> discoveredServices; // 存储发现的服务数据\r
+ bool isCompleted; // 标记发现是否完成\r
+ bool isLastCharacteristic; // 新增:标记当前是否在处理最后一个特征值\r
+ uint16_t lastServiceEndHandle; // 新增:记录最后一个服务的结束句柄\r
+ \r
+ DiscoveryContext() : connId(0), isInProgress(false), currentStartHandle(0),\r
+ callback(JSI::CreateUndefined()), thisVal(JSI::CreateUndefined()), \r
+ currentDescHandle(0), expectedDescCount(0), receivedDescCount(0),\r
+ isCompleted(false), isLastCharacteristic(false), lastServiceEndHandle(0) {}\r
+};\r
+\r
+// 读写请求上下文,用于匹配请求和回调结果\r
+struct GattOperationContext {\r
+ enum Type {\r
+ READ_CHARACTERISTIC,\r
+ WRITE_CHARACTERISTIC,\r
+ READ_DESCRIPTOR,\r
+ WRITE_DESCRIPTOR\r
+ };\r
+\r
+ Type type;\r
+ uint16_t connId; // 新增:关联的连接ID\r
+ std::string serviceUuid;\r
+ std::string charUuid;\r
+ std::string descUuid;\r
+ uint16_t charHandle;\r
+ uint16_t descHandle;\r
+ JSIValue callback;\r
+ JSIValue thisVal;\r
+ GattWriteType writeType; // 仅用于写操作\r
+};\r
+\r
+struct DiscoveryData {\r
+ uint16_t connId;\r
+ std::vector<GattService> services;\r
+ std::vector<BLECharacteristic> characteristics;\r
+ std::vector<BLEDescriptor> descriptors;\r
+ JSIValue callback;\r
+ JSIValue thisVal;\r
+ \r
+ DiscoveryData(uint16_t id) : connId(id), \r
+ callback(JSI::CreateUndefined()), \r
+ thisVal(JSI::CreateUndefined()) {}\r
+ \r
+ ~DiscoveryData() {\r
+ JSI::ReleaseValueList(callback, thisVal);\r
+ }\r
+};\r
+\r
+struct DispatchAsync {\r
+ JSIValue err;\r
+ JSIValue result;\r
+ JSIValue callback;\r
+ JSIValue thisVal;\r
+ char* type;\r
+ uint16_t connId;\r
+ BLECharacteristic characteristicArgs;\r
+};\r
+uint8_t Char2Num(int8_t c);\r
+bool CompareHexStrings(const std::string& str1, const std::string& str2);\r
+errcode_t DecodeUuidFromStr(const char *uuidStr, uint8_t *uuid, int32_t *cnt);\r
+std::string FormatMacAddress(const uint8_t addr[BLE_ADDR_LEN]);\r
+errcode_t ParseUuidList(const uint8_t *data, uint8_t len, uint8_t uuid_size, std::vector<std::string> &uuid_list);\r
+bool CheckUuidMatch(const std::string &uuid, const std::string &filter, const std::string &mask);\r
+std::string GetUUidStr(const bt_uuid_t &uuid);\r
+void GetAttValueData(uint8_t *dataVec, bool enable, bool indication);\r
+errcode_t SetJsiBLECharacteristic(JSIValue jsiBleCharacteristic, uint16_t connId,\r
+ BLECharacteristic *bleCharacteristicArgs);\r
+void DiscoveryWorkerThread(void* arg);\r
+void GapBleEnableStackCbk(errcode_t status);\r
+void GapBleDisableStackCbk(errcode_t status);\r
+void GapBleSetAdvDataCbk(uint8_t adv_id, errcode_t status);\r
+void GapBleSetAdvParamCbk(uint8_t advId, errcode_t status);\r
+void GapBleSetScanParamCbk(errcode_t status);\r
+void GapBleStartAdvCbk(uint8_t advId, adv_status_t status);\r
+void GapBleStopAdvCbk(uint8_t advId, adv_status_t status);\r
+void GattcIndicationCbk(uint8_t client_id, uint16_t connId, gattc_handle_value_t *data,\r
+ errcode_t status);\r
+void GattcNotificationdCbk(uint8_t client_id, uint16_t connId, gattc_handle_value_t *data, errcode_t status);\r
+void GattsMtuChangedCbk(uint8_t server_id, uint16_t conn_id, uint16_t mtu_size, errcode_t status);\r
+void GattcMtuChangedCbk(uint8_t client_id, uint16_t conn_id, uint16_t mtu_size, errcode_t status);\r
+void GattcWriteCfmCbk(uint8_t client_id, uint16_t conn_id, uint16_t handle, gatt_status_t status);\r
+void GattcReadByUuidRespone(uint8_t client_id, uint16_t conn_id,\r
+ gattc_read_req_by_uuid_param_t *param, errcode_t status);\r
+void GattcReadCfmCbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *read_result, gatt_status_t status);\r
+void GattcDiscoveryDescResponse(uint8_t client_id, uint16_t conn_id, uint16_t character_handle,\r
+ errcode_t status);\r
+void GattcDiscoveryDescCbk(uint8_t client_id, uint16_t conn_id,\r
+ gattc_discovery_descriptor_result_t* descriptor, errcode_t status);\r
+void GattcDiscoveryCharResponse(uint8_t client_id, uint16_t conn_id, gattc_discovery_character_param_t *param,\r
+ errcode_t status);\r
+void GattcDiscoveryCharCbk(uint8_t client_id, uint16_t conn_id,\r
+ gattc_discovery_character_result_t *character, errcode_t status);\r
+void GattcDiscoverySvcResponse(uint8_t client_id, uint16_t conn_id, bt_uuid_t *uuid, errcode_t status);\r
+void GattcDiscoverySvcCbk(uint8_t client_id, uint16_t conn_id, gattc_discovery_service_result_t *service,\r
+ errcode_t status);\r
+void GapBleAuthCompeteCbk(uint16_t conn_id, const bd_addr_t *addr, errcode_t status,\r
+ const ble_auth_info_evt_t* evt);\r
+void GapBleReadRemoteRssiCbk(uint16_t conn_id, int8_t rssi, errcode_t status);\r
+void GapBleConnectParamUpdateCbk(uint16_t conn_id, errcode_t status,\r
+ const gap_ble_conn_param_update_t *param);\r
+void GapBleTerminateAdvCbk(uint8_t adv_id, adv_status_t status);\r
+void GapBlePariedCompleteCbk(uint16_t conn_id, const bd_addr_t *addr, errcode_t status);\r
+void GapBleConnStateChangeCbk(uint16_t conn_id, bd_addr_t *addr, gap_ble_conn_state_t conn_state,\r
+ gap_ble_pair_state_t pair_state, gap_ble_disc_reason_t disc_reason);\r
+void GapBleScanResultCbk(gap_scan_result_data_t *scan_result_data);\r
+void WorkerThreadFunc(void *argument);\r
+void GetCharacteristic(const JSIValue *args, BLECharacteristic &bleCharacteristicArgs, bool isRead);\r
+void GetProperty(const JSIValue jsiCharacteristic, BLECharacteristic &bleCharacteristicArgs);\r
+bool ValidateWriteParameters(uint8_t argsSize, const JSIValue* args);\r
+// 解析参数函数\r
+errcode_t ParseWriteArguments(const JSIValue* args, BLECharacteristic& bleCharacteristicArgs,\r
+ GattWriteType& writeType);\r
+void CleanupDiscoveryWorker();\r
+void InitDiscoveryWorker();\r
+void GetProperties(uint8_t properties, GattProperties &props);\r
+void CreateGattServices(JSIValue *rltArray, const std::vector<GattService> &services);\r
+JSIValue ConstructJSIResult(const gattc_handle_value_t *read_result, const BLECharacteristic *charFound,\r
+ const BLEDescriptor *descFound, const std::string &serviceUuid, const std::string &charUuid,\r
+ const std::string &descUuid);\r
+std::vector<GattService> AssembleGattServicesThreaded(std::shared_ptr<DiscoveryData> data);\r
+std::string FormatDeviceName(gap_scan_result_data_t *scan_result_data);\r
+BleParsedResult ParseMixedAdvertisingData(const uint8_t *data, uint8_t len);\r
+bool CheckBasicDeviceMatch(const BleScanFilter& filter, const ScanResult& scanResultTmp);\r
+bool CheckUuidMatch(const BleScanFilter& filter, const BleParsedResult& parsedResult);\r
+bool CheckDataMatch(const BleScanFilter& filter, const BleParsedResult& parsedResult);\r
+bool ReadMatchFilter(const BleScanFilter& filter, const BleParsedResult& parsedResult, \r
+ const ScanResult& scanResultTmp);\r
+void UpdateScanResult(const ScanResult &scanResultTmp, std::vector<ScanResult>::iterator existingIt,\r
+ std::vector<ScanResult> &scanResultList);\r
+} // namespace ACELite\r
+} // namespace OHOS\r
+#endif // BLE_CLIENT_MODULE_COMMON_H
\ No newline at end of file
--- /dev/null
+/**
+ * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved.
+ * Description: appmanger_module module.
+ * Author: CompanyName
+ * Create: 2025-09-04
+ */
+#include <cstdio>
+#include <cstring>
+#include <cerrno>
+#include <cstdlib>
+#include <securec.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "ace_mem_base.h"
+#include "memory_heap.h"
+#include "cJSON.h"
+#include "ace_log.h"
+#include "calendar_manager.h"
+
+#define FILE_SIZE_MAX 0xF00000
+namespace OHOS {
+namespace ACELite {
+// Error message mapping table
+static const char *g_errorStrings[CALENDAR_ERROR_MAX] = {"Operation successful",
+ "File does not exist",
+ "File open failed",
+ "JSON parsing error",
+ "User does not exist",
+ "Event does not exist",
+ "Event ID already exists",
+ "User information does not match",
+ "Memory allocation failed",
+ "Invalid parameter",
+ "File write failed",
+ "Failed to allocate event ID"};
+
+// Get error message string
+const char *GetCalendarErrorString(CalendarError error)
+{
+ return (error >= 0 && error < CALENDAR_ERROR_MAX) ? g_errorStrings[error] : "Unknown error";
+}
+
+// Internal utility: Read JSON file content
+static char *ReadJsonFile(const char *filename, CalendarError *error)
+{
+ if (!filename || !error) {
+ if (error) {
+ *error = CALENDAR_INVALID_PARAMETER;
+ }
+ return nullptr;
+ }
+
+ FILE *file = fopen(filename, "rb");
+ if (!file) {
+ *error = (errno == ENOENT) ? CALENDAR_FILE_NOT_FOUND : CALENDAR_FILE_OPEN_FAILED;
+ return nullptr;
+ }
+
+ // Get file size
+ fseek(file, 0, SEEK_END);
+ long fileLen = ftell(file);
+ fseek(file, 0, SEEK_SET);
+ if (fileLen > FILE_SIZE_MAX) {
+ return nullptr;
+ }
+ // Allocate memory (+1 for terminator)
+ char *data = (char *)malloc(fileLen + 1);
+ if (!data) {
+ fclose(file);
+ *error = CALENDAR_MEMORY_ALLOC_FAILED;
+ return nullptr;
+ }
+
+ // Read file
+ size_t readLen = fread(data, 1, fileLen, file);
+ fclose(file);
+
+ if (readLen != fileLen) {
+ free(data);
+ *error = CALENDAR_FILE_OPEN_FAILED;
+ return nullptr;
+ }
+ data[fileLen] = '\0';
+ *error = CALENDAR_SUCCESS;
+ return data;
+}
+
+// Internal utility: Write to JSON file
+static CalendarError writeJsonFile(const char *filename, cJSON *root)
+{
+ if (!filename || !root) {
+ return CALENDAR_INVALID_PARAMETER;
+ }
+
+ char *jsonStr = cJSON_Print(root);
+ if (!jsonStr) {
+ return CALENDAR_MEMORY_ALLOC_FAILED;
+ }
+
+ int fd = open(filename, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
+ if (fd == -1) {
+ free(jsonStr);
+ return CALENDAR_FILE_OPEN_FAILED;
+ }
+
+ size_t strLen = strlen(jsonStr);
+ ssize_t writeLen = write(fd, jsonStr, strLen);
+ close(fd); // Close file descriptor
+ free(jsonStr);
+
+ return (writeLen == strLen) ? CALENDAR_SUCCESS : CALENDAR_FILE_WRITE_FAILED;
+}
+
+// Internal utility: Get or create JSON root object
+static cJSON *getOrCreateRoot(const char *filename, CalendarError *error)
+{
+ if (!filename || !error) {
+ *error = CALENDAR_INVALID_PARAMETER;
+ return nullptr;
+ }
+
+ char *jsonData = ReadJsonFile(filename, error);
+ cJSON *root = nullptr;
+
+ // Create empty root object when file doesn't exist
+ if (*error == CALENDAR_FILE_NOT_FOUND) {
+ root = cJSON_CreateObject();
+ *error = (root) ? CALENDAR_SUCCESS : CALENDAR_MEMORY_ALLOC_FAILED;
+ return root;
+ }
+
+ // Return directly if read failed
+ if (*error != CALENDAR_SUCCESS) {
+ return nullptr;
+ }
+
+ // Parse JSON data
+ root = cJSON_Parse(jsonData);
+ free(jsonData);
+ jsonData = nullptr;
+ if (!root) {
+ *error = CALENDAR_JSON_PARSE_ERROR;
+ } else {
+ *error = CALENDAR_SUCCESS;
+ }
+
+ return root;
+}
+
+// Internal utility: Find user JSON object
+static cJSON *findUserObject(cJSON *root, const char *userName)
+{
+ if (!root || !userName || !cJSON_IsObject(root)) {
+ return nullptr;
+ }
+ return cJSON_GetObjectItemCaseSensitive(root, userName);
+}
+
+// Internal utility: Find event index in array (-1 means not exists)
+static int findEventIndex(cJSON *eventsArray, int eventId)
+{
+ if (!eventsArray || !cJSON_IsArray(eventsArray)) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid parameter");
+ return -1;
+ }
+
+ int index = 0;
+ cJSON *event = nullptr;
+ cJSON_ArrayForEach(event, eventsArray)
+ {
+ cJSON *idItem = cJSON_GetObjectItemCaseSensitive(event, "id");
+ if (idItem && cJSON_IsNumber(idItem) && idItem->valueint == eventId) {
+ return index;
+ }
+ index++;
+ }
+ return -1;
+}
+
+// Internal utility: Create cJSON object from CalendarEvent struct
+static cJSON *createEventJson(const CalendarEvent *event)
+{
+ if (!event) {
+ return nullptr;
+ }
+
+ cJSON *eventJson = cJSON_CreateObject();
+ if (!eventJson) {
+ return nullptr;
+ }
+ cJSON_AddNumberToObject(eventJson, "id", event->id);
+ cJSON_AddNumberToObject(eventJson, "type", event->type);
+ cJSON_AddNumberToObject(eventJson, "startTime", event->startTime);
+ cJSON_AddNumberToObject(eventJson, "endTime", event->endTime);
+ cJSON_AddStringToObject(eventJson, "bundlename", event->bundlename);
+ cJSON_AddBoolToObject(eventJson, "isAllDay", event->isAllDay);
+ cJSON_AddBoolToObject(eventJson, "hasReminder", event->hasReminder);
+ cJSON_AddBoolToObject(eventJson, "isRepeat", event->isRepeat);
+ cJSON_AddNumberToObject(eventJson, "recurrenceFrequency", event->recurrenceFrequency);
+ cJSON_AddStringToObject(eventJson, "eventContent", event->eventContent);
+ return eventJson;
+}
+
+// Internal utility: Create user account JSON object
+static cJSON *createUserAccountJson(const char *name, const char *type, const char *displayName)
+{
+ if (!name || !type || !displayName) {
+ return nullptr;
+ }
+
+ cJSON *account = cJSON_CreateObject();
+ if (!account) {
+ return nullptr;
+ }
+
+ // Create CalendarAccount object
+ cJSON *calendarAccount = cJSON_CreateObject();
+ if (!calendarAccount) {
+ cJSON_Delete(account);
+ return nullptr;
+ }
+ cJSON_AddStringToObject(calendarAccount, "name", name);
+ cJSON_AddStringToObject(calendarAccount, "type", type);
+ cJSON_AddStringToObject(calendarAccount, "displayName", displayName);
+ cJSON_AddItemToObject(account, "CalendarAccount", calendarAccount);
+
+ // Create empty events array
+ cJSON *events = cJSON_CreateArray();
+ if (!events) {
+ cJSON_Delete(account);
+ return nullptr;
+ }
+ cJSON_AddItemToObject(account, "events", events);
+
+ return account;
+}
+
+// 1. Create or append user
+const char *CreateOrAppendUser(
+ const char *filename, const char *name, const char *type, const char *displayName, CalendarError *error)
+{
+ if (!filename || !name || !type || !displayName || !error) {
+ if (error) {
+ *error = CALENDAR_INVALID_PARAMETER;
+ }
+ return nullptr;
+ }
+
+ cJSON *root = getOrCreateRoot(filename, error);
+ if (!root || *error != CALENDAR_SUCCESS) {
+ return nullptr;
+ }
+
+ cJSON *user = findUserObject(root, name);
+ if (user) {
+ // User already exists, check if information matches
+ cJSON *account = cJSON_GetObjectItemCaseSensitive(user, "CalendarAccount");
+ if (!account) {
+ cJSON_Delete(root);
+ *error = CALENDAR_JSON_PARSE_ERROR;
+ return nullptr;
+ }
+
+ cJSON *existingtype = cJSON_GetObjectItemCaseSensitive(account, "type");
+ cJSON *existingDisplayName = cJSON_GetObjectItemCaseSensitive(account, "displayName");
+
+ if (!existingtype || !existingDisplayName || !cJSON_IsString(existingtype) ||
+ !cJSON_IsString(existingDisplayName) || strcmp(existingtype->valuestring, type) != 0 ||
+ strcmp(existingDisplayName->valuestring, displayName) != 0) {
+ cJSON_Delete(root);
+ *error = CALENDAR_USER_INFO_MISMATCH;
+ return nullptr;
+ }
+
+ // Information matches, return username
+ cJSON_Delete(root);
+ *error = CALENDAR_SUCCESS;
+ return name;
+ }
+
+ // Create new user
+ cJSON *newUser = createUserAccountJson(name, type, displayName);
+ if (!newUser) {
+ cJSON_Delete(root);
+ *error = CALENDAR_MEMORY_ALLOC_FAILED;
+ return nullptr;
+ }
+
+ cJSON_AddItemToObject(root, name, newUser);
+ *error = writeJsonFile(filename, root);
+ cJSON_Delete(root);
+
+ return (*error == CALENDAR_SUCCESS) ? name : nullptr;
+}
+
+// 2. Append single event (using CalendarEvent struct for parameters)
+CalendarError AppendEvent(const char *filename, const char *name, const CalendarEvent *event)
+{
+ if (!filename || !name || !event) {
+ return CALENDAR_INVALID_PARAMETER;
+ }
+
+ CalendarError error = CALENDAR_INVALID_PARAMETER;
+ cJSON *root = getOrCreateRoot(filename, &error);
+ if (!root || error != CALENDAR_SUCCESS) {
+ return error;
+ }
+
+ cJSON *user = findUserObject(root, name);
+ if (!user) {
+ cJSON_Delete(root);
+ return CALENDAR_USER_NOT_FOUND;
+ }
+
+ cJSON *events = cJSON_GetObjectItemCaseSensitive(user, "events");
+ if (!events || !cJSON_IsArray(events)) {
+ events = cJSON_CreateArray();
+ if (!events) {
+ cJSON_Delete(root);
+ return CALENDAR_MEMORY_ALLOC_FAILED;
+ }
+ cJSON_AddItemToObject(user, "events", events);
+ }
+
+ // Check if event ID already exists
+ if (findEventIndex(events, event->id) != -1) {
+ cJSON_Delete(root);
+ return CALENDAR_EVENT_ID_EXISTS;
+ }
+
+ // Create and add new event
+ cJSON *eventJson = createEventJson(event);
+ if (!eventJson) {
+ cJSON_Delete(root);
+ return CALENDAR_MEMORY_ALLOC_FAILED;
+ }
+
+ cJSON_AddItemToArray(events, eventJson);
+ error = writeJsonFile(filename, root);
+ cJSON_Delete(root);
+
+ return error;
+}
+
+// 3. Append multiple events
+CalendarError AppendEvents(const char *filename, const char *name, const CalendarEventArray *eventArray)
+{
+ if (!filename || !name || !eventArray || !eventArray->events || eventArray->count == 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "AppendEvents Invalid parameter");
+ return CALENDAR_INVALID_PARAMETER;
+ }
+
+ CalendarError error = CALENDAR_INVALID_PARAMETER;
+ cJSON *root = getOrCreateRoot(filename, &error);
+ if (!root || error != CALENDAR_SUCCESS) {
+ return error;
+ }
+
+ cJSON *user = findUserObject(root, name);
+ if (!user) {
+ cJSON_Delete(root);
+ return CALENDAR_USER_NOT_FOUND;
+ }
+
+ cJSON *eventsArray = cJSON_GetObjectItemCaseSensitive(user, "events");
+ if (!eventsArray || !cJSON_IsArray(eventsArray)) {
+ eventsArray = cJSON_CreateArray();
+ if (!eventsArray) {
+ cJSON_Delete(root);
+ return CALENDAR_MEMORY_ALLOC_FAILED;
+ }
+ cJSON_AddItemToObject(user, "events", eventsArray);
+ }
+
+ // Check if all event IDs already exist
+ for (size_t i = 0; i < eventArray->count; i++) {
+ if (findEventIndex(eventsArray, eventArray->events[i].id) != -1) {
+ cJSON_Delete(root);
+ return CALENDAR_EVENT_ID_EXISTS;
+ }
+ }
+
+ // Add events in batch
+ for (size_t i = 0; i < eventArray->count; i++) {
+ cJSON *eventJson = createEventJson(&eventArray->events[i]);
+ if (!eventJson) {
+ cJSON_Delete(root);
+ return CALENDAR_MEMORY_ALLOC_FAILED;
+ }
+ cJSON_AddItemToArray(eventsArray, eventJson);
+ }
+
+ error = writeJsonFile(filename, root);
+ cJSON_Delete(root);
+
+ return error;
+}
+
+// 4. Get user's specific event
+CalendarEvent *CalendarGetEvent(const char *filename, const char *name, int eventId, CalendarError *error)
+{
+ if (!filename || !name || !error) {
+ *error = CALENDAR_INVALID_PARAMETER;
+ HILOG_ERROR(HILOG_MODULE_ACE, "AppendEvents Invalid parameter");
+ return nullptr;
+ }
+
+ char *jsonData = ReadJsonFile(filename, error);
+ if (!jsonData || *error != CALENDAR_SUCCESS) {
+ return nullptr;
+ }
+
+ cJSON *root = cJSON_Parse(jsonData);
+ free(jsonData);
+ jsonData = nullptr;
+ if (!root) {
+ *error = CALENDAR_JSON_PARSE_ERROR;
+ return nullptr;
+ }
+
+ cJSON *user = findUserObject(root, name);
+ if (!user) {
+ cJSON_Delete(root);
+ *error = CALENDAR_USER_NOT_FOUND;
+ return nullptr;
+ }
+
+ cJSON *events = cJSON_GetObjectItemCaseSensitive(user, "events");
+ if (!events || !cJSON_IsArray(events)) {
+ cJSON_Delete(root);
+ *error = CALENDAR_EVENT_NOT_FOUND;
+ return nullptr;
+ }
+
+ int index = findEventIndex(events, eventId);
+ if (index == -1) {
+ cJSON_Delete(root);
+ *error = CALENDAR_EVENT_NOT_FOUND;
+ return nullptr;
+ }
+
+ // Extract event information
+ cJSON *eventObj = cJSON_GetArrayItem(events, index);
+ CalendarEvent *event = (CalendarEvent *)malloc(sizeof(CalendarEvent));
+ if (!event) {
+ cJSON_Delete(root);
+ *error = CALENDAR_MEMORY_ALLOC_FAILED;
+ return nullptr;
+ }
+
+ cJSON *item = nullptr;
+
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "id");
+ event->id = (item && cJSON_IsNumber(item)) ? item->valueint : -1;
+
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "type");
+ event->type = (item && cJSON_IsNumber(item)) ? item->valueint : -1;
+
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "startTime");
+ event->startTime = (item && cJSON_IsNumber(item)) ? item->valuedouble : -1;
+
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "endTime");
+ event->endTime = (item && cJSON_IsNumber(item)) ? item->valuedouble : -1;
+
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "bundlename");
+ if (item && cJSON_IsString(item)) {
+ if (strcpy_s(event->bundlename, sizeof(event->bundlename), item->valuestring) != EOK) {
+ cJSON_Delete(root);
+ *error = CALENDAR_MEMORY_ALLOC_FAILED;
+ return nullptr;
+ }
+ }
+
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "isAllDay");
+ event->isAllDay = (item && cJSON_IsBool(item)) ? item->valueint : false;
+
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "hasReminder");
+ event->hasReminder = (item && cJSON_IsBool(item)) ? item->valueint : false;
+
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "isRepeat");
+ event->isRepeat = (item && cJSON_IsBool(item)) ? item->valueint : false;
+
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "recurrenceFrequency");
+ event->recurrenceFrequency = (item && cJSON_IsNumber(item)) ? item->valuedouble : -1;
+
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "eventContent");
+ if (item && cJSON_IsString(item)) {
+ if (strcpy_s(event->eventContent, sizeof(event->eventContent), item->valuestring) != EOK) {
+ cJSON_Delete(root);
+ *error = CALENDAR_MEMORY_ALLOC_FAILED;
+ return nullptr;
+ }
+ }
+
+ cJSON_Delete(root);
+ root = nullptr;
+ *error = CALENDAR_SUCCESS;
+ return event;
+}
+
+// Batch get all events of a user
+CalendarEventArray *CalendarGetEvents(const char *filename, const char *name, CalendarError *error)
+{
+ // Parameter validation
+ if (!filename || !name || !error) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "AppendEvents Invalid parameter");
+ *error = CALENDAR_INVALID_PARAMETER;
+ return nullptr;
+ }
+ *error = CALENDAR_SUCCESS;
+
+ // Read JSON file content
+ char *jsonData = ReadJsonFile(filename, error);
+ if (!jsonData || *error != CALENDAR_SUCCESS) {
+ return nullptr;
+ }
+
+ // Parse JSON
+ cJSON *root = cJSON_Parse(jsonData);
+ free(jsonData); // Free JSON string memory
+ jsonData = nullptr;
+ if (!root) {
+ *error = CALENDAR_JSON_PARSE_ERROR;
+ return nullptr;
+ }
+
+ // Find user object
+ cJSON *user = findUserObject(root, name);
+ if (!user) {
+ cJSON_Delete(root);
+ *error = CALENDAR_USER_NOT_FOUND;
+ return nullptr;
+ }
+
+ // Get events array
+ cJSON *events = cJSON_GetObjectItemCaseSensitive(user, "events");
+ if (!events || !cJSON_IsArray(events)) {
+ cJSON_Delete(root);
+ *error = CALENDAR_EVENT_NOT_FOUND;
+ return nullptr;
+ }
+
+ // Get event count
+ int eventCount = cJSON_GetArraySize(events);
+ if (eventCount <= 0) {
+ cJSON_Delete(root);
+ *error = CALENDAR_EVENT_NOT_FOUND;
+ return nullptr;
+ }
+
+ // Allocate memory for event array
+ CalendarEvent *eventList = (CalendarEvent *)malloc(sizeof(CalendarEvent) * eventCount);
+ if (!eventList) {
+ cJSON_Delete(root);
+ *error = CALENDAR_MEMORY_ALLOC_FAILED;
+ return nullptr;
+ }
+
+ // Allocate memory for event array structure
+ CalendarEventArray *eventArray = (CalendarEventArray *)malloc(sizeof(CalendarEventArray));
+ if (!eventArray) {
+ free(eventList);
+ cJSON_Delete(root);
+ *error = CALENDAR_MEMORY_ALLOC_FAILED;
+ return nullptr;
+ }
+
+ // Parse events one by one
+ cJSON *eventObj = nullptr;
+ int i = 0;
+ cJSON_ArrayForEach(eventObj, events)
+ {
+ cJSON *item = nullptr;
+
+ // Parse event ID
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "id");
+ eventList[i].id = (item && cJSON_IsNumber(item)) ? item->valueint : -1;
+
+ // Parse event type
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "type");
+ eventList[i].type = (item && cJSON_IsNumber(item)) ? item->valueint : -1;
+
+ // Parse start time
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "startTime");
+ eventList[i].startTime = (item && cJSON_IsNumber(item)) ? (int64_t)item->valuedouble : -1;
+
+ // Parse end time
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "endTime");
+ eventList[i].endTime = (item && cJSON_IsNumber(item)) ? (int64_t)item->valuedouble : -1;
+
+ // Parse bundlename
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "bundlename");
+ if (item && cJSON_IsString(item)) {
+ if (strcpy_s(eventList[i].bundlename, sizeof(eventList[i].bundlename), item->valuestring) != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "strcpy_s faild");
+ }
+ } else {
+ memset_s(eventList[i].bundlename, sizeof(eventList[i].bundlename), 0, sizeof(eventList[i].bundlename));
+ }
+
+ // Parse isAllDay
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "isAllDay");
+ eventList[i].isAllDay = (item && cJSON_IsBool(item)) ? item->valueint : false;
+
+ // Parse hasReminder
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "hasReminder");
+ eventList[i].hasReminder = (item && cJSON_IsBool(item)) ? item->valueint : false;
+
+ // Parse isRepeat
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "isRepeat");
+ eventList[i].isRepeat = (item && cJSON_IsBool(item)) ? (int64_t)item->valuedouble : false;
+
+ // Parse recurrenceFrequency
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "recurrenceFrequency");
+ eventList[i].recurrenceFrequency = (item && cJSON_IsNumber(item)) ? (int64_t)item->valuedouble : -1;
+
+ // Parse eventContent
+ item = cJSON_GetObjectItemCaseSensitive(eventObj, "eventContent");
+ if (item && cJSON_IsString(item)) {
+ if(strcpy_s((char *)eventList[i].eventContent, sizeof(eventList[i].eventContent), item->valuestring) != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "strcpy_s faild");
+ }
+ } else {
+ memset_s(
+ eventList[i].eventContent, sizeof(eventList[i].eventContent), 0, sizeof(eventList[i].eventContent));
+ }
+ i++;
+ }
+
+ // Fill event array structure
+ eventArray->events = eventList;
+ eventArray->count = eventCount;
+
+ // Clean up resources
+ cJSON_Delete(root);
+
+ *error = CALENDAR_SUCCESS;
+ return eventArray;
+}
+
+// 5. Delete single event
+CalendarError CalendarDeleteEvent(const char *filename, const char *name, int eventId)
+{
+ if (!filename || !name) {
+ return CALENDAR_INVALID_PARAMETER;
+ }
+
+ CalendarError error = CALENDAR_INVALID_PARAMETER;
+ cJSON *root = getOrCreateRoot(filename, &error);
+ if (!root || error != CALENDAR_SUCCESS) {
+ return error;
+ }
+
+ cJSON *user = findUserObject(root, name);
+ if (!user) {
+ cJSON_Delete(root);
+ return CALENDAR_USER_NOT_FOUND;
+ }
+
+ cJSON *events = cJSON_GetObjectItemCaseSensitive(user, "events");
+ if (!events || !cJSON_IsArray(events)) {
+ cJSON_Delete(root);
+ return CALENDAR_EVENT_NOT_FOUND;
+ }
+
+ int index = findEventIndex(events, eventId);
+ if (index == -1) {
+ cJSON_Delete(root);
+ return CALENDAR_EVENT_NOT_FOUND;
+ }
+
+ // Delete event
+ cJSON_DeleteItemFromArray(events, index);
+ error = writeJsonFile(filename, root);
+ cJSON_Delete(root);
+
+ return error;
+}
+
+// 6. Batch delete events
+CalendarError CalendarDeleteEvents(const char *filename, const char *name, const int *eventIds, size_t idCount)
+{
+ if (!filename || !name || !eventIds || idCount == 0) {
+ return CALENDAR_INVALID_PARAMETER;
+ }
+
+ CalendarError error = CALENDAR_INVALID_PARAMETER;
+ cJSON *root = getOrCreateRoot(filename, &error);
+ if (!root || error != CALENDAR_SUCCESS) {
+ return error;
+ }
+
+ cJSON *user = findUserObject(root, name);
+ if (!user) {
+ cJSON_Delete(root);
+ return CALENDAR_USER_NOT_FOUND;
+ }
+
+ cJSON *events = cJSON_GetObjectItemCaseSensitive(user, "events");
+ if (!events || !cJSON_IsArray(events)) {
+ cJSON_Delete(root);
+ return CALENDAR_EVENT_NOT_FOUND;
+ }
+
+ // Mark indices of events to delete (sorted from largest to smallest to avoid index changes)
+ int *indices = (int *)malloc(sizeof(int) * idCount);
+ if (!indices) {
+ cJSON_Delete(root);
+ return CALENDAR_MEMORY_ALLOC_FAILED;
+ }
+
+ size_t foundCount = 0;
+ for (size_t i = 0; i < idCount; i++) {
+ int index = findEventIndex(events, eventIds[i]);
+ if (index != -1) {
+ indices[foundCount++] = index;
+ }
+ }
+
+ // Delete from largest index to smallest to avoid index shifting issues
+ for (int i = foundCount - 1; i >= 0; i--) {
+ cJSON_DeleteItemFromArray(events, indices[i]);
+ }
+
+ free(indices);
+ error = writeJsonFile(filename, root);
+ cJSON_Delete(root);
+
+ return error;
+}
+
+// 7. Modify/add event (using CalendarEvent struct for parameters)
+CalendarError CalendarUpdateEvent(const char *filename, const char *name, const CalendarEvent *event)
+{
+ if (!filename || !name || !event) {
+ return CALENDAR_INVALID_PARAMETER;
+ }
+
+ CalendarError error = CALENDAR_INVALID_PARAMETER;
+ cJSON *root = getOrCreateRoot(filename, &error);
+ if (!root || error != CALENDAR_SUCCESS) {
+ return error;
+ }
+
+ cJSON *user = findUserObject(root, name);
+ if (!user) {
+ cJSON_Delete(root);
+ return CALENDAR_USER_NOT_FOUND;
+ }
+
+ cJSON *events = cJSON_GetObjectItemCaseSensitive(user, "events");
+ if (!events || !cJSON_IsArray(events)) {
+ events = cJSON_CreateArray();
+ if (!events) {
+ cJSON_Delete(root);
+ return CALENDAR_MEMORY_ALLOC_FAILED;
+ }
+ cJSON_AddItemToObject(user, "events", events);
+ }
+
+ // Find if event exists
+ int index = findEventIndex(events, event->id);
+ if (index != -1) {
+ // Event exists, delete old event first
+ cJSON_DeleteItemFromArray(events, index);
+ // Add new event (whether update or add)
+ cJSON *eventJson = createEventJson(event);
+ if (!eventJson) {
+ cJSON_Delete(root);
+ return CALENDAR_MEMORY_ALLOC_FAILED;
+ }
+ cJSON_AddItemToArray(events, eventJson);
+ error = writeJsonFile(filename, root);
+ } else {
+ error = CALENDAR_EVENT_NOT_FOUND;
+ }
+
+ cJSON_Delete(root);
+ return error;
+}
+
+CalendarError CalendarUpdateEvents(const char *filename, const char *name, const CalendarEventArray *events)
+{
+ // Parameter validity check
+ if (!filename || !name || !events || !events->events || events->count == 0) {
+ return CALENDAR_INVALID_PARAMETER;
+ }
+
+ CalendarError error = CALENDAR_INVALID_PARAMETER;
+ cJSON *root = getOrCreateRoot(filename, &error);
+ if (!root || error != CALENDAR_SUCCESS) {
+ return error;
+ }
+
+ // Find user object
+ cJSON *user = findUserObject(root, name);
+ if (!user) {
+ cJSON_Delete(root);
+ return CALENDAR_USER_NOT_FOUND;
+ }
+
+ // Get or create events array
+ cJSON *eventsArray = cJSON_GetObjectItemCaseSensitive(user, "events");
+ if (!eventsArray || !cJSON_IsArray(eventsArray)) {
+ eventsArray = cJSON_CreateArray();
+ if (!eventsArray) {
+ cJSON_Delete(root);
+ return CALENDAR_MEMORY_ALLOC_FAILED;
+ }
+ cJSON_AddItemToObject(user, "events", eventsArray);
+ }
+
+ // Record whether any events were successfully updated
+ bool hasUpdated = false;
+
+ // Iterate through all events to update
+ for (size_t i = 0; i < events->count; i++) {
+ const CalendarEvent *event = &events->events[i];
+
+ // Find event position in JSON array
+ int index = findEventIndex(eventsArray, event->id);
+ if (index != -1) {
+ // Found event, delete old version first
+ cJSON_DeleteItemFromArray(eventsArray, index);
+
+ // Create new event JSON object
+ cJSON *eventJson = createEventJson(event);
+ if (!eventJson) {
+ cJSON_Delete(root);
+ return CALENDAR_MEMORY_ALLOC_FAILED;
+ }
+
+ // Add updated event
+ cJSON_AddItemToArray(eventsArray, eventJson);
+ hasUpdated = true;
+ }
+ }
+
+ // If any events were updated, write to file
+ if (hasUpdated) {
+ error = writeJsonFile(filename, root);
+ } else {
+ // No events found to update
+ error = CALENDAR_EVENT_NOT_FOUND;
+ }
+
+ // Clean up resources
+ cJSON_Delete(root);
+ return error;
+}
+
+// 8. Get user information
+CalendarAccount *GetUserInfo(const char *filename, const char *name, CalendarError *error)
+{
+ if (!filename || !name || !error) {
+ *error = CALENDAR_INVALID_PARAMETER;
+ return nullptr;
+ }
+
+ char *jsonData = ReadJsonFile(filename, error);
+ if (!jsonData || *error != CALENDAR_SUCCESS) {
+ return nullptr;
+ }
+
+ cJSON *root = cJSON_Parse(jsonData);
+ free(jsonData);
+ jsonData = nullptr;
+ if (!root) {
+ *error = CALENDAR_JSON_PARSE_ERROR;
+ return nullptr;
+ }
+
+ cJSON *user = findUserObject(root, name);
+ if (!user) {
+ cJSON_Delete(root);
+ *error = CALENDAR_USER_NOT_FOUND;
+ return nullptr;
+ }
+
+ cJSON *accountObj = cJSON_GetObjectItemCaseSensitive(user, "CalendarAccount");
+ if (!accountObj) {
+ cJSON_Delete(root);
+ *error = CALENDAR_JSON_PARSE_ERROR;
+ return nullptr;
+ }
+
+ // Allocate memory for account information structure
+ CalendarAccount *account = (CalendarAccount *)malloc(sizeof(CalendarAccount));
+ if (!account) {
+ cJSON_Delete(root);
+ *error = CALENDAR_MEMORY_ALLOC_FAILED;
+ return nullptr;
+ }
+ memset_s(account, sizeof(CalendarAccount), 0, sizeof(CalendarAccount));
+
+ // Extract account information
+ cJSON *item = cJSON_GetObjectItemCaseSensitive(accountObj, "name");
+ if (item && cJSON_IsString(item)) {
+ account->name = (char *)ace_malloc(strlen(item->valuestring) + 1);
+ if (!account->name) {
+ free(account);
+ cJSON_Delete(root);
+ *error = CALENDAR_MEMORY_ALLOC_FAILED;
+ return nullptr;
+ }
+ memset_s(account->name, (strlen(item->valuestring) + 1), 0, (strlen(item->valuestring) + 1));
+ if(memcpy_s(account->name,
+ strlen(item->valuestring) + 1, item->valuestring, strlen(item->valuestring) + 1) != EOK) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "memcpy_s faild");
+ }
+ }
+
+ item = cJSON_GetObjectItemCaseSensitive(accountObj, "type");
+ if (item && cJSON_IsString(item)) {
+ account->type = (char *)ace_malloc(strlen(item->valuestring) + 1);
+ if (!account->type) {
+ ace_free(account->name);
+ free(account);
+ cJSON_Delete(root);
+ *error = CALENDAR_MEMORY_ALLOC_FAILED;
+ return nullptr;
+ }
+ memset_s(account->type, (strlen(item->valuestring) + 1), 0, (strlen(item->valuestring) + 1));
+ if(memcpy_s(account->type, strlen(item->valuestring) + 1, item->valuestring, strlen(item->valuestring) + 1) != EOK) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "memcpy_s faild");
+ }
+ }
+
+ item = cJSON_GetObjectItemCaseSensitive(accountObj, "displayName");
+ if (item && cJSON_IsString(item)) {
+ account->displayName = (char *)ace_malloc(strlen(item->valuestring) + 1);
+ if (!account->displayName) {
+ ace_free(account->name);
+ ace_free(account->type);
+ free(account);
+ cJSON_Delete(root);
+ *error = CALENDAR_MEMORY_ALLOC_FAILED;
+ return nullptr;
+ }
+ memset_s(account->displayName, (strlen(item->valuestring) + 1), 0, (strlen(item->valuestring) + 1));
+ if(memcpy_s(account->displayName,
+ strlen(item->valuestring) + 1, item->valuestring, strlen(item->valuestring) + 1) != EOK) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "memcpy_s faild");
+ }
+ }
+
+ cJSON_Delete(root);
+ *error = CALENDAR_SUCCESS;
+ return account;
+}
+
+// Free event memory
+void FreeCalendarEvent(CalendarEvent *event)
+{
+ if (event) {
+ free(event);
+ }
+}
+
+// Helper function to free CalendarEventArray resources
+void FreeCalendarEventArray(CalendarEventArray *array)
+{
+ if (array) {
+ free(static_cast<void*>(array->events)); // Free event array
+ free(array); // Free array structure
+ }
+}
+
+// Convert timestamp to datetime string
+// Return 0 on success, -1 on failure
+int TimestampToDatetime(time_t timestamp, char *datetimeStr, size_t maxLen)
+{
+ if (datetimeStr == nullptr || maxLen < 20) { // At least 20 bytes needed for "YYYY-MM-DD HH:MM:SS"
+ return -1;
+ }
+
+ struct tm *tminfo = localtime(×tamp); // Convert to local time
+ if (tminfo == nullptr) {
+ return -1;
+ }
+
+ // Format datetime string
+ strftime(datetimeStr, maxLen, "%Y-%m-%d %H:%M:%S", tminfo);
+ return 0;
+}
+
+} // namespace ACELite
+} // namespace OHOS
--- /dev/null
+/**
+ * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved.
+ * Description: appmanger_module module.
+ * Author: CompanyName
+ * Create: 2025-09-04
+ */
+#ifndef CALENDAR_MANAGER_H
+#define CALENDAR_MANAGER_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <ctime>
+
+namespace OHOS {
+namespace ACELite {
+// Error code definitions
+typedef enum {
+ CALENDAR_SUCCESS = 0,
+ CALENDAR_FILE_NOT_FOUND,
+ CALENDAR_FILE_OPEN_FAILED,
+ CALENDAR_JSON_PARSE_ERROR,
+ CALENDAR_USER_NOT_FOUND,
+ CALENDAR_EVENT_NOT_FOUND,
+ CALENDAR_EVENT_ID_EXISTS,
+ CALENDAR_USER_INFO_MISMATCH,
+ CALENDAR_MEMORY_ALLOC_FAILED,
+ CALENDAR_INVALID_PARAMETER,
+ CALENDAR_FILE_WRITE_FAILED,
+ CALENDAR_EVENT_ID_ALLOC_FAILED,
+ CALENDAR_ERROR_MAX
+} CalendarError;
+
+// Calendar event structure
+typedef struct {
+ int id;
+ int type;
+ int64_t startTime;
+ int64_t endTime;
+ bool isAllDay;
+ bool hasReminder;
+ bool isRepeat;
+ int64_t recurrenceFrequency;
+ char bundlename[64]; // String passed from outside, internal code does not handle its release
+ char eventContent[256];
+} CalendarEvent;
+
+// Batch event array structure
+typedef struct {
+ CalendarEvent *events; // Pointer to event array
+ size_t count; // Number of events
+} CalendarEventArray;
+
+// Calendar account structure
+typedef struct {
+ char *name;
+ char *type;
+ char *displayName;
+} CalendarAccount;
+
+// Error message retrieval interface
+const char *GetCalendarErrorString(CalendarError error);
+
+// 1. Create or append user
+// Return value: Returns username string on success, nullptr on failure
+const char *CreateOrAppendUser(
+ const char *filename, const char *name, const char *type, const char *displayName, CalendarError *error);
+
+// 2. Append single event (using CalendarEvent struct for parameters)
+CalendarError AppendEvent(const char *filename, const char *name, const CalendarEvent *event);
+
+// 3. Append multiple events
+CalendarError AppendEvents(const char *filename, const char *name, const CalendarEventArray *eventArray);
+
+// 4. Get user's specific event
+// Return value: Returns dynamically allocated CalendarEvent on success,
+// needs to be released by calling FreeCalendarEvent
+CalendarEvent *CalendarGetEvent(const char *filename, const char *name, int eventId, CalendarError *error);
+
+// Batch get all events of a user
+CalendarEventArray *CalendarGetEvents(const char *filename, const char *name, CalendarError *error);
+
+// 5. Delete single event
+CalendarError CalendarDeleteEvent(const char *filename, const char *name, int eventId);
+
+// 6. Batch delete events
+CalendarError CalendarDeleteEvents(const char *filename, const char *name, const int *eventIds, size_t idCount);
+
+// 7. Modify/add event (using CalendarEvent struct for parameters)
+CalendarError CalendarUpdateEvent(const char *filename, const char *name, const CalendarEvent *event);
+
+CalendarError CalendarUpdateEvents(const char *filename, const char *name, const CalendarEventArray *events);
+
+// 8. Get user information
+// Return value: Returns dynamically allocated CalendarAccount on success,
+CalendarAccount *GetUserInfo(const char *filename, const char *name, CalendarError *error);
+
+// Convert timestamp to datetime string
+// Return 0 on success, -1 on failure
+int TimestampToDatetime(time_t timestamp, char *datetimeStr, size_t maxLen);
+
+// Memory release interfaces
+void FreeCalendarEvent(CalendarEvent *event);
+} // namespace ACELite
+} // namespace OHOS
+#endif // CALENDAR_MANAGER_H
--- /dev/null
+/**
+ * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved.
+ * Description: appmanger_module module.
+ * Author: CompanyName
+ * Create: 2025-09-04
+ */
+#include <cstring>
+#include <climits>
+#include "calendar_manager.h"
+#include "event_id_manager.h"
+#include "ability_env.h"
+#include "calendar_utils.h"
+#include "ace_log.h"
+#include "calendar_module.h"
+namespace OHOS {
+namespace ACELite {
+// Global variable for calendar file path
+std::string g_canlendarFilePath = "/user/app/calendar.json";
+
+// Module constant definitions
+const char *const CalendarModule::MODULE_NAME = "calendar";
+const char *const CalendarModule::CREATE_CALENDAR = "createCalendar";
+const char *const CalendarModule::DELETE_CALENDAR = "deleteCalendar";
+const char *const CalendarModule::GET_CALENDAR = "getCalendar";
+const char *const CalendarModule::ADD_EVENT = "addEvent";
+const char *const CalendarModule::ADD_EVENTS = "addEvents";
+const char *const CalendarModule::DELETE_EVENT = "deleteEvent";
+const char *const CalendarModule::DELETE_EVENTS = "deleteEvents";
+const char *const CalendarModule::UPDATE_EVENT = "updateEvent";
+const char *const CalendarModule::UPDATE_EVENTS = "updateEvents";
+const char *const CalendarModule::GET_EVENT = "getEvent";
+const char *const CalendarModule::GET_EVENTS = "getEvents";
+const char *const CalendarModule::GET_ACCOUNT = "getAccount";
+const char *const CalendarModule::GET_CONFIG = "getconfig";
+const char *const CalendarModule::SET_CONFIG = "setconfig";
+
+// Static member variable for callback data
+CalendarCallback *CalendarModule::callbackData_ = nullptr;
+
+// Module initialization
+void CalendarModule::Init(JSIValue exports)
+{}
+
+void InitCalendarModule(JSIValue exports)
+{
+ // Register Calendar module API functions
+ JSI::SetModuleAPI(exports, CalendarModule::CREATE_CALENDAR, CalendarModule::CreateCalendar);
+ JSI::SetModuleAPI(exports, CalendarModule::DELETE_CALENDAR, CalendarModule::DeleteCalendar);
+ JSI::SetModuleAPI(exports, CalendarModule::GET_CALENDAR, CalendarModule::GetCalendar);
+}
+
+// Helper function: Convert JS object to CalendarAccount
+bool CalendarModule::ConvertToCalendarAccount(const JSIValue jsAccount, CalendarAccount &account)
+{
+ if (!JSI::ValueIsObject(jsAccount)) {
+ return false;
+ }
+
+ // Extract name property
+ JSIValue nameVal = JSI::GetNamedProperty(jsAccount, "name");
+ if (JSI::ValueIsString(nameVal)) {
+ account.name = JSI::ValueToString(nameVal);
+ } else {
+ JSI::ReleaseValue(nameVal);
+ return false;
+ }
+ JSI::ReleaseValue(nameVal);
+
+ // Extract type property
+ JSIValue typeVal = JSI::GetNamedProperty(jsAccount, "type");
+ if (JSI::ValueIsString(typeVal)) {
+ account.type = JSI::ValueToString(typeVal);
+ } else {
+ JSI::ReleaseValue(typeVal);
+ ace_free(static_cast<void*>(account.name));
+ return false;
+ }
+ JSI::ReleaseValue(typeVal);
+
+ // Extract displayName property
+ JSIValue displayNameVal = JSI::GetNamedProperty(jsAccount, "displayName");
+ if (JSI::ValueIsString(displayNameVal)) {
+ account.displayName = JSI::ValueToString(displayNameVal);
+ } else {
+ JSI::ReleaseValue(displayNameVal);
+ ace_free(static_cast<void*>(account.name));
+ ace_free(static_cast<void*>(account.type));
+ return false;
+ }
+ JSI::ReleaseValue(displayNameVal);
+
+ return true;
+}
+
+// Helper function: Convert CalendarEvent to JS object
+JSIValue CalendarModule::ConvertToJSEvent(const CalendarEvent &event)
+{
+ JSIValue jsEvent = JSI::CreateObject();
+
+ JSI::SetNamedProperty(jsEvent, "id", JSI::CreateNumber(event.id));
+ JSI::SetNamedProperty(jsEvent, "type", JSI::CreateNumber(event.type));
+ JSI::SetNamedProperty(jsEvent, "startTime", JSI::CreateNumber(event.startTime));
+ JSI::SetNamedProperty(jsEvent, "endTime", JSI::CreateNumber(event.endTime));
+ JSI::SetNamedProperty(jsEvent, "bundlename", JSI::CreateString(event.bundlename));
+ JSI::SetNamedProperty(jsEvent, "isAllDay", JSI::CreateBoolean(event.isAllDay));
+ JSI::SetNamedProperty(jsEvent, "hasReminder", JSI::CreateBoolean(event.hasReminder));
+ JSI::SetNamedProperty(jsEvent, "isRepeat", JSI::CreateBoolean(event.isRepeat));
+ JSI::SetNamedProperty(jsEvent, "recurrenceFrequency", JSI::CreateNumber(event.recurrenceFrequency));
+ JSI::SetNamedProperty(jsEvent, "eventContent", JSI::CreateString(event.eventContent));
+
+ return jsEvent;
+}
+
+// Helper function: Convert CalendarAccount to JS object
+JSIValue CalendarModule::ConvertToJSAccount(const CalendarAccount &account)
+{
+ JSIValue jsAccount = JSI::CreateObject();
+
+ if (account.name) {
+ JSI::SetNamedProperty(jsAccount, "name", JSI::CreateString(account.name));
+ }
+ if (account.type) {
+ JSI::SetNamedProperty(jsAccount, "type", JSI::CreateString(account.type));
+ }
+ if (account.displayName) {
+ JSI::SetNamedProperty(jsAccount, "displayName", JSI::CreateString(account.displayName));
+ }
+
+ return jsAccount;
+}
+
+// Free callback data
+void CalendarModule::FreeCallbackData(CalendarCallback *callbackData)
+{
+ if (callbackData) {
+ if (callbackData->account.name) {
+ ace_free(callbackData->account.name);
+ callbackData->account.name = nullptr;
+ }
+ if (callbackData->account.type) {
+ ace_free(callbackData->account.type);
+ callbackData->account.type = nullptr;
+ }
+ if (callbackData->account.displayName) {
+ ace_free(callbackData->account.displayName);
+ callbackData->account.displayName = nullptr;
+ }
+ delete callbackData;
+ }
+}
+
+// Create calendar
+JSIValue CalendarModule::CreateCalendar(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ if (argsNum < ARGC_TWO || !JSI::ValueIsObject(args[0]) || !JSI::ValueIsFunction(args[1])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for createCalendar");
+ return JSI::CreateUndefined();
+ }
+
+ // Create callback data
+ CalendarCallback *callbackData = new CalendarCallback();
+ if (!callbackData) {
+ return JSI::CreateUndefined();
+ }
+ callbackData->account.name = nullptr;
+ callbackData->account.displayName = nullptr;
+ callbackData->account.type = nullptr;
+ if (!callbackData) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Failed to allocate memory for callback data");
+ return JSI::CreateUndefined();
+ }
+ // Save callback function and context
+ callbackData->callback = JSI::AcquireValue(args[1]);
+ callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+ // Convert calendar account information
+ if (!ConvertToCalendarAccount(args[0], callbackData->account)) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Failed to convert to CalendarAccount");
+ FreeCallbackData(callbackData);
+ JSI::ReleaseValue(callbackData->callback);
+ JSI::ReleaseValue(callbackData->jsCtx);
+ return JSI::CreateUndefined();
+ }
+ // Dispatch asynchronous work
+ JsAsyncWork::DispatchAsyncWork(CreateCalendarCallback, static_cast<void *>(callbackData));
+
+ return JSI::CreateUndefined();
+}
+
+// Asynchronous callback for creating calendar
+void CalendarModule::CreateCalendarCallback(void *data)
+{
+ CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+ if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+ FreeCallbackData(callbackData);
+ JSI::ReleaseValue(callbackData->callback);
+ JSI::ReleaseValue(callbackData->jsCtx);
+ return;
+ }
+ // Call calendar management tool to create user
+ CalendarError error = CALENDAR_INVALID_PARAMETER;
+ const char *result = CreateOrAppendUser(GetCanlendarFilePath(),
+ callbackData->account.name,
+ callbackData->account.type,
+ callbackData->account.displayName,
+ &error);
+ // Prepare callback parameters
+ JSIValue args[ARGC_TWO];
+ JSIValue addEvent;
+ JSIValue addEvents;
+ JSIValue deleteEvent;
+ JSIValue deleteEvents;
+ JSIValue updateEvent;
+ JSIValue updateEvents;
+ JSIValue getEvent;
+ JSIValue getEvents;
+ JSIValue getAccount;
+ JSIValue getConfig;
+ JSIValue setConfig;
+ JSIValue calendarObj;
+ if (error == CALENDAR_SUCCESS && result != nullptr) {
+ // Success: first parameter is null, second is calendar object
+ args[0] = JSI::CreateNull();
+ // Create calendar object
+ calendarObj = JSI::CreateObject();
+ addEvent = JSI::CreateFunction(CalendarModule::AddEvent);
+ addEvents = JSI::CreateFunction(CalendarModule::AddEvents);
+ deleteEvent = JSI::CreateFunction(CalendarModule::DeleteEvent);
+ deleteEvents = JSI::CreateFunction(CalendarModule::DeleteEvents);
+ updateEvent = JSI::CreateFunction(CalendarModule::UpdateEvent);
+ updateEvents = JSI::CreateFunction(CalendarModule::UpdateEvents);
+ getEvent = JSI::CreateFunction(CalendarModule::GetEvent);
+ getEvents = JSI::CreateFunction(CalendarModule::GetEvents);
+ getAccount = JSI::CreateFunction(CalendarModule::GetAccount);
+ getConfig = JSI::CreateFunction(CalendarModule::GetConfig);
+ setConfig = JSI::CreateFunction(CalendarModule::SetConfig);
+ JSI::SetNamedProperty(calendarObj, ADD_EVENT, addEvent);
+ JSI::SetNamedProperty(calendarObj, ADD_EVENTS, addEvents);
+ JSI::SetNamedProperty(calendarObj, DELETE_EVENT, deleteEvent);
+ JSI::SetNamedProperty(calendarObj, DELETE_EVENTS, deleteEvents);
+ JSI::SetNamedProperty(calendarObj, UPDATE_EVENT, updateEvent);
+ JSI::SetNamedProperty(calendarObj, UPDATE_EVENTS, updateEvents);
+ JSI::SetNamedProperty(calendarObj, GET_EVENT, getEvent);
+ JSI::SetNamedProperty(calendarObj, GET_EVENTS, getEvents);
+ JSI::SetNamedProperty(calendarObj, GET_ACCOUNT, getAccount);
+ JSI::SetNamedProperty(calendarObj, GET_CONFIG, getConfig);
+ JSI::SetNamedProperty(calendarObj, SET_CONFIG, setConfig);
+ // Store calendar account information;
+ args[1] = calendarObj;
+ if (callbackData_) {
+ FreeCallbackData(callbackData_);
+ callbackData_ = nullptr;
+ }
+ callbackData_ = callbackData;
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+ JSI::ReleaseValueList(args[0],
+ args[1],
+ callbackData->callback,
+ callbackData->jsCtx,
+ addEvent,
+ addEvents,
+ deleteEvent,
+ deleteEvents,
+ updateEvent,
+ updateEvents,
+ getConfig,
+ setConfig,
+ getEvent,
+ getEvents,
+ getAccount,
+ ARGS_END);
+ } else {
+ // Failure: first parameter is error message, second is null
+ args[0] = JSI::CreateString(GetCalendarErrorString(error));
+ args[1] = JSI::CreateNull();
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+ JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+ FreeCallbackData(callbackData);
+ }
+}
+
+// Delete calendar
+JSIValue CalendarModule::DeleteCalendar(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ if (callbackData_) {
+ FreeCallbackData(callbackData_);
+ callbackData_ = nullptr;
+ }
+ return JSI::CreateUndefined();
+}
+
+// Asynchronous callback for deleting calendar
+void CalendarModule::DeleteCalendarCallback(void *data)
+{
+ // Implement actual logic and callback handling for deleting calendar
+}
+
+// Get default calendar
+JSIValue CalendarModule::GetCalendar(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ if (argsNum < 1 || !JSI::ValueIsFunction(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for getCalendar");
+ return JSI::CreateUndefined();
+ }
+ // Create callback data
+ CalendarCallback *callbackData = new CalendarCallback();
+ if (!callbackData) {
+ return JSI::CreateUndefined();
+ }
+ callbackData->account.name = nullptr;
+ callbackData->account.displayName = nullptr;
+ callbackData->account.type = nullptr;
+ if (!callbackData) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Failed to allocate memory for callback data");
+ return JSI::CreateUndefined();
+ }
+ // Save callback function and context
+ callbackData->callback = JSI::AcquireValue(args[0]);
+ callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+ OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(GetCalendarCallback, static_cast<void *>(callbackData));
+
+ return JSI::CreateUndefined();
+}
+
+// Asynchronous callback for getting default calendar
+void CalendarModule::GetCalendarCallback(void *data)
+{
+ // Implement actual logic and callback handling for getting default calendar
+ CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+ if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+ FreeCallbackData(callbackData);
+ return;
+ }
+ CalendarError error = CALENDAR_INVALID_PARAMETER;
+ CalendarAccount *account = GetUserInfo(GetCanlendarFilePath(), "default", &error);
+ if (account) {
+ callbackData->account.type = account->type;
+ callbackData->account.name = account->name;
+ callbackData->account.displayName = account->displayName;
+ free(account);
+ }
+ // Prepare callback parameters
+ JSIValue args[ARGC_TWO];
+ JSIValue addEvent;
+ JSIValue addEvents;
+ JSIValue deleteEvent;
+ JSIValue deleteEvents;
+ JSIValue updateEvent;
+ JSIValue updateEvents;
+ JSIValue getEvent;
+ JSIValue getEvents;
+ JSIValue getAccount;
+ JSIValue getConfig;
+ JSIValue setConfig;
+ if (error == CALENDAR_SUCCESS) {
+ // Success: first parameter is null, second is calendar object
+ args[0] = JSI::CreateNull();
+ // Create calendar object
+ JSIValue calendarObj = JSI::CreateObject();
+ addEvent = JSI::CreateFunction(CalendarModule::AddEvent);
+ addEvents = JSI::CreateFunction(CalendarModule::AddEvents);
+ deleteEvent = JSI::CreateFunction(CalendarModule::DeleteEvent);
+ deleteEvents = JSI::CreateFunction(CalendarModule::DeleteEvents);
+ updateEvent = JSI::CreateFunction(CalendarModule::UpdateEvent);
+ updateEvents = JSI::CreateFunction(CalendarModule::UpdateEvents);
+ getEvent = JSI::CreateFunction(CalendarModule::GetEvent);
+ getEvents = JSI::CreateFunction(CalendarModule::GetEvents);
+ getAccount = JSI::CreateFunction(CalendarModule::GetAccount);
+ getConfig = JSI::CreateFunction(CalendarModule::GetConfig);
+ setConfig = JSI::CreateFunction(CalendarModule::SetConfig);
+ JSI::SetNamedProperty(calendarObj, ADD_EVENT, addEvent);
+ JSI::SetNamedProperty(calendarObj, ADD_EVENTS, addEvents);
+ JSI::SetNamedProperty(calendarObj, DELETE_EVENT, deleteEvent);
+ JSI::SetNamedProperty(calendarObj, DELETE_EVENTS, deleteEvents);
+ JSI::SetNamedProperty(calendarObj, UPDATE_EVENT, updateEvent);
+ JSI::SetNamedProperty(calendarObj, UPDATE_EVENTS, updateEvents);
+ JSI::SetNamedProperty(calendarObj, GET_EVENT, getEvent);
+ JSI::SetNamedProperty(calendarObj, GET_EVENTS, getEvents);
+ JSI::SetNamedProperty(calendarObj, GET_ACCOUNT, getAccount);
+ JSI::SetNamedProperty(calendarObj, GET_CONFIG, getConfig);
+ JSI::SetNamedProperty(calendarObj, SET_CONFIG, setConfig);
+ // Store calendar account information;
+ args[1] = calendarObj;
+ if (callbackData_) {
+ FreeCallbackData(callbackData_);
+ callbackData_ = nullptr;
+ }
+ callbackData_ = callbackData;
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+ JSI::ReleaseValueList(args[0],
+ args[1],
+ addEvent,
+ addEvents,
+ deleteEvent,
+ deleteEvents,
+ updateEvent,
+ updateEvents,
+ getConfig,
+ setConfig,
+ getEvent,
+ getEvents,
+ getAccount,
+ ARGS_END);
+ } else {
+ // Failure: first parameter is error message, second is null
+ args[0] = JSI::CreateString(GetCalendarErrorString(error));
+ args[1] = JSI::CreateNull();
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+ JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+ FreeCallbackData(callbackData);
+ }
+}
+
+// Add event
+void CalendarModule::AddEventCallback(void *data)
+{
+ CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+ if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+ FreeCallbackData(callbackData);
+ return;
+ }
+ CalendarError error = CALENDAR_INVALID_PARAMETER;
+ int id = AllocateAndSetCalendarEvent(callbackData->eventarray.events);
+ if (id > 0) {
+ error = AppendEvent(GetCanlendarFilePath(), callbackData_->account.name, callbackData->eventarray.events);
+ if (error != CALENDAR_SUCCESS) {
+ FreeEventId(id);
+ }
+ } else {
+ error = CALENDAR_EVENT_ID_ALLOC_FAILED;
+ free(callbackData->eventarray.events);
+ }
+
+ JSIValue args[ARGC_TWO];
+ if (error == CALENDAR_SUCCESS) {
+ args[1] = JSI::CreateNumber(callbackData->eventarray.events->id);
+ args[0] = JSI::CreateNull();
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+ JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+ } else {
+ args[0] = JSI::CreateString(GetCalendarErrorString(error));
+ args[1] = JSI::CreateNull();
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+ JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+ }
+ delete callbackData;
+ callbackData = nullptr;
+}
+
+JSIValue CalendarModule::AddEvent(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ // Implement logic for adding a single event
+ if (callbackData_ == nullptr) {
+ return nullptr;
+ }
+ if (argsNum < 1 || !JSI::ValueIsFunction(args[1]) || !JSI::ValueIsObject(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for AddEvent");
+ return JSI::CreateUndefined();
+ }
+ CalendarCallback *callbackData = new CalendarCallback();
+ if (!callbackData) {
+ return JSI::CreateUndefined();
+ }
+ callbackData->eventarray.events = (CalendarEvent *)malloc(sizeof(CalendarEvent));
+ if (!callbackData->eventarray.events) {
+ delete callbackData;
+ return JSI::CreateUndefined();
+ }
+ if (strcpy_s(callbackData->eventarray.events->bundlename,
+ sizeof(callbackData->eventarray.events->bundlename),
+ GetBundleName()) != EOK) {
+ free(callbackData->eventarray.events);
+ delete callbackData;
+ return JSI::CreateUndefined();
+ }
+ callbackData->eventarray.events->startTime = (int64_t)JSI::GetNumberProperty(args[0], "startTime");
+ callbackData->eventarray.events->endTime = (int64_t)JSI::GetNumberProperty(args[0], "endTime");
+ callbackData->eventarray.events->type = (int)JSI::GetNumberProperty(args[0], "type");
+ char *eventContent = JSI::GetStringProperty(args[0], "eventContent");
+ if (strcpy_s(callbackData->eventarray.events->eventContent,
+ sizeof(callbackData->eventarray.events->eventContent),
+ eventContent) != EOK) {
+ free(callbackData->eventarray.events);
+ ace_free(eventContent);
+ delete callbackData;
+ return JSI::CreateUndefined();
+ }
+ ace_free(eventContent);
+ callbackData->eventarray.events->isAllDay = JSI::GetBooleanProperty(args[0], "isAllDay");
+ callbackData->eventarray.events->hasReminder = JSI::GetBooleanProperty(args[0], "hasReminder");
+ callbackData->eventarray.events->isRepeat = JSI::GetBooleanProperty(args[0], "isRepeat");
+ callbackData->eventarray.events->recurrenceFrequency =
+ (int64_t)JSI::GetNumberProperty(args[0], "recurrenceFrequency");
+ // Save callback function and context
+ callbackData->callback = JSI::AcquireValue(args[1]);
+ callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+ OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(AddEventCallback, static_cast<void *>(callbackData));
+ return JSI::CreateUndefined();
+}
+
+// Add multiple events
+void CalendarModule::AddEventsCallback(void *data)
+{
+ CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+ if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+ FreeCallbackData(callbackData);
+ return;
+ }
+ CalendarError error = CALENDAR_SUCCESS;
+ int *ids = static_cast<int*>(ace_malloc(sizeof(int) * callbackData->eventarray.count));
+ if (!ids) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+ FreeCallbackData(callbackData);
+ return;
+ }
+ for (uint32_t arrIndex = 0; arrIndex < callbackData->eventarray.count; arrIndex++) {
+ CalendarEvent *event = (CalendarEvent *)malloc(sizeof(CalendarEvent));
+ if (!event) {
+ FreeCallbackData(callbackData);
+ return;
+ }
+ if(memcpy_s(event, sizeof(CalendarEvent),
+ callbackData->eventarray.events + arrIndex, sizeof(CalendarEvent)) != EOK) {
+ FreeCallbackData(callbackData);
+ return;
+ }
+ ids[arrIndex] = AllocateAndSetCalendarEvent(event);
+ callbackData->eventarray.events[arrIndex].id = ids[arrIndex];
+ if (ids[arrIndex] <= 0) {
+ error = CALENDAR_EVENT_ID_ALLOC_FAILED;
+ for (uint32_t i = 0; i < arrIndex; i++) {
+ FreeEventId(ids[i]);
+ }
+ break;
+ }
+ }
+ ace_free(ids);
+ bool flag = true;
+ if (error == CALENDAR_SUCCESS) {
+ error = AppendEvents(GetCanlendarFilePath(), callbackData_->account.name, &callbackData->eventarray);
+ if (error != CALENDAR_SUCCESS) {
+ flag = false;
+ }
+ }
+ JSIValue args[ARGC_TWO];
+ JSIValue result[callbackData->eventarray.count];
+ if (error == CALENDAR_SUCCESS) {
+ JSIValue evnetArray = JSI::CreateArray(callbackData->eventarray.count);
+ for (uint32_t evnetArrayCnt = 0; evnetArrayCnt < callbackData->eventarray.count; evnetArrayCnt++) {
+ result[evnetArrayCnt] = JSI::CreateNumber(callbackData->eventarray.events[evnetArrayCnt].id);
+ JSI::SetPropertyByIndex(evnetArray, evnetArrayCnt, result[evnetArrayCnt]);
+ }
+ args[1] = evnetArray;
+ args[0] = JSI::CreateNull();
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+ for (uint32_t evnetArrayCnt = 0; evnetArrayCnt < callbackData->eventarray.count; evnetArrayCnt++) {
+ JSI::ReleaseValue(result[evnetArrayCnt]);
+ }
+ JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+ } else {
+ if (!flag) {
+ for (uint32_t arrIndex = 0; arrIndex < callbackData->eventarray.count; arrIndex++) {
+ FreeEventId(callbackData->eventarray.events[arrIndex].id);
+ }
+ }
+ args[0] = JSI::CreateString(GetCalendarErrorString(error));
+ args[1] = JSI::CreateNull();
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+ JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+ }
+ if (callbackData->eventarray.events) {
+ free(static_cast<void*>(callbackData->eventarray.events));
+ }
+
+ delete callbackData;
+ callbackData = nullptr;
+}
+
+// Batch add events
+JSIValue CalendarModule::AddEvents(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ // Implement logic for batch adding events
+ if (callbackData_ == nullptr) {
+ return nullptr;
+ }
+ if (argsNum < 1 || !JSI::ValueIsFunction(args[1]) || !JSI::ValueIsArray(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for AddEvents");
+ return JSI::CreateUndefined();
+ }
+ CalendarCallback *callbackData = new CalendarCallback();
+ if (!callbackData) {
+ return JSI::CreateUndefined();
+ }
+ uint32_t count = JSI::GetArrayLength(args[0]);
+ callbackData->eventarray.events = (CalendarEvent *)malloc(sizeof(CalendarEvent) * count);
+ if (!callbackData->eventarray.events) {
+ delete callbackData;
+ return JSI::CreateUndefined();
+ }
+ for (uint32_t arrIndex = 0; arrIndex < count; arrIndex++) {
+ JSIValue point = JSI::GetPropertyByIndex(args[0], arrIndex);
+ if (strcpy_s(callbackData->eventarray.events[arrIndex].bundlename,
+ sizeof(callbackData->eventarray.events[arrIndex].bundlename),
+ GetBundleName()) != EOK) {
+ free(callbackData->eventarray.events);
+ delete callbackData;
+ return JSI::CreateUndefined();
+ }
+ callbackData->eventarray.events[arrIndex].startTime = (int64_t)JSI::GetNumberProperty(point, "startTime");
+ callbackData->eventarray.events[arrIndex].endTime = (int64_t)JSI::GetNumberProperty(point, "endTime");
+ callbackData->eventarray.events[arrIndex].type = (int)JSI::GetNumberProperty(point, "type");
+ callbackData->eventarray.events[arrIndex].isAllDay = JSI::GetBooleanProperty(point, "isAllDay");
+ callbackData->eventarray.events[arrIndex].hasReminder = JSI::GetBooleanProperty(point, "hasReminder");
+ callbackData->eventarray.events[arrIndex].isRepeat = JSI::GetBooleanProperty(point, "isRepeat");
+ callbackData->eventarray.events[arrIndex].recurrenceFrequency =
+ (int64_t)JSI::GetNumberProperty(point, "recurrenceFrequency");
+ char *eventContent = JSI::GetStringProperty(point, "eventContent");
+ if (strcpy_s(callbackData->eventarray.events[arrIndex].eventContent,
+ sizeof(callbackData->eventarray.events[arrIndex].eventContent),
+ eventContent) != EOK) {
+ free(callbackData->eventarray.events);
+ ace_free(eventContent);
+ delete callbackData;
+ return JSI::CreateUndefined();
+ }
+ ace_free(eventContent);
+ JSI::ReleaseValue(point);
+ }
+ callbackData->eventarray.count = count;
+ // Save callback function and context
+ callbackData->callback = JSI::AcquireValue(args[1]);
+ callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+ OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(AddEventsCallback, static_cast<void *>(callbackData));
+ return JSI::CreateUndefined();
+}
+
+// Delete event
+void CalendarModule::DeleteEventCallback(void *data)
+{
+ CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+ if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+ FreeCallbackData(callbackData);
+ return;
+ }
+ CalendarError error = CALENDAR_INVALID_PARAMETER;
+ error = CalendarDeleteEvent(GetCanlendarFilePath(),
+ callbackData_->account.name, callbackData->eventarray.events->id);
+ JSIValue args[ARGC_ONE];
+ if (error == CALENDAR_SUCCESS) {
+ FreeEventId(callbackData->eventarray.events->id);
+ args[0] = JSI::CreateNull();
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_ONE);
+ JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], ARGS_END);
+ } else {
+ args[0] = JSI::CreateString(GetCalendarErrorString(error));
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_ONE);
+ JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], ARGS_END);
+ }
+ free(static_cast<void*>(callbackData->eventarray.events));
+ delete callbackData;
+ callbackData = nullptr;
+}
+
+JSIValue CalendarModule::DeleteEvent(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ // Implement logic for deleting a single event
+ if (callbackData_ == nullptr) {
+ return nullptr;
+ }
+ if (argsNum < 1 || !JSI::ValueIsFunction(args[1]) || !JSI::ValueIsNumber(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for DeleteEvent");
+ return JSI::CreateUndefined();
+ }
+ CalendarCallback *callbackData = new CalendarCallback();
+ if (!callbackData) {
+ return JSI::CreateUndefined();
+ }
+ callbackData->eventarray.events = (CalendarEvent *)malloc(sizeof(CalendarEvent));
+ if (!callbackData->eventarray.events) {
+ delete callbackData;
+ return JSI::CreateUndefined();
+ }
+ callbackData->eventarray.events->id = static_cast<int64_t>(JSI::ValueToNumber(args[0]));
+ // Save callback function and context
+ callbackData->callback = JSI::AcquireValue(args[1]);
+ callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+ OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(DeleteEventCallback, static_cast<void *>(callbackData));
+ return JSI::CreateUndefined();
+}
+
+// Batch delete events
+void CalendarModule::DeleteEventsCallback(void *data)
+{
+ CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+ if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+ FreeCallbackData(callbackData);
+ return;
+ }
+ CalendarError error = CALENDAR_INVALID_PARAMETER;
+ int *eventIds = static_cast<int*>(ace_malloc(sizeof(int) * callbackData->eventarray.count));
+ if (!eventIds) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+ FreeCallbackData(callbackData);
+ return;
+ }
+ for (uint32_t i = 0; i < callbackData->eventarray.count; i++) {
+ eventIds[i] = callbackData->eventarray.events[i].id;
+ }
+ error = CalendarDeleteEvents(GetCanlendarFilePath(),
+ callbackData_->account.name, eventIds, callbackData->eventarray.count);
+ ace_free(eventIds);
+ JSIValue args[ARGC_ONE];
+ if (error == CALENDAR_SUCCESS) {
+ for (uint32_t i = 0; i < callbackData->eventarray.count; i++) {
+ FreeEventId(callbackData->eventarray.events[i].id);
+ }
+ args[0] = JSI::CreateNull();
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_ONE);
+ JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], ARGS_END);
+ } else {
+ args[0] = JSI::CreateString(GetCalendarErrorString(error));
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_ONE);
+ JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], ARGS_END);
+ }
+ free(static_cast<void*>(callbackData->eventarray.events));
+ delete callbackData;
+ callbackData = nullptr;
+}
+
+JSIValue CalendarModule::DeleteEvents(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ // Implement logic for batch deleting events
+ if (callbackData_ == nullptr) {
+ return nullptr;
+ }
+ if (argsNum < 1 || !JSI::ValueIsFunction(args[1]) || !JSI::ValueIsArray(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for DeleteEvents");
+ return JSI::CreateUndefined();
+ }
+ CalendarCallback *callbackData = new CalendarCallback();
+ if (!callbackData) {
+ return JSI::CreateUndefined();
+ }
+ uint32_t count = JSI::GetArrayLength(args[0]);
+ callbackData->eventarray.events = (CalendarEvent *)malloc(sizeof(CalendarEvent) * count);
+ if (!callbackData->eventarray.events) {
+ delete callbackData;
+ return JSI::CreateUndefined();
+ }
+ for (uint32_t arrIndex = 0; arrIndex < count; arrIndex++) {
+ JSIValue point = JSI::GetPropertyByIndex(args[0], arrIndex);
+ callbackData->eventarray.events[arrIndex].id = static_cast<int64_t>(JSI::GetNumberProperty(point, "id"));
+ JSI::ReleaseValue(point);
+ }
+ callbackData->eventarray.count = count;
+ // Save callback function and context
+ callbackData->callback = JSI::AcquireValue(args[1]);
+ callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+ OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(DeleteEventsCallback, static_cast<void *>(callbackData));
+ return JSI::CreateUndefined();
+}
+
+// Update event
+void CalendarModule::UpdateEventCallback(void *data)
+{
+ CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+ if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+ FreeCallbackData(callbackData);
+ return;
+ }
+ CalendarError error = CALENDAR_INVALID_PARAMETER;
+ error = CalendarUpdateEvent(GetCanlendarFilePath(), callbackData_->account.name, callbackData->eventarray.events);
+ JSIValue args[ARGC_ONE];
+ if (error == CALENDAR_SUCCESS) {
+ FreeEventId(callbackData->eventarray.events->id);
+ CalendarEvent *event = (CalendarEvent *)malloc(sizeof(CalendarEvent));
+ if (!event) {
+ FreeCallbackData(callbackData);
+ return;
+ }
+ if(memcpy_s(event, sizeof(CalendarEvent), callbackData->eventarray.events, sizeof(CalendarEvent)) != EOK) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "memcpy_s fail");
+ }
+ SetCalendarEventWithSpecificId(callbackData->eventarray.events->id, event);
+ args[0] = JSI::CreateNull();
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_ONE);
+ JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], ARGS_END);
+ } else {
+ args[0] = JSI::CreateString(GetCalendarErrorString(error));
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_ONE);
+ JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], ARGS_END);
+ }
+ if (static_cast<void*>(callbackData->eventarray.events)) {
+ free(static_cast<void*>(callbackData->eventarray.events));
+ }
+ delete callbackData;
+ callbackData = nullptr;
+}
+
+JSIValue CalendarModule::UpdateEvent(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ // Implement logic for updating a single event
+ if (callbackData_ == nullptr) {
+ return nullptr;
+ }
+ if (argsNum < 1 || !JSI::ValueIsFunction(args[1]) || !JSI::ValueIsObject(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for UpdateEvent");
+ return JSI::CreateUndefined();
+ }
+ CalendarCallback *callbackData = new CalendarCallback();
+ if (!callbackData) {
+ return JSI::CreateUndefined();
+ }
+ callbackData->eventarray.events = (CalendarEvent *)malloc(sizeof(CalendarEvent));
+ if (!callbackData->eventarray.events) {
+ delete callbackData;
+ return JSI::CreateUndefined();
+ }
+ if (strcpy_s(callbackData->eventarray.events->bundlename,
+ sizeof(callbackData->eventarray.events->bundlename),
+ GetBundleName()) != EOK) {
+ free(callbackData->eventarray.events);
+ delete callbackData;
+ return JSI::CreateUndefined();
+ }
+ callbackData->eventarray.events->startTime = (int64_t)JSI::GetNumberProperty(args[0], "startTime");
+ callbackData->eventarray.events->endTime = (int64_t)JSI::GetNumberProperty(args[0], "endTime");
+ callbackData->eventarray.events->type = (int)JSI::GetNumberProperty(args[0], "type");
+ callbackData->eventarray.events->id = (int)JSI::GetNumberProperty(args[0], "id");
+ char *eventContent = JSI::GetStringProperty(args[0], "eventContent");
+ if (strcpy_s(callbackData->eventarray.events->eventContent,
+ sizeof(callbackData->eventarray.events->eventContent),
+ eventContent) != EOK) {
+ free(callbackData->eventarray.events);
+ ace_free(eventContent);
+ delete callbackData;
+ return JSI::CreateUndefined();
+ }
+ ace_free(eventContent);
+ callbackData->eventarray.events->isAllDay = JSI::GetBooleanProperty(args[0], "isAllDay");
+ callbackData->eventarray.events->hasReminder = JSI::GetBooleanProperty(args[0], "hasReminder");
+ callbackData->eventarray.events->isRepeat = JSI::GetBooleanProperty(args[0], "isRepeat");
+ callbackData->eventarray.events->recurrenceFrequency =
+ (int64_t)JSI::GetNumberProperty(args[0], "recurrenceFrequency");
+ // Save callback function and context
+ callbackData->callback = JSI::AcquireValue(args[1]);
+ callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+ OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(UpdateEventCallback, static_cast<void *>(callbackData));
+ return JSI::CreateUndefined();
+}
+
+// Batch update events
+void CalendarModule::UpdateEventsCallback(void *data)
+{
+ CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+ if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+ FreeCallbackData(callbackData);
+ return;
+ }
+ CalendarError error = CALENDAR_INVALID_PARAMETER;
+ error = CalendarUpdateEvents(GetCanlendarFilePath(), callbackData_->account.name, &callbackData->eventarray);
+ if (error == CALENDAR_SUCCESS) {
+ for (uint32_t evnetArrayCnt = 0; evnetArrayCnt < callbackData->eventarray.count; evnetArrayCnt++) {
+ CalendarEvent *event = (CalendarEvent *)malloc(sizeof(CalendarEvent));
+ if (!event) {
+ FreeCallbackData(callbackData);
+ return;
+ }
+ memcpy_s(
+ event, sizeof(CalendarEvent), callbackData->eventarray.events + evnetArrayCnt, sizeof(CalendarEvent));
+ FreeEventId(callbackData->eventarray.events[evnetArrayCnt].id);
+ SetCalendarEventWithSpecificId(callbackData->eventarray.events[evnetArrayCnt].id, event);
+ }
+ }
+ JSIValue args[ARGC_TWO];
+ JSIValue result[callbackData->eventarray.count];
+ if (error == CALENDAR_SUCCESS) {
+ JSIValue evnetArray = JSI::CreateArray(callbackData->eventarray.count);
+ for (uint32_t evnetArrayCnt = 0; evnetArrayCnt < callbackData->eventarray.count; evnetArrayCnt++) {
+ result[evnetArrayCnt] = JSI::CreateNumber(callbackData->eventarray.events[evnetArrayCnt].id);
+ JSI::SetPropertyByIndex(evnetArray, evnetArrayCnt, result[evnetArrayCnt]);
+ }
+ args[1] = evnetArray;
+ args[0] = JSI::CreateNull();
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+ for (uint32_t evnetArrayCnt = 0; evnetArrayCnt < callbackData->eventarray.count; evnetArrayCnt++) {
+ JSI::ReleaseValue(result[evnetArrayCnt]);
+ }
+ JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+ } else {
+ args[0] = JSI::CreateString(GetCalendarErrorString(error));
+ args[1] = JSI::CreateNull();
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+ JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+ }
+ if (callbackData->eventarray.events) {
+ free(static_cast<void*>(callbackData->eventarray.events));
+ }
+ delete callbackData;
+ callbackData = nullptr;
+}
+
+JSIValue CalendarModule::UpdateEvents(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ // Implement logic for batch updating events
+ if (callbackData_ == nullptr) {
+ return nullptr;
+ }
+ if (argsNum < 1 || !JSI::ValueIsFunction(args[1]) || !JSI::ValueIsArray(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for UpdateEvents");
+ return JSI::CreateUndefined();
+ }
+ CalendarCallback *callbackData = new CalendarCallback();
+ if (!callbackData) {
+ return JSI::CreateUndefined();
+ }
+ uint32_t count = JSI::GetArrayLength(args[0]);
+ callbackData->eventarray.events = (CalendarEvent *)malloc(sizeof(CalendarEvent) * count);
+ if (!callbackData->eventarray.events) {
+ delete callbackData;
+ return JSI::CreateUndefined();
+ }
+ for (uint32_t arrIndex = 0; arrIndex < count; arrIndex++) {
+ JSIValue point = JSI::GetPropertyByIndex(args[0], arrIndex);
+ if (strcpy_s(callbackData->eventarray.events[arrIndex].bundlename,
+ sizeof(callbackData->eventarray.events[arrIndex].bundlename),
+ GetBundleName()) != EOK) {
+ free(callbackData->eventarray.events);
+ delete callbackData;
+ return JSI::CreateUndefined();
+ }
+ callbackData->eventarray.events[arrIndex].startTime = (int64_t)JSI::GetNumberProperty(point, "startTime");
+ callbackData->eventarray.events[arrIndex].endTime = (int64_t)JSI::GetNumberProperty(point, "endTime");
+ callbackData->eventarray.events[arrIndex].type = (int)JSI::GetNumberProperty(point, "type");
+ callbackData->eventarray.events[arrIndex].id = (int64_t)JSI::GetNumberProperty(point, "id");
+ char *eventContent = JSI::GetStringProperty(point, "eventContent");
+ if (strcpy_s(callbackData->eventarray.events[arrIndex].eventContent,
+ sizeof(callbackData->eventarray.events[arrIndex].eventContent),
+ eventContent) != EOK) {
+ ace_free(eventContent);
+ free(callbackData->eventarray.events);
+ delete callbackData;
+ return JSI::CreateUndefined();
+ }
+ ace_free(eventContent);
+ callbackData->eventarray.events[arrIndex].isAllDay = JSI::GetBooleanProperty(point, "isAllDay");
+ callbackData->eventarray.events[arrIndex].hasReminder = JSI::GetBooleanProperty(point, "hasReminder");
+ callbackData->eventarray.events[arrIndex].isRepeat = JSI::GetBooleanProperty(point, "isRepeat");
+ callbackData->eventarray.events[arrIndex].recurrenceFrequency =
+ (int64_t)JSI::GetNumberProperty(point, "recurrenceFrequency");
+ JSI::ReleaseValue(point);
+ }
+ callbackData->eventarray.count = count;
+ // Save callback function and context
+ callbackData->callback = JSI::AcquireValue(args[1]);
+ callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+ OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(UpdateEventsCallback, static_cast<void *>(callbackData));
+ return JSI::CreateUndefined();
+}
+
+// Get event
+void CalendarModule::GetEventCallback(void *data)
+{
+ CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+ if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+ FreeCallbackData(callbackData);
+ return;
+ }
+ CalendarError error = CALENDAR_INVALID_PARAMETER;
+ CalendarEvent *event = CalendarGetEvent(GetCanlendarFilePath(),
+ callbackData_->account.name, callbackData->eventarray.events->id, &error);
+ JSIValue args[ARGC_TWO];
+ if (error == CALENDAR_SUCCESS && event != nullptr) {
+ args[1] = JSI::CreateObject();
+ JSI::SetNumberProperty(args[1], "startTime", event->startTime);
+ JSI::SetNumberProperty(args[1], "endTime", event->endTime);
+ JSI::SetNumberProperty(args[1], "type", event->type);
+ JSI::SetNumberProperty(args[1], "id", event->id);
+ JSI::SetStringProperty(args[1], "bundlename", event->bundlename);
+ JSI::SetBooleanProperty(args[1], "isAllDay", event->isAllDay);
+ JSI::SetBooleanProperty(args[1], "hasReminder", event->hasReminder);
+ JSI::SetBooleanProperty(args[1], "isRepeat", event->isRepeat);
+ JSI::SetNumberProperty(args[1], "recurrenceFrequency", event->recurrenceFrequency);
+ JSI::SetStringProperty(args[1], "eventContent", event->eventContent);
+ args[0] = JSI::CreateNull();
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+ JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+ } else {
+ args[0] = JSI::CreateString(GetCalendarErrorString(error));
+ args[1] = JSI::CreateNull();
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+ JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+ }
+ if (event) {
+ free(event);
+ }
+ free(callbackData->eventarray.events);
+ delete callbackData;
+ callbackData = nullptr;
+}
+
+JSIValue CalendarModule::GetEvent(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ // Implement logic for getting a single event
+ if (callbackData_ == nullptr) {
+ return nullptr;
+ }
+ if (argsNum < 1 || !JSI::ValueIsFunction(args[1]) || !JSI::ValueIsNumber(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for GetEvent");
+ return JSI::CreateUndefined();
+ }
+ CalendarCallback *callbackData = new CalendarCallback();
+ if (!callbackData) {
+ return JSI::CreateUndefined();
+ }
+ callbackData->eventarray.events = (CalendarEvent *)malloc(sizeof(CalendarEvent));
+ if (!callbackData->eventarray.events) {
+ delete callbackData;
+ return JSI::CreateUndefined();
+ }
+ callbackData->eventarray.events->id = static_cast<int64_t>(JSI::ValueToNumber(args[0]));
+ // Save callback function and context
+ callbackData->callback = JSI::AcquireValue(args[1]);
+ callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+ OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(GetEventCallback, static_cast<void *>(callbackData));
+ return JSI::CreateUndefined();
+}
+
+// Get all events
+void CalendarModule::GetEventsCallback(void *data)
+{
+ CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+ if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+ FreeCallbackData(callbackData);
+ return;
+ }
+ CalendarError error = CALENDAR_INVALID_PARAMETER;
+ CalendarEventArray *eventarray = CalendarGetEvents(GetCanlendarFilePath(), callbackData_->account.name, &error);
+ JSIValue args[ARGC_TWO];
+ if (error == CALENDAR_SUCCESS && eventarray != nullptr) {
+ args[1] = JSI::CreateArray(eventarray->count);
+ for (uint32_t arrIndex = 0; arrIndex < eventarray->count; arrIndex++) {
+ JSIValue point = JSI::CreateObject();
+ JSI::SetNumberProperty(point, "startTime", eventarray->events[arrIndex].startTime);
+ JSI::SetNumberProperty(point, "endTime", eventarray->events[arrIndex].endTime);
+ JSI::SetNumberProperty(point, "type", eventarray->events[arrIndex].type);
+ JSI::SetNumberProperty(point, "id", eventarray->events[arrIndex].id);
+ JSI::SetStringProperty(point, "bundlename", eventarray->events[arrIndex].bundlename);
+ JSI::SetBooleanProperty(point, "isAllDay", eventarray->events[arrIndex].isAllDay);
+ JSI::SetBooleanProperty(point, "hasReminder", eventarray->events[arrIndex].hasReminder);
+ JSI::SetBooleanProperty(point, "isRepeat", eventarray->events[arrIndex].isRepeat);
+ JSI::SetNumberProperty(point, "recurrenceFrequency", eventarray->events[arrIndex].recurrenceFrequency);
+ JSI::SetStringProperty(point, "eventContent", eventarray->events[arrIndex].eventContent);
+ JSI::SetPropertyByIndex(args[1], arrIndex, point);
+ JSI::ReleaseValue(point);
+ }
+ args[0] = JSI::CreateNull();
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+ JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+ } else {
+ args[0] = JSI::CreateString(GetCalendarErrorString(error));
+ args[1] = JSI::CreateNull();
+ JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+ JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+ }
+ if (eventarray) {
+ if (eventarray->events) {
+ free(eventarray->events);
+ }
+ free(eventarray);
+ }
+
+ delete callbackData;
+ callbackData = nullptr;
+}
+
+JSIValue CalendarModule::GetEvents(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ // Implement logic for getting all events
+ if (callbackData_ == nullptr) {
+ return nullptr;
+ }
+ if (argsNum < 1 || !JSI::ValueIsFunction(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for GetEvents");
+ return JSI::CreateUndefined();
+ }
+ CalendarCallback *callbackData = new CalendarCallback();
+ if (!callbackData) {
+ return JSI::CreateUndefined();
+ }
+ // Save callback function and context
+ callbackData->callback = JSI::AcquireValue(args[0]);
+ callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+ OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(GetEventsCallback, static_cast<void *>(callbackData));
+ return JSI::CreateUndefined();
+}
+
+// Get account information
+JSIValue CalendarModule::GetAccount(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ // Implement logic for getting account information
+ if (argsNum != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for GetAccount");
+ return JSI::CreateUndefined();
+ }
+ if (callbackData_) {
+ JSIValue point = JSI::CreateObject();
+ JSI::SetStringProperty(point, "name", callbackData_->account.name);
+ JSI::SetStringProperty(point, "displayName", callbackData_->account.displayName);
+ JSI::SetStringProperty(point, "type", callbackData_->account.type);
+ return point;
+ } else {
+ return JSI::CreateUndefined();
+ }
+}
+
+// Set Config information
+JSIValue CalendarModule::SetConfig(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ // Implement logic for getting account information
+ if (argsNum < 1 || !JSI::ValueIsObject(args[0])) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for SetConfig");
+ return JSI::CreateBoolean(false);
+ }
+ if (callbackData_) {
+ callbackData_->enableReminder = JSI::GetBooleanProperty(args[0], "enableReminder");
+ callbackData_->color = JSI::GetNumberProperty(args[0], "color");
+ return JSI::CreateBoolean(true);
+ } else {
+ return JSI::CreateBoolean(false);
+ }
+}
+
+// Get Config information
+JSIValue CalendarModule::GetConfig(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ // Implement logic for getting account information
+ if (argsNum != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for GetConfig");
+ return JSI::CreateUndefined();
+ }
+ if (callbackData_) {
+ JSIValue point = JSI::CreateObject();
+ JSI::SetBooleanProperty(point, "enableReminder", callbackData_->enableReminder);
+ JSI::SetNumberProperty(point, "color", callbackData_->color);
+ return point;
+ } else {
+ return JSI::CreateUndefined();
+ }
+}
+
+// Asynchronous callback for event operations
+void CalendarModule::EventOperationCallback(void *data)
+{
+ // Implement callback handling for event operations
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void SetCanlendarFilePath(char *canlendarFilePath)
+{
+ g_canlendarFilePath = canlendarFilePath;
+}
+
+const char *GetCanlendarFilePath(void)
+{
+ return g_canlendarFilePath.c_str();
+}
+#ifdef __cplusplus
+};
+#endif
+
+} // namespace ACELite
+} // namespace OHOS
--- /dev/null
+/**
+ * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved.
+ * Description: appmanger_module module.
+ * Author: CompanyName
+ * Create: 2025-09-04
+ */
+#ifndef OHOS_ACELITE_CALENDAR_MODULE_H
+#define OHOS_ACELITE_CALENDAR_MODULE_H
+
+#include <string>
+#include "acelite_config.h"
+#include "jsi.h"
+#include "js_async_work.h"
+#include "non_copyable.h"
+#include "calendar_manager.h"
+#include "calendar_timer.h"
+
+namespace OHOS {
+namespace ACELite {
+
+// Calendar module callback structure
+struct CalendarCallback {
+ JSIValue callback; // Asynchronous callback function
+ JSIValue jsCtx; // JS context
+ CalendarAccount account; // Calendar account
+ CalendarEventArray eventarray;
+ bool enableReminder;
+ uint64_t color;
+};
+
+class CalendarModule final : public MemoryHeap {
+public:
+ ACE_DISALLOW_COPY_AND_MOVE(CalendarModule);
+ CalendarModule() = default;
+ ~CalendarModule() = default;
+
+ // Module initialization
+ static void Init(JSIValue exports);
+
+ // Calendar management APIs
+ static JSIValue CreateCalendar(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue DeleteCalendar(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue GetCalendar(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+
+ // Calendar event operation APIs
+ static JSIValue AddEvent(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue AddEvents(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue DeleteEvent(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue DeleteEvents(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue UpdateEvent(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue UpdateEvents(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue GetEvent(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue GetEvents(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue GetAccount(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue SetConfig(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+ static JSIValue GetConfig(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+
+ // Asynchronous operation callback functions
+ static void CreateCalendarCallback(void *data);
+ static void DeleteCalendarCallback(void *data);
+ static void GetCalendarCallback(void *data);
+ static void EventOperationCallback(void *data);
+ static void AddEventCallback(void *data);
+ static void AddEventsCallback(void *data);
+ static void DeleteEventCallback(void *data);
+ static void GetEventsCallback(void *data);
+ static void DeleteEventsCallback(void *data);
+ static void GetEventCallback(void *data);
+ static void UpdateEventCallback(void *data);
+ static void UpdateEventsCallback(void *data);
+
+ static const char *const MODULE_NAME;
+ static const char *const CREATE_CALENDAR;
+ static const char *const DELETE_CALENDAR;
+ static const char *const GET_CALENDAR;
+ static const char *const ADD_EVENT;
+ static const char *const ADD_EVENTS;
+ static const char *const DELETE_EVENT;
+ static const char *const DELETE_EVENTS;
+ static const char *const UPDATE_EVENT;
+ static const char *const UPDATE_EVENTS;
+ static const char *const GET_EVENT;
+ static const char *const GET_EVENTS;
+ static const char *const GET_ACCOUNT;
+ static const char *const GET_CONFIG;
+ static const char *const SET_CONFIG;
+
+private:
+ // Helper function: Convert JS object to CalendarAccount
+ static bool ConvertToCalendarAccount(const JSIValue jsAccount, CalendarAccount &account);
+ // Helper function: Convert CalendarEvent to JS object
+ static JSIValue ConvertToJSEvent(const CalendarEvent &event);
+ // Helper function: Convert CalendarAccount to JS object
+ static JSIValue ConvertToJSAccount(const CalendarAccount &account);
+ // Release callback data
+ static void FreeCallbackData(CalendarCallback *callbackData);
+
+ static CalendarCallback *callbackData_;
+};
+
+} // namespace ACELite
+} // namespace OHOS
+
+#endif // OHOS_ACELITE_CALENDAR_MODULE_H
--- /dev/null
+/**
+ * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved.
+ * Description: appmanger_module module.
+ * Author: CompanyName
+ * Create: 2025-09-04
+ */
+#include <securec.h>
+#include <cstdlib>
+#include <cstdlib>
+#include <cstring>
+#include <csignal>
+#include <cerrno>
+#include <cstdio>
+#include "ace_mem_base.h"
+#include "memory_heap.h"
+#include "ace_log.h"
+#include "calendar_timer.h"
+
+namespace OHOS {
+namespace ACELite {
+
+// Timer callback function
+static void TimerCallback(union sigval v)
+{
+ struct CalendarTimer *timer = (struct CalendarTimer *)v.sival_ptr;
+ if (timer != nullptr && timer->cb != nullptr) {
+ timer->cb(timer->arg);
+ }
+}
+
+CalendarTimer *CalendarTimerInit(int32_t periodMs, CalendarTimerCb cb, void *arg, bool isPeriodic)
+{
+ CalendarTimer *timer = CalendarTimerCreate(periodMs, cb, arg, isPeriodic);
+ if (timer) {
+ int ret = CalendarTimerSetTime(timer, periodMs, true);
+ if (ret != 0) {
+ CalendarTimerDelete(timer);
+ return nullptr;
+ }
+ } else {
+ return nullptr;
+ }
+ int ret = CalendarTimerStart(timer);
+ if (ret != 0) {
+ CalendarTimerDelete(timer);
+ return nullptr;
+ }
+ return timer;
+}
+
+CalendarTimer *CalendarTimerCreate(int32_t periodMs, CalendarTimerCb cb, void *arg, bool isPeriodic)
+{
+ // Parameter validation
+ if (periodMs <= 0 || periodMs > MAX_PERIOD_MS || cb == nullptr) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Timer create failed, invalid parameters. period=%d", periodMs);
+ return nullptr;
+ }
+
+ // Allocate timer structure
+ struct CalendarTimer *timer = (struct CalendarTimer *)malloc(sizeof(struct CalendarTimer));
+ if (timer == nullptr) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Timer create failed, out of memory.");
+ return nullptr;
+ }
+
+ // Initialize timer structure
+ memset_s(timer, sizeof(struct CalendarTimer), 0, sizeof(struct CalendarTimer));
+ timer->cb = cb;
+ timer->arg = arg;
+ timer->periodMs = periodMs;
+ timer->isPeriodic = isPeriodic;
+
+ // Create system timer
+ struct sigevent sev;
+ memset_s(&sev, sizeof(sev), 0, sizeof(sev));
+ sev.sigev_notify = SIGEV_THREAD;
+ sev.sigev_notify_function = TimerCallback;
+ sev.sigev_value.sival_ptr = timer;
+
+ if (timer_create(CLOCK_REALTIME, &sev, &timer->timerId) == -1) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Timer create failed. err=%s", strerror(errno));
+ free(timer);
+ return nullptr;
+ }
+
+ return timer;
+}
+
+int CalendarTimerSetTime(CalendarTimer *timer, int32_t periodMs, bool isPeriodic)
+{
+ if (timer == nullptr || periodMs <= 0 || periodMs > MAX_PERIOD_MS) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Timer set time failed, invalid parameters.");
+ return -1;
+ }
+
+ timer->periodMs = periodMs;
+ timer->isPeriodic = isPeriodic;
+ return 0;
+}
+
+int CalendarTimerStart(CalendarTimer *timer)
+{
+ if (timer == nullptr || timer->periodMs <= 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Timer start failed, invalid timer.\n");
+ return -1;
+ }
+
+ struct itimerspec its;
+ its.it_value.tv_sec = timer->periodMs / MS_PER_SECOND;
+ its.it_value.tv_nsec = (timer->periodMs % MS_PER_SECOND) * NS_PER_MS;
+
+ if (timer->isPeriodic) {
+ its.it_interval.tv_sec = its.it_value.tv_sec;
+ its.it_interval.tv_nsec = its.it_value.tv_nsec;
+ } else {
+ its.it_interval.tv_sec = 0;
+ its.it_interval.tv_nsec = 0;
+ }
+
+ if (timer_settime(timer->timerId, 0, &its, nullptr) == -1) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Timer start failed. err=%s\n", strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+int CalendarTimerStop(CalendarTimer *timer)
+{
+ if (timer == nullptr) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Timer stop failed, invalid timer.\n");
+ return -1;
+ }
+
+ struct itimerspec its;
+ memset_s(&its, sizeof(its), 0, sizeof(its));
+
+ if (timer_settime(timer->timerId, 0, &its, nullptr) == -1) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Timer stop failed. err=%s\n", strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+int CalendarTimerDelete(CalendarTimer *timer)
+{
+ if (timer == nullptr) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Timer delete failed, invalid timer.\n");
+ return -1;
+ }
+
+ // Stop the timer first
+ CalendarTimerStop(timer);
+
+ // Delete system timer
+ if (timer_delete(timer->timerId) == -1) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Timer delete failed. err=%s\n", strerror(errno));
+ free(timer);
+ return -1;
+ }
+
+ // Free timer structure
+ free(timer);
+ return 0;
+}
+} // namespace ACELite
+} // namespace OHOS
--- /dev/null
+/**
+ * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved.
+ * Description: appmanger_module module.
+ * Author: CompanyName
+ * Create: 2025-09-04
+ */
+#ifndef CALENDAR_TIMER_H
+#define CALENDAR_TIMER_H
+
+#include <stdint.h>
+#include <ctime>
+#include <stdbool.h>
+#include "sys/time.h"
+
+#define MAX_PERIOD_MS 86400000 // Maximum period is 24 hours
+#define MS_PER_SECOND 1000
+#define NS_PER_MS 1000000
+
+static constexpr int16_t SEC_TO_MILLI = 1000;
+static constexpr int16_t USEC_TO_MILLI = 1000;
+static constexpr int16_t MIN_TO_HOUR = 60;
+static constexpr int16_t HOURLY_SYSTEM = 24;
+
+namespace OHOS {
+namespace ACELite {
+
+// Timer callback function type
+typedef void (*CalendarTimerCb)(void *arg);
+
+// Timer structure definition
+struct CalendarTimer {
+ timer_t timerId; // System timer ID
+ CalendarTimerCb cb; // Callback function
+ void *arg; // Argument for callback function
+ int32_t periodMs; // Period time (in milliseconds)
+ bool isPeriodic; // Whether it's a periodic timer
+};
+
+// Timer handle structure (opaque type, users don't need to know the internal implementation)
+typedef struct CalendarTimer CalendarTimer;
+
+CalendarTimer *CalendarTimerInit(int32_t periodMs, CalendarTimerCb cb, void *arg, bool isPeriodic);
+
+/**
+ * Create a timer
+ * @param periodMs Period time in milliseconds. For one-shot timers, this is the first trigger time
+ * @param cb Timer callback function
+ * @param arg Argument passed to the callback function
+ * @param isPeriodic Whether it's a periodic timer
+ * @return Returns timer handle on success, nullptr on failure
+ */
+CalendarTimer *CalendarTimerCreate(int32_t periodMs, CalendarTimerCb cb, void *arg, bool isPeriodic);
+
+/**
+ * Set the timer's time
+ * @param timer Timer handle
+ * @param periodMs Period time in milliseconds
+ * @param isPeriodic Whether it's a periodic timer
+ * @return Returns 0 on success, -1 on failure
+ */
+int CalendarTimerSetTime(CalendarTimer *timer, int32_t periodMs, bool isPeriodic);
+
+/**
+ * Start the timer
+ * @param timer Timer handle
+ * @return Returns 0 on success, -1 on failure
+ */
+int CalendarTimerStart(CalendarTimer *timer);
+
+/**
+ * Stop the timer
+ * @param timer Timer handle
+ * @return Returns 0 on success, -1 on failure
+ */
+int CalendarTimerStop(CalendarTimer *timer);
+
+/**
+ * Delete the timer
+ * @param timer Timer handle
+ * @return Returns 0 on success, -1 on failure
+ */
+int CalendarTimerDelete(CalendarTimer *timer);
+
+} // namespace ACELite
+} // namespace OHOS
+
+#endif // CALENDAR_TIMER_H
--- /dev/null
+/**
+ * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved.
+ * Description: appmanger_module module.
+ * Author: CompanyName
+ * Create: 2025-09-04
+ */
+#ifndef OHOS_ACELITE_CALENDAR_UTILS_H
+#define OHOS_ACELITE_CALENDAR_UTILS_H
+
+#include <string>
+namespace OHOS {
+namespace ACELite {
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void SetCanlendarFilePath(char *hapPath);
+const char *GetCanlendarFilePath(void);
+#ifdef __cplusplus
+};
+#endif
+
+} // namespace ACELite
+} // namespace OHOS
+
+#endif // OHOS_ACELITE_CALENDAR_MODULE_H
--- /dev/null
+/**
+ * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved.
+ * Description: appmanger_module module.
+ * Author: CompanyName
+ * Create: 2025-09-04
+ */
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <sys/time.h>
+#include <cerrno>
+#include <iostream>
+#include "cJSON.h"
+#include "calendar_utils.h"
+#include "msg_center_msg.h"
+#include "msg_center_client.h"
+#include "event_id_manager.h"
+
+namespace OHOS {
+namespace ACELite {
+#define ALLOC_CALENDAR_EVENTID_FAILD -1
+#define MINUTE_IN_MILLISECONDS 60000
+// Global containers (after splitting)
+std::map<int64_t, CalendarEvent *> reminderEventMap; // Reminder event container
+std::map<int64_t, CalendarEvent *> normalEventMap; // Non-reminder event container
+std::unordered_set<int64_t> usedEventIds; // Used ID set
+int64_t g_reminderEventCount = 0; // Reminder event count
+
+/**
+ * @brief Read file content into a string
+ */
+static char *ReadFileToString(const char *filePath)
+{
+ if (!filePath) {
+ printf("[ERROR] File path is nullptr\n");
+ return nullptr;
+ }
+
+ FILE *file = fopen(filePath, "r");
+ if (!file) {
+ printf("[ERROR] Failed to open file %s (errno: %d)\n", filePath, errno);
+ return nullptr;
+ }
+
+ fseek(file, 0, SEEK_END);
+ long fileSize = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ if (fileSize < 0) {
+ printf("[ERROR] Failed to get file size (errno: %d)\n", errno);
+ fclose(file);
+ return nullptr;
+ }
+
+ char *buffer = (char *)malloc(fileSize + 1);
+ if (!buffer) {
+ printf("[ERROR] Malloc buffer failed\n");
+ fclose(file);
+ return nullptr;
+ }
+
+ size_t readSize = fread(buffer, 1, fileSize, file);
+ if (readSize != static_cast<size_t>(fileSize)) {
+ printf("[ERROR] Failed to read file content\n");
+ free(buffer);
+ fclose(file);
+ return nullptr;
+ }
+ buffer[readSize] = '\0';
+
+ fclose(file);
+ return buffer;
+}
+
+/**
+ * @brief Parse calendar event from JSON object
+ */
+static CalendarEvent *parseCalendarEvent(cJSON *eventJson)
+{
+ if (!eventJson) {
+ return nullptr;
+ }
+
+ CalendarEvent *event = (CalendarEvent *)malloc(sizeof(CalendarEvent));
+ if (!event) {
+ return nullptr;
+ }
+ memset_s(event, sizeof(CalendarEvent), 0, sizeof(CalendarEvent));
+
+ cJSON *idJson = cJSON_GetObjectItem(eventJson, "id");
+ cJSON *typeJson = cJSON_GetObjectItem(eventJson, "type");
+ cJSON *startTimeJson = cJSON_GetObjectItem(eventJson, "startTime");
+ cJSON *endTimeJson = cJSON_GetObjectItem(eventJson, "endTime");
+ cJSON *bundlenameJson = cJSON_GetObjectItem(eventJson, "bundlename");
+ cJSON *isAllDayJson = cJSON_GetObjectItem(eventJson, "isAllDay");
+ cJSON *hasReminderJson = cJSON_GetObjectItem(eventJson, "hasReminder");
+ cJSON *isRepeatJson = cJSON_GetObjectItem(eventJson, "isRepeat");
+ cJSON *recurrenceFrequencyJson = cJSON_GetObjectItem(eventJson, "recurrenceFrequency");
+ cJSON *eventContentJson = cJSON_GetObjectItem(eventJson, "eventContent");
+
+ event->id = idJson ? idJson->valueint : 0;
+ event->type = typeJson ? typeJson->valueint : 0;
+ event->startTime = startTimeJson ? (int64_t)startTimeJson->valuedouble : 0;
+ event->endTime = endTimeJson ? (int64_t)endTimeJson->valuedouble : 0;
+
+ if (bundlenameJson && bundlenameJson->valuestring) {
+ strncpy_s(event->bundlename, sizeof(event->bundlename) - 1,
+ bundlenameJson->valuestring, sizeof(event->bundlename) - 1);
+ }
+
+ event->isAllDay = isAllDayJson ? (isAllDayJson->type == cJSON_True) : false;
+ event->hasReminder = hasReminderJson ? (hasReminderJson->type == cJSON_True) : false;
+ event->isRepeat = isRepeatJson ? (isRepeatJson->type == cJSON_True) : false;
+ event->recurrenceFrequency = recurrenceFrequencyJson ? recurrenceFrequencyJson->valuedouble : 0;
+
+ if (eventContentJson && eventContentJson->valuestring) {
+ strncpy_s(event->eventContent, sizeof(event->eventContent) - 1,
+ eventContentJson->valuestring, sizeof(event->eventContent) - 1);
+ }
+ return event;
+}
+
+/**
+ * @brief Get current timestamp (in milliseconds)
+ */
+static int64_t GetCurrentTimestamp()
+{
+ struct timeval tv;
+ gettimeofday(&tv, nullptr);
+ return static_cast<int64_t>(
+ static_cast<uint64_t>(tv.tv_sec) * SEC_TO_MILLI +
+ static_cast<uint64_t>(tv.tv_usec) / SEC_TO_MILLI
+ );
+}
+
+/**
+ * @brief Calendar timer callback function
+ */
+static void CalendarTimerCallback(void *arg)
+{
+ struct timeval tv;
+ gettimeofday(&tv, nullptr);
+ uint64_t currentTimeMs = GetCurrentTimestamp();
+
+ // Use iterator for traversal to support safe element deletion
+ auto it = reminderEventMap.begin();
+ while (it != reminderEventMap.end()) {
+ // Remove const qualifier since we need to modify startTime and endTime
+ CalendarEvent *event = it->second;
+ if (!event) {
+ // Handle null pointer event, delete directly
+ it = reminderEventMap.erase(it);
+ g_reminderEventCount--;
+ continue;
+ }
+
+ // Logic correction: consider "triggered" when current time exceeds start time
+ bool isTriggered = (currentTimeMs > event->startTime);
+ if (isTriggered) {
+ MsgCenterSendMsg(CALENDAR_TO_MSGCENTER, 0, (void *)event, sizeof(CalendarEvent));
+ if (event->isRepeat) {
+ // Calculate next trigger time for recurring events
+ uint64_t times = (currentTimeMs - event->startTime) / event->recurrenceFrequency;
+ event->startTime += (times + 1) * event->recurrenceFrequency;
+ event->endTime += (times + 1) * event->recurrenceFrequency;
+ ++it; // Move to next element
+ } else {
+ // Insert key-value pair (not iterator) to normalEventMap
+ normalEventMap.insert(*it);
+ // Remove from reminderEventMap and move iterator
+ it = reminderEventMap.erase(it);
+ g_reminderEventCount--;
+ }
+ } else {
+ // Untriggered events: keep in reminder list
+ ++it; // Move to next element
+ }
+ }
+}
+
+// Check if it's a valid reminder event
+static bool CheckValidReminderEvent(int64_t currentTimeMs, CalendarEvent *event)
+{
+ bool isActiveReminder = false;
+ if (event->hasReminder) {
+ bool isExpired = (currentTimeMs > event->startTime);
+ if (!(isExpired && !event->isRepeat)) {
+ isActiveReminder = true;
+ if (isExpired && event->isRepeat) {
+ uint64_t times = (currentTimeMs - event->startTime) / event->recurrenceFrequency;
+ event->startTime += ((times + 1) * event->recurrenceFrequency);
+ event->endTime += ((times + 1) * event->recurrenceFrequency);
+ }
+ }
+ }
+ return isActiveReminder;
+}
+
+/**
+ * @brief Initialize event maps from JSON file
+ */
+bool InitEventMaps()
+{
+ ClearAllEvents();
+ char *jsonContent = ReadFileToString(GetCanlendarFilePath());
+ if (!jsonContent) {
+ return false;
+ }
+ cJSON *root = cJSON_Parse(jsonContent);
+ free(jsonContent);
+ if (!root) {
+ return false;
+ }
+ int64_t currentTimeMs = GetCurrentTimestamp();
+
+ cJSON *userNode = nullptr;
+ cJSON_ArrayForEach(userNode, root)
+ {
+ cJSON *userProp = nullptr;
+ cJSON_ArrayForEach(userProp, userNode)
+ {
+ if (strcmp(userProp->string, "events") == 0 && cJSON_IsArray(userProp)) {
+ cJSON *eventNode = nullptr;
+ cJSON_ArrayForEach(eventNode, userProp)
+ {
+ CalendarEvent *event = parseCalendarEvent(eventNode);
+ if (!event) {
+ continue;
+ }
+
+ usedEventIds.insert(event->id);
+ if (CheckValidReminderEvent(currentTimeMs, event)) {
+ reminderEventMap[event->id] = event;
+ g_reminderEventCount++;
+ } else {
+ normalEventMap[event->id] = event;
+ }
+ }
+ }
+ }
+ }
+ CalendarTimerInit(MINUTE_IN_MILLISECONDS, CalendarTimerCallback, nullptr, true);
+
+ cJSON_Delete(root);
+ return true;
+}
+
+/**
+ * @brief Clear all event data
+ */
+void ClearAllEvents()
+{
+ // Free reminder event memory
+ for (auto &pair : reminderEventMap) {
+ if (pair.second)
+ free(pair.second);
+ }
+ reminderEventMap.clear();
+
+ // Free non-reminder event memory
+ for (auto &pair : normalEventMap) {
+ if (pair.second)
+ free(pair.second);
+ }
+ normalEventMap.clear();
+
+ usedEventIds.clear();
+ g_reminderEventCount = 0;
+}
+
+/**
+ * @brief Check if specified ID is already in use
+ */
+bool IsEventIdInUse(int64_t id)
+{
+ if (id < MIN_EVENT_ID || id > MAX_EVENT_ID) {
+ return false;
+ }
+ return usedEventIds.find(id) != usedEventIds.end();
+}
+
+/**
+ * @brief Automatically allocate ID and set event
+ */
+int64_t AllocateAndSetCalendarEvent(CalendarEvent *event)
+{
+ if (!event) {
+ return ALLOC_CALENDAR_EVENTID_FAILD;
+ }
+
+ // Check reminder event count
+ if (event->hasReminder && g_reminderEventCount >= MAX_REMINDER_COUNT) {
+ fprintf(stderr, "Reminder events have reached maximum limit\n");
+ return ALLOC_CALENDAR_EVENTID_FAILD;
+ }
+ int64_t currentTime = GetCurrentTimestamp();
+ // Find available ID
+ for (int64_t id = MIN_EVENT_ID; id <= MAX_EVENT_ID; ++id) {
+ if (!IsEventIdInUse(id)) {
+ event->id = id;
+ usedEventIds.insert(id);
+
+ // Add to corresponding container based on reminder property
+ if (event->hasReminder && ((event->startTime > currentTime || event->isRepeat))) {
+ reminderEventMap[id] = event;
+ g_reminderEventCount++;
+ } else {
+ normalEventMap[id] = event;
+ }
+ return id;
+ }
+ }
+ fprintf(stderr, "No available event ID\n");
+ return ALLOC_CALENDAR_EVENTID_FAILD;
+}
+
+/**
+ * @brief Set event with specified ID
+ */
+bool SetCalendarEventWithSpecificId(int64_t id, CalendarEvent *event)
+{
+ if (!event || id < MIN_EVENT_ID || id > MAX_EVENT_ID) {
+ return false;
+ }
+ if (IsEventIdInUse(id)) {
+ return false;
+ }
+
+ // Check reminder event count
+ if (event->hasReminder && g_reminderEventCount >= MAX_REMINDER_COUNT) {
+ return false;
+ }
+
+ event->id = id;
+ usedEventIds.insert(id);
+
+ // Add to corresponding container based on reminder property
+ if (event->hasReminder) {
+ reminderEventMap[id] = event;
+ g_reminderEventCount++;
+ } else {
+ normalEventMap[id] = event;
+ }
+
+ return true;
+}
+
+/**
+ * @brief Free resources for event with specified ID
+ */
+int FreeEventId(int64_t id)
+{
+ if (id < MIN_EVENT_ID || id > MAX_EVENT_ID) {
+ return 0;
+ }
+ if (!IsEventIdInUse(id)) {
+ return 0;
+ }
+
+ // Free from corresponding container
+ auto remIt = reminderEventMap.find(id);
+ if (remIt != reminderEventMap.end()) {
+ free(remIt->second);
+ reminderEventMap.erase(remIt);
+ g_reminderEventCount--;
+ usedEventIds.erase(id);
+ return 1;
+ }
+
+ auto normIt = normalEventMap.find(id);
+ if (normIt != normalEventMap.end()) {
+ free(normIt->second);
+ normalEventMap.erase(normIt);
+ usedEventIds.erase(id);
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Get event with specified ID
+ */
+CalendarEvent *GetCalendarEvent(int64_t id)
+{
+ if (id < MIN_EVENT_ID || id > MAX_EVENT_ID) {
+ return nullptr;
+ }
+
+ auto remIt = reminderEventMap.find(id);
+ if (remIt != reminderEventMap.end())
+ return remIt->second;
+
+ auto normIt = normalEventMap.find(id);
+ if (normIt != normalEventMap.end())
+ return normIt->second;
+
+ return nullptr;
+}
+
+/**
+ * @brief Get current count of reminder events
+ */
+int GetReminderEventCount()
+{
+ return g_reminderEventCount;
+}
+
+/**
+ * @brief Check if more reminder events can be added
+ */
+bool CanAddMoreReminders()
+{
+ return g_reminderEventCount < MAX_REMINDER_COUNT;
+}
+
+/**
+ * @brief Update non-reminder event to reminder event
+ */
+bool UpdateNonReminderToReminder(int64_t id, CalendarEvent *updatedEvent)
+{
+ if (id < MIN_EVENT_ID || id > MAX_EVENT_ID || !updatedEvent || !updatedEvent->hasReminder) {
+ return false;
+ }
+
+ // Check if original event is a non-reminder event
+ auto normIt = normalEventMap.find(id);
+ if (normIt == normalEventMap.end() || !normIt->second) {
+ return false;
+ }
+
+ // Check reminder event count
+ if (g_reminderEventCount >= MAX_REMINDER_COUNT) {
+ return false;
+ }
+
+ // Free original event, add new event to reminder container
+ free(normIt->second);
+ normalEventMap.erase(normIt);
+
+ updatedEvent->id = id;
+ reminderEventMap[id] = updatedEvent;
+ g_reminderEventCount++;
+
+ return true;
+}
+
+/**
+ * @brief Timer initialization function (external implementation)
+ */
+void CalendarTimerInit(uint32_t intervalMs, void (*callback)(void *), void *arg, bool isLoop)
+{
+ // Timer implementation provided externally
+ printf("Timer initialized, interval: %u ms\n", intervalMs);
+}
+
+/**
+ * @brief Get reminder event container
+ */
+const std::map<int64_t, CalendarEvent *> &GetReminderEventMap()
+{
+ return reminderEventMap;
+}
+
+/**
+ * @brief Get non-reminder event container
+ */
+const std::map<int64_t, CalendarEvent *> &GetNormalEventMap()
+{
+ return normalEventMap;
+}
+
+} // namespace ACELite
+} // namespace OHOS
--- /dev/null
+/**
+ * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved.
+ * Description: appmanger_module module.
+ * Author: CompanyName
+ * Create: 2025-09-04
+ */
+#ifndef EVENT_ID_MANAGER_H
+#define EVENT_ID_MANAGER_H
+
+#include <cstdint>
+#include <map>
+#include <unordered_set>
+#include "calendar_timer.h"
+#include "calendar_manager.h"
+
+namespace OHOS {
+namespace ACELite {
+
+// Event ID range constants
+const int64_t MIN_EVENT_ID = 1; // Minimum event ID
+const int64_t MAX_EVENT_ID = 64; // Maximum event ID
+const int64_t MAX_REMINDER_COUNT = 32; // Maximum number of reminder events
+
+// Global container declarations
+extern std::map<int64_t, CalendarEvent *> reminderEventMap; // Reminder event container
+extern std::map<int64_t, CalendarEvent *> normalEventMap; // Non-reminder event container
+extern std::unordered_set<int64_t> usedEventIds; // Set of used IDs
+extern int64_t g_reminderEventCount;
+
+// Function declarations
+/**
+ * @brief Initialize event containers from JSON file (automatically split into reminder and non-reminder containers)
+ * @param jsonFilePath Path to the JSON file
+ * @return Returns true if initialization is successful, false otherwise
+ */
+bool InitEventMaps();
+
+/**
+ * @brief Clear all event containers and free memory
+ */
+void ClearAllEvents();
+
+/**
+ * @brief Check if the specified ID is already in use
+ * @param id Event ID
+ * @return Returns true if the ID is in use, false otherwise
+ */
+bool IsEventIdInUse(int64_t id);
+
+/**
+ * @brief Automatically allocate ID and add event (classified into corresponding container based on hasReminder
+ * property)
+ * @param event Pointer to the event
+ * @return Returns the allocated ID on success, 0 on failure
+ */
+int64_t AllocateAndSetCalendarEvent(CalendarEvent *event);
+
+/**
+ * @brief Add event with specified ID (classified into corresponding container based on hasReminder property)
+ * @param id Event ID
+ * @param event Pointer to the event
+ * @return Returns true on success, false on failure
+ */
+bool SetCalendarEventWithSpecificId(int64_t id, CalendarEvent *event);
+
+/**
+ * @brief Free the event with the specified ID
+ * @param id Event ID
+ * @return Returns 1 on success, 0 on failure
+ */
+int FreeEventId(int64_t id);
+
+/**
+ * @brief Get the event with the specified ID
+ * @param id Event ID
+ * @return Returns pointer to the event on success, nullptr on failure
+ */
+CalendarEvent *GetCalendarEvent(int64_t id);
+
+/**
+ * @brief Get the count of reminder events
+ * @return Number of reminder events
+ */
+int GetReminderEventCount();
+
+/**
+ * @brief Check if more reminder events can be added
+ * @return Returns true if more reminders can be added, false otherwise
+ */
+bool CanAddMoreReminders();
+
+/**
+ * @brief Update a non-reminder event to a reminder event
+ * @param id Event ID
+ * @param updatedEvent Updated event
+ * @return Returns true on success, false on failure
+ */
+bool UpdateNonReminderToReminder(int64_t id, CalendarEvent *updatedEvent);
+
+/**
+ * @brief Timer initialization function
+ * @param intervalMs Timer interval in milliseconds
+ * @param callback Callback function
+ * @param arg Callback argument
+ * @param isLoop Whether to loop periodically
+ */
+void CalendarTimerInit(uint32_t intervalMs, void (*callback)(void *), void *arg, bool isLoop);
+
+/**
+ * @brief Get the reminder event container (for external traversal)
+ * @return Constant reference to the reminder event container
+ */
+const std::map<int64_t, CalendarEvent *> &GetReminderEventMap();
+
+/**
+ * @brief Get the non-reminder event container (for external traversal)
+ * @return Constant reference to the non-reminder event container
+ */
+const std::map<int64_t, CalendarEvent *> &GetNormalEventMap();
+
+} // namespace ACELite
+} // namespace OHOS
+
+#endif // EVENT_ID_MANAGER_H
if (display_api->get_screen_state() != SCREEN_ON) {\r
display_api->turn_on_screen();\r
}\r
+ result = display_api->set_screen_set_keepon_timeout(0);\r
result = display_api->set_screen_set_keepon_timeout(3600000); // 3600000ms\r
} else {\r
+ result = display_api->set_screen_set_keepon_timeout(0);\r
result = display_api->set_screen_set_keepon_timeout(g_keepOnTimeout);\r
}\r
if (result == ERRCODE_SUCC) {\r
\r
using namespace OHOS::Location;\r
\r
-const double LocationModule::LONGITUDE = 123.456789;\r
-const double LocationModule::LATITUDE = 45.678901;\r
-const double LocationModule::ALTITUDE = 100.0;\r
-const double LocationModule::ACCURACY = 10.0;\r
-const uint32_t LocationModule::TIME = 163456789;\r
+double LocationModule::LONGITUDE = 123.456789;\r
+double LocationModule::LATITUDE = 45.678901;\r
+double LocationModule::ALTITUDE = 100.0;\r
+double LocationModule::ACCURACY = 10.0;\r
+uint32_t LocationModule::TIME = 163456789;\r
+double LocationModule::SPEED_ACCURACY = 14.72;\r
+double LocationModule::ALTITUDE_ACCURACY = 8.4;\r
+double LocationModule::DIRECTION_ACCURACY = 0;\r
+double LocationModule::VELOCITY_NORTH = -43.311;\r
+double LocationModule::VELOCITY_EAST = 16.366;\r
+double LocationModule::VELOCITY_DESCEND = 10;\r
+int32_t LocationModule::SATELLITE_NUMBER = 49;\r
+int32_t LocationModule::STATUS_NUMBER = 1;\r
const char *const LocationModule::LONGITUDE_NAME = "longitude";\r
const char *const LocationModule::LATITUDE_NAME = "latitude";\r
const char *const LocationModule::ALTITUDE_NAME = "altitude";\r
const char *const LocationModule::ACCURACY_NAME = "accuracy";\r
+const char *const LocationModule::SPEED_ACCURACY_NAME = "speedAccuracy";\r
+const char *const LocationModule::ALTITUDE_ACCURACY_NAME = "altitudeAccuracy";\r
+const char *const LocationModule::DIRECTION_ACCURACY_NAME = "directionAccuracy";\r
+const char *const LocationModule::VELOCITY_NORTH_NAME = "velocityNorth";\r
+const char *const LocationModule::VELOCITY_EAST_NAME = "velocityEast";\r
+const char *const LocationModule::VELOCITY_DESCEND_NAME = "velocityDescend";\r
+const char *const LocationModule::STATUS_NUMBER_NAME = "statusNumber";\r
+const char *const LocationModule::SATELLITE_NUMBER_NAME = "satelliteNubmer";\r
const char *const LocationModule::TIME_NAME = "time";\r
const char *const LocationModule::COORD_TYPES_NAME = "coordType";\r
const char *const LocationModule::LOCATIONTYPE_NAME = "types";\r
} CoordTypeMap;\r
\r
LocatorCallback *LocationModule::locatorCallback_ = nullptr;\r
+GnssStatusCallback *LocationModule::gnssStatusCallback_ = nullptr;\r
\r
static CoordTypeMap g_coordTypeMap[] = {\r
{WGS84, "WGS84"},\r
JSIValue LocationModule::Unsubscribe(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
{\r
#if defined(ENABLE_LOCATION)\r
- ExecuteUnsubscribe();\r
+ JsAsyncWork::DispatchAsyncWork(ExecuteUnsubscribe, nullptr);\r
#endif\r
return JSI::CreateUndefined();\r
}\r
return undefValue;\r
}\r
\r
+void LocationModule::OnDestroy()\r
+{\r
+ UnsubscribeAndStopLocating();\r
+}\r
+\r
+void GnssStatusCallback::OnStatusChange(const std::shared_ptr<SatelliteStatus> &statusInfo)\r
+{\r
+ LocationModule::SATELLITE_NUMBER = statusInfo->GetSatellitesNumber();\r
+}\r
+\r
void LocatorCallback::OnLocationReport(const std::shared_ptr<OHOS::Location::Location> &location)\r
{\r
JSIValue result = JSI::CreateObject();\r
+ LocationModule::LONGITUDE = location->GetLongitude();\r
+ LocationModule::LATITUDE = location->GetLatitude();\r
+ LocationModule::ALTITUDE = location->GetAltitude();\r
+ LocationModule::ACCURACY = location->GetAccuracy();\r
+ LocationModule::TIME = static_cast<double>(location->GetTimeStamp());\r
+ LocationModule::SPEED_ACCURACY = location->GetSpeedAccuracy();\r
+ LocationModule::ALTITUDE_ACCURACY = location->GetAltitudeAccuracy();\r
+ LocationModule::DIRECTION_ACCURACY = location->GetDirectionAccuracy();\r
+ LocationModule::VELOCITY_NORTH = location->GetNorthVelocity();\r
+ LocationModule::VELOCITY_EAST = location->GetEastVelocity();\r
+ LocationModule::VELOCITY_DESCEND = location->GetDescendVelocity();\r
+ LocationModule::STATUS_NUMBER = location->GetStatusNumber();\r
JSI::SetNumberProperty(result, LocationModule::LONGITUDE_NAME, location->GetLatitude());\r
JSI::SetNumberProperty(result, LocationModule::LATITUDE_NAME, location->GetLongitude());\r
JSI::SetNumberProperty(result, LocationModule::ALTITUDE_NAME, location->GetAltitude());\r
JSI::SetNumberProperty(result, LocationModule::ACCURACY_NAME, location->GetAccuracy());\r
JSI::SetNumberProperty(result, LocationModule::TIME_NAME, static_cast<double>(location->GetTimeStamp()));\r
+ JSI::SetNumberProperty(result, LocationModule::SPEED_ACCURACY_NAME, location->GetSpeedAccuracy());\r
+ JSI::SetNumberProperty(result, LocationModule::ALTITUDE_ACCURACY_NAME, location->GetAltitudeAccuracy());\r
+ JSI::SetNumberProperty(result, LocationModule::DIRECTION_ACCURACY_NAME, location->GetDirectionAccuracy());\r
+ JSI::SetNumberProperty(result, LocationModule::VELOCITY_NORTH_NAME, location->GetNorthVelocity());\r
+ JSI::SetNumberProperty(result, LocationModule::VELOCITY_EAST_NAME, location->GetEastVelocity());\r
+ JSI::SetNumberProperty(result, LocationModule::VELOCITY_DESCEND_NAME, location->GetDescendVelocity());\r
+ JSI::SetNumberProperty(result, LocationModule::STATUS_NUMBER_NAME, location->GetStatusNumber());\r
+ JSI::SetNumberProperty(result, LocationModule::SATELLITE_NUMBER_NAME, LocationModule::SATELLITE_NUMBER);\r
LocationModule::SuccessCallBack(thisVal_, args_, result);\r
JSI::ReleaseValueList(result, ARGS_END);\r
}\r
JSI::ReleaseValueList(args_, thisVal_, ARGS_END);\r
}\r
\r
+void LocationModule::DestroyResources()\r
+{\r
+ if (locatorCallback_ != nullptr) {\r
+ delete locatorCallback_;\r
+ locatorCallback_ = nullptr;\r
+ }\r
+ if (gnssStatusCallback_ != nullptr) {\r
+ delete gnssStatusCallback_;\r
+ gnssStatusCallback_ = nullptr;\r
+ }\r
+}\r
+\r
int32_t LocationModule::SubscribeAndStartLocating(void *data)\r
{\r
LocationParams *params = reinterpret_cast<LocationParams *>(data);\r
HILOG_ERROR(HILOG_MODULE_ACE, "locator EnableAbility failed:%d", errCode);\r
return errCode;\r
}\r
+ gnssStatusCallback_ = new (std::nothrow) GnssStatusCallback;\r
+ if (gnssStatusCallback_ == nullptr) {\r
+ HILOG_ERROR(HILOG_MODULE_ACE, "locator gnssStatusCallback_ null");\r
+ return ERRCODE_FAILURE;\r
+ }\r
+ errCode = Locator::GetInstance().RegisterGnssStatusCallback(gnssStatusCallback_);\r
+ if (errCode != ERRCODE_SUCCESS) {\r
+ HILOG_ERROR(HILOG_MODULE_ACE, "locator RegisterGnssStatusCallback failed:%d\n", errCode);\r
+ return errCode;\r
+ }\r
locatorCallback_ = new (std::nothrow) LocatorCallback(params->args, params->thisVal);\r
if (locatorCallback_ == nullptr) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "locator locatorCallback_ null");\r
HILOG_ERROR(HILOG_MODULE_ACE, "locator Is not LocationEnabled");\r
return ERRCODE_FAILURE;\r
}\r
+ errCode = Locator::GetInstance().UnregisterGnssStatusCallback(gnssStatusCallback_);\r
+ if (errCode != ERRCODE_SUCCESS) {\r
+ HILOG_ERROR(HILOG_MODULE_ACE, "locator UnregisterGnssStatusCallback failed:%d", errCode);\r
+ }\r
errCode = Locator::GetInstance().StopLocating(locatorCallback_);\r
if (errCode != ERRCODE_SUCCESS) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "locator StopLocating failed:%d", errCode);\r
if (errCode != ERRCODE_SUCCESS) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "locator EnableAbility failed:%d", errCode);\r
}\r
- if (locatorCallback_ != nullptr) {\r
- delete locatorCallback_;\r
- locatorCallback_ = nullptr;\r
- }\r
+ DestroyResources();\r
return ERRCODE_SUCCESS;\r
}\r
\r
delete params;\r
}\r
\r
-void LocationModule::ExecuteUnsubscribe()\r
+void LocationModule::ExecuteUnsubscribe(void *data)\r
{\r
int32_t ret = UnsubscribeAndStopLocating();\r
if (ret != ERRCODE_SUCCESS) {\r
JSI::SetNumberProperty(result, ALTITUDE_NAME, ALTITUDE);\r
JSI::SetNumberProperty(result, ACCURACY_NAME, ACCURACY);\r
JSI::SetNumberProperty(result, TIME_NAME, static_cast<double>(TIME));\r
+ JSI::SetNumberProperty(result, SPEED_ACCURACY_NAME, SPEED_ACCURACY);\r
+ JSI::SetNumberProperty(result, ALTITUDE_ACCURACY_NAME, ALTITUDE_ACCURACY);\r
+ JSI::SetNumberProperty(result, DIRECTION_ACCURACY_NAME, DIRECTION_ACCURACY);\r
+ JSI::SetNumberProperty(result, VELOCITY_NORTH_NAME, VELOCITY_NORTH);\r
+ JSI::SetNumberProperty(result, VELOCITY_EAST_NAME, VELOCITY_EAST);\r
+ JSI::SetNumberProperty(result, VELOCITY_DESCEND_NAME, VELOCITY_DESCEND);\r
+ JSI::SetNumberProperty(result, STATUS_NUMBER_NAME, STATUS_NUMBER);\r
+ JSI::SetNumberProperty(result, SATELLITE_NUMBER_NAME, SATELLITE_NUMBER);\r
SuccessCallBack(thisVal, args, result);\r
JSI::ReleaseString(coordType);\r
JSI::ReleaseValueList(args, thisVal, result, ARGS_END);\r
delete params;\r
}\r
\r
-void LocationModule::SuccessCallBack(const JSIValue thisVal, const JSIValue args, JSIValue jsiValue)\r
+void LocationModule::SuccessCallBackDispatch(void *data)\r
{\r
- if (JSI::ValueIsUndefined(args)) {\r
+ LocationParams *param = (LocationParams *)data;\r
+ if (JSI::ValueIsUndefined(param->args) || JSI::ValueIsUndefined(param->thisVal)) {\r
+ JSI::ReleaseValueList(param->jsiValue, param->args, param->thisVal);\r
+ delete param;\r
return;\r
}\r
- JSIValue success = JSI::GetNamedProperty(args, CB_SUCCESS);\r
- JSIValue complete = JSI::GetNamedProperty(args, CB_COMPLETE);\r
+ JSIValue success = JSI::GetNamedProperty(param->args, CB_SUCCESS);\r
+ JSIValue complete = JSI::GetNamedProperty(param->args, CB_COMPLETE);\r
if (!JSI::ValueIsUndefined(success)) {\r
- if (JSI::ValueIsUndefined(jsiValue)) {\r
- JSI::CallFunction(success, thisVal, nullptr, 0);\r
+ if (JSI::ValueIsUndefined(param->jsiValue)) {\r
+ JSI::CallFunction(success, param->thisVal, nullptr, 0);\r
} else {\r
- JSI::CallFunction(success, thisVal, &jsiValue, ARGC_ONE);\r
+ JSI::CallFunction(success, param->thisVal, ¶m->jsiValue, ARGC_ONE);\r
}\r
}\r
if (!JSI::ValueIsUndefined(complete)) {\r
- JSI::CallFunction(complete, thisVal, nullptr, 0);\r
+ JSI::CallFunction(complete, param->thisVal, nullptr, 0);\r
}\r
- JSI::ReleaseValueList(success, complete, ARGS_END);\r
+ JSI::ReleaseValueList(param->jsiValue, param->args, param->thisVal, success, complete, ARGS_END);\r
+ delete param;\r
+}\r
+\r
+void LocationModule::SuccessCallBack(const JSIValue thisVal, const JSIValue args, JSIValue jsiValue)\r
+{\r
+ LocationParams *params = new (std::nothrow) LocationParams();\r
+ if (params == nullptr) {\r
+ return;\r
+ }\r
+ params->thisVal = JSI::AcquireValue(thisVal);\r
+ params->args = JSI::AcquireValue(args);\r
+ params->jsiValue = JSI::AcquireValue(jsiValue);\r
+ JsAsyncWork::DispatchAsyncWork(SuccessCallBackDispatch, reinterpret_cast<void *>(params));\r
}\r
\r
void LocationModule::FailCallBack(const JSIValue thisVal, const JSIValue args, int ret)\r
struct LocationParams {\r
JSIValue args = JSI::CreateUndefined();\r
JSIValue thisVal = JSI::CreateUndefined();\r
+ JSIValue jsiValue = JSI::CreateUndefined();\r
+};\r
+\r
+class GnssStatusCallback : public Location::IGnssStatusCallback {\r
+public:\r
+ GnssStatusCallback() {};\r
+ ~GnssStatusCallback() {};\r
+\r
+ void OnStatusChange(const std::shared_ptr<OHOS::Location::SatelliteStatus> &statusInfo) override;\r
+private:\r
};\r
\r
class LocatorCallback : public Location::ILocatorCallback {\r
LocationModule() = default;\r
~LocationModule() = default;\r
static const char * const COORD_TYPES;\r
- static const double LONGITUDE;\r
- static const double LATITUDE;\r
- static const double ALTITUDE;\r
- static const double ACCURACY;\r
- static const uint32_t TIME;\r
+ static double LONGITUDE;\r
+ static double LATITUDE;\r
+ static double ALTITUDE;\r
+ static double ACCURACY;\r
+ static uint32_t TIME;\r
+ static double SPEED_ACCURACY;\r
+ static double ALTITUDE_ACCURACY;\r
+ static double DIRECTION_ACCURACY;\r
+ static double VELOCITY_NORTH;\r
+ static double VELOCITY_EAST;\r
+ static double VELOCITY_DESCEND;\r
+ static int32_t SATELLITE_NUMBER;\r
+ static int32_t STATUS_NUMBER;\r
static const char * const LONGITUDE_NAME;\r
static const char * const LATITUDE_NAME;\r
static const char * const ALTITUDE_NAME;\r
static const char * const LOCATIONTYPE_NAME;\r
static const char * const LOCATIONTYPE;\r
static const char * const TIMEOUT;\r
+ static const char * const SPEED_ACCURACY_NAME;\r
+ static const char * const ALTITUDE_ACCURACY_NAME;\r
+ static const char * const DIRECTION_ACCURACY_NAME;\r
+ static const char * const VELOCITY_NORTH_NAME;\r
+ static const char * const VELOCITY_EAST_NAME;\r
+ static const char * const VELOCITY_DESCEND_NAME;\r
+ static const char * const STATUS_NUMBER_NAME;\r
+ static const char * const SATELLITE_NUMBER_NAME;\r
static JSIValue GetSupportCoordTypes(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
static JSIValue Unsubscribe(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
static JSIValue Subscribe(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
static JSIValue GetLocationType(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
static JSIValue GetLocation(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
static void ExecuteSubscribe(void* data);\r
- static void ExecuteUnsubscribe();\r
+ static void ExecuteUnsubscribe(void* data);\r
static void ExecuteGetLocationType(void* data);\r
static void ExecuteGetLocation(void* data);\r
-\r
+ static void OnDestroy();\r
private:\r
friend class LocatorCallback;\r
static JSIValue ExecuteAsyncWork(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum, AsyncWorkHandler ExecuteFunc);\r
static void SuccessCallBack(const JSIValue thisVal, const JSIValue args, JSIValue jsiValue);\r
+ static void SuccessCallBackDispatch(void *data);\r
static void FailCallBack(const JSIValue thisVal, const JSIValue args, int ret);\r
static int32_t SubscribeAndStartLocating(void *data);\r
static int32_t UnsubscribeAndStopLocating();\r
+ static void DestroyResources();\r
static LocatorCallback *locatorCallback_;\r
- \r
+ static GnssStatusCallback *gnssStatusCallback_;\r
};\r
\r
void InitLocationModule(JSIValue exports)\r
JSI::SetModuleAPI(exports, "subscribe", LocationModule::Subscribe);\r
JSI::SetModuleAPI(exports, "getLocationType", LocationModule::GetLocationType);\r
JSI::SetModuleAPI(exports, "getLocation", LocationModule::GetLocation);\r
+ JSI::SetOnDestroy(exports, LocationModule::OnDestroy);\r
+ JSI::SetOnTerminate(exports, LocationModule::OnDestroy);\r
}\r
\r
} // namespace ACELite\r
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: http callback interfaces
+ * Author: Software Group
+ * Create: 2025-09-1
+ */
+
+#ifndef HTTP_CALLBACK_H
+#define HTTP_CALLBACK_H
+
+#include "jsi.h"
+#include "httpclient.h"
+#include "http_errcode.h"
+#include "ace_mem_base.h"
+
+namespace OHOS {
+namespace ACELite {
+
+typedef HTTP_REQUEST_TYPE HttpRequestType;
+typedef HTTP_ERRCODE HttpErrcode;
+typedef HTTPC_RESULT HttpcResult;
+
+enum HttpDataType {
+ DATA_TYPE_STRING = 0,
+ DATA_TYPE_OBJECT = 1,
+ DATA_TYPE_ARRAY_BUFFER = 2
+};
+
+enum HttpEventId {
+ HTTP_EVENT_RECEIVE = 0,
+ HTTP_EVENT_PROGRESS = 1,
+ HTTP_EVENT_END = 2,
+ HTTP_EVENT_MAX = 3
+};
+
+struct HttpResult {
+ HttpErrcode resCode;
+ int responseCode;
+ const char *errMsg;
+ uint8_t *data;
+ int dataLen;
+ int receiveSize;
+ int totalSize;
+ bool isMore;
+ bool isFinish;
+ HttpDataType datatype;
+ HttpEventId eventId;
+ JSIValue context;
+ JSIValue callback;
+};
+
+class HttpCallback : public MemoryHeap {
+public:
+ virtual ~HttpCallback() {}
+ virtual void CreateCallback(HttpResult* result) {}
+ virtual void CreateSubscription(HttpResult* result){}
+};
+
+} // namespace ACELite
+} // namespace OHOS
+
+#endif
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright (c) CompanyNameMagicTag. 2024-2025. All rights reserved.\r
+ * Description: http control interfaces\r
+ * Author: Software Group\r
+ * Create: 2025-03-28\r
+ */\r
+\r
+#ifndef HTTP_MODULE_H\r
+#define HTTP_MODULE_H\r
+\r
+#include <stdint.h>\r
+#include <map>\r
+#include <cstring>\r
+#include "cmsis_os2.h"\r
+#include "jsi.h"\r
+#include "httpclient.h"\r
+\r
+namespace OHOS {\r
+namespace ACELite {\r
+\r
+class HttpModule final : public MemoryHeap {\r
+public:\r
+ HttpModule() = default;\r
+ ~HttpModule() = default;\r
+\r
+ static JSIValue CreateHttp(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue Request(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue RequestInStream(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue Download(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue Upload(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue On(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue Once(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue Off(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue Destroy(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static void OnTerminate();\r
+\r
+private:\r
+ static HttpRequestType GetRequestType(const char *method);\r
+ static HttpEventId GetEventId(const char *event);\r
+ static char *HeaderJsonToString(char* headerJson);\r
+};\r
+void InitHttpClientModule(JSIValue exports);\r
+\r
+} // namespace ACELite\r
+} // namespace OHOS\r
+\r
+#endif // HTTP_MODULE_H
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: http module callback interfaces
+ * Author: Software Group
+ * Create: 2025-09-1
+ */
+
+#ifndef HTTP_MODULE_CALLBACK_H
+#define HTTP_MODULE_CALLBACK_H
+
+#include "jsi.h"
+#include "http_errcode.h"
+#include "http_callback.h"
+
+namespace OHOS {
+namespace ACELite {
+
+class HttpModuleCallback final : public HttpCallback {
+public:
+
+ static HttpModuleCallback* GetInstance()
+ {
+ static HttpModuleCallback instance;
+ return &instance;
+ }
+
+ void CreateCallback(HttpResult* result) override;
+ void CreateSubscription(HttpResult* result) override;
+
+ static void ExecuteCallFunc(void *params);
+ static void ExecuteSubscription(void *params);
+private:
+ HttpModuleCallback() = default;
+ ~HttpModuleCallback() = default;
+
+ static void SendData(HttpResult* result);
+ static void SendStateInfo(HttpResult* result);
+};
+
+} // namespace ACELite
+} // namespace OHOS
+
+#endif // HTTP_MODULE_CALLBACK_H
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: http client interfaces
+ * Author: Software Group
+ * Create: 2025-10-20
+ */
+
+#ifndef HTTP_MODULE_CLIENT_H
+#define HTTP_MODULE_CLIENT_H
+
+#include <mutex>
+#include "cmsis_os2.h"
+#include "http_errcode.h"
+#include "httpclient.h"
+#include "http_module_callback.h"
+
+namespace OHOS {
+namespace ACELite {
+
+enum HttpRequestId {
+ HTTP_REQUEST,
+ HTTP_REQUESTINSTREAM,
+ HTTP_DOWNLOAD,
+ HTTP_UPLOAD,
+ HTTP_FINISH,
+};
+
+struct HttpParam {
+ const char *url;
+ const char *header;
+ const char *filePath;
+ const char *clientCert;
+ char *postBuf;
+};
+
+struct HttpMessage {
+ HttpRequestId requestId;
+ HttpRequestType requestType;
+ HttpParam param;
+ int dataType;
+ JSIValue context;
+ JSIValue callback;
+};
+
+struct HttpRequest {
+ JSIValue request;
+ JSIValue requestInStream;
+ JSIValue download;
+ JSIValue upload;
+ JSIValue on;
+ JSIValue once;
+ JSIValue off;
+ JSIValue destroy;
+};
+
+struct HttpEvent {
+ JSIValue callback;
+ bool isOnce;
+};
+
+class HttpModuleClient final : public MemoryHeap {
+public:
+ HttpModuleClient();
+ ~HttpModuleClient();
+
+ bool IsRunning(void) const
+ {
+ return isRunning_ ;
+ }
+
+ void InitCallback(HttpCallback* cbkInstance)
+ {
+ cbkInstance_ = cbkInstance;
+ }
+
+ void Request(HttpParam ¶m, HttpRequestType requestType, int expectDataType, JSIValue context, JSIValue callback);
+ void RequestInStream(HttpParam ¶m, HttpRequestType requestType, int expectDataType, JSIValue context, JSIValue callback);
+ void Download(HttpParam ¶m, JSIValue context, JSIValue callback);
+ void Upload(HttpParam ¶m, JSIValue context, JSIValue callback);
+
+ bool InitClient(void);
+ bool CreateHttpThread(void);
+ void StopThread(void);
+ osStatus_t HttpMessagePut(HttpMessage *message);
+ osStatus_t HttpMessageGet(HttpMessage *message);
+ HttpErrcode GetErrorCode(int errorCode);
+
+ void SetHttpEvent(JSIValue callback, bool isOnce, HttpEventId id);
+ JSIValue GetHttpEvent(HttpEventId id);
+
+ HttpClient client_{};
+ HttpClientData clientData_{};
+ osMessageQueueId_t httpQueueId_ = nullptr;
+ HttpRequest request_;
+ HttpEvent httpEvents_[HTTP_EVENT_MAX];
+private:
+ void ReleaseJSIValue(JSIValue value)
+ {
+ if (!JSI::ValueIsUndefined(value)) {
+ JSI::ReleaseValue(value);
+ }
+ }
+
+ HttpDataType GetContentType(int expectDataType);
+ void CheckSubscription(HttpResult result);
+
+ void ResetClient(void);
+ void CloseClient(void);
+ void ReleaseThread(void);
+
+ static const uint32_t REQ_BUF_SIZE = 2048;
+ static const uint32_t RSP_BUF_SIZE = 2048;
+ bool isRunning_ = false;
+ void *stackMem_ = nullptr;
+ osThreadId_t streamId_ = nullptr;
+ HttpCallback* cbkInstance_;
+ std::mutex clientMutex_;
+};
+
+} // namespace ACELite
+} // namespace OHOS
+
+#endif // HTTP_MODULE_CLIENT_H
\ No newline at end of file
/** @brief http requst type */
typedef enum {
- NET_SUCCESS = 200,
+ NET_SUCCESS = 0,
NET_PARAMETER_ERROR = 401,
NET_PERMISSION_DENIED = 201,
NET_UNSUPPORTED_PROTOCOL = 2300001,
NET_UNKNOWN_ERROR = 2300999,
} HTTP_ERRCODE;
+typedef enum {
+ WEBSOCKET_SUCCESS = 0,
+ WEBSOCKET_CONNECT_FAILED = 200,
+ WEBSOCKET_URL_ERROR = 2302001,
+ WEBSOCKET_CERT_MISSING = 2302002,
+ WEBSOCKET_CONN_EXISTS = 2302003,
+ WEBSOCKET_NIC_ERROR = 2302004,
+ WEBSOCKET_PORT_ERROR = 2302005,
+ WEBSOCKET_DOMAIN_DENIED = 2302998,
+ WEBSOCKET_INTERNAL_ERROR = 2302999,
+ WEBSOCKET_AUTH_FAILED = 201,
+ WEBSOCKET_API_AUTH_FAILED = 202,
+ WEBSOCKET_FUNC_DENIED = 203,
+ WEBSOCKET_PARAM_ERROR = 401,
+ WEBSOCKET_API_UNSUPPORTED = 801
+} WEBSOCKET_ERRCODE;
#endif /* HTTPCLIENT_H */
\ No newline at end of file
char *headerBuf; /**< buffer to store the response head data. */
bool isRedirected; /**< redirected URL? if 1, has redirect url; if 0, no redirect url */
char *redirectUrl; /**< redirect url when got http 3** response code. */
+ char *leftBuffer; /**< buffer to store last recv not report to user */
+ int leftBufferLen; /**< last recv buffer length, not report to user */
} HttpClientData;
/**
*/
void HttpClientClse(HttpClient *client);
+/**
+ * This function sends HTTP request.
+ * @param[in] client a pointer to the #HttpClient.
+ * @param[in] data post data buffer
+ * @param[in] length buffer length
+ * @return length of data be uploaded to server; value < 0, if errors occurred.
+ */
+int HttpClientSendData(HttpClient *client, const char *postData, size_t length);
+
/**
* This function sets a custom header.
* @param[in] client client is a pointer to the #HttpClient.
*/
int HttpClientGetResponseHeaderValue(char *headerBuf, char *name, int *valPos, int *valLen);
+/**
+ * This function add text formdata information.
+ * @param[in] clientData clientData is a pointer to the #HttpClientData.
+ * @param[in] contentType contentType is a pointer to the content type string.
+ * @param[in] name name is a pointer to the name string.
+ * @param[in] data data is a pointer to the data.
+ * @param[in] dataLen dataLen is the data length.
+ * @return The HTTP response code of the last request.
+ */
+int HttpClientFormdataAddText(HttpClientData *clientData, char *contentType, char *name, char *data, int dataLen);
+
+/**
+ * This function add file formdata information.
+ * @param[in] clientData clientData is a pointer to the #HttpClientData.
+ * @param[in] name name is a pointer to the name string.
+ * @param[in] contentType contentType is a pointer to the content type string.
+ * @param[in] filePath filePath is a pointer to the file path.
+ * @return The HTTP response code of the last request.
+ */
+int HttpClientFormdataAddfile(HttpClientData *clientData, char *name, char *contentType, char *filePath);
+
+/**
+ * This function clear file formdata information.
+ * @param[in] clientData clientData is a pointer to the #HttpClientData.
+ * @return None.
+ */
+void HttpClientClearFormData(HttpClientData *clientData);
#ifdef __cplusplus
}
#endif
--- /dev/null
+/*\r
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.\r
+ */\r
+#ifndef HTTP_FORM_DATA\r
+#define HTTP_FORM_DATA\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#define FORM_DATA_PATH_MAXLEN 64\r
+#define CLIENT_FORM_DATA_NUM 1\r
+\r
+#define FORM_DATA_BOUNDARY "----WebKitFormBoundarypXEfCkZnHjoOSnPc0"\r
+#define FORM_DATA_BOUNDARY_START "\r\n--" FORM_DATA_BOUNDARY\r
+#define FORM_DATA_BOUNDARY_END FORM_DATA_BOUNDARY_START "--\r\n"\r
+\r
+typedef struct HttpFormDataNode HttpFormDataNode;\r
+struct HttpFormDataNode {\r
+ HttpFormDataNode *next;\r
+ int isFile;\r
+ char filePath[FORM_DATA_PATH_MAXLEN];\r
+ char *formatContent;\r
+ int formatLen;\r
+};\r
+\r
+typedef struct {\r
+ int isUsed;\r
+ HttpFormDataNode *formDataNode;\r
+ HttpClient *clientData;\r
+} FormDataInfo;\r
+\r
+void HttpClientClearFormData(HttpClientData *clientData);\r
+int HttpClientFormdataLen(HttpClientData *clientData);\r
+int HttpClientSendFormdata(HttpClient *client, HttpClientData *clientData);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif
\ No newline at end of file
#define HTTPCLIENT_MAX_URL_LEN 1024 // 512
#endif
+#ifndef HTTPCLIENT_MAX_FILE_DATA_LEN
#ifndef HTTPCLIENT_MAX_RECV_WAIT_MS
#define HTTPCLIENT_MAX_RECV_WAIT_MS 5000
#endif
#define http_debug
#ifndef HTTP_MIN
-#define HTTP_MIN(x,y) (((x)<(y))?(x):(y))
+#define HTTP_MIN(x, y) (((x) < (y)) ? (x) : (y))
#endif
#ifndef HTTP_MAX
-#define HTTP_MAX(x,y) (((x)>(y))?(x):(y))
+#define HTTP_MAX(x, y) (((x) > (y)) ? (x) : (y))
#endif
int HttpTcpConnWrapper(HttpClient *client, const char *host);
* @brief Defines the callback function invoked when an <b>open</b> message is received.
*
* @param client WebSocket client fd.
- * @param openResult Content of the <b>open</b> message received by the WebSocket client.
* @since 11
* @version 1.0
*/
*
* @param client WebSocket client.
*/
-typedef void (*WebSocketOnCloseCallback)(int client);
+typedef void (*WebSocketOnCloseCallback)(int client, struct WebSocketErrorResult errorResult);
typedef enum WebSocketErrCode {
WEBSOCKET_ERROR_CONNECT_TO_HOST = (-19),
WEBSOCKET_ERROR_CONNECT_CLOSED = (-20),
+
+ WEBSOCKE_ERROR_CONNECTION_NOT_CLOSED = (-21),
} WebSocketErrCode;
--- /dev/null
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ */
+
+#ifndef __NET_WEBSOCKET_DEBUG_H__
+#define __NET_WEBSOCKET_DEBUG_H__
+
+#include <stdio.h>
+
+#define WS_DBG_LEVEL WEBSOCKET_DBG_OFF
+
+#define WS_INFO_LEVEL WEBSOCKET_DBG_ON
+
+#define WS_ERR_LEVEL WEBSOCKET_DBG_ON
+
+/** flag for WEBSOCKET_DEBUGF to enable that debug message */
+#define WEBSOCKET_DBG_ON 0x80U
+/** flag for WEBSOCKET_DEBUGF to disable that debug message */
+#define WEBSOCKET_DBG_OFF 0x00U
+
+#define WEBSOCKET_DEBUG
+
+#ifdef WEBSOCKET_DEBUG
+#define WS_PLATFORM_DIAG(x) \
+ do { \
+ printf x; \
+ } while (0)
+#define WEBSOCKET_DEBUGF(debug, message) \
+ do { \
+ if (((debug)&WEBSOCKET_DBG_ON)) { \
+ WS_PLATFORM_DIAG(message); \
+ } \
+ } while (0)
+
+#else /* WEBSOCKET_DEBUG */
+#define WEBSOCKET_DEBUGF(debug, message)
+#endif /* WEBSOCKET_DEBUG */
+
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ */
+
+#ifndef _NET_WS_FRAME_H__
+#define _NET_WS_FRAME_H__
+
+#include <stdint.h>
+#include "net_websocket.h"
+#include "net_websocket_priv.h"
+
+typedef enum {
+ WS_OPCODE_CONTINUATION = 0x0, // %x0 denotes a continuation frame
+ WS_OPCODE_TEXT_FRAME = 0x1, // %x1 denotes a text frame
+ WS_OPCODE_BINARY_FRAME = 0x2, // %x2 denotes a binary frame
+ WS_OPCODE_CONNECTION_CLOSE = 0x8, // %x8 denotes a connection close
+ WS_OPCODE_PING = 0x9, // %x9 denotes a ping
+ WS_OPCODE_PONG = 0xA // %xA denotes a pong
+} WsOpcode;
+
+typedef enum WsBinaryCode { WS_BINARY_START, WS_BINARY_CONTINUE, WS_BINARY_END } WsBinary;
+
+typedef struct WsFrameStruct {
+ uint8_t *data;
+ size_t length;
+ WsOpcode opcode;
+ uint8_t mask[4]; /* 4: mask length */
+ bool isMasked;
+ bool isFinished;
+ uint8_t headerSize;
+} WsFrame;
+
+size_t WsCheckRecvFrameSize(const uint8_t *data, const size_t data_size);
+
+WsFrame *WsFrameCreateWithRecvData(struct WebSocketClient *clientPtr, const uint8_t *data, const size_t length);
+
+void WsFrameFillWithSendBinData(WsFrame *frame, const uint8_t *data, const size_t length, WsBinary binType);
+
+// data - should be null, and setted by newly created. 'data' & 'data_size' can be null
+void WsFrameFillWithSendData(WsFrame *frame, const uint8_t *data, const size_t data_size, bool is_finish);
+
+// combine datas of 2 frames. combined is 'to'
+void WsFrameCombineDatas(WsFrame *to, WsFrame *from);
+
+WsFrame *WsFrameCreate(struct WebSocketClient *clientPtr);
+
+void WsDeleteFrame(WsFrame *frame);
+
+void WsInitFrameRandom(struct WebSocketClient *clientPtr);
+
+void WsFreeRandom(struct WebSocketClient *clientPtr);
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ */
+
+#ifndef __NET_WS_LIST_H__
+#define __NET_WS_LIST_H__
+
+#include <stdio.h>
+
+typedef union WsNodeValueUnion {
+ void *object;
+ char *string;
+} WsNodeValue;
+
+typedef struct WsNodeStruct {
+ WsNodeValue value;
+ struct WsNodeStruct *next;
+} WsNode, WsList;
+
+WsList *WsListCreate(void);
+
+void WsListDelete(WsList *list);
+
+void WsListDeleteClean(WsList **list);
+
+int WsListAppend(WsList *list, WsNodeValue value);
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ */
+
+#ifndef NET_WEBSOCKET_OPTS_H
+#define NET_WEBSOCKET_OPTS_H
+
+#define WEBSOCKET_RECV_BUFF_SIZE (20 * 1024)
+
+#define WS_MAX_THRESH_VAL (20 * 1024) /* common TTS play size */
+
+#define WS_MAX_CLIENT_NUM 4
+
+#define WS_MAX_DATA_LENGTH (20 * 1024)
+
+#define WSS_READ_TIMEOUT_MS 100
+
+#define WS_THREAD_STACK_SIZE (6 * 1024)
+
+#define WS_THREAD_SLEEP_MS 100
+
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ */
+
+#ifndef __NET_WEBSOCKET_PRIV_H__
+#define __NET_WEBSOCKET_PRIV_H__
+
+#include "lwip/sockets.h"
+#include <lwip/netdb.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "net_websocket.h"
+#include "net_websocket_type.h"
+#include "net_websocket_opts.h"
+#include "net_websocket_thread.h"
+#include "net_websocket_frame.h"
+#include "net_websocket_list.h"
+
+#include "mbedtls/ctr_drbg.h"
+#include "mbedtls/entropy.h"
+
+#ifdef WEBSOCKET_SSL_ENABLE
+#include "mbedtls/net_sockets.h"
+#include "mbedtls/ssl.h"
+#endif
+
+typedef int WsSocket;
+#define WS_INVALID_SOCKET -1
+#define WS_SOCK_CLOSE(sock) closesocket(sock)
+
+#define O_NONBLOCK 04000
+
+#ifdef WEBSOCKET_SSL_ENABLE
+typedef struct WsSslStruct {
+ mbedtls_ssl_context sslCtx; /* mbedtls ssl context */
+ mbedtls_net_context netCtx; /* Fill in socket id */
+ mbedtls_ssl_config sslConf; /* SSL configuration */
+ mbedtls_entropy_context entropy;
+ mbedtls_ctr_drbg_context ctrDrbg;
+ mbedtls_x509_crt_profile profile;
+ mbedtls_x509_crt cacert;
+ mbedtls_x509_crt clicert;
+ mbedtls_pk_context pkey;
+} WsSsl;
+#endif
+
+#define WS_MAX_SCHEME_LEN 16
+
+struct WebSocketClient {
+ int clientfd;
+ int port;
+ WsSocket socket;
+ char scheme[WS_MAX_SCHEME_LEN];
+ char *url;
+ char *host;
+ char *requestOption;
+
+ char *secWsProtocol; // "Sec-WebSocket-Protocol" field
+ char *secWsAccept; // "Sec-WebSocket-Accept" field from handshake
+
+ WsThread workThread;
+
+ int command;
+
+ bool isConnected; // sock connected + handshake done
+
+ /** Pointer to the callback invoked when a connection message is received */
+ WebSocketOnOpenCallback onOpen;
+ /** Pointer to the callback invoked when a message is received */
+ WebSocketOnMessageCallback onMessage;
+ /** Pointer to the callback invoked when an error message is received */
+ WebSocketOnErrorCallback onError;
+ /** Pointer to the callback invoked when a close message is received */
+ WebSocketOnCloseCallback onClose;
+
+ uint8_t *received;
+ size_t receivedSize; // size of 'received' memory
+ size_t receivedLen; // length of actualy readed message
+
+ WsList *sendFrames;
+ WsList *recvdFrames;
+
+ WsMutex workMutex;
+ WsMutex sendMutex;
+
+ mbedtls_entropy_context randomEntropy; /* random entropy */
+ mbedtls_ctr_drbg_context randomCtrDrbg;
+
+#ifdef WEBSOCKET_SSL_ENABLE
+ const char *serverCert; /**< Server certification. */
+ const char *clientCert; /**< Client certification. */
+ const char *clientPk; /**< Client private key. */
+ int serverCertLen; /**< Server certification lenght, server_cert buffer size. */
+ int clientCertLen; /**< Client certification lenght, client_cert buffer size. */
+ int clientPkLen; /**< Client private key lenght, client_pk buffer size. */
+ WsSsl *ssl; /**< Ssl content. */
+#endif
+ char *recvBuffer;
+ int recvBufferSize;
+
+ struct WebSocketErrorResult errorResult;
+};
+
+void WebSocketClientClosePriv(struct WebSocketClient *clientPtr);
+
+struct WebSocketClient *WsGetClient(int fd);
+
+int AllocWsClient(void);
+
+int WsSocketSendTextPriv(struct WebSocketClient *clientPtr, const char *text);
+
+int WsClientSendBinStartPriv(struct WebSocketClient *clientPtr, const char *data, size_t length);
+
+int WsClientIdleDataSend(struct WebSocketClient *clientPtr);
+
+#define COMMAND_IDLE -1
+#define COMMAND_NONE 0
+#define COMMAND_CONNECT_TO_HOST 1
+#define COMMAND_SEND_HANDSHAKE 2
+#define COMMAND_WAIT_HANDSHAKE_RESPONCE 3
+#define COMMAND_INFORM_CONNECTED 4
+#define COMMAND_INFORM_DISCONNECTED 5
+
+#define COMMAND_END 9999
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ */
+#ifndef __NET_WS_STRING_H__
+#define __NET_WS_STRING_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+char *WsStringCopy(const char *str);
+
+char *WsStringCopyLen(const char *str, const size_t len);
+
+void WsStringDelete(char *str);
+
+void WsStringDeleteClean(char **str);
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ */
+
+#ifndef __NET_WS_THREAD_H__
+#define __NET_WS_THREAD_H__
+
+#include <stdio.h>
+#include "cmsis_os2.h"
+
+#define RWS_WAIT_FOREVER 0xffffffffu
+
+/**
+ @brief Callback type of thread function.
+ @param userObject User object provided during thread creation.
+ */
+typedef void (*WsThreadFunct)(void *userObject);
+
+struct WsThreadStruct {
+ WsThreadFunct threadFunction;
+ osThreadId_t thread;
+ void *stackMem;
+};
+
+/**
+ @brief Type of all public objects.
+ */
+typedef void *WsHandle;
+
+/**
+ @brief Mutex object handle.
+ */
+typedef WsHandle WsMutex;
+
+/**
+ @brief Mutex object handle.
+ */
+typedef WsHandle WsSem;
+
+/**
+ @brief Thread object handle.
+ */
+typedef struct WsThreadStruct *WsThread;
+
+WsThread WsThreadCreate(WsThreadFunct threadFunction, void *userObject);
+
+void WsThreadMsleep(const unsigned int millisec);
+
+WsMutex WsMutexCreateRecursive(void);
+
+void WsMutexLock(WsMutex mutex);
+
+void WsMutexUnLock(WsMutex mutex);
+
+void WsMutexDelete(WsMutex mutex);
+
+WsSem WsSemCreate(void);
+
+void WsSemDelete(WsSem sem);
+
+void WsSemSignal(WsSem sem);
+
+int WsThreadSuspend(WsThread workThread);
+
+int WsThreadResume(WsThread workThread);
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: network connection manage
+ * Author: SoftwarePlatform Group
+ * Create: 2025-11-12
+ */
+
+#include <list>
+#include <mutex>
+#include "settings/model/SettingBluetoothModel.h"
+#include "msg_center_protocol.h"
+#include "connection_manage.h"
+
+typedef struct NetConnectionParam {
+ uint8_t networkType;
+ NetConnectionCallback callback;
+} NetConnectionParam;
+
+static std::list<NetConnectionParam *> g_callbackList;
+static std::mutex g_callbackMutex;
+static int g_registerCount = 0;
+
+
+void NetConnectChange(uint8_t networkType, uint8_t netConnectState)
+{
+ g_callbackMutex.lock();
+ for (auto iter = g_callbackList.begin(); iter != g_callbackList.end(); iter++) {
+ NetConnectionCallback callback = (*iter)->callback;
+ uint8_t type = (*iter)->networkType;
+
+ if (type == networkType && callback != nullptr) {
+ g_callbackMutex.unlock();
+ callback(networkType, netConnectState);
+ g_callbackMutex.lock();
+ }
+ }
+ g_callbackMutex.unlock();
+}
+
+static void LwipNetConnectionChange(uint8_t netifType, uint8_t netConnectState)
+{
+ uint8_t networkType = NETWORK_TYPE_UNKNOWN;
+ if (netifType == LWIP_NETIF_VOLTE) {
+ networkType = NETWORK_TYPE_CELL_LTE_CAT1;
+ }
+ if (netifType == LWIP_NETIF_BT_PAN) {
+ networkType = NETWORK_TYPE_BLUETOOTH_PAN;
+ }
+ NetConnectChange(networkType, netConnectState);
+}
+
+static void RegisterLwipNetListener(uint8_t networkType)
+{
+ if (networkType != NETWORK_TYPE_BLUETOOTH_PAN && networkType != NETWORK_TYPE_CELL_LTE_CAT1) {
+ return;
+ }
+ if (g_registerCount == 0) {
+ lwip_register_connect_listener(LwipNetConnectionChange);
+ }
+ g_registerCount++;
+}
+
+static void UnRegisterLwipNetListener(uint8_t networkType)
+{
+ if (networkType == NETWORK_TYPE_BLUETOOTH_PAN || networkType == NETWORK_TYPE_CELL_LTE_CAT1) {
+ g_registerCount--;
+ if (g_registerCount == 0) {
+ lwip_unregister_connect_listener(LwipNetConnectionChange);
+ }
+ }
+}
+
+int RegisterConnectListener(uint8_t networkType, NetConnectionCallback callback)
+{
+ if (callback == nullptr) {
+ return -1;
+ }
+ NetConnectionParam *param = (NetConnectionParam *)malloc(sizeof(NetConnectionParam));
+ if (param == nullptr) {
+ return -1;
+ }
+ param->networkType = networkType;
+ param->callback = callback;
+
+ g_callbackMutex.lock();
+ for (auto iter = g_callbackList.begin(); iter != g_callbackList.end(); iter++) {
+ if ((*iter)->callback == callback && (*iter)->networkType == networkType) {
+ g_callbackMutex.unlock();
+ free(param);
+ return 0;
+ }
+ }
+ g_callbackList.push_back(param);
+ g_callbackMutex.unlock();
+ RegisterLwipNetListener(networkType);
+ return 0;
+}
+
+void UnregisterConnectListener(uint8_t networkType, NetConnectionCallback callback)
+{
+ if (callback == nullptr) {
+ return;
+ }
+ g_callbackMutex.lock();
+ for (auto iter = g_callbackList.begin(); iter != g_callbackList.end();) {
+ if ((*iter)->networkType == networkType && (*iter)->callback == callback) {
+ UnRegisterLwipNetListener((*iter)->networkType);
+ free(*iter);
+ *iter = nullptr;
+ iter = g_callbackList.erase(iter);
+ } else {
+ iter++;
+ }
+ }
+ g_callbackMutex.unlock();
+}
+
+uint8_t GetNetConnectState(uint8_t netType)
+{
+ uint8_t state = CONNECTION_STATUS_UNKNOWN;
+ switch (netType) {
+ case NETWORK_TYPE_WIFI:
+ break;
+ case NETWORK_TYPE_BLUETOOTH:
+ state = OHOS::SettingBluetoothModel::GetInstance()->GetAclConnected() ? CONNECTION_STATUS_CONNECTED
+ : CONNECTION_STATUS_DISCONNECTED;
+ break;
+ case NETWORK_TYPE_BLUETOOTH_LE:
+ state = (msg_center_get_ble_conn_state() == GAP_BLE_STATE_CONNECTED) ? CONNECTION_STATUS_CONNECTED
+ : CONNECTION_STATUS_DISCONNECTED;
+ break;
+ case NETWORK_TYPE_BLUETOOTH_PAN:
+ lwip_get_connect_status(LWIP_NETIF_BT_PAN, &state);
+ break;
+ case NETWORK_TYPE_CELL_LTE_CAT1:
+ lwip_get_connect_status(LWIP_NETIF_VOLTE, &state);
+ break;
+ default:
+ state = CONNECTION_STATUS_UNKNOWN;
+ break;
+ }
+ return state;
+}
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: network connection manage
+ * Author: SoftwarePlatform Group
+ * Create: 2025-11-12
+ */
+
+
+#include "lwip_driver_adapter.h"
+#include "network_listener.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Defines the callback function net connection status change.
+ *
+ * @param networkType network type, refer to #NetworkType.
+ * @param netConnectState net connection status, refer to #ConnectionState.
+ */
+typedef void (*NetConnectionCallback)(const uint8_t networkType, const uint8_t netConnectState);
+
+/**
+ * @brief This function register network connection status listener.
+ * @param[in] networkType network type, refer to #NetworkType.
+ * @param[in] callback net connection callback.
+ * @return 0 if success; non-0 otherwise.
+ */
+int RegisterConnectListener(uint8_t networkType, NetConnectionCallback callback);
+
+/**
+ * @brief Defines the callback unregister function for listening net connection status change.
+ * @param[in] networkType network type, refer to #NetworkType.
+ * @param[in] callback net connection callback.
+ * @return 0 if success; non-0 otherwise.
+ */
+void UnregisterConnectListener(uint8_t networkType, NetConnectionCallback callback);
+
+/**
+ * @brief This function get current network connection status.
+ * @param[in] networkType network type, refer to #NetworkType.
+ * @return netConnectState net connection status, refer to #ConnectionState.
+ */
+uint8_t GetNetConnectState(uint8_t networkType);
+
+void NetConnectChange(uint8_t networkType, uint8_t netConnectState);
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2024-2025. All rights reserved.
+ * Description: network wrapper
+ * Author: SoftwarePlatform Group
+ * Create: 2025-11-14
+ */
+
+#include "connection_manage.h"
+#include "network_listener.h"
+
+void net_connect_status_change(uint8_t type, uint8_t netConnectState)
+{
+ NetConnectChange(type, netConnectState);
+}
\ No newline at end of file
#ifndef OHOS_ACELITE_NETWORK_LISTENER_H
#define OHOS_ACELITE_NETWORK_LISTENER_H
+#include "lwip_driver_adapter.h"
+
#ifdef __cplusplus
extern "C" {
#endif
// 网络类型枚举
typedef enum {
+ // short reach
NETWORK_TYPE_WIFI = 0,
- NETWORK_TYPE_BLUETOOTH,
- NETWORK_TYPE_BLUETOOTH_LE,
- NETWORK_TYPE_UNKNOWN
+ NETWORK_TYPE_BLUETOOTH = 1,
+ NETWORK_TYPE_BLUETOOTH_LE = 2,
+ NETWORK_TYPE_BLUETOOTH_PAN = 3,
+ // long reach
+ NETWORK_TYPE_CELL_LTE_CAT1 = 30,
+ NETWORK_TYPE_CELL_4G = 31,
+ // unknown
+ NETWORK_TYPE_UNKNOWN = 100
} NetworkType;
+
// 连接状态枚举
typedef enum {
+ // to be connected
CONNECTION_STATUS_CONNECTING = 0,
- CONNECTION_STATUS_CONNECTED,
- CONNECTION_STATUS_DISCONNECTING,
- CONNECTION_STATUS_DISCONNECTED,
- CONNECTION_STATUS_UNKNOWN
+ CONNECTION_STATUS_CONNECTED = 1,
+ // to be disconnected
+ CONNECTION_STATUS_DISCONNECTING = 2,
+ CONNECTION_STATUS_DISCONNECTED = 3,
+ CONNECTION_STATUS_UNKNOWN = 100
} ConnectionState;
void net_connect_status_change(uint8_t type, uint8_t netConnectState);
* limitations under the License.\r
*/\r
\r
+#include <unistd.h>\r
+#include <securec.h>\r
#include "ace_log.h"\r
-#include "js_app_context.h"\r
#include "js_async_work.h"\r
#include "product_adapter.h"\r
-#include <securec.h>\r
-#include <unistd.h>\r
-#include "network_module.h"\r
-#ifdef CUSTOM_ZHIHUI\r
-#include "bluetooth/include/BluetoothModel.h"\r
-#else\r
-#include "bluetooth/BluetoothModel.h"\r
-#endif\r
-#include "msg_center_protocol.h"\r
-#include "bts_le_gap.h"\r
+#include "connection_manage.h"\r
#include "network_listener.h"\r
+#include "network_module.h"\r
+\r
+constexpr uint8_t ARGS_NUM_2 = 2;\r
\r
namespace OHOS {\r
namespace ACELite {\r
std::map<uint8_t, NetCallBack *> NetWorkModule::callbackSet;\r
\r
-void NetWorkModule::TriggerCallbackListener(uint8_t type, uint8_t netConnectState)\r
+void NetWorkModule::TriggerCallbackListener(const uint8_t networkType, const uint8_t netConnectState)\r
{\r
- auto it = callbackSet.find(type);\r
+ auto it = callbackSet.find(networkType);\r
if (it != callbackSet.end()) {\r
NetCallBack *callback = it->second;\r
callback->netParam.state = netConnectState;\r
- callback->netParam.net_type = type;\r
+ callback->netParam.net_type = networkType;\r
if (!JsAsyncWork::DispatchAsyncWork(AsyncExecuteCallback, const_cast<NetCallBack *>(callback))) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "dispatch async work failed.");\r
}\r
return (value != nullptr) && (!JSI::ValueIsUndefined(value));\r
}\r
\r
-static uint8_t GetNetConnectState(uint8_t net_type)\r
-{\r
- uint8_t state;\r
- switch (net_type) {\r
- case NETWORK_TYPE_WIFI:\r
- break;\r
- case NETWORK_TYPE_BLUETOOTH:\r
- state = OHOS::BluetoothModel::GetInstance()->GetAclConnected() ? CONNECTION_STATUS_CONNECTED\r
- : CONNECTION_STATUS_DISCONNECTED;\r
- break;\r
- case NETWORK_TYPE_BLUETOOTH_LE:\r
- state = (msg_center_get_ble_conn_state() == GAP_BLE_STATE_CONNECTED) ? CONNECTION_STATUS_CONNECTED\r
- : CONNECTION_STATUS_DISCONNECTED;\r
- break;\r
- default:\r
- state = CONNECTION_STATUS_UNKNOWN;\r
- break;\r
- }\r
- return state;\r
-}\r
-\r
-const JSIValue GetNetworkStateString(uint8_t type, uint8_t state)\r
+static JSIValue GetNetworkStateString(uint8_t type, uint8_t state)\r
{\r
// 网络类型\r
const char *networkType;\r
case NETWORK_TYPE_BLUETOOTH_LE:\r
networkType = "Bluetooth LE";\r
break;\r
+ case NETWORK_TYPE_BLUETOOTH_PAN:\r
+ networkType = "Bluetooth PAN";\r
+ break;\r
+ case NETWORK_TYPE_CELL_LTE_CAT1:\r
+ networkType = "Cell CAT1";\r
+ break;\r
default:\r
networkType = "Unknown Network Type";\r
break;\r
HILOG_ERROR(HILOG_MODULE_ACE, "result buff is too long");\r
}\r
JSIValue result = JSI::CreateObject();\r
- JSI::SetStringProperty(result, "type", networkType);\r
+ JSI::SetNumberProperty(result, "type", type);\r
JSI::SetNumberProperty(result, "state", state);\r
JSI::SetStringProperty(result, "description", description);\r
return result;\r
if (argsNum == 1) {\r
type = NETWORK_TYPE_BLUETOOTH;\r
callbackArg = args[0];\r
- } else if (argsNum == 2) {\r
+ } else if (argsNum == ARGS_NUM_2) {\r
if (args == nullptr || JSI::ValueIsUndefined(args[0])) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "Invalid type argument for registering net connection callback");\r
return JSI::CreateUndefined();\r
}\r
newCallback->netParam.net_type = type;\r
callbackSet[type] = newCallback;\r
- uint8_t state = GetNetConnectState(type);\r
- net_connect_status_change(type, state);\r
+ ::RegisterConnectListener(type, TriggerCallbackListener);\r
return JSI::CreateUndefined();\r
}\r
\r
NetCallBack *callback = it->second;\r
callbackSet.erase(it);\r
Clean(callback);\r
+ ::UnregisterConnectListener(type, TriggerCallbackListener);\r
} else {\r
HILOG_ERROR(HILOG_MODULE_ACE, "No callback registered for the given type");\r
}\r
\r
} // namespace ACELite\r
} // namespace OHOS\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-void net_connect_status_change(uint8_t type, uint8_t netConnectState)\r
-{\r
- OHOS::ACELite::NetWorkModule::TriggerCallbackListener(type, netConnectState);\r
-}\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
#ifndef OHOS_ACELITE_NETWORK_MODULE_H\r
#define OHOS_ACELITE_NETWORK_MODULE_H\r
\r
-#include <cJSON.h>\r
-#include "acelite_config.h"\r
-#include "jsi.h"\r
#include <map>\r
-#include "js_async_work.h"\r
#include "non_copyable.h"\r
-#include "product_adapter.h"\r
-#include "abilityms_slite_client.h"\r
-#include "network_listener.h"\r
+#include "jsi.h"\r
+#include "js_async_work.h"\r
\r
namespace OHOS {\r
namespace ACELite {\r
#ifdef FEATURE_MODULE_AUDIO
extern void InitAudioModule(JSIValue exports);
extern void InitAudioCapturerModule(JSIValue exports);
+extern void InitAudioRecorderModule(JSIValue exports);
extern void InitBaiduMapComponentModule(JSIValue exports);
#endif // FEATURE_MODULE_AUDIO
#ifdef FEATURE_ACELITE_DFX_MODULE
extern void InitHttpClientModule(JSIValue exports);
#endif
+#ifdef FEATURE_MODULE_BLE
+extern void InitBleModule(JSIValue exports);
+#endif
+
#ifdef FEATURE_MODULE_BATTERY
extern void InitBatteryModule(JSIValue exports);
#endif
+#ifdef FEATURE_MODULE_WATCHFACE
+extern void InitWatchFaceModule(JSIValue exports);
+#endif
+
#ifdef FEATURE_MODULE_WEBSOCKET
-extern void InitWebsocketClientModule(JSIValue exports);
+extern void InitWebSocketClientModule(JSIValue exports);
#endif
#ifdef FEATURE_MODULE_CONFIGURATION
#ifdef FEATURE_MODULE_NFC
extern void NfcHceInitModule(JSIValue exports);
#endif
+#ifdef ENABLE_MODULE_CALENDAR
+extern void InitCalendarModule(JSIValue exports);
+#endif
extern void InitNetWorkModule(JSIValue exports);
extern void InitKeyInputModule(JSIValue exports);
// #ifdef FEATURE_ACELITE_SYSTEM_CAPABILITY
#ifdef FEATURE_MODULE_AUDIO
{"audio", InitAudioModule},
{"audiocapturer", InitAudioCapturerModule},
+ {"multimedia.AudioRecorder", InitAudioRecorderModule},
#endif
#ifdef FEATURE_MODULE_BAIDU
{"baidumapcomponent",InitBaiduMapComponentModule},
#ifdef FEATURE_MODULE_HTTP
{"net.http", InitHttpClientModule},
#endif
+#ifdef FEATURE_MODULE_BLE
+ {"bluetooth.ble", InitBleModule},
+#endif
#ifdef FEATURE_MODULE_BATTERY
{"battery", InitBatteryModule},
#endif
// {"capability", InitCapabilityModule},
// #endif
#ifdef FEATURE_MODULE_WEBSOCKET
- {"net.webSocket", InitWebsocketClientModule},
+ {"net.webSocket", InitWebSocketClientModule},
#endif
#ifdef FEATURE_MODULE_NFC
{"nfc.cardEmulation", NfcHceInitModule},
+#endif
+#ifdef FEATURE_MODULE_WATCHFACE
+ {"watchface", InitWatchFaceModule},
#endif
{"network", InitNetWorkModule},
{"keyinput", InitKeyInputModule},
+#ifdef ENABLE_MODULE_CALENDAR
+ {"CalendarManager", InitCalendarModule},
+#endif
};
} // namespace ACELite
} // namespace OHOS
#include "js_app_context.h"
#include "js_profiler.h"
#include "jsi/internal/jsi_internal.h"
+#include "NativeAbility.h"
+#include "AppViewIDs.h"
namespace OHOS {
namespace ACELite {
void InitRouterModule(JSIValue exports)
{
JSI::SetModuleAPI(exports, "replace", RouterModule::Replace);
+ JSI::SetModuleAPI(exports, "replaceToNative", RouterModule::ReplaceToNative);
}
JSIValue RouterModule::Replace(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
jerry_value_t replaceResult = router->Replace(object);
return AS_JSI_VALUE(replaceResult);
}
+
+JSIValue RouterModule::ReplaceToNative(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+ uint16_t sliceId = 0;
+ // router.replaceToNative({sliceId: 1}}
+ JSIValue jsId = JSI::GetNamedProperty(args[0], "sliceId");
+ // router.replaceToNative({sliceName: "APP_LIST"}}
+ JSIValue jsName = JSI::GetNamedProperty(args[0], "sliceName");
+
+ // If sliceId and sliceName are contained, only sliceId is used.
+ if (!JSI::ValueIsUndefined(jsId)) {
+ sliceId = static_cast<uint16_t>(JSI::ValueToNumber(jsId));
+ } else if (!JSI::ValueIsUndefined(jsName)) {
+ char *sliceName = JSI::ValueToString(jsName);
+ if (sliceName == nullptr) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "ReplaceToSlice sliceName is invalid");
+ return JSI::CreateUndefined();
+ }
+
+ if (strcmp(sliceName, "LAUNCHER") == 0) {
+ sliceId = VIEW_MAIN_SAMPLE;
+ } else if (strcmp(sliceName, "APP_LIST") == 0) {
+ sliceId = VIEW_APPLIST;
+ } else {
+ HILOG_ERROR(HILOG_MODULE_ACE, "ReplaceToSlice sliceName mismatch");
+ JSI::ReleaseString(sliceName);
+ return JSI::CreateUndefined();
+ }
+ JSI::ReleaseString(sliceName);
+ } else {
+ HILOG_ERROR(HILOG_MODULE_ACE, "ReplaceToSlice args is nullptr");
+ return JSI::CreateUndefined();
+ }
+
+ OHOS::NativeAbility::GetInstance().ChangeSlice(sliceId);
+ return JSI::CreateUndefined();
+}
} // namespace ACELite
} // namespace OHOS
RouterModule() {}
~RouterModule() {}
static JSIValue Replace(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum);
+ static JSIValue ReplaceToNative(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum);
};
void InitRouterModule(JSIValue exports);
#include "product_adapter.h"\r
#include <securec.h>\r
#include "sensor_module.h"\r
-#include "media_log.h"\r
#include "global.h"\r
#include "screen.h"\r
\r
SensorInfo *SensorModule::sensorInfo_ = nullptr;\r
int32_t SensorModule::sensorCnt_ = 0;\r
\r
+static void RecordAccelSensorCallback(SensorEvent *event);\r
+static void RecordBarSensorCallback(SensorEvent *event);\r
+static void RecordGyroSensorCallback(SensorEvent *event);\r
+static void RecordHrSensorCallback(SensorEvent *event);\r
+static void RecordObsSensorCallback(SensorEvent *event);\r
+static void RecordScSensorCallback(SensorEvent *event);\r
+\r
+struct SensorDev {\r
+ SensorTypeId sensorTypeId;\r
+ SensorUser user;\r
+ bool subscribed;\r
+ SensorParams sensorParams;\r
+};\r
+\r
static struct SensorDev g_sensorDev[] = {\r
- {SENSOR_TYPE_ID_ACCELEROMETER, {"SensorModule", SensorModule::RecordAccelSensorCallback, nullptr}, SensorModule::UnsubscribeBySensorTypeId, false},\r
- {SENSOR_TYPE_ID_BAROMETER, {"SensorModule", SensorModule::RecordBarSensorCallback, nullptr}, SensorModule::UnsubscribeBySensorTypeId, false},\r
- {SENSOR_TYPE_ID_GYROSCOPE, {"SensorModule", SensorModule::RecordCyroSensorCallback, nullptr}, SensorModule::UnsubscribeBySensorTypeId, false},\r
- {SENSOR_TYPE_ID_HEART_RATE, {"SensorModule", SensorModule::RecordHrSensorCallback, nullptr}, SensorModule::UnsubscribeBySensorTypeId, false},\r
- {SENSOR_TYPE_ID_WEAR_DETECTION, {"SensorModule", SensorModule::RecordObsSensorCallback, nullptr}, SensorModule::UnsubscribeBySensorTypeId, false},\r
- {SENSOR_TYPE_ID_PEDOMETER, {"SensorModule", SensorModule::RecordScSensorCallback, nullptr}, SensorModule::UnsubscribeBySensorTypeId, false},\r
+ {SENSOR_TYPE_ID_ACCELEROMETER, {"SensorModule", RecordAccelSensorCallback, nullptr}, false},\r
+ {SENSOR_TYPE_ID_BAROMETER, {"SensorModule", RecordBarSensorCallback, nullptr}, false},\r
+ {SENSOR_TYPE_ID_GYROSCOPE, {"SensorModule", RecordGyroSensorCallback, nullptr}, false},\r
+ {SENSOR_TYPE_ID_HEART_RATE, {"SensorModule", RecordHrSensorCallback, nullptr}, false},\r
+ {SENSOR_TYPE_ID_WEAR_DETECTION, {"SensorModule", RecordObsSensorCallback, nullptr}, false},\r
+ {SENSOR_TYPE_ID_PEDOMETER, {"SensorModule", RecordScSensorCallback, nullptr}, false},\r
};\r
\r
-SensorDev *SensorModule::GetSensorIdBySensorDevIndex(SensorTypeId sensorTypeId)\r
+static struct SensorDev *GetSensorIdBySensorDevIndex(SensorTypeId sensorTypeId)\r
{\r
- if (sensorCnt_ <= 0 || sensorInfo_ == nullptr) {\r
+ if (SensorModule::sensorCnt_ <= 0 || SensorModule::sensorInfo_ == nullptr) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "must GetAllSensors first");\r
return nullptr;\r
}\r
bool found = false;\r
- for (int32_t index = 0; index < sensorCnt_; index++) {\r
- if (sensorInfo_[index].sensorTypeId == sensorTypeId) {\r
+ for (int32_t index = 0; index < SensorModule::sensorCnt_; index++) {\r
+ if (SensorModule::sensorInfo_[index].sensorTypeId == sensorTypeId) {\r
found = true;\r
break;\r
}\r
JSI::ReleaseValueList(fail, complete, errInfo, errCode, ARGS_END);\r
}\r
\r
-void SensorModule::RecordAccelSensorCallback(SensorEvent *event)\r
+void RecordAccelSensorCallbackDispatch(void *arg)\r
{\r
+ SensorEvent *event = reinterpret_cast<SensorEvent *>(arg);\r
+ if (event == nullptr) {\r
+ HILOG_ERROR(HILOG_MODULE_ACE, "Sensor event is NULL!");\r
+ return;\r
+ }\r
if (event->data == NULL || event->dataLen == 0 || event->dataLen != sizeof(AccelData)) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "SensorEvent data invalid");\r
return;\r
HILOG_ERROR(HILOG_MODULE_ACE, "sensorTypeId %d is not ACCELEROMETER", event->sensorTypeId);\r
return;\r
}\r
- SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
+ struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
if (sensorDev == nullptr) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
return;\r
JSI::SetNumberProperty(result, "x", static_cast<double>(accelData->axisX));\r
JSI::SetNumberProperty(result, "y", static_cast<double>(accelData->axisY));\r
JSI::SetNumberProperty(result, "z", static_cast<double>(accelData->axisZ));\r
- SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
+ SensorModule::SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
JSI::ReleaseString(interval);\r
JSI::ReleaseValueList(result, ARGS_END);\r
}\r
\r
-void SensorModule::RecordBarSensorCallback(SensorEvent *event)\r
+void RecordAccelSensorCallback(SensorEvent *event)\r
{\r
+ JsAsyncWork::DispatchAsyncWork(RecordAccelSensorCallbackDispatch, event);\r
+}\r
+\r
+void RecordBarSensorCallbackDispatch(void *arg)\r
+{\r
+ SensorEvent *event = reinterpret_cast<SensorEvent *>(arg);\r
if (event->data == NULL || event->dataLen == 0 || event->dataLen != sizeof(PressureData)) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "SensorEvent data invalid");\r
return;\r
HILOG_ERROR(HILOG_MODULE_ACE, "sensorTypeId %d is not BAROMETER", event->sensorTypeId);\r
return;\r
}\r
- SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
+ struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
if (sensorDev == nullptr) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
return;\r
PressureData *pressureData = (PressureData *)event->data;\r
JSIValue result = JSI::CreateObject();\r
JSI::SetNumberProperty(result, SensorModule::PRESSURE, static_cast<double>(pressureData->pressure));\r
- SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
+ SensorModule::SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
JSI::ReleaseValueList(result, ARGS_END);\r
}\r
\r
-void SensorModule::RecordCyroSensorCallback(SensorEvent *event)\r
+void RecordBarSensorCallback(SensorEvent *event)\r
{\r
+ JsAsyncWork::DispatchAsyncWork(RecordBarSensorCallbackDispatch, event);\r
+}\r
+\r
+void RecordGyroSensorCallbackDispatch(void *arg)\r
+{\r
+ SensorEvent *event = reinterpret_cast<SensorEvent *>(arg);\r
if (event->data == NULL || event->dataLen == 0 || event->dataLen != sizeof(GyroData)) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "SensorEvent data invalid");\r
return;\r
HILOG_ERROR(HILOG_MODULE_ACE, "sensorTypeId %d is not GYROSCOPE", event->sensorTypeId);\r
return;\r
}\r
- SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
+ struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
if (sensorDev == nullptr) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
return;\r
JSI::SetNumberProperty(result, "x", static_cast<double>(gyroData->axisX));\r
JSI::SetNumberProperty(result, "y", static_cast<double>(gyroData->axisY));\r
JSI::SetNumberProperty(result, "z", static_cast<double>(gyroData->axisZ));\r
- SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
+ SensorModule::SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
JSI::ReleaseString(interval);\r
JSI::ReleaseValueList(result, ARGS_END);\r
}\r
\r
-void SensorModule::RecordHrSensorCallback(SensorEvent *event)\r
+void RecordGyroSensorCallback(SensorEvent *event)\r
+{\r
+ JsAsyncWork::DispatchAsyncWork(RecordGyroSensorCallbackDispatch, event);\r
+}\r
+\r
+void RecordHrSensorCallbackDispatch(void *arg)\r
{\r
+ SensorEvent *event = reinterpret_cast<SensorEvent *>(arg);\r
if (event->data == NULL || event->dataLen == 0 || event->dataLen != sizeof(uint32_t)) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "SensorEvent data invalid");\r
return;\r
HILOG_ERROR(HILOG_MODULE_ACE, "sensorTypeId %d is not HEART_RATE", event->sensorTypeId);\r
return;\r
}\r
- SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
+ struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
if (sensorDev == nullptr) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
return;\r
uint32_t heartRate = *(uint32_t *)event->data;\r
JSIValue result = JSI::CreateObject();\r
JSI::SetNumberProperty(result, SensorModule::HEARTRATE, static_cast<double>(heartRate));\r
- SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
+ SensorModule::SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
JSI::ReleaseValueList(result, ARGS_END);\r
}\r
\r
-void SensorModule::RecordObsSensorCallback(SensorEvent *event)\r
+void RecordHrSensorCallback(SensorEvent *event)\r
{\r
+ JsAsyncWork::DispatchAsyncWork(RecordHrSensorCallbackDispatch, event);\r
+}\r
+\r
+void RecordObsSensorCallbackDispatch(void *arg)\r
+{\r
+ SensorEvent *event = reinterpret_cast<SensorEvent *>(arg);\r
if (event->data == NULL || event->dataLen == 0 || event->dataLen != sizeof(uint8_t)) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "SensorEvent data invalid");\r
return;\r
HILOG_ERROR(HILOG_MODULE_ACE, "sensorTypeId %d is not WEAR_DETECTION", event->sensorTypeId);\r
return;\r
}\r
- SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
+ struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
if (sensorDev == nullptr) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
return;\r
bool value = isonbody == 0 ? false : true;\r
JSIValue result = JSI::CreateObject();\r
JSI::SetNumberProperty(result, SensorModule::ISONBODY, static_cast<double>(value));\r
- SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
+ SensorModule::SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
JSI::ReleaseValueList(result, ARGS_END);\r
}\r
\r
-void SensorModule::RecordScSensorCallback(SensorEvent *event)\r
+void RecordObsSensorCallback(SensorEvent *event)\r
+{\r
+ JsAsyncWork::DispatchAsyncWork(RecordObsSensorCallbackDispatch, event);\r
+}\r
+\r
+void RecordScSensorCallbackDispatch(void *arg)\r
{\r
+ SensorEvent *event = reinterpret_cast<SensorEvent *>(arg);\r
+ if (event == nullptr) {\r
+ HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
+ return;\r
+ }\r
if (event->data == NULL || event->dataLen == 0 || event->dataLen != sizeof(uint32_t)) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "SensorEvent data invalid");\r
return;\r
HILOG_ERROR(HILOG_MODULE_ACE, "sensorTypeId %d is not PEDOMETER", event->sensorTypeId);\r
return;\r
}\r
- SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
+ struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
if (sensorDev == nullptr) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
return;\r
uint32_t steps = *(uint32_t *)event->data;\r
JSIValue result = JSI::CreateObject();\r
JSI::SetNumberProperty(result, SensorModule::STEPS, static_cast<double>(steps));\r
- SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
+ SensorModule::SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
JSI::ReleaseValueList(result, ARGS_END);\r
}\r
\r
+void RecordScSensorCallback(SensorEvent *event)\r
+{\r
+ JsAsyncWork::DispatchAsyncWork(RecordScSensorCallbackDispatch, event);\r
+}\r
+\r
void SensorModule::ExecuteGetAllSensors()\r
{\r
if (sensorCnt_ != 0 || sensorInfo_ != nullptr) {\r
- HILOG_INFO(HILOG_MODULE_ACE, "sensorInfo is Got");\r
+ HILOG_ERROR(HILOG_MODULE_ACE, "sensorInfo is Got");\r
return;\r
}\r
int32_t errCode = GetAllSensors(&sensorInfo_, &sensorCnt_);\r
}\r
}\r
\r
+void SensorModule::ExecuteUnsubscribeAllSensors()\r
+{\r
+ HILOG_INFO(HILOG_MODULE_ACE, "ExecuteUnsubscribeAllSensors");\r
+ for (uint32_t index = 0; index < ARRAY_SIZE(g_sensorDev); index++) {\r
+ if (!g_sensorDev[index].subscribed) {\r
+ continue;\r
+ }\r
+ UnsubscribeBySensorTypeId(g_sensorDev[index].sensorTypeId);\r
+ }\r
+}\r
+\r
int32_t SensorModule::SubscribeBySensorTypeId(void *data, SensorTypeId sensorTypeId)\r
{\r
SensorParams *params = reinterpret_cast<SensorParams *>(data);\r
- SensorDev *sensorDev = GetSensorIdBySensorDevIndex(sensorTypeId);\r
+ struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex(sensorTypeId);\r
if (sensorDev == nullptr) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
return SENSOR_ERROR_UNKNOWN;\r
}\r
- int32_t errCode = ActivateSensor(sensorTypeId, &sensorDev->user);\r
+ int32_t errCode = SubscribeSensor(sensorTypeId, &sensorDev->user);\r
if (errCode != SENSOR_OK) {\r
- HILOG_ERROR(HILOG_MODULE_ACE, "ActivateSensor failed:%d", errCode);\r
+ HILOG_ERROR(HILOG_MODULE_ACE, "SubscribeSensor failed:%d", errCode);\r
return SENSOR_ERROR_UNKNOWN;\r
}\r
- errCode = SubscribeSensor(sensorTypeId, &sensorDev->user);\r
+ errCode = ActivateSensor(sensorTypeId, &sensorDev->user);\r
if (errCode != SENSOR_OK) {\r
- HILOG_ERROR(HILOG_MODULE_ACE, "SubscribeSensor failed:%d", errCode);\r
+ HILOG_ERROR(HILOG_MODULE_ACE, "ActivateSensor failed:%d", errCode);\r
return SENSOR_ERROR_UNKNOWN;\r
}\r
sensorDev->sensorParams.args = params->args;\r
\r
int32_t SensorModule::UnsubscribeBySensorTypeId(SensorTypeId sensorTypeId)\r
{\r
- SensorDev *sensorDev = GetSensorIdBySensorDevIndex(sensorTypeId);\r
- if (sensorDev == nullptr) {\r
+ struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex(sensorTypeId);\r
+ if (sensorDev == nullptr || sensorDev->subscribed == false) {\r
HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
+ return SENSOR_ERROR_UNKNOWN;\r
}\r
int32_t errCode = UnsubscribeSensor(sensorTypeId, &sensorDev->user);\r
if (errCode != SENSOR_OK) {\r
if (errCode != SENSOR_OK) {\r
FailCallBack(thisVal, args, -1, false);\r
HILOG_ERROR(HILOG_MODULE_ACE, "SubscribeSensor failed:%d", errCode);\r
+ delete params;\r
+ return;\r
}\r
delete params;\r
}\r
if (errCode != SENSOR_OK) {\r
FailCallBack(thisVal, args, -1, false);\r
HILOG_ERROR(HILOG_MODULE_ACE, "SubscribeSensor failed:%d", errCode);\r
+ delete params;\r
+ return;\r
}\r
delete params;\r
}\r
if (errCode != SENSOR_OK) {\r
FailCallBack(thisVal, args, -1, false);\r
HILOG_ERROR(HILOG_MODULE_ACE, "SubscribeSensor failed:%d", errCode);\r
+ delete params;\r
+ return;\r
}\r
delete params;\r
}\r
if (errCode != SENSOR_OK) {\r
FailCallBack(thisVal, args, -1, false);\r
HILOG_ERROR(HILOG_MODULE_ACE, "SubscribeSensor failed:%d", errCode);\r
+ delete params;\r
+ return;\r
}\r
delete params;\r
}\r
if (errCode != SENSOR_OK) {\r
FailCallBack(thisVal, args, -1, false);\r
HILOG_ERROR(HILOG_MODULE_ACE, "SubscribeSensor failed:%d", errCode);\r
+ delete params;\r
+ return;\r
}\r
delete params;\r
}\r
if (errCode != SENSOR_OK) {\r
FailCallBack(thisVal, args, -1, false);\r
HILOG_ERROR(HILOG_MODULE_ACE, "SubscribeSensor failed:%d", errCode);\r
+ delete params;\r
+ return;\r
}\r
delete params;\r
}\r
\r
-struct SensorParams *SensorModule::GetSensorParamsFromArgs(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)\r
+void SensorModule::ExecuteGetAccelerometerData(void *data)\r
{\r
- JSIValue undefValue = JSI::CreateUndefined();\r
- if ((args == nullptr) || (argsNum == 0) || (JSI::ValueIsUndefined(args[0]))) {\r
- HILOG_ERROR(HILOG_MODULE_ACE, "Error in obtaining Sensor information parameters");\r
- return nullptr;\r
+ SensorParams *params = reinterpret_cast<SensorParams *>(data);\r
+ if (params == nullptr) {\r
+ return;\r
+ }\r
+ JSIValue args = params->args;\r
+ JSIValue thisVal = params->thisVal;\r
+ struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex(SENSOR_TYPE_ID_ACCELEROMETER);\r
+ if (sensorDev == nullptr) {\r
+ HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
+ return;\r
+ }\r
+ SensorData *sensorData = new SensorData;\r
+ if (sensorData == nullptr) {\r
+ HILOG_ERROR(HILOG_MODULE_ACE, "malloc failed!");\r
+ SensorModule::FailCallBack(thisVal, args, SENSOR_ERROR_UNKNOWN, false);\r
+ return;\r
}\r
+ int32_t ret = GetSensorData(SENSOR_TYPE_ID_ACCELEROMETER, &sensorDev->user, sensorData);\r
+ if (ret != SENSOR_OK) {\r
+ HILOG_ERROR(HILOG_MODULE_ACE, "Get accelerometer data failed!");\r
+ delete sensorData;\r
+ SensorModule::FailCallBack(thisVal, args, SENSOR_ERROR_UNKNOWN, false);\r
+ return;\r
+ }\r
+ AccelData *accelData = (AccelData *)sensorData->data;\r
+ JSIValue result = JSI::CreateObject();\r
+ for (uint32_t i = 0; i < sensorData->batchCnt; i++) {\r
+ JSI::SetNumberProperty(result, "x", static_cast<double>(accelData[i].axisX));\r
+ JSI::SetNumberProperty(result, "y", static_cast<double>(accelData[i].axisY));\r
+ JSI::SetNumberProperty(result, "z", static_cast<double>(accelData[i].axisZ));\r
+ SensorModule::SuccessCallBack(thisVal, args, result, false);\r
+ }\r
+ JSI::SetNumberProperty(result, "batchCnt", static_cast<double>(sensorData->batchCnt));\r
+ JSI::SetNumberProperty(result, "timestamp", static_cast<double>(sensorData->timestamp));\r
+ SensorModule::SuccessCallBack(thisVal, args, result, false);\r
+ JSI::ReleaseValueList(result, ARGS_END);\r
+ delete sensorData;\r
+}\r
\r
- SensorParams *params = new (std::nothrow) SensorParams();\r
+void SensorModule::ExecuteGetGyroscopeData(void *data)\r
+{\r
+ SensorParams *params = reinterpret_cast<SensorParams *>(data);\r
if (params == nullptr) {\r
- HILOG_ERROR(HILOG_MODULE_ACE, "Error in new Sensor information parameters");\r
- return nullptr;\r
+ return;\r
}\r
- params->thisVal = JSI::AcquireValue(thisVal);\r
- if (args != nullptr) {\r
- params->args = JSI::AcquireValue(args[0]);\r
+ JSIValue args = params->args;\r
+ JSIValue thisVal = params->thisVal;\r
+ struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex(SENSOR_TYPE_ID_GYROSCOPE);\r
+ if (sensorDev == nullptr) {\r
+ HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
+ return;\r
+ }\r
+ SensorData *sensorData = new SensorData;\r
+ if (sensorData == nullptr) {\r
+ HILOG_ERROR(HILOG_MODULE_ACE, "malloc failed!");\r
+ SensorModule::FailCallBack(thisVal, args, SENSOR_ERROR_UNKNOWN, false);\r
+ return;\r
+ }\r
+ int32_t ret = GetSensorData(SENSOR_TYPE_ID_GYROSCOPE, &sensorDev->user, sensorData);\r
+ if (ret != 0) {\r
+ HILOG_ERROR(HILOG_MODULE_ACE, "Get accelerometer data failed!");\r
+ delete sensorData;\r
+ SensorModule::FailCallBack(thisVal, args, SENSOR_ERROR_UNKNOWN, false);\r
+ return;\r
}\r
- return params;\r
+ GyroData *gyroData = (GyroData *)sensorData->data;\r
+ JSIValue result = JSI::CreateObject();\r
+ for (uint32_t i = 0; i < sensorData->batchCnt; i++) {\r
+ JSI::SetNumberProperty(result, "x", static_cast<double>(gyroData->axisX));\r
+ JSI::SetNumberProperty(result, "y", static_cast<double>(gyroData->axisY));\r
+ JSI::SetNumberProperty(result, "z", static_cast<double>(gyroData->axisZ));\r
+ SensorModule::SuccessCallBack(thisVal, args, result, false);\r
+ }\r
+ JSI::SetNumberProperty(result, "batchCnt", static_cast<double>(sensorData->batchCnt));\r
+ JSI::SetNumberProperty(result, "timestamp", static_cast<double>(sensorData->timestamp));\r
+ SensorModule::SuccessCallBack(thisVal, args, result, false);\r
+ JSI::ReleaseValueList(result, ARGS_END);\r
+ delete sensorData;\r
}\r
\r
-JSIValue SensorModule::ExecuteSyncWork(\r
+JSIValue SensorModule::ExecuteAsyncWork(\r
const JSIValue thisVal, const JSIValue *args, uint8_t argsNum, AsyncWorkHandler ExecuteFunc)\r
{\r
JSIValue undefValue = JSI::CreateUndefined();\r
- SensorParams *params = GetSensorParamsFromArgs(thisVal, args, argsNum);\r
+ if ((args == nullptr) || (argsNum == 0) || (JSI::ValueIsUndefined(args[0]))) {\r
+ HILOG_ERROR(HILOG_MODULE_ACE, "Error in obtaining Sensor information parameters");\r
+ return undefValue;\r
+ }\r
+\r
+ SensorParams *params = new (std::nothrow) SensorParams();\r
if (params == nullptr) {\r
return undefValue;\r
}\r
- ExecuteFunc(reinterpret_cast<void *>(params));\r
+ params->thisVal = JSI::AcquireValue(thisVal);\r
+ if (args != nullptr) {\r
+ params->args = JSI::AcquireValue(args[0]);\r
+ }\r
+ JsAsyncWork::DispatchAsyncWork(ExecuteFunc, reinterpret_cast<void *>(params));\r
return undefValue;\r
}\r
\r
JSIValue SensorModule::SubscribeStepCounter(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
{\r
- JSIValue undefValue = JSI::CreateUndefined();\r
- SensorParams *params = GetSensorParamsFromArgs(thisVal, args, argsNum);\r
- if (params == nullptr) {\r
- return undefValue;\r
- }\r
- ExecuteSubscribeStepCounter(reinterpret_cast<void *>(params));\r
- return undefValue;\r
+ return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteSubscribeStepCounter);\r
}\r
\r
JSIValue SensorModule::UnsubscribeStepCounter(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
\r
JSIValue SensorModule::SubscribeBarometer(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
{\r
- JSIValue undefValue = JSI::CreateUndefined();\r
- SensorParams *params = GetSensorParamsFromArgs(thisVal, args, argsNum);\r
- if (params == nullptr) {\r
- return undefValue;\r
- }\r
- ExecuteSubscribeBarometer(reinterpret_cast<void *>(params));\r
- return undefValue;\r
+ return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteSubscribeBarometer);\r
}\r
\r
JSIValue SensorModule::UnsubscribeBarometer(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
\r
JSIValue SensorModule::SubscribeHeartRate(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
{\r
- JSIValue undefValue = JSI::CreateUndefined();\r
- SensorParams *params = GetSensorParamsFromArgs(thisVal, args, argsNum);\r
- if (params == nullptr) {\r
- return undefValue;\r
- }\r
- ExecuteSubscribeHeartRate(reinterpret_cast<void *>(params));\r
- return undefValue;\r
+ return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteSubscribeHeartRate);\r
}\r
\r
JSIValue SensorModule::UnsubscribeHeartRate(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
\r
JSIValue SensorModule::SubscribeOnBodyState(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
{\r
- JSIValue undefValue = JSI::CreateUndefined();\r
- SensorParams *params = GetSensorParamsFromArgs(thisVal, args, argsNum);\r
- if (params == nullptr) {\r
- return undefValue;\r
- }\r
- ExecuteSubscribeOnBodyState(reinterpret_cast<void *>(params));\r
- return undefValue;\r
+ return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteSubscribeOnBodyState);\r
}\r
\r
JSIValue SensorModule::UnsubscribeOnBodyState(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
\r
JSIValue SensorModule::GetOnBodyState(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
{\r
- return ExecuteSyncWork(thisVal, args, argsNum, ExecuteGetOnBodyState);\r
+ return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteGetOnBodyState);\r
}\r
\r
JSIValue SensorModule::SubscribeAccelerometer(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
{\r
- JSIValue undefValue = JSI::CreateUndefined();\r
- SensorParams *params = GetSensorParamsFromArgs(thisVal, args, argsNum);\r
- if (params == nullptr) {\r
- return undefValue;\r
- }\r
- ExecuteSubscribeAccelerometer(reinterpret_cast<void *>(params));\r
- return undefValue;\r
+ return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteSubscribeAccelerometer);\r
}\r
\r
JSIValue SensorModule::UnsubscribeAccelerometer(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
\r
JSIValue SensorModule::SubscribeGyroscope(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
{\r
- JSIValue undefValue = JSI::CreateUndefined();\r
- SensorParams *params = GetSensorParamsFromArgs(thisVal, args, argsNum);\r
- if (params == nullptr) {\r
- return undefValue;\r
- }\r
- ExecuteSubscribeGyroscope(reinterpret_cast<void *>(params));\r
- return undefValue;\r
+ return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteSubscribeGyroscope);\r
}\r
\r
JSIValue SensorModule::UnsubscribeGyroscope(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
return JSI::CreateUndefined();\r
}\r
\r
-void SensorModule::OnDestroy()\r
+JSIValue SensorModule::GetAccelerometerData(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
{\r
- for (uint32_t index = 0; index < ARRAY_SIZE(g_sensorDev); index++) {\r
- SensorTypeId sensorTypeId = g_sensorDev[index].sensorTypeId;\r
- if (!g_sensorDev[index].subscribed) {\r
- continue;\r
- }\r
- int32_t errCode = g_sensorDev[index].unSubscribeSensor(sensorTypeId);\r
- if (errCode != SENSOR_OK) {\r
- HILOG_INFO(HILOG_MODULE_ACE, "Unsubscribe :%d failed:%d", sensorTypeId, errCode);\r
- }\r
- }\r
+ return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteGetAccelerometerData);\r
+}\r
+\r
+JSIValue SensorModule::GetGyroscopeData(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
+{\r
+ return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteGetGyroscopeData);\r
+}\r
+\r
+void SensorModule::OnTerminate()\r
+{\r
+ ExecuteUnsubscribeAllSensors();\r
+ sensorInfo_ = nullptr;\r
+ sensorCnt_ = 0;\r
}\r
\r
} // namespace ACELite\r
JSIValue thisVal = JSI::CreateUndefined();\r
};\r
\r
-typedef int32_t (*UnsubscribeBySensorTypeId)(SensorTypeId sensorTypeId);\r
-\r
-struct SensorDev {\r
- SensorTypeId sensorTypeId;\r
- SensorUser user;\r
- UnsubscribeBySensorTypeId unSubscribeSensor;\r
- bool subscribed;\r
- SensorParams sensorParams;\r
-};\r
-\r
class SensorModule final : public MemoryHeap {\r
public:\r
ACE_DISALLOW_COPY_AND_MOVE(SensorModule);\r
static JSIValue UnsubscribeAccelerometer(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
static JSIValue SubscribeGyroscope(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
static JSIValue UnsubscribeGyroscope(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
+ static JSIValue GetAccelerometerData(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
+ static JSIValue GetGyroscopeData(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
static void SuccessCallBack(const JSIValue thisVal, const JSIValue args, JSIValue jsiValue, bool flag);\r
-\r
- static void RecordAccelSensorCallback(SensorEvent *event);\r
- static void RecordBarSensorCallback(SensorEvent *event);\r
- static void RecordCyroSensorCallback(SensorEvent *event);\r
- static void RecordHrSensorCallback(SensorEvent *event);\r
- static void RecordObsSensorCallback(SensorEvent *event);\r
- static void RecordScSensorCallback(SensorEvent *event);\r
-\r
static void ExecuteGetAllSensors();\r
+ static void ExecuteUnsubscribeAllSensors();\r
static int32_t SubscribeBySensorTypeId(void *data, SensorTypeId sensorTypeId);\r
static int32_t UnsubscribeBySensorTypeId(SensorTypeId sensorTypeId);\r
+ static void OnTerminate();\r
\r
- static void OnDestroy();\r
+ static SensorInfo *sensorInfo_;\r
+ static int32_t sensorCnt_;\r
\r
private:\r
- static JSIValue ExecuteSyncWork(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum, AsyncWorkHandler ExecuteFunc);\r
- static SensorDev *GetSensorIdBySensorDevIndex(SensorTypeId sensorTypeId);\r
- static SensorParams *GetSensorParamsFromArgs(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum);\r
+ static JSIValue ExecuteAsyncWork(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum, AsyncWorkHandler ExecuteFunc);\r
static void FailCallBack(const JSIValue thisVal, const JSIValue args, int ret, bool flag);\r
-\r
static void ExecuteSubscribeStepCounter(void *data);\r
static void ExecuteSubscribeBarometer(void *data);\r
static void ExecuteSubscribeHeartRate(void *data);\r
static void ExecuteGetOnBodyState(void *data);\r
static void ExecuteSubscribeGyroscope(void *data);\r
static void ExecuteSubscribeAccelerometer(void *data);\r
- static SensorInfo *sensorInfo_;\r
- static int32_t sensorCnt_;\r
-\r
+ static void ExecuteGetAccelerometerData(void *data);\r
+ static void ExecuteGetGyroscopeData(void *data);\r
};\r
\r
void InitSensorModule(JSIValue exports)\r
JSI::SetModuleAPI(exports, "unsubscribeAccelerometer", SensorModule::UnsubscribeAccelerometer);\r
JSI::SetModuleAPI(exports, "subscribeGyroscope", SensorModule::SubscribeGyroscope);\r
JSI::SetModuleAPI(exports, "unsubscribeGyroscope", SensorModule::UnsubscribeGyroscope);\r
- JSI::SetOnDestroy(exports, SensorModule::OnDestroy);\r
+ JSI::SetModuleAPI(exports, "getAccelerometerData", SensorModule::GetAccelerometerData);\r
+ JSI::SetModuleAPI(exports, "getGyroscopeData", SensorModule::GetGyroscopeData);\r
+ JSI::SetOnTerminate(exports, SensorModule::OnTerminate);\r
+ JSI::SetOnDestroy(exports, SensorModule::OnTerminate);\r
SensorModule::ExecuteGetAllSensors();\r
}\r
\r
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: watchface JS intarface
+ * Author: Software Group
+ * Create: 2025-09-5
+ */
+
+#include <string>
+#include "jsi.h"
+#include "securec.h"
+#include "ace_log.h"
+#include "js_async_work.h"
+#include "watchface_module.h"
+
+namespace OHOS {
+namespace ACELite {
+
+bool WatchfaceModule::isListenerRunning_ = false;
+bool WatchfaceModule::isTerminate_ = false;
+
+constexpr static uint32_t STEP_SIZE = 512;
+constexpr static uint32_t DELAY_TIME = 500;
+
+// 下载状态打桩变量
+static uint32_t totalSize = 16 * 1024;
+static uint32_t receivedSize = 0;
+
+bool WatchfaceModule::GetDialInfo(uint32_t uuid, WatchDialInfo& watch, JSIValue& dialInfo)
+{
+ bool isGet = ::GetWatchFaceInfo(uuid, &watch);
+ if (isGet) {
+ JSI::SetNumberProperty(dialInfo, "uuid", watch.uuid);
+ JSI::SetNumberProperty(dialInfo, "install_state", watch.install_state);
+ JSI::SetNumberProperty(dialInfo, "is_current_watch", watch.is_current_watch);
+ JSI::SetStringProperty(dialInfo, "watch_protocol_version", reinterpret_cast<char*>(watch.watch_protocol_version));
+ JSI::SetStringProperty(dialInfo, "watch_version", reinterpret_cast<char*>(watch.watch_version));
+ return true;
+ } else {
+ return false;
+ }
+}
+
+JSIValue WatchfaceModule::SetWatchFace(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
+{
+ if (argsSize != ARGC_TWO) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid parameter!");
+ return JSI::CreateUndefined();
+ }
+
+ WATCHFACE_ERRCODE ret = WATCHFACE_SUCCESS;
+ JSIValue dialInfo = JSI::CreateObject();
+ JSIValue callback = JSI::AcquireValue(args[1]);
+ bool isGet = false;
+
+ uint32_t uuid = JSI::ValueToNumber(args[0]);
+ bool installed = SetCurrentWatchFace(uuid);
+ if (!installed) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "SetCurrentWatchFace failed!");
+ ret = WATCHFACE_INSTALL_ERROR;
+ goto exit;
+ }
+
+ WatchDialInfo watch;
+ memset_s(&watch, sizeof(WatchDialInfo), 0, sizeof(WatchDialInfo));
+ isGet = GetDialInfo(uuid, watch, dialInfo);
+ if (!isGet) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "GetDialInfo failed!");
+ ret = WATCHFACE_GETINFO_ERROR;
+ }
+
+exit:
+ JSIValue err = JSI::CreateNumber(ret);
+ JSIValue argv[ARGC_TWO] = {err, dialInfo};
+ JSI::CallFunction(callback, thisVal, argv, ARGC_TWO);
+ JSI::ReleaseValueList(err, callback, dialInfo);
+ return JSI::CreateUndefined();
+}
+
+JSIValue WatchfaceModule::GetWatchFaceInfo(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
+{
+ if (argsSize != ARGC_TWO) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid parameter!");
+ return JSI::CreateUndefined();
+ }
+
+ WatchDialInfo watch;
+ memset_s(&watch, sizeof(WatchDialInfo), 0, sizeof(WatchDialInfo));
+ WATCHFACE_ERRCODE ret = WATCHFACE_SUCCESS;
+
+ uint32_t uuid = JSI::ValueToNumber(args[0]);
+ JSIValue dialInfo = JSI::CreateObject();
+ bool isGet = GetDialInfo(uuid, watch, dialInfo);
+ if (!isGet) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "GetDialInfo failed!");
+ ret = WATCHFACE_GETINFO_ERROR;
+ }
+
+ JSIValue err = JSI::CreateNumber(ret);
+ JSIValue callback = JSI::AcquireValue(args[1]);
+ JSIValue argv[ARGC_TWO] = {err, dialInfo};
+ JSI::CallFunction(callback, thisVal, argv, ARGC_TWO);
+ JSI::ReleaseValueList(err, callback, dialInfo);
+
+ return JSI::CreateUndefined();
+}
+
+// 下载状态打桩函数
+static int GetDownloadStatus(DownloadStatus& status)
+{
+ status.receivedSize = receivedSize;
+ status.totalSize = totalSize;
+ receivedSize += STEP_SIZE;
+ if (receivedSize > totalSize) {
+ receivedSize = totalSize;
+ }
+ status.uuid = 1;
+
+ osal_msleep(DELAY_TIME);
+ return 0;
+}
+
+void WatchfaceModule::FailCallback(void *data)
+{
+ if (data == nullptr) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid null argument in FailCallback");
+ isListenerRunning_ = false;
+ return;
+ }
+
+ WatchfaceParams *params = static_cast<WatchfaceParams *>(data);
+
+ JSIValue installInfo = JSI::CreateObject();
+ JSIValue err = JSI::CreateNumber(WATCHFACE_GETMSG_ERROR);
+ JSIValue callback = params->callback;
+ JSIValue thisVal = params->thisVal;
+
+ JSIValue argv[ARGC_TWO] = {err, installInfo};
+
+ if (!isTerminate_) {
+ JSI::CallFunction(callback, thisVal, argv, ARGC_TWO);
+ }
+ JSI::ReleaseValueList(callback, thisVal);
+ JSI::ReleaseValueList(err, installInfo);
+ delete params;
+ isListenerRunning_ = false;
+ return;
+}
+
+void WatchfaceModule::SuccessCallback(void *data)
+{
+ if (data == nullptr) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid null argument in SuccessCallback");
+ return;
+ }
+
+ WatchfaceParams *params = static_cast<WatchfaceParams *>(data);
+ JSIValue callback = params->callback;
+ JSIValue thisVal = params->thisVal;
+
+ JSIValue installInfo = JSI::CreateObject();
+ JSIValue err = JSI::CreateNumber(WATCHFACE_SUCCESS);
+ JSI::SetNumberProperty(installInfo, "process", params->process);
+ JSI::SetNumberProperty(installInfo, "install_state", params->installState);
+
+ JSIValue argv[ARGC_TWO] = {err, installInfo};
+
+ if (!isTerminate_) {
+ JSI::CallFunction(callback, thisVal, argv, ARGC_TWO);
+ }
+
+ JSI::ReleaseValueList(err, installInfo);
+ if (params->installState || isTerminate_) {
+ JSI::ReleaseValueList(callback, thisVal);
+ delete params;
+ isListenerRunning_ = false;
+ }
+ return;
+}
+
+static void WatchFaceDownload(void *argument)
+{
+ if (argument == nullptr) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid null argument in DownloadListener");
+ return;
+ }
+ WatchfaceParams *params = static_cast<WatchfaceParams *>(argument);
+
+ do {
+ DownloadStatus status;
+ int ret = GetDownloadStatus(status);
+ if (ret != 0) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "GetDownloadStatus failed");
+ JsAsyncWork::DispatchAsyncWork(WatchfaceModule::FailCallback, static_cast<void *>(params));
+ break;
+ }
+
+ WatchDialInfo watch;
+ if (status.receivedSize == status.totalSize) {
+ bool isGet = ::GetWatchFaceInfo(status.uuid, &watch);
+ if (!isGet) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "GetWatchFaceInfo failed");
+ JsAsyncWork::DispatchAsyncWork(WatchfaceModule::FailCallback, static_cast<void *>(params));
+ break;
+ }
+ params->installState = watch.install_state;
+ }
+
+ params->process = static_cast<double>(status.receivedSize) / status.totalSize;
+
+ JsAsyncWork::DispatchAsyncWork(WatchfaceModule::SuccessCallback, static_cast<void *>(params));
+ } while(!params->installState && !WatchfaceModule::isTerminate_);
+}
+
+JSIValue WatchfaceModule::SetDownloadListener(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
+{
+ if (argsSize != ARGC_ONE) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Invalid parameter!");
+ return JSI::CreateUndefined();
+ }
+
+ if (isListenerRunning_) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "another DownloadListener is running!");
+ return JSI::CreateUndefined();
+ }
+
+ WatchfaceParams *params = new WatchfaceParams{};
+ if (params == nullptr) {
+ HILOG_ERROR(HILOG_MODULE_ACE, "Failed to allocate memory for params!");
+ return JSI::CreateUndefined();
+ }
+
+ params->thisVal = JSI::AcquireValue(thisVal);
+ params->callback = JSI::AcquireValue(args[0]);
+
+ osThreadId_t id;
+ osThreadAttr_t attr;
+ attr.name = "WatchFaceDownload";
+ attr.attr_bits = osThreadDetached;
+ attr.cb_mem = NULL;
+ attr.cb_size = 0U;
+ attr.stack_mem = NULL;
+ attr.stack_size = 0x1000;
+ attr.priority = osPriorityNormal;
+
+ isTerminate_ = false;
+ isListenerRunning_ = true;
+ receivedSize = 0; // 打桩数据初始化
+ id = osThreadNew((osThreadFunc_t)WatchFaceDownload, (void *)params, &attr);
+
+ return JSI::CreateUndefined();
+}
+
+JSIValue WatchfaceModule::Destroy(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
+{
+ isTerminate_ = true;
+ return JSI::CreateUndefined();
+}
+
+void InitWatchFaceModule(JSIValue exports)
+{
+ JSI::SetModuleAPI(exports, "setWatchFace", WatchfaceModule::SetWatchFace);
+ JSI::SetModuleAPI(exports, "getWatchFaceInfo", WatchfaceModule::GetWatchFaceInfo);
+ JSI::SetModuleAPI(exports, "setDownloadListener", WatchfaceModule::SetDownloadListener);
+ JSI::SetModuleAPI(exports, "destroy", WatchfaceModule::Destroy);
+}
+} // namespace ACELite
+} // namespace OHOS
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: watchface JS intarface
+ * Author: Software Group
+ * Create: 2025-09-5
+ */
+
+#ifndef WATCHFACE_MODULE_H
+#define WATCHFACE_MODULE_H
+
+#include <stdint.h>
+#include <map>
+#include "jsi.h"
+#include "WatchInterface.h"
+
+namespace OHOS {
+namespace ACELite {
+
+typedef enum {
+ WATCHFACE_SUCCESS = 0,
+ WATCHFACE_PARAM_ERROR = 401,
+ WATCHFACE_INSTALL_ERROR = 2400001,
+ WATCHFACE_GETINFO_ERROR = 2400002,
+ WATCHFACE_GETMSG_ERROR = 2400003,
+} WATCHFACE_ERRCODE;
+
+typedef watch_dial_info WatchDialInfo;
+
+struct DownloadStatus {
+ uint32_t receivedSize;
+ uint32_t totalSize;
+ uint32_t uuid;
+};
+
+struct WatchfaceParams{
+ JSIValue thisVal;
+ JSIValue callback;
+ double process;
+ uint8_t installState;
+};
+
+class WatchfaceModule final : public MemoryHeap {
+public:
+ WatchfaceModule() = default;
+ ~WatchfaceModule() = default;
+ static JSIValue SetWatchFace(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);
+ static JSIValue GetWatchFaceInfo(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);
+ static JSIValue SetDownloadListener(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);
+ static JSIValue Destroy(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);
+ static void FailCallback(void *data);
+ static void SuccessCallback(void *data);
+ static bool isTerminate_;
+private:
+ static bool GetDialInfo(uint32_t uuid, WatchDialInfo& watch, JSIValue& dialInfo);
+ static bool isListenerRunning_;
+};
+void InitWatchFaceModule(JSIValue exports);
+
+} // namespace ACELite
+} // namespace OHOS
+
+#endif // WATCHFACE_MODULE_H
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: websocket common definition
+ * Author: Software Group
+ * Create: 2025-11-19
+ */
+
+#ifndef WEBSOCKET_COMMON_H
+#define WEBSOCKET_COMMON_H
+
+
+namespace OHOS {
+namespace ACELite {
+
+#define net_malloc ace_malloc
+#define net_free ace_free
+
+enum WsEventId {
+ WS_EVENT_OPEN = 0,
+ WS_EVENT_MESSAGE = 1,
+ WS_EVENT_CLOSE = 2,
+ WS_EVENT_ERROR = 3,
+ WS_EVENT_MAX = 4
+};
+
+} // namespace ACELite
+} // namespace OHOS
+
+#endif
\ No newline at end of file
#include "jsi.h"\r
#include <map>\r
#include <cstring>\r
+#include "websocket_common.h"\r
+#include "websocket_module_callback.h"\r
\r
namespace OHOS {\r
namespace ACELite {\r
JSIValue context;\r
};\r
\r
-class WebsocketModule final : public MemoryHeap {\r
+class WebSocketModule final : public MemoryHeap {\r
public:\r
- WebsocketModule() = default;\r
- ~WebsocketModule() = default;\r
- static JSIValue CreateWebsocket(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ WebSocketModule() = default;\r
+ ~WebSocketModule() = default;\r
+ static JSIValue CreateWebSocket(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
static JSIValue Connect(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
static JSIValue Send(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue SendInit(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue SendUpdate(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue SendFinish(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
static JSIValue Close(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ static JSIValue Destroy(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
static JSIValue On(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
static JSIValue Off(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
static std::map<std::string, EventCallback *> eventCallbacks;\r
- static void Destroy();\r
static void OnTerminate();\r
+private:\r
+ static WsEventId GetEventId(const char *event);\r
+ static char *HeaderJsonToString(char* headerJson);\r
};\r
-void InitWebsocketModule(JSIValue exports);\r
+void InitWebSocketClientModule(JSIValue exports);\r
\r
} // namespace ACELite\r
} // namespace OHOS\r
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: websocket callback interfaces
+ * Author: Software Group
+ * Create: 2025-09-1
+ */
+
+#ifndef WEBSOCKET_MODULE_CALLBACK_H
+#define WEBSOCKET_MODULE_CALLBACK_H
+
+#include "jsi.h"
+#include "net_websocket_type.h"
+#include "http_errcode.h"
+#include "websocket_common.h"
+
+namespace OHOS {
+namespace ACELite {
+
+struct WsResult {
+ int resCode;
+ char* reason;
+ char* data;
+ int length;
+ bool isBinary;
+ int clientId;
+ WsEventId eventId;
+};
+
+class WsCallback final : public MemoryHeap {
+public:
+ WsCallback() = default;
+ ~WsCallback() = default;
+
+ static void DispatchStateInfo(int resCode, const char* reason, WsEventId eventId, int clientId);
+ static void DispatchMessage(const char *data, size_t length, bool isBinary, int clientId);
+
+private:
+ static void SendStateInfo(void *param);
+ static void SendMessage(void *param);
+
+private:
+};
+
+} // namespace ACELite
+} // namespace OHOS
+
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: websocket client interfaces
+ * Author: Software Group
+ * Create: 2025-10-20
+ */
+
+#ifndef WEBSOCKET_CLIENT_H
+#define WEBSOCKET_CLIENT_H
+
+#include "jsi.h"
+#include "net_websocket.h"
+#include "net_websocket_type.h"
+#include "websocket_common.h"
+
+namespace OHOS {
+namespace ACELite {
+
+enum WsDataType {
+ DATA_TYPE_STRING = 0,
+ DATA_TYPE_OBJECT = 1,
+ DATA_TYPE_ARRAY_BUFFER = 2
+};
+
+struct WsHandler {
+ JSIValue send;
+ JSIValue sendInit;
+ JSIValue sendUpdate;
+ JSIValue sendFinish;
+ JSIValue connect;
+ JSIValue close;
+ JSIValue destroy;
+ JSIValue on;
+ JSIValue off;
+};
+
+class WsModuleClient final : public MemoryHeap {
+public:
+ WsModuleClient();
+ ~WsModuleClient();
+
+ int GetClientId(void) const
+ {
+ return clientId_;
+ }
+
+ int Connect(const char *url, const char *option);
+ int Send(const char *data, size_t length, WsDataType dataType);
+ int SendInit(uint32_t size);
+ int SendUpdate(const char *data, size_t length);
+ int SendFinish(const char *data, size_t length, WsDataType dataType);
+ int Close(void);
+ static int GetErrorCode(int8_t errorCode);
+
+ WsHandler handler_;
+ JSIValue context_;
+ JSIValue WsEvents_[WS_EVENT_MAX];
+private:
+ void ReleaseJSIValue(JSIValue value)
+ {
+ if (!JSI::ValueIsUndefined(value)) {
+ JSI::ReleaseValue(value);
+ }
+ }
+
+ int SendBinary(const char *data, size_t bufferSize);
+
+ static const uint32_t WS_MAX_DATA_LENGTH = 20 * 1024;
+ static const uint32_t WS_MAX_SEND_LENGTH = 100 * 1024;
+ int clientId_ = -1;
+ char *msgBuffer_ = nullptr;
+ uint32_t bufferSize_ = 0;
+ uint32_t dataSize_ = 0;
+
+};
+
+} // namespace ACELite
+} // namespace OHOS
+
+#endif // WEBSOCKET_CLIENT_H
\ No newline at end of file
namespace OHOS {
namespace ACELite {
+int8_t GetStateMachineInfo();
+
class Router final : public MemoryHeap {
public:
ACE_DISALLOW_COPY_AND_MOVE(Router);
static JSIValue Stop(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
\r
/**\r
- handle exception\r
+ * Start\r
+ * Start XiaoduVoice when args[0] == "XiaoduVoice", no input param\r
+ * Start AudioCaptruer otherwise\r
+ * @inputparam args, include properties buffersize, format, etc\r
*/\r
- static void ExceptionStop(void);\r
+ static JSIValue start(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+\r
+ /**\r
+ * Stop\r
+ */\r
+ static JSIValue stop(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+\r
+ /**\r
+ * ListenerOn\r
+ * @inputparam args, include properties success, fail\r
+ */\r
+ static JSIValue ListenerOn(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
\r
/**\r
* Cancel\r
*/\r
static JSIValue Cancel(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+ /**\r
+ * ListenerOff\r
+ */\r
+ static JSIValue ListenerOff(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+\r
+ /**\r
+ handle exception\r
+ */\r
+ static void ExceptionStop(void);\r
+ static void OnDestroy(void);\r
+ static void OnTerminate(void);\r
};\r
\r
void InitAudioCapturerModule(JSIValue exports);\r
class PlayerCallback {\r
public:\r
enum PlayerInfoType : int32_t {\r
- /** Pushed the first video frame for rendering */\r
- PLAYER_INFO_RENDER_START = 0,\r
+ PLAYER_INFO_PLAY_START = 0,\r
+ PLAYER_INFO_PLAYING,\r
+ PLAYER_INFO_PLAY_END,\r
+ PLAYER_INFO_SEEK_START,\r
+ PLAYER_INFO_SEEK_END,\r
+ PLAYER_INFO_STOPPED,\r
+ PLAYER_INFO_PAUSED,\r
+ PLAYER_INFO_BUTT,\r
};\r
\r
enum PlayerErrorType : int32_t {\r
};\r
\r
enum PlayerErrorCode : int32_t {\r
- PLAYER_ERROR_CODE_VID_PLAY_FAIL = 0x0, /* The video fails to be played. */\r
+ PLAYER_ERROR_CODE_VID_PLAY_FAIL = 0, /* The video fails to be played. */\r
PLAYER_ERROR_CODE_AUD_PLAY_FAIL, /* The audio fails to be played. */\r
PLAYER_ERROR_CODE_DEMUX_FAIL, /* The file fails to be played. */\r
PLAYER_ERROR_CODE_TIMEOUT, /* Operation timeout. For example, reading data timeout. */\r
PLAYER_ERROR_CODE_NOT_SUPPORT, /* The file format is not supportted. */\r
- PLAYER_ERROR_CODE_UNKNOW, /* Unknown error. */\r
PLAYER_ERROR_CODE_ILLEGAL_STATEACTION, /* illegal action at cur state. */\r
+ PLAYER_ERROR_CODE_UNKNOWN, /* Unknown error. */\r
PLAYER_ERROR_CODE_BUTT,\r
};\r
\r
* @since 1.0\r
* @version 1.0\r
*/\r
- virtual void OnInfo(int type, int extra) = 0;\r
+ virtual void OnInfo(int32_t type, int32_t extra) = 0;\r
\r
/**\r
* @brief Called when the rewind is complete.\r
# @brief cmake file
# Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved.
#===============================================================================
+if("BRANDY_PRODUCT_EVB4" IN_LIST DEFINES OR "BRANDY_PRODUCT_EVB" IN_LIST DEFINES)
set(COMPONENT_NAME "lwip")
+else()
+set(COMPONENT_NAME "ohos_lwip")
+endif()
set(CMAKE_LWIP_SOURCE_DIR
${CMAKE_CURRENT_SOURCE_DIR}/lwip_v2.1.3)
set(LWIP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lwip_v2.1.3)
-if("liteos_207_1_0" IN_LIST TARGET_COMPONENT)
- set(CMAKE_LWIP_ADAPTER_DIR
- ${CMAKE_CURRENT_SOURCE_DIR}/lwip_adapter/liteos)
-elseif("liteos_207_0_0" IN_LIST TARGET_COMPONENT)
+if("__LITEOS__" IN_LIST DEFINES)
set(CMAKE_LWIP_ADAPTER_DIR
${CMAKE_CURRENT_SOURCE_DIR}/lwip_adapter/liteos)
elseif("freertos" IN_LIST TARGET_COMPONENT)
${CMAKE_CURRENT_SOURCE_DIR}/lwip_adapter/freertos)
endif()
-# PPP
-set(lwipppp_SRCS
- ${LWIP_DIR}/src/netif/ppp/auth.c
- ${LWIP_DIR}/src/netif/ppp/ccp.c
- ${LWIP_DIR}/src/netif/ppp/chap-md5.c
- ${LWIP_DIR}/src/netif/ppp/chap_ms.c
- ${LWIP_DIR}/src/netif/ppp/chap-new.c
- ${LWIP_DIR}/src/netif/ppp/demand.c
- ${LWIP_DIR}/src/netif/ppp/eap.c
- ${LWIP_DIR}/src/netif/ppp/ecp.c
- ${LWIP_DIR}/src/netif/ppp/eui64.c
- ${LWIP_DIR}/src/netif/ppp/fsm.c
- ${LWIP_DIR}/src/netif/ppp/ipcp.c
- ${LWIP_DIR}/src/netif/ppp/ipv6cp.c
- ${LWIP_DIR}/src/netif/ppp/lcp.c
- ${LWIP_DIR}/src/netif/ppp/magic.c
- ${LWIP_DIR}/src/netif/ppp/mppe.c
- ${LWIP_DIR}/src/netif/ppp/multilink.c
- ${LWIP_DIR}/src/netif/ppp/ppp.c
- ${LWIP_DIR}/src/netif/ppp/pppapi.c
- ${LWIP_DIR}/src/netif/ppp/pppcrypt.c
- ${LWIP_DIR}/src/netif/ppp/pppoe.c
- ${LWIP_DIR}/src/netif/ppp/pppol2tp.c
- ${LWIP_DIR}/src/netif/ppp/pppos.c
- ${LWIP_DIR}/src/netif/ppp/upap.c
- ${LWIP_DIR}/src/netif/ppp/utils.c
- ${LWIP_DIR}/src/netif/ppp/vj.c
- ${LWIP_DIR}/src/netif/ppp/polarssl/arc4.c
- ${LWIP_DIR}/src/netif/ppp/polarssl/des.c
- ${LWIP_DIR}/src/netif/ppp/polarssl/md4.c
- ${LWIP_DIR}/src/netif/ppp/polarssl/md5.c
- ${LWIP_DIR}/src/netif/ppp/polarssl/sha1.c
-)
-
set(SOURCES
${CMAKE_LWIP_SOURCE_DIR}/src/core/tcp_out.c
${CMAKE_LWIP_SOURCE_DIR}/src/core/inet_chksum.c
${CMAKE_LWIP_SOURCE_DIR}/src/api/api_lib.c
${CMAKE_LWIP_ADAPTER_DIR}/src/arch/sys_arch.c
${CMAKE_LWIP_ADAPTER_DIR}/src/arch/ethernetif.c
- ${CMAKE_LWIP_ADAPTER_DIR}/src/arch/sio.c
- ${CMAKE_LWIP_SOURCE_DIR}/src/netif/slipif.c
- ${CMAKE_LWIP_ADAPTER_DIR}/src/test/lwip_test.c
- ${CMAKE_LWIP_ADAPTER_DIR}/src/test/socket_test.c
- ${CMAKE_LWIP_ADAPTER_DIR}/src/test/slip_test.c
- ${CMAKE_CURRENT_SOURCE_DIR}/lwip_adapter/lwip_driver_adapter/lwip_driver_adapter.c
- ${lwipppp_SRCS}
)
if("__LITEOS__" IN_LIST DEFINES)
list(APPEND SOURCES
${ROOT_DIR}/open_source/mbedtls/mbedtls_v3.6.0/library/net_sockets.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/lwip_adapter/lwip_driver_adapter/lwip_net_manage.c
)
endif()
-
-
-
-
-
set(PUBLIC_HEADER
)
MBEDTLS_NET_C
)
+if("SUPPORT_BREDR" IN_LIST DEFINES AND "__LITEOS__" IN_LIST DEFINES)
+ list(APPEND SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/lwip_adapter/lwip_driver_adapter/lwip_driver_adapter.c
+ )
+endif()
# use this when you want to add ccflags like -include xxx
set(COMPONENT_PUBLIC_CCFLAGS
)
+if("BRANDY_PRODUCT_EVB4" IN_LIST DEFINES OR "BRANDY_PRODUCT_EVB" IN_LIST DEFINES)
+set(COMPONENT_CCFLAGS
+)
+else()
set(COMPONENT_CCFLAGS
+ -Wno-unused-but-set-variable
)
+endif()
if("__ALIOS__" IN_LIST DEFINES)
list(APPEND PRIVATE_HEADER
#define UNUSED(a) ((void)(a))
#endif
+struct sys_arch_thread {
+ void *arg;
+ u8_t *stackMem;
+ u32_t taskId;
+};
+
#define LWIP_SEM_ID(x) (u32_t)(uintptr_t)((x)->sem)
#define MBOX_EXPAND_MULTIPLE_SIZE 2
/* Lwip docs mentioned like wraparound is not a problem in this funtion */
return (u32_t)((LOS_TickCountGet() * 1000) / LOSCFG_BASE_CORE_TICK_PER_SECOND);
}
+
+void sys_thread_delete(void *param)
+{
+ if (param == NULL) {
+ return;
+ }
+ struct sys_arch_thread *threadCtl = (struct sys_arch_thread *)param;
+ LOS_TaskJoin(threadCtl->taskId, NULL);
+
+ if (threadCtl->stackMem != NULL) {
+ free(threadCtl->stackMem);
+ threadCtl->stackMem = NULL;
+ }
+ free(threadCtl);
+}
+
u32_t sys_jiffies(void)
{
/*sys_jiffies is the same as sys_now*/
return (u32_t)((LOS_TickCountGet() * 1000) / LOSCFG_BASE_CORE_TICK_PER_SECOND);
}
+
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio)
{
- TSK_INIT_PARAM_S task;
- UINT32 taskid, ret;
- (void)memset_s(&task, sizeof(task), 0, sizeof(task));
-
+ TSK_INIT_PARAM_S task = {0};
+ u32_t taskId, ret;
+#ifdef LOSCFG_TASK_STACK_STATIC_ALLOCATION
+ u8_t *stackMem = NULL;
+#endif
+ if (function == NULL) {
+ return 0;
+ }
+ struct sys_arch_thread *param = calloc(1, sizeof(struct sys_arch_thread));
+ if (param == NULL) {
+ return 0;
+ }
+ param->arg = arg;
/* Create host Task */
task.pfnTaskEntry = (TSK_ENTRY_FUNC)function;
task.uwStackSize = 3072; // 修改为3K=3072
task.pcName = (char *)name;
task.usTaskPrio = prio;
- task.uwResved = LOS_TASK_STATUS_DETACHED;
+ task.uwResved = LOS_TASK_STATUS_JOINABLE;
#ifdef BR_HW_LITEOS_VERSION
LOS_TASK_PARAM_INIT_ARG(task, arg);
#else
task.auwArgs[0] = (UINTPTR)arg;
#endif
- ret = LOS_TaskCreate(&taskid, &task);
+#ifdef LOSCFG_TASK_STACK_STATIC_ALLOCATION
+ stackMem = memalign(LOSCFG_STACK_POINT_ALIGN_SIZE, task.uwStackSize);
+ if (stackMem == NULL) {
+ LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: memalign fail\r\n"));
+ free(param);
+ return 0;
+ }
+ param->stackMem = stackMem;
+ ret = LOS_TaskCreateStatic(&taskId, &task, stackMem);
+#else
+ ret = LOS_TaskCreate(&taskId, &task);
+#endif
+ param->taskId = taskId;
if (ret != LOS_OK) {
LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: LOS_TaskCreate error %u\n", ret));
- return SYS_ARCH_ERROR;
+ free(stackMem);
+ free(param);
+ return 0;
}
(void)stacksize;
- return taskid;
+ return (uintptr_t)param;
}
#ifdef LWIP_DEBUG
#include <errno.h>
#include "asm/atomic.h"
+#include <sys/time.h>
#ifdef __cplusplus
extern "C" {
typedef struct sys_mbox *sys_mbox_t;
-typedef unsigned int sys_thread_t;
+typedef uintptr_t sys_thread_t;
#define sys_sem_valid(x) (((*x).sem == NULL) ? 0 : 1)
#define sys_sem_set_invalid(x) ((*x).sem = NULL)
#define TCP_SND_BUF (65535 / 3)
#endif
+/**
+ * TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least
+ * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work.
+ */
#ifndef TCP_SND_QUEUELEN
-#define TCP_SND_QUEUELEN (TCP_SND_BUF / TCP_MSS)
+#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
#endif
#ifndef TCP_WND
#endif
#ifndef MEMP_NUM_NETDB
-#define MEMP_NUM_NETDB 1
+#define MEMP_NUM_NETDB 8
#endif
#ifndef DNS_TABLE_SIZE
-#define DNS_TABLE_SIZE 2
+#define DNS_TABLE_SIZE 8
#endif
#ifndef DNS_MAX_IPADDR
#define IP_REASSEMBLY 1
#endif
+#if IP_REASSEMBLY
+/* The IP reassembly timer interval in milliseconds. */
+#ifndef IP_TMR_INTERVAL
+#define IP_TMR_INTERVAL 2000
+#endif
+#endif
+
#ifndef LWIP_RPL
#define LWIP_RPL 0
#endif
#define TCP_OOSEQ_MAX_PBUFS 8
#endif
+/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
+ * by your system, set this to 0 and include <sys/time.h> in cc.h */
+#ifndef LWIP_TIMEVAL_PRIVATE
+#define LWIP_TIMEVAL_PRIVATE 0
+#endif
/**
* NO_SYS==1: Provides very minimal functionality. Otherwise,
*/
#ifndef LWIP_NUM_SOCKETS
-/**
- * DEFAULT_LWIP_NUM_SOCKETS is default number of sockets.
- */
-#ifndef DEFAULT_LWIP_NUM_SOCKETS
-#define DEFAULT_LWIP_NUM_SOCKETS 8
-#endif /* DEFAULT_LWIP_NUM_SOCKETS */
-
#else /* else LWIP_NUM_SOCKETS*/
#ifndef DEFAULT_LWIP_NUM_SOCKETS
/* @ingroup Config_TCP
* Defines the TCP TTL value.
*/
+#if LWIP_TCP
+#ifndef TCP_TMR_INTERVAL
+#define TCP_TMR_INTERVAL 2000 /* The TCP timer interval in milliseconds. */
+#endif /* TCP_TMR_INTERVAL */
+#endif
+
#ifndef TCP_TTL
#define TCP_TTL 255
#endif
#define LWIP_ARP 1
#endif
+#if LWIP_ARP
+#ifndef ARP_TMR_INTERVAL
+#define ARP_TMR_INTERVAL 2000
+#endif
+#endif
+
/**
* Defines the mailbox size for the tcpip thread messages
* The queue size value itself is platform-dependent, but is passed to
/* ---------- IGMP options ---------- */
#ifndef LWIP_IGMP
-#define LWIP_IGMP 1
+#define LWIP_IGMP 0
+#endif
+
+#if LWIP_IPV6
+#ifndef ND6_TMR_INTERVAL
+#define ND6_TMR_INTERVAL 2000
+#endif
+
+#ifndef MLD6_TMR_INTERVAL
+#define MLD6_TMR_INTERVAL 2000 /* Milliseconds */
+#endif
+
+/** The IPv6 reassembly timer interval in milliseconds. */
+#ifndef IP6_REASS_TMR_INTERVAL
+#define IP6_REASS_TMR_INTERVAL 2000
+#endif
+
+#endif
+
+/* IGMP timer */
+#if LWIP_IGMP
+#ifndef IGMP_TMR_INTERVAL
+#define IGMP_TMR_INTERVAL 2000 /* Milliseconds */
+#endif
+
+#ifndef IGMP_V1_DELAYING_MEMBER_TMR
+#define IGMP_V1_DELAYING_MEMBER_TMR 10
+#endif
+
+#ifndef IGMP_JOIN_DELAYING_MEMBER_TMR
+#define IGMP_JOIN_DELAYING_MEMBER_TMR 5
+#endif
#endif
/* ---------- DHCP options ---------- */
#define LWIP_DHCP 1
#endif
+#if LWIP_DHCP
+/** period (in milliseconds) of the application calling dhcp_fine_tmr() */
+#ifndef DHCP_FINE_TIMER_MSECS
+#define DHCP_FINE_TIMER_MSECS 2000
+#endif
+#endif
/* ---------- DNS options ---------- */
/**
* LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS
#ifndef LWIP_DNS_REVERSE
#define LWIP_DNS_REVERSE 1
#endif
+/** DNS timer period */
+#ifndef DNS_TMR_INTERVAL
+#define DNS_TMR_INTERVAL 3000
+#endif
#else
#undef LWIP_DNS_REVERSE
#define LWIP_DNS_REVERSE 0
#if !defined DNS_MAX_RETRIES && LWIP_SMALL_SIZE
#define DNS_MAX_RETRIES 2
+
+/** period (in milliseconds) of the application calling dhcp6_tmr() */
+#if LWIP_IPV6_DHCP6
+#ifndef DHCP6_TIMER_MSECS
+#define DHCP6_TIMER_MSECS 2000
+#endif
+#endif
+
#endif
/* ---------- UDP options ---------- */
/* -----------LOOPIF options -----------*/
#ifndef LWIP_HAVE_LOOPIF
-#define LWIP_HAVE_LOOPIF 1
+#define LWIP_HAVE_LOOPIF 0
#endif
/* -----------LOOPBACK options -----------*/
#ifndef LWIP_NETIF_LOOPBACK
-#define LWIP_NETIF_LOOPBACK 1
+#define LWIP_NETIF_LOOPBACK 0
#endif
-/* ---------- Statistics options ---------- */
-/**
- * LWIP_STATS==1: Enables statistics gathering in lwip_stats.
- */
-#ifndef LWIP_STATS
-#define LWIP_STATS 1
-#endif
-/* ---------- TFTP options ---------- */
-#ifndef LWIP_TFTP
-#define LWIP_TFTP 1
-#endif
-
-/* ---------- SNTP options ---------- */
-#ifndef LWIP_SNTP
-#define LWIP_SNTP 1
-#endif
#if LWIP_SNTP
#if LWIP_LITEOS_COMPAT
#ifndef TCPIP_THREAD_STACKSIZE
-#define TCPIP_THREAD_STACKSIZE 0x6000
+#define TCPIP_THREAD_STACKSIZE 0x1000
#endif
#ifndef TCPIP_THREAD_PRIO
-#define TCPIP_THREAD_PRIO 5
+#define TCPIP_THREAD_PRIO 24
#endif
#ifndef LWIP_SOCKET_START_NUM
#endif
#endif
-#ifndef LWIP_IPV6_MLD
-#define LWIP_IPV6_MLD 1
-#endif
-
#ifndef LWIP_MLD6_ENABLE_MLD_ON_DAD
#define LWIP_MLD6_ENABLE_MLD_ON_DAD LWIP_IPV6 && LWIP_IPV6_MLD
#endif
#include "lwip_driver_adapter.h"
#include "lwip/tcpip.h"
+#include "lwip/etharp.h"
#include "lwip/netifapi.h"
#include "lwip/arch.h"
-#ifdef SUPPORT_BREDR
#include "bts_pan.h"
#include "bts_br_gap.h"
+
+#define LWIP_ADAPTER_DEBUG
+#ifdef LWIP_ADAPTER_DEBUG
+#define LWIP_DEBUG_LOG(message) LWIP_PLATFORM_DIAG(message)
+#else
+#define LWIP_DEBUG_LOG(message)
#endif
+#define PAN_LOW_POWER
+
+static struct netif *g_bt_pan_netif = NULL;
+static net_connection_callback g_bt_pan_callback = NULL;
+static uint8_t g_pan_net_state = CONNECTION_UNKNOWN;
-#ifdef SUPPORT_BREDR
-static struct netif *bt_pan_netif = NULL;
+#ifndef PAN_LOW_POWER
+typedef struct {
+ uint8_t thread_run;
+ uint8_t end_thread;
+ sys_sem_t pan_sem;
+ void *param;
+} thread_ctl;
+
+static thread_ctl g_pan_thread = {0};
#endif
+
+#define BTPAN_THREAD_NAME "bt_pan_listen"
+#define BTPAN_THREAD_STACKSIZE 0xc00
+#define BTPAN_THREAD_PRIO 30
+#define BTPAN_MAX_PAIRED_DEVICES 5
+#define DEVICE_MAJOR_CLASS_PHONE 0x200 /* 手机设备COD:Major Device Class = phone */
+
static err_t lwip_driver_output(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr);
static err_t lwip_netif_linkout(struct netif *netif, struct pbuf *p)
{
+ (void)netif;
if (p == NULL || p->payload == NULL) {
return ERR_ARG;
}
payload += SIZEOF_ETH_HDR;
p->len -= SIZEOF_ETH_HDR;
}
-#ifdef SUPPORT_BREDR
pan_service_write_data(payload, p->len, PAN_NETWORK_PROTOCOL_ARP, PAN_PACKET_TYPE_DEST_ONLY_UNICAST);
-#endif
return ERR_OK;
}
static err_t lwip_driver_init_fn(struct netif *netif_p)
{
+ if (netif_p == NULL) {
+ return ERR_ARG;
+ }
netif_p->output = lwip_driver_output;
netif_p->linkoutput = lwip_netif_linkout;
netifapi_netif_set_up(netif_p);
netifapi_netif_set_link_up(netif_p);
+ netifapi_netif_set_default(netif_p);
netif_p->mtu = 1000; /* 1000: mtu */
return ERR_OK;
static struct netif *lwip_driver_init_netif(const char *name, const unsigned char *hw_addr)
{
struct netif *netif = (struct netif *)malloc(sizeof(struct netif));
-#if LWIP_IPV4
- ip4_addr_t ipaddr, netmask, gw;
-
- IP4_ADDR(&gw, 192, 168, 44, 1); /* 192 168 44 1 : default gw addr */
- IP4_ADDR(&ipaddr, 192, 168, 44, 66); /* 192 168 44 66 : default ip addr */
- IP4_ADDR(&netmask, 255, 255, 255, 0); /* 255 0 : default netmask */
-#endif
if (netif == NULL) {
return NULL;
return NULL;
}
netif->hwaddr_len = NETIF_MAX_HWADDR_LEN;
- netifapi_netif_add(netif,
-#if LWIP_IPV4
- &ipaddr,
- &netmask,
- &gw,
-#endif
- NULL,
- lwip_driver_init_fn,
- tcpip_input);
- netif_set_default(netif);
+ netifapi_netif_add(netif, NULL, NULL, NULL, NULL, lwip_driver_init_fn, tcpip_input);
return netif;
}
if (netif == NULL || p == NULL || ipaddr == NULL) {
return ERR_ARG;
}
-#ifdef SUPPORT_BREDR
+
+ uint8_t *payload = NULL;
+ struct pbuf *p_clone = NULL;
+ if (p->tot_len > p->len && p->next != NULL) {
+ p_clone = pbuf_clone(PBUF_RAW, PBUF_RAM, p); /* packet queue copy to one packet */
+ if (p_clone == NULL) {
+ return ERR_MEM;
+ }
+ payload = p_clone->payload;
+ } else {
+ payload = p->payload;
+ }
if (ip4_addr_isbroadcast(ipaddr, netif)) {
- pan_service_write_data(p->payload, p->len, PAN_NETWORK_PROTOCOL_IPV4, PAN_PACKET_TYPE_DEST_ONLY_BORADCAST);
+ pan_service_write_data(payload, p->tot_len, PAN_NETWORK_PROTOCOL_IPV4, PAN_PACKET_TYPE_DEST_ONLY_BORADCAST);
} else {
- pan_service_write_data(p->payload, p->len, PAN_NETWORK_PROTOCOL_IPV4, PAN_PACKET_TYPE_DEST_ONLY_UNICAST);
+ pan_service_write_data(payload, p->tot_len, PAN_NETWORK_PROTOCOL_IPV4, PAN_PACKET_TYPE_DEST_ONLY_UNICAST);
+ }
+ if (p_clone != NULL) {
+ pbuf_free(p_clone);
}
-#endif
return ERR_OK;
}
-#ifdef SUPPORT_BREDR
-static void sample_pan_net_state_callback(uint8_t net_state)
+static void bt_pan_net_state_callback(uint8_t net_state)
{
- printf("sample pan net_state=%u\n", net_state);
+ struct netif *netif_p = g_bt_pan_netif;
+ if (netif_p == NULL) {
+ return;
+ }
if (net_state == 1) {
+ netifapi_netif_set_link_up(netif_p);
+ netifapi_netif_set_up(netif_p);
#if defined(LWIP_DHCP) && LWIP_DHCP
- netifapi_dhcp_start(bt_pan_netif);
- printf("dhcp start\n");
+ netifapi_dhcp_start(netif_p);
+#endif
+ } else {
+ netifapi_netif_set_link_down(netif_p);
+ netifapi_netif_set_down(netif_p);
+#if LWIP_IPV4
+ ip_addr_set_zero_ip4(&netif_p->ip_addr);
+ ip_addr_set_zero_ip4(&netif_p->netmask);
+ ip_addr_set_zero_ip4(&netif_p->gw);
+#endif
+#ifndef PAN_LOW_POWER
+ sys_sem_signal(&g_pan_thread.pan_sem);
#endif
}
}
}
#endif
-static void sample_pan_rpt_ethernet(uint8_t *packet, uint16_t packet_length, uint16_t network_protocol)
+static void bt_pan_rpt_ethernet(uint8_t *packet, uint16_t packet_length, uint16_t network_protocol)
{
int ret = ERR_OK;
+ struct netif *netif_p = g_bt_pan_netif;
+ if (netif_p == NULL) {
+ return;
+ }
if (network_protocol == PAN_NETWORK_PROTOCOL_ARP) {
#if defined(LWIP_IPV4) && LWIP_IPV4 && defined(LWIP_ARP) && LWIP_ARP
- ret = lwip_input_arp(packet, packet_length, bt_pan_netif);
+ ret = lwip_input_arp(packet, packet_length, netif_p);
#endif
} else if (network_protocol == PAN_NETWORK_PROTOCOL_IPV4) {
- ret = lwip_driver_input(packet, packet_length, bt_pan_netif);
+ ret = lwip_driver_input(packet, packet_length, netif_p);
} else {
return;
}
if (ret != 0) {
- printf("pan receive packet fail, ret=0x%x\n", ret);
+ LWIP_DEBUG_LOG(("pan receive packet fail, ret=0x%x\n", ret));
}
}
-static pan_callbacks_t g_sample_pan_callbacks_t = {sample_pan_net_state_callback, sample_pan_rpt_ethernet};
+static pan_callbacks_t g_bt_pan_callbacks_t = {bt_pan_net_state_callback, bt_pan_rpt_ethernet};
/* mac addr to big-endian */
static void mac_addr_hton(uint8_t *data)
data[3] = temp; /* 3 : byte index */
}
-static void lwip_register_bt_netif(void)
+static void init_register_bt_netif(void)
{
- unsigned char local_addr[6]; /* 6: mac addr length */
+#if defined(BRANDY_PRODUCT_EVB4) || defined(BRANDY_PRODUCT_EVB)
+ unsigned char local_addr[6]; /* 6: mac addr length */
bluetooth_get_local_addr(local_addr, 6); /* 6: mac addr length */
mac_addr_hton(local_addr);
- if (bt_pan_netif != NULL) {
+#else
+ bd_addr_t local_addr = {0};
+ bluetooth_get_local_addr(&local_addr);
+ mac_addr_hton(local_addr.addr);
+#endif
+ if (g_bt_pan_netif != NULL) {
return;
}
- bt_pan_netif = lwip_driver_init_netif("bt", local_addr);
- if (bt_pan_netif == NULL) {
- printf("sample pan init lwip fail\n");
+#if defined(BRANDY_PRODUCT_EVB4) || defined(BRANDY_PRODUCT_EVB)
+ g_bt_pan_netif = lwip_driver_init_netif("bt", local_addr);
+#else
+ g_bt_pan_netif = lwip_driver_init_netif("bt", local_addr.addr);
+#endif
+ if (g_bt_pan_netif == NULL) {
+ LWIP_DEBUG_LOG(("bt pan init lwip fail\n"));
}
}
-void bt_pan_open(void)
+static int bt_pan_get_paired_device(bd_addr_t *addr)
{
- int result;
- bool ret;
- gap_paired_device_info_t dev_info[1] = {0};
- int number = 1;
- lwip_register_bt_netif();
- ret = gap_get_paired_devices_list(dev_info, &number);
- if (ret) {
- printf("get bt dev info ok\n");
+ int index = 0;
+ int number = BTPAN_MAX_PAIRED_DEVICES;
+#if defined(BRANDY_PRODUCT_EVB4) || defined(BRANDY_PRODUCT_EVB)
+ gap_paired_device_info_t dev_info[BTPAN_MAX_PAIRED_DEVICES] = {0};
+#else
+ gap_remote_device_info_t dev_info[BTPAN_MAX_PAIRED_DEVICES] = {0};
+#endif
+#if defined(BRANDY_PRODUCT_EVB4) || defined(BRANDY_PRODUCT_EVB)
+ if (!gap_get_paired_devices_list(dev_info, &number)) {
+ LWIP_DEBUG_LOG(("get bt dev info fail\n"));
+ return -1;
+ }
+#else
+ if (gap_br_get_paired_devices_list(dev_info, &number) != ERRCODE_BT_SUCCESS) {
+ LWIP_DEBUG_LOG(("get bt dev info fail\n"));
+ return -1;
+ }
+#endif
+ for (index = 0; index < BTPAN_MAX_PAIRED_DEVICES; index++) {
+#if defined(BRANDY_PRODUCT_EVB4) || defined(BRANDY_PRODUCT_EVB)
+ if ((gap_get_device_class(&dev_info[index].addr) & DEVICE_MAJOR_CLASS_PHONE) != 0) {
+ break;
+ }
+#else
+ if((dev_info[index].device_class & DEVICE_MAJOR_CLASS_PHONE) != 0) {
+ break;
+ }
+#endif
+ }
+ if (index >= BTPAN_MAX_PAIRED_DEVICES) {
+ LWIP_DEBUG_LOG(("Not find paired phone\n"));
+ return -1;
+ }
+ if (memcpy_s(addr, sizeof(bd_addr_t), &dev_info[index].addr, sizeof(bd_addr_t)) != 0) {
+ return -1;
+ }
+ return 0;
+}
+
+#if defined(PAN_LOW_POWER)
+static int bt_pan_open_service(void)
+{
+ bd_addr_t addr;
+ int ret;
+ ret = bt_pan_get_paired_device(&addr);
+ if (ret != 0) {
+ LWIP_DEBUG_LOG(("bt_pan_get_paired_device fail\n"));
+ return ret;
+ }
+ ret = pan_service_open(&addr);
+ if (ret == 0) {
+ LWIP_DEBUG_LOG(("pan_service_open ok\n"));
} else {
- printf("get bt dev info fail\n");
+ LWIP_DEBUG_LOG(("pan_service_open fail, ret=0x%x\n", ret));
+ }
+ return ret;
+}
+
+#else
+static void bt_pan_thread(void *arg)
+{
+ bd_addr_t addr;
+ int ret;
+ thread_ctl *thread = (thread_ctl *)arg;
+ if (thread == NULL) {
return;
}
- result = pan_register_callbacks(&g_sample_pan_callbacks_t);
- if (result == 0) {
- printf("pan register callbacks ok\n");
- } else {
- printf("pan register fail\n");
+ thread->thread_run = 1;
+ sys_sem_new(&thread->pan_sem, 0);
+
+ while (thread->end_thread == 0) {
+ ret = bt_pan_get_paired_device(&addr);
+ if (ret != 0) {
+ LWIP_DEBUG_LOG(("bt_pan_get_paired_device fail\n"));
+ break;
+ }
+ if (pan_service_open(&addr) == 0) {
+ sys_arch_sem_wait(&thread->pan_sem, 0);
+ pan_service_close(&addr);
+ } else {
+ break;
+ }
+ if (thread->end_thread) {
+ break;
+ }
+ sleep(30); /* 30 : sleep 30s */
+ }
+ sys_sem_free(&thread->pan_sem);
+ thread->thread_run = 0;
+ thread->end_thread = 0;
+}
+#endif
+
+void bt_pan_close(void)
+{
+ int ret;
+ bd_addr_t addr;
+ struct netif *netif_p = g_bt_pan_netif;
+ if (netif_p == NULL) {
return;
}
+ pan_deregister_callbacks();
+#ifndef PAN_LOW_POWER
+ if (g_pan_thread.thread_run == 1) {
+ g_pan_thread.end_thread = 1;
+ sys_sem_signal(&g_pan_thread.pan_sem);
+ }
- result = pan_service_open(&dev_info[0].addr);
+ if (g_pan_thread.param != NULL) {
+ sys_thread_delete(g_pan_thread.param);
+ g_pan_thread.param = NULL;
+ }
+#endif
+ netifapi_netif_set_link_down(netif_p);
+ netifapi_netif_set_down(netif_p);
+ netifapi_netif_remove(netif_p);
+
+ free(netif_p);
+ g_bt_pan_netif = NULL;
+ g_pan_net_state = CONNECTION_DISCONNECTED;
+
+ ret = bt_pan_get_paired_device(&addr);
+ if (ret != 0) {
+ return;
+ }
+ pan_service_close(&addr);
+}
+
+void bt_pan_open(void)
+{
+ int result;
+
+ init_register_bt_netif();
+
+ result = pan_register_callbacks(&g_bt_pan_callbacks_t);
if (result == 0) {
- printf("pan_service_open ok\n");
+ LWIP_DEBUG_LOG(("pan register callbacks ok\n"));
} else {
- printf("pan_service_open fail\n");
+ bt_pan_close();
+ LWIP_DEBUG_LOG(("pan register fail\n"));
+ return;
}
+#ifdef PAN_LOW_POWER
+ result = bt_pan_open_service();
+ if (result != 0) {
+ bt_pan_close();
+ }
+#else
+ if (g_pan_thread.thread_run == 0) {
+ g_pan_thread.end_thread = 0;
+ g_pan_thread.param =
+ (void *)sys_thread_new(BTPAN_THREAD_NAME, bt_pan_thread, &g_pan_thread, BTPAN_THREAD_STACKSIZE, BTPAN_THREAD_PRIO);
+ if (g_pan_thread.param == NULL) {
+ LWIP_DEBUG_LOG(("bt pan thread create fail\n"));
+ }
+ }
+#endif
}
-#endif /* SUPPORT_BREDR */
\ No newline at end of file
+
+uint8_t pan_get_net_state(void)
+{
+ return g_pan_net_state;
+}
+
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+static netif_ext_callback_t g_netif_ext_callback;
+
+static void pan_net_callback(struct netif *netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t *args)
+{
+ if (netif != g_bt_pan_netif) {
+ return;
+ }
+
+ if ((reason & LWIP_NSC_IPV4_ADDRESS_CHANGED || reason & LWIP_NSC_IPV6_SET) &&
+ g_pan_net_state != CONNECTION_CONNECTED) {
+ g_pan_net_state = CONNECTION_CONNECTED;
+ if (g_bt_pan_callback != NULL) {
+ LWIP_DEBUG_LOG(("pan CONNECTION_CONNECTED\n"));
+ g_bt_pan_callback(LWIP_NETIF_BT_PAN, CONNECTION_CONNECTED);
+ }
+ }
+
+ if (reason & LWIP_NSC_STATUS_CHANGED && args->status_changed.state == 0 &&
+ g_pan_net_state != CONNECTION_DISCONNECTED) {
+ g_pan_net_state = CONNECTION_DISCONNECTED;
+ if (g_bt_pan_callback != NULL) {
+ LWIP_DEBUG_LOG(("pan CONNECTION_DISCONNECTED\n"));
+ g_bt_pan_callback(LWIP_NETIF_BT_PAN, CONNECTION_DISCONNECTED);
+ }
+ }
+}
+
+void bt_pan_register_net_callback(net_connection_callback callback)
+{
+ if (g_bt_pan_callback != NULL) {
+ return;
+ }
+ g_bt_pan_callback = callback;
+ netif_add_ext_callback(&g_netif_ext_callback, pan_net_callback);
+}
+
+void bt_pan_unregister_net_callback(void)
+{
+ g_bt_pan_callback = NULL;
+ netif_remove_ext_callback(&g_netif_ext_callback);
+}
+#else
+void bt_pan_register_net_callback(net_connection_callback callback)
+{
+ (void)callback;
+}
+
+void bt_pan_unregister_net_callback(void)
+{}
+#endif
\ No newline at end of file
/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * Copyright (c) CompanyNameMagicTag 2023-2023. All rights reserved.
+ * Description: extend functions
*/
-#ifndef LWIP_DRIVER_ADAPTER_H
-#define LWIP_DRIVER_ADAPTER_H
+#ifndef INCLUDE_LWIP_PUBLIC_H
+#define INCLUDE_LWIP_PUBLIC_H
+
+#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
-#ifdef SUPPORT_BREDR
-void bt_pan_open(void);
-#endif
+typedef enum {
+ /* 4g Cat1 netif */
+ LWIP_NETIF_VOLTE = 0,
+ /* bluetooth BT PAN netif */
+ LWIP_NETIF_BT_PAN = 1,
+ /* NULL netif */
+ LWIP_NETIF_NONE
+} lwip_netif_type;
+
+typedef enum {
+ CONNECTION_CONNECTING = 0,
+ CONNECTION_CONNECTED = 1,
+
+ CONNECTION_DISCONNECTING = 2,
+ CONNECTION_DISCONNECTED = 3,
+
+ CONNECTION_UNKNOWN = 100
+} lwip_net_connection_state;
+
+/**
+ * @brief Defines the callback function net connection status change.
+ *
+ * @param netif_type net if type, refer to #lwip_netif_type.
+ * @param net_connect_state net connection status, refer to #lwip_net_connection_state.
+ */
+typedef void (*net_connection_callback)(const uint8_t netif_type, const uint8_t net_connect_state);
+
+/**
+ * @brief This function register network connection status listener.
+ * @param[in] conn_listener net_connection_callback.
+ * @return 0 if success; non-0 otherwise.
+ */
+int lwip_register_connect_listener(net_connection_callback conn_listener);
+
+/**
+ * @brief Defines the callback unregister function for listening net connection status change.
+ */
+void lwip_unregister_connect_listener(net_connection_callback conn_listener);
+
+/**
+ * @brief This function get current network connection status.
+ * @param[in] netif_type netif type, refer to #lwip_netif_type.
+ * @param[in, out] net_connect_state network connection statue, refer to #lwip_net_connection_state.
+ * @return 0 if success; non-0 otherwise.
+ */
+int lwip_get_connect_status(uint8_t netif_type, uint8_t *net_connect_state);
+
+/**
+ * @brief init and open bt pan net interface.
+ */
+void lwip_open_bt_pan(void);
+
+/**
+ * @brief close bt pan net interface.
+ */
+void lwip_close_bt_pan(void);
#ifdef __cplusplus
}
--- /dev/null
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ */
+
+#include <stddef.h>
+
+#include "lwip_driver_adapter.h"
+
+#if defined(SUPPORT_VOLTE)
+static lwip_netif_type g_netif_state = LWIP_NETIF_VOLTE;
+#elif defined(SUPPORT_BREDR)
+static lwip_netif_type g_netif_state = LWIP_NETIF_BT_PAN;
+#else
+static lwip_netif_type g_netif_state = LWIP_NETIF_NONE;
+#endif
+
+typedef struct net_status_callback_t {
+ net_connection_callback callback_fn;
+ struct net_status_callback_t *next;
+} net_status_callback_t;
+
+static net_status_callback_t g_head_callback = {0};
+static uint8_t g_net_is_register = 0;
+
+static void net_status_litener(const uint8_t netif_type, const uint8_t net_connect_state)
+{}
+
+void lwip_netif_switch_volte(void)
+{
+#if defined(SUPPORT_VOLTE) && defined(SUPPORT_BREDR)
+ if (g_netif_state == LWIP_NETIF_VOLTE) {
+ return;
+ }
+ if (g_net_is_register == 0) {
+ lwip_register_connect_listener(net_status_litener);
+ g_net_is_register = 1;
+ }
+ bt_pan_close();
+ cat1_open_inner();
+ g_netif_state = LWIP_NETIF_VOLTE;
+#endif
+}
+
+void lwip_netif_switch_bt_pan(void)
+{
+#if defined(SUPPORT_VOLTE) && defined(SUPPORT_BREDR)
+ if (g_netif_state == LWIP_NETIF_BT_PAN) {
+ return;
+ }
+ if (g_net_is_register == 0) {
+ lwip_register_connect_listener(net_status_litener);
+ g_net_is_register = 1;
+ }
+ cat1_close_inner();
+ bt_pan_open();
+ g_netif_state = LWIP_NETIF_BT_PAN;
+#endif
+}
+
+void lwip_open_bt_pan(void)
+{
+#if defined(SUPPORT_BREDR)
+ if (g_netif_state != LWIP_NETIF_BT_PAN) {
+ return;
+ }
+ if (g_net_is_register == 0) {
+ lwip_register_connect_listener(net_status_litener);
+ g_net_is_register = 1;
+ }
+ bt_pan_open();
+#endif
+}
+
+void lwip_close_bt_pan(void)
+{
+#if defined(SUPPORT_BREDR)
+ if (g_netif_state != LWIP_NETIF_BT_PAN) {
+ return;
+ }
+ if (g_net_is_register) {
+ lwip_unregister_connect_listener(net_status_litener);
+ g_net_is_register = 0;
+ }
+ bt_pan_close();
+#endif
+}
+
+void lwip_cat1_open(void)
+{
+#if defined(SUPPORT_VOLTE)
+ if (g_netif_state != LWIP_NETIF_VOLTE) {
+ return;
+ }
+ if (g_net_is_register == 0) {
+ lwip_register_connect_listener(net_status_litener);
+ g_net_is_register = 1;
+ }
+ cat1_open_inner();
+#endif
+}
+
+void lwip_cat1_close(void)
+{
+#if defined(SUPPORT_VOLTE)
+ if (g_netif_state != LWIP_NETIF_VOLTE) {
+ return;
+ }
+ if (g_net_is_register) {
+ lwip_unregister_connect_listener(net_status_litener);
+ g_net_is_register = 0;
+ }
+ cat1_close_inner();
+#endif
+}
+
+int lwip_get_connect_status(uint8_t netif_type, uint8_t *net_connect_state)
+{
+ if (g_netif_state != netif_type) {
+ *net_connect_state = CONNECTION_DISCONNECTED;
+ return 0;
+ }
+#if defined(SUPPORT_VOLTE)
+ if (netif_type == LWIP_NETIF_VOLTE) {
+ *net_connect_state = cat1_get_net_state();
+ return 0;
+ }
+#endif
+#if defined(SUPPORT_BREDR)
+ if (netif_type == LWIP_NETIF_BT_PAN) {
+ *net_connect_state = pan_get_net_state();
+ return 0;
+ }
+#endif
+ return -1;
+}
+
+static void lwip_net_conn_callback(const uint8_t netif_type, const uint8_t net_connect_state)
+{
+ net_status_callback_t *iter_node = &g_head_callback;
+ while (iter_node != NULL) {
+ if (iter_node->callback_fn != NULL) {
+ iter_node->callback_fn(netif_type, net_connect_state);
+ }
+ iter_node = iter_node->next;
+ }
+}
+
+int lwip_register_connect_listener(net_connection_callback callback)
+{
+ net_status_callback_t *iter_node = &g_head_callback;
+ if (callback == NULL) {
+ return -1;
+ }
+#if defined(SUPPORT_VOLTE)
+ cat1_register_net_callback(lwip_net_conn_callback);
+#endif
+#if defined(SUPPORT_BREDR)
+ bt_pan_register_net_callback(lwip_net_conn_callback);
+#endif
+ if (g_head_callback.callback_fn == NULL) {
+ g_head_callback.callback_fn = callback;
+ return 0;
+ }
+ net_status_callback_t *ext_call_node = (net_status_callback_t *)malloc(sizeof(net_status_callback_t));
+ if (ext_call_node == NULL) {
+ return -1;
+ }
+ (void)memset_s(ext_call_node, sizeof(net_status_callback_t), 0, sizeof(net_status_callback_t));
+ ext_call_node->callback_fn = callback;
+
+ while (iter_node != NULL) {
+ if (iter_node->callback_fn == callback) {
+ free(ext_call_node);
+ return 0;
+ }
+ if (iter_node->next == NULL) {
+ iter_node->next = ext_call_node;
+ return 0;
+ }
+ iter_node = iter_node->next;
+ }
+ return 0;
+}
+
+void lwip_unregister_connect_listener(net_connection_callback callback)
+{
+ net_status_callback_t *iter_node = &g_head_callback;
+ net_status_callback_t *last = iter_node;
+ if (callback == NULL) {
+ return;
+ }
+
+ if (iter_node->callback_fn == callback) {
+ if (iter_node->next != NULL) {
+ g_head_callback.callback_fn = iter_node->next->callback_fn;
+ g_head_callback.next = iter_node->next->next;
+ free(iter_node->next);
+ return;
+ } else {
+ iter_node->callback_fn = NULL;
+ goto END;
+ }
+ }
+ while (iter_node != NULL) {
+ if (iter_node->callback_fn == callback) {
+ last->next = iter_node->next;
+ free(iter_node);
+ return;
+ }
+ last = iter_node;
+ iter_node = iter_node->next;
+ }
+ return;
+END:
+#if defined(SUPPORT_VOLTE)
+ cat1_unregister_net_callback();
+#endif
+#if defined(SUPPORT_BREDR)
+ bt_pan_unregister_net_callback();
+#endif
+}
\ No newline at end of file
void
dns_init(void)
{
-
- #ifdef DNS_SERVER_ADDRESS
+#ifdef DNS_SERVER_ADDRESS
/* initialize default DNS server address */
ip_addr_t dnsserver = {0};
+ u8_t n;
DNS_SERVER_ADDRESS(&dnsserver);
- dns_setserver(0, &dnsserver);
-#ifdef DNS_SERVER_ADDRESS_SECONDARY
- DNS_SERVER_ADDRESS_SECONDARY(&dnsserver);
- dns_setserver(1, &dnsserver);
-#endif
+ /* DNS servers */
+ for (n = 0; (n < LWIP_DHCP_MAX_DNS_SERVERS); n++) {
+ dns_setserver(n, &dnsserver);
+ }
#endif /* DNS_SERVER_ADDRESS */
LWIP_ASSERT("sanity check SIZEOF_DNS_QUERY",
if (dhcp->tries < 255) {
dhcp->tries++;
}
- msecs = (u16_t)((dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000);
+ msecs = (u16_t)((dhcp->tries < 6 ? 2 : 60) * 1000); /* 6, 2, 60, 1000 : retry interval */
dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %"U16_F" msecs\n", msecs));
return result;
autoip_start(netif);
}
#endif /* LWIP_DHCP_AUTOIP_COOP */
- msecs = (u16_t)((dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000);
+ msecs = (u16_t)((dhcp->tries < 6 ? 2 : 60) * 1000); /* 6, 2, 60, 1000 : retry interval */
dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs));
return result;
netif_ext_callback_t *callback = ext_callback;
LWIP_ASSERT("netif must be != NULL", netif != NULL);
-
- while (callback != NULL) {
+ while (callback != NULL && callback->callback_fn != NULL) {
callback->callback_fn(netif, reason, args);
callback = callback->next;
}
/* useg should point to last segment on unacked queue */
useg = pcb->unacked;
if (useg != NULL) {
- for (; useg->next != NULL; useg = useg->next);
+ for (; useg != NULL && useg->next != NULL; useg = useg->next);
}
/* data available and window allows it to be sent? */
while (seg != NULL &&
/* In the case of fast retransmit, the packet should not go to the tail
* of the unacked queue, but rather somewhere before it. We need to check for
* this case. -STJ Jul 27, 2004 */
+ if (useg != NULL) {
if (TCP_SEQ_LT(lwip_ntohl(seg->tcphdr->seqno), lwip_ntohl(useg->tcphdr->seqno))) {
/* add segment to before tail of unacked list, keeping the list sorted */
struct tcp_seg **cur_seg = &(pcb->unacked);
useg->next = seg;
useg = useg->next;
}
+ }
}
/* do not queue empty segments on the unacked list */
} else {
#define DHCP_COARSE_TIMER_SECS 60
/** period (in milliseconds) of the application calling dhcp_coarse_tmr() */
#define DHCP_COARSE_TIMER_MSECS (DHCP_COARSE_TIMER_SECS * 1000UL)
+
/** period (in milliseconds) of the application calling dhcp_fine_tmr() */
+#ifndef DHCP_FINE_TIMER_MSECS
#define DHCP_FINE_TIMER_MSECS 500
+#endif
#define DHCP_BOOT_FILE_LEN 128U
#endif
/** period (in milliseconds) of the application calling dhcp6_tmr() */
+#ifndef DHCP6_TIMER_MSECS
#define DHCP6_TIMER_MSECS 500
+#endif
struct dhcp6
{
#endif
/** DNS timer period */
+#ifndef DNS_TMR_INTERVAL
#define DNS_TMR_INTERVAL 1000
+#endif
/* DNS resolve types: */
#define LWIP_DNS_ADDRTYPE_IPV4 0
#endif
/** 1 seconds period */
+#ifndef ARP_TMR_INTERVAL
#define ARP_TMR_INTERVAL 1000
+#endif
#if ARP_QUEUEING
/** struct for queueing outgoing packets for unknown address
#endif
/* IGMP timer */
+#ifndef IGMP_TMR_INTERVAL
#define IGMP_TMR_INTERVAL 100 /* Milliseconds */
-#define IGMP_V1_DELAYING_MEMBER_TMR (1000/IGMP_TMR_INTERVAL)
-#define IGMP_JOIN_DELAYING_MEMBER_TMR (500 /IGMP_TMR_INTERVAL)
+#endif
+
+#ifndef IGMP_V1_DELAYING_MEMBER_TMR
+#define IGMP_V1_DELAYING_MEMBER_TMR 10
+#endif
+
+#ifndef IGMP_JOIN_DELAYING_MEMBER_TMR
+#define IGMP_JOIN_DELAYING_MEMBER_TMR 5
+#endif
/* Compatibility defines (don't use for new code) */
#define IGMP_DEL_MAC_FILTER NETIF_DEL_MAC_FILTER
#if IP_REASSEMBLY
/* The IP reassembly timer interval in milliseconds. */
+#ifndef IP_TMR_INTERVAL
#define IP_TMR_INTERVAL 1000
+#endif
/** IP reassembly helper struct.
* This is exported because memp needs to know the size.
#if LWIP_IPV6 && LWIP_IPV6_REASS /* don't build if not configured for use in lwipopts.h */
/** The IPv6 reassembly timer interval in milliseconds. */
+#ifndef IP6_REASS_TMR_INTERVAL
#define IP6_REASS_TMR_INTERVAL 1000
+#endif
/** IP6_FRAG_COPYHEADER==1: for platforms where sizeof(void*) > 4, "struct
* ip6_reass_helper" is too large to be stored in the IPv6 fragment header, and
u8_t use;
};
+#ifndef MLD6_TMR_INTERVAL
#define MLD6_TMR_INTERVAL 100 /* Milliseconds */
+#endif
err_t mld6_stop(struct netif *netif);
void mld6_report_groups(struct netif *netif);
#endif
/** 1 second period */
+#ifndef ND6_TMR_INTERVAL
#define ND6_TMR_INTERVAL 1000
+#endif
/** Router solicitations are sent in 4 second intervals (see RFC 4861, ch. 6.3.7) */
#ifndef ND6_RTR_SOLICITATION_INTERVAL
public:
NativeapiFs() = default;
~NativeapiFs() = default;
-
+ static int GetFullPath(const char* uri, char* fullPath, int len);
static JSIValue MoveFile(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum);
static JSIValue CopyFile(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum);
static JSIValue DeleteFile(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum);
#include "js_async_work.h"\r
#include "nativeapi_common.h"\r
#include "nativeapi_fs_impl.h"\r
+#include <climits>\r
\r
namespace OHOS {\r
namespace ACELite {\r
const unsigned int PREFIX_LEN = strlen(FILE_PREFIX);\r
const char *trustPath = "/user/music";\r
const int trustPathSize = strlen(trustPath);\r
+const int MAX_READ_FILE_SIZE = 10 * 1024 * 1024;\r
\r
bool IsValidPath(const char* path)\r
{\r
return true;\r
}\r
\r
-int GetFullPath(const char* uri, char* fullPath, int len)\r
-{\r
- if (!IsValidPath(uri) || (fullPath == nullptr)) {\r
- return ERROR_CODE_PARAM;\r
- }\r
- const char* dataPath = GetDataPath();\r
- int size = PREFIX_LEN;\r
- bool isTrustPath = (strncmp(uri, trustPath, strlen(trustPath)) == 0);\r
- if (isTrustPath) {\r
- size = 0;\r
- }\r
-\r
- if (dataPath == nullptr) {\r
- return ERROR_CODE_PARAM;\r
- }\r
-\r
- if (memset_s(fullPath, len, 0x0, len) != EOK) {\r
- return ERROR_CODE_GENERAL;\r
- }\r
-\r
- if (sprintf_s(fullPath, len, "%s%s", (isTrustPath ? "" : dataPath), uri + size) < 0) {\r
- return ERROR_CODE_GENERAL;\r
- }\r
-\r
- return NATIVE_SUCCESS;\r
-}\r
-\r
JSIValue ExecuteAsyncWork(const JSIValue thisVal, const JSIValue* args,\r
uint8_t argsNum, AsyncWorkHandler ExecuteFunc, bool flag = false)\r
{\r
char* dest = JSI::GetStringProperty(args, FILE_DESTINATION_URI);\r
char* destFullPath = nullptr;\r
JSIValue result = JSI::CreateUndefined();\r
- int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
+ int ret = NativeapiFs::GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
JSI::ReleaseString(src);\r
if (ret != NATIVE_SUCCESS) {\r
NativeapiCommon::FailCallBack(thisVal, args, ret);\r
NativeapiCommon::FailCallBack(thisVal, args, ERROR_CODE_GENERAL);\r
goto EXIT;\r
}\r
- ret = GetFullPath(dest, destFullPath, FILE_NAME_MAX_LEN + 1);\r
+ ret = NativeapiFs::GetFullPath(dest, destFullPath, FILE_NAME_MAX_LEN + 1);\r
if (ret != NATIVE_SUCCESS) {\r
NativeapiCommon::FailCallBack(thisVal, args, ret);\r
goto EXIT;\r
JSIValue args = params->args;\r
JSIValue thisVal = params->thisVal;\r
char* src = JSI::GetStringProperty(args, FILE_URI);\r
- int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
+ int ret = NativeapiFs::GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
JSI::ReleaseString(src);\r
if (ret != NATIVE_SUCCESS) {\r
NativeapiCommon::FailCallBack(thisVal, args, ret);\r
JSIValue thisVal = params->thisVal;\r
char* uri = JSI::GetStringProperty(args, FILE_URI);\r
JSIValue result = JSI::CreateObject();\r
- int ret = GetFullPath(uri, g_uriFullPath, sizeof(g_uriFullPath));\r
+ int ret = NativeapiFs::GetFullPath(uri, g_uriFullPath, sizeof(g_uriFullPath));\r
JSI::ReleaseString(uri);\r
if (ret != NATIVE_SUCCESS) {\r
NativeapiCommon::FailCallBack(thisVal, args, ret);\r
bool recursive = JSI::GetBooleanProperty(args, RECURSIVE);\r
struct stat info = {0};\r
JSIValue result = JSI::CreateObject();\r
- int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
+ int ret = NativeapiFs::GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
if (ret != NATIVE_SUCCESS) {\r
NativeapiCommon::FailCallBack(thisVal, args, ret);\r
goto EXIT;\r
char* src = JSI::GetStringProperty(args, FILE_URI);\r
char* text = JSI::GetStringProperty(args, TEXT);\r
bool append = JSI::GetBooleanProperty(args, FILE_APPEND);\r
- int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
+ int ret = NativeapiFs::GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
JSI::ReleaseString(src);\r
if ((text == nullptr) || (ret != NATIVE_SUCCESS)) {\r
NativeapiCommon::FailCallBack(thisVal, args, ERROR_CODE_PARAM);\r
if (length == 0) {\r
length = TEXT_MAX_READ_LEN;\r
}\r
- int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
+ int ret = NativeapiFs::GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
if (ret != NATIVE_SUCCESS) {\r
return ret;\r
}\r
JSIValue args = params->args;\r
JSIValue thisVal = params->thisVal;\r
char* src = JSI::GetStringProperty(args, FILE_URI);\r
- int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
+ int ret = NativeapiFs::GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
JSI::ReleaseString(src);\r
bool recursive = JSI::GetBooleanProperty(args, RECURSIVE);\r
if (ret != NATIVE_SUCCESS) {\r
if (ret != NATIVE_SUCCESS) {\r
return ret;\r
}\r
- void* text = malloc(info.st_size + 1);\r
- if (text == nullptr) {\r
+\r
+ size_t fileSize = (info.st_size < 0) ? 0 : static_cast<size_t>(info.st_size);\r
+ if (fileSize > static_cast<size_t>(MAX_READ_FILE_SIZE)) {\r
+ return ERROR_CODE_GENERAL;\r
+ }\r
+\r
+ size_t pos = static_cast<size_t>(position);\r
+ if (pos > static_cast<size_t>(INT_MAX)) {\r
+ return ERROR_CODE_GENERAL;\r
+ }\r
+\r
+ size_t maxCanRead = (pos < fileSize) ? (fileSize - pos) : 0;\r
+ size_t toRead = (len == 0 || len > maxCanRead) ? maxCanRead : len;\r
+\r
+ if (toRead == 0) {\r
+ uint8_t *p = nullptr;\r
+ JSIValue emptyBuf = JSI::CreateArrayBuffer(0, p);\r
+ JSIValue emptyArr = JSI::CreateTypedArray(TypedArrayType::JSI_UINT8_ARRAY, 0, emptyBuf, 0);\r
+ JSI::SetNamedProperty(result, FILE_BUFFER, emptyArr);\r
+ JSI::ReleaseValueList(emptyArr, emptyBuf, ARGS_END);\r
+ return NATIVE_SUCCESS;\r
+ }\r
+\r
+ void *buf = malloc(toRead);\r
+ if (buf == nullptr) {\r
return ERROR_CODE_GENERAL;\r
}\r
+\r
size_t actualLen = 0;\r
- ret = ReadFileImpl(path, text, len, static_cast<int>(position), &actualLen);\r
+ ret = ReadFileImpl(path, buf, toRead, static_cast<int>(position), &actualLen);\r
if (ret != NATIVE_SUCCESS) {\r
- free(text);\r
+ free(buf);\r
return ret;\r
}\r
- uint8_t* ptr = nullptr;\r
+\r
+ uint8_t *ptr = nullptr;\r
JSIValue arrayBuffer = JSI::CreateArrayBuffer(actualLen, ptr);\r
if (ptr == nullptr) {\r
- free(text);\r
+ free(buf);\r
JSI::ReleaseValue(arrayBuffer);\r
return ERROR_CODE_GENERAL;\r
}\r
- ret = memcpy_s(ptr, actualLen, text, actualLen);\r
- free(text);\r
+\r
+ ret = memcpy_s(ptr, actualLen, buf, actualLen);\r
+ free(buf);\r
if (ret != EOK) {\r
JSI::ReleaseValue(arrayBuffer);\r
return ERROR_CODE_GENERAL;\r
}\r
+\r
JSIValue typedArray = JSI::CreateTypedArray(TypedArrayType::JSI_UINT8_ARRAY, actualLen, arrayBuffer, 0);\r
JSI::SetNamedProperty(result, FILE_BUFFER, typedArray);\r
JSI::ReleaseValueList(typedArray, arrayBuffer, ARGS_END);\r
NativeapiCommon::FailCallBack(thisVal, args, ret);\r
goto EXIT;\r
}\r
- ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
+ ret = NativeapiFs::GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
JSI::ReleaseString(src);\r
if (ret != NATIVE_SUCCESS) {\r
NativeapiCommon::FailCallBack(thisVal, args, ret);\r
JSIValue args = params->args;\r
JSIValue thisVal = params->thisVal;\r
char* src = JSI::GetStringProperty(args, FILE_URI);\r
- int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
+ int ret = NativeapiFs::GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
JSI::ReleaseString(src);\r
if (ret != NATIVE_SUCCESS) {\r
NativeapiCommon::FailCallBack(thisVal, args, ret);\r
#endif\r
}\r
\r
+int NativeapiFs::GetFullPath(const char* uri, char* fullPath, int len)\r
+{\r
+ if (!IsValidPath(uri) || (fullPath == nullptr)) {\r
+ return ERROR_CODE_PARAM;\r
+ }\r
+ const char* dataPath = GetDataPath();\r
+ int size = PREFIX_LEN;\r
+ bool isTrustPath = (strncmp(uri, trustPath, strlen(trustPath)) == 0);\r
+ if (isTrustPath) {\r
+ size = 0;\r
+ }\r
+\r
+ if (dataPath == nullptr) {\r
+ return ERROR_CODE_PARAM;\r
+ }\r
+\r
+ if (memset_s(fullPath, len, 0x0, len) != EOK) {\r
+ return ERROR_CODE_GENERAL;\r
+ }\r
+\r
+ if (sprintf_s(fullPath, len, "%s%s", (isTrustPath ? "" : dataPath), uri + size) < 0) {\r
+ return ERROR_CODE_GENERAL;\r
+ }\r
+\r
+ return NATIVE_SUCCESS;\r
+}\r
+\r
JSIValue NativeapiFs::MoveFile(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)\r
{\r
return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteCopyFile, true);\r