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"); } } }