| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789 | 
							- /*
 
-  * telnet_server.c
 
-  *
 
-  *  Created on: 24.11.2017
 
-  *      Author: balbekova
 
-  */
 
- #pragma GCC diagnostic error "-Wall"
 
- /* Standard includes. */
 
- #include <string.h>
 
- /* lwIP core includes */
 
- #include "lwip/opt.h"
 
- #include "lwip/sockets.h"
 
- /* FreeRTOS includes. */
 
- #include "FreeRTOS.h"
 
- #include "task.h"
 
- #include "fr_timers.h"
 
- /* Utils includes. */
 
- #include "FreeRTOS_CLI.h"
 
- #include "CLI_Commands.h"
 
- #include "cli.h"
 
- #include "telnet_server.h"
 
- #include "settings_api.h"
 
- #include "parameters.h"
 
- #include "control_symbol.h"
 
- #include "log.h"
 
- #include "web_params_api.h"
 
- #define ISO_nl       0x0a
 
- #define ISO_cr       0x0d
 
- //
 
- // States
 
- //
 
- typedef enum {
 
- 	TELNET_STATE_NORMAL = 0,
 
- 	TELNET_STATE_IAC,
 
- 	TELNET_STATE_OPT,
 
- 	TELNET_STATE_SB,
 
- 	TELNET_STATE_OPTDAT,
 
- 	//TELNET_STATE_SE,
 
- 	TELNET_STATE_CLOSE,
 
- } telnet_state_t;
 
- //
 
- // Special telnet characters
 
- //
 
- #define TELNET_SE    240   // End of subnegotiation parameters
 
- #define TELNET_NOP   241   // No operation
 
- #define TELNET_MARK  242   // Data mark
 
- #define TELNET_BRK   243   // Break
 
- #define TELNET_IP    244   // Interrupt process
 
- #define TELNET_AO    245   // Abort output
 
- #define TELNET_AYT   246   // Are you there
 
- #define TELNET_EC    247   // Erase character
 
- #define TELNET_EL    248   // Erase line
 
- #define TELNET_GA    249   // Go ahead
 
- #define TELNET_SB    250   // Start of subnegotiation parameters
 
- #define TELNET_WILL  251   // Will option code
 
- #define TELNET_WONT  252   // Won't option code
 
- #define TELNET_DO    253   // Do option code
 
- #define TELNET_DONT  254   // Don't option code
 
- #define TELNET_IAC   255   // Interpret as command
 
- //
 
- // Telnet options
 
- //
 
- #define TELOPT_TRANSMIT_BINARY      0  // Binary Transmission (RFC856)
 
- #define TELOPT_ECHO                 1  // Echo (RFC857)
 
- #define TELOPT_SUPPRESS_GO_AHEAD    3  // Suppress Go Ahead (RFC858)
 
- #define TELOPT_STATUS               5  // Status (RFC859)
 
- #define TELOPT_TIMING_MARK          6  // Timing Mark (RFC860)
 
- #define TELOPT_NAOCRD              10  // Output Carriage-Return Disposition (RFC652)
 
- #define TELOPT_NAOHTS              11  // Output Horizontal Tab Stops (RFC653)
 
- #define TELOPT_NAOHTD              12  // Output Horizontal Tab Stop Disposition (RFC654)
 
- #define TELOPT_NAOFFD              13  // Output Formfeed Disposition (RFC655)
 
- #define TELOPT_NAOVTS              14  // Output Vertical Tabstops (RFC656)
 
- #define TELOPT_NAOVTD              15  // Output Vertical Tab Disposition (RFC657)
 
- #define TELOPT_NAOLFD              16  // Output Linefeed Disposition (RFC658)
 
- #define TELOPT_EXTEND_ASCII        17  // Extended ASCII (RFC698)
 
- #define TELOPT_TERMINAL_TYPE       24  // Terminal Type (RFC1091)
 
- #define TELOPT_NAWS                31  // Negotiate About Window Size (RFC1073)
 
- #define TELOPT_TERMINAL_SPEED      32  // Terminal Speed (RFC1079)
 
- #define TELOPT_TOGGLE_FLOW_CONTROL 33  // Remote Flow Control (RFC1372)
 
- #define TELOPT_LINEMODE            34  // Linemode (RFC1184)
 
- #define TELOPT_DISPLAY_POS         35  // Linemode (RFC1184)
 
