char *dataBuffer; //The dataBuffer Array Pointer for the TCP-Data to send over the handleData Function uint8_t *dataSplit; //The dataSplit Array Pointer for indicating with Data needs to send next for the handleData Function /* Puts the Data which we want to send to the Client into a buffer in the RAM to send it when we received * the last ACK from the package before. If the function gets called at the first time then the data is * directly given to the Client via calling the tcpSend() Function. * Arguments: * uint8_t *buf: The Ethernetbuffer * char *data : Data we want to send */ void tcpSendToClient(uint8_t *buf, char* data) { static uint16_t offset = 0; //Offset in the dataBuffer if(freeed) offset = 0; //In case the function gets called after we reset everything reset also the offset back to zero if(!currentlySended) { //Are we currently not sending? Send directly to Client the Data bool makeAckself = false; //Making the ACK itself? if(initialSend) { //Is this the Initial Send of Data and the Client has no Data send before. In this case we have no information about seq nr and ack. So we need to make itself the SEQ and ACK from the SYN/ACK Package makeAckself = true; //Making ACK itself }else{ //No Initial Send? Client has send Data before makeAckself = false; //Using SEQ and ACK from last Package to calculate it right } tcpSend(buf, data, makeAckself); //Send the Data to the Client currentlySended = true; //Currently sending yes }else{ //We are currently sending so we can put the Data directly to the Client we need to store them in RAM uint16_t dSize = strlen(data); //Get Length of the Data if(dataBuffer == NULL || freeed) { //If dataBuffer is NULL (malloc initialize or failed) or we have reset the Data freeed = false; //We have reset the data dataBuffer = malloc((dSize + 1) * sizeof(char)); //Allocate Memory dataSplit = malloc(2 * sizeof(uint8_t)); }else{ //dataBuffer is not NULL and reset is not active so realloc the new requested Memory for the RAM freeed = false; dataBuffer = realloc(dataBuffer, (offset + dSize + 1) * sizeof(char)); dataSplit = realloc(dataSplit, 2 * sizeof(uint8_t)); } if(dataBuffer == NULL || dataSplit == NULL) { //malloc or realloc for databuffer/dataSplit has failed return; //Exit } uint16_t end = offset + dSize; //Calculate the End of the Data Length for(uint16_t i = offset; i < end; i++) { //For Loop dataBuffer[i] = data[i - offset]; //Copy the Data from input (data argument of this function) to the dataBuffer in RAM } dataSplit[dataInBuffer] = dSize; //Set the data length in the data Indicator for the handleTCPSend Function dataSplit[dataInBuffer + 1] = 0xFF; //Add by dataInBuffer + 1 the 0xFF in the data Indicator dataInBuffer += 2; //Increase dataInBuffer by two offset += dSize; //Increase Offset by current Length of Data for next run } } /* Handles the TCP Data Send. Multiple Message are put via tcpSendToClient into a buffer. The first Message will be directly send to the Client * via the tcpSend() Function. If more Message needs to be send but no ACK is received the other Message will be stored in the RAM and if a ACK * is received then the next Message will be send to the Client and so on until no more data is in the ram. Then everything gets reseted * Arguments: * uint8_t *buf : The Ethernetbuffer */ void handleTCPSend(uint8_t *buf) { static uint16_t index = 0; //Current Index in dataBuffer static uint16_t oldLengthOfData = 0; //Length of the last data Package in dataBuffer if(dataSplit[index + 1] == 0xFF) { //Check if we have more Data to send. index[0] is the Length of Data and index[1] is 0xFF to indicate the end of the first data if(!currentlySended) { //Check if we are currently Sending if(dataSplit != NULL && dataBuffer != NULL) { //Check if both Arrays are not NULL (In case that malloc or realloc failed) uint16_t lengthOfData; //The Length of the Data which needs to extracted from the dataBuffer bool dataFound = false; //Indicates if we have found a new Data Package while(true) { //Loop if(dataSplit[index] == 0xFF) { //Check if index is 0xFF (End of Data Package) lengthOfData = dataSplit[index - 1]; //Get the Length of the Data Package (if index is 0xFF then index - 1 contains the length of the Data Package) index++; //Increase Index by 1 dataFound = true; //Set Flag Data found break; //Break loop } index++; //Increase Index again by one to hit the 0xFF } if(!dataFound) return; //If no Data was found exit Function char *send; send = (char*) malloc((lengthOfData + 1) * sizeof(char)); if(send == NULL) return; //malloc failed. Exit memset(send, 0x00, sizeof(send)); //Set the Buffer to Zeros only for(uint16_t i = 0; i < lengthOfData; i++) { //For Loop send[i] = dataBuffer[oldLengthOfData + i]; //Copy new Data into the send Buffer } tcpSend(buf, send, true); //Sends the data to the TCP Client. 3th Argument is makeACKSelf. oldLengthOfData += lengthOfData; //Increase old Length by current Length to get the next Data package currentlySended = true; //Set Currently Sending to true }else{ return; //malloc or realloc failed. Exit Function } } }else{ //If we have no more data in RAM to send. if(!freeed) { //Have we reset everything for the next run? free(dataBuffer); //Free Memory from malloc free(dataSplit); //Free Memory from malloc index = 0; oldLengthOfData = 0; dataInBuffer = 0; freeed = true; } } }