/*
 *
 * IOSControllerWiFi library (“The Software”) and the related documentation (“The Documentation”) are supplied to you 
 * by the Author in consideration of your agreement to the following terms, and your use or installation of The Software and the use of The Documentation 
 * constitutes acceptance of these terms.  
 * If you do not agree with these terms, please do not use or install The Software.
 * The Author grants you a personal, non-exclusive license, under author's copyrights in this original software, to use The Software. 
 * Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by the Author, including but not limited to any 
 * patent rights that may be infringed by your derivative works or by other works in which The Software may be incorporated.
 * The Software and the Documentation are provided by the Author on an "AS IS" basis.  THE AUTHOR MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT 
 * LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE SOFTWARE OR ITS USE AND OPERATION 
 * ALONE OR IN COMBINATION WITH YOUR PRODUCTS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, 
 * REPRODUCTION AND MODIFICATION OF THE SOFTWARE AND OR OF THE DOCUMENTATION, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 
 * STRICT LIABILITY OR OTHERWISE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * Author: Fabrizio Boco - fabboco@gmail.com
 *
 * All rights reserved
 *
 */

#include "IOSControllerWiFi.h"
#include <avr/eeprom.h>


#define ALARMCHECKDELAY 		  64000
#define ALARMCHECKDELAY_CONNECTED 50

#define LEAP_YEAR(Y)     ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) )

static  const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31}; // API starts months from 1, this array starts from 0

#ifdef ALARMS_SUPPORT
IOSControllerWiFi::IOSControllerWiFi(WiFiServer *server, 
                             void (*doWork)(void), 
                             void (*doSync)(char *variable),
                             void (*processIncomingMessages)(char *variable, char *value),
                             void (*processOutgoingMessages)(void),
                             void (*processAlarms)(char *alarm),
                             void (*deviceConnected)(void),
							 void (*deviceDisconnected)(void)
                             )
{
	_var = true;
    _idx = 0;
    _server = server;
    _doWork = doWork;
    _doSync = doSync;
    _processIncomingMessages = processIncomingMessages;
    _processOutgoingMessages = processOutgoingMessages;
    _processAlarms = processAlarms;
    _deviceConnected = deviceConnected;
    _deviceDisconnected = deviceDisconnected;
    
    _variable[0] = '\0';
    _value[0]    = '\0';
        
    _startTime = 0;
    _fireAlarmDelay = 0;
        
	this->inizializeAlarms();
}
#endif 


IOSControllerWiFi::IOSControllerWiFi(WiFiServer *server, 
                             void (*doWork)(void), 
                             void (*doSync)(char *variable),
                             void (*processIncomingMessages)(char *variable, char *value),
                             void (*processOutgoingMessages)(void),
                             void (*deviceConnected)(void),
							 void (*deviceDisconnected)(void)
                             )
{
	_var = true;
    _idx = 0;
    _server = server;
    _doWork = doWork;
    _doSync = doSync;
    _processIncomingMessages = processIncomingMessages;
    _processOutgoingMessages = processOutgoingMessages;
    _deviceConnected = deviceConnected;
    _deviceDisconnected = deviceDisconnected;
    
    _variable[0] = '\0';
    _value[0]    = '\0';
    
}                             

void IOSControllerWiFi::loop() {
	this->loop(150);
}

