Final 350 project

Dependencies:   uzair Camera_LS_Y201 F7_Ethernet LCD_DISCO_F746NG NetworkAPI SDFileSystem mbed

main.cpp

Committer:
shoaib_ahmed
Date:
2017-07-31
Revision:
0:791a779d6220

File content as of revision 0:791a779d6220:

#include "mbed.h"
#include "SDFileSystem.h"
#include <jpeglib.h>                        //convert
#include <stdio.h>                          //convert
#include <stdlib.h>                         //convert
#include <string.h>                         //convert
#include "LCD_DISCO_F746NG.h"               //screen
#include "EthernetInterface.h"              //lan
#define EnDebugMSG  false                   //true-> print debug message 
#include "filelib.h"
#define IP      "192.168.240.100"
#define MASK    "255.255.255.0"
#define GATEWAY "192.168.240.1"
#define PORT    80
#define DEBMSG      printf                 
#define NEWLINE()   printf("\r\n")          
#if USE_SDCARD                              
#define FILENAME    "/sd/IMG_%04d.jpg"      
#else                                       
#define FILENAME    "/sd/IMG_%04d.jpg"     
SDFileSystem sd("sd");                      
#endif                                     


DigitalIn pb(USER_BUTTON);
LCD_DISCO_F746NG lcd;


//lan module 
char sMethod[7];
char sURL[250];
char sProtocol[8];
EthernetInterface eth;
TCPSocketServer svr;
bool serverIsListened = false;
TCPSocketConnection client;
bool clientIsConnected = false;
char sentBuffer[1072] = {};                // 2*536=1072, 3*536=1608, 4*536=2144
char line_response[256]= {0};
char file_path[256] = {0};
DigitalOut led1(LED1);                     //server listning status
DigitalOut led2(LED2);                     //socket connecting status
Ticker ledTick;
//~lan module

//convert module
unsigned char *raw_image = NULL;

typedef struct work 
{
    FILE *fp;
} work_t;
work_t work;
 
void callback_func(int done, int total, uint8_t *buf, size_t siz) 
{
    fwrite(buf, siz, 1, work.fp); 
    static int n = 0;
    int tmp = done * 100 / total;
    if (n != tmp) 
    {
        n = tmp;
        DEBMSG("Writing...: %3d%%", n);
        NEWLINE();
    }
}

/* dimensions of the image we want to write */
int width;
int height;
int bytes_per_pixel;

/* or 1 for GRACYSCALE images */
int color_space; /* or JCS_GRAYSCALE for grayscale images */

typedef struct{
    long filesize;
    char reserved[2];
    long headersize;
    long infoSize;
    long width;
    long depth;
    short biPlanes;
    short bits;
    long biCompression;
    long biSizeImage;
    long biXPelsPerMeter;
    long biYPelsPerMeter;
    long biClrUsed;
    long biClrImportant;
} BMPHEAD;
// ~convertjpegtobmp

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                              convert .jpeg image to .bmp image                                        //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int Convert_output(char *filename)
{
    sd.mount();

    BMPHEAD bh;

    memset((char *)&bh, 0, sizeof(BMPHEAD)); /* sets everything to 0 */
    bh.headersize = 54L;                     //for 24 bit images)
    bh.infoSize = 0x28L;                     //for 24 bit images)
    bh.width = width;                        //in pixels of your image
    bh.depth = height;                       // in pixels of your image
    bh.biPlanes = 1;                         //for 24 bit images)
    bh.bits = 24;                            //for 24 bit images)
    bh.biCompression = 0L;;                  //no compression)

    int bytesPerLine;

    bytesPerLine = width * 3;               /* (for 24 bit images) */
                                            /* round up to a dword boundary */
    if (bytesPerLine & 0x0003)
    {
        bytesPerLine |= 0x0003;
        ++bytesPerLine;
    }
    bh.filesize = bh.headersize + (long)bytesPerLine*bh.depth;

    FILE * bmpfile;

    printf("Bytes per line : %d\n", bytesPerLine);

    bmpfile = fopen(filename, "wb");
    if (bmpfile == NULL)
    {
        printf("Error opening output file\n");
        /* -- close all open files and free any allocated memory -- */
        exit(1);
    }
    fwrite("BM", 1, 2, bmpfile);
    fwrite((char *)&bh, 1, sizeof(bh), bmpfile);

    char *linebuf;

    linebuf = (char *)calloc(1, bytesPerLine);
    if (linebuf == NULL)
    {
        printf("Error allocating memory\n");
        free(raw_image);
        /* -- close all open files and free any allocated memory -- */
        exit(1);
    }


    int line, x;

    for (line = height - 1; line >= 0; line--)
    {
        /* fill line linebuf with the image data for that line */
        for (x = 0; x < width; x++)
        {
            *(linebuf + x*bytes_per_pixel) = *(raw_image + (x + line*width)*bytes_per_pixel + 2);
            *(linebuf + x*bytes_per_pixel + 1) = *(raw_image + (x + line*width)*bytes_per_pixel + 1);
            *(linebuf + x*bytes_per_pixel + 2) = *(raw_image + (x + line*width)*bytes_per_pixel + 0);
        }
        fwrite(linebuf, 1, bytesPerLine, bmpfile);
    }
    free(linebuf);
    fclose(bmpfile);
    printf("bytes writing process complete");
}


