main/ims_tcp.c
/*
 * Task to get and set parameter settings from a web interface on port 80 at the local ip address of the ESP
 */
Task to get and set parameter settings from a web interface on port 80 at the local ip address of the ESP
Task to get and set parameter settings from a web interface on port 80 at the local ip address of the ESP
void tcp_task( void *pvParameter ){
	int tcpChild, fdmax;
	int listener;     
	int ii = 0, nbytes = 0;
	char tcpbuffer[BUFSIZE] = { 0 };
	struct sockaddr_in tcpServer;
	struct sockaddr_in remoteaddr; 
	socklen_t addrlen;
	struct timeval tv;
	fd_set tcpmaster, tcpreadfds;
	List_t socketList;
    globalPtrs = (globalptrs_t *) pvParameter;
	while(1){
		if( xEventGroupGetBits( globalPtrs->wifi_event_group ) & (WIFI_READY) ){
			tv.tv_sec = 0;
			tv.tv_usec = 1000;		
			tcpServer.sin_family = AF_INET;  			
			tcpServer.sin_port = htons(TCPPORT);		
			tcpServer.sin_addr.s_addr = INADDR_ANY;
			memset(tcpServer.sin_zero, '\0', sizeof tcpServer.sin_zero);	
			listener = socket(PF_INET, SOCK_STREAM, 0);
			fcntl(listener, F_SETFL, O_NONBLOCK);
			if (bind(listener, (struct sockaddr * )&tcpServer, sizeof(tcpServer))
					< 0) {
				perror("bind failed");
				return;
			}
			if (listen(listener, 10) == -1) {
				perror("listen");
				exit(1);
			}
			FD_ZERO(&tcpreadfds);  				
			FD_SET(listener, &tcpreadfds);		
			ListItem_t firstListItem;
			vListInitialiseItem(&firstListItem);
			firstListItem.xItemValue = listener;
			vListInitialise(&socketList);
			vListInsert(&socketList, &firstListItem);
			fdmax = getMaxListValue( &socketList );		
			tcpmaster = tcpreadfds;						
			for (;;) {
				ii = 0;
				tcpreadfds = tcpmaster;
				select(fdmax + 1, &tcpreadfds, NULL, NULL, &tv);
				ListItem_t tempItem;
				tempItem = *(ListItem_t *) listGET_HEAD_ENTRY( &socketList );	
				int len = listCURRENT_LIST_LENGTH( &socketList );
				for ( int aa = 0; aa < len; ++aa ){
					ii = listGET_LIST_ITEM_VALUE( &tempItem );
					if (FD_ISSET(ii, &tcpreadfds)) {
						if (ii == listener) {
							addrlen = sizeof remoteaddr;
							tcpChild = accept(listener,
									(struct sockaddr * ) &remoteaddr,
									&addrlen);
							if (tcpChild == -1)
								perror("accept");
							else {
								FD_SET(tcpChild, &tcpmaster);
								ListItem_t *newListItem = malloc(sizeof(ListItem_t));
								vListInitialiseItem(newListItem);
								listSET_LIST_ITEM_VALUE( newListItem, tcpChild );
								vListInsert(&socketList, newListItem);
								fdmax = getMaxListValue( &socketList );
							}
						} else {
							if ((nbytes = recv(ii, tcpbuffer, sizeof(tcpbuffer), 0)) <= 0) {
								if(nbytes < 0)
									perror("recvfrom failed");
							}
							else {
								tcpbuffer[nbytes + 1] = '\0';
								parseRecvData(tcpbuffer, nbytes, ii);
								if (notfound){
									send404ReplyHTML(ii);
									notfound = false;
								} else{
									sendReplyHTML(ii);
								}
								if( (xEventGroupGetBits( globalPtrs->wifi_event_group ) & (NEW_LOCALIP | NEW_NETMASK | NEW_GATEWAY )) > 0 ){
									xEventGroupClearBits( globalPtrs->wifi_event_group, (NEW_LOCALIP | NEW_NETMASK | NEW_GATEWAY ));
									init_wifi();
								}
							}
							close(ii);
							FD_CLR(ii, &tcpmaster);
							removeListItemWithValue( &socketList, ii);
							fdmax = getMaxListValue( &socketList );
						}
					}
					tempItem = *(ListItem_t *)listGET_NEXT( &tempItem );
				}
				if( (xEventGroupGetBits( globalPtrs->system_event_group ) & FW_UPDATE_SUCCESS ) > 0 ){
					xEventGroupClearBits( globalPtrs->system_event_group, ( FW_UPDATE_SUCCESS ));
				}
				else if( (xEventGroupGetBits( globalPtrs->system_event_group ) & FW_UPDATE_FAIL ) > 0 ){
					xEventGroupClearBits( globalPtrs->system_event_group, ( FW_UPDATE_FAIL ));
				}
				else if( (xEventGroupGetBits( globalPtrs->system_event_group ) & FW_UPDATE_CRITICAL_FAIL ) > 0 ){
					xEventGroupClearBits( globalPtrs->system_event_group, ( FW_UPDATE_CRITICAL_FAIL ));
				}
				vTaskDelay(pdMS_TO_TICKS(10)); 
			}
		}
		vTaskDelay(pdMS_TO_TICKS(50));
	}
}
void tcp_task ( void * pvParameter ) { int tcpChild , fdmax ; int listener ; int ii = 0 , nbytes = 0 ; char tcpbuffer [ BUFSIZE ] = { 0 } ; struct sockaddr_in tcpServer ; struct sockaddr_in remoteaddr ; socklen_t addrlen ; struct timeval tv ; fd_set tcpmaster , tcpreadfds ; List_t socketList ; globalPtrs = ( globalptrs_t * ) pvParameter ; while ( 1 ) { if ( xEventGroupGetBits ( globalPtrs -> wifi_event_group ) & ( WIFI_READY ) ) { tv . tv_sec = 0 ; tv . tv_usec = 1000 ; tcpServer . sin_family = AF_INET ; tcpServer . sin_port = htons ( TCPPORT ) ; tcpServer . sin_addr . s_addr = INADDR_ANY ; memset ( tcpServer . sin_zero , ' \0 ' , sizeof tcpServer . sin_zero ) ; listener = socket ( PF_INET , SOCK_STREAM , 0 ) ; fcntl ( listener , F_SETFL , O_NONBLOCK ) ; if ( bind ( listener , ( struct sockaddr * ) & tcpServer , sizeof ( tcpServer ) ) < 0 ) { perror ( " " ) ; return ; } if ( listen ( listener , 10 ) == -1 ) { perror ( " " ) ; exit ( 1 ) ; } FD_ZERO ( & tcpreadfds ) ; FD_SET ( listener , & tcpreadfds ) ; ListItem_t firstListItem ; vListInitialiseItem ( & firstListItem ) ; firstListItem . xItemValue = listener ; vListInitialise ( & socketList ) ; vListInsert ( & socketList , & firstListItem ) ; fdmax = getMaxListValue ( & socketList ) ; tcpmaster = tcpreadfds ; for ( ; ; ) { ii = 0 ; tcpreadfds = tcpmaster ; select ( fdmax + 1 , & tcpreadfds , NULL , NULL , & tv ) ; ListItem_t tempItem ; tempItem = * ( ListItem_t * ) listGET_HEAD_ENTRY ( & socketList ) ; int len = listCURRENT_LIST_LENGTH ( & socketList ) ; for ( int aa = 0 ; aa < len ; ++ aa ) { ii = listGET_LIST_ITEM_VALUE ( & tempItem ) ; if ( FD_ISSET ( ii , & tcpreadfds ) ) { if ( ii == listener ) { addrlen = sizeof remoteaddr ; tcpChild = accept ( listener , ( struct sockaddr * ) & remoteaddr , & addrlen ) ; if ( tcpChild == -1 ) perror ( " " ) ; else { FD_SET ( tcpChild , & tcpmaster ) ; ListItem_t * newListItem = malloc ( sizeof ( ListItem_t ) ) ; vListInitialiseItem ( newListItem ) ; listSET_LIST_ITEM_VALUE ( newListItem , tcpChild ) ; vListInsert ( & socketList , newListItem ) ; fdmax = getMaxListValue ( & socketList ) ; } } else { if ( ( nbytes = recv ( ii , tcpbuffer , sizeof ( tcpbuffer ) , 0 ) ) <= 0 ) { if ( nbytes < 0 ) perror ( " " ) ; } else { tcpbuffer [ nbytes + 1 ] = ' \0 ' ; parseRecvData ( tcpbuffer , nbytes , ii ) ; if ( notfound ) { send404ReplyHTML ( ii ) ; notfound = false ; } else { sendReplyHTML ( ii ) ; } if ( ( xEventGroupGetBits ( globalPtrs -> wifi_event_group ) & ( NEW_LOCALIP | NEW_NETMASK | NEW_GATEWAY ) ) > 0 ) { xEventGroupClearBits ( globalPtrs -> wifi_event_group , ( NEW_LOCALIP | NEW_NETMASK | NEW_GATEWAY ) ) ; init_wifi ( ) ; } } close ( ii ) ; FD_CLR ( ii , & tcpmaster ) ; removeListItemWithValue ( & socketList , ii ) ; fdmax = getMaxListValue ( & socketList ) ; } } tempItem = * ( ListItem_t * ) listGET_NEXT ( & tempItem ) ; } if ( ( xEventGroupGetBits ( globalPtrs -> system_event_group ) & FW_UPDATE_SUCCESS ) > 0 ) { xEventGroupClearBits ( globalPtrs -> system_event_group , ( FW_UPDATE_SUCCESS ) ) ; } else if ( ( xEventGroupGetBits ( globalPtrs -> system_event_group ) & FW_UPDATE_FAIL ) > 0 ) { xEventGroupClearBits ( globalPtrs -> system_event_group , ( FW_UPDATE_FAIL ) ) ; } else if ( ( xEventGroupGetBits ( globalPtrs -> system_event_group ) & FW_UPDATE_CRITICAL_FAIL ) > 0 ) { xEventGroupClearBits ( globalPtrs -> system_event_group , ( FW_UPDATE_CRITICAL_FAIL ) ) ; } vTaskDelay ( pdMS_TO_TICKS ( 10 ) ) ; } } vTaskDelay ( pdMS_TO_TICKS ( 50 ) ) ; } }
Task to get and set parameter settings from a web interface on port 80 at the local ip address of the ESP
Task to get and set parameter settings from a web interface on port 80 at the local ip address of the ESP
// listening socket descriptor // client address //1 ms timeout //leave this as is //http port //zero the rest of the struct //clear all entries from set of filedescriptors //add tcpSocket to the set //add tcpSocket to listitem //add listitem to list //keep track of highest socket number //'select' modifies readfds, so keep a backup of readfds for each loop //get first item in the list //loop through all file descriptors in the list //ESP_LOGI(TAG,"checking socket %d",ii); //if there is new data on a fd //new tcp connection request //Create new listitem and set its value //Add new listitem to list //read bytes from a client //got error or connection closed by client //some data received //								printf("\n%s\n\n",tcpbuffer); //print received data. TODO: comment out when not needed //								sendReplyHTML(ii); //restart wifi if there are new ip addresses //close connection //check if a firmware update has been completed //TODO: leaving this here for eventual update to show update progress in web interface or standalone app //					ESP_LOGI(TAG,"OTA successful, restarting..."); //					esp_restart(); //					ESP_LOGE(TAG,"OTA failed, try again."); //restart adc timer and interrupt //					ESP_LOGE(TAG,"OTA failed, restarting..."); //					esp_restart(); //delay to reduce processor load