void IOSControllerWiFi::loop(unsigned long _delay) {
  	
#ifdef ALARMS_SUPPORT  	
  	
 	if (_processAlarms != NULL) {
		this->checkAndFireAlarms(ALARMCHECKDELAY);
    }
#endif  	
  	
 	_doWork();

	_client = _server->available();
    
  	if (_client) {

    	// Client connected
            
        if (_deviceConnected != NULL) {
        
        	_deviceConnected();	
        	// _sendNtpRequest = true;  // Sync Time
		}
        
    	while(_client.connected()) {
            
            // Read incoming messages if any
            this->readVariable();
            
            if (strcmp(_variable,"Sync") == 0 && strlen(_value)>0) {
                
                // Process sync messages for the variable _value
                _doSync(_value);
            }
            else {
            
#ifdef ALARMS_SUPPORT     
        	
            	// Manages Alarm creation and update requests
           
            	char id[8];
            	unsigned long time;
            	bool repeat;
            
            	if (strcmp(_variable,"$AlarmId$") == 0 && strlen(_value)>0) {
            	
            		strcpy(id,_value);	
            	} 
            	else if (strcmp(_variable,"$AlarmT$") == 0 && strlen(_value)>0) {
            	
            		time=atol(_value);
            	}
            	else if (strcmp(_variable,"$AlarmR$") == 0 && strlen(_value)>0) {

					if (time == 0)
						this->removeAlarm(id);
					else
            			this->createUpdateAlarm(id,time,atoi(_value));    
            			
            		#ifdef DEBUG
						this->dumpAlarms();
					#endif 
					     		 
            	}
            	else 
#endif            	
				{
#ifdef SDLOGGEDATAGRAPH_SUPPORT

  					if (strlen(_variable)>0 && strcmp(_variable,"$SDLogData$") == 0) {
    
    					this->sdSendLogData(_value);    			
  					}
  				
#endif
            		if (strlen(_variable)>0 && strlen(_value)>0) {
                
                		if (strcmp(_variable,"$Time$") == 0) {
                	
                			_startTime = atol(_value)-millis()/1000;
#ifdef DEBUG
							Serial.println(_value);
							Serial.println(atol(_value));
							Serial.println("Time Synchronized");
#endif                		
                		}                
                
	    	            // Process incoming messages
    	    	        _processIncomingMessages(_variable,_value);
            		} 
            	}
            }
            
#ifdef ALARMS_SUPPORT             

            // Check and Fire Alarms
            if (_processAlarms != NULL) {
				this->checkAndFireAlarms(ALARMCHECKDELAY_CONNECTED);
            }
            
#endif
            // Write outgoing messages
            _processOutgoingMessages();
            
#ifdef ALARMS_SUPPORT             
            // Sync local time with NTP Server
            
            
#endif
  			            
            _doWork();
            
            delay(_delay);
        }
        
        // Client disconnected
        _client = NULL;
        
    	if (_deviceDisconnected != NULL)
        	_deviceDisconnected();

        //Serial.println();
        //Serial.println("disconnecting.");
        _client.stop();
    }
    
}

void IOSControllerWiFi::readVariable(void) {
    
	int c=0;

	_variable[0]='\0'; 
	_value[0]='\0';
	    
    //Serial.println("readVariable");
    
	while (_client.available()) {
        
/*                
        if (_upload) {
        
        	_dataFile.write(_client.read());
        	
        	_fileLen++;
        	//Serial.println(_fileLen);
        	
        	if (_fileLen == _expectedFileLen) {
        	
	        	_upload = false;  
        		_dataFile.close();
        		
        		this->writeTxtMessage("SD","$ESDUL$");

				_fileLen = 0;
        	}
        	
        }
        else {
*/        
        char c = _client.read();
        
        //Serial.print(c);
        
        if (isprint (c)) {
            
            //Serial.println("isprintf");
            
            if ((char)c == '=') {
                
                _variable[_idx]='\0'; 
                _var = false; 
                _idx = 0;
            }
            else {
                
                if ((char)c == '#') {
                                        
                    _value[_idx]='\0'; 
                    _var = true; 
                    _idx = 0; 
                    
#ifdef SD_SUPPORT	
				if (strcmp(_variable,"SD")==0) {
   
   					//Serial.println("List of Files");
   					
					this->sendFileList();
				}

				if (strcmp(_variable,"$SDDL$")==0) {
    
  					//Serial.print("File: "); Serial.println(_value);
    
   					this->sendFile(_value);
				}
		
/*		
				if (strcmp(_variable,"$SDUL$")==0) {

    				_upload = true;
    				_fileLen = 0;   					

    				char name[20];
    				char len[20];
    				
    				byte idx = 0;
    				byte wIdx = 0;
    				
    				while(_value[idx] != ':') {
    					
    					name[wIdx++] = _value[idx++];
    				}
    				name[wIdx] = '\0';
    				
    				strcpy(len,&_value[idx+1]);
    				    				
    				_expectedFileLen = atol(len);	
    				    				
					if (SD.exists(name))  
						SD.remove(name);  				    				
    				_dataFile = SD.open(name,FILE_WRITE);
    					    					
    				Serial.println("Starting upload");
    				Serial.print("Size: "); Serial.println(len);

    				Serial.println(">");
			    	Serial.println(">");
    				while(!Serial.available())
						;
					Serial.read();	
 				}			
*/ 					
#endif 	
                                    
                    return;
                }
                else {
                    
                    if (_var) {
                    
                        if(_idx==VARIABLELEN) 
	                        _variable[_idx] = '\0';
	                        else
                        	_variable[_idx++] = c;
                    }
                    else {
                        
                        if(_idx==VALUELEN)
                        	_value[_idx] = '\0';
                        	else
                        	_value[_idx++] = c;
                    }
                }
            }
        }
    }    
    //}
}


