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;
}