#include #include #include #include #include #include #include #include #include "../socket_protocol.h" #include "../thread_pool.h" #include "../log_handle.h" #include "server_api.h" #include "server_core.h" #include "capture_image.h" #include "mini_shell.h" #include "isp_handle.h" #include "raw_flow_opt.h" #define SERVER_THREADS_MAX 20 enum server_flag_e { SERVER_FLAG_INIT_NOT = 0x00, SERVER_FLAG_INIT_YES = 0x01, SERVER_FLAG_STOP_NOT = 0x02, SERVER_FLAG_STOP_YES = 0x03, }; static int g_server_init_flag = SERVER_FLAG_INIT_NOT; static int g_server_socket_fd = -1; static int g_server_stop_flag = SERVER_FLAG_STOP_NOT; /* *length of question/answer cannot be greater than sock_packet.reserved in bytes * for current, the lenght are both 16, sock_packet.reserved is 16 */ #define SERVER_SOCK_QUESTION "wHo Am i? woOOo" #define SERVER_SOCK_ANSWER "WHos yoUR daddY" static int client_handle(int sock_fd) { int ret = -1; static sock_packet comm_packet; thread_work_func thread_func_ptr = NULL; LOG("%s: starts - %d\n", __FUNCTION__, sock_fd); // 1. ack question pack_packet(&comm_packet); comm_packet.cmd_ids[0] = SOCK_CMD_ACK; comm_packet.cmd_ids[1] = SOCK_CMD_ACK_QUESTION; comm_packet.ret = htonl(SOCK_CMD_RET_OK); strcpy((char *)comm_packet.reserved, SERVER_SOCK_QUESTION); ret = sock_write_check_packet(__FUNCTION__, sock_fd, &comm_packet, SOCK_CMD_ACK, SOCK_DEFAULT_TIMEOUT); if (ret != SOCK_RW_CHECK_OK) { LOG("%s: failed to write and check\n", __FUNCTION__); close(sock_fd); return -1; } if (comm_packet.cmd_ids[1] != SOCK_CMD_ACK_ANSWER || strncmp((const char *)comm_packet.reserved, SERVER_SOCK_ANSWER, sizeof(comm_packet.reserved))) { ((char *)comm_packet.reserved)[sizeof(comm_packet.reserved) - 1] = '\0'; LOG("%s: wrong answer: %d, %s\n", __FUNCTION__, comm_packet.cmd_ids[1], (const char *)comm_packet.reserved); close(sock_fd); return -1; } switch (comm_packet.cmd_ids[2]) { case SOCK_TYPE_HEART_JUMP: thread_func_ptr = &sock_handle_heart_jump_thread; break; case SOCK_TYPE_PREVIEW: thread_func_ptr = &sock_handle_preview_thread; break; case SOCK_TYPE_CAPTURE: thread_func_ptr = &sock_handle_capture_thread; break; case SOCK_TYPE_TUNING: thread_func_ptr = &sock_handle_tuning_thread; break; case SOCK_TYPE_STATISTICS: thread_func_ptr = &sock_handle_statistics_thread; break; case SOCK_TYPE_SCRIPT: thread_func_ptr = &sock_handle_script_thread; break; case SOCK_TYPE_REGOPT: thread_func_ptr = &sock_handle_register_thread; break; case SOCK_TYPE_AELV: thread_func_ptr = &sock_handle_aelv_thread; break; case SOCK_TYPE_SET_INPUT: thread_func_ptr = &sock_handle_set_input_thread; break; case SOCK_TYPE_RAW_FLOW: thread_func_ptr = &sock_handle_raw_flow_thread; break; case SOCK_TYPE_ISP_VERSION: thread_func_ptr = &sock_handle_isp_version_thread; break; #if 1 case SOCK_CMD_EXIT: LOG("%s: recv exit\n", __FUNCTION__); g_server_stop_flag = SERVER_FLAG_STOP_YES; close(sock_fd); return -1; #endif default: LOG("%s: unknown request(%d)\n", __FUNCTION__, comm_packet.cmd_ids[2]); close(sock_fd); return -1; } // 3. add work ret = add_work(thread_func_ptr, (void *)(intptr_t)sock_fd); // 4. reply //pack_packet(&comm_packet); //comm_packet.cmd_ids[0] = SOCK_CMD_ACK; comm_packet.cmd_ids[1] = SOCK_CMD_ACK_RET; if (ret < 0) { comm_packet.ret = htonl(SOCK_CMD_RET_FAILED); ret = sock_write(sock_fd, (const void *)&comm_packet, sizeof(comm_packet), SOCK_DEFAULT_TIMEOUT); close(sock_fd); LOG("%s: threads out of range\n", __FUNCTION__); return -1; } else { comm_packet.ret = htonl(SOCK_CMD_RET_OK); ret = sock_write(sock_fd, (const void *)&comm_packet, sizeof(comm_packet), SOCK_DEFAULT_TIMEOUT); } return 0; } static void reset_server_params() { g_server_init_flag = SERVER_FLAG_INIT_NOT; g_server_socket_fd = -1; g_server_stop_flag = SERVER_FLAG_STOP_NOT; } /* * get ip address by socket * returns 0 if OK, -1 if something went wrong */ int get_sock_ip(int sock_fd, char *ip_addr) { struct ifconf if_config = { 0 }; struct ifreq *if_req = NULL; char buf[512] = { 0 }, *ip0 = NULL; int i = 0, ret = -1; if (sock_fd < 0 || !ip_addr) { return -1; } if_config.ifc_len = sizeof(buf); if_config.ifc_buf = buf; if (ioctl(sock_fd, SIOCGIFCONF, &if_config) < 0) { return -1; } if_req = if_config.ifc_req; for (i = if_config.ifc_len / sizeof(struct ifreq); i > 0; i--) { ip0 = inet_ntoa(((struct sockaddr_in *)&(if_req->ifr_addr))->sin_addr); LOG(" ip: %s, name: %s\n", ip0, if_req->ifr_name); if (ret < 0 && strncmp(ip0, "127.0", 4) && !strncmp(if_req->ifr_name, "eth", 3)) { strcpy(ip_addr, ip0); ret = 0; } if_req++; } return ret; } /* * init server * returns 0 if init success, <0 if something went wrong */ int init_server(int port) { struct sockaddr_in server_socket_addr = { 0 }; char ip_addr[64] = { 0 }, *ip = NULL; int ret = -1; #ifdef FUNCTION_END_FLAG #undef FUNCTION_END_FLAG #endif #define FUNCTION_END_FLAG _##__FUNCTION__##_END_ if (SERVER_FLAG_INIT_YES == g_server_init_flag) { exit_server(); } reset_server_params(); server_socket_addr.sin_family = AF_INET; server_socket_addr.sin_port = htons(port); server_socket_addr.sin_addr.s_addr = htons(INADDR_ANY); // creat sever socket ret = socket(AF_INET, SOCK_STREAM, 0); if (-1 == ret) { LOG("%s: failed to create socket(%d, %s)\n", __FUNCTION__, errno, strerror(errno)); return -1; } g_server_socket_fd = ret; if (get_sock_ip(g_server_socket_fd, ip_addr) == 0) { ip = ip_addr; } else { ip = "unknown host"; } LOG("%s: ready to start server: %s:%d ++++++++++++++++++++++++\n", __FUNCTION__, ip, port) // ignoral pipe error signal(SIGPIPE, SIG_IGN); // bind ret = bind(g_server_socket_fd, (struct sockaddr*)&server_socket_addr, sizeof(server_socket_addr)); if (-1 == ret) { LOG("%s: failed to bind socket(%d, %s)\n", __FUNCTION__, errno, strerror(errno)); goto FUNCTION_END_FLAG; } //listen ret = listen(g_server_socket_fd, SERVER_THREADS_MAX); if (-1 == ret) { LOG("%s: failed to listen socket(%d, %s)\n", __FUNCTION__, errno, strerror(errno)); goto FUNCTION_END_FLAG; } LOG("%s: server starts: %s:%d ++++++++++++++++++++++++\n", __FUNCTION__, ip, port); ret = init_thread_pool(); if (ret < 0) { LOG("%s: failed to init thread pool\n", __FUNCTION__); goto FUNCTION_END_FLAG; } ret = init_capture_module(); if (CAP_ERR_NONE != ret) { LOG("%s: failed to init capture module\n", __FUNCTION__); } //ret = init_isp_module(); //if (ret < 0) { // LOG("%s: failed to init isp module\n", __FUNCTION__); //} //ret = select_isp(0); //if (ret < 0) { // LOG("%s: failed to select isp 0\n", __FUNCTION__); //} ///// #if 0 msleep(1000); LOG("%s: ready to select isp 0\n", __FUNCTION__); ret = select_isp(0); if (ret < 0) { LOG("%s: failed to select isp 0\n", __FUNCTION__); } LOG("%s: ready to select isp 0, DONE\n", __FUNCTION__); #endif ret = init_mini_shell(NULL); if (0 != ret) { LOG("%s: failed to init mini shell\n", __FUNCTION__); } g_server_init_flag = SERVER_FLAG_INIT_YES; LOG("%s: init done\n", __FUNCTION__); return 0; FUNCTION_END_FLAG: close(g_server_socket_fd); g_server_socket_fd = -1; g_server_init_flag = SERVER_FLAG_INIT_NOT; return ret; } /* * run server * this function will be running until get some exit message from client/server * returns 0 if exit normal, <0 if something went wrong */ int run_server() { int ret = -1; int client_socket = -1; int try_times = 0; struct sockaddr_in client_socket_addr; socklen_t client_socket_addr_len = sizeof(client_socket_addr); if (SERVER_FLAG_INIT_YES == g_server_init_flag) { while (1) { if (SERVER_FLAG_STOP_YES == g_server_stop_flag) { LOG("%s: recv stop flag\n", __FUNCTION__); return 0; } ret = CheckThreadsStatus(); if (ret & TH_STATUS_SERVER_QUIT) { LOG("%s: recv STOP, ready to stop server(%08x)...\n", __FUNCTION__, ret); try_times = 0; while ((try_times++ < 100) && (ret & 0x00FFFFFF)) { msleep(32); ret = CheckThreadsStatus(); } LOG("%s: exits(%d, %08x)\n", __FUNCTION__, try_times, ret); return 0; } memset(&client_socket_addr, 0, sizeof(client_socket_addr)); client_socket = socket_accept(g_server_socket_fd, (struct sockaddr*)&client_socket_addr, &client_socket_addr_len, SOCK_DEFAULT_TIMEOUT); if (client_socket >= 0) { ret = client_handle(client_socket); } else { if (!SHOULD_TRY_AGAIN()) { LOG("%s: failed to accept(%d, %s)\n", __FUNCTION__, errno, strerror(errno)); return -1; } else { errno = 0; } } msleep(1); } } LOG("%s: not init yet\n", __FUNCTION__); return -1; } /* * exit server * clean and exit */ void exit_server() { g_server_stop_flag = SERVER_FLAG_STOP_YES; if (SERVER_FLAG_INIT_YES == g_server_init_flag) { close(g_server_socket_fd); g_server_socket_fd = -1; g_server_init_flag = SERVER_FLAG_INIT_NOT; } exit_mini_shell(); exit_isp_module(); exit_capture_module(); exit_thread_pool(); LOG("%s: exits\n", __FUNCTION__); }