From ef8756dee2321446d77c92b22d79a9637dac429a Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E8=A2=81=E6=B8=85=E6=A2=A6?= <3449750381@qq.com> Date: Tue, 30 Sep 2025 11:25:20 +0000 Subject: [PATCH] Merge #2460 into sdk650pathc0423 from refs/changes/2460/head MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Code review from 袁清梦 * refs/changes/2460/head: (2 commits squashed) - 优化时间同步 - Merge branch 'sdk650pathc0423' of https://codeup.aliyun.com/64191456b9581d62e8f81ac0/FD230 into sdk650pathc0423 Signed-off-by: Caisking <3449750381@qq.com> Reviewed-by: snickersun@163.com Merged-by: snickersun@163.com CR-link: https://codeup.aliyun.com/64191456b9581d62e8f81ac0/FD230/change/2460 --- .../ble_service/bleservice/bleEvent.c | 209 ++++++++++++------ 1 file changed, 136 insertions(+), 73 deletions(-) diff --git a/code/sdk/zhihui/services/ble_service/bleservice/bleEvent.c b/code/sdk/zhihui/services/ble_service/bleservice/bleEvent.c index 40275078e..83d602f80 100644 --- a/code/sdk/zhihui/services/ble_service/bleservice/bleEvent.c +++ b/code/sdk/zhihui/services/ble_service/bleservice/bleEvent.c @@ -1566,100 +1566,163 @@ void senfindphoneSend(uint8_t flag) memcpy(sendBuf+7,&tmp,4); memcpy(sendBuf+11,&tmp,4); //15 memcpy(sendBuf+15,&tmp_data,2); //17 - sendBuf[17] = flag; + sendBuf[17] = flag; sendBuf[18] = Calculate_CRC(sendBuf,18); sendBleData(sendBuf,19); } +// 辅助函数:检查日期是否有效 +static bool is_valid_date(int year, int month, int day) { + if (year < 1970 || year > 2100) return false; + if (month < 1 || month > 12) return false; + if (day < 1) return false; + + // 检查月份天数 + int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + // 闰年检查 + if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) { + days_in_month[1] = 29; + } + + return day <= days_in_month[month - 1]; +} + +// 辅助函数:检查时间是否有效 +static bool is_valid_time(int hour, int minute, int second) { + return (hour >= 0 && hour <= 23) && + (minute >= 0 && minute <= 59) && + (second >= 0 && second <= 59); +} + +// 辅助函数:安全获取JSON数字值 +static int get_json_int_safe(cJSON* item, int default_value, int min_val, int max_val) { + if (!item || !cJSON_IsNumber(item)) { + return default_value; + } + + int value = item->valueint; + if (value < min_val || value > max_val) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Value %d out of range [%d, %d], using default %d", + value, min_val, max_val, default_value); + return default_value; + } + + return value; +} + static uint8_t jsonCheck_time(uint8_t *buf)//json 格式解析 { - // char time_data[24]; - // memset(time_data,0,24); + if (buf == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Input buffer is NULL"); + return 2; + } - uint8_t *json; - json = buf; - cJSON* root = cJSON_Parse((const char *)json); + cJSON* root = cJSON_Parse((const char *)buf); if (root == NULL) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"时间 JSON解析错误\n"); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "JSON解析错误"); return 2; } - char *locations; - int year = 1970; - uint8_t month = 1; - uint8_t day = 1; - uint8_t week = 4; - uint8_t hour = 0; - uint8_t minute = 0; - uint8_t second = 0; - uint32_t timestamp; + + // 验证必需字段 cJSON* time = cJSON_GetObjectItem(root, "time"); - if (time && cJSON_IsNumber(time)) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"time: %d\n", time->valueint); - timestamp = time->valueint; - // WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"time: %d\n", time->valueint); - } - cJSON* jsweek = cJSON_GetObjectItem(root, "week"); - if (jsweek && cJSON_IsNumber(jsweek)) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"week: %d\n", jsweek->valueint); - week = jsweek->valueint; - } - cJSON* jsyear = cJSON_GetObjectItem(root, "year"); - if (jsyear && cJSON_IsNumber(jsyear)) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"year: %d\n", jsyear->valueint); - year = jsyear->valueint; - } - cJSON* jsmonth = cJSON_GetObjectItem(root, "month"); - if (jsmonth && cJSON_IsNumber(jsmonth)) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"month: %d\n", jsmonth->valueint); - month = jsmonth->valueint; - } - cJSON* jsday = cJSON_GetObjectItem(root, "day"); - if (jsday && cJSON_IsNumber(jsday)) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"day: %d\n", jsday->valueint); - day = jsday->valueint; - } - cJSON* jshour = cJSON_GetObjectItem(root, "hour"); - if (jshour && cJSON_IsNumber(jshour)) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"hour: %d\n", jshour->valueint); - hour = jshour->valueint; - } - cJSON* jsminute = cJSON_GetObjectItem(root, "minute"); - if (jsminute && cJSON_IsNumber(jsminute)) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"minute: %d\n", jsminute->valueint); - minute = jsminute->valueint; - } - cJSON* jssecond = cJSON_GetObjectItem(root, "second"); - if (jssecond && cJSON_IsNumber(jssecond)) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"second: %d\n", jssecond->valueint); - second = jssecond->valueint; - } - cJSON* location = cJSON_GetObjectItem(root, "location"); - if (location && cJSON_IsString(location)) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"location: %s\n", location->valuestring); - locations = location->valuestring; + if (!time || !cJSON_IsNumber(time)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Missing or invalid 'time' field"); + cJSON_Delete(root); + return 2; } - // sprintf((char *)time_data,"%d-%d-%d %d:%d:%d",year+2000,month,day,hour,minute,second); - // set_system_time(time_data); + uint32_t timestamp = (uint32_t)time->valueint; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "time: %u", timestamp); - /***计算timezone*/ - struct tm tmp={0}; - tmp.tm_year = year+2000 - 1900; - tmp.tm_mon = month -1; + // 打印原始json内容 + char *json_string = cJSON_Print(root); + if (json_string) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "json: %s", json_string); + free(json_string); // 释放cJSON_Print分配的内存 + } + + // 安全获取其他字段,带范围验证 + // 注意:year字段是"年份减去2000",所以21表示2021年 + int year_offset = get_json_int_safe(cJSON_GetObjectItem(root, "year"), 21, 0, 100); // 0-100对应2000-2100年 + int month = get_json_int_safe(cJSON_GetObjectItem(root, "month"), 1, 1, 12); + int day = get_json_int_safe(cJSON_GetObjectItem(root, "day"), 1, 1, 31); + int hour = get_json_int_safe(cJSON_GetObjectItem(root, "hour"), 0, 0, 23); + int minute = get_json_int_safe(cJSON_GetObjectItem(root, "minute"), 0, 0, 59); + int second = get_json_int_safe(cJSON_GetObjectItem(root, "second"), 0, 0, 59); + int week = get_json_int_safe(cJSON_GetObjectItem(root, "week"), 4, 0, 6); + + // 将年份偏移转换为实际年份 + int year = year_offset + 2000; + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Parsed: %d-%02d-%02d %02d:%02d:%02d (week:%d) [year_offset:%d]", + year, month, day, hour, minute, second, week, year_offset); + + // 验证日期有效性 + if (!is_valid_date(year, month, day)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid date: %d-%02d-%02d", year, month, day); + cJSON_Delete(root); + return 2; + } + + // 验证时间有效性 + if (!is_valid_time(hour, minute, second)) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid time: %02d:%02d:%02d", hour, minute, second); + cJSON_Delete(root); + return 2; + } + + // 年份已经通过协议正确转换,直接使用 + int actual_year = year; + + // 计算时区 + struct tm tmp = {0}; + tmp.tm_year = actual_year - 1900; + tmp.tm_mon = month - 1; tmp.tm_mday = day; tmp.tm_hour = hour; tmp.tm_min = minute; tmp.tm_sec = second; - time_t timestamp2 = __tm_to_secs(&tmp); - int16_t timezone = (timestamp2-timestamp)/60/15; - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"timezone in quarters %d\n",timezone); - uapi_set_timezone(timezone); //要在uaip_sntp_set_time_utc 之前执行才有效 - /********/ - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"time: %d\n",timestamp ); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "实际时间: %d-%02d-%02d %02d:%02d:%02d", + tmp.tm_year + 1900, tmp.tm_mon + 1, tmp.tm_mday, tmp.tm_hour, tmp.tm_min, tmp.tm_sec); + + time_t timestamp2 = __tm_to_secs(&tmp); + + // 验证时间戳计算 + if (timestamp2 == (time_t)-1) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid timestamp calculation"); + cJSON_Delete(root); + return 2; + } + + // 计算时区(以15分钟为单位) + int64_t time_diff = (int64_t)timestamp2 - (int64_t)timestamp; + int16_t timezone_quarters = (int16_t)(time_diff / 60 / 15); + + // 验证时区范围(-48到+48个15分钟单位,即-12到+12小时) + if (timezone_quarters < -48 || timezone_quarters > 48) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid timezone: %d quarters (diff: %lld seconds)", + timezone_quarters, time_diff); + cJSON_Delete(root); + return 2; + } + + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Calculated timezone: %d quarters (%.1f hours)", + timezone_quarters, timezone_quarters * 0.25); + + // 设置时区和时间 + uapi_set_timezone(timezone_quarters); uaip_sntp_set_time_utc(timestamp); - + + // 记录位置信息(如果有) + cJSON* location = cJSON_GetObjectItem(root, "location"); + if (location && cJSON_IsString(location)) { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "location: %s", location->valuestring); + } + cJSON_Delete(root); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Time set successfully"); return 1; } -- 2.17.1