static void telnet_wait_for_connection (void) { SlSocklen_t in_addrSize; sockaddr_in sClientAddress; // accepts a connection from a TCP client, if there is any, otherwise returns SL_EAGAIN telnet_data.n_sd = sl_Accept(telnet_data.sd, (SlSockAddr_t *)&sClientAddress, (SlSocklen_t *)&in_addrSize); if (telnet_data.n_sd == SL_EAGAIN) { return; } else { if (telnet_data.n_sd <= 0) { // error telnet_reset(); return; } // close the listening socket, we don't need it anymore servers_close_socket(&telnet_data.sd); // add the new socket to the network administration modusocket_socket_add(telnet_data.n_sd, false); // client connected, so go on telnet_data.rxWindex = 0; telnet_data.rxRindex = 0; telnet_data.txRetries = 0; telnet_data.state = E_TELNET_STE_CONNECTED; telnet_data.substate.connected = E_TELNET_STE_SUB_WELCOME; telnet_data.credentialsValid = true; telnet_data.logginRetries = 0; telnet_data.timeout = 0; } }
static telnet_result_t telnet_send_non_blocking (void *data, _i16 Len) { int16_t result = sl_Send(telnet_data.n_sd, data, Len, 0); if (result > 0) { telnet_data.txRetries = 0; return E_TELNET_RESULT_OK; } else if ((TELNET_TX_RETRIES_MAX >= ++telnet_data.txRetries) && (result == SL_EAGAIN)) { return E_TELNET_RESULT_AGAIN; } else { // error telnet_reset(); return E_TELNET_RESULT_FAILED; } }
static telnet_result_t telnet_recv_text_non_blocking (void *buff, _i16 Maxlen, _i16 *rxLen) { *rxLen = sl_Recv(telnet_data.n_sd, buff, Maxlen, 0); // if there's data received, parse it if (*rxLen > 0) { telnet_data.timeout = 0; telnet_parse_input (buff, rxLen); if (*rxLen > 0) { return E_TELNET_RESULT_OK; } } else if (*rxLen != SL_EAGAIN) { // error telnet_reset(); return E_TELNET_RESULT_FAILED; } return E_TELNET_RESULT_AGAIN; }
/****************************************************************************** DECLARE PUBLIC FUNCTIONS ******************************************************************************/ void TASK_Servers (void *pvParameters) { bool cycle = false; strcpy (servers_user, SERVERS_DEF_USER); strcpy (servers_pass, SERVERS_DEF_PASS); telnet_init(); ftp_init(); for ( ;; ) { if (servers_data.do_enable) { // enable network services telnet_enable(); ftp_enable(); // now set/clear the flags servers_data.enabled = true; servers_data.do_enable = false; } else if (servers_data.do_disable) { // disable network services telnet_disable(); ftp_disable(); // now clear the flags servers_data.do_disable = false; servers_data.enabled = false; } else if (servers_data.do_reset) { // resetting the servers is needed to prevent half-open sockets servers_data.do_reset = false; if (servers_data.enabled) { telnet_reset(); ftp_reset(); } // and we should also close all user sockets. We do it here // for convinience and to save on code size. modusocket_close_all_user_sockets(); } if (cycle) { telnet_run(); } else { ftp_run(); } if (sleep_sockets) { sleep_sockets = false; pybwdt_srv_sleeping(true); modusocket_enter_sleep(); pybwdt_srv_sleeping(false); } // set the alive flag for the wdt pybwdt_srv_alive(); // move to the next cycle cycle = cycle ? false : true; mp_hal_delay_ms(SERVERS_CYCLE_TIME_MS); } }
void terminal_new_connection(void) { telnet_reset(); telnet_send_negotiations(); }
void telnet_disable (void) { telnet_reset(); telnet_data.enabled = false; telnet_data.state = E_TELNET_STE_DISABLED; }
void telnet_run (void) { _i16 rxLen; switch (telnet_data.state) { case E_TELNET_STE_DISABLED: telnet_wait_for_enabled(); break; case E_TELNET_STE_START: if (wlan_is_connected() && telnet_create_socket()) { telnet_data.state = E_TELNET_STE_LISTEN; } break; case E_TELNET_STE_LISTEN: telnet_wait_for_connection(); break; case E_TELNET_STE_CONNECTED: switch (telnet_data.substate.connected) { case E_TELNET_STE_SUB_WELCOME: telnet_send_and_proceed((void *)telnet_welcome_msg, strlen(telnet_welcome_msg), E_TELNET_STE_SUB_SND_USER_OPTIONS); break; case E_TELNET_STE_SUB_SND_USER_OPTIONS: telnet_send_and_proceed((void *)telnet_options_user, sizeof(telnet_options_user), E_TELNET_STE_SUB_REQ_USER); break; case E_TELNET_STE_SUB_REQ_USER: // to catch any left over characters from the previous actions telnet_recv_text_non_blocking(telnet_data.rxBuffer, TELNET_RX_BUFFER_SIZE, &rxLen); telnet_send_and_proceed((void *)telnet_request_user, strlen(telnet_request_user), E_TELNET_STE_SUB_GET_USER); break; case E_TELNET_STE_SUB_GET_USER: if (E_TELNET_RESULT_OK == telnet_recv_text_non_blocking(telnet_data.rxBuffer + telnet_data.rxWindex, TELNET_RX_BUFFER_SIZE - telnet_data.rxWindex, &rxLen)) { int result; if ((result = telnet_process_credential (servers_user, rxLen))) { telnet_data.credentialsValid = result > 0 ? true : false; telnet_data.substate.connected = E_TELNET_STE_SUB_REQ_PASSWORD; } } break; case E_TELNET_STE_SUB_REQ_PASSWORD: telnet_send_and_proceed((void *)telnet_request_password, strlen(telnet_request_password), E_TELNET_STE_SUB_SND_PASSWORD_OPTIONS); break; case E_TELNET_STE_SUB_SND_PASSWORD_OPTIONS: // to catch any left over characters from the previous actions telnet_recv_text_non_blocking(telnet_data.rxBuffer, TELNET_RX_BUFFER_SIZE, &rxLen); telnet_send_and_proceed((void *)telnet_options_pass, sizeof(telnet_options_pass), E_TELNET_STE_SUB_GET_PASSWORD); break; case E_TELNET_STE_SUB_GET_PASSWORD: if (E_TELNET_RESULT_OK == telnet_recv_text_non_blocking(telnet_data.rxBuffer + telnet_data.rxWindex, TELNET_RX_BUFFER_SIZE - telnet_data.rxWindex, &rxLen)) { int result; if ((result = telnet_process_credential (servers_pass, rxLen))) { if ((telnet_data.credentialsValid = telnet_data.credentialsValid && (result > 0 ? true : false))) { telnet_data.substate.connected = E_TELNET_STE_SUB_SND_REPL_OPTIONS; } else { telnet_data.substate.connected = E_TELNET_STE_SUB_INVALID_LOGGIN; } } } break; case E_TELNET_STE_SUB_INVALID_LOGGIN: if (E_TELNET_RESULT_OK == telnet_send_non_blocking((void *)telnet_invalid_loggin, strlen(telnet_invalid_loggin))) { telnet_data.credentialsValid = true; if (++telnet_data.logginRetries >= TELNET_LOGIN_RETRIES_MAX) { telnet_reset(); } else { telnet_data.substate.connected = E_TELNET_STE_SUB_SND_USER_OPTIONS; } } break; case E_TELNET_STE_SUB_SND_REPL_OPTIONS: telnet_send_and_proceed((void *)telnet_options_repl, sizeof(telnet_options_repl), E_TELNET_STE_SUB_LOGGIN_SUCCESS); break; case E_TELNET_STE_SUB_LOGGIN_SUCCESS: if (E_TELNET_RESULT_OK == telnet_send_non_blocking((void *)telnet_loggin_success, strlen(telnet_loggin_success))) { // clear the current line and force the prompt telnet_reset_buffer(); telnet_data.state= E_TELNET_STE_LOGGED_IN; } default: break; } break; case E_TELNET_STE_LOGGED_IN: telnet_process(); break; default: break; } if (telnet_data.state >= E_TELNET_STE_CONNECTED) { if (telnet_data.timeout++ > (servers_get_timeout() / TELNET_CYCLE_TIME_MS)) { telnet_reset(); } } }