 /**
- * apolloClient is a sketch that downloads another sketch from a webserver and loads
- * it onto the arduino.
- * 
- * The sketch should have been created with the apollo/mkfirmware tool. The sketch is 
- * downloaded onto an sdcard, and integrity is checked against a few 'prepended'
- * bytes. The first two bytes of the binary represent the size of the file excluding
- * the prepended bytes. The following two bytes represent the checksum of the remainder
- * of the file, which is computed using a fletcher 16 algorithm.
- * 
- * Once a binary file has been succesfully downloaded the arduino will issue a reset
- * call, which will allow the bootloader to load the new firmware.
- * 
- * This sketch works fine on it's own, but there's no point in it unless the arduino
- * it is running on has a modified bootloader.
- * 
- * Author: Jadin Roste Andrews 
- * Email: jadinandrews@gmail.com
- * 
- * TODO: This is like the first working version, with most features in place, lots can still be improved.
- * TODO: Need a way to store the downloaded file in a temporary file, and then rename it to FIRMWARE.BIN
- *       only if the download passes the checks. I don't think this is an easy task with the fat16 lib,
- *       but maybe it won't be too bad to simply copy a temp file into FIRMWARE.BIN? 
- *       
- * NOTE: This sketch relies on the Seedstudio ethernet shieal v2.0, with an integrated SD card slot.
- *       For other cobinations, just make sure your cs pins don't conflict, otherwise everything should
- *       work just fine.
- * 
+   apolloClient is a sketch that downloads another sketch from a webserver and loads
+   it onto the arduino.
+
+   The sketch should have been created with the apollo/mkfirmware tool. The sketch is
+   downloaded onto an sdcard, and integrity is checked against a few 'prepended'
+   bytes. The first two bytes of the binary represent the size of the file excluding
+   the prepended bytes. The following two bytes represent the checksum of the remainder
+   of the file, which is computed using a fletcher 16 algorithm.
+
+   Once a binary file has been succesfully downloaded the arduino will issue a reset
+   call, which will allow the bootloader to load the new firmware.
+
+   This sketch works fine on it's own, but there's no point in it unless the arduino
+   it is running on has a modified bootloader.
+
+   Author: Jadin Roste Andrews
+   Email: jadinandrews@gmail.com
+
+   TODO: This is like the first working version, with most features in place, lots can still be improved.
+   TODO: Need a way to store the downloaded file in a temporary file, and then rename it to FIRMWARE.BIN
+         only if the download passes the checks. I don't think this is an easy task with the fat16 lib,
+         but maybe it won't be too bad to simply copy a temp file into FIRMWARE.BIN?
+
+   NOTE: This sketch relies on the Seedstudio ethernet shieal v2.0, with an integrated SD card slot.
+         For other cobinations, just make sure your cs pins don't conflict, otherwise everything should
+         work just fine.
+
  * */
 
 

    const char name[] = "FIRMWARE.BIN";
    file.open(name, O_CREAT | O_WRITE);

    sendGET();

    
    Serial.println();
    Serial.print(F("Prepended Value = "));
    int prependedSize = twoBytes();
    byte checkSum1 = client.read();
    byte checkSum2 = client.read();
    Serial.print(prependedSize);
    Serial.println(F(" bytes"));
    Serial.print(F("Prepended Sum1 = "));
    Serial.println(checkSum1);
    Serial.print(F("Prepended Sum2 = "));
    Serial.println(checkSum2);
    
    
    
    Serial.print(F("Data: "));
      int i = 0;
      byte sum1 = 0;
      byte sum2 = 0;

      while(client.connected()) {
        while(client.available()) {
          byte e = client.read();

          if (i == 0) {
            Serial.print(F("0% "));
          }
          if(i % (prependedSize / 64) == 0) {
            Serial.print(F("."));
          }
          if(i == prependedSize - 1) {
            Serial.print(F(" 100%"));
          }
      
          file.write(e);
          sum1 = (sum1 + e) % 255;
          sum2 = (sum2 + sum1) % 255;
          i++;
        }
      }
    Serial.println();
    Serial.print("Sum1 = ");
    Serial.print(sum1);
    Serial.print("; Sum2 = ");
    Serial.println(sum2);
    
    file.close();
    Serial.println();
    Serial.print(i);
    Serial.println(F(" Bytes Received."));
    if (prependedSize <= 0 || prependedSize != i || checkSum1 != sum1 || checkSum2 != sum2) {
      Serial.println(F("ERROR RECEIVING FIRMWARE!"));
    }
    else {
      Serial.println(F("SUCCESS!"));
    }
    if (!client.connected()) {
      Serial.println(F("Disconecting from update server"));
      client.stop();
    }
  
    //Disable the SD card:
    pinMode(CHIP_SELECT, OUTPUT);
    digitalWrite(CHIP_SELECT, HIGH);

    if(i > 4096) {
      Serial.println(F("Resetting..."));
      delay(200);
      resetFunc();
    }
  }
 }

void sendGET() //client function to send/receive GET request data.
{
  Serial.println(F("Getting new Firmware file"));
  if (client.connect(updateServer, 80)) {  //starts client connection, checks for connection
    Serial.println(F("Connected to Update Server"));
    client.println(F("GET /apollo/FIRMWARE.BIN HTTP/1.1")); //download text
    client.println(F("Host: www.debcal.co.za"));
    client.println(F("Connection: close"));  //close 1.1 persistent connection  
    client.println(); //end of get request

      // Wait for http reponse and remove header
      Serial.println(F("waiting for data"));
  while(client.connected()) {
    while(client.available()) {
      if (checkBytes(crnl, byteStream)) {
        goto end;
      }
    }
  }
  end:
  Serial.println(F("done waiting for data"));
  } 
  else {
    Serial.println(F("connection failed")); //error message if no client connect
    Serial.println();
  }
}

/**
 * setupWDT sets up the watchdog timer bits and scaler to execute every 8s.
 */
void setupWDT()
{
  // Clear the reset flag.
  MCUSR &= ~(1<<WDRF);
  
  // In order to change WDE or the prescaler, we need to
  // set WDCE (This will allow updates for 4 clock cycles).
  WDTCSR |= (1<<WDCE) | (1<<WDE);

  // Set new watchdog timeout prescaler value
  // 8.0 seconds
  WDTCSR = 1<<WDP0 | 1<<WDP3;
  
  // Enable the WD interrupt.
  WDTCSR |= _BV(WDIE);
}


/**
  * The WDT_vect routine is called by the WDT interrupt.
  * The Arduino will be reset once the update interval has been exceeded.
  *
  */
ISR(WDT_vect)
{
  updateCounter++;
   if (updateCounter * 8 / 15 >= updateInterval)
   {
     updateNow = true;
   }
   // Quick Lock up watch Dawg.
   else if (updateCounter * 8 / 60 >= updateInterval)
   {
    resetFunc();
   }
}

/**
 * resetEthernet reset the ethernet controller.
 * @param pin is to be directly connected to the reset pin on the ethernet shield.
 */
void resetEthernet(int pin) {
  pinMode(pin, OUTPUT);
  digitalWrite(pin, LOW);


bool checkBytes(char* bytes, char (*stream)()) {
  int byteCount = 0;
  while (matchingBytes < 4) {
    matchingBytes = bytes[matchingBytes] == stream() ? matchingBytes + 1 : 0;
    byteCount++;
    if (byteCount >= 2048) {