- #define TELOPT_AUTHENTICATION      37  // Authentication (RFC1416)
 
- #define TELOPT_NEW_ENV_OPTION      39  // Authentication (RFC1416)
 
- //Sub option for LINEMODE
 
- #define LINEMODE_MODE             1
 
- #define LINEMODE_EDIT             1
 
- #define LINEMODE_TRAPSIG          2
 
- #define LINEMODE_MODE_ACK         4
 
- #define LINEMODE_SOFT_TAB         8
 
- #define LINEMODE_LIT_ECHO        16
 
- #define LINEMODE_FORWARDMASK      2
 
- #define LINEMODE_SLC              3
 
- #define LINEMODE_SLC_SYNCH        1
 
- #define LINEMODE_SLC_BRK          2
 
- #define LINEMODE_SLC_IP           3
 
- #define LINEMODE_SLC_AO           4
 
- #define LINEMODE_SLC_AYT          5
 
- #define LINEMODE_SLC_EOR          6
 
- #define LINEMODE_SLC_ABORT        7
 
- #define LINEMODE_SLC_EOF          8
 
- #define LINEMODE_SLC_SUSP         9
 
- #define LINEMODE_SLC_EC          10
 
- #define LINEMODE_SLC_EL          11
 
- #define LINEMODE_SLC_EW          12
 
- #define LINEMODE_SLC_RP          13
 
- #define LINEMODE_SLC_LNEXT       14
 
- #define LINEMODE_SLC_XON         15
 
- #define LINEMODE_SLC_XOFF        16
 
- #define LINEMODE_SLC_FORW1       17
 
- #define LINEMODE_SLC_FORW2       18
 
- #define LINEMODE_SLC_MCL         19
 
- #define LINEMODE_SLC_MCR         20
 
- #define LINEMODE_SLC_MCWL        21
 
- #define LINEMODE_SLC_MCWR        22
 
- #define LINEMODE_SLC_MCBOL       23
 
- #define LINEMODE_SLC_MCEOL       24
 
- #define LINEMODE_SLC_INSRT       25
 
- #define LINEMODE_SLC_OVER        26
 
- #define LINEMODE_SLC_ECR         27
 
- #define LINEMODE_SLC_EWR         28
 
- #define LINEMODE_SLC_EBOL        29
 
- #define LINEMODE_SLC_EEOL        30
 
- #define LINEMODE_SLC_DEFAULT      3
 
- #define LINEMODE_SLC_VALUE        2
 
- #define LINEMODE_SLC_CANTCHANGE   1
 
- #define LINEMODE_SLC_NOSUPPORT    0
 
- #define LINEMODE_SLC_LEVELBITS    3
 
- #define LINEMODE_SLC_ACK        128
 
- #define LINEMODE_SLC_FLUSHIN     64
 
- #define LINEMODE_SLC_FLUSHOUT    32
 
- #define LINEMODE_EOF            236
 
- #define LINEMODE_SUSP           237
 
- #define LINEMODE_ABORT          238
 
- /* Repeat Login timeout, 1 seconds */
 
- #define REPEAT_SENSOR_INFO_TIME		configTICK_RATE_HZ*5*1
 
- /* Set option to drop old connection if the new one is accepted */
 
- #define TCP_DROP_PREV_CONNECTION    0
 
- /**
 
-  * A telnet connection structure.
 
-  */
 
- typedef struct{
 
- 	telnet_state_t state;
 
- 	uint8_t code;
 
- 	unsigned char optdata[cmdMAX_INPUT_SIZE];
 
- 	uint8_t optlen;
 
- 	uint8_t login_err;	// the number of failed password entry attempts
 
- 	uint8_t num_connect;
 
- 	bool active_conn;
 
- 	cli_state_t *cli_state;
 
- } telnetd_state_t;
 
- telnetd_state_t auth_tlnt_srvr_param[NUMBER_TELNET_CONNECT];
 
- uint8_t type_term = 0;
 
- static int32_t lSocket;
 
- static int8_t *pcOutputString;
 
- static struct fd_set master_set, read_set;
 
- static int max_sd;
 
- static struct sockaddr_in sa;
 
- static const int8_t * const pcEndOfCommandOutputString = ( int8_t * ) "\r\n[Нажмите клавишу ENTER для повторного выполнения предыдущей команды]\r\n>";
 
- /**
 
-   * @brief  Общая структура настроек
 
-   */
 
