优化时间同步
authorCaisking <Casiking@zhihuishixun.com>
Tue, 30 Sep 2025 09:57:52 +0000 (17:57 +0800)
committerCaisking <Casiking@zhihuishixun.com>
Tue, 30 Sep 2025 09:57:52 +0000 (17:57 +0800)
code/sdk/zhihui/services/ble_service/bleservice/bleEvent.c

index 4027507..83d602f 100644 (file)
@@ -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;
 }