Hi I am using ELM-Chan FatFS library and I need to set it as file system manager for TCPlib FTP server. I do some changes in ftp_uif.c like this:
#include "header.h" #define num_of_ftp_file 10 FIL fsrc[num_of_ftp_file]; BOOL FILE_inuse[num_of_ftp_file]={__FALSE}; void *ftp_fopen (U8 *fname, U8 *mode) {//done by ali FRESULT res; U8 cnt; FILE *ret; for(cnt=0;cnt<num_of_ftp_file;cnt++){ if (FILE_inuse[cnt]==__FALSE){ break; } } if (cnt==num_of_ftp_file) return NULL; printf("fopen"); if (mode[0]=='r'){ res = f_open(&fsrc[cnt], (char *)fname+1, FA_OPEN_EXISTING | FA_READ); printf("\tr%d> %s\r\n",res,(char *)fname); } else if (mode[0]=='w'){ res = f_open(&fsrc[cnt], (char *)fname+1, FA_CREATE_NEW | FA_WRITE); printf("\tw%d> %s\r\n",res,(char *)fname); } else if (mode[0]=='a'){ res = f_open(&fsrc[cnt], (char *)fname+1, FA_OPEN_ALWAYS); printf("\ta%d> %s\r\n",res,(char *)fname); } else return NULL; if (res!=FR_OK) return NULL; printf("file no:%d\r\n",cnt); FILE_inuse[cnt]=__TRUE; ret->handle=cnt; return (ret); } void ftp_fclose (void *file) {//done by ali FILE *fno=(FILE *)file; int no=fno->handle; FILE_inuse[no]=__FALSE; printf("file closed:%d\r\n",no); f_close(&fsrc[no]); } U16 ftp_fread (void *file, U8 *buf, U16 len) {//done by ali FILE *fno=(FILE *)file; int no=fno->handle; U32 res; f_read (&fsrc[no], buf,len,&res); return res; } U16 ftp_fwrite (void *file, U8 *buf, U16 len) { FILE *fno=(FILE *)file; int no=fno->handle; U32 res; f_write(&fsrc[no], buf, len, &res); f_sync(&fsrc[no]); return res; } BOOL ftp_fdelete (U8 *fname) {//done by ali printf("file deleted:%s\r\n",(char *)fname); if (f_unlink ((char *)fname) == FR_OK) { return (__TRUE); } return (__FALSE); } BOOL ftp_frename (U8 *fname, U8 *newn) {//done by ali /* Rename a file, return __TRUE on success. */ if (f_rename((char *)fname, (char *)newn) == FR_OK) { return (__TRUE); } return (__FALSE); } DIR Dir; static FILINFO Finfo; U8 getdir=0; U16 ftp_ffind (U8 code, U8 *buf, U8 *mask, U16 buflen) { U32 rlen,v; U8 *tp; char *ptr="0:"; volatile FRESULT res; if (getdir==0){ res = f_opendir(&Dir, ptr); getdir=1; } printf("code:%d\r\n",code); if (code < 4) { res = f_opendir(&Dir, ptr); } rlen = 0; next: res=f_readdir(&Dir, &Finfo); printf("%s\r\n",Finfo.fname); if ((res != FR_OK) || !Finfo.fname[0]) return 0; if (Finfo.fname[0] == '.') { if ((Finfo.fname[1] == 0) || (Finfo.fname[1] == '.' && Finfo.fname[2]) == 0) { /* Ignore the '.' and '..' folders. */ goto next; } } switch (code) { case 0: /* Return file size as decimal number. */ rlen = sprintf ((char *)buf,"%d\r\n", Finfo.fsize); break; case 1: /* Return last-modified time in format "YYYYMMDDhhmmss". */ rlen = sprintf ((char *)buf,"%04d%02d%02d", (Finfo.fdate >> 9) + 1980, (Finfo.fdate >> 5) & 15, Finfo.fdate & 31); rlen += sprintf ((char *)&buf[rlen],"%02d%02d%02d\r\n", (Finfo.ftime >> 11), (Finfo.ftime >> 5) & 63, (Finfo.ftime & 31)*2); break; case 2: case 4: rlen = sprintf ((char *)buf,"%s\r\n", Finfo.fname); break; case 3: case 8: case 5: rlen = sprintf ((char *)buf,"%02d-%02d-%02d", (Finfo.fdate >> 5) & 15, Finfo.fdate & 31, (Finfo.fdate >> 9) + 1980); /* Convert time to "AM/PM" format. */ v = (Finfo.ftime >> 11) % 12; if (v == 0) v = 12; if ((Finfo.ftime >> 11) < 12) tp = "AM"; else tp = "PM"; rlen += sprintf ((char *)&buf[rlen]," %02d:%02d%s",v,(Finfo.ftime >> 5) & 63,tp); if (Finfo.fattrib & AM_DIR) {//AM_DIR rlen += sprintf ((char *)&buf[rlen],"%-21s"," <DIR>"); } else { rlen += sprintf ((char *)&buf[rlen],"%21d", Finfo.fsize); } rlen += sprintf ((char *)&buf[rlen]," %s\r\n", Finfo.fname); break; } if (rlen==0) getdir=0; return (rlen); }
as you know Fatfs is some how different form FlashFS ... I have no any way to simulate as FILE struct except make an array of FIL as you can see in my code. my first question is about it and is there any solution to do it.
another problem is about different browser: this code is not complete but google chrome does not show any file. firefox is the same. Internet explorer can show all of files in memory card. from explorer I can see every thing. from printf I found sometimes with chrome library send "code=8" and there was no condition about it. I didn't check anything except ftp_ffind I know it is contain problem but this is my first step to implement FTP server based on FatFS
So what does "ret" ever point too? Random junk on the stack, and your using it as a pointer for something, how's that work? Wouldn't you need to allocate some space for a structure? Why not overload FILE * as FIL * ?
Hi
thanks Westonsupermare Pier about "ret" that was my mistake and I did it in this way:
#include "header.h" #define num_of_ftp_file 10 FIL fsrc[num_of_ftp_file]; BOOL FILE_inuse[num_of_ftp_file]={__FALSE}; // FILE ret; void *ftp_fopen (U8 *fname, U8 *mode) {//done by ali FRESULT res; U8 cnt; for(cnt=0;cnt<num_of_ftp_file;cnt++){ if (FILE_inuse[cnt]==__FALSE){ break; } } if (cnt==num_of_ftp_file) return NULL; if (mode[0]=='r'){ res = f_open(&fsrc[cnt], (char *)(fname+1), FA_OPEN_EXISTING | FA_READ); printf("\tr%d> %s\r\n",res,(char *)(fname+1)); } else if (mode[0]=='w'){ res = f_open(&fsrc[cnt], (char *)(fname+1), FA_CREATE_NEW | FA_WRITE); printf("\tw%d> %s\r\n",res,(char *)(fname+1)); } else if (mode[0]=='a'){ res = f_open(&fsrc[cnt], (char *)(fname+1), FA_OPEN_ALWAYS); printf("\ta%d> %s\r\n",res,(char *)(fname+1)); } else return NULL; if (res!=FR_OK) return NULL; FILE_inuse[cnt]=__TRUE; return (&fsrc[cnt]); } /*--------------------------- ftp_fclose ------------------------------------*/ void ftp_fclose (void *file) {//done by ali f_close(file); } /*--------------------------- ftp_fread -------------------------------------*/ U16 ftp_fread (void *file, U8 *buf, U16 len) {//done by ali U32 res; f_read (file, buf,len,&res); return res; } /*--------------------------- ftp_fwrite ------------------------------------*/ U16 ftp_fwrite (void *file, U8 *buf, U16 len) { U32 res; f_write(file, buf, len, &res); f_sync(file); printf("%d:%d\r\n",len,res); return res; } /*--------------------------- ftp_fdelete -----------------------------------*/ BOOL ftp_fdelete (U8 *fname) {//done by ali if (f_unlink ((char *)fname) == FR_OK) { return (__TRUE); } return (__FALSE); } /*--------------------------- ftp_frename -----------------------------------*/ BOOL ftp_frename (U8 *fname, U8 *newn) {//done by ali if (f_rename((char *)fname, (char *)newn) == FR_OK) { return (__TRUE); } return (__FALSE); } DIR Dir; static FILINFO Finfo; U8 getdir=0; U16 ftp_ffind (U8 code, U8 *buf, U8 *mask, U16 buflen) { U32 rlen,v; U8 *tp; char *ptr="0:"; volatile FRESULT res; if (getdir==0){ res = f_opendir(&Dir, ptr); getdir=1; } if (code < 4) { res = f_opendir(&Dir, ptr); } rlen = 0; next: if ((res != FR_OK) || !Finfo.fname[0]) return 0; if (Finfo.fname[0] == '.') { if ((Finfo.fname[1] == 0) || (Finfo.fname[1] == '.' && Finfo.fname[2]) == 0) { /* Ignore the '.' and '..' folders. */ goto next; } } switch (code) { case 0: /* Return file size as decimal number. */ rlen = sprintf ((char *)buf,"%d\r\n", Finfo.fsize); break; case 1: /* Return last-modified time in format "YYYYMMDDhhmmss". */ rlen = sprintf ((char *)buf,"%04d%02d%02d", (Finfo.fdate >> 9) + 1980, (Finfo.fdate >> 5) & 15, Finfo.fdate & 31); rlen += sprintf ((char *)&buf[rlen],"%02d%02d%02d\r\n", (Finfo.ftime >> 11), (Finfo.ftime >> 5) & 63, (Finfo.ftime & 31)*2); break; case 2: case 4: /* List file names only. */ rlen = sprintf ((char *)buf,"%s\r\n", Finfo.fname); break; case 3: case 8: case 5: /* List directory in extended format. */ rlen = sprintf ((char *)buf,"%02d-%02d-%02d", (Finfo.fdate >> 5) & 15, Finfo.fdate & 31, (Finfo.fdate >> 9) + 1980); /* Convert time to "AM/PM" format. */ v = (Finfo.ftime >> 11) % 12; if (v == 0) v = 12; if ((Finfo.ftime >> 11) < 12) tp = "AM"; else tp = "PM"; rlen += sprintf ((char *)&buf[rlen]," %02d:%02d%s",v,(Finfo.ftime >> 5) & 63,tp); if (Finfo.fattrib & AM_DIR) {//AM_DIR rlen += sprintf ((char *)&buf[rlen],"%-21s"," <DIR>"); } else { rlen += sprintf ((char *)&buf[rlen],"%21d", Finfo.fsize); } rlen += sprintf ((char *)&buf[rlen]," %s\r\n", Finfo.fname); break; } return (rlen); }
but problem with Chrome still alive and can not show list of files.(firefox v20 was the same) but IE8 and windows explorer can show files list, read and write. this code is not final and it can just show the root directory. Is there any network debugger or FTP debugger?
In terms of a cheap and easy solutions I'd probably fire up WireShark on a port of a 10BT HUB (not a switch), and watch the traffic on that. I'd instrument the ARM code, to understand what was happening, and if multiple streams from the file system were being requested.
If you're comfortable with socket programming then test with that, consider also using WGET
10BT HUB (not a switch)
I agree with the point made, but would like to emphasize something. The important point is that it should be a hub and not a switch. 100MB HUBs are available. Unfortunately, they are rare. I use a Netgear DS104.
Hubs are harder and harder to find.
Managed switches can also be used for the task - they normally have support for duplicating data to a specific port just with the intention of being able to sniff communication.
Managed switches can also be used for the task
Unfortunately, competent, willing-to-help IT teams seem to be getting harder and harder to find. Sometimes getting someone able and prepared to route the traffic through to a specific line is a major task in itself.