- extern SETTINGS_t sSettings;
 
- static void deconfigure_telnet_state(telnetd_state_t *state)
 
- {
 
- 	if (state->cli_state) {
 
- 		free_state(state->cli_state);
 
- 		state->cli_state = NULL;
 
- 	}
 
- 	memset(state->optdata, 0, cmdMAX_INPUT_SIZE);
 
- 	state->optlen = 0;
 
- 	state->state = TELNET_STATE_NORMAL;
 
- 	state->num_connect = 0;
 
- 	state->active_conn = false;
 
- }
 
- static void sendopt(telnetd_state_t *s, u8_t code, u8_t option)
 
- {
 
- 	unsigned char buf[3];
 
- 	buf[0] = TELNET_IAC;
 
- 	buf[1] = code;
 
- 	buf[2] = option;
 
- 	send( s->num_connect, buf, 3, 0 );
 
- }
 
- static void sendopt_cli(cli_state_t *s, u8_t code, u8_t option)
 
- {
 
- 	unsigned char buf[3];
 
- 	buf[0] = TELNET_IAC;
 
- 	buf[1] = code;
 
- 	buf[2] = option;
 
- 	send( s->num_connect, buf, 3, 0 );
 
- }
 
- static void sendsubopt(telnetd_state_t *s, u8_t code, u8_t *option, u8_t len)
 
- {
 
- 	unsigned char buf[cmdMAX_INPUT_SIZE+3];
 
- 	buf[0] = TELNET_IAC;
 
- 	buf[1] = TELNET_SB;
 
- 	buf[2] = code;
 
- 	memcpy(&buf[3], option, len);
 
- 	buf[len + 3] = TELNET_IAC;
 
- 	buf[len + 4] = TELNET_SE;
 
- 		send( s->num_connect, buf, (len + 5), 0 );
 
- }
 
- void parseopt(telnetd_state_t *ts, uint8_t code, uint8_t option)
 
- {
 
- 	switch (option) {
 
- 		case TELOPT_ECHO:
 
- 			if (code == TELNET_WONT) {
 
- 				type_term = 0;
 
- 			}
 
- 			else if (code == TELNET_WILL ){
 
- 				type_term = 1;
 
- 			}
 
- 			break;
 
- 		case TELOPT_SUPPRESS_GO_AHEAD:
 
- 		case TELOPT_LINEMODE:
 
- 		case TELOPT_NAWS:
 
- 		case TELOPT_DISPLAY_POS:
 
- 		case TELOPT_NEW_ENV_OPTION:
 
- 		case TELOPT_TERMINAL_SPEED:
 
- 		case TELOPT_TERMINAL_TYPE:
 
- 		case TELOPT_STATUS:
 
- 		case TELOPT_TOGGLE_FLOW_CONTROL:
 
- 			break;
 
- 		case TELOPT_TIMING_MARK:
 
- 			xTimerStop(ts->cli_state->RepeatSensorInfoTimer, 0);
 
- 			ts->cli_state->flag_telnet_ip_option = true;
 
- 			sendopt(ts, TELNET_WILL, TELOPT_TIMING_MARK);
 
- 			sendopt(ts, TELNET_MARK, 0);
 
- 			if(ts->cli_state->input_state != CLI_CHANGE_PWD && ts->cli_state->input_state != CLI_CHANGE_PWD_ACK)
 
- 				send( ts->num_connect, pcEndOfCommandOutputString, strlen( ( const char * ) pcEndOfCommandOutputString ), 0 );
 
- 			break;
 
- 		default:
 
- 			if (code == TELNET_WILL || code == TELNET_WONT) {
 
- 				sendopt(ts, TELNET_DONT, option);
 
- 			} else {
 
- 				sendopt(ts, TELNET_WONT, option);
 
- 			}
 
- 			break;
 
- 	}
 
- }
 
