bool tpsocket_event_filelog_to_hub(struct tpsocket_handler *handler, struct list_head *buf, int event)
{
struct tpsocket_fd *sock = container_of(handler, struct tpsocket_fd, handler);
FileLogSession *session = handler->priv;
if(!session){
return false;
}
int decrypt_flag = session->decrypt_flag;
struct tpsocket_buf *nbuf = NULL;
FILE *fp = session->fp;
if (!fp)
{
DBG_ERR("File pointer is NULL, cannot write\n");
return false;
}
int remaining = session->remaining;
char *filepath = session->filepath;
DBG_ERR("sock=%p, event=%s\n", sock, tpsocket_event_name(event));
switch(event) {
case TPSOCKET_EVENT_LISTEN:
DBG_ERR("TPSOCKET_EVENT_LISTEN: %s:%s Listen\n", sock->addr, sock->port);
break;
case TPSOCKET_EVENT_SHUTDOWN:
DBG_ERR("TPSOCKET_EVENT_LISTEN: %s:%s Shutdown\n", sock->addr, sock->port);
break;
case TPSOCKET_EVENT_ACCEPT:
DBG_ERR("TPSOCKET_EVENT_LISTEN: %s:%s Accepted\n", sock->addr, sock->port);
break;
case TPSOCKET_EVENT_CONNECTED:
DBG_ERR("TPSOCKET_EVENT_LISTEN: %s:%s connected\n", sock->addr, sock->port);
break;
case TPSOCKET_EVENT_REQ_HEAD:
DBG_ERR("TPSOCKET_EVENT_LISTEN: %s Requested path: %s\n", sock->path, sock->parser.http.url);
break;
case TPSOCKET_EVENT_RSP_HEAD:
break;
case TPSOCKET_EVENT_SUB_HEAD:
break;
case TPSOCKET_EVENT_UPGRADE:
break;
case TPSOCKET_EVENT_MESSAGE:
nbuf = tpsocket_merge_buf(buf);
if (!nbuf) {
DBG_ERR("Failed to merge buffer\n");
break;
}
unsigned char *input_data = tpbuf_data(nbuf);
bool error = false;
int input_len = tpbuf_data_len(nbuf);
DBG_ERR("input_len:%d", input_len);
if (decrypt_flag)
{
DBG_ERR("+++++++++++++++++++++++++++++");
int decoded_len = tpsocket_base64_decode(input_data, input_len, input_data);
if (decoded_len < 0)
{
DBG_ERR("Base64 decoding failed\n");
error = true;
}
DBG_ERR("tpsocket_base64_decode\n");
// unsigned char *plain_data = tpbuf_data(nbuf);
// if (!plain_data)
// {
// DBG_ERR("Memory allocation failed for plain buffer\n");
// error = true;
// }
int plain_len = decoded_len;
if (remaining > decoded_len)
{
remaining = decoded_len;
DBG_ERR("decode session->remaining:%d\n", remaining);
}
unsigned char *plain_data = calloc(plain_len, sizeof(unsigned char));
work_tapo_log_decrypt(tpbuf_data(nbuf), decoded_len, plain_data, &plain_len);
DBG_ERR("plain_len:%d\n",plain_len);
// 写入解密后的内容
if (fwrite(plain_data, 1, plain_len, fp) < plain_len)
{
DBG_ERR("File write error after decryption: %s\n", strerror(errno));
error = true;
}
else
{
const char newline = '\n';
if (fwrite(&newline, 1, 1, fp) != 1) {
DBG_ERR("Failed to write newline character: %s\n", strerror(errno));
}
remaining -= plain_len;
}
}
else
{
if (fwrite(input_data, 1, input_len, fp) < input_len) {
DBG_ERR("File write error: %s\n", strerror(errno));
error = true;
} else {
const char newline = '\n';
if (fwrite(&newline, 1, 1, fp) != 1) {
DBG_ERR("Failed to write newline character: %s\n", strerror(errno));
}
remaining -= input_len;
}
}
DBG_ERR("session->remaining: %d\n", remaining);
// 传输完成处理
if (remaining <= 0 || error) {
if (fp) {
fclose(fp);
session->fp = NULL;
}
char resp[256];
if (error) {
snprintf(resp, sizeof(resp),
"HTTP/1.1 500 Internal Error\r\n"
"Connection: close\r\n"
"\r\n");
} else {
snprintf(resp, sizeof(resp),
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Content-Length: 0\r\n"
"Connection: close\r\n"
"\r\n");
}
struct tpsocket_buf *resp_buf = tpbuf_snprintf(strlen(resp) + 1, resp);
if (resp_buf) tpsocket_write(sock, resp_buf);
// if (error) unlink(filepath);
// if(session){
// free(session);
// handler->priv = NULL;
// }
}
// tpsocket_close(sock);
break;
case TPSOCKET_EVENT_STREAM:
return true;
case TPSOCKET_EVENT_RESET:
break;
case TPSOCKET_EVENT_TIMEOUT:
break;
case TPSOCKET_EVENT_CLOSED:
DBG_ERR("TPSOCKET_EVENT_CLOSED\n");
if (session != NULL) {
// 异常关闭时清理资源
DBG_ERR("entering TPSOCKET_EVENT_CLOSED\n");
if (session->fp) {
fclose(session->fp);
session->fp = NULL;
}
unlink(filepath);
free(session);
handler->priv = NULL;
}
tpsocket_close(sock);
break;
case TPSOCKET_EVENT_ERROR:
default:
break;
}
tpsocket_free_buf(buf, tpsocket_event_name(event), 0);
return true;
}if (!strncmp(sock->parser.http.url, "/diagnose_log/set", sizeof("/diagnose_log/set"))) {
if (false == worker_file_log_set_handle(handler->priv, sock, buf)) {
tpsocket_free_buf(buf, tpsocket_event_name(event), 0);
return false;
}
}bool worker_file_log_set_handle(WORKER_CTX *worker_ctx, struct tpsocket_fd *sock, struct list_head *buf)
{
// 1. 获取设备MAC地址
char *mac = common_find_key_from_buf(buf, "Device-Mac");
if (!mac || strlen(mac) < 12) {
DBG_ERR("Invalid MAC address\n");
return false;
}
DBG_ERR("mac: %s\n", mac);
// 2. MAC格式化处理(冒号转下划线)
char processed_mac[18] = {0};
strncpy(processed_mac, mac, sizeof(processed_mac)-1);
for (char *p = processed_mac; *p; p++) {
if (*p == ':') *p = '_';
}
DBG_ERR("processed_mac: %s\n", processed_mac);
// 3. 创建目标目录
char dirpath[128];
snprintf(dirpath, sizeof(dirpath), "%s/%s", FILELOG_PATH , processed_mac);
// 检创建父目录(/mnt/sd_card)
if (access(FILELOG_PATH, F_OK) != 0) {
if (mkdir(FILELOG_PATH,0755) != 0) {
DBG_ERR("SD card mount failed: %s\n", strerror(errno));
return false;
}
}
// 创建设备目录(/mnt/sd_card/<processed_mac>)
if (access(dirpath, F_OK) != 0) {
if (mkdir(dirpath, 0755) != 0) {
DBG_ERR("Device dir '%s' creation failed: %s\n",
dirpath, strerror(errno));
return false;
}
}
// 4. 构建文件路径
char filepath[256];
snprintf(filepath, sizeof(filepath), "%s/log.txt", dirpath);
DBG_ERR("filepath: %s\n", filepath);
// 5. 获取内容长度(
char *content_length_str = common_find_key_from_buf(buf, "Content-Length");
if (!content_length_str || *content_length_str == '\0') {
DBG_ERR("Missing Content-Length header\n");
return false;
}
size_t content_len = atol(content_length_str);
if (content_len <= 0) {
DBG_ERR("Invalid content length: %s\n", content_length_str);
return false;
}
DBG_ERR("Content-Length: %zu\n", content_len);
// 滚动写入
FILE *fp = fopen(filepath, "ab+");
if (!fp) { /* 错误处理 */ }
fseek(fp, 0, SEEK_END);
long file_size = ftell(fp);
// 处理超大数据特殊情况
if (content_len > MAX_FILELOG_DIR_SIZE) {
DBG_ERR("Unable to free sufficient space\n");
const char *resp = "HTTP/1.1 507 Insufficient Storage\r\n\r\n";
struct tpsocket_buf *resp_buf = tpbuf_snprintf(strlen(resp)+1, resp);
if (resp_buf) tpsocket_write(sock, resp_buf);
return false;
}
// 循环删除行直到空间足够
while (file_size > 0 && file_size + content_len > MAX_FILELOG_DIR_SIZE) {
rewind(fp);
long line_start = 0;
long line_end = 0;
// 增强行定位:逐字符扫描换行符
int ch;
while ((ch = fgetc(fp)) != EOF) {
line_end = ftell(fp);
if (ch == '\n') {
// 找到完整行边界
line_start = line_end;
// 检查剩余空间
if (file_size - line_start + content_len <= MAX_FILELOG_DIR_SIZE)
break;
}
}
// 截断并移位(避免大内存分配)
if (line_start > 0) {
FILE *temp = tmpfile(); // 创建临时文件
fseek(fp, line_start, SEEK_SET);
// 流式复制保留内容
char buffer[1024];
size_t bytes;
while ((bytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) {
fwrite(buffer, 1, bytes, temp);
}
// 原子替换原文件
ftruncate(fileno(fp), 0);
rewind(fp);
rewind(temp);
while ((bytes = fread(buffer, 1, sizeof(buffer), temp)) > 0) {
fwrite(buffer, 1, bytes, fp);
}
fclose(temp);
file_size = ftell(fp);
} else {
ftruncate(fileno(fp), 0);
file_size = 0;
break;
}
}
// fclose(fp);
//session
FileLogSession *session = calloc(1, sizeof(FileLogSession));
if (!session) return false;
// session->fp = fopen(filepath, "ab");
session->fp = fp;
if (!session->fp) {
free(session);
return false;
}
session->remaining = content_len;
session->total_size = content_len;
char *if_encrypt = common_find_key_from_buf(buf, "X-If-Encrypt");
DBG_ERR("if_encrypt:%s\n",if_encrypt);
if (if_encrypt)
{
session->decrypt_flag = atoi(if_encrypt);
DBG_ERR("session->decrypt_flagt:%d\n",session->decrypt_flag);
char *nonce = NULL;
if ((nonce = common_find_key_from_buf(buf, "X-Nonce")))
{
DBG_ERR("nonce:%s\n",nonce);
work_tapo_log_refresh_nonce(nonce);
free(nonce);
}
}
else
{
session->decrypt_flag = 0;
}
free(if_encrypt);
snprintf(session->filepath,sizeof(session->filepath),"%s",filepath);
sock->handler.cb = tpsocket_event_filelog_to_hub;
sock->handler.priv = session;
return sock->handler.cb;
}打印:[1103 09:59:36][Error] mediacenter: [worker.c:6600][tpsocket_event_worker_listen_cb] WORKERC: 192.168.137.1:50592 connected
[1103 09:59:36][Error] mediacenter: [worker.c:3961][worker_file_log_set_handle] mac: 40AE30181089
[1103 09:59:36][Error] mediacenter: [worker.c:3968][worker_file_log_set_handle] processed_mac: 40AE30181089
[1103 09:59:36][Error] mediacenter: [worker.c:3990][worker_file_log_set_handle] filepath: /mnt/sdcard/40AE30181089/log.txt
[1103 09:59:36][Error] mediacenter: [worker.c:4002][worker_file_log_set_handle] Content-Length: 216
[1103 09:59:36][Error] mediacenter: [worker.c:4077][worker_file_log_set_handle] if_encrypt:1
[1103 09:59:36][Error] mediacenter: [worker.c:4081][worker_file_log_set_handle] session->decrypt_flagt:1
[1103 09:59:36][Error] mediacenter: [worker.c:4085][worker_file_log_set_handle] nonce:1234567890abcdef
[1103 09:59:36][Error] mediacenter: [worker.c:240][work_tapo_refresh_encrypt_key] tapo_nonce:
[1103 09:59:36][Error] mediacenter: [worker.c:256][work_tapo_refresh_encrypt_key] tapo_key: 9a33cbb078ebbf78533f35b2ad7a58db
[1103 09:59:36][Error] mediacenter: [worker.c:258][work_tapo_refresh_encrypt_key] tapo_iv: 1f7d50c56381bb05217922bda930004c
[1103 09:59:36][Error] mediacenter: [storage.c:916][tpsocket_event_filelog_to_hub] sock=0xd37090, event=TPSOCKET_EVENT_STREAM
[1103 09:59:36][Error] mediacenter: [storage.c:916][tpsocket_event_filelog_to_hub] sock=0xd37090, event=TPSOCKET_EVENT_MESSAGE
[1103 09:59:36][Error] mediacenter: [storage.c:948][tpsocket_event_filelog_to_hub] input_len:216
[1103 09:59:36][Error] mediacenter: [storage.c:951][tpsocket_event_filelog_to_hub] +++++++++++++++++++++++++++++
[1103 09:59:36][Error] mediacenter: [storage.c:958][tpsocket_event_filelog_to_hub] tpsocket_base64_decode
[1103 09:59:36][Error] mediacenter: [storage.c:969][tpsocket_event_filelog_to_hub] decode session->remaining:160
[1103 09:59:36][Error] mediacenter: [storage.c:973][tpsocket_event_filelog_to_hub] plain_len:160
[1103 09:59:36][Error] mediacenter: [storage.c:1002][tpsocket_event_filelog_to_hub] session->remaining: 0
[1103 09:59:36][Error] mediacenter: [storage.c:911][tpsocket_event_filelog_to_hub] File pointer is NULL, cannot write
[1103 09:59:36][Error] mediacenter: [storage.c:911][tpsocket_event_filelog_to_hub] File pointer is NULL, cannot write
分析为什么会出现这种情况?
最新发布