/* * SDWebBrowse.ino * * This sketch uses the microSD card slot on the a WIZ5500 Ethernet shield * to serve up files over a very minimal browsing interface * * Some code is from Bill Greiman's SdFatLib examples, some is from the * Arduino Ethernet WebServer example and the rest is from Limor Fried * (Adafruit) so its probably under GPL * * Tutorial is at https://learn.adafruit.com/arduino-ethernet-sd-card/serving-files-over-ethernet * */ #include #include #include /************ ETHERNET STUFF ************/ byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // change if necessary byte ip[] = { 192, 168, 1, 177 }; // change if necessary EthernetServer server(80); /************ SDCARD STUFF ************/ #define SDCARD_CS 4 File root; #if defined(ESP8266) // default for ESPressif #define WIZ_CS 15 #elif defined(ESP32) #define WIZ_CS 33 #elif defined(ARDUINO_STM32_FEATHER) // default for WICED #define WIZ_CS PB4 #elif defined(TEENSYDUINO) #define WIZ_CS 10 #elif defined(ARDUINO_FEATHER52) #define WIZ_CS 11 #else // default for 328p, 32u4 and m0 #define WIZ_CS 10 #endif // store error strings in flash to save RAM #define error(s) error_P(PSTR(s)) void error_P(const char* str) { Serial.print(F("error: ")); Serial.println(str); while(1); } void setup() { Serial.begin(115200); while (!Serial); // For 32u4 based microcontrollers like 32u4 Adalogger Feather //Serial.print(F("Free RAM: ")); Serial.println(FreeRam()); if (!SD.begin(SDCARD_CS)) { error("card.init failed!"); } root = SD.open("/"); printDirectory(root, 0); // Recursive list of all directories Serial.println(F("Files found in all dirs:")); printDirectory(root, 0); Serial.println(); Serial.println(F("Done")); // Debugging complete, we start the server! Serial.println(F("Initializing WizNet")); Ethernet.init(WIZ_CS); // give the ethernet module time to boot up delay(1000); // start the Ethernet connection // Use the fixed IP specified. If you want to use DHCP first // then switch the Ethernet.begin statements Ethernet.begin(mac, ip); // try to congifure using DHCP address instead of IP: // Ethernet.begin(mac); // print the Ethernet board/shield's IP address to Serial monitor Serial.print(F("My IP address: ")); Serial.println(Ethernet.localIP()); server.begin(); } void ListFiles(EthernetClient client, uint8_t flags, File dir) { client.println(""); } // How big our line buffer should be. 100 is plenty! #define BUFSIZ 100 void loop() { char clientline[BUFSIZ]; char name[17]; int index = 0; EthernetClient client = server.available(); if (client) { // an http request ends with a blank line boolean current_line_is_blank = true; // reset the input buffer index = 0; while (client.connected()) { if (client.available()) { char c = client.read(); // If it isn't a new line, add the character to the buffer if (c != '\n' && c != '\r') { clientline[index] = c; index++; // are we too big for the buffer? start tossing out data if (index >= BUFSIZ) index = BUFSIZ -1; // continue to read more data! continue; } // got a \n or \r new line, which means the string is done clientline[index] = 0; // Print it out for debugging Serial.println(clientline); // Look for substring such as a request to get the file if (strstr(clientline, "GET /") != 0) { // this time no space after the /, so a sub-file! char *filename; filename = clientline + 5; // look after the "GET /" (5 chars) ******* // a little trick, look for the " HTTP/1.1" string and // turn the first character of the substring into a 0 to clear it out. (strstr(clientline, " HTTP"))[0] = 0; if(filename[strlen(filename)-1] == '/') { // Trim a directory filename filename[strlen(filename)-1] = 0; // as Open throws error with trailing / } Serial.print(F("Web request for: ")); Serial.println(filename); // print the file we want File file = SD.open(filename, O_READ); if ( file == 0 ) { // Opening the file with return code of 0 is an error in SDFile.open client.println("HTTP/1.1 404 Not Found"); client.println("Content-Type: text/html"); client.println(); client.println("

File Not Found!

"); client.println("

Couldn't open the File!

"); break; } Serial.println("File Opened!"); client.println("HTTP/1.1 200 OK"); if (file.isDirectory()) { Serial.println("is a directory"); //file.close(); client.println("Content-Type: text/html"); client.println(); client.print("

Files in /"); client.print(filename); client.println(":

"); ListFiles(client,LS_SIZE,file); file.close(); } else { // Any non-directory clicked, server will send file to client for download client.println("Content-Type: application/octet-stream"); client.println(); char file_buffer[16]; int avail; while (avail = file.available()) { int to_read = min(avail, 16); if (to_read != file.read(file_buffer, to_read)) { break; } // uncomment the serial to debug (slow!) //Serial.write((char)c); client.write(file_buffer, to_read); } file.close(); } } else { // everything else is a 404 client.println("HTTP/1.1 404 Not Found"); client.println("Content-Type: text/html"); client.println(); client.println("

File Not Found!

"); } break; } } // give the web browser time to receive the data delay(1); client.stop(); } } void printDirectory(File dir, int numTabs) { while(true) { File entry = dir.openNextFile(); if (! entry) { // no more files break; } for (uint8_t i=0; i