- static void parseoptdat(telnetd_state_t *ts, int option, unsigned char *data, uint8_t len) {
 
- 	uint8_t subopt = 0;
 
- 	uint8_t subopt_val = 0;
 
- 	uint8_t sub_opt_data[2] = {LINEMODE_MODE, LINEMODE_EDIT};
 
- 	switch (option) {
 
- 		case TELOPT_NAWS:
 
- 			break;
 
- 		case TELOPT_TERMINAL_SPEED:
 
- 			break;
 
- 		case TELOPT_TERMINAL_TYPE:
 
- 			break;
 
- 		case TELOPT_LINEMODE:
 
- 			subopt = data[0];
 
- 			switch (subopt) {
 
- 			case LINEMODE_SLC:
 
- 			if(data[2] & LINEMODE_SLC_ACK){
 
- 				return;
 
- 			}
 
- 			sendsubopt(ts, option, sub_opt_data, 2);
 
- 			for(uint8_t i = 1; i < len; i += 3){
 
- 				subopt_val = data[i];
 
- 				switch (subopt_val) {
 
- 				case LINEMODE_SLC_IP:
 
- 					data[i+1] = LINEMODE_SLC_VALUE | LINEMODE_SLC_FLUSHIN | LINEMODE_SLC_FLUSHOUT | LINEMODE_SLC_ACK;
 
- 					break;
 
- 				case LINEMODE_SLC_XON:
 
- 				case LINEMODE_SLC_XOFF:
 
- 				case LINEMODE_SLC_EC:
 
- 					data[i+1] = LINEMODE_SLC_VALUE | LINEMODE_SLC_ACK;
 
- 					break;
 
- 				default:
 
- 					data[i+1] = LINEMODE_SLC_NOSUPPORT;
 
- 					data[i+2] = 0;
 
- 					break;
 
- 				}
 
- 			}
 
- 			sendsubopt(ts, option, data, len);
 
- 			break;
 
- 			}
 
- 		break;
 
- 	}
 
- }
 
- extern int8_t cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];
 
- portBASE_TYPE FreeRTOS_CLIAuthProcess( int8_t * pcWriteBuffer, cli_state_t *s)
 
- {
 
- 	portBASE_TYPE xReturn = pdTRUE;
 
- 	uint32_t len;
 
- 	user_level_t user_id = MAX_USER_LEVELS;
 
- 	char password[cmdMAX_INPUT_SIZE] = { 0 };
 
- 	const int8_t * const pcPSWHeader = ( int8_t * ) "\r\npassword:";
 
- 	const int8_t * const pcLoginHeader = ( int8_t * ) "\r\nlogin:";
 
- 	printf("CAP buf: %s\r\n", s->buf);
 
- 	memset(pcWriteBuffer, 0, configCOMMAND_INT_MAX_OUTPUT_SIZE);
 
- 	switch(s->input_state){
 
- 	case CLI_AUTH:
 
- 		memset(s->login, 0, MAX_WEB_LOGIN_LEN);
 
- 		len = strlen(s->buf);
 
- 		if (len < MAX_WEB_LOGIN_LEN){
 
- 			strncpy(s->login, s->buf, len);
 
- 			sendopt_cli(s, TELNET_WILL, TELOPT_ECHO);
 
- 			strncpy( ( char * ) pcWriteBuffer, ( const char * ) pcPSWHeader, strlen( ( char * ) pcPSWHeader ) );
 
- 			s->input_state = CLI_AUTH_PASSW;
 
- 			xReturn = pdTRUE;
 
- 		} else {
 
- 			xReturn = pdFALSE;
 
- 		}
 
- 		break;
 
- 	case CLI_AUTH_PASSW:
 
- 		sendopt_cli(s, TELNET_WONT, TELOPT_ECHO);
 
- 		memset(password, 0, MAX_WEB_PASSWD_LEN);
 
- 		len = strlen(s->buf);
 
- 		strncpy(password, s->buf, len);
 
- 		user_id = cli_auth_user((const char *)s->login, password, LOG_LOGIN_TELNET);
 
- 		if (user_id != MAX_USER_LEVELS) {
 
- 			s->user_id = user_id;
 
- 			s->login_err = 0;
 
- 			strcpy( ( char * ) pcWriteBuffer, "\r\nАвторизация успешно пройдена\r\n>" );
 
- 			s->input_state = CLI_CMD;
 
- 			xReturn = pdTRUE;
 
- 		} else {
 
- 			xReturn = pdFALSE;
 
- 		}
 
- 		break;
 
- 	default:
 
- 		// called auth when already authorized
 
- 		xReturn = pdFALSE;
 
- 		s->input_state = CLI_AUTH;
 
- 		return xReturn;
 
- 		break;
 
- 	}
 
- 	if (xReturn == pdFALSE){
 
- 		s->input_state = CLI_AUTH;
 
- 		if (s->login_err < 4){
 
- 			s->login_err ++;
 
- 			strcpy( ( char * ) pcWriteBuffer, "\r\nОшибка авторизации\r\n" );
 
- 			strncat( ( char * ) pcWriteBuffer, ( const char * ) pcLoginHeader, strlen( ( char * ) pcLoginHeader ) );
 
- 			xReturn = pdTRUE;
 
- 		} else {
 
- 			// password entry tries exceeded
 
- 			s->login_err = 0;
 
- 			xReturn = pdFALSE;
 
- 		}
 
- 		printf("login error, errors so far: %d\r\n", s->login_err);
 
- 	}
 
- 	return xReturn;
 
- }
 
