int manage_client() { int highest; int err; g_zappy->read.fdl[0] = 1; g_zappy->read.fdl[1] = g_zappy->fd; g_zappy->write.fdl[0] = 0; highest = g_zappy->fd; g_zappy->highest = &highest; g_zappy->is_paused = 0; while (1) { if ((err = recv_client())) return (err); if ((err = update())) return (err); if ((err = is_game_ended()) >= 0) return (err); if (!g_zappy->is_paused) update_nourriture(); if (!g_zappy->speed_mode) usleep(10000); } return (0); }
/** * test_server_loop() 関数テスト * * @return なし */ void test_server_loop(void) { pid_t cpid = 0; /* 子プロセスID */ pid_t w = 0; /* wait戻り値 */ int status = 0; /* wait引数 */ int retval = 0; /* 戻り値 */ int count = 1; /* ループカウント */ if (set_port_string(port) < 0) cut_error("set_port_string"); ssock = server_sock(); cpid = fork(); if (cpid < 0) { cut_error("fork(%d)", errno); return; } if (cpid == 0) { dbglog("child"); count = 2; g_sig_handled = 1; while (count--) server_loop(ssock); exit(EXIT_SUCCESS); } else { dbglog("parent: cpid=%d", (int)cpid); csock = inet_sock_client(); if (csock < 0) return; /* 送信 */ retval = send_client(csock, expr, sizeof(expr)); if (retval < 0) { cut_error("send_client: csock=%d(%d)", csock, errno); return; } /* 受信 */ retval = recv_client(csock, readbuf); if (retval < 0) { cut_error("recv_client: csock=%d(%d)", csock, errno); return; } cut_assert_equal_string((char *)expected, (char *)readbuf); w = wait(&status); if (w < 0) cut_notify("wait(%d)", errno); dbglog("w=%d", (int)w); } }
DWORD WINAPI recvfunc(LPVOID pointerToObject) { while (true) { char* bal = recv_client(pointerToObject); std::cout<<"BAL: "<<bal<<"\n"; if (strncmp( bal, "1", 1) == 0) { std::cout<<"RETURNED PROPERLY!\n"; return 1; } } return 0; }
/** * test_server_proc() 関数テスト * * @return なし */ void test_server_proc(void) { pid_t cpid = 0; /* 子プロセスID */ pid_t w = 0; /* wait戻り値 */ int status = 0; /* wait引数 */ int retval = 0; /* 戻り値 */ thread_data *dt = NULL; /* ソケット情報構造体 */ void *servret = NULL; /* テスト関数戻り値 */ if (set_port_string(port) < 0) cut_error("set_port_string"); ssock = server_sock(); cpid = fork(); if (cpid < 0) { cut_error("fork(%d)", errno); return; } if (cpid == 0) { dbglog("child"); dt = (thread_data *)malloc(sizeof(thread_data)); if (!dt) { outlog("malloc: size=%zu", sizeof(thread_data)); exit(EXIT_FAILURE); } (void)memset(dt, 0, sizeof(thread_data)); dt->len = (socklen_t)sizeof(dt->addr); dt->sock = accept(ssock, (struct sockaddr *)&dt->addr, &dt->len); if (dt->sock < 0) { outlog("accept: ssock=%d", ssock); memfree((void **)&dt, NULL); exit(EXIT_FAILURE); } g_sig_handled = 1; /* テスト関数実行 */ servret = server.server_proc(dt); if (servret) { outlog("server_proc"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } else { dbglog("parent: cpid=%d", (int)cpid); csock = inet_sock_client(); if (csock < 0) return; /* 送信 */ retval = send_client(csock, expr, sizeof(expr)); if (retval < 0) { cut_error("send_client: csock=%d(%d)", csock, errno); return; } /* 受信 */ retval = recv_client(csock, readbuf); if (retval < 0) { cut_error("recv_client: csock=%d(%d)", csock, errno); return; } cut_assert_equal_string((char *)expected, (char *)readbuf); w = wait(&status); if (w < 0) cut_notify("wait(%d)", errno); dbglog("w=%d", (int)w); if (WEXITSTATUS(status)) cut_error("child failed"); } }
int main(int argc, char* argv[]) { int opt, ret; int daemon = 1, lock = 0; int screen_status, aux_pressed, power_pressed, y, x; char *config; FILE *file; struct sockaddr_un addr; struct chain_socket *aux_grabber = 0, *power_grabber = 0; struct input_event input; struct iod_cmd cmd; struct chain_socket *cs; size_t size; y = x = screen_status = aux_pressed = power_pressed = 0; pwd = IOD_PWD; while((opt = getopt(argc, argv, "fd:")) != -1) { switch(opt) { case 'f': daemon = 0; break; case 'd': pwd = optarg; break; default: usage(argv[0]); return 0; } } if(optind == argc) { usage(argv[0]); return 0; } config = argv[optind]; if(mkdir(pwd, 0777) == -1 && errno != EEXIST) { perror("Failed to create working dir"); return 7; } if(daemon) { int tmp = fork(); if(tmp < 0) { perror("Failed to fork process"); return 1; } if(tmp > 0) { return 0; } setsid(); close(0); close(1); close(2); tmp = open("/dev/null", O_RDWR); dup(tmp); dup(tmp); chdir(pwd); if((tmp = open("pid", O_WRONLY|O_CREAT, 755)) < 0) { perror("Failed to open pidfile"); return 2; } pid_t pid = getpid(); char buf[10]; int count = sprintf(buf, "%i", pid); write(tmp, &buf, count*sizeof(char)); if(lockf(tmp, F_TLOCK, -count*sizeof(char)) < 0) { perror("Daemon already running"); return 3; } } if(!(file = fopen(config, "r"))) { perror("Failed to open config file"); return 4; } if((size = getline(&screen_dev, &size, file)) == -1) { fprintf(stderr, "Failed to read screen config\n"); return 5; } screen_dev[size-1] = 0; if((screen_fd = open(screen_dev, O_RDONLY)) == -1) { perror("Failed to open screen socket"); return 6; } if((size = getline(&aux_dev, &size, file)) == -1) { fprintf(stderr, "Failed to read aux config\n"); return 7; } aux_dev[size-1] = 0; if((aux_fd = open(aux_dev, O_RDONLY)) == -1) { perror("Failed to open aux socket"); return 8; } if((size = getline(&power_dev, &size, file)) == -1) { fprintf(stderr, "Failed to read power config\n"); return 9; } power_dev[size-1] = 0; fclose(file); if((power_fd = open(power_dev, O_RDONLY)) == -1) { perror("Failed to open power socket"); return 10; } DEBUG(print_info(screen_fd)); DEBUG(print_info(aux_fd)); DEBUG(print_info(power_fd)); if((ret = open_socket(&sock, &addr))) return ret; pfds_cap = 10; pfds = malloc(pfds_cap*sizeof(struct pollfd)); pfds[0].fd = screen_fd; pfds[0].events = POLLIN; pfds[1].fd = aux_fd; pfds[1].events = POLLIN; pfds[2].fd = power_fd; pfds[2].events = POLLIN; pfds[3].fd = sock; pfds[3].events = POLLIN; client_count = 0; CIRCLEQ_INIT(&client_list); signal(SIGINT, signal_handler); DEBUG(printf("Ready\n")); while(1) { poll(pfds, client_count+4, -1); if(pfds[0].revents & POLLHUP || pfds[0].revents & POLLERR) { DEBUG(printf("pollhup/err on screen socket\n")); close(screen_fd); if((screen_fd = open(screen_dev, O_RDONLY)) < 0) { perror("Failed to open screen socket"); screen_fd = 0; cleanup(); return 6; } } else if(pfds[0].revents & POLLIN) { read(screen_fd, &input, sizeof(struct input_event)); if(lock) continue; switch(input.type) { case EV_KEY: switch(input.code) { case BTN_TOUCH: switch(input.value) { case 0: screen_status = 0; break; case 1: screen_status = 1; break; } break; } break; case EV_ABS: switch(input.code) { case ABS_X: y = input.value-MIN_PIXEL; break; case ABS_Y: x = input.value-MIN_PIXEL; break; case ABS_PRESSURE: break; } break; case EV_SYN: switch(input.code) { case SYN_REPORT: switch(screen_status) { case 0: DEBUG(printf("Touchscreen released (%i,%i)\n", y, x)); send_client_cord(IOD_EVENT_RELEASED, y, x, 0); break; case 1: DEBUG(printf("Touchscreen pressed (%i,%i)\n", y, x)); send_client_cord(IOD_EVENT_PRESSED, y, x, 0); screen_status = 2; break; case 2: send_client_cord(IOD_EVENT_MOVED, y, x, 0); break; } break; } break; } } else if(pfds[1].revents & POLLHUP || pfds[1].revents & POLLERR) { DEBUG(printf("pollhup/err on aux socket\n")); close(aux_fd); if((aux_fd = open(aux_dev, O_RDONLY)) == -1) { perror("Failed to open aux socket"); aux_fd = 0; cleanup(); return 8; } } else if(pfds[1].revents & POLLIN) { read(aux_fd, &input, sizeof(struct input_event)); switch(input.type) { case EV_KEY: switch(input.code) { case KEY_PHONE: aux_pressed = input.value; break; } break; case EV_SYN: switch(input.code) { case SYN_REPORT: DEBUG(printf("AUX %s\n", aux_pressed ? "pressed" : "released")); cs = aux_grabber ? aux_grabber : 0; send_client_status(IOD_EVENT_AUX, aux_pressed, cs); break; } break; } } else if(pfds[2].revents & POLLHUP || pfds[2].revents & POLLERR) { DEBUG(printf("pollhup/err on power socket\n")); close(power_fd); if((power_fd = open(power_dev, O_RDONLY)) == -1) { perror("Failed to open power socket"); power_fd = 0; cleanup(); return 10; } } else if(pfds[2].revents & POLLIN) { read(power_fd, &input, sizeof(struct input_event)); switch(input.type) { case EV_KEY: switch(input.code) { case KEY_POWER: power_pressed = input.value; break; } break; case EV_PWR: break; case EV_SYN: switch(input.code) { case SYN_REPORT: DEBUG(printf("Power %s\n", power_pressed ? "pressed" : "released")); cs = power_grabber ? power_grabber : 0; send_client_status(IOD_EVENT_POWER, power_pressed, cs); break; } break; } } else if(pfds[3].revents & POLLHUP || pfds[3].revents & POLLERR) { DEBUG(printf("pollhup/err on socket\n")); close(sock); if((ret = open_socket(&sock, &addr))) { sock = 0; cleanup(); return ret; } } else if(pfds[3].revents & POLLIN) { int client; if((client = accept(sock, 0, 0)) == -1) { DEBUG(perror("Failed to accept client")); continue; } cs = client_list.cqh_first; add_client(client); if(cs != (void*)&client_list) send_client_status(IOD_EVENT_DEACTIVATED, 0, cs); else send_client_status(IOD_EVENT_ACTIVATED, 0, 0); } else { int x; for(x=4; x<client_count+4; x++) if(pfds[x].revents & POLLHUP || pfds[x].revents & POLLERR) { DEBUG(printf("pollhup/pollerr on client socket [%i]\n", pfds[x].fd)); cs = find_client(&x, 0); remove: if(cs == aux_grabber) { DEBUG(printf("AUX ungrabbed [%i] %i\n", cs->sock, cs->pid)); aux_grabber = 0; } if(cs == power_grabber) { DEBUG(printf("Power ungrabbed [%i] %i\n", cs->sock, cs->pid)); power_grabber = 0; } if(cs->lock) { DEBUG(printf("Screen unlocked [%i] %i\n", cs->sock, cs->pid)); lock = 0; } if(rem_client(x, cs)) send_client_status(IOD_EVENT_ACTIVATED, 0, 0); break; } else if(pfds[x].revents & POLLIN) { if(recv_client(pfds[x].fd, &cmd)) break; switch(cmd.cmd) { case IOD_CMD_REGISTER: register_client(x, cmd.pid); break; case IOD_CMD_REMOVE: if((cs = find_client(&x, cmd.pid))) { if(cs->sock == pfds[x].fd) goto remove; else { DEBUG(printf("Client remove [%i] %i\n", cs->sock, cs->pid)); send_client_status( IOD_EVENT_REMOVED, 0, cs); } } break; case IOD_CMD_SWITCH: cs = client_list.cqh_first; if(switch_client(cmd.value, x, cmd.pid)) send_client_status( IOD_EVENT_DEACTIVATED, 0, cs); break; case IOD_CMD_LOCK: cs = find_client(&x, 0); if(!lock || cs->lock) { lock = cs->lock = cmd.value; DEBUG(printf("Screen %s [%i] %i\n", lock ? "locked" : "unlocked", x, cs->pid)); send_client_status( IOD_EVENT_LOCK, IOD_SUCCESS_MASK, cs); } else send_client_status( IOD_EVENT_LOCK, 0, cs); break; case IOD_CMD_HIDE: hide_client(x, cmd.pid, cmd.value & ~IOD_HIDE_MASK, cmd.value & IOD_HIDE_MASK); break; case IOD_CMD_ACK: switch(cmd.value) { case IOD_EVENT_DEACTIVATED: cs = client_list.cqh_first; DEBUG(printf("Client switched [%i] %i -> [%i] %i\n", pfds[x].fd, find_client(&x, 0)->pid, cs->sock, cs->pid)); send_client_status( IOD_EVENT_ACTIVATED, 0, 0); break; case IOD_EVENT_REMOVED: cs = find_client(&x, 0); goto remove; default: DEBUG(printf("Client done [%i] %i\n", pfds[x].fd, find_client(&x, 0)->pid)); break; } break; case IOD_CMD_GRAB: cs = find_client(&x, 0); switch(cmd.value & ~IOD_GRAB_MASK) { case IOD_GRAB_AUX: if(!aux_grabber || cs == aux_grabber) { if(cmd.value & IOD_GRAB_MASK) { DEBUG(printf("AUX grabbed [%i] %i\n", cs->sock, cs->pid)); aux_grabber = cs; } else { DEBUG(printf("AUX ungrabbed [%i] %i\n", cs->sock, cs->pid)); aux_grabber = 0; } send_client_status(IOD_EVENT_GRAB, IOD_SUCCESS_MASK|IOD_GRAB_AUX, cs); } else send_client_status(IOD_EVENT_GRAB, IOD_GRAB_AUX, cs); break; case IOD_GRAB_POWER: if(!power_grabber || cs == power_grabber) { if(cmd.value & IOD_GRAB_MASK) { DEBUG(printf("Power grabbed [%i] %i\n", cs->sock, cs->pid)); power_grabber = cs; } else { DEBUG(printf("Power ungrabbed [%i] %i\n", cs->sock, cs->pid)); power_grabber = 0; } send_client_status(IOD_EVENT_GRAB, IOD_SUCCESS_MASK|IOD_GRAB_POWER, cs); } else send_client_status(IOD_EVENT_GRAB, IOD_GRAB_POWER, cs); break; } break; case IOD_CMD_POWERSAVE: DEBUG(printf("Powersave %s broadcast\n", cmd.value ? "on" : "off")); cs = client_list.cqh_first; while(cs != (void*)&client_list) { if(cs->sock != pfds[x].fd) send_client_status( IOD_EVENT_POWERSAVE, cmd.value, cs); cs = cs->chain.cqe_next; } break; default: DEBUG(printf("Unrecognized command 0x%02hhx [%i] %i\n", cmd.cmd, pfds[x].fd, find_client(&x, 0)->pid)); } break; } } } cleanup(); return 0; }
void redrobd_rc_net_server_thread::handle_clients(void) { long rc; socket_address client_sa; char client_ip[DOTTED_IP_ADDR_LEN]; ostringstream oss_msg; while (1) { oss_msg << "Wait for client on port:" << dec << m_server_port; redrobd_log_writeln(get_name() + " : " + oss_msg.str()); oss_msg.str(""); // Wait for client to connect rc = accept_socket(m_server_sd, &m_client_sd, &client_sa); // Check if controlled server shutdown if ( (rc != SOCKET_SUPPORT_SUCCESS) && (m_shutdown_requested) ) { // This was a controlled shutdown. // Quit server thread with no error. break; } else if (rc != SOCKET_SUPPORT_SUCCESS) { // This was not a controlled shutdown. // Quit server thread with error. THROW_EXP(REDROBD_INTERNAL_ERROR, REDROBD_SOCKET_OPERATION_FAILED, "Accept server socket failed in thread %s", get_name().c_str()); } else { m_client_connected = true; } // Get address info for connected client if (to_ip_address(client_sa.net_addr, client_ip, DOTTED_IP_ADDR_LEN) != SOCKET_SUPPORT_SUCCESS) { THROW_EXP(REDROBD_INTERNAL_ERROR, REDROBD_SOCKET_OPERATION_FAILED, "Client address for server socket failed in thread %s", get_name().c_str()); } oss_msg << "Client connected => " << client_ip << ", port:" << dec << client_sa.port; redrobd_log_writeln(get_name() + " : " + oss_msg.str()); oss_msg.str(""); // Handle client commands bool handle_command = true; while (handle_command) { try { uint16_t client_command; // Wait for command recv_client((void *)&client_command, sizeof(client_command)); ntoh16(&client_command); // Handle command if (client_command == CLI_CMD_STEER) { uint8_t steer_code; // Get steer code recv_client((void *)&steer_code, sizeof(steer_code)); // Update latest steer code pthread_mutex_lock(&m_steer_code_mutex); m_steer_code = steer_code; pthread_mutex_unlock(&m_steer_code_mutex); } else if (client_command == CLI_CMD_GET_VOLTAGE) { uint16_t voltage; // Reply with latest voltage pthread_mutex_lock(&m_voltage_mutex); voltage = m_voltage; pthread_mutex_unlock(&m_voltage_mutex); hton16(&voltage); send_client((void *)&voltage, sizeof(voltage)); } else if (client_command == CLI_CMD_CAMERA) { uint8_t camera_code; // Get camera code recv_client((void *)&camera_code, sizeof(camera_code)); // Update latest camera code pthread_mutex_lock(&m_camera_code_mutex); m_camera_code = camera_code; pthread_mutex_unlock(&m_camera_code_mutex); } else if (client_command == CLI_CMD_GET_SYS_STATS) { RC_NET_SYS_STAT sys_stat; // Reply with latest system statistics pthread_mutex_lock(&m_sys_stat_mutex); memcpy(&sys_stat, &m_sys_stat, sizeof(m_sys_stat)); pthread_mutex_unlock(&m_sys_stat_mutex); hton32(&sys_stat.mem_used); hton16(&sys_stat.irq); hton32(&sys_stat.uptime); hton32(&sys_stat.cpu_temp); hton16(&sys_stat.cpu_voltage); hton16(&sys_stat.cpu_freq); send_client((void *)&sys_stat, sizeof(sys_stat)); } else { oss_msg << "Unknown client command : 0x" << hex << (unsigned)client_command; redrobd_log_writeln(get_name() + " : " + oss_msg.str()); oss_msg.str(""); handle_command = false; } } catch (...) { handle_command = false; } } if (m_shutdown_requested) { // This was a controlled shutdown. // Quit server thread with no error. break; } // Shutdown client socket if (shutdown_socket(m_client_sd, true, true) != SOCKET_SUPPORT_SUCCESS) { THROW_EXP(REDROBD_INTERNAL_ERROR, REDROBD_SOCKET_OPERATION_FAILED, "Shutdown client socket failed in thread %s", get_name().c_str()); } // Close client socket if (close_socket(m_client_sd) != SOCKET_SUPPORT_SUCCESS) { THROW_EXP(REDROBD_INTERNAL_ERROR, REDROBD_SOCKET_OPERATION_FAILED, "Close client socket failed in thread %s", get_name().c_str()); } m_client_connected = false; } }