void IOSControllerWiFi::writeMessage(char *variable, float value)
{
    char buffer[VARIABLELEN+VALUELEN+3];
    char vbuffer[VALUELEN];
         
	if (_client == NULL)
    	return;   
    	
    dtostrf(value, 0, 3, vbuffer);    
    snprintf(buffer,VARIABLELEN+VALUELEN+3, "%s=%s#", variable, vbuffer); 
        
    _client.write((const uint8_t *)buffer, strlen(buffer)*sizeof(char));
}


void IOSControllerWiFi::writeTxtMessage(char *variable, char *value) 
{
    char buffer[128];    
        
    snprintf(buffer,128, "%s=%s#", variable, value);
    
    _client.write((const uint8_t *)buffer, strlen(buffer)*sizeof(char));

/*
	int i = 0;
    while(variable[i] != '\0') 
    {
        _client.write(variable[i++]);
    }
    
    _client.write('=');
    
    i = 0;
    while(value[i] != '\0') 
    {
        _client.write(value[i++]);
    }

    _client.write('#');
*/    
}

void IOSControllerWiFi::log(char *msg) 
{
	this->writeTxtMessage("$D$",msg);
}

void IOSControllerWiFi::log(int msg)
{
	char buffer[11];
	itoa(msg, buffer, 10);
	
	this->writeTxtMessage("$D$",buffer);
}


void IOSControllerWiFi::logLn(char *msg) 
{
	this->writeTxtMessage("$DLN$",msg);
}

void IOSControllerWiFi::logLn(int msg)
{
	char buffer[11];
	itoa(msg, buffer, 10);
	
	this->writeTxtMessage("$DLN$",buffer);
}

void IOSControllerWiFi::logLn(long msg)
{
	char buffer[11];
	ltoa(msg, buffer, 10);
	
	this->writeTxtMessage("$DLN$",buffer);
}

void IOSControllerWiFi::logLn(unsigned long msg) {

	char buffer[11];
	ltoa(msg, buffer, 10);
	
	this->writeTxtMessage("$DLN$",buffer);
}

#ifdef SD_SUPPORT
void IOSControllerWiFi::sendFileList(void) 
{
 	File root = SD.open("/");
 	root.rewindDirectory();
    
    File entry =  root.openNextFile();
        
    while(entry) {
    
      	if(!entry.isDirectory())
        	this->writeTxtMessage("SD",entry.name());

		entry.close();
      	entry =  root.openNextFile();
    }
    
    root.close();
    
    this->writeTxtMessage("SD","$EFL$");
}


void IOSControllerWiFi::sendFile(char *fileName) {
	
    File dataFile = SD.open(_value,FILE_READ);
	
	if (dataFile) {
	
		//unsigned long tot = 0;
	
		//this->writeTxtMessage("SD","$C$");
		_client.print("SD=$C$#");
				
		delay(3000);
				
		byte n=0;
		uint8_t buffer[32];

		while(dataFile.available()) {
				
			n = dataFile.read(buffer, sizeof(buffer));			
			_client.write(buffer, n*sizeof(uint8_t));	
				
			//tot += n;		
			//Serial.println(tot);
		}
/*		
		while(dataFile.available()) {
				
			_client.write(dataFile.read());
			//n++;
			//Serial.print("n: "); Serial.println(n);
		}				
*/								

		strcpy((char *)&buffer[0],"SD=$E$#");
		_client.write(buffer,7*sizeof(uint8_t));
		
		dataFile.close();
		
		//Serial.println("End File sent");
	}
	else {
		
		//Serial.println("File not available");
	}

}