- /*-----------------------------------------------------------------------------------*/
 
- static void newdata(telnetd_state_t *s, char c)
 
- {
 
- 	switch(s->state) {
 
- 	case TELNET_STATE_IAC:
 
- 		switch (c) {
 
- 		case TELNET_IAC:
 
- 			s->state = TELNET_STATE_NORMAL;
 
- 			break;
 
- 		case TELNET_WILL:
 
- 		case TELNET_WONT:
 
- 		case TELNET_DO:
 
- 		case TELNET_DONT:
 
- 			s->code = c;
 
- 			s->state = TELNET_STATE_OPT;
 
- 			break;
 
- 		case TELNET_SB:
 
- 			s->state = TELNET_STATE_SB;
 
- 			break;
 
- 		default:
 
- 			s->state = TELNET_STATE_NORMAL;
 
- 			break;
 
- 		}
 
- 		break;
 
- 	case TELNET_STATE_OPT:
 
- 		parseopt(s, s->code, c);
 
- 		s->state = TELNET_STATE_NORMAL;
 
- 		break;
 
- 	case TELNET_STATE_SB:
 
- 		s->code = c;
 
- 		s->optlen = 0;
 
- 		s->state = TELNET_STATE_OPTDAT;
 
- 		break;
 
- 	case TELNET_STATE_OPTDAT:
 
- 		if (c == TELNET_SE && s->optdata[s->optlen-1] == TELNET_IAC) {
 
- 			parseoptdat(s, s->code, s->optdata, (s->optlen-1));
 
- 			s->state = TELNET_STATE_NORMAL;
 
- 			//s->state = TELNET_STATE_SE;
 
- 		} else if (s->optlen < sizeof(s->optdata)) {
 
- 			s->optdata[s->optlen++] = c;
 
- 		}
 
- 		break;
 
- 	/*case TELNET_STATE_SE:
 
- 		if (c == TELNET_SE) parseoptdat(s, s->code, s->optdata, s->optlen);
 
- 		s->state = TELNET_STATE_NORMAL;
 
- 		break;*/
 
- 	case TELNET_STATE_NORMAL:
 
- 		if(c == TELNET_IAC) {
 
- 			s->state = TELNET_STATE_IAC;
 
- 		} else {
 
- 			// incoming user input
 
- 			cli_getchar(s->cli_state, c, type_term == 1);
 
- 		}
 
- 		break;
 
- 	default:
 
- 		printf("unexpected telnet state\r\n");
 
- 	}
 
- }
 
- /*-----------------------------------------------------------*/
 
- /* Stop server */
 
- static void stop_server(void) {
 
- 	/* Clean up all of the sockets that are open */
 
- 	for (int i = 0; i <= max_sd; ++i)
 
- 	{
 
- 		 if (FD_ISSET(i, &master_set)) {
 
- 				DBG printf("Close sock %d\n", i);
 
- 				closesocket(i);
 
- 				FD_CLR(i, &master_set);
 
- 		 }
 
- 	}
 
- 	DBG printf("Portgw stopped\n");
 
- 	for (int i = 0; i < array_len(auth_tlnt_srvr_param); ++i) {
 
- 		deconfigure_telnet_state(auth_tlnt_srvr_param + i);
 
- 	}
 
- }
 
- /* Start server */
 
- static bool start_server(uint16_t port)
 
