#pragma once #include #include #include #include #include #include "util/rc4.h" #include "module.h" #include "websocket.h" #include "serial.h" namespace api { struct ClientState { SOCKADDR_IN address; SOCKET socket; bool close = false; std::vector modules; std::string password; bool password_change = false; util::RC4 *cipher = nullptr; }; class Controller { private: // configuration const static int server_backlog = 16; const static int server_receive_buffer_size = 64 * 1024; const static int server_message_buffer_max_size = 64 * 1024; const static int server_worker_count = 2; const static int server_connection_limit = 4096; // settings unsigned short port; std::string password; bool pretty; // server WebSocketController *websocket; std::vector serial; std::vector server_workers; std::vector server_handlers; std::mutex server_handlers_m; std::vector client_states; std::mutex client_states_m; SOCKET server; void server_worker(); void connection_handler(ClientState client_state); public: // state bool server_running; // constructor / destructor Controller(unsigned short port, std::string password, bool pretty); ~Controller(); void listen_serial(std::string port, DWORD baud); bool process_request(ClientState *state, std::vector *in, std::vector *out); bool process_request(ClientState *state, const char *in, size_t in_size, std::vector *out); static void process_password_change(ClientState *state); void init_state(ClientState *state); static void free_state(ClientState *state); void free_socket(); void obtain_client_states(std::vector *output); std::string get_ip_address(sockaddr_in addr); inline const std::string &get_password() const { return this->password; } }; }