/*
void IOSControllerWiFi::sendFile(char *fileName) {

	this->writeTxtMessage("SD","$C$");
	
	File dataFile = SD.open(fileName,FILE_READ);
	
	if (dataFile) {
	
		char buffer[64];
		int idx = -1;
	
		while(dataFile.available()) {
		
			char b = dataFile.read();
			idx++;
			
			if (idx == 64) {
				buffer[64] = '\0';
				_client.print(buffer);
				idx = 0;
			}
			buffer[idx]=b;
			Serial.print(b);
		}
		
		buffer[idx] = '\0';
		_client.print(buffer);
		
		dataFile.close();
		
		delay(5);
		
		this->writeTxtMessage("SD","$E$");
	}	
}
*/
#endif

void IOSControllerWiFi::temporaryDigitalWrite(uint8_t pin, uint8_t value, unsigned long ms) {

	int previousValue = digitalRead(pin);

    digitalWrite(pin, value);
    delay(ms);
    digitalWrite(pin, previousValue);
}


// Time Management 

#ifdef ALARMS_SUPPORT 
void IOSControllerWiFi::setNTPServerAddress(IPAddress address) {

	
}

unsigned long IOSControllerWiFi::now() {
	
	unsigned long now = _startTime + millis()/1000;
	
	return now;
}