- {
 
- 	int res;
 
- 	lSocket = socket(PF_INET, SOCK_STREAM, 0);
 
- 	if (lSocket < 0) {
 
- 		DBG printf("Socket create failed\r\n");
 
- 		return false;
 
- 	}
 
- 	res = fcntl(lSocket, F_SETFL, O_NONBLOCK);
 
- 	if (res < 0) {
 
- 			DBG printf("fcntl() failed");
 
- 			closesocket(lSocket);
 
- 			return false;
 
- 	}
 
- 	memset(&sa, 0, sizeof(struct sockaddr_in));
 
- 	sa.sin_family = AF_INET;
 
- 	sa.sin_addr.s_addr = IPADDR_ANY;
 
- 	sa.sin_port = htons(port);
 
- 	if (bind(lSocket, (struct sockaddr *)&sa, sizeof(sa)) == -1)
 
- 	{
 
- 			DBG printf("Bind to port %d failed\n", port);
 
- 			closesocket(lSocket);
 
- 			return false;
 
- 	}
 
- 	res = listen(lSocket, 20);
 
- 	if (res < 0) {
 
- 			DBG printf("Listen failed failed\r\n");
 
- 			closesocket(lSocket);
 
- 			return false;
 
- 	}
 
- 	FD_ZERO(&master_set);
 
- 	max_sd = lSocket;
 
- 	FD_SET(lSocket, &master_set);
 
- 	DBG printf("Port %d opened\n", port);
 
- 	return true;
 
- }
 
- static void cli_send(intptr_t fd, const char *str, unsigned len)
 
- {
 
- 	send(fd, str, len, 0);
 
- }
 
- void vBasicSocketsCommandInterpreterTask( void *pvParameters )
 