int Convert_input(char *filename)
{
    /* these are standard libjpeg structures for reading(decompression) */
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    /* libjpeg data structure for storing one row, that is, scanline of an image */
    JSAMPROW row_pointer[1];

    FILE *infile = fopen(filename,"rb");
    unsigned long location = 0;
    int i = 0;
    
    if (!infile)
    {
        printf("Error opening jpeg file %s\n!", filename);
        return -1;
    }
    
    /* here we set up the standard libjpeg error handler */
    cinfo.err = jpeg_std_error(&jerr);
    /* setup decompression process and source, then read JPEG header */
    jpeg_create_decompress(&cinfo);
    /* this makes the library read from infile */
    jpeg_stdio_src(&cinfo, infile);
    /* reading the image header which contains image information */
    jpeg_read_header(&cinfo, TRUE);
    /* Uncomment the following to output image information, if needed. */

    printf("JPEG File Information: \n");
    printf("Image width and height: %d pixels and %d pixels.\n", width = cinfo.image_width, height = cinfo.image_height);
    printf("Color components per pixel: %d.\n", bytes_per_pixel = cinfo.num_components);
    printf("Color space: %d.\n", cinfo.jpeg_color_space);

    /* Start decompression jpeg here */
    jpeg_start_decompress(&cinfo);

    /* allocate memory to hold the uncompressed image */
    raw_image = (unsigned char*)malloc(cinfo.output_width*cinfo.output_height*cinfo.num_components);
    /* now actually read the jpeg into the raw buffer */
    row_pointer[0] = (unsigned char *)malloc(cinfo.output_width*cinfo.num_components);
    /* read one scan line at a time */
    while (cinfo.output_scanline < cinfo.image_height)
    {
        jpeg_read_scanlines(&cinfo, row_pointer, 1);
        for (i = 0; i<cinfo.image_width*cinfo.num_components; i++)
        raw_image[location++] = row_pointer[0][i];
    }
    
    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
    free(row_pointer[0]);
    fclose(infile);
    return 1;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                              ~convert .jpeg image to .bmp image                                       //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                       HTTP File SERVER                                                //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


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("\r\n-->sent Header--\r\n");
 
    client.send_all(sentBuffer,strlen(sentBuffer));
    
    if (EnDebugMSG) 
    {
        printf(sentBuffer);
        printf("\r\n--end Header-- bytes:%d",strlen(sentBuffer));
    }
    wait(0.2);  //200ms important for browser!
}
 
void send_HTML_line(char* line, unsigned int length_line)
{
    client.send_all(line,length_line);
    if (EnDebugMSG)
        printf("\r\n-->send HTML line:\r\n%s ...Ok!",line);
    wait(0.01);
}
 
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("\r\n-->send_error...\r\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),"/sd/%s",path_file);
        
    if (EnDebugMSG) 
    {
        printf("\r\n-->from send_file:%s",file_path);
        printf("\r\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("\r\n---bytes_for_send...%d",bytes_for_send);
        client.send_all(sentBuffer,bytes_for_send);
        sentBuffer[0]=NULL; //clear buffer
        //Thread::wait(10);
        all_send_bytes += bytes_for_send;
    }
    if (EnDebugMSG)
        printf("\r\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),"/sd%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
    d= opendir("/sd/");
    while((p = readdir(d)) != NULL) 
    {
        printf("\n inside while loop p = readdir(d)\n" );
        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)
{
    sd.mount();
    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);
    }
   // send_file(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);
    }
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                             HTTP File SERVER                                                          //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                  Main                                                                 //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 
int main()
{
    
    int check=1;
    int newcheck=10;
    int insidecondition=0;
    
    while(1)
    {
        pb.mode(PullUp);
        newcheck=pb;
        if(check==newcheck)
        {  
            eth.init("192.168.240.100","255.255.255.0","192.168.240.1");
            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 
            {
                sd.mount();
                char Input_Filename[] = "/sd/IMG_0000.jpg \n";
                char Output_Filename[] = "/sd/Output.bmp \n";
                Convert_input(Input_Filename);
                Convert_output(Output_Filename);
                free(raw_image);
                printf("\n image convertion process complete \n");
                printf("\n waiting for WEB file request \n");
           }
         
         while (serverIsListened) 
         {
                //blocking mode(never timeout)
                if(svr.accept(client)<0) 
                {
                    printf("failed to accept connection.\n\r");
                } 
                else 
                {    
                    if(insidecondition==2)
                    { 
                         lcd.DrawBitmap(0,0,(uint8_t *)"/sd/new.bmp");  //displaying pic to lcd
                    }
                
                    printf("connection success!\n\rIP: %s\n\r",client.get_address());
                    clientIsConnected = true;
                    led2 = true;
                    while(clientIsConnected) 
                    {
                      char buffer[512] = {};
                      switch(client.receive(buffer, 511)) 
                        {
                            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 (strcmp(sMethod, "GET" ) == 0 ) 
                                    {
                                        printf("GET request incomming.\n\r");
                                        processHTTP(sMethod, sURL, sProtocol);
                                        clientIsConnected = false;
                                    }
                                    break;
                        }
                           
                    }
                        printf("close connection.\n\rHTTP server is listening...\n\r\n");
                        insidecondition=insidecondition+1;
                        client.close();
                        wait(1);
                        led2 = false;
                }
            } 
        }
        else
        {        
            printf("Press button to start FS and Convert \n"); 
        }
            
    }
    

}