void IOSControllerWiFi::breakTime(unsigned long time, int *seconds, int *minutes, int *hours, int *Wday, long *Year, int *Month, int *Day) {
  // break the given time_t into time components
  // this is a more compact version of the C library localtime function
  // note that year is offset from 1970 !!!

  unsigned long year;
  uint8_t month, monthLength;
  unsigned long days;

  *seconds = time % 60;
  time /= 60; // now it is minutes
  *minutes = time % 60;
  time /= 60; // now it is hours
  *hours = time % 24;
  time /= 24; // now it is days
  *Wday = ((time + 4) % 7) + 1;  // Sunday is day 1 

  year = 1970;  
  days = 0;
  while((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) {
    year++;
  }
  *Year = year; // year is offset from 1970 

  days -= LEAP_YEAR(year) ? 366 : 365;
  time  -= days; // now it is days in this year, starting at 0

  days=0;
  month=0;
  monthLength=0;
  for (month=0; month<12; month++) {
    if (month==1) { // february
      if (LEAP_YEAR(year)) {
        monthLength=29;
      } 
      else {
        monthLength=28;
      }
    } 
    else {
      monthLength = monthDays[month];
    }

    if (time >= monthLength) {
      time -= monthLength;
    } 
    else {
      break;
    }
  }
  *Month = month + 1;  // jan is month 1  
  *Day = time + 1;     // day of month
}


#ifdef DEBUG
void IOSControllerWiFi::printTime(unsigned long time) {

    	int seconds;
   		int minutes;
   		int hours;
   		int Wday;
   		long Year;
   		int Month;
   		int Day;
		
		this->breakTime(time, &seconds, &minutes, &hours, &Wday, &Year, &Month, &Day);

	   	Serial.print(Day);
	   	Serial.print("/");
	   	Serial.print(Month);
	   	Serial.print("/");
	   	Serial.print(Year);
	   	Serial.print(" ");
	   	Serial.print(hours);
	   	Serial.print(":");
	   	Serial.print(minutes);
	   	Serial.print(":");
	   	Serial.print(seconds);
}
#endif

void IOSControllerWiFi::createUpdateAlarm(char *id, unsigned long time, bool repeat) {

	char lid[12];
	
	lid[0] = 'A';
	strcpy(&lid[1],id);

	// Update

	for(int i=0; i<5; i++) {
		
		alarm a;
		
		eeprom_read_block((void*)&a, (void*)(i*sizeof(a)), sizeof(a));
		
		if (strcmp(a.id,lid) == 0) {
				a.time = time;
				a.repeat = repeat;
				
				eeprom_write_block((const void*)&a, (void*)(i*sizeof(a)), sizeof(a));
				
				return;
		}		
	}

	// Create

	for(int i=0; i<5; i++) {
	
		alarm a;
		
		eeprom_read_block((void*)&a, (void*)(i*sizeof(a)), sizeof(a));
	
		if(a.id[1]=='\0') {
		
			strcpy(a.id,lid);
			a.time = time;
			a.repeat = repeat;
		
			eeprom_write_block((const void*)&a, (void*)(i*sizeof(a)), sizeof(a));
			
			return;
		}
	}
}

void IOSControllerWiFi::removeAlarm(char *id) {

	char lid[12];
	
	lid[0] = 'A';
	strcpy(&lid[1],id);

	for(int i=0; i<5; i++) {
	
		alarm a;
		
		eeprom_read_block((void*)&a, (void*)(i*sizeof(a)), sizeof(a));
	
		if(strcmp(a.id,lid) == 0) {
		
			a.id[1]='\0';
			a.time = 0;
	        a.repeat = 0;
			
			eeprom_write_block((const void*)&a, (void*)(i*sizeof(a)), sizeof(a));
		}
	}
}

void IOSControllerWiFi::inizializeAlarms() {

	for(int i=0; i<5; i++) {
	
		alarm a;
		
		eeprom_read_block((void*)&a, (void*)(i*sizeof(a)), sizeof(a));
	
		if(a.id[0] != 'A') {
		
			a.id[0]='A';
			a.id[1]='\0';
			a.time=0;
			a.repeat = 0;
			
			eeprom_write_block((const void*)&a, (void*)(i*sizeof(a)), sizeof(a));
		}
	}
}

#ifdef DEBUG
void IOSControllerWiFi::dumpAlarms() {

	Serial.println("\t----Dump Alarms -----"); 
	
	for(int i=0;i<5; i++) {

		alarm al;
					
		eeprom_read_block((void*)&al, (void*)(i*sizeof(al)), sizeof(al));

		Serial.print("\t");
    	Serial.print(al.id); 
    	Serial.print(" "); 
    	this->printTime(al.time);
    	Serial.print(" ");
    	Serial.println(al.repeat);
	}
}
#endif

void IOSControllerWiFi::checkAndFireAlarms(unsigned long delay) {

	if (_fireAlarmDelay < delay) {
		_fireAlarmDelay++;
    }
	else {
    	_fireAlarmDelay=0;

		unsigned long now = _startTime + millis()/1000;

#ifdef DEBUG
		Serial.print("checkAndFireAlarms ");
	    this->printTime(now);
	    Serial.println();
#endif

	    for(int i=0; i<5; i++) {

			alarm a;

			eeprom_read_block((void*)&a, (void*)(i*sizeof(a)), sizeof(a));

	    	if(a.id[1]!='\0' && a.time<now) {

#ifdef DEBUG
				Serial.println(a.id);
#endif				
				// First character of id is A and has to be removed
            	_processAlarms(&a.id[1]);

	    		if(a.repeat) {
	    	
    	    		a.time += 86400; // Scheduled again tomorrow
    	    		
#ifdef DEBUG
					Serial.print("Alarm rescheduled at ");
	            	this->printTime(a.time);
#endif	            Serial.println();	
            	}
	        	else {
            		//     Alarm removed
            	
	            	a.id[1]='\0';
	            	a.time = 0;
	            	a.repeat = 0;
            	}

				eeprom_write_block((const void*)&a, (void*)(i*sizeof(a)), sizeof(a));
#ifdef DEBUG
				this->dumpAlarms();
#endif        		 
			}
    	}
	}
}
#endif

#ifdef SDLOGGEDATAGRAPH_SUPPORT

void IOSControllerWiFi::sdLogLabels(char *variable, char *label1) {

	this->sdLogLabels(variable,label1,NULL,NULL,NULL,NULL);
}

void IOSControllerWiFi::sdLogLabels(char *variable, char *label1, char *label2) {

	this->sdLogLabels(variable,label1,label2,NULL,NULL,NULL);
}

void IOSControllerWiFi::sdLogLabels(char *variable, char *label1, char *label2, char *label3) {

	this->sdLogLabels(variable,label1,label2,label3,NULL,NULL);
}

void IOSControllerWiFi::sdLogLabels(char *variable, char *label1, char *label2, char *label3, char *label4) {

	this->sdLogLabels(variable,label1,label2,label3,label4,NULL);
}

void IOSControllerWiFi::sdLogLabels(char *variable, char *label1, char *label2, char *label3, char *label4, char *label5) {

	File dataFile = SD.open(variable, FILE_WRITE);
  
  	if (dataFile) 
  	{
    	dataFile.print("-");
    	dataFile.print(";");
    	dataFile.print(label1);
    	dataFile.print(";");

    	if(label2 != NULL)
	    	dataFile.print(label2);
	    else
	    	dataFile.print("-");
    	dataFile.print(";");
    	
    	if(label3 != NULL)
	    	dataFile.print(label3);
	    else
	    	dataFile.print("-");
    	dataFile.print(";");
    	
    	if(label4 != NULL)
	    	dataFile.print(label4);
	    else
	    	dataFile.print("-");
    	dataFile.print(";");
    	
    	if(label5 != NULL)
	    	dataFile.println(label5);
	    else
	    	dataFile.println("-");
    
    	dataFile.flush();
    	dataFile.close();
  	}
}


void IOSControllerWiFi::sdLog(char *variable, unsigned long time, float v1) {

	File dataFile = SD.open(variable, FILE_WRITE);
  
  	if (dataFile && time>0) 
  	{
    	dataFile.print(time);
    	dataFile.print(";");
    	dataFile.print(v1);
     
    	dataFile.print(";-;-;-;-");
    	    
    	dataFile.flush();
    	dataFile.close();
  	}
}

void IOSControllerWiFi::sdLog(char *variable, unsigned long time, float v1, float v2) {

	File dataFile = SD.open(variable, FILE_WRITE);
  
  	if (dataFile && time>0) 
  	{
    	dataFile.print(time);
    	dataFile.print(";");
    	dataFile.print(v1);
    	dataFile.print(";");

    	dataFile.print(v2);
     
    	dataFile.print(";-;-;-");
    	    
    	dataFile.flush();
    	dataFile.close();
  	}
}

void IOSControllerWiFi::sdLog(char *variable, unsigned long time, float v1, float v2, float v3) {

	File dataFile = SD.open(variable, FILE_WRITE);
  
  	if (dataFile && time>0) 
  	{
    	dataFile.print(time);
    	dataFile.print(";");
    	dataFile.print(v1);
    	dataFile.print(";");

    	dataFile.print(v2);
    	dataFile.print(";");
     
       	dataFile.print(v3);
    	
    	dataFile.print(";-;-");
    	        
    	dataFile.flush();
    	dataFile.close();
  	}
}

void IOSControllerWiFi::sdLog(char *variable, unsigned long time, float v1, float v2, float v3, float v4) {

	File dataFile = SD.open(variable, FILE_WRITE);
  
  	if (dataFile && time>0) 
  	{
    	dataFile.print(time);
    	dataFile.print(";");
    	dataFile.print(v1);
    	dataFile.print(";");

    	dataFile.print(v2);
    	dataFile.print(";");
     
       	dataFile.print(v3);
    	dataFile.print(";");
    	
    	dataFile.print(v4);
    	    
	    dataFile.println(";-");
    
    	dataFile.flush();
    	dataFile.close();
  	}
}

void IOSControllerWiFi::sdLog(char *variable, unsigned long time, float v1, float v2, float v3, float v4, float v5) {

	File dataFile = SD.open(variable, FILE_WRITE);
  
  	if (dataFile && time>0) 
  	{
    	dataFile.print(time);
    	dataFile.print(";");
    	dataFile.print(v1);
    	dataFile.print(";");

    	dataFile.print(v2);
    	dataFile.print(";");
    	
    	dataFile.print(v3);
    	dataFile.print(";");
    	
    	dataFile.print(v4);
    	dataFile.print(";");
    	
    	dataFile.println(v5);
    
    	dataFile.flush();
    	dataFile.close();
  	}
}
	
void IOSControllerWiFi::sdSendLogData(char *variable) {

//Serial.print("sdSendLogData for ");
//Serial.println(variable);

int rows = 0;

	cli();
    
  	File dataFile = SD.open(variable, FILE_READ); 
  	if (dataFile) {
    
    	char c;
    	char buffer[128];
    	int i = 0;
                        
    	dataFile.seek(0);
    	
    	
    	while( (c=dataFile.read()) != -1 ) {
      
      		if (c == '\n') {
        
        		buffer[i++] = '\0';
        
		        this->writeTxtMessage(variable,buffer); 
        
        		i=0;
        		
        		rows++;
      		}
      		else {      		
        		buffer[i++] = c;
        	}
        	
        	//delay(5);
    	}    	

		dataFile.close();
  	}
  
  	this->writeTxtMessage(variable,"");
  
  	sei();  	
}	
	
#endif	