- {
 
- 	int32_t lBytes;
 
- 	int new_sd;
 
- 	int desc_ready, rc;
 
- 	struct timeval timeout;
 
- 	uint16_t port;
 
- 	bool enabled;
 
- 	bool firstrun = true;
 
- #if HARDWARE_BT6709 || HARDWARE_BT6709_MTS 
 
- 	struct sockaddr_in sa_temp;
 
- 	socklen_t len;
 
- #endif
 
- #if TCP_DROP_PREV_CONNECTION
 
- 	static int active_sd = -1;
 
- #endif
 
- 	static uint8_t cnt_conn = 0;
 
- 	uint8_t cur_cnt = 0;
 
- 	FD_ZERO(&master_set);
 
- 	timeout.tv_sec = 5;
 
- 	timeout.tv_usec = 0;
 
- 	( void ) pvParameters;
 
- 	pcOutputString = FreeRTOS_CLIGetOutputBuffer();
 
- 	enabled = sSettings.sTelnet.TelnetEnable;
 
- 	port = ( uint16_t ) sSettings.sTelnet.port;
 
- 	while (1) {
 
- 		/* Check if network settings was changed */
 
- 		if ((sSettings.sTelnet.port != port) ||
 
- 				(sSettings.sTelnet.TelnetEnable != enabled) ||
 
- 				(firstrun))
 
- 		{
 
- 			if (!firstrun || sSettings.sTelnet.port != port) {
 
- 				/* Stop server */
 
- 				stop_server();
 
- 				cnt_conn = 0;
 
- 			}
 
- 			if (sSettings.sTelnet.TelnetEnable) {
 
- 				/* (Re)start server */
 
- 				if (!start_server(sSettings.sTelnet.port)) {
 
- 					DBG printf("Server start error\n");
 
- 					firstrun = true;
 
- 					vTaskDelay(5000);
 
- 					continue;
 
- 				}
 
- 			}
 
- 			else {
 
- 				/* Obtain the address of the output buffer.  Note there is no mutual
 
- 				exclusion on this buffer as it is assumed only one command console
 
- 				interface will be used at any one time. */
 
- 				firstrun = true;
 
- 				vTaskDelay(5000);
 
- 				continue;
 
- 			}
 
- 			firstrun = false;
 
- 			port = sSettings.sTelnet.port;
 
- 			enabled = sSettings.sTelnet.TelnetEnable;
 
- 		}
 
- 		if (!enabled) {
 
- 			firstrun = true;
 
- 			vTaskDelay(5000);
 
- 			continue;
 
- 		}
 
- 		memcpy(&read_set, &master_set, sizeof(master_set));
 
- 		DBG printf("Waiting on select()...\n");
 
- 		rc = select(max_sd + 1, &read_set, NULL, NULL, &timeout);
 
- 		DBG printf("  select() returned %d\n", rc);
 
- 		if (rc < 0) {
 
- 			DBG printf("  select() failed\n");
 
- 		}
 
- 		if (rc == 0) {
 
- 			DBG printf("  select() timed out.\n");
 
- 		}
 
- 		/* One or more descriptors are readable.  Need to         \
 
- 		 * determine which ones they are.                         */
 
- 		desc_ready = rc;
 
- 		for (int sock = 0; sock <= max_sd && desc_ready > 0; ++sock) {
 
- 			/*******************************************************/
 
- 			/* Check to see if this descriptor is ready            */
 
- 			/*******************************************************/
 
- 			if (FD_ISSET(sock, &read_set)) {
 
- 				/* A descriptor was found that was readable - one  \
 
- 				* less has to be looked for.  This is being done   \
 
- 				* so that we can stop looking at the working set   \
 
- 				* once we have found all of the descriptors that   \
 
- 				* were ready.                                      */
 
- 				desc_ready -= 1;
 
- 				/* Check to see if this is the listening socket     */
 
- 				if (sock == lSocket) {
 
- 					DBG printf("  Listening socket is readable\n");
 
- 					/* Accept all incoming connections that are      */
 
- 					/* queued up on the listening socket before we   */
 
- 					/* loop back and call select again.              */
 
- 					do {
 
- 						/* Accept each incoming connection.  If       */
 
- 						/* accept fails with EWOULDBLOCK, then we     */
 
- 						/* have accepted all of them.  Any other      */
 
- 						/* failure on accept will cause us to end the */
 
- 						/* server.                                    */
 
- 						new_sd = accept(lSocket, NULL, NULL);
 
- 						if (new_sd < 0) {
 
- 							if (errno != EWOULDBLOCK) {
 
- 								DBG printf("  accept() failed\n");
 
- 							}
 
- 							break;
 
- 						}
 
- 						/* Add the new incoming connection to the     */
 
- 						/* master read set                            */
 
- 						printf("  New incoming connection - %d\n", new_sd);
 
- 						FD_SET(new_sd, &master_set);
 
- 						if (new_sd > max_sd) {
 
- 							max_sd = new_sd;
 
- 						}
 
- #if HARDWARE_BT6709 || HARDWARE_BT6709_MTS 
 
- 						lwip_getpeername(new_sd, &sa_temp, &len);
 
- #endif
 
- 					//	recv( new_sd, &auth_tlnt_srvr_param[cur_cnt].buf, 27, 0 );
 
- 						// Send initial options
 
- 						bool not_enough_memory = false;
 
- 						if(cnt_conn < NUMBER_TELNET_CONNECT){
 
- 							cli_state_t *cli_state = 0;
 
- 							for(uint8_t k = 0; k < NUMBER_TELNET_CONNECT; k ++){
 
- 								if(auth_tlnt_srvr_param[k].active_conn == false && (cli_state = alloc_state())){
 
- 									auth_tlnt_srvr_param[k].active_conn = true;
 
- 									auth_tlnt_srvr_param[k].num_connect = new_sd;
 
- 									auth_tlnt_srvr_param[k].state = TELNET_STATE_NORMAL;
 
- 									cli_state->num_connect = new_sd;
 
- 									cli_state->send = cli_send;
 
- 									cli_state->state = STATE_NORMAL;
 
- 									auth_tlnt_srvr_param[k].cli_state = cli_state;
 
- 									char c;
 
- 									while (recv(new_sd, &c, 1, MSG_DONTWAIT) > 0) {
 
- 										newdata(&auth_tlnt_srvr_param[k], c);
 
- 										vTaskDelay(10);
 
- 									}
 
- 									sendopt(&auth_tlnt_srvr_param[k], TELNET_DO, TELOPT_SUPPRESS_GO_AHEAD);
 
- 									sendopt(&auth_tlnt_srvr_param[k], TELNET_DO, TELOPT_LINEMODE);
 
- 									sendopt(&auth_tlnt_srvr_param[k], TELNET_DONT, TELOPT_ECHO);
 
- 									vTaskDelay(50);
 
- 									while (recv(new_sd, &c, 1, MSG_DONTWAIT) > 0) {
 
- 										newdata(&auth_tlnt_srvr_param[k], c);
 
- 										vTaskDelay(5);
 
- 									}
 
- 									send( new_sd, TELNET_CLI_WELCOME_MESSAGE, strlen( TELNET_CLI_WELCOME_MESSAGE ), 0 );
 
- 									break;
 
- 								}
 
- 							}
 
- 							if (!cli_state) {
 
- 								not_enough_memory = true;
 
- 							} else {
 
- 								cnt_conn++;
 
- 							}
 
- 						} else {
 
- 							not_enough_memory = true;
 
- 						}
 
- 						if (not_enough_memory) {
 
- 							send(new_sd, pcWarningMessage, pcWarningMessageLen, 0);
 
- 							closesocket(new_sd);
 
- 							FD_CLR(new_sd, &master_set);
 
- 							while (FD_ISSET(max_sd, &master_set) == false) {
 
- 								max_sd -= 1;
 
- 							}
 
- 						}
 
- #if TCP_DROP_PREV_CONNECTION
 
- 						/* Close previous active connection */
 
- 						if (active_sd != -1 && active_sd != new_sd) {
 
- 								DBG printf("	Close prev active connection %d\n", active_sd);
 
- 								close(active_sd);
 
- 								FD_CLR(active_sd, &master_set);
 
- 								if (active_sd == max_sd) {
 
- 										while (FD_ISSET(max_sd, &master_set) == false) {
 
- 												max_sd -= 1;
 
- 										}
 
- 								}
 
- 						}
 
- 						/* Mark new connection as active */
 
- 						active_sd = new_sd;
 
- 						DBG printf("	New active connection %d\n", active_sd);
 
- #endif
 
- 						/* Loop back up and accept another incoming   */
 
- 						/* connection                                 */
 
- 					} while (new_sd != -1);
 
- 				}
 
- 				/* This is not the listening socket, therefore an   */
 
- 				/* existing connection must be readable             */
 
- 				else {
 
- 					DBG printf("  Descriptor %d is readable\n", sock);
 
- 					for(cur_cnt = 0; cur_cnt < NUMBER_TELNET_CONNECT; cur_cnt ++){
 
- 						if(auth_tlnt_srvr_param[cur_cnt].num_connect == sock){
 
- 							break;
 
- 						}
 
- 					}
 
- 					/* Receive data on this connection until the  */
 
- 					/* recv fails with EWOULDBLOCK.  If any other */
 
- 					/* failure occurs, we will close the          */
 
- 					/* connection.                                */
 
- 					char c;
 
- 					if ((lBytes = recv(sock, &c, 1, 0)) > 0) {
 
- 						newdata(&auth_tlnt_srvr_param[cur_cnt], c);
 
- 					}
 
- 					if (lBytes < 0) {
 
- 						if (errno != EWOULDBLOCK){
 
- 							DBG printf("  recv() failed\n");
 
- 							auth_tlnt_srvr_param[cur_cnt].state = TELNET_STATE_CLOSE;
 
- 						}
 
- 					}
 
- 					/* Check to see if the connection has been    */
 
- 					/* closed by the client                       */
 
- 					if (lBytes == 0) {
 
- 						DBG printf("  Connection closed\n");
 
- 						auth_tlnt_srvr_param[cur_cnt].state = TELNET_STATE_CLOSE;
 
- 					}
 
- 					/* If the close_conn flag was turned on, we need */
 
- 					/* to clean up this active connection.  This     */
 
- 					/* clean up process includes removing the        */
 
- 					/* descriptor from the master set and            */
 
- 					/* determining the new maximum descriptor value  */
 
- 					/* based on the bits that are still turned on in */
 
- 					/* the master set.                               */
 
- 					if (auth_tlnt_srvr_param[cur_cnt].state == TELNET_STATE_CLOSE || auth_tlnt_srvr_param[cur_cnt].cli_state->state == STATE_CLOSE) {
 
- 						deconfigure_telnet_state(auth_tlnt_srvr_param + cur_cnt);
 
- 						cnt_conn -= 1;
 
- 						closesocket(sock);
 
- 						FD_CLR(sock, &master_set);
 
- 						if (sock == max_sd) {
 
- 							while (FD_ISSET(max_sd, &master_set) == false) {
 
- 								max_sd -= 1;
 
- 							}
 
- 						}
 
- 					}
 
- 				}
 
- 			}
 
- 		}
 
- 	}
 
- }
 
- void telnet_server_init(void) {
 
- 	xTaskCreate(vBasicSocketsCommandInterpreterTask, ( char * ) "vBasicSocketsCommandInterpreterTask", 8*configMINIMAL_STACK_SIZE , NULL, tskIDLE_PRIORITY + 1, NULL);
 
- }
 
 
  |