HTTP Server, using SD card and EthernetInterface.

Dependencies:   EthernetInterface SDFileSystem mbed-rtos mbed

Files at this revision

API Documentation at this revision

Comitter:
azsymaivan
Date:
Sun Apr 07 11:23:03 2013 +0000
Commit message:
HTTP Server, using SD card and EthernetInterface. This code work, but sometimes mbed frizing. Always frizing occurs when mbed sent information to HTTP client. Exactly when call function tcpip_apimsg(struct api_msg *apimsg) in file "tcpip.c".

Changed in this revision

EthernetInterface.lib Show annotated file Show diff for this revision Revisions of this file
SDFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
filelib.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r fbb29d9ea96b EthernetInterface.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EthernetInterface.lib	Sun Apr 07 11:23:03 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/EthernetInterface/#9b2d10dc0392
diff -r 000000000000 -r fbb29d9ea96b SDFileSystem.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDFileSystem.lib	Sun Apr 07 11:23:03 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/azsymaivan/code/SDFileSystem/#f242d7bdef28
diff -r 000000000000 -r fbb29d9ea96b filelib.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/filelib.h	Sun Apr 07 11:23:03 2013 +0000
@@ -0,0 +1,127 @@
+#ifndef filelib
+#define filelib
+
+#include "mbed.h"
+#include <time.h>
+#include <ff.h> //found in lib SDFileSystem->FATFileSystem/ChaN
+#include "SDFileSystem.h"
+
+
+/*
+typedef enum {
+    FR_OK = 0,              // (0) Succeeded
+    FR_DISK_ERR,            // (1) A hard error occurred in the low level disk I/O layer
+    FR_INT_ERR,             // (2) Assertion failed
+    FR_NOT_READY,           // (3) The physical drive cannot work
+    FR_NO_FILE,             // (4) Could not find the file
+    FR_NO_PATH,             // (5) Could not find the path
+    FR_INVALID_NAME,        // (6) The path name format is invalid
+    FR_DENIED,              // (7) Access denied due to prohibited access or directory full
+    FR_EXIST,               // (8) Access denied due to prohibited access
+    FR_INVALID_OBJECT,      // (9) The file/directory object is invalid
+    FR_WRITE_PROTECTED,     // (10) The physical drive is write protected
+    FR_INVALID_DRIVE,       // (11) The logical drive number is invalid
+    FR_NOT_ENABLED,         // (12) The volume has no work area
+    FR_NO_FILESYSTEM,       // (13) There is no valid FAT volume
+    FR_MKFS_ABORTED,        // (14) The f_mkfs() aborted due to any parameter error
+    FR_TIMEOUT,             // (15) Could not get a grant to access the volume within defined period
+    FR_LOCKED,              // (16) The operation is rejected according to the file sharing policy
+    FR_NOT_ENOUGH_CORE,     // (17) LFN working buffer could not be allocated
+    FR_TOO_MANY_OPEN_FILES, // (18) Number of open files > _FS_SHARE
+    FR_INVALID_PARAMETER    // (19) Given parameter is invalid
+} FRESULT;
+
+*/
+/*
+mode_t values in octal
+       S_IFREG       0100000
+       S_IFDIR        040000
+       S_IRUSR          0400    read permission, owner
+       S_IWUSR          0200    write permission, owner
+       S_IXUSR          0100    execute/search permission, owner
+       S_IRGRP           040    read permission, group
+       S_IWGRP           020    write permission, group
+       S_IXGRP           010    execute/search permission, group
+       S_IROTH            04    read permission, others
+       S_IWOTH            02    write permission, others
+       S_IXOTH            01    execute/search permission, others
+*/
+struct sMystat {
+//               dev_t     st_dev;     /* ID of device containing file */
+//               ino_t     st_ino;     /* inode number */
+    mode_t    st_mode;    /* protection */
+//               nlink_t   st_nlink;   /* number of hard links */
+//               uid_t     st_uid;     /* user ID of owner */
+//               gid_t     st_gid;     /* group ID of owner */
+//               dev_t     st_rdev;    /* device ID (if special file) */
+    //        off_t     st_size;    /* total size, in bytes */
+    DWORD     st_size;    /* total size, in bytes */
+//               blksize_t st_blksize; /* blocksize for file system I/O */
+//               blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
+//               time_t    st_atime;   /* time of last access */
+    time_t    st_mtime;   /* time of last modification */
+//               time_t    st_ctime;   /* time of last status change */
+};
+
+sMystat myStatBuf;  //store info for file
+FILINFO finfo;      //global file info struct see ff.h
+FATFS_DIR dinfo;    //global directoty info struct see ff.h
+
+FRESULT get_fileInfo(const char *path)  //use finfo for get result fields
+{
+    FRESULT res = f_stat(path,&finfo);    /* Get file status */
+    if (EnDebugMSG)
+        if (res)
+            printf("\n-->get_fileInfo:%s ,res=%d ,Not Found!",path,res);
+        else
+            printf("\n-->get_fileInfo:%s ,res=%d ,Found!",path,res);
+    return res;
+}
+
+FRESULT get_dirInfo(const char *path)
+{
+    FRESULT res= f_opendir (&dinfo,path);   /* FR_OK(0): successful, !=0: error code */
+    if (EnDebugMSG)
+        if (res)
+            printf("\n-->get_dirInfo :%s res=%d ,This is Not Directory!",path,res);
+        else
+            printf("\n-->get_dirInfo :%s res=%d ,This is Directory!",path,res);
+    return res;
+}
+
+FRESULT Mystat(const char *path, struct sMystat *buf)
+{
+    FRESULT res = f_stat(path,&finfo);    /* Get file status */
+    if (res == FR_OK) {
+        buf->st_size = finfo.fsize;
+        buf->st_mtime = finfo.ftime;    //fdate;
+        buf->st_mode = 4;   //?
+    }
+    if (EnDebugMSG)
+        printf("\n--Mystat Path:%s ,filesize:%14lld ,res=%d",path, buf->st_size, res);
+    return res;
+}
+
+
+static char* get_mime_type( char* filename )
+{
+    char* extension;
+    extension = strrchr( filename, '.' );   //get string after last .
+    if (EnDebugMSG)
+        printf("\n-->get_mime_tipe filename:%s, extension:%s",filename, extension);
+    if (extension !=NULL) {
+        if (strcasecmp(extension,".htm")==0  || strcasecmp(extension,".html") ==0)
+            return "text/html; charset=iso-8859-1";
+        if (strcasecmp(extension,".png")==0)
+            return "image/png";
+        if (strcasecmp(extension,".css")==0)
+            return "text/css";
+        if (strcasecmp(extension,".gif")==0)
+            return "image/gif";
+        if (strcasecmp(extension,".jpg")==0 || strcasecmp(extension,".jpeg" )==0)
+            return "image/jpeg";
+    }
+    return "text/plain; charset=iso-8859-1";
+}
+
+#endif
diff -r 000000000000 -r fbb29d9ea96b main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Apr 07 11:23:03 2013 +0000
@@ -0,0 +1,370 @@
+#include "mbed.h"
+#include "EthernetInterface.h"
+#include "SDFileSystem.h"
+
+#define EnDebugMSG  false //true-> print debug message to PC USB terminal, false->not print
+#include "filelib.h"
+
+#define IP      "192.168.100.100"
+#define MASK    "255.255.255.0"
+#define GATEWAY "192.168.100.1"
+#define PORT    80
+
+Serial pc (USBTX,USBRX);    // tx, rx
+SDFileSystem sd(p5, p6, p7, p8, "wfs"); // the pinout on the mbed
+
+char sMethod[7];
+char sURL[250];
+char sProtocol[8];
+
+EthernetInterface eth;
+
+TCPSocketServer svr;
+bool serverIsListened = false;
+
+TCPSocketConnection client;
+bool clientIsConnected = false;
+
+char sentBuffer[1608] = {}; // 2*536=1072, 3*536=1608, 4*536=2144   !1500
+char line_response[256]= {0};
+char file_path[256] = {0};
+
+DigitalOut led1(LED1); //server listning status
+DigitalOut led2(LED2); //socket connecting status
+
+Ticker ledTick;
+
+void ledTickfunc()
+{
+    if(serverIsListened)  {
+        led1 = !led1;
+    } else {
+        led1 = false;
+    }
+}
+
+void send_HTTP_header(char* protocol, int code, char* title, char* mime_type, long long lengthBody)
+{
+    snprintf(line_response, sizeof(line_response),"%s %d %s\r\n", protocol, code, title );
+    snprintf(sentBuffer, sizeof(sentBuffer),"%s",line_response);
+
+    if ( mime_type != NULL ) {
+        snprintf(line_response, sizeof(line_response), "Content-Type: %s\r\n", mime_type );
+        snprintf(sentBuffer, sizeof(sentBuffer), "%s%s",sentBuffer,line_response);    //append to sentBuffer
+    }
+    if ( lengthBody >= 0 ) {
+        snprintf(line_response, sizeof(line_response), "Content-Length: %lld\r\n", lengthBody );
+        snprintf(sentBuffer, sizeof(sentBuffer), "%s%s",sentBuffer,line_response);    //append to sentBuffer
+    }
+    snprintf(line_response, sizeof(line_response), "Connection: close\r\n" );
+    snprintf(sentBuffer, sizeof(sentBuffer),"%s%s\r\n",sentBuffer,line_response);    //append to sentBuffer
+
+    if (EnDebugMSG)
+        printf("\n-->sent Header--\n");
+
+    client.send_all(sentBuffer,strlen(sentBuffer));
+    if (EnDebugMSG) {
+        printf(sentBuffer);
+        printf("\n--end Header-- bytes:%d",strlen(sentBuffer));
+    }
+    Thread::wait(200);  //200ms important for browser!
+}
+
+void send_HTML_line(char* line, unsigned int length_line)
+{
+    client.send_all(line,length_line);
+    if (EnDebugMSG)
+        printf("\n-->send HTML line:\n%s ...Ok!",line);
+    Thread::wait(10);
+}
+
+void send_HTML_error( int status_code, char* title, char* body_text)
+{
+    send_HTTP_header("HTTP/1.1", status_code, title, "text/html", -1);
+    if (EnDebugMSG)
+        printf("\n-->send_error...\n");
+    sentBuffer[0]=NULL; //clear buffer
+    sprintf(line_response, "<!DOCTYPE html>\r\n<html>\r\n<head>\r\n<title>%d %s</title>\r\n</head>\r\n", status_code, title);
+    snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+    sprintf(line_response, "<body><center><h2><center>%d %s</center></h2>\r\n",status_code, title );
+    snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+    sprintf(line_response, "%s\r\n", body_text );
+    snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+    sprintf(line_response, "<p>mbed HTTP File Server</p>\r\n</center></body></html>\r\n");
+    snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+    send_HTML_line(sentBuffer, strlen(sentBuffer));
+}
+
+int send_file(char *path_file)
+{
+    char *mime_type = {0};
+    unsigned int bytes_for_send=0;
+    long long filesize, all_send_bytes = 0;
+
+    mime_type =  get_mime_type( path_file );
+    snprintf(file_path, sizeof(file_path),"/wfs/%s",path_file);
+    if (EnDebugMSG) {
+        printf("\n-->from send_file:%s",file_path);
+        printf("\n-->from send_file mime type:%s",mime_type);
+    }
+
+    if (Mystat(path_file, &myStatBuf)) { //fault with file
+        send_HTML_error( 403, "Forbidden", "403 - File access forbidden.");
+        return 403;
+    }
+    FILE* fp = NULL;
+    fp = fopen(file_path,"r");
+    if (fp==NULL ) {
+        send_HTML_error( 403, "Forbidden", "403 - File access forbidden.");
+        return 403;
+    }
+
+    filesize = myStatBuf.st_size;
+    send_HTTP_header("HTTP/1.1", 200, "Ok", mime_type, myStatBuf.st_size);
+    //binary send
+    all_send_bytes=0;
+    while(filesize)  {  //check for EOF !feof(fp)
+        bytes_for_send = filesize;
+        if (bytes_for_send > sizeof(sentBuffer)) {
+            bytes_for_send = sizeof(sentBuffer);
+        }
+        fread (sentBuffer,1,bytes_for_send,fp);
+        filesize -= bytes_for_send;
+        if (EnDebugMSG)
+            printf("\n---bytes_for_send...%d",bytes_for_send);
+        client.send_all(sentBuffer,bytes_for_send);
+        //Thread::wait(10);
+        all_send_bytes += bytes_for_send;
+    }
+    if (EnDebugMSG)
+        printf("\n---buffer fill end - all ...%lld", all_send_bytes);
+    //binary send
+
+    sprintf(line_response, "\r\n");
+    client.send_all(line_response,strlen(line_response));
+    if ( fp != NULL )
+        fclose(fp);
+    //Thread::wait(10);
+    return 0;
+}
+
+int send_directory(char *path)
+{
+    char process_name[64]= {0};
+
+    char posOfLastSlash;
+    char *pLS;
+
+    struct dirent *p;
+    struct sMystat sb;
+    struct tm *timeinfo;
+    char timeBuf[40];
+
+    if (EnDebugMSG)
+        printf("\n-->from send_directory:%s",path);
+    snprintf(file_path,sizeof(file_path),"/wfs%s",path);
+    DIR *d = opendir(file_path);
+    if (EnDebugMSG && d!=NULL)
+        printf("\n-->from send_directory:%s ...open OK",file_path);
+    if (d==NULL) {   //error open dir
+        send_HTML_error( 403, "Forbidden", "403 - Directory access forbidden.");
+        return -1;
+    }
+    send_HTTP_header("HTTP/1.1", 200, "Ok",NULL, -1);
+    sentBuffer[0]=NULL;
+    sprintf(line_response,"<!DOCTYPE html>\r\n<html>\n<head><title>Index of %s</title>\n",path);
+    snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+    
+    sprintf(line_response,"<meta content=\"text/html; charset=iso-8859-1\" http-equiv=\"Content-Type\"></head>\n");
+    snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+    
+    
+    sprintf(line_response,"<body><center>\n<h3>Index of %s</h3>\n", path);
+    snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+    send_HTML_line(sentBuffer, strlen(sentBuffer));
+//begin table
+    sentBuffer[0]=NULL; //clear buffer
+    sprintf(line_response,"<table border=\"0\">\n");
+    snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+    sprintf(line_response,"<tr><th align=\"left\" width=\"200\">Name</th><th align=\"right\" width=\"100\">Size(bytes)</th><th align=\"right\" width=\"200\">Date/Time</th></tr>\n");
+    snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+//begin table
+
+    pLS=strrchr(path,'/');
+    posOfLastSlash=pLS-path+1;
+    if (EnDebugMSG)
+        printf("\r\n>>posOfLastSlash=%d",posOfLastSlash);
+    snprintf(process_name,posOfLastSlash+1,"%s",path);
+    if (EnDebugMSG)
+        printf("\r\n>>process_name=%s",process_name);
+    sprintf(line_response,"<tr><td align=\"left\"><a href=\"%s\">../</a></td></tr>\n",process_name);
+    snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+    while((p = readdir(d)) != NULL) {
+        if (EnDebugMSG)
+            printf("\n   :%s",p->d_name);
+        sprintf(file_path,"%s/%s",path,p->d_name);
+        Mystat( file_path, &sb );
+        if (get_dirInfo(file_path)==0 ) { //this is directory path
+            if (EnDebugMSG)
+                printf("\nDIR");
+            sprintf(line_response, "<tr><td align=\"left\"><a href=\"%s\">%s</a><br></td></tr>\n",file_path,p->d_name);
+            if (strlen(line_response)>(sizeof(sentBuffer)-strlen(sentBuffer))) { //buffer must be sent
+                send_HTML_line(sentBuffer, strlen(sentBuffer));
+                sentBuffer[0]=NULL; //clear buffer
+            }
+            snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+
+        } else {    //this is file
+            if (EnDebugMSG)
+                printf("\nFILE");
+            timeinfo = localtime (&sb.st_mtime);
+            //strftime(timeBuf,40, "%I:%M:%S %p (%Y/%m/%d)\r\n", localtime(&sb.st_mtime));
+            strftime(timeBuf, 40, "%c", timeinfo);
+            sprintf(line_response, "<tr><td align=\"left\"><a href=\"%s\">%s</a></td><td align=\"right\">%lld</td><td align=\"right\">%s</td></tr>\n", file_path, p->d_name,(long long) sb.st_size,timeBuf);    // asctime(timeinfo) );
+
+            if (strlen(line_response)>(sizeof(sentBuffer)-strlen(sentBuffer))) { //buffer must be sent
+                send_HTML_line(sentBuffer, strlen(sentBuffer));
+                sentBuffer[0]=NULL; //clear buffer
+            }
+            snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+        }
+    }
+    send_HTML_line(sentBuffer, strlen(sentBuffer));
+    closedir(d);
+
+    sprintf(line_response, "</table>\n<br><h4>mbed HTTP File Server</h4>\n</center></body></html>\n");
+    send_HTML_line(line_response, strlen(line_response));
+
+    return 0;
+}
+
+void parseHTTPRequest(char* buffer)
+{
+    char spacePos;
+    char *tmpBuffer;
+    spacePos = strcspn(buffer, " ") + 1;   //position of first space character
+    snprintf(sMethod, spacePos,"%s", buffer);
+
+    //get Protocol
+    tmpBuffer=&(buffer[spacePos]);   //move pointer to buffer (delete Method)
+    spacePos = strcspn(tmpBuffer, "\r\n") + 1;
+    tmpBuffer[spacePos]='\0';    //set end of string ...cut
+    sprintf(sProtocol, "%s", strrchr(tmpBuffer,' '));  //get string after last (space )
+    printf("\r\nsProtocol:%s", tmpBuffer);
+    buffer = &(sProtocol[1]);  //cut first character (space)
+    sprintf(sProtocol, "%s", buffer);
+
+    //get URL
+    snprintf(sURL,strlen(tmpBuffer)-strlen(sProtocol),"%s\r\n", tmpBuffer);   //URL is between Method and Protocol
+
+    printf("\nParse Method:%s",sMethod);
+    printf("\nParse URL:%s",sURL);
+    printf("\nParse PROTOCOL:%s",sProtocol);
+    printf("\n\r\n");
+}
+
+int processHTTP(char* sMethod, char* sURL, char* sProtocol)
+{
+    int gdi, gfi;   //status of get_dir_info(xxx), and get_file_info(xxx)
+
+    if (strcmp(sMethod,"GET")!=0) {
+        send_HTML_error( 501, "501 Not Implemented", "501 - The server either does not recognize the request method");
+        return 501;
+    }
+    if (sURL[0]!= '/') {
+        send_HTML_error( 400, "Bad Request", "400 - The request cannot be fulfilled due to bad syntax.");
+        return 400;
+    }
+    if (sURL[strlen(sURL)-1]=='/') {
+        sURL[strlen(sURL)-1]=sURL[strlen(sURL)];  //delete last symbol
+        if (EnDebugMSG)
+            printf("\n delete last:%s",sURL);
+    }
+    gdi= get_dirInfo(sURL);
+    gfi= get_fileInfo(sURL);
+    if (gfi!=0) {   //!=0 file not found
+        if (gdi==0) { //0-ok this is directory
+            return send_directory(sURL);
+        }
+        if (EnDebugMSG)
+            printf("\n404-br File not found or...(Fresult is:%d)",gfi);
+        send_HTML_error( 404, "Not Found","404 - The requested resource could not be found.");
+        return 404;
+    } else {    //==0  found
+        if (gdi==0)  //0-ok this is directory
+            return send_directory(sURL);
+        else
+            return send_file(sURL);
+    }
+}
+
+int main()
+{
+
+
+    ledTick.attach(&ledTickfunc,0.5);
+    //ledTick.detach();
+    //setup ethernet interface
+    //eth.init(); //Use DHCP
+    eth.init(IP,MASK,GATEWAY);  //IP,mask,Gateway
+    eth.connect();
+    printf("IP Address is %s\n\r", eth.getIPAddress());
+
+    //setup tcp socket
+    if(svr.bind(PORT)< 0) {
+        printf("tcp server bind failed.\n\r");
+        return -1;
+    } else {
+        printf("tcp server bind successed.\n\r");
+        serverIsListened = true;
+    }
+
+    if(svr.listen(1) < 0) {
+        printf("tcp server listen failed.\n\r");
+        return -1;
+    } else {
+        printf("tcp server is listening...\n\r");
+    }
+
+    //listening for http GET request
+    while (serverIsListened) {
+        //blocking mode(never timeout)
+        if(svr.accept(client)<0) {
+            printf("failed to accept connection.\n\r");
+        } else {
+            //client.set_blocking(false,5000);    //5000=5sec
+            printf("connection success!\n\rIP: %s\n\r",client.get_address());
+            clientIsConnected = true;
+            led2 = true;
+            while(clientIsConnected) {
+                char buffer[1024] = {};
+                switch(client.receive(buffer, 1023)) {
+                    case 0:
+                        printf("recieved buffer is empty.\n\r");
+                        clientIsConnected = false;
+                        break;
+                    case -1:
+                        printf("failed to read data from client.\n\r");
+                        clientIsConnected = false;
+                        break;
+                    default:
+                        printf("Recieved Data: %d\n\r\n\r%.*s\n\r",strlen(buffer),strlen(buffer),buffer);
+                        parseHTTPRequest(buffer);
+                        //if(buffer[0] == 'G' && buffer[1] == 'E' && buffer[2] == 'T' ) {
+                        if (strcmp(sMethod, "GET" ) == 0 ) {
+                            printf("GET request incomming.\n\r");
+                            processHTTP(sMethod, sURL, sProtocol);
+                            clientIsConnected = false;
+                        }//if get
+                        break;
+                }   //switch
+                //ledTick.attach(&ledTickfunc,0.5);
+            }//while
+            printf("close connection.\n\rHTTP server is listening...\n\r\n");
+            client.close();
+            Thread::wait(50);
+            led2 = false;
+        }
+    }
+
+}
diff -r 000000000000 -r fbb29d9ea96b mbed-rtos.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Sun Apr 07 11:23:03 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-rtos/#53e6cccd8782
diff -r 000000000000 -r fbb29d9ea96b mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Apr 07 11:23:03 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/5e5da4a5990b
\ No newline at end of file