#include "rkaiq_protocol.h" #include #include #include #include #include #ifdef __ANDROID__ #include #include #endif #include "domain_tcp_client.h" #include "tcp_server.h" #include "tcp_client.h" #include "rkaiq_socket.h" #ifdef LOG_TAG #undef LOG_TAG #endif #define LOG_TAG "aiqtool" extern int g_app_run_mode; extern int g_width; extern int g_height; extern int g_rtsp_en; extern int g_rtsp_en_from_cmdarg; extern int g_device_id; extern int g_allow_killapp; extern uint32_t g_offlineFrameRate; extern DomainTCPClient g_tcpClient; extern struct ucred* g_aiqCred; extern std::string iqfile; extern std::string g_sensor_name; extern std::shared_ptr rkaiq_media; extern std::string g_stream_dev_name; extern std::shared_ptr tcpServer; extern int ConnectAiq(); bool RKAiqProtocol::is_recv_running = false; std::unique_ptr RKAiqProtocol::forward_thread = nullptr; std::unique_ptr RKAiqProtocol::offlineRawThread = nullptr; std::mutex RKAiqProtocol::mutex_; static int startOfflineRawFlag = 0; #define MAX_PACKET_SIZE 8192 #pragma pack(1) typedef struct FileTransferData_s { uint8_t RKID[8]; // "SendFile" unsigned long long packetSize; int commandID; int commandResult; int targetDirLen; uint8_t targetDir[256]; int targetFileNameLen; uint8_t targetFileName[128]; unsigned long long dataSize; char* data; unsigned int dataHash; } FileTransferData; typedef struct OfflineRAW_s { uint8_t RKID[8]; // "OffRAW" unsigned long long packetSize; int commandID; int commandResult; int offlineRawModeControl; } OfflineRAW; #pragma pack() static void HexDump(unsigned char* data, size_t size) { printf("####\n"); int i; size_t offset = 0; while (offset < size) { printf("%04x ", offset); for (i = 0; i < 16; i++) { if (i % 8 == 0) { putchar(' '); } if (offset + i < size) { printf("%02x ", data[offset + i]); } else { printf(" "); } } printf(" "); for (i = 0; i < 16 && offset + i < size; i++) { if (isprint(data[offset + i])) { printf("%c", data[offset + i]); } else { putchar('.'); } } putchar('\n'); offset += 16; } printf("####\n\n"); } static int ProcessExists(const char* process_name) { FILE* fp; char cmd[1024] = {0}; char buf[1024] = {0}; snprintf(cmd, sizeof(cmd), "ps -ef | grep %s | grep -v grep", process_name); fp = popen(cmd, "r"); if (!fp) { LOG_DEBUG("popen ps | grep %s fail\n", process_name); return -1; } while (fgets(buf, sizeof(buf), fp)) { LOG_DEBUG("ProcessExists %s\n", buf); if (strstr(buf, process_name)) { fclose(fp); return 1; } } fclose(fp); return 0; } int StopProcess(const char* process, const char* str) { int count = 0; while (ProcessExists(process) > 0) { LOG_DEBUG("StopProcess %s... \n", process); system(str); sleep(1); count++; if (count > 3) { return -1; } } return 0; } int WaitProcessExit(const char* process, int sec) { int count = 0; LOG_DEBUG("WaitProcessExit %s... \n", process); while (ProcessExists(process) > 0) { LOG_DEBUG("WaitProcessExit %s... \n", process); sleep(1); count++; if (count > sec) { return -1; } } return 0; } void RKAiqProtocol::KillApp() { #ifdef __ANDROID__ if (g_allow_killapp) { unlink(LOCAL_SOCKET_PATH); property_set("ctrl.stop", "cameraserver"); property_set("ctrl.stop", "vendor.camera-provider-2-4"); property_set("ctrl.stop", "vendor.camera-provider-2-4-ext"); system("stop cameraserver"); system("stop vendor.camera-provider-2-4"); system("stop vendor.camera-provider-2-4-ext"); } #else if (g_allow_killapp) { if (g_aiqCred != nullptr) { kill(g_aiqCred->pid, SIGTERM); delete g_aiqCred; g_aiqCred = nullptr; } } #endif std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } int RKAiqProtocol::StartApp() { int ret = -1; #ifdef __ANDROID__ if (g_allow_killapp) { property_set("ctrl.start", "cameraserver"); system("start cameraserver"); system("start vendor.camera-provider-2-4"); system("start vendor.camera-provider-2-4-ext"); } std::this_thread::sleep_for(std::chrono::milliseconds(1000)); #endif return 0; } int RKAiqProtocol::StartRTSP() { int ret = -1; LOG_DEBUG("Starting RTSP !!!"); KillApp(); ret = rkaiq_media->LinkToIsp(true); if (ret) { LOG_ERROR("link isp failed!!!\n"); return ret; } std::this_thread::sleep_for(std::chrono::milliseconds(1000)); media_info_t mi = rkaiq_media->GetMediaInfoT(g_device_id); #ifdef __ANDROID__ int readback = 0; std::string isp3a_server_cmd = "/vendor/bin/rkaiq_3A_server -mmedia="; if (mi.isp.media_dev_path.length() > 0) { isp3a_server_cmd.append(mi.isp.media_dev_path); LOG_DEBUG("#### using isp dev path.\n"); } else if (mi.cif.media_dev_path.length() > 0) { isp3a_server_cmd.append(mi.cif.media_dev_path); LOG_DEBUG("#### using cif dev path.\n"); } else { isp3a_server_cmd.append("/dev/media2"); LOG_DEBUG("#### using default dev path.\n"); } isp3a_server_cmd.append(" --sensor_index="); isp3a_server_cmd.append(std::to_string(g_device_id)); isp3a_server_cmd.append(" &"); system("pkill rkaiq_3A_server*"); system(isp3a_server_cmd.c_str()); std::this_thread::sleep_for(std::chrono::milliseconds(200)); #endif if (g_stream_dev_name.empty()) { int isp_ver = rkaiq_media->GetIspVer(); LOG_DEBUG(">>>>>>>> isp ver = %d\n", isp_ver); if (isp_ver == 4) { ret = init_rtsp(mi.ispp.pp_scale0_path.c_str(), g_width, g_height); } else if (isp_ver == 5) { ret = init_rtsp(mi.isp.main_path.c_str(), g_width, g_height); } else { ret = init_rtsp(mi.isp.main_path.c_str(), g_width, g_height); } } else { ret = init_rtsp(g_stream_dev_name.c_str(), g_width, g_height); } if (ret) { LOG_ERROR("init_rtsp failed!!"); return ret; } LOG_DEBUG("Started RTSP !!!"); return 0; } int RKAiqProtocol::StopRTSP() { LOG_DEBUG("Stopping RTSP !!!"); deinit_rtsp(); #ifdef __ANDROID__ system("pkill rkaiq_3A_server*"); #endif std::this_thread::sleep_for(std::chrono::milliseconds(1000)); LOG_DEBUG("Stopped RTSP !!!"); return 0; } int RKAiqProtocol::DoChangeAppMode(appRunStatus mode) { std::lock_guard lg(mutex_); int ret = -1; LOG_DEBUG("Switch to mode %d->%d\n", g_app_run_mode, mode); if (g_app_run_mode == mode) { return 0; } if (mode == APP_RUN_STATUS_CAPTURE) { LOG_DEBUG("Switch to APP_RUN_STATUS_CAPTURE\n"); if (g_rtsp_en) { ret = StopRTSP(); if (ret) { LOG_ERROR("stop RTSP failed!!!\n"); g_app_run_mode = APP_RUN_STATUS_INIT; return ret; } } KillApp(); ret = rkaiq_media->LinkToIsp(false); if (ret) { LOG_ERROR("unlink isp failed!!!\n"); g_app_run_mode = APP_RUN_STATUS_INIT; return ret; } } else { LOG_DEBUG("Switch to APP_RUN_STATUS_TUNRING\n"); ret = rkaiq_media->LinkToIsp(true); if (ret) { LOG_ERROR("link isp failed!!!\n"); g_app_run_mode = APP_RUN_STATUS_INIT; // return ret; } if (!g_rtsp_en) { ret = StartApp(); if (ret) { LOG_ERROR("start app failed!!!\n"); g_app_run_mode = APP_RUN_STATUS_INIT; return ret; } } } g_app_run_mode = mode; LOG_DEBUG("Change mode to %d exit\n", g_app_run_mode); return 0; } static void InitCommandPingAns(CommandData_t* cmd, int ret_status) { strncpy((char*)cmd->RKID, RKID_CHECK, sizeof(cmd->RKID)); cmd->cmdType = DEVICE_TO_PC; cmd->cmdID = CMD_ID_CAPTURE_STATUS; cmd->datLen = 1; memset(cmd->dat, 0, sizeof(cmd->dat)); cmd->dat[0] = ret_status; cmd->checkSum = 0; for (int i = 0; i < cmd->datLen; i++) { cmd->checkSum += cmd->dat[i]; } } static void DoAnswer(int sockfd, CommandData_t* cmd, int cmd_id, int ret_status) { char send_data[MAXPACKETSIZE]; LOG_DEBUG("enter\n"); strncpy((char*)cmd->RKID, TAG_OL_DEVICE_TO_PC, sizeof(cmd->RKID)); cmd->cmdType = DEVICE_TO_PC; cmd->cmdID = cmd_id; strncpy((char*)cmd->version, RKAIQ_TOOL_VERSION, sizeof(cmd->version)); cmd->datLen = 4; memset(cmd->dat, 0, sizeof(cmd->dat)); cmd->dat[0] = ret_status; cmd->checkSum = 0; for (int i = 0; i < cmd->datLen; i++) { cmd->checkSum += cmd->dat[i]; } memcpy(send_data, cmd, sizeof(CommandData_t)); send(sockfd, send_data, sizeof(CommandData_t), 0); LOG_DEBUG("exit\n"); } void RKAiqProtocol::HandlerCheckDevice(int sockfd, char* buffer, int size) { CommandData_t* common_cmd = (CommandData_t*)buffer; CommandData_t send_cmd; char send_data[MAXPACKETSIZE]; int ret = -1; LOG_DEBUG("HandlerCheckDevice:\n"); // for (int i = 0; i < common_cmd->datLen; i++) { // LOG_DEBUG("DATA[%d]: 0x%x\n", i, common_cmd->dat[i]); // } if (strcmp((char*)common_cmd->RKID, RKID_CHECK) == 0) { LOG_DEBUG("RKID: %s\n", common_cmd->RKID); } else { LOG_DEBUG("RKID: Unknow\n"); return; } LOG_DEBUG("cmdID: %d\n", common_cmd->cmdID); switch (common_cmd->cmdID) { case CMD_ID_CAPTURE_STATUS: LOG_DEBUG("CmdID CMD_ID_CAPTURE_STATUS in\n"); if (common_cmd->dat[0] == KNOCK_KNOCK) { InitCommandPingAns(&send_cmd, READY); LOG_DEBUG("Device is READY\n"); } else { LOG_ERROR("Unknow CMD_ID_CAPTURE_STATUS message\n"); } memcpy(send_data, &send_cmd, sizeof(CommandData_t)); send(sockfd, send_data, sizeof(CommandData_t), 0); LOG_DEBUG("cmdID CMD_ID_CAPTURE_STATUS out\n\n"); break; case CMD_ID_GET_STATUS: DoAnswer(sockfd, &send_cmd, common_cmd->cmdID, READY); break; case CMD_ID_GET_MODE: DoAnswer(sockfd, &send_cmd, common_cmd->cmdID, g_app_run_mode); break; case CMD_ID_START_RTSP: if (g_rtsp_en_from_cmdarg == 1) { g_rtsp_en = 1; } ret = StartRTSP(); if (ret) { LOG_ERROR("start RTSP failed!!!\n"); } DoAnswer(sockfd, &send_cmd, common_cmd->cmdID, g_app_run_mode); break; case CMD_ID_STOP_RTSP: if (g_rtsp_en_from_cmdarg == 1) { g_rtsp_en = 0; } ret = StopRTSP(); if (ret) { LOG_ERROR("stop RTSP failed!!!\n"); } g_app_run_mode = APP_RUN_STATUS_INIT; DoAnswer(sockfd, &send_cmd, common_cmd->cmdID, g_app_run_mode); break; default: break; } } void RKAiqProtocol::HandlerReceiveFile(int sockfd, char* buffer, int size) { FileTransferData* recData = (FileTransferData*)buffer; LOG_DEBUG("HandlerReceiveFile begin\n"); // HexDump((unsigned char*)buffer, size); // parse data unsigned long long packetSize = recData->packetSize; LOG_DEBUG("FILETRANS receive : sizeof(packetSize):%d\n", sizeof(packetSize)); // HexDump((unsigned char*)&recData->packetSize, 8); LOG_DEBUG("FILETRANS receive : packetSize:%llu\n", packetSize); unsigned long long dataSize = recData->dataSize; LOG_DEBUG("FILETRANS receive : dataSize:%llu\n", dataSize); if (packetSize <= 0 || packetSize - dataSize > 500) { printf("FILETRANS no data received or packetSize error, return.\n"); char tmpBuf[200] = {0}; snprintf(tmpBuf, sizeof(tmpBuf), "##StatusMessage##FileTransfer##Failed##TransferError##"); std::string resultStr = tmpBuf; send(sockfd, (char*)resultStr.c_str(), resultStr.length(), 0); return; } char* receivedPacket = (char*)malloc(packetSize); memset(receivedPacket, 0, packetSize); memcpy(receivedPacket, buffer, size); unsigned long long remain_size = packetSize - size; int recv_size = 0; struct timespec startTime = {0, 0}; struct timespec currentTime = {0, 0}; clock_gettime(CLOCK_REALTIME, &startTime); LOG_DEBUG("FILETRANS get, start receive:%ld\n", startTime.tv_sec); while (remain_size > 0) { clock_gettime(CLOCK_REALTIME, ¤tTime); if (currentTime.tv_sec - startTime.tv_sec >= 20) { LOG_DEBUG("FILETRANS receive: receive data timeout, return\n"); char tmpBuf[200] = {0}; snprintf(tmpBuf, sizeof(tmpBuf), "##StatusMessage##FileTransfer##Failed##Timeout##"); std::string resultStr = tmpBuf; send(sockfd, (char*)resultStr.c_str(), resultStr.length(), 0); return; } unsigned long long offset = packetSize - remain_size; unsigned long long targetSize = 0; if (remain_size > MAX_PACKET_SIZE) { targetSize = MAX_PACKET_SIZE; } else { targetSize = remain_size; } recv_size = recv(sockfd, &receivedPacket[offset], targetSize, 0); remain_size = remain_size - recv_size; // LOG_DEBUG("FILETRANS receive,remain_size: %llu\n", remain_size); } LOG_DEBUG("FILETRANS receive: receive success, need check data\n"); // HexDump((unsigned char*)receivedPacket, packetSize); // Send(receivedPacket, packetSize); //for debug use // parse data FileTransferData receivedData; memset((void*)&receivedData, 0, sizeof(FileTransferData)); unsigned long long offset = 0; // magic memcpy(receivedData.RKID, receivedPacket, sizeof(receivedData.RKID)); // HexDump((unsigned char*)receivedData.RKID, sizeof(receivedData.RKID)); offset += sizeof(receivedData.RKID); // packetSize memcpy((void*)&receivedData.packetSize, receivedPacket + offset, sizeof(receivedData.packetSize)); offset += sizeof(receivedData.packetSize); // command id memcpy((void*)&(receivedData.commandID), receivedPacket + offset, sizeof(int)); offset += sizeof(int); // command result memcpy((void*)&(receivedData.commandResult), receivedPacket + offset, sizeof(int)); offset += sizeof(int); // target dir len memcpy((void*)&(receivedData.targetDirLen), receivedPacket + offset, sizeof(receivedData.targetDirLen)); offset += sizeof(receivedData.targetDirLen); LOG_DEBUG("FILETRANS receive: receivedData.targetDirLen:%d\n", receivedData.targetDirLen); // target dir memcpy((void*)&(receivedData.targetDir), receivedPacket + offset, sizeof(receivedData.targetDir)); // HexDump((unsigned char*)receivedData.targetDir, sizeof(receivedData.targetDir)); LOG_DEBUG("FILETRANS receive: receivedData.targetDir:%s\n", receivedData.targetDir); offset += sizeof(receivedData.targetDir); // target file name len memcpy((void*)&(receivedData.targetFileNameLen), receivedPacket + offset, sizeof(receivedData.targetFileNameLen)); offset += sizeof(receivedData.targetFileNameLen); LOG_DEBUG("FILETRANS receive: receivedData.targetFileNameLen:%d\n", receivedData.targetFileNameLen); // target file name memcpy((void*)&(receivedData.targetFileName), receivedPacket + offset, sizeof(receivedData.targetFileName)); // HexDump((unsigned char*)receivedData.targetFileName, sizeof(receivedData.targetFileName)); LOG_DEBUG("FILETRANS receive: receivedData.targetFileName:%s\n", receivedData.targetFileName); offset += sizeof(receivedData.targetFileName); // data size memcpy((void*)&(receivedData.dataSize), receivedPacket + offset, sizeof(unsigned long long)); LOG_DEBUG("FILETRANS receive: receivedData.dataSize:%u\n", receivedData.dataSize); offset += sizeof(unsigned long long); // data receivedData.data = (char*)malloc(receivedData.dataSize); memcpy(receivedData.data, receivedPacket + offset, receivedData.dataSize); offset += receivedData.dataSize; // data hash memcpy((void*)&(receivedData.dataHash), receivedPacket + offset, sizeof(unsigned int)); if (receivedPacket != NULL) { free(receivedPacket); receivedPacket = NULL; } // size check if (receivedData.dataSize != dataSize) { LOG_DEBUG("FILETRANS receive: receivedData.dataSize != target data size, return\n"); char tmpBuf[200] = {0}; snprintf(tmpBuf, sizeof(tmpBuf), "##StatusMessage##FileTransfer##Failed##DataSizeError##"); std::string resultStr = tmpBuf; send(sockfd, (char*)resultStr.c_str(), resultStr.length(), 0); return; } // hash check unsigned int dataHash = MurMurHash(receivedData.data, receivedData.dataSize); LOG_DEBUG("FILETRANS receive 2: dataHash calculated:%x\n", dataHash); LOG_DEBUG("FILETRANS receive: receivedData.dataHash:%x\n", receivedData.dataHash); if (dataHash == receivedData.dataHash) { LOG_DEBUG("FILETRANS receive: data hash check pass\n"); } else { LOG_DEBUG("FILETRANS receive: data hash check failed\n"); char tmpBuf[200] = {0}; snprintf(tmpBuf, sizeof(tmpBuf), "##StatusMessage##FileTransfer##Failed##HashCheckFail##"); std::string resultStr = tmpBuf; send(sockfd, (char*)resultStr.c_str(), resultStr.length(), 0); return; } // save to file std::string dstDir = (char*)receivedData.targetDir; std::string dstFileName = (char*)receivedData.targetFileName; std::string dstFilePath = dstDir + "/" + dstFileName; DIR* dirPtr = opendir(dstDir.c_str()); if (dirPtr == NULL) { LOG_DEBUG("FILETRANS target dir %s not exist, return \n", dstDir.c_str()); char tmpBuf[200] = {0}; snprintf(tmpBuf, sizeof(tmpBuf), "##StatusMessage##FileTransfer##Failed##DirError##"); std::string resultStr = tmpBuf; send(sockfd, (char*)resultStr.c_str(), resultStr.length(), 0); return; } else { closedir(dirPtr); } FILE* fWrite = fopen(dstFilePath.c_str(), "w"); if (fWrite != NULL) { fwrite(receivedData.data, receivedData.dataSize, 1, fWrite); } else { LOG_DEBUG("FILETRANS failed to create file %s, return\n", dstFilePath.c_str()); char tmpBuf[200] = {0}; snprintf(tmpBuf, sizeof(tmpBuf), "##StatusMessage##FileTransfer##Failed##FileSaveError##"); std::string resultStr = tmpBuf; send(sockfd, (char*)resultStr.c_str(), resultStr.length(), 0); return; } fclose(fWrite); if (receivedData.data != NULL) { free(receivedData.data); receivedData.data = NULL; } LOG_DEBUG("HandlerReceiveFile process finished.\n"); LOG_INFO("receive file %s finished.\n", dstFilePath.c_str()); char tmpBuf[200] = {0}; snprintf(tmpBuf, sizeof(tmpBuf), "##StatusMessage##FileTransfer##Success##%s##", dstFileName.c_str()); std::string resultStr = tmpBuf; send(sockfd, (char*)resultStr.c_str(), resultStr.length(), 0); } void RKAiqProtocol::HandlerOfflineRawProcess(int sockfd, char* buffer, int size) { OfflineRAW* recData = (OfflineRAW*)buffer; LOG_DEBUG("HandlerOfflineRawProcess begin\n"); // HexDump((unsigned char*)buffer, size); // parse data unsigned long long packetSize = recData->packetSize; LOG_DEBUG("receive : sizeof(packetSize):%d\n", sizeof(packetSize)); // HexDump((unsigned char*)&recData->packetSize, 8); LOG_DEBUG("receive : packetSize:%llu\n", packetSize); if (packetSize <= 0 || packetSize > 50) { printf("no data received or packetSize error, return.\n"); // char tmpBuf[200] = {0}; // snprintf(tmpBuf, sizeof(tmpBuf), "##StatusMessage##FileTransfer##Failed##TransferError##"); // std::string resultStr = tmpBuf; // send(sockfd, (char*)resultStr.c_str(), resultStr.length(), 0); return; } char* receivedPacket = (char*)malloc(packetSize); memset(receivedPacket, 0, packetSize); memcpy(receivedPacket, buffer, size); unsigned long long remain_size = packetSize - size; int recv_size = 0; struct timespec startTime = {0, 0}; struct timespec currentTime = {0, 0}; clock_gettime(CLOCK_REALTIME, &startTime); LOG_DEBUG("start receive:%ld\n", startTime.tv_sec); while (remain_size > 0) { clock_gettime(CLOCK_REALTIME, ¤tTime); if (currentTime.tv_sec - startTime.tv_sec >= 20) { LOG_DEBUG("receive: receive data timeout, return\n"); // char tmpBuf[200] = {0}; // snprintf(tmpBuf, sizeof(tmpBuf), "##StatusMessage##FileTransfer##Failed##Timeout##"); // std::string resultStr = tmpBuf; // send(sockfd, (char*)resultStr.c_str(), resultStr.length(), 0); return; } unsigned long long offset = packetSize - remain_size; unsigned long long targetSize = 0; if (remain_size > MAX_PACKET_SIZE) { targetSize = MAX_PACKET_SIZE; } else { targetSize = remain_size; } recv_size = recv(sockfd, &receivedPacket[offset], targetSize, 0); remain_size = remain_size - recv_size; // LOG_DEBUG("FILETRANS receive,remain_size: %llu\n", remain_size); } // HexDump((unsigned char*)receivedPacket, packetSize); // Send(receivedPacket, packetSize); //for debug use // parse data OfflineRAW receivedData; memset((void*)&receivedData, 0, sizeof(OfflineRAW)); unsigned long long offset = 0; // magic memcpy(receivedData.RKID, receivedPacket, sizeof(receivedData.RKID)); offset += sizeof(receivedData.RKID); // packetSize memcpy((void*)&receivedData.packetSize, receivedPacket + offset, sizeof(receivedData.packetSize)); offset += sizeof(receivedData.packetSize); // command id memcpy((void*)&(receivedData.commandID), receivedPacket + offset, sizeof(int)); offset += sizeof(int); // command result memcpy((void*)&(receivedData.commandResult), receivedPacket + offset, sizeof(int)); offset += sizeof(int); // mode control memcpy((void*)&(receivedData.offlineRawModeControl), receivedPacket + offset, sizeof(int)); offset += sizeof(int); // start process offline process if (receivedData.offlineRawModeControl == 1) // start { LOG_INFO("#### start offline RAW mode. ####\n"); forward_thread = std::unique_ptr(new std::thread(&RKAiqProtocol::offlineRawProcess)); forward_thread->detach(); LOG_INFO("#### offline RAW mode stopped. ####\n"); } else if (receivedData.offlineRawModeControl == 0) // stop { startOfflineRawFlag = 0; } else if (receivedData.offlineRawModeControl == 2) // remove ini file { LOG_DEBUG("#### remove offline RAW config file. ####\n"); system("rm -f /tmp/aiq_offline.ini && sync"); } LOG_DEBUG("HandlerOfflineRawProcess process finished.\n"); // char tmpBuf[200] = {0}; // snprintf(tmpBuf, sizeof(tmpBuf), "##StatusMessage##FileTransfer##Success##%s##", dstFileName.c_str()); // std::string resultStr = tmpBuf; // send(sockfd, (char*)resultStr.c_str(), resultStr.length(), 0); } static void ExecuteCMD(const char* cmd, char* result) { char buf_ps[2048]; char ps[2048] = {0}; FILE* ptr; strcpy(ps, cmd); if ((ptr = popen(ps, "r")) != NULL) { while (fgets(buf_ps, 2048, ptr) != NULL) { strcat(result, buf_ps); if (strlen(result) > 2048) { break; } } pclose(ptr); ptr = NULL; } else { printf("popen %s error\n", ps); } } void RKAiqProtocol::HandlerTCPMessage(int sockfd, char* buffer, int size) { CommandData_t* common_cmd = (CommandData_t*)buffer; LOG_DEBUG("HandlerTCPMessage:\n"); LOG_DEBUG("HandlerTCPMessage CommandData_t: 0x%lx\n", sizeof(CommandData_t)); LOG_DEBUG("HandlerTCPMessage RKID: %s\n", (char*)common_cmd->RKID); int resetThreadFlag = 1; // TODO Check APP Mode if (strcmp((char*)common_cmd->RKID, TAG_PC_TO_DEVICE) == 0) { char result[2048] = {0}; std::string pattern{"Isp online"}; std::regex re(pattern); std::smatch results; ExecuteCMD("cat /proc/rkisp0-vir0", result); std::string srcStr = result; // LOG_INFO("#### srcStr:%s\n", srcStr.c_str()); if (std::regex_search(srcStr, results, re)) // finded { LOG_INFO("Isp online, please use online raw capture.\n"); return; } RKAiqRawProtocol::HandlerRawCapMessage(sockfd, buffer, size); } else if (strcmp((char*)common_cmd->RKID, TAG_OL_PC_TO_DEVICE) == 0) { RKAiqOLProtocol::HandlerOnLineMessage(sockfd, buffer, size); } else if (strcmp((char*)common_cmd->RKID, RKID_CHECK) == 0) { HandlerCheckDevice(sockfd, buffer, size); } else if (memcmp((char*)common_cmd->RKID, RKID_SEND_FILE, 8) == 0) { HandlerReceiveFile(sockfd, buffer, size); } else if (memcmp((char*)common_cmd->RKID, RKID_OFFLINE_RAW, 6) == 0) { HandlerOfflineRawProcess(sockfd, buffer, size); } else { resetThreadFlag = 0; if (!DoChangeAppMode(APP_RUN_STATUS_TUNRING)) MessageForward(sockfd, buffer, size); } } int RKAiqProtocol::doMessageForward(int sockfd) { is_recv_running = true; while (is_recv_running) { char recv_buffer[MAXPACKETSIZE] = {0}; int recv_len = g_tcpClient.Receive(recv_buffer, MAXPACKETSIZE); if (recv_len > 0) { ssize_t ret = send(sockfd, recv_buffer, recv_len, 0); if (ret < 0) { LOG_ERROR("#########################################################\n"); LOG_ERROR("## Forward socket %d failed, please check AIQ status.####\n", sockfd); LOG_ERROR("#########################################################\n\n"); close(sockfd); std::lock_guard lk(mutex_); is_recv_running = false; return -1; } } else if (recv_len < 0 && errno != EAGAIN) { g_tcpClient.Close(); close(sockfd); std::lock_guard lk(mutex_); is_recv_running = false; return -1; } } std::lock_guard lk(mutex_); is_recv_running = false; return 0; } int RKAiqProtocol::offlineRawProcess() { startOfflineRawFlag = 1; LOG_DEBUG("offlineRawProcess begin\n"); while (startOfflineRawFlag == 1) { DIR* dir = opendir("/data/OfflineRAW"); struct dirent* dir_ent = NULL; std::vector raw_files; if (dir) { while ((dir_ent = readdir(dir))) { if (dir_ent->d_type == DT_REG) { // is raw file if (strstr(dir_ent->d_name, ".raw")) { raw_files.push_back(dir_ent->d_name); } } } closedir(dir); } if (raw_files.size() == 0) { LOG_INFO("No raw files in /data/OfflineRAW\n"); return 1; } std::sort(raw_files.begin(), raw_files.end()); for (auto raw_file : raw_files) { cout << raw_file.c_str() << endl; if (startOfflineRawFlag == 0) { break; } LOG_DEBUG("ENUM_ID_SYSCTL_ENQUEUERKRAWFILE begin\n"); struct timeval tv; struct timezone tz; gettimeofday(&tv, &tz); long startTime = tv.tv_sec * 1000 + tv.tv_usec / 1000; LOG_DEBUG("begin millisecond: %ld\n", startTime); // ms std::string filePath = "/data/OfflineRAW/" + raw_file; LOG_INFO("process raw : %s \n", filePath.c_str()); if (RkAiqSocketClientINETSend(ENUM_ID_SYSCTL_ENQUEUERKRAWFILE, (void*)filePath.c_str(), (unsigned int)filePath.length() + 1) != 0) { LOG_ERROR("########################################################\n"); LOG_ERROR("#### OfflineRawProcess failed. Please check AIQ.####\n"); LOG_ERROR("########################################################\n\n"); return 1; } uint32_t frameInterval = 1000 / g_offlineFrameRate; std::this_thread::sleep_for(std::chrono::milliseconds(frameInterval)); gettimeofday(&tv, &tz); long endTime = tv.tv_sec * 1000 + tv.tv_usec / 1000; LOG_DEBUG("end millisecond: %ld\n", endTime); // ms LOG_DEBUG("####################################### time spend: %ld ms\n", endTime - startTime); // ms LOG_DEBUG("ENUM_ID_SYSCTL_ENQUEUERKRAWFILE end\n"); } } std::lock_guard lk(mutex_); LOG_DEBUG("offlineRawProcess end\n"); return 0; } int RKAiqProtocol::MessageForward(int sockfd, char* buffer, int size) { LOG_DEBUG("[%s]got data:%d!\n", __func__, size); // HexDump((unsigned char*)buffer, size); int ret = g_tcpClient.Send((char*)buffer, size); if (ret < 0 && (errno != EAGAIN && errno != EINTR)) { if (ConnectAiq() < 0) { g_tcpClient.Close(); g_app_run_mode = APP_RUN_STATUS_INIT; LOG_ERROR("########################################################\n"); LOG_ERROR("#### Forward to AIQ failed! please check AIQ status.####\n"); LOG_ERROR("########################################################\n\n"); close(sockfd); is_recv_running = false; return -1; } else { LOG_ERROR("########################################################\n"); LOG_ERROR("#### Forward to AIQ failed! Auto reconnect success.####\n"); LOG_ERROR("########################################################\n\n"); } } std::lock_guard lk(mutex_); if (is_recv_running) { return 0; } #if 0 if (forward_thread && forward_thread->joinable()) forward_thread->join(); #endif forward_thread = std::unique_ptr(new std::thread(&RKAiqProtocol::doMessageForward, sockfd)); forward_thread->detach(); return 0; } void RKAiqProtocol::Exit() { { std::lock_guard lk(mutex_); is_recv_running = false; } #if 0 if (forward_thread && forward_thread->joinable()) { forward_thread->join